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