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