]> andersk Git - moira.git/blob - server/qfollow.pc
add uprn, apsv, gpsv, upsv, dpsv
[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
564 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
565  * type in argv[1].  Then completes the upcall to the user.
566  *
567  * argv[2] is of the form "123:234" where the first integer is the machine
568  * ID if it is a pop box, and the second is the string ID if it is an SMTP
569  * box.  argv[1] should be "POP", "SMTP", or "NONE".  Boxes of type NONE
570  * are skipped.
571  */
572
573 int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v,
574                   int (*action)(int, char *[], void *), void *actarg,
575                   client *cl)
576 {
577   char **argv;
578   char *ptype, *p;
579   int mid, sid, status, i;
580
581   /* for each row */
582   while (sq_get_data(sq, &argv))
583     {
584       mr_trim_args(2, argv);
585       ptype = argv[1];
586       p = strchr(argv[2], ':');
587       *p++ = '\0';
588       mid = atoi(argv[2]);
589       sid = atoi(p);
590
591       if (!strcmp(ptype, "POP"))
592         {
593           status = id_to_name(mid, MACHINE_TABLE, &argv[2]);
594           if (status == MR_NO_MATCH)
595             return MR_MACHINE;
596         }
597       else if (!strcmp(ptype, "SMTP"))
598         {
599           status = id_to_name(sid, STRINGS_TABLE, &argv[2]);
600           if (status == MR_NO_MATCH)
601             return MR_STRING;
602         }
603       else /* ptype == "NONE" */
604         goto skip;
605       if (status)
606         return status;
607
608       if (!strcmp(q->shortname, "gpob"))
609         {
610           sid = atoi(argv[4]);
611           if (sid > 0)
612             status = id_to_name(sid, USERS_TABLE, &argv[4]);
613           else
614             status = id_to_name(-sid, STRINGS_TABLE, &argv[4]);
615         }
616       if (status && status != MR_NO_MATCH)
617         return status;
618
619       (*action)(q->vcnt, argv, actarg);
620     skip:
621       /* free saved data */
622       for (i = 0; i < q->vcnt; i++)
623         free(argv[i]);
624       free(argv);
625     }
626
627   sq_destroy(sq);
628   return MR_SUCCESS;
629 }
630
631
632 /* followup_gsnt: fix the ace_name in argv[7].  argv[6] will contain the
633  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[7] into the
634  * proper name based on the type, and repace that string in the argv.
635  * Also fixes the modby field by called followup_fix_modby.
636  */
637
638 int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v,
639                   int (*action)(int, char *[], void *), void *actarg,
640                   client *cl)
641 {
642   char **argv, *type;
643   int id, i, idx, status;
644
645   idx = 8;
646
647   while (sq_get_data(sq, &argv))
648     {
649       mr_trim_args(q->vcnt, argv);
650
651       id = atoi(argv[i = q->vcnt - 2]);
652       if (id > 0)
653         status = id_to_name(id, USERS_TABLE, &argv[i]);
654       else
655         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
656       if (status && status != MR_NO_MATCH)
657         return status;
658
659       id = atoi(argv[idx]);
660       type = argv[idx - 1];
661
662       if (!strcmp(type, "LIST"))
663         status = id_to_name(id, LIST_TABLE, &argv[idx]);
664       else if (!strcmp(type, "USER"))
665         status = id_to_name(id, USERS_TABLE, &argv[idx]);
666       else if (!strcmp(type, "KERBEROS"))
667         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
668       else if (!strcmp(type, "NONE"))
669         {
670           status = 0;
671           free(argv[idx]);
672           argv[idx] = xstrdup("NONE");
673         }
674       else
675         {
676           status = 0;
677           free(argv[idx]);
678           argv[idx] = xstrdup("???");
679         }
680       if (status && status != MR_NO_MATCH)
681         return status;
682
683       /* send the data */
684       (*action)(q->vcnt, argv, actarg);
685
686       /* free saved data */
687       for (i = 0; i < q->vcnt; i++)
688         free(argv[i]);
689       free(argv);
690     }
691
692   sq_destroy(sq);
693   return MR_SUCCESS;
694 }
695
696
697 /* followup_ghst: fix the ace_name in argv[12].  argv[11] will contain the
698  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[12] into the
699  * proper name based on the type, and repace that string in the argv.
700  * Also fixes the modby field by called followup_fix_modby.
701  */
702
703 int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v,
704                   int (*action)(int, char *[], void *), void *actarg,
705                   client *cl)
706 {
707   char **argv, *type;
708   int id, i, idx, status;
709
710   while (sq_get_data(sq, &argv))
711     {
712       mr_trim_args(q->vcnt, argv);
713
714       id = atoi(argv[i = q->vcnt - 2]);
715       if (id > 0)
716         status = id_to_name(id, USERS_TABLE, &argv[i]);
717       else
718         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
719       if (status && status != MR_NO_MATCH)
720         return status;
721
722       id = atoi(argv[13]);
723       status = id_to_name(id, STRINGS_TABLE, &argv[13]);
724       if (status)
725         return status;
726       id = atoi(argv[14]);
727       status = id_to_name(id, STRINGS_TABLE, &argv[14]);
728       if (status)
729         return status;
730       id = atoi(argv[16]);
731       if (id < 0)
732         status = id_to_name(-id, STRINGS_TABLE, &argv[16]);
733       else
734         status = id_to_name(id, USERS_TABLE, &argv[16]);
735       if (status && status != MR_NO_MATCH)
736         return status;
737
738       idx = 12;
739       id = atoi(argv[idx]);
740       type = strtrim(argv[idx - 1]);
741
742       if (!strcmp(type, "LIST"))
743         status = id_to_name(id, LIST_TABLE, &argv[idx]);
744       else if (!strcmp(type, "USER"))
745         status = id_to_name(id, USERS_TABLE, &argv[idx]);
746       else if (!strcmp(type, "KERBEROS"))
747         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
748       else if (!strcmp(type, "NONE"))
749         {
750           status = 0;
751           free(argv[idx]);
752           argv[idx] = xstrdup("NONE");
753         }
754       else
755         {
756           status = 0;
757           free(argv[idx]);
758           argv[idx] = xstrdup("???");
759         }
760       if (status && status != MR_NO_MATCH)
761         return status;
762
763       /* send the data */
764       (*action)(q->vcnt, argv, actarg);
765
766       /* free saved data */
767       for (i = 0; i < q->vcnt; i++)
768         free(argv[i]);
769       free(argv);
770     }
771
772   sq_destroy(sq);
773   return MR_SUCCESS;
774 }
775
776
777 /* followup_glin: fix the ace_name in argv[8].  argv[7] will contain the
778  * ace_type: "LIST", "USER", or "NONE".  Decode the id in argv[8] into the
779  * proper name based on the type, and repace that string in the argv.
780  * Also fixes the modby field by called followup_fix_modby.
781  */
782
783 int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
784                   int (*action)(int, char *[], void *), void *actarg,
785                   client *cl)
786 {
787   char **argv, *type;
788   int id, i, idx, status;
789
790   idx = 8;
791   if (!strcmp(q->shortname, "gsin"))
792     idx = 12;
793
794   while (sq_get_data(sq, &argv))
795     {
796       mr_trim_args(q->vcnt, argv);
797
798       id = atoi(argv[i = q->vcnt - 2]);
799       if (id > 0)
800         status = id_to_name(id, USERS_TABLE, &argv[i]);
801       else
802         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
803       if (status && status != MR_NO_MATCH)
804         return status;
805
806       id = atoi(argv[idx]);
807       type = argv[idx - 1];
808
809       if (!strcmp(type, "LIST"))
810         status = id_to_name(id, LIST_TABLE, &argv[idx]);
811       else if (!strcmp(type, "USER"))
812         status = id_to_name(id, USERS_TABLE, &argv[idx]);
813       else if (!strcmp(type, "KERBEROS"))
814         status = id_to_name(id, STRINGS_TABLE, &argv[idx]);
815       else if (!strcmp(type, "NONE"))
816         {
817           status = 0;
818           free(argv[idx]);
819           argv[idx] = xstrdup("NONE");
820         }
821       else
822         {
823           status = 0;
824           free(argv[idx]);
825           argv[idx] = xstrdup("???");
826         }
827       if (status && status != MR_NO_MATCH)
828         return status;
829
830       if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1)
831         {
832           argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1);
833           strcpy(argv[6], UNIQUE_GID);
834         }
835
836       /* send the data */
837       (*action)(q->vcnt, argv, actarg);
838
839       /* free saved data */
840       for (i = 0; i < q->vcnt; i++)
841         free(argv[i]);
842       free(argv);
843     }
844
845   sq_destroy(sq);
846   return MR_SUCCESS;
847 }
848
849 int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v,
850                   int (*action)(int, char *[], void *), void *actarg,
851                   client *cl)
852 {
853   char **argv, *type;
854   int id, i, status;
855
856   while (sq_get_data(sq, &argv))
857     {
858       mr_trim_args(q->vcnt, argv);
859
860       id = atoi(argv[PRINTSERVER_OWNER_NAME]);
861       type = argv[PRINTSERVER_OWNER_TYPE];
862
863       if (!strcmp(type, "LIST"))
864         status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
865       else if (!strcmp(type, "USER"))
866         status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
867       else if (!strcmp(type, "KERBEROS"))
868         status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]);
869       else
870         {
871           status = 0;
872           free(argv[PRINTSERVER_OWNER_NAME]);
873           argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE");
874         }
875       if (status && status != MR_NO_MATCH)
876         return status;
877     }
878
879   return followup_fix_modby(q, sq, v, action, actarg, cl);
880 }
881   
882
883 /* followup_gqot: Fix the entity name, directory name & modby fields
884  *   argv[0] = filsys_id
885  *   argv[1] = type
886  *   argv[2] = entity_id
887  *   argv[3] = ascii(quota)
888  */
889
890 int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v,
891                   int (*action)(int, char *[], void *), void *actarg,
892                   client *cl)
893 {
894   int j;
895   char **argv;
896   EXEC SQL BEGIN DECLARE SECTION;
897   int id;
898   char *name, *label;
899   EXEC SQL END DECLARE SECTION;
900   int status, idx;
901
902   if (!strcmp(q->name, "get_quota") ||
903       !strcmp(q->name, "get_quota_by_filesys"))
904     idx = 4;
905   else
906     idx = 3;
907   while (sq_get_data(sq, &argv))
908     {
909       if (idx == 4)
910         {
911           switch (argv[1][0])
912             {
913             case 'U':
914               status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]);
915               break;
916             case 'G':
917             case 'L':
918               status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]);
919               break;
920             case 'A':
921               free(argv[2]);
922               argv[2] = xstrdup("system:anyuser");
923               break;
924             default:
925               id = atoi(argv[2]);
926               argv[2] = xmalloc(8);
927               sprintf(argv[2], "%d", id);
928             }
929         }
930       id = atoi(argv[idx]);
931       free(argv[idx]);
932       argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE);
933       name = argv[idx];
934       name[0] = '\0';
935       if (id == 0)
936         {
937           label = argv[0];
938           EXEC SQL SELECT name INTO :name FROM filesys
939             WHERE label = :label;
940         }
941       else
942         {
943           EXEC SQL SELECT dir INTO :name FROM nfsphys
944             WHERE nfsphys_id = :id;
945         }
946       if (sqlca.sqlerrd[2] != 1)
947         sprintf(argv[idx], "#%d", id);
948
949       id = atoi(argv[idx + 3]);
950       if (id > 0)
951         status = id_to_name(id, USERS_TABLE, &argv[idx + 3]);
952       else
953         status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]);
954       if (status && status != MR_NO_MATCH)
955         return status;
956       (*action)(q->vcnt, argv, actarg);
957       for (j = 0; j < q->vcnt; j++)
958         free(argv[j]);
959       free(argv);
960     }
961   sq_destroy(sq);
962   return MR_SUCCESS;
963 }
964
965
966 /* followup_aqot: Add allocation to nfsphys after creating quota.
967  *   argv[0] = filsys_id
968  *   argv[1] = type if "add_quota" or "update_quota"
969  *   argv[2 or 1] = id
970  *   argv[3 or 2] = ascii(quota)
971  */
972
973 int followup_aqot(struct query *q, char *argv[], client *cl)
974 {
975   EXEC SQL BEGIN DECLARE SECTION;
976   int quota, id, fs, who, physid, table;
977   char *entity, *qtype, *tname;
978   EXEC SQL END DECLARE SECTION;
979   char incr_qual[60];
980   char *incr_argv[2];
981   int status;
982
983   table = q->rtable;
984   tname = table_name[table];
985   fs = *(int *)argv[0];
986   EXEC SQL SELECT phys_id INTO :physid FROM filesys
987     WHERE filsys_id = :fs;
988   if (dbms_errno)
989     return mr_errcode;
990
991   if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot"))
992     {
993       qtype = argv[1];
994       id = *(int *)argv[2];
995       quota = atoi(argv[3]);
996       sprintf(incr_qual, "q.filsys_id = %d", fs);
997     }
998   else
999     {
1000       qtype = "USER";
1001       id = *(int *)argv[1];
1002       quota = atoi(argv[2]);
1003       sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND "
1004               "q.entity_id = %d", fs, qtype, id);
1005     }
1006
1007   /* quota case of incremental_{before|after} only looks at slot 1 */
1008   incr_argv[1] = qtype;
1009
1010   /* Follows one of many possible gross hacks to fix these particular
1011    * conflicts between what is possible in the query table and what
1012    * is possible in SQL.
1013    */
1014   if (q->type == APPEND)
1015     {
1016       incremental_clear_before();
1017       EXEC SQL INSERT INTO quota
1018         (filsys_id, type, entity_id, quota, phys_id)
1019         VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid);
1020       incremental_after(table, incr_qual, incr_argv);
1021     }
1022   else
1023     {
1024       incremental_before(table, incr_qual, incr_argv);
1025       EXEC SQL UPDATE quota SET quota = :quota
1026         WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id;
1027       status = mr_errcode;
1028       incremental_after(table, incr_qual, incr_argv);
1029     }
1030
1031   if (dbms_errno)
1032     return mr_errcode;
1033   flush_name(argv[0], table);
1034   if (q->type == APPEND)
1035     {
1036       EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE
1037         WHERE table_name = :tname;
1038     }
1039   else
1040     {
1041       EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE
1042         WHERE table_name = :tname;
1043     }
1044
1045   /* Proceed with original followup */
1046   who = cl->client_id;
1047   entity = cl->entity;
1048
1049   EXEC SQL UPDATE quota
1050     SET modtime = SYSDATE, modby = :who, modwith = :entity
1051     WHERE filsys_id = :fs and type = :qtype and entity_id = :id;
1052   EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota
1053     WHERE nfsphys_id = :physid;
1054   if (dbms_errno)
1055     return mr_errcode;
1056   return MR_SUCCESS;
1057 }
1058
1059
1060 /* Necessitated by the requirement of a correlation name by the incremental
1061  * routines, since query table deletes don't provide one.
1062  */
1063 int followup_dqot(struct query *q, char **argv, client *cl)
1064 {
1065   char *qtype;
1066   int id, fs, table;
1067   char *incr_argv[2];
1068   EXEC SQL BEGIN DECLARE SECTION;
1069   char incr_qual[80], *tname;
1070   EXEC SQL END DECLARE SECTION;
1071
1072   table = q->rtable;
1073   tname = table_name[table];
1074   fs = *(int *)argv[0];
1075   if (!strcmp(q->shortname, "dqot"))
1076     {
1077       qtype = argv[1];
1078       id = *(int *)argv[2];
1079     }
1080   else
1081     {
1082       qtype = "USER";
1083       id = *(int *)argv[1];
1084     }
1085   sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d",
1086           fs, qtype, id);
1087
1088   /* quota case of incremental_{before|after} only looks at slot 1 */
1089   incr_argv[1] = qtype;
1090
1091   incremental_before(table, incr_qual, incr_argv);
1092   EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype
1093     AND q.entity_id = :id;
1094   incremental_clear_after();
1095
1096   if (dbms_errno)
1097     return mr_errcode;
1098   flush_name(argv[0], table);
1099
1100   EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE
1101     WHERE table_name = :tname;
1102   return MR_SUCCESS;
1103 }
1104
1105 /* followup_gzcl:
1106  */
1107
1108 int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v,
1109                   int (*action)(int, char *[], void *), void *actarg,
1110                   client *cl)
1111 {
1112   int id, i, status;
1113   char **argv;
1114
1115   while (sq_get_data(sq, &argv))
1116     {
1117       mr_trim_args(q->vcnt, argv);
1118
1119       id = atoi(argv[i = q->vcnt - 2]);
1120       if (id > 0)
1121         status = id_to_name(id, USERS_TABLE, &argv[i]);
1122       else
1123         status = id_to_name(-id, STRINGS_TABLE, &argv[i]);
1124       if (status && status != MR_NO_MATCH)
1125         return status;
1126
1127       for (i = 1; i < 8; i += 2)
1128         {
1129           id = atoi(argv[i + 1]);
1130           if (!strcmp(argv[i], "LIST"))
1131             status = id_to_name(id, LIST_TABLE, &argv[i + 1]);
1132           else if (!strcmp(argv[i], "USER"))
1133             status = id_to_name(id, USERS_TABLE, &argv[i + 1]);
1134           else if (!strcmp(argv[i], "KERBEROS"))
1135             status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]);
1136           else if (!strcmp(argv[i], "NONE"))
1137             {
1138               status = 0;
1139               free(argv[i + 1]);
1140               argv[i + 1] = xstrdup("NONE");
1141             }
1142           else
1143             {
1144               status = 0;
1145               free(argv[i + 1]);
1146               argv[i + 1] = xstrdup("???");
1147             }
1148           if (status && status != MR_NO_MATCH)
1149             return status;
1150         }
1151
1152       /* send the data */
1153       (*action)(q->vcnt, argv, actarg);
1154
1155       /* free saved data */
1156       for (i = 0; i < q->vcnt; i++)
1157         free(argv[i]);
1158       free(argv);
1159     }
1160   sq_destroy(sq);
1161   return MR_SUCCESS;
1162 }
1163
1164
1165 /* followup_gsha:
1166  */
1167
1168 int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v,
1169                   int (*action)(int, char *[], void *), void *actarg,
1170                   client *cl)
1171 {
1172   char **argv;
1173   int i, id, status;
1174
1175   while (sq_get_data(sq, &argv))
1176     {
1177       mr_trim_args(q->vcnt, argv);
1178
1179       id = atoi(argv[4]);
1180       if (id > 0)
1181         status = id_to_name(id, USERS_TABLE, &argv[4]);
1182       else
1183         status = id_to_name(-id, STRINGS_TABLE, &argv[4]);
1184       if (status && status != MR_NO_MATCH)
1185         return status;
1186
1187       id = atoi(argv[2]);
1188       if (!strcmp(argv[1], "LIST"))
1189         status = id_to_name(id, LIST_TABLE, &argv[2]);
1190       else if (!strcmp(argv[1], "USER"))
1191         status = id_to_name(id, USERS_TABLE, &argv[2]);
1192       else if (!strcmp(argv[1], "KERBEROS"))
1193         status = id_to_name(id, STRINGS_TABLE, &argv[2]);
1194       else if (!strcmp(argv[1], "NONE"))
1195         {
1196           status = 0;
1197           free(argv[2]);
1198           argv[2] = xstrdup("NONE");
1199         }
1200       else
1201         {
1202           status = 0;
1203           free(argv[2]);
1204           argv[2] = xstrdup("???");
1205         }
1206       if (status && status != MR_NO_MATCH)
1207         return status;
1208
1209       /* send the data */
1210       (*action)(q->vcnt, argv, actarg);
1211
1212       /* free saved data */
1213       for (i = 0; i < q->vcnt; i++)
1214         free(argv[i]);
1215       free(argv);
1216     }
1217   sq_destroy(sq);
1218   return MR_SUCCESS;
1219 }
1220
1221
1222 int _sdl_followup(struct query *q, char *argv[], client *cl)
1223 {
1224   if (atoi(argv[0]))
1225     EXEC SQL ALTER SESSION SET SQL_TRACE TRUE;
1226   else
1227     EXEC SQL ALTER SESSION SET SQL_TRACE FALSE;
1228
1229   return MR_SUCCESS;
1230 }
1231
1232
1233 int trigger_dcm(struct query *q, char *argv[], client *cl)
1234 {
1235   pid_t pid;
1236   char prog[MAXPATHLEN];
1237
1238   sprintf(prog, "%s/startdcm", BIN_DIR);
1239   pid = vfork();
1240   switch (pid)
1241     {
1242     case 0:
1243       execl(prog, "startdcm", 0);
1244       exit(1);
1245
1246     case -1:
1247       return errno;
1248
1249     default:
1250       return MR_SUCCESS;
1251     }
1252 }
This page took 0.13236 seconds and 5 git commands to generate.