]> andersk Git - moira.git/blob - server/qfollow.pc
second code style cleanup: void/void * usage, proper #includes. try to
[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 <ctype.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #ifdef GDSS
20 #include "gdss.h"
21 #endif /* GDSS */
22
23 EXEC SQL INCLUDE sqlca;
24
25 RCSID("$Header$");
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, char *[], void *),
295                        void *actarg, client *cl)
296 {
297   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, char *[], void *), void *actarg,
331                   client *cl)
332 {
333   int i, j;
334   char **argv;
335 #ifdef GDSS
336   unsigned char sigbuf[256];
337   char *kname;
338   SigInfo  si;
339   EXEC SQL BEGIN DECLARE SECTION;
340   int timestamp, who;
341   char *login;
342   char rsig[256];
343   EXEC SQL VAR rsig IS STRING(256);
344   EXEC SQL END DECLARE SECTION;
345 #endif /* GDSS */
346   int id, status;
347
348   i = q->vcnt - 2;
349   while (sq_get_data(sq, &argv))
350     {
351       id = atoi(argv[i]);
352       if (id > 0)
353         status = id_to_name(id, USERS_TABLE, &argv[i]);
354       else
355         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
356       if (status && status != MR_NO_MATCH)
357         return status;
358 #ifdef GDSS
359       if (q->vcnt == U_END && strlen(argv[U_SIGNATURE]))
360         {
361           login = strtrim(argv[U_NAME]);
362           EXEC SQL SELECT signature, sigdate, sigwho
363             INTO :rsig, :timestamp, :who FROM users
364             WHERE login = :login;
365           if (dbms_errno)
366             return mr_errcode;
367           kname = malloc(1);
368           status = id_to_name(who, STRINGS_TABLE, &kname);
369           si.timestamp = timestamp;
370           si.SigInfoVersion = 0; /* XXXXX this isn't used */
371           kname_parse(si.pname, si.pinst, si.prealm, kname);
372           free(kname);
373           si.rawsig = (unsigned char *)strdup(rsig);
374           if (log_flags & LOG_GDSS)
375             com_err(whoami, 0, "rawsig length = %d, sig=\"%s\"",
376                     strlen(si.rawsig), si.rawsig);
377           GDSS_Recompose(&si, sigbuf);
378           free(si.rawsig);
379           free(argv[U_SIGNATURE]);
380           argv[U_SIGNATURE] = strdup(sigbuf);
381           if (log_flags & LOG_GDSS)
382             com_err(whoami, 0, "generated signature length %d",
383                     strlen(sigbuf));
384         }
385 #endif /* GDSS */
386       (*action)(q->vcnt, argv, actarg);
387       for (j = 0; j < q->vcnt; j++)
388         free(argv[j]);
389       free(argv);
390     }
391   sq_destroy(sq);
392   return MR_SUCCESS;
393 }
394
395
396 /**
397  ** followup_ausr - add finger and pobox entries, set_user_modtime
398  **
399  ** Inputs:
400  **     argv[0] - login (add_user)
401  **     argv[3] - last name
402  **     argv[4] - first name
403  **     argv[5] - middle name
404  **
405  **/
406
407 int followup_ausr(struct query *q, char *argv[], client *cl)
408 {
409   EXEC SQL BEGIN DECLARE SECTION;
410   int who, status;
411   char *login, *entity, *name;
412   char fullname[129];
413   EXEC SQL END DECLARE SECTION;
414 #ifdef GDSS
415   char databuf[32];
416   EXEC SQL BEGIN DECLARE SECTION;
417   char rawsig[128];
418   int sigwho, timestamp;
419   EXEC SQL END DECLARE SECTION;
420   SigInfo si;
421 #endif /* GDSS */
422
423   /* build fullname */
424   if (strlen(argv[4]) && strlen(argv[5]))
425     sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
426   else if (strlen(argv[4]))
427     sprintf(fullname, "%s %s", argv[4], argv[3]);
428   else
429     sprintf(fullname, "%s", argv[3]);
430
431 #ifdef GDSS
432   if (q->vcnt == U_END && *argv[U_SIGNATURE])
433     {
434       sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]);
435       /* skip bytes for timestamp & kname */
436       si.rawsig = (unsigned char *) rawsig;
437       status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si);
438       if (strlen(rawsig) > mr_sig_length)
439         {
440           com_err(whoami, 0, "GDSS signature would be truncated.");
441           return MR_INTERNAL;
442         }
443       if (status == 0)
444         {
445           name = kname_unparse(si.pname, si.pinst, si.prealm);
446           status = name_to_id(name, STRINGS_TABLE, &sigwho);
447           if (status == MR_NO_MATCH)
448             sigwho = add_string(name);
449           else if (status)
450             return status;
451           timestamp = si.timestamp;
452         }
453       else
454         {
455           if (log_flags & LOG_GDSS)
456             hex_dump(argv[U_SIGNATURE]);
457           return gdss2et(status);
458         }
459     }
460   else
461     {
462       rawsig[0] = '\0';
463       sigwho = 0;
464       timestamp = 0;
465     }
466 #endif /* GDSS */
467
468   login = argv[0];
469   who = cl->client_id;
470   entity = cl->entity;
471
472   /* create finger entry, pobox & set modtime on user */
473 #ifdef GDSS
474   EXEC SQL UPDATE users
475     SET modtime = SYSDATE, modby = :who, modwith = :entity,
476     fullname = NVL(:fullname, CHR(0)), affiliation = type,
477     signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp,
478     sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who,
479     fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE,
480     pmodby = :who, pmodwith = :entity
481     WHERE login = :login;
482 #else /* GDSS */
483   EXEC SQL UPDATE users
484     SET modtime = SYSDATE, modby = :who, modwith = :entity,
485     fullname = NVL(:fullname, CHR(0)), affiliation = type,
486     fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity,
487     potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity
488     WHERE login = :login;
489 #endif /* GDSS */
490
491   return MR_SUCCESS;
492 }
493
494
495 /**
496  ** followup_uuac - do signature, set_user_modtime
497  **
498  ** Inputs:
499  **   argv[0] - login (add_user)
500  **   argv[U_SIGNATURE] - sig
501  **
502  **/
503
504 int followup_uuac(struct query *q, char *argv[], client *cl)
505 {
506   EXEC SQL BEGIN DECLARE SECTION;
507   int who, status, id;
508   char *entity, *name;
509   EXEC SQL END DECLARE SECTION;
510 #ifdef GDSS
511   char databuf[32];
512   EXEC SQL BEGIN DECLARE SECTION;
513   char rawsig[128];
514   char *login;
515   int sigwho, timestamp;
516   EXEC SQL END DECLARE SECTION;
517   SigInfo si;
518 #endif /* GDSS */
519
520   id = *(int *)argv[0];
521   who = cl->client_id;
522   entity = cl->entity;
523
524 #ifdef GDSS
525   if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1])
526     {
527       login = malloc(1);
528       status = id_to_name(id, USERS_TABLE, &login);
529       sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]);
530       free(login);
531       /* skip bytes for timestamp & kname */
532       si.rawsig = (unsigned char *) rawsig;
533       status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1],
534                            &si);
535       if (strlen(rawsig) > mr_sig_length)
536         {
537           com_err(whoami, 0, "GDSS signature would be truncated.");
538           return MR_INTERNAL;
539         }
540       if (status == 0)
541         {
542           name = kname_unparse(si.pname, si.pinst, si.prealm);
543           status = name_to_id(name, STRINGS_TABLE, &sigwho);
544           if (status == MR_NO_MATCH)
545             sigwho = add_string(name);
546           else if (status)
547             return status;
548           timestamp = si.timestamp;
549         }
550       else
551         {
552           if (log_flags & LOG_GDSS)
553             hex_dump(argv[U_SIGNATURE + 1]);
554           return gdss2et(status);
555         }
556     }
557   else
558     {
559       rawsig[0] = '\0';
560       sigwho = 0;
561       timestamp = 0;
562     }
563 #endif /* GDSS */
564
565   /* create finger entry, pobox & set modtime on user */
566
567 #ifdef GDSS
568   EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity,
569     signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho
570     WHERE users_id = :id;
571 #else /* GDSS */
572   EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity
573     WHERE users_id = :id;
574 #endif /* GDSS */
575   return MR_SUCCESS;
576 }
577
578 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
579  * type in argv[1].  Then completes the upcall to the user.
580  *
581  * argv[2] is of the form "123:234" where the first integer is the machine
582  * ID if it is a pop box, and the second is the string ID if it is an SMTP
583  * box.  argv[1] should be "POP", "SMTP", or "NONE".  Boxes of type NONE
584  * are skipped.
585  */
586
587 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
588                   int (*action)(int, char *[], void *), void *actarg,
589                   client *cl)
590 {
591   char **argv;
592   char *ptype, *p;
593   int mid, sid, status, i;
594
595   /* for each row */
596   while (sq_get_data(sq, &argv))
597     {
598       mr_trim_args(2, argv);
599       ptype = argv[1];
600       p = strchr(argv[2], ':');
601       *p++ = '\0';
602       mid = atoi(argv[2]);
603       sid = atoi(p);
604
605       if (!strcmp(ptype, "POP"))
606         {
607           status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
608           if (status == MR_NO_MATCH)
609             return MR_MACHINE;
610         }
611       else if (!strcmp(ptype, "SMTP"))
612         {
613           status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
614           if (status == MR_NO_MATCH)
615             return MR_STRING;
616         }
617       else /* ptype == "NONE" */
618         goto skip;
619       if (status)
620         return status;
621
622       if (!strcmp(q->shortname, "gpob"))
623         {
624           sid = atoi(argv[4]);
625           if (sid > 0)
626             status = id_to_name(sid, USERS_TABLE, &argv[4]);
627           else
628             status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
629         }
630       if (status && status != MR_NO_MATCH)
631         return status;
632
633       (*action)(q->vcnt, argv, actarg);
634     skip:
635       /* free saved data */
636       for (i = 0; i < q->vcnt; i++)
637         free(argv[i]);
638       free(argv);
639     }
640
641   sq_destroy(sq);
642   return MR_SUCCESS;
643 }
644
645
646 /* followup_gsnt: fix the ace_name in argv[7].  argv[6] will contain the
647  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[7] into the
648  * proper name based on the type, and repace that string in the argv.
649  * Also fixes the modby field by called followup_fix_modby.
650  */
651
652 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
653                   int (*action)(int, char *[], void *), void *actarg,
654                   client *cl)
655 {
656   char **argv, *type;
657   int id, i, idx, status;
658
659   idx = 8;
660
661   while (sq_get_data(sq, &argv))
662     {
663       mr_trim_args(q->vcnt, argv);
664
665       id = atoi(argv[i = q->vcnt - 2]);
666       if (id > 0)
667         status = id_to_name(id, USERS_TABLE, &argv[i]);
668       else
669         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
670       if (status && status != MR_NO_MATCH)
671         return status;
672
673       id = atoi(argv[idx]);
674       type = argv[idx - 1];
675
676       if (!strcmp(type, "LIST"))
677         status = id_to_name(id, LIST_TABLE, &argv[idx]);
678       else if (!strcmp(type, "USER"))
679         status = id_to_name(id, USERS_TABLE, &argv[idx]);
680       else if (!strcmp(type, "KERBEROS"))
681         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
682       else if (!strcmp(type, "NONE"))
683         {
684           status = 0;
685           free(argv[idx]);
686           argv[idx] = strdup("NONE");
687         }
688       else
689         {
690           status = 0;
691           free(argv[idx]);
692           argv[idx] = strdup("???");
693         }
694       if (status && status != MR_NO_MATCH)
695         return status;
696
697       /* send the data */
698       (*action)(q->vcnt, argv, actarg);
699
700       /* free saved data */
701       for (i = 0; i < q->vcnt; i++)
702         free(argv[i]);
703       free(argv);
704     }
705
706   sq_destroy(sq);
707   return MR_SUCCESS;
708 }
709
710
711 /* followup_ghst: fix the ace_name in argv[12].  argv[11] will contain the
712  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[12] into the
713  * proper name based on the type, and repace that string in the argv.
714  * Also fixes the modby field by called followup_fix_modby.
715  */
716
717 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
718                   int (*action)(int, char *[], void *), void *actarg,
719                   client *cl)
720 {
721   char **argv, *type;
722   int id, i, idx, status;
723
724   while (sq_get_data(sq, &argv))
725     {
726       mr_trim_args(q->vcnt, argv);
727
728       id = atoi(argv[i = q->vcnt - 2]);
729       if (id > 0)
730         status = id_to_name(id, USERS_TABLE, &argv[i]);
731       else
732         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
733       if (status && status != MR_NO_MATCH)
734         return status;
735
736       id = atoi(argv[13]);
737       status = id_to_name(id, STRINGS_TABLE, &argv[13]);
738       if (status)
739         return status;
740       id = atoi(argv[14]);
741       status = id_to_name(id, STRINGS_TABLE, &argv[14]);
742       if (status)
743         return status;
744       id = atoi(argv[16]);
745       if (id < 0)
746         status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
747       else
748         status = id_to_name(id, USERS_TABLE, &argv[16]);
749       if (status && status != MR_NO_MATCH)
750         return status;
751
752       idx = 12;
753       id = atoi(argv[idx]);
754       type = strtrim(argv[idx - 1]);
755
756       if (!strcmp(type, "LIST"))
757         status = id_to_name(id, LIST_TABLE, &argv[idx]);
758       else if (!strcmp(type, "USER"))
759         status = id_to_name(id, USERS_TABLE, &argv[idx]);
760       else if (!strcmp(type, "KERBEROS"))
761         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
762       else if (!strcmp(type, "NONE"))
763         {
764           status = 0;
765           free(argv[idx]);
766           argv[idx] = strdup("NONE");
767         }
768       else
769         {
770           status = 0;
771           free(argv[idx]);
772           argv[idx] = strdup("???");
773         }
774       if (status && status != MR_NO_MATCH)
775         return status;
776
777       /* send the data */
778       (*action)(q->vcnt, argv, actarg);
779
780       /* free saved data */
781       for (i = 0; i < q->vcnt; i++)
782         free(argv[i]);
783       free(argv);
784     }
785
786   sq_destroy(sq);
787   return MR_SUCCESS;
788 }
789
790
791 /* followup_glin: fix the ace_name in argv[8].  argv[7] will contain the
792  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] into the
793  * proper name based on the type, and repace that string in the argv.
794  * Also fixes the modby field by called followup_fix_modby.
795  */
796
797 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
798                   int (*action)(int, char *[], void *), void *actarg,
799                   client *cl)
800 {
801   char **argv, *type;
802   int id, i, idx, status;
803
804   idx = 8;
805   if (!strcmp(q->shortname, "gsin"))
806     idx = 12;
807
808   while (sq_get_data(sq, &argv))
809     {
810       mr_trim_args(q->vcnt, argv);
811
812       id = atoi(argv[i = q->vcnt - 2]);
813       if (id > 0)
814         status = id_to_name(id, USERS_TABLE, &argv[i]);
815       else
816         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
817       if (status && status != MR_NO_MATCH)
818         return status;
819
820       id = atoi(argv[idx]);
821       type = argv[idx - 1];
822
823       if (!strcmp(type, "LIST"))
824         status = id_to_name(id, LIST_TABLE, &argv[idx]);
825       else if (!strcmp(type, "USER"))
826         status = id_to_name(id, USERS_TABLE, &argv[idx]);
827       else if (!strcmp(type, "KERBEROS"))
828         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
829       else if (!strcmp(type, "NONE"))
830         {
831           status = 0;
832           free(argv[idx]);
833           argv[idx] = strdup("NONE");
834         }
835       else
836         {
837           status = 0;
838           free(argv[idx]);
839           argv[idx] = strdup("???");
840         }
841       if (status && status != MR_NO_MATCH)
842         return status;
843
844       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
845         {
846           argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
847           strcpy(argv[6], UNIQUE_GID);
848         }
849
850       /* send the data */
851       (*action)(q->vcnt, argv, actarg);
852
853       /* free saved data */
854       for (i = 0; i < q->vcnt; i++)
855         free(argv[i]);
856       free(argv);
857     }
858
859   sq_destroy(sq);
860   return MR_SUCCESS;
861 }
862
863
864 /* followup_gqot: Fix the entity name, directory name & modby fields
865  *   argv[0] = filsys_id
866  *   argv[1] = type
867  *   argv[2] = entity_id
868  *   argv[3] = ascii(quota)
869  */
870
871 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
872                   int (*action)(int, char *[], void *), void *actarg,
873                   client *cl)
874 {
875   int j;
876   char **argv;
877   EXEC SQL BEGIN DECLARE SECTION;
878   int id;
879   char *name, *label;
880   EXEC SQL END DECLARE SECTION;
881   int status, idx;
882
883   if (!strcmp(q->name, "get_quota") ||
884       !strcmp(q->name, "get_quota_by_filesys"))
885     idx = 4;
886   else
887     idx = 3;
888   while (sq_get_data(sq, &argv))
889     {
890       if (idx == 4)
891         {
892           switch (argv[1][0])
893             {
894             case 'U':
895               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
896               break;
897             case 'G':
898             case 'L':
899               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
900               break;
901             case 'A':
902               free(argv[2]);
903               argv[2] = strdup("system:anyuser");
904               break;
905             default:
906               id = atoi(argv[2]);
907               argv[2] = malloc(8);
908               sprintf(argv[2], "%d", id);
909             }
910         }
911       id = atoi(argv[idx]);
912       free(argv[idx]);
913       argv[idx] = malloc(256);
914       name = argv[idx];
915       if (id == 0)
916         {
917           label = argv[0];
918           EXEC SQL SELECT name INTO :name FROM filesys
919             WHERE label = :label;
920         }
921       else
922         {
923           EXEC SQL SELECT dir INTO :name FROM nfsphys
924             WHERE nfsphys_id = :id;
925         }
926       if (sqlca.sqlerrd[2] != 1)
927         sprintf(argv[idx], "#%d", id);
928
929       id = atoi(argv[idx + 3]);
930       if (id > 0)
931         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
932       else
933         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
934       if (status && status != MR_NO_MATCH)
935         return status;
936       (*action)(q->vcnt, argv, actarg);
937       for (j = 0; j < q->vcnt; j++)
938         free(argv[j]);
939       free(argv);
940     }
941   sq_destroy(sq);
942   return MR_SUCCESS;
943 }
944
945
946 /* followup_aqot: Add allocation to nfsphys after creating quota.
947  *   argv[0] = filsys_id
948  *   argv[1] = type if "add_quota" or "update_quota"
949  *   argv[2 or 1] = id
950  *   argv[3 or 2] = ascii(quota)
951  */
952
953 int followup_aqot(struct query *q, char *argv[], client *cl)
954 {
955   EXEC SQL BEGIN DECLARE SECTION;
956   int quota, id, fs, who, physid, table;
957   char *entity, *qtype, *tname;
958   EXEC SQL END DECLARE SECTION;
959   char incr_qual[60];
960   char *incr_argv[2];
961   int status;
962
963   table = q->rtable;
964   tname = table_name[table];
965   fs = *(int *)argv[0];
966   EXEC SQL SELECT phys_id INTO :physid FROM filesys
967     WHERE filsys_id = :fs;
968   if (dbms_errno)
969     return mr_errcode;
970
971   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
972     {
973       qtype = argv[1];
974       id = *(int *)argv[2];
975       quota = atoi(argv[3]);
976       sprintf(incr_qual, "q.filsys_id = %d", fs);
977     }
978   else
979     {
980       qtype = "USER";
981       id = *(int *)argv[1];
982       quota = atoi(argv[2]);
983       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
984               "q.entity_id = %d", fs, qtype, id);
985     }
986
987   /* quota case of incremental_{before|after} only looks at slot 1 */
988   incr_argv[1] = qtype;
989
990   /* Follows one of many possible gross hacks to fix these particular
991    * conflicts between what is possible in the query table and what
992    * is possible in SQL.
993    */
994   if (q->type == APPEND)
995     {
996       incremental_clear_before();
997       EXEC SQL INSERT INTO quota
998         (filsys_id, type, entity_id, quota, phys_id)
999         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1000       incremental_after(table, incr_qual, incr_argv);
1001     }
1002   else
1003     {
1004       incremental_before(table, incr_qual, incr_argv);
1005       EXEC SQL UPDATE quota SET quota = :quota
1006         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1007       status = mr_errcode;
1008       incremental_after(table, incr_qual, incr_argv);
1009     }
1010
1011   if (dbms_errno)
1012     return mr_errcode;
1013   flush_name(argv[0], table);
1014   if (q->type == APPEND)
1015     {
1016       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1017         WHERE table_name = :tname;
1018     }
1019   else
1020     {
1021       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1022         WHERE table_name = :tname;
1023     }
1024
1025   /* Proceed with original followup */
1026   who = cl->client_id;
1027   entity = cl->entity;
1028
1029   EXEC SQL UPDATE quota
1030     SET modtime = SYSDATE, modby = :who, modwith = :entity
1031     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1032   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1033     WHERE nfsphys_id = :physid;
1034   if (dbms_errno)
1035     return mr_errcode;
1036   return MR_SUCCESS;
1037 }
1038
1039
1040 /* Necessitated by the requirement of a correlation name by the incremental
1041  * routines, since query table deletes don't provide one.
1042  */
1043 int followup_dqot(struct query *q, char **argv, client *cl)
1044 {
1045   char *qtype;
1046   int id, fs, table;
1047   char *incr_argv[2];
1048   EXEC SQL BEGIN DECLARE SECTION;
1049   char incr_qual[80], *tname;
1050   EXEC SQL END DECLARE SECTION;
1051
1052   table = q->rtable;
1053   tname = table_name[table];
1054   fs = *(int *)argv[0];
1055   if (!strcmp(q->shortname, "dqot"))
1056     {
1057       qtype = argv[1];
1058       id = *(int *)argv[2];
1059     }
1060   else
1061     {
1062       qtype = "USER";
1063       id = *(int *)argv[1];
1064     }
1065   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1066           fs, qtype, id);
1067
1068   /* quota case of incremental_{before|after} only looks at slot 1 */
1069   incr_argv[1] = qtype;
1070
1071   incremental_before(table, incr_qual, incr_argv);
1072   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1073     AND q.entity_id = :id;
1074   incremental_clear_after();
1075
1076   if (dbms_errno)
1077     return mr_errcode;
1078   flush_name(argv[0], table);
1079
1080   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1081     WHERE table_name = :tname;
1082   return MR_SUCCESS;
1083 }
1084
1085
1086 int followup_gpce(struct query *q, struct save_queue *sq, struct validate *v,
1087                   int (*action)(int, char *[], void *), void *actarg,
1088                   client *cl)
1089 {
1090   int i, j;
1091   char **argv;
1092   int id, status;
1093
1094   i = q->vcnt - 2;
1095   while (sq_get_data(sq, &argv))
1096     {
1097       id = atoi(argv[PCAP_QSERVER]);
1098       status = id_to_name(id, MACHINE_TABLE, &argv[PCAP_QSERVER]);
1099       if (status)
1100         return status;
1101       id = atoi(argv[i]);
1102       if (id > 0)
1103         status = id_to_name(id, USERS_TABLE, &argv[i]);
1104       else
1105         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1106       if (status && status != MR_NO_MATCH)
1107         return status;
1108       (*action)(q->vcnt, argv, actarg);
1109       for (j = 0; j < q->vcnt; j++)
1110         free(argv[j]);
1111       free(argv);
1112     }
1113   sq_destroy(sq);
1114   return MR_SUCCESS;
1115 }
1116
1117
1118 /* followup_gzcl:
1119  */
1120
1121 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1122                   int (*action)(int, char *[], void *), void *actarg,
1123                   client *cl)
1124 {
1125   int id, i, status;
1126   char **argv;
1127
1128   while (sq_get_data(sq, &argv))
1129     {
1130       mr_trim_args(q->vcnt, argv);
1131
1132       id = atoi(argv[i = q->vcnt - 2]);
1133       if (id > 0)
1134         status = id_to_name(id, USERS_TABLE, &argv[i]);
1135       else
1136         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1137       if (status && status != MR_NO_MATCH)
1138         return status;
1139
1140       for (i = 1; i < 8; i += 2)
1141         {
1142           id = atoi(argv[i + 1]);
1143           if (!strcmp(argv[i], "LIST"))
1144             status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1145           else if (!strcmp(argv[i], "USER"))
1146             status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1147           else if (!strcmp(argv[i], "KERBEROS"))
1148             status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1149           else if (!strcmp(argv[i], "NONE"))
1150             {
1151               status = 0;
1152               free(argv[i + 1]);
1153               argv[i + 1] = strdup("NONE");
1154             }
1155           else
1156             {
1157               status = 0;
1158               free(argv[i + 1]);
1159               argv[i + 1] = strdup("???");
1160             }
1161           if (status && status != MR_NO_MATCH)
1162             return status;
1163         }
1164
1165       /* send the data */
1166       (*action)(q->vcnt, argv, actarg);
1167
1168       /* free saved data */
1169       for (i = 0; i < q->vcnt; i++)
1170         free(argv[i]);
1171       free(argv);
1172     }
1173   sq_destroy(sq);
1174   return MR_SUCCESS;
1175 }
1176
1177
1178 /* followup_gsha:
1179  */
1180
1181 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1182                   int (*action)(int, char *[], void *), void *actarg,
1183                   client *cl)
1184 {
1185   char **argv;
1186   int i, id, status;
1187
1188   while (sq_get_data(sq, &argv))
1189     {
1190       mr_trim_args(q->vcnt, argv);
1191
1192       id = atoi(argv[4]);
1193       if (id > 0)
1194         status = id_to_name(id, USERS_TABLE, &argv[4]);
1195       else
1196         status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1197       if (status && status != MR_NO_MATCH)
1198         return status;
1199
1200       id = atoi(argv[2]);
1201       if (!strcmp(argv[1], "LIST"))
1202         status = id_to_name(id, LIST_TABLE, &argv[2]);
1203       else if (!strcmp(argv[1], "USER"))
1204         status = id_to_name(id, USERS_TABLE, &argv[2]);
1205       else if (!strcmp(argv[1], "KERBEROS"))
1206         status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1207       else if (!strcmp(argv[1], "NONE"))
1208         {
1209           status = 0;
1210           free(argv[2]);
1211           argv[2] = strdup("NONE");
1212         }
1213       else
1214         {
1215           status = 0;
1216           free(argv[2]);
1217           argv[2] = strdup("???");
1218         }
1219       if (status && status != MR_NO_MATCH)
1220         return status;
1221
1222       /* send the data */
1223       (*action)(q->vcnt, argv, actarg);
1224
1225       /* free saved data */
1226       for (i = 0; i < q->vcnt; i++)
1227         free(argv[i]);
1228       free(argv);
1229     }
1230   sq_destroy(sq);
1231   return MR_SUCCESS;
1232 }
1233
1234
1235 int _sdl_followup(struct query *q, char *argv[], client *cl)
1236 {
1237   int i;
1238   i = atoi(argv[0]);
1239   log_flags = i;
1240
1241   if (i & LOG_SQL)
1242     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1243   else
1244     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1245
1246   return MR_SUCCESS;
1247 }
1248
1249
1250 static void hex_dump(unsigned char *p)
1251 {
1252   fprintf(stderr, "Size: %d\n", strlen(p));
1253   while (strlen(p) >= 8)
1254     {
1255       fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1256               p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
1257       p += 8;
1258     }
1259   switch (strlen(p))
1260     {
1261     case 7:
1262       fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x\n",
1263               p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
1264       break;
1265     case 6:
1266       fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n",
1267               p[0], p[1], p[2], p[3], p[4], p[5]);
1268       break;
1269     case 5:
1270       fprintf(stderr, "%02x %02x %02x %02x %02x\n",
1271                 p[0], p[1], p[2], p[3], p[4]);
1272       break;
1273     case 4:
1274       fprintf(stderr, "%02x %02x %02x %02x\n",
1275               p[0], p[1], p[2], p[3]);
1276         break;
1277     case 3:
1278       fprintf(stderr, "%02x %02x %02x\n",
1279               p[0], p[1], p[2]);
1280       break;
1281     case 2:
1282       fprintf(stderr, "%02x %02x\n",
1283               p[0], p[1]);
1284       break;
1285     case 1:
1286       fprintf(stderr, "%02x\n",
1287               p[0]);
1288       break;
1289     default:
1290       return;
1291     }
1292 }
This page took 0.135207 seconds and 5 git commands to generate.