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