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