]> andersk Git - moira.git/blob - server/qfollow.pc
make get_pobox return an additional argument so it will include both
[moira.git] / server / qfollow.pc
1 /* $Id$
2  *
3  * Query followup routines
4  *
5  * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6  * For copying and distribution information, please see the file
7  * <mit-copyright.h>.
8  *
9  */
10
11 #include <mit-copyright.h>
12 #include "mr_server.h"
13 #include "query.h"
14 #include "qrtn.h"
15
16 #include <errno.h>
17 #include <ctype.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #ifdef GDSS
21 #include "gdss.h"
22 #endif /* GDSS */
23
24 EXEC SQL INCLUDE sqlca;
25
26 RCSID("$Header$");
27
28 extern char *whoami, *table_name[];
29 extern int dbms_errno, mr_errcode;
30
31 EXEC SQL BEGIN DECLARE SECTION;
32 extern char stmt_buf[];
33 EXEC SQL END DECLARE SECTION;
34
35 EXEC SQL WHENEVER SQLERROR DO dbmserr();
36
37
38 /* FOLLOWUP ROUTINES */
39
40 /* generic set_modtime routine.  This takes the table id from the query,
41  * and will update the modtime, modby, and modwho fields in the entry in
42  * the table whose name field matches argv[0].
43  */
44
45 int set_modtime(struct query *q, char *argv[], client *cl)
46 {
47   char *name, *entity, *table;
48   int who;
49
50   entity = cl->entity;
51   who = cl->client_id;
52   table = table_name[q->rtable];
53   name = argv[0];
54
55   sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
56           "modwith = '%s' WHERE name = '%s'", table, who, entity, name);
57   EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
58
59   return MR_SUCCESS;
60 }
61
62 /* generic set_modtime_by_id routine.  This takes the table id from
63  * the query, and the id name from the validate record,
64  * and will update the modtime, modby, and modwho fields in the entry in
65  * the table whose id matches argv[0].
66  */
67
68 int set_modtime_by_id(struct query *q, char *argv[], client *cl)
69 {
70   char *entity, *table, *id_name;
71   int who, id;
72
73   entity = cl->entity;
74   who = cl->client_id;
75   table = table_name[q->rtable];
76   id_name = q->validate->object_id;
77
78   id = *(int *)argv[0];
79   sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
80           "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id);
81   EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
82   return MR_SUCCESS;
83 }
84
85
86 /* Sets the finger modtime on a user record.  The users_id will be in argv[0].
87  */
88
89 int set_finger_modtime(struct query *q, char *argv[], client *cl)
90 {
91   EXEC SQL BEGIN DECLARE SECTION;
92   int users_id, who;
93   char *entity;
94   EXEC SQL END DECLARE SECTION;
95
96   entity = cl->entity;
97   who = cl->client_id;
98   users_id = *(int *)argv[0];
99
100   EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who,
101     fmodwith = :entity WHERE users_id = :users_id;
102
103   return MR_SUCCESS;
104 }
105
106
107 /* Sets the pobox modtime on a user record.  The users_id will be in argv[0].
108  */
109
110 int set_pobox_modtime(struct query *q, char *argv[], client *cl)
111 {
112   EXEC SQL BEGIN DECLARE SECTION;
113   int users_id, who;
114   char *entity;
115   EXEC SQL END DECLARE SECTION;
116
117   entity = cl->entity;
118   who = cl->client_id;
119   users_id = *(int *)argv[0];
120
121   EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who,
122     pmodwith = :entity WHERE users_id = :users_id;
123
124   return MR_SUCCESS;
125 }
126
127
128 /* Like set_modtime, but uppercases the name first.
129  */
130
131 int set_uppercase_modtime(struct query *q, char *argv[], client *cl)
132 {
133   char *name, *entity, *table;
134   int who;
135
136   entity = cl->entity;
137   who = cl->client_id;
138   table = table_name[q->rtable];
139   name = argv[0];
140
141   sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, "
142           "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name);
143   EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
144
145   return MR_SUCCESS;
146 }
147
148
149 /* Sets the modtime on the machine whose mach_id is in argv[0].  This routine
150  * is necessary for add_machine_to_cluster becuase the table that query
151  * operates on is "mcm", not "machine".
152  */
153
154 int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl)
155 {
156   EXEC SQL BEGIN DECLARE SECTION;
157   char *entity;
158   int who, id;
159   EXEC SQL END DECLARE SECTION;
160
161   entity = cl->entity;
162   who = cl->client_id;
163   id = *(int *)argv[0];
164   EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who,
165     modwith = :entity WHERE mach_id = :id;
166
167   return MR_SUCCESS;
168 }
169
170
171 /* Sets the modtime on the cluster whose mach_id is in argv[0].  This routine
172  * is necessary for add_cluster_data and delete_cluster_data becuase the
173  * table that query operates on is "svc", not "cluster".
174  */
175
176 int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl)
177 {
178   EXEC SQL BEGIN DECLARE SECTION;
179   char *entity;
180   int who, id;
181   EXEC SQL END DECLARE SECTION;
182
183   entity = cl->entity;
184   who = cl->client_id;
185
186   id = *(int *)argv[0];
187   EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who,
188     modwith = :entity WHERE clu_id = :id;
189   return MR_SUCCESS;
190 }
191
192
193 /* sets the modtime on the serverhost where the service name is in argv[0]
194  * and the mach_id is in argv[1].
195  */
196
197 int set_serverhost_modtime(struct query *q, char *argv[], client *cl)
198 {
199   EXEC SQL BEGIN DECLARE SECTION;
200   char *entity, *serv;
201   int who, id;
202   EXEC SQL END DECLARE SECTION;
203
204   entity = cl->entity;
205   who = cl->client_id;
206
207   serv = argv[0];
208   id = *(int *)argv[1];
209   EXEC SQL UPDATE serverhosts
210     SET modtime = SYSDATE, modby = :who, modwith = :entity
211     WHERE service = :serv AND mach_id = :id;
212   return MR_SUCCESS;
213 }
214
215
216 /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
217  * directory name is in argv[1].
218  */
219
220 int set_nfsphys_modtime(struct query *q, char *argv[], client *cl)
221 {
222   EXEC SQL BEGIN DECLARE SECTION;
223   char *entity, *dir;
224   int who, id;
225   EXEC SQL END DECLARE SECTION;
226
227   entity = cl->entity;
228   who = cl->client_id;
229
230   id = *(int *)argv[0];
231   dir = argv[1];
232   EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who,
233     modwith = :entity WHERE dir = :dir AND mach_id = :id;
234   return MR_SUCCESS;
235 }
236
237
238 /* sets the modtime on a filesystem, where argv[0] contains the filesys
239  * label.
240  */
241
242 int set_filesys_modtime(struct query *q, char *argv[], client *cl)
243 {
244   EXEC SQL BEGIN DECLARE SECTION;
245   char *label, *entity;
246   int who;
247   extern int _var_phys_id;
248   EXEC SQL END DECLARE SECTION;
249
250   entity = cl->entity;
251   who = cl->client_id;
252
253   label = argv[0];
254   if (!strcmp(q->shortname, "ufil"))
255     label = argv[1];
256
257   EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who,
258     modwith = :entity, phys_id = :_var_phys_id
259     WHERE label = :label;
260   return MR_SUCCESS;
261 }
262
263
264 /* sets the modtime on a zephyr class, where argv[0] contains the class
265  * name.
266  */
267
268 int set_zephyr_modtime(struct query *q, char *argv[], client *cl)
269 {
270   EXEC SQL BEGIN DECLARE SECTION;
271   char *class, *entity;
272   int who;
273   EXEC SQL END DECLARE SECTION;
274
275   entity = cl->entity;
276   who = cl->client_id;
277
278   class = argv[0];
279
280   EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who,
281     modwith = :entity WHERE class = :class;
282
283   return MR_SUCCESS;
284 }
285
286
287 /* fixes the modby field.  This will be the second to last thing in the
288  * argv, the argv length is determined from the query structure.  It is
289  * passed as a pointer to an integer.  This will either turn it into a
290  * username, or # + the users_id.
291  */
292 int followup_fix_modby(struct query *q, struct save_queue *sq,
293                        struct validate *v, int (*action)(int, char *[], void *),
294                        void *actarg, client *cl)
295 {
296   int i, j;
297   char **argv;
298   int id, status;
299
300   i = q->vcnt - 2;
301   while (sq_get_data(sq, &argv))
302     {
303       id = atoi(argv[i]);
304       if (id > 0)
305         status = id_to_name(id, USERS_TABLE, &argv[i]);
306       else
307         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
308       if (status && status != MR_NO_MATCH)
309         return status;
310       (*action)(q->vcnt, argv, actarg);
311       for (j = 0; j < q->vcnt; j++)
312         free(argv[j]);
313       free(argv);
314     }
315   sq_destroy(sq);
316   return MR_SUCCESS;
317 }
318
319
320 /* After retrieving a user account, fix the modby field and signature.
321  * The modby field is the second to last thing in the
322  * argv, the argv length is determined from the query structure.  It is
323  * passed as a pointer to an integer.  This will either turn it into a
324  * username, or # + the users_id.  Only "gua*" queries have a signature,
325  * these are ones with U_END return values.  "gub*" queries also use this
326  * routine but don't have a signature.
327  */
328 int followup_guax(struct query *q, struct save_queue *sq, struct validate *v,
329                   int (*action)(int, char *[], void *), void *actarg,
330                   client *cl)
331 {
332   int i, j;
333   char **argv;
334 #ifdef GDSS
335   unsigned char sigbuf[512];
336   char *kname;
337   SigInfo  si;
338   EXEC SQL BEGIN DECLARE SECTION;
339   int timestamp, who;
340   char *login;
341   char rsig[USERS_SIGNATURE_SIZE];
342   EXEC SQL VAR rsig IS STRING(USERS_SIGNATURE_SIZE);
343   EXEC SQL END DECLARE SECTION;
344 #endif /* GDSS */
345   int id, status;
346
347   i = q->vcnt - 2;
348   while (sq_get_data(sq, &argv))
349     {
350       id = atoi(argv[i]);
351       if (id > 0)
352         status = id_to_name(id, USERS_TABLE, &argv[i]);
353       else
354         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
355       if (status && status != MR_NO_MATCH)
356         return status;
357 #ifdef GDSS
358       if (q->vcnt == U_END && strlen(argv[U_SIGNATURE]))
359         {
360           login = strtrim(argv[U_NAME]);
361           EXEC SQL SELECT signature, sigdate, sigwho
362             INTO :rsig, :timestamp, :who FROM users
363             WHERE login = :login;
364           if (dbms_errno)
365             return mr_errcode;
366           kname = malloc(0);
367           status = id_to_name(who, STRINGS_TABLE, &kname);
368           si.timestamp = timestamp;
369           si.SigInfoVersion = 0; /* XXXXX this isn't used */
370           kname_parse(si.pname, si.pinst, si.prealm, kname);
371           free(kname);
372           si.rawsig = (unsigned char *)xstrdup(rsig);
373           GDSS_Recompose(&si, sigbuf);
374           free(si.rawsig);
375           free(argv[U_SIGNATURE]);
376           argv[U_SIGNATURE] = xstrdup(sigbuf);
377         }
378 #endif /* GDSS */
379       (*action)(q->vcnt, argv, actarg);
380       for (j = 0; j < q->vcnt; j++)
381         free(argv[j]);
382       free(argv);
383     }
384   sq_destroy(sq);
385   return MR_SUCCESS;
386 }
387
388
389 /**
390  ** followup_ausr - add finger and pobox entries, set_user_modtime
391  **
392  ** Inputs:
393  **     argv[0] - login (add_user)
394  **     argv[3] - last name
395  **     argv[4] - first name
396  **     argv[5] - middle name
397  **
398  **/
399
400 int followup_ausr(struct query *q, char *argv[], client *cl)
401 {
402   EXEC SQL BEGIN DECLARE SECTION;
403   int who, status;
404   char *login, *entity, *name;
405   char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE];
406   EXEC SQL END DECLARE SECTION;
407 #ifdef GDSS
408   char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
409   EXEC SQL BEGIN DECLARE SECTION;
410   char rawsig[512];
411   int sigwho, timestamp;
412   EXEC SQL END DECLARE SECTION;
413   SigInfo si;
414 #endif /* GDSS */
415
416   /* build fullname */
417   if (strlen(argv[4]) && strlen(argv[5]))
418     sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
419   else if (strlen(argv[4]))
420     sprintf(fullname, "%s %s", argv[4], argv[3]);
421   else
422     sprintf(fullname, "%s", argv[3]);
423
424 #ifdef GDSS
425   if (q->vcnt == U_END && *argv[U_SIGNATURE])
426     {
427       sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
428       /* skip bytes for timestamp & kname */
429       si.rawsig = (unsigned char *) rawsig;
430       status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
431       if (strlen(rawsig) > mr_sig_length)
432         {
433           com_err(whoami, 0, "GDSS signature would be truncated.");
434           return MR_INTERNAL;
435         }
436       if (status == 0)
437         {
438           name = kname_unparse(si.pname, si.pinst, si.prealm);
439           status = name_to_id(name, STRINGS_TABLE, &sigwho);
440           if (status == MR_NO_MATCH)
441             sigwho = add_string(name);
442           else if (status)
443             return status;
444           timestamp = si.timestamp;
445         }
446       else
447         return gdss2et(status);
448     }
449   else
450     {
451       rawsig[0] = '\0';
452       sigwho = 0;
453       timestamp = 0;
454     }
455 #endif /* GDSS */
456
457   login = argv[0];
458   who = cl->client_id;
459   entity = cl->entity;
460
461   /* create finger entry, pobox & set modtime on user */
462 #ifdef GDSS
463   EXEC SQL UPDATE users
464     SET modtime = SYSDATE, modby = :who, modwith = :entity,
465     fullname = NVL(:fullname, CHR(0)), affiliation = type,
466     signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp,
467     sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who,
468     fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE,
469     pmodby = :who, pmodwith = :entity
470     WHERE login = :login;
471 #else /* GDSS */
472   EXEC SQL UPDATE users
473     SET modtime = SYSDATE, modby = :who, modwith = :entity,
474     fullname = NVL(:fullname, CHR(0)), affiliation = type,
475     fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
476     potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
477     WHERE login = :login;
478 #endif /* GDSS */
479
480   return MR_SUCCESS;
481 }
482
483
484 /**
485  ** followup_uuac - do signature, set_user_modtime
486  **
487  ** Inputs:
488  **   argv[0] - login (add_user)
489  **   argv[U_SIGNATURE] - sig
490  **
491  **/
492
493 int followup_uuac(struct query *q, char *argv[], client *cl)
494 {
495   EXEC SQL BEGIN DECLARE SECTION;
496   int who, status, id;
497   char *entity, *name;
498   EXEC SQL END DECLARE SECTION;
499 #ifdef GDSS
500   char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE];
501   EXEC SQL BEGIN DECLARE SECTION;
502   char rawsig[512];
503   char *login;
504   int sigwho, timestamp;
505   EXEC SQL END DECLARE SECTION;
506   SigInfo si;
507 #endif /* GDSS */
508
509   id = *(int *)argv[0];
510   who = cl->client_id;
511   entity = cl->entity;
512
513 #ifdef GDSS
514   if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1])
515     {
516       login = malloc(0);
517       status = id_to_name(id, USERS_TABLE, &login);
518       sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]);
519       free(login);
520       /* skip bytes for timestamp & kname */
521       si.rawsig = (unsigned char *) rawsig;
522       status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1],
523                            &si);
524       if (strlen(rawsig) > mr_sig_length)
525         {
526           com_err(whoami, 0, "GDSS signature would be truncated.");
527           return MR_INTERNAL;
528         }
529       if (status == 0)
530         {
531           name = kname_unparse(si.pname, si.pinst, si.prealm);
532           status = name_to_id(name, STRINGS_TABLE, &sigwho);
533           if (status == MR_NO_MATCH)
534             sigwho = add_string(name);
535           else if (status)
536             return status;
537           timestamp = si.timestamp;
538         }
539       else
540         return gdss2et(status);
541     }
542   else
543     {
544       rawsig[0] = '\0';
545       sigwho = 0;
546       timestamp = 0;
547     }
548 #endif /* GDSS */
549
550   /* create finger entry, pobox & set modtime on user */
551
552 #ifdef GDSS
553   EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity,
554     signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho
555     WHERE users_id = :id;
556 #else /* GDSS */
557   EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity
558     WHERE users_id = :id;
559 #endif /* GDSS */
560   return MR_SUCCESS;
561 }
562
563
564 /* followup_gpob: fixes argv[2] and argv[3] based on the pobox type.
565  * Then completes the upcall to the user.
566  *
567  * argv[2] is the users_id on input and should be converted to the
568  * pobox name on output. argv[3] is empty on input and should be
569  * converted to an email address on output.
570  */
571
572 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
573                   int (*action)(int, char *[], void *), void *actarg,
574                   client *cl)
575 {
576   char **argv;
577   char *ptype, *p;
578   int mid, sid, status, i;
579   EXEC SQL BEGIN DECLARE SECTION;
580   int users_id;
581   char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
582   char str[STRINGS_STRING_SIZE];
583   EXEC SQL END DECLARE SECTION;
584
585   /* for each row */
586   while (sq_get_data(sq, &argv))
587     {
588       mr_trim_args(4, argv);
589       ptype = argv[1];
590       users_id = atoi(argv[2]);
591
592       if (!strcmp(ptype, "POP"))
593         {
594           EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
595             WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
596           if (sqlca.sqlcode)
597             return MR_MACHINE;
598           free(argv[2]);
599           argv[2] = xstrdup(strtrim(mach));
600           free(argv[3]);
601           argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
602           sprintf(argv[3], "%s@%s", argv[0], argv[2]);
603         }
604       else if (!strcmp(ptype, "SMTP"))
605         {
606           EXEC SQL SELECT s.string INTO :str FROM strings s, users u
607             WHERE u.users_id = :users_id AND u.box_id = s.string_id;
608           if (sqlca.sqlcode)
609             return MR_STRING;
610           free(argv[2]);
611           free(argv[3]);
612           argv[2] = xstrdup(strtrim(str));
613           argv[3] = xstrdup(str);
614         }
615       else if (!strcmp(ptype, "IMAP"))
616         {
617           EXEC SQL SELECT f.label, m.name INTO :fs, :mach
618             FROM filesys f, machine m, users u
619             WHERE u.users_id = :users_id AND f.filsys_id = u.imap_id
620             AND f.mach_id = m.mach_id;
621           if (sqlca.sqlcode)
622             return MR_FILESYS;
623           free(argv[2]);
624           argv[2] = xstrdup(strtrim(fs));
625           free(argv[3]);
626           argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
627           sprintf(argv[3], "%s@%s", argv[0], mach);
628         }
629       else /* ptype == "NONE" */
630         goto skip;
631
632       if (!strcmp(q->shortname, "gpob"))
633         {
634           sid = atoi(argv[5]);
635           if (sid > 0)
636             status = id_to_name(sid, USERS_TABLE, &argv[5]);
637           else
638             status = id_to_name(-sid, STRINGS_TABLE, &argv[5]);
639           if (status && status != MR_NO_MATCH)
640             return status;
641         }
642
643       (*action)(q->vcnt, argv, actarg);
644     skip:
645       /* free saved data */
646       for (i = 0; i < q->vcnt; i++)
647         free(argv[i]);
648       free(argv);
649     }
650
651   sq_destroy(sq);
652   return MR_SUCCESS;
653 }
654
655
656 /* followup_gsnt: fix the ace_name in argv[7].  argv[6] will contain the
657  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[7] into the
658  * proper name based on the type, and repace that string in the argv.
659  * Also fixes the modby field by called followup_fix_modby.
660  */
661
662 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
663                   int (*action)(int, char *[], void *), void *actarg,
664                   client *cl)
665 {
666   char **argv, *type;
667   int id, i, idx, status;
668
669   idx = 8;
670
671   while (sq_get_data(sq, &argv))
672     {
673       mr_trim_args(q->vcnt, argv);
674
675       id = atoi(argv[i = q->vcnt - 2]);
676       if (id > 0)
677         status = id_to_name(id, USERS_TABLE, &argv[i]);
678       else
679         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
680       if (status && status != MR_NO_MATCH)
681         return status;
682
683       id = atoi(argv[idx]);
684       type = argv[idx - 1];
685
686       if (!strcmp(type, "LIST"))
687         status = id_to_name(id, LIST_TABLE, &argv[idx]);
688       else if (!strcmp(type, "USER"))
689         status = id_to_name(id, USERS_TABLE, &argv[idx]);
690       else if (!strcmp(type, "KERBEROS"))
691         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
692       else if (!strcmp(type, "NONE"))
693         {
694           status = 0;
695           free(argv[idx]);
696           argv[idx] = xstrdup("NONE");
697         }
698       else
699         {
700           status = 0;
701           free(argv[idx]);
702           argv[idx] = xstrdup("???");
703         }
704       if (status && status != MR_NO_MATCH)
705         return status;
706
707       /* send the data */
708       (*action)(q->vcnt, argv, actarg);
709
710       /* free saved data */
711       for (i = 0; i < q->vcnt; i++)
712         free(argv[i]);
713       free(argv);
714     }
715
716   sq_destroy(sq);
717   return MR_SUCCESS;
718 }
719
720
721 /* followup_ghst: fix the ace_name in argv[12].  argv[11] will contain the
722  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[12] into the
723  * proper name based on the type, and repace that string in the argv.
724  * Also fixes the modby field by called followup_fix_modby.
725  */
726
727 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
728                   int (*action)(int, char *[], void *), void *actarg,
729                   client *cl)
730 {
731   char **argv, *type;
732   int id, i, idx, status;
733
734   while (sq_get_data(sq, &argv))
735     {
736       mr_trim_args(q->vcnt, argv);
737
738       id = atoi(argv[i = q->vcnt - 2]);
739       if (id > 0)
740         status = id_to_name(id, USERS_TABLE, &argv[i]);
741       else
742         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
743       if (status && status != MR_NO_MATCH)
744         return status;
745
746       id = atoi(argv[13]);
747       status = id_to_name(id, STRINGS_TABLE, &argv[13]);
748       if (status)
749         return status;
750       id = atoi(argv[14]);
751       status = id_to_name(id, STRINGS_TABLE, &argv[14]);
752       if (status)
753         return status;
754       id = atoi(argv[16]);
755       if (id < 0)
756         status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
757       else
758         status = id_to_name(id, USERS_TABLE, &argv[16]);
759       if (status && status != MR_NO_MATCH)
760         return status;
761
762       idx = 12;
763       id = atoi(argv[idx]);
764       type = strtrim(argv[idx - 1]);
765
766       if (!strcmp(type, "LIST"))
767         status = id_to_name(id, LIST_TABLE, &argv[idx]);
768       else if (!strcmp(type, "USER"))
769         status = id_to_name(id, USERS_TABLE, &argv[idx]);
770       else if (!strcmp(type, "KERBEROS"))
771         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
772       else if (!strcmp(type, "NONE"))
773         {
774           status = 0;
775           free(argv[idx]);
776           argv[idx] = xstrdup("NONE");
777         }
778       else
779         {
780           status = 0;
781           free(argv[idx]);
782           argv[idx] = xstrdup("???");
783         }
784       if (status && status != MR_NO_MATCH)
785         return status;
786
787       /* send the data */
788       (*action)(q->vcnt, argv, actarg);
789
790       /* free saved data */
791       for (i = 0; i < q->vcnt; i++)
792         free(argv[i]);
793       free(argv);
794     }
795
796   sq_destroy(sq);
797   return MR_SUCCESS;
798 }
799
800
801 /* followup_glin: fix the ace_name in argv[8].  argv[7] will contain the
802  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] into the
803  * proper name based on the type, and repace that string in the argv.
804  * Also fixes the modby field by called followup_fix_modby.
805  */
806
807 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
808                   int (*action)(int, char *[], void *), void *actarg,
809                   client *cl)
810 {
811   char **argv, *type;
812   int id, i, idx, status;
813
814   idx = 8;
815   if (!strcmp(q->shortname, "gsin"))
816     idx = 12;
817
818   while (sq_get_data(sq, &argv))
819     {
820       mr_trim_args(q->vcnt, argv);
821
822       id = atoi(argv[i = q->vcnt - 2]);
823       if (id > 0)
824         status = id_to_name(id, USERS_TABLE, &argv[i]);
825       else
826         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
827       if (status && status != MR_NO_MATCH)
828         return status;
829
830       id = atoi(argv[idx]);
831       type = argv[idx - 1];
832
833       if (!strcmp(type, "LIST"))
834         status = id_to_name(id, LIST_TABLE, &argv[idx]);
835       else if (!strcmp(type, "USER"))
836         status = id_to_name(id, USERS_TABLE, &argv[idx]);
837       else if (!strcmp(type, "KERBEROS"))
838         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
839       else if (!strcmp(type, "NONE"))
840         {
841           status = 0;
842           free(argv[idx]);
843           argv[idx] = xstrdup("NONE");
844         }
845       else
846         {
847           status = 0;
848           free(argv[idx]);
849           argv[idx] = xstrdup("???");
850         }
851       if (status && status != MR_NO_MATCH)
852         return status;
853
854       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
855         {
856           argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
857           strcpy(argv[6], UNIQUE_GID);
858         }
859
860       /* send the data */
861       (*action)(q->vcnt, argv, actarg);
862
863       /* free saved data */
864       for (i = 0; i < q->vcnt; i++)
865         free(argv[i]);
866       free(argv);
867     }
868
869   sq_destroy(sq);
870   return MR_SUCCESS;
871 }
872
873 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
874                   int (*action)(int, char *[], void *), void *actarg,
875                   client *cl)
876 {
877   char **argv, *type;
878   int id, i, status;
879
880   while (sq_get_data(sq, &argv))
881     {
882       mr_trim_args(q->vcnt, argv);
883
884       id = atoi(argv[PRINTSERVER_OWNER_NAME]);
885       type = argv[PRINTSERVER_OWNER_TYPE];
886
887       if (!strcmp(type, "LIST"))
888         status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
889       else if (!strcmp(type, "USER"))
890         status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
891       else if (!strcmp(type, "KERBEROS"))
892         status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
893       else
894         {
895           status = 0;
896           free(argv[PRINTSERVER_OWNER_NAME]);
897           argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
898         }
899       if (status && status != MR_NO_MATCH)
900         return status;
901     }
902
903   return followup_fix_modby(q, sq, v, action, actarg, cl);
904 }
905   
906
907 /* followup_gqot: Fix the entity name, directory name & modby fields
908  *   argv[0] = filsys_id
909  *   argv[1] = type
910  *   argv[2] = entity_id
911  *   argv[3] = ascii(quota)
912  */
913
914 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
915                   int (*action)(int, char *[], void *), void *actarg,
916                   client *cl)
917 {
918   int j;
919   char **argv;
920   EXEC SQL BEGIN DECLARE SECTION;
921   int id;
922   char *name, *label;
923   EXEC SQL END DECLARE SECTION;
924   int status, idx;
925
926   if (!strcmp(q->name, "get_quota") ||
927       !strcmp(q->name, "get_quota_by_filesys"))
928     idx = 4;
929   else
930     idx = 3;
931   while (sq_get_data(sq, &argv))
932     {
933       if (idx == 4)
934         {
935           switch (argv[1][0])
936             {
937             case 'U':
938               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
939               break;
940             case 'G':
941             case 'L':
942               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
943               break;
944             case 'A':
945               free(argv[2]);
946               argv[2] = xstrdup("system:anyuser");
947               break;
948             default:
949               id = atoi(argv[2]);
950               argv[2] = xmalloc(8);
951               sprintf(argv[2], "%d", id);
952             }
953         }
954       id = atoi(argv[idx]);
955       free(argv[idx]);
956       argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
957       name = argv[idx];
958       name[0] = '\0';
959       if (id == 0)
960         {
961           label = argv[0];
962           EXEC SQL SELECT name INTO :name FROM filesys
963             WHERE label = :label;
964         }
965       else
966         {
967           EXEC SQL SELECT dir INTO :name FROM nfsphys
968             WHERE nfsphys_id = :id;
969         }
970       if (sqlca.sqlerrd[2] != 1)
971         sprintf(argv[idx], "#%d", id);
972
973       id = atoi(argv[idx + 3]);
974       if (id > 0)
975         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
976       else
977         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
978       if (status && status != MR_NO_MATCH)
979         return status;
980       (*action)(q->vcnt, argv, actarg);
981       for (j = 0; j < q->vcnt; j++)
982         free(argv[j]);
983       free(argv);
984     }
985   sq_destroy(sq);
986   return MR_SUCCESS;
987 }
988
989
990 /* followup_aqot: Add allocation to nfsphys after creating quota.
991  *   argv[0] = filsys_id
992  *   argv[1] = type if "add_quota" or "update_quota"
993  *   argv[2 or 1] = id
994  *   argv[3 or 2] = ascii(quota)
995  */
996
997 int followup_aqot(struct query *q, char *argv[], client *cl)
998 {
999   EXEC SQL BEGIN DECLARE SECTION;
1000   int quota, id, fs, who, physid, table;
1001   char *entity, *qtype, *tname;
1002   EXEC SQL END DECLARE SECTION;
1003   char incr_qual[60];
1004   char *incr_argv[2];
1005   int status;
1006
1007   table = q->rtable;
1008   tname = table_name[table];
1009   fs = *(int *)argv[0];
1010   EXEC SQL SELECT phys_id INTO :physid FROM filesys
1011     WHERE filsys_id = :fs;
1012   if (dbms_errno)
1013     return mr_errcode;
1014
1015   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
1016     {
1017       qtype = argv[1];
1018       id = *(int *)argv[2];
1019       quota = atoi(argv[3]);
1020       sprintf(incr_qual, "q.filsys_id = %d", fs);
1021     }
1022   else
1023     {
1024       qtype = "USER";
1025       id = *(int *)argv[1];
1026       quota = atoi(argv[2]);
1027       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1028               "q.entity_id = %d", fs, qtype, id);
1029     }
1030
1031   /* quota case of incremental_{before|after} only looks at slot 1 */
1032   incr_argv[1] = qtype;
1033
1034   /* Follows one of many possible gross hacks to fix these particular
1035    * conflicts between what is possible in the query table and what
1036    * is possible in SQL.
1037    */
1038   if (q->type == APPEND)
1039     {
1040       incremental_clear_before();
1041       EXEC SQL INSERT INTO quota
1042         (filsys_id, type, entity_id, quota, phys_id)
1043         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1044       incremental_after(table, incr_qual, incr_argv);
1045     }
1046   else
1047     {
1048       incremental_before(table, incr_qual, incr_argv);
1049       EXEC SQL UPDATE quota SET quota = :quota
1050         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1051       status = mr_errcode;
1052       incremental_after(table, incr_qual, incr_argv);
1053     }
1054
1055   if (dbms_errno)
1056     return mr_errcode;
1057   flush_name(argv[0], table);
1058   if (q->type == APPEND)
1059     {
1060       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1061         WHERE table_name = :tname;
1062     }
1063   else
1064     {
1065       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1066         WHERE table_name = :tname;
1067     }
1068
1069   /* Proceed with original followup */
1070   who = cl->client_id;
1071   entity = cl->entity;
1072
1073   EXEC SQL UPDATE quota
1074     SET modtime = SYSDATE, modby = :who, modwith = :entity
1075     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1076   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1077     WHERE nfsphys_id = :physid;
1078   if (dbms_errno)
1079     return mr_errcode;
1080   return MR_SUCCESS;
1081 }
1082
1083
1084 /* Necessitated by the requirement of a correlation name by the incremental
1085  * routines, since query table deletes don't provide one.
1086  */
1087 int followup_dqot(struct query *q, char **argv, client *cl)
1088 {
1089   char *qtype;
1090   int id, fs, table;
1091   char *incr_argv[2];
1092   EXEC SQL BEGIN DECLARE SECTION;
1093   char incr_qual[80], *tname;
1094   EXEC SQL END DECLARE SECTION;
1095
1096   table = q->rtable;
1097   tname = table_name[table];
1098   fs = *(int *)argv[0];
1099   if (!strcmp(q->shortname, "dqot"))
1100     {
1101       qtype = argv[1];
1102       id = *(int *)argv[2];
1103     }
1104   else
1105     {
1106       qtype = "USER";
1107       id = *(int *)argv[1];
1108     }
1109   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1110           fs, qtype, id);
1111
1112   /* quota case of incremental_{before|after} only looks at slot 1 */
1113   incr_argv[1] = qtype;
1114
1115   incremental_before(table, incr_qual, incr_argv);
1116   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1117     AND q.entity_id = :id;
1118   incremental_clear_after();
1119
1120   if (dbms_errno)
1121     return mr_errcode;
1122   flush_name(argv[0], table);
1123
1124   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1125     WHERE table_name = :tname;
1126   return MR_SUCCESS;
1127 }
1128
1129 /* followup_gzcl:
1130  */
1131
1132 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1133                   int (*action)(int, char *[], void *), void *actarg,
1134                   client *cl)
1135 {
1136   int id, i, status;
1137   char **argv;
1138
1139   while (sq_get_data(sq, &argv))
1140     {
1141       mr_trim_args(q->vcnt, argv);
1142
1143       id = atoi(argv[i = q->vcnt - 2]);
1144       if (id > 0)
1145         status = id_to_name(id, USERS_TABLE, &argv[i]);
1146       else
1147         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1148       if (status && status != MR_NO_MATCH)
1149         return status;
1150
1151       for (i = 1; i < 8; i += 2)
1152         {
1153           id = atoi(argv[i + 1]);
1154           if (!strcmp(argv[i], "LIST"))
1155             status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1156           else if (!strcmp(argv[i], "USER"))
1157             status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1158           else if (!strcmp(argv[i], "KERBEROS"))
1159             status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1160           else if (!strcmp(argv[i], "NONE"))
1161             {
1162               status = 0;
1163               free(argv[i + 1]);
1164               argv[i + 1] = xstrdup("NONE");
1165             }
1166           else
1167             {
1168               status = 0;
1169               free(argv[i + 1]);
1170               argv[i + 1] = xstrdup("???");
1171             }
1172           if (status && status != MR_NO_MATCH)
1173             return status;
1174         }
1175
1176       /* send the data */
1177       (*action)(q->vcnt, argv, actarg);
1178
1179       /* free saved data */
1180       for (i = 0; i < q->vcnt; i++)
1181         free(argv[i]);
1182       free(argv);
1183     }
1184   sq_destroy(sq);
1185   return MR_SUCCESS;
1186 }
1187
1188
1189 /* followup_gsha:
1190  */
1191
1192 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1193                   int (*action)(int, char *[], void *), void *actarg,
1194                   client *cl)
1195 {
1196   char **argv;
1197   int i, id, status;
1198
1199   while (sq_get_data(sq, &argv))
1200     {
1201       mr_trim_args(q->vcnt, argv);
1202
1203       id = atoi(argv[4]);
1204       if (id > 0)
1205         status = id_to_name(id, USERS_TABLE, &argv[4]);
1206       else
1207         status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1208       if (status && status != MR_NO_MATCH)
1209         return status;
1210
1211       id = atoi(argv[2]);
1212       if (!strcmp(argv[1], "LIST"))
1213         status = id_to_name(id, LIST_TABLE, &argv[2]);
1214       else if (!strcmp(argv[1], "USER"))
1215         status = id_to_name(id, USERS_TABLE, &argv[2]);
1216       else if (!strcmp(argv[1], "KERBEROS"))
1217         status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1218       else if (!strcmp(argv[1], "NONE"))
1219         {
1220           status = 0;
1221           free(argv[2]);
1222           argv[2] = xstrdup("NONE");
1223         }
1224       else
1225         {
1226           status = 0;
1227           free(argv[2]);
1228           argv[2] = xstrdup("???");
1229         }
1230       if (status && status != MR_NO_MATCH)
1231         return status;
1232
1233       /* send the data */
1234       (*action)(q->vcnt, argv, actarg);
1235
1236       /* free saved data */
1237       for (i = 0; i < q->vcnt; i++)
1238         free(argv[i]);
1239       free(argv);
1240     }
1241   sq_destroy(sq);
1242   return MR_SUCCESS;
1243 }
1244
1245
1246 int _sdl_followup(struct query *q, char *argv[], client *cl)
1247 {
1248   if (atoi(argv[0]))
1249     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1250   else
1251     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1252
1253   return MR_SUCCESS;
1254 }
1255
1256
1257 int trigger_dcm(struct query *q, char *argv[], client *cl)
1258 {
1259   pid_t pid;
1260   char prog[MAXPATHLEN];
1261
1262   sprintf(prog, "%s/startdcm", BIN_DIR);
1263   pid = vfork();
1264   switch (pid)
1265     {
1266     case 0:
1267       execl(prog, "startdcm", 0);
1268       exit(1);
1269
1270     case -1:
1271       return errno;
1272
1273     default:
1274       return MR_SUCCESS;
1275     }
1276 }
This page took 0.137363 seconds and 5 git commands to generate.