]> andersk Git - moira.git/blob - server/qsetup.dc
mucked with host table authorization checks...
[moira.git] / server / qsetup.dc
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_qsupport_dc = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include "query.h"
18 #include "mr_server.h"
19 #include <ctype.h>
20 #ifdef GDSS
21 #include "gdss.h"
22 #endif /* GDSS */
23 EXEC SQL INCLUDE sqlca;
24 EXEC SQL INCLUDE sqlda;
25 #include "qrtn.h"
26
27 extern char *whoami, *strsave();
28 extern int ingres_errno, mr_errcode;
29
30 EXEC SQL BEGIN DECLARE SECTION;
31 extern char stmt_buf[];
32 EXEC SQL END DECLARE SECTION;
33
34 EXEC SQL WHENEVER SQLERROR CALL ingerr;
35
36
37 /* Setup Routines */
38
39 /* Setup routine for add_user
40  *
41  * Inputs: argv[0] - login
42  *         argv[1] - uid
43  *
44  * Description:
45  *
46  * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
47  * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
48  */
49
50 setup_ausr(q, argv, cl)
51     struct query *q;
52     register char *argv[];
53     client *cl;
54 {
55     int row;
56     EXEC SQL BEGIN DECLARE SECTION;
57     int nuid;
58     EXEC SQL END DECLARE SECTION;
59
60     if (!strcmp(q->shortname, "uusr") || !strcmp(q->shortname, "uuac"))
61       row = 2;
62     else
63       row = 1;
64     if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1) {
65         if (set_next_object_id("uid", "users", 1))
66           return(MR_INGRES_ERR);
67         EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'uid';
68         if (sqlca.sqlerrd[2] != 1)
69           return(MR_INTERNAL);
70         sprintf(argv[row], "%d", nuid);
71     }
72
73     if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[row]) == -1) {
74         sprintf(argv[0], "#%s", argv[row]);
75     }
76
77     if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
78       return(mr_errcode);
79
80     return(MR_SUCCESS);
81 }
82
83
84 /* setup_dusr - verify that the user is no longer being referenced
85  * and may safely be deleted.
86  */
87
88 int setup_dusr(q, argv)
89     struct query *q;
90     char **argv;
91 {
92     EXEC SQL BEGIN DECLARE SECTION;
93     int flag, id, cnt;
94     EXEC SQL END DECLARE SECTION;
95
96     id = *(int *)argv[0];
97
98     /* For now, only allow users to be deleted if their status is 0 */
99     EXEC SQL REPEATED SELECT status INTO :flag FROM users
100       WHERE users_id = :id;
101     if (flag != 0 && flag != 4)
102       return(MR_IN_USE);
103
104     EXEC SQL REPEATED DELETE FROM quota WHERE entity_id = :id AND type='USER';
105     EXEC SQL REPEATED DELETE FROM krbmap WHERE users_id = :id;
106     EXEC SQL REPEATED SELECT COUNT(member_id) INTO :cnt FROM imembers
107       WHERE member_id = :id AND member_type = 'USER';
108     if (cnt > 0)
109         return(MR_IN_USE);
110     EXEC SQL REPEATED SELECT COUNT(label) INTO :cnt FROM filesys 
111         WHERE owner = :id;
112     if (cnt > 0)
113         return(MR_IN_USE);
114     EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM list
115       WHERE acl_id = :id AND acl_type = 'USER';
116     if (cnt > 0)
117         return(MR_IN_USE);
118     EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM servers
119       WHERE acl_id = :id AND acl_type = 'USER';
120     if (cnt > 0)
121         return(MR_IN_USE);
122     EXEC SQL REPEATED SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
123       WHERE acl_id = :id AND acl_type = 'USER';
124     if (cnt > 0)
125         return(MR_IN_USE);
126     if (ingres_errno)
127         return(mr_errcode);
128     return(MR_SUCCESS);
129 }
130
131
132 /* setup_spop: verify that there is already a valid POP machine_id in the
133  * pop_id field.  Also take care of keeping track of the post office usage.
134  */
135 int setup_spop(q, argv)
136 struct query *q;
137 char **argv;
138 {
139     EXEC SQL BEGIN DECLARE SECTION;
140     int id, mid, flag;
141     char type[9];
142     EXEC SQL END DECLARE SECTION;
143
144     id = *(int *)argv[0];
145     EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :mid FROM users
146       WHERE users_id = :id;
147     if(sqlca.sqlerrd[2] = 0)
148       return(MR_MACHINE);
149     EXEC SQL REPEATED SELECT mach_id INTO :mid FROM machine
150       WHERE mach_id = :mid;
151     if (sqlca.sqlerrd[2] = 0)
152       return(MR_MACHINE);
153     if (strcmp(strtrim(type), "POP"))
154       set_pop_usage(mid, 1);
155     return(MR_SUCCESS);
156 }
157
158
159 /* setup_dpob:  Take care of keeping track of the post office usage.
160  */
161 int setup_dpob(q, argv)
162      struct query *q;
163      char **argv;
164 {
165     EXEC SQL BEGIN DECLARE SECTION;
166     int id, user;
167     char type[9];
168     EXEC SQL END DECLARE SECTION;
169
170     user = *(int *)argv[0];
171     EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :id FROM users
172       WHERE users_id = :user;
173     if (ingres_errno) return(mr_errcode);
174
175     if (!strcmp(strtrim(type), "POP"))
176       set_pop_usage(id, -1);
177     return(MR_SUCCESS);
178 }
179
180
181 /* setup_dmac - verify that the machine is no longer being referenced
182  * and may safely be deleted.
183  */
184
185 int setup_dmac(q, argv)
186     struct query *q;
187     char **argv;
188 {
189     EXEC SQL BEGIN DECLARE SECTION;
190     int flag, id, cnt;
191     EXEC SQL END DECLARE SECTION;
192
193     id = *(int *)argv[0];
194
195     EXEC SQL REPEATED SELECT status INTO :flag FROM machine
196       WHERE mach_id = :id;
197     if (flag != 3)
198       return(MR_IN_USE);
199     EXEC SQL REPEATED SELECT COUNT(login) INTO :cnt FROM users
200       WHERE potype='POP' AND pop_id = :id;
201     if (cnt > 0)
202         return(MR_IN_USE);
203     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
204       WHERE mach_id = :id;
205     if (cnt > 0)
206         return(MR_IN_USE);
207     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
208       WHERE mach_id = :id;
209     if (cnt > 0)
210         return(MR_IN_USE);
211     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
212       WHERE mach_id = :id;
213     if (cnt > 0)
214         return(MR_IN_USE);
215     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM printcap
216       WHERE mach_id = :id;
217     if (cnt > 0)
218         return(MR_IN_USE);
219     EXEC SQL REPEATED SELECT COUNT(quotaserver) INTO :cnt FROM printcap
220       WHERE quotaserver = :id;
221     if (cnt > 0)
222         return(MR_IN_USE);
223     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM palladium
224       WHERE mach_id = :id;
225     if (cnt > 0)
226         return(MR_IN_USE);
227
228     EXEC SQL REPEATED DELETE FROM mcmap WHERE mach_id = :id;
229     if (ingres_errno) return(mr_errcode);
230     return(MR_SUCCESS);
231 }
232
233
234 /* setup_dsnt - verify that the subnet is no longer being referenced
235  * and may safely be deleted.
236  */
237
238 int setup_dsnt(q, argv)
239     struct query *q;
240     char **argv;
241 {
242     EXEC SQL BEGIN DECLARE SECTION;
243     int flag, id, cnt = 0;
244     EXEC SQL END DECLARE SECTION;
245
246     id = *(int *)argv[0];
247     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM machine
248       WHERE snet_id = :id;
249     if (cnt > 0)
250         return(MR_IN_USE);
251     return(MR_SUCCESS);
252 }
253
254
255 /* setup_dclu - verify that the cluster is no longer being referenced
256  * and may safely be deleted.
257  */
258
259 int setup_dclu(q, argv)
260     struct query *q;
261     char **argv;
262 {
263     EXEC SQL BEGIN DECLARE SECTION;
264     int id, cnt;
265     EXEC SQL END DECLARE SECTION;
266
267     id = *(int *)argv[0];
268     EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM mcmap
269       WHERE clu_id = :id;
270     if (cnt > 0)
271         return(MR_IN_USE);
272     EXEC SQL REPEATED SELECT COUNT(clu_id) INTO :cnt FROM svc
273       WHERE clu_id = :id;
274     if (cnt > 0)
275         return(MR_IN_USE);
276     if (ingres_errno)
277         return(mr_errcode);
278     return(MR_SUCCESS);
279 }
280
281
282 /* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
283  * a new gid and put it in argv[6].  Otherwise if argv[6] is UNIQUE_ID but
284  * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
285  * a -1 there.  Remember that this is also used for ulis, with the indexes
286  * at 6 & 7.  Also check that the list name does not contain uppercase
287  * characters, control characters, @, or :.
288  */
289
290 static int badlistchars[] = {
291     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
292     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
293     1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
294     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
295     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
296     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, /* P - _ */
297     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
298     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
299     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
300     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
301     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
302     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
303     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
304     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
305     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
306     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
307 };
308
309 int setup_alis(q, argv, cl)
310     struct query *q;
311     char *argv[];
312     client *cl;
313 {
314     EXEC SQL BEGIN DECLARE SECTION;
315     int ngid;
316     EXEC SQL END DECLARE SECTION;
317     unsigned char *p;
318     int idx;
319
320     if (!strcmp(q->shortname, "alis"))
321       idx = 0;
322     else if (!strcmp(q->shortname, "ulis"))
323       idx = 1;
324
325     for (p = (unsigned char *) argv[idx]; *p; p++)
326       if (badlistchars[*p])
327         return(MR_BAD_CHAR);
328  
329     if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1) {
330         if (atoi(argv[5 + idx])) {
331             if (set_next_object_id("gid", "list", 1))
332               return(MR_INGRES_ERR);
333             EXEC SQL REPEATED SELECT value INTO :ngid FROM numvalues
334               WHERE name = 'gid';
335             if (ingres_errno) return(mr_errcode);
336             sprintf(argv[6 + idx], "%d", ngid);
337         } else {
338             strcpy(argv[6 + idx], "-1");
339         }
340     }
341
342     if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
343       return(mr_errcode);
344
345     return(MR_SUCCESS);
346 }
347
348
349 /* setup_dlis - verify that the list is no longer being referenced
350  * and may safely be deleted.
351  */
352
353 int setup_dlis(q, argv)
354     struct query *q;
355     char *argv[];
356 {
357     int flag, id, ec;
358
359     id = *(int *)argv[0];
360     sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE member_id = %d AND member_type='LIST'",id);
361     if(ec=mr_select_any(stmt_buf)) {
362         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
363     }
364     
365     sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE list_id = %d",id);
366     if(ec=mr_select_any(stmt_buf)) {
367         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
368     }
369
370     sprintf(stmt_buf,"SELECT label FROM filesys WHERE owners = %d",id);
371     if(ec=mr_select_any(stmt_buf)) {
372         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
373     }
374
375     sprintf(stmt_buf,"SELECT tag FROM capacls WHERE list_id = %d",id);
376     if(ec=mr_select_any(stmt_buf)) {
377         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
378     }
379
380     sprintf(stmt_buf,"SELECT name FROM list WHERE acl_id = %d AND acl_type='LIST' AND list_id != %d",id,id);
381     if(ec=mr_select_any(stmt_buf)) {
382         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
383     }
384
385     sprintf(stmt_buf,"SELECT name FROM servers WHERE acl_id = %d AND acl_type='LIST'",id);
386     if(ec=mr_select_any(stmt_buf)) {
387         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
388     }
389
390     sprintf(stmt_buf,"SELECT entity_id FROM quota WHERE entity_id = %d AND type='GROUP'",id);
391     if(ec=mr_select_any(stmt_buf)) {
392         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
393     }
394  
395     sprintf(stmt_buf,"SELECT acl_id  FROM hostaccess WHERE acl_id = %d AND acl_type='LIST'",id);
396     if(ec=mr_select_any(stmt_buf)) {
397         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
398     }
399
400     sprintf(stmt_buf,"SELECT class FROM zephyr z \
401 WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \
402 OR z.sub_type = 'LIST' AND z.sub_id = %d \
403 OR z.iws_type = 'LIST' AND z.iws_id = %d \
404 OR z.iui_type = 'LIST' AND z.iui_id = %d",id,id,id,id);
405     if(ec=mr_select_any(stmt_buf)) {
406         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
407     }
408
409     return(MR_SUCCESS);
410 }
411
412
413 /* setup_dsin - verify that the service is no longer being referenced
414  * and may safely be deleted.
415  */
416
417 int setup_dsin(q, argv)
418     struct query *q;
419     char **argv;
420 {
421     EXEC SQL BEGIN DECLARE SECTION;     
422     int ec;
423     char *svrname;
424     EXEC SQL END DECLARE SECTION;
425
426     sprintf(stmt_buf,"SELECT service FROM serverhosts WHERE service = UPPERCASE('%s')",argv[0]);
427     if(ec=mr_select_any(stmt_buf)) {
428         if(ec==MR_EXISTS) 
429             return(MR_IN_USE); 
430         else 
431             return(ec);
432     }
433
434     svrname=argv[0];
435     EXEC SQL SELECT inprogress INTO :ec FROM servers 
436       WHERE name=UPPERCASE(:svrname);
437     if(ingres_errno) 
438         return(mr_errcode);
439     if(ec) 
440         return(MR_IN_USE); 
441
442     return(MR_SUCCESS);
443 }
444
445
446 /* setup_dshi - verify that the service-host is no longer being referenced
447  * and may safely be deleted.
448  */
449
450 int setup_dshi(q, argv)
451     struct query *q;
452     char **argv;
453 {
454     EXEC SQL BEGIN DECLARE SECTION;
455     int id, ec;
456     char *svrname;
457     EXEC SQL END DECLARE SECTION;
458
459     svrname=argv[0];
460     id = *(int *)argv[1];
461
462     EXEC SQL SELECT inprogress INTO :ec FROM serverhosts 
463       WHERE service=UPPERCASE(:svrname) AND mach_id = :id;
464     if(ingres_errno) 
465         return(mr_errcode);
466     if(ec) 
467         return(MR_IN_USE); 
468
469
470     return(MR_SUCCESS);
471 }
472
473
474 /**
475  ** setup_add_filesys - verify existance of referenced file systems
476  **
477  ** Inputs:     Add
478  **   argv[1] - type
479  **   argv[2] - mach_id
480  **   argv[3] - name
481  **   argv[5] - access
482  **
483  ** Description:
484  **   - for type = RVD:
485  **        * allow anything
486  **   - for type = NFS:
487  **        * extract directory prefix from name
488  **        * verify mach_id/dir in nfsphys
489  **        * verify access in {r, w, R, W}
490  **
491  **  Side effect: sets variable _var_phys_id to the ID of the physical
492  **     filesystem (nfsphys_id for NFS, 0 for RVD)
493  **
494  ** Errors:
495  **   MR_NFS - specified directory not exported
496  **   MR_FILESYS_ACCESS - invalid filesys access
497  **
498  **/
499
500 EXEC SQL BEGIN DECLARE SECTION;
501 int _var_phys_id;
502 EXEC SQL END DECLARE SECTION;
503
504 setup_afil(q, argv, cl)
505     struct query *q;
506     char *argv[];
507     client *cl;
508 {
509     char *type, *name;
510     int mach_id;
511     EXEC SQL BEGIN DECLARE SECTION;
512     int ok;
513     char ftype[32], *access;
514     EXEC SQL END DECLARE SECTION;
515
516     type = argv[1];
517     mach_id = *(int *)argv[2];
518     name = argv[3];
519     access = argv[5];
520     _var_phys_id = 0;
521
522     sprintf(ftype, "fs_access_%s", type);
523     EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
524         WHERE name = :ftype AND type = 'TYPE' and trans = :access;   
525     if (ingres_errno) return(mr_errcode);
526     if (ok == 0) return(MR_FILESYS_ACCESS);
527
528     if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
529       return(mr_errcode);
530
531     if (!strcmp(type, "NFS"))
532         return (check_nfs(mach_id, name, access));
533
534     return(MR_SUCCESS);
535 }
536
537
538 /* Verify the arguments, depending on the FStype.  Also, if this is an
539  * NFS filesystem, then update any quotas for that filesystem to reflect
540  * the new phys_id.
541  */
542
543 setup_ufil(q, argv, cl)
544     struct query *q;
545     char *argv[];
546     client *cl;
547 {
548     int mach_id, status;
549     char *type, *name;
550     EXEC SQL BEGIN DECLARE SECTION;
551     int fid, total, who, ok;
552     char *entity, ftype[32], *access;
553     short int total_null;
554     EXEC SQL END DECLARE SECTION;
555
556     _var_phys_id = 0;
557     type = argv[2];
558     mach_id = *(int *)argv[3];
559     name = argv[4];
560     access = argv[6];
561     fid = *(int *)argv[0];
562     who = cl->client_id;
563     entity = cl->entity;
564
565     sprintf(ftype, "fs_access_%s", type);
566     EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
567       WHERE name = :ftype AND type='TYPE' AND trans = :access;
568     if (ingres_errno) return(mr_errcode);
569     if (ok == 0) return(MR_FILESYS_ACCESS);
570
571     EXEC SQL SELECT type INTO :ftype FROM filesys
572       WHERE filsys_id = :fid;
573     strtrim(ftype);
574     if (ingres_errno) return(mr_errcode);
575
576     if (!strcmp(type, "NFS")) {
577         status = check_nfs(mach_id, name, access);
578         EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
579           WHERE filsys_id = :fid;
580         if (ingres_errno) return(mr_errcode);
581         return(status);
582     } else if (!strcmp(type, "AFS") && strcmp(ftype, "AFS")) {
583         total = 0;
584         EXEC SQL REPEATED DELETE FROM quota
585           WHERE type = 'ANY' AND filsys_id = :fid;
586         EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
587           WHERE filsys_id = :fid AND phys_id != 0;
588         if (ingres_errno) return(mr_errcode);
589         if (!total_null && (total != 0)) {
590 /*
591  *             append quota (quota = total, filsys_id = fid,
592  *                           phys_id = 0, entity_id = 0, type = "ANY",
593  *                           modtime = "now", modby = who, modwith = entity)
594  */
595             EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
596                                         type, modtime, modby, modwith)
597               VALUES (:total, :fid, 0, 0,
598                       'ANY', 'now', :who, :entity) ;
599             if (ingres_errno) return(mr_errcode);
600         }
601     } else {
602         EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
603         if (ingres_errno) return(mr_errcode);
604     }
605     return(MR_SUCCESS);
606 }
607
608
609 /* Find the NFS physical partition that the named directory is on.
610  * This is done by comparing the dir against the mount point of the
611  * partition.  To make sure we get the correct match when there is
612  * more than one, we sort the query in reverse order by dir name.
613  */
614
615 check_nfs(mach_id, name, access)
616     EXEC SQL BEGIN DECLARE SECTION;
617     int mach_id;
618     EXEC SQL END DECLARE SECTION;
619     char *name;
620     char *access;
621 {
622     EXEC SQL BEGIN DECLARE SECTION;
623     char dir[81];
624     EXEC SQL END DECLARE SECTION;
625     char caccess;
626     register int status;
627     register char *cp1;
628     register char *cp2;
629
630     status = MR_NFS;
631     EXEC SQL DECLARE csr101 CURSOR FOR
632       SELECT nfsphys_id, TRIM (dir) FROM nfsphys
633         WHERE mach_id = :mach_id
634         ORDER BY 2 DESC;
635     if (ingres_errno)
636         return(mr_errcode);
637     EXEC SQL OPEN csr101;
638     if (ingres_errno)
639         return(mr_errcode);
640     while(1) {
641         EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
642         if(sqlca.sqlcode != 0) break;
643         cp1 = name;
644         cp2 = dir;
645         while (*cp2) {
646             if (*cp1++ != *cp2) break;
647             cp2++;
648         }
649         if (*cp2 == 0) {
650             status = MR_SUCCESS;
651             break;
652         }
653     }
654     EXEC SQL CLOSE csr101;
655     if (ingres_errno)
656         return(mr_errcode);
657     return(status);
658 }
659
660
661 /* setup_dfil: free any quota records and fsgroup info associated with
662  * a filesystem when it is deleted.  Also adjust the allocation numbers.
663  */
664
665 setup_dfil(q, argv, cl)
666     struct query  *q;
667     char **argv;
668     client *cl;
669 {
670     EXEC SQL BEGIN DECLARE SECTION;
671     int id, total, phys_id;
672     short int none;
673     EXEC SQL END DECLARE SECTION;
674
675     id = *(int *)argv[0];
676     EXEC SQL REPEATED SELECT SUM (quota) INTO :total:none FROM quota
677       WHERE filsys_id = :id;
678
679     if(none) total=0;
680
681     /** What if there are multiple phys_id's per f/s? (bad data) **/
682     EXEC SQL REPEATED SELECT phys_id INTO :phys_id FROM filesys
683       WHERE filsys_id = :id;
684     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :total
685       WHERE nfsphys_id = :phys_id;
686
687     if(!none) {
688         EXEC SQL REPEATED DELETE FROM quota WHERE filsys_id = :id;
689     }
690     EXEC SQL REPEATED DELETE FROM fsgroup WHERE filsys_id = :id;
691     EXEC SQL REPEATED DELETE FROM fsgroup WHERE group_id = :id;
692     if (ingres_errno) return(mr_errcode);
693     return(MR_SUCCESS);
694 }
695
696
697 /* setup_dnfp: check to see that the nfs physical partition does not have
698  * any filesystems assigned to it before allowing it to be deleted.
699  */
700
701 setup_dnfp(q, argv, cl)
702     struct query  *q;
703     char **argv;
704     client *cl;
705 {
706     EXEC SQL BEGIN DECLARE SECTION;
707     int id, cnt;
708     char *dir;
709     EXEC SQL END DECLARE SECTION;
710
711     id = *(int *)argv[0];
712     dir = argv[1];
713     EXEC SQL REPEATED SELECT count(fs.tid) INTO :cnt FROM filesys fs, nfsphys np
714       WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
715         AND np.mach_id = :id AND np.dir = :dir;
716     if (cnt > 0)
717       return(MR_IN_USE);
718     if (ingres_errno)
719       return(mr_errcode);
720     return(MR_SUCCESS);
721 }
722
723
724 /* setup_dqot: Remove allocation from nfsphys before deleting quota.
725  *   argv[0] = filsys_id
726  *   argv[1] = type if "update_quota" or "delete_quota"
727  *   argv[2 or 1] = users_id or list_id
728  */
729
730 setup_dqot(q, argv, cl)
731     struct query  *q;
732     char **argv;
733     client *cl;
734 {
735     EXEC SQL BEGIN DECLARE SECTION;
736     int quota, fs, id, physid;
737     char *qtype;
738     EXEC SQL END DECLARE SECTION;
739
740     fs = *(int *)argv[0];
741     if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
742         qtype = argv[1];
743         id = *(int *)argv[2];
744     } else {
745         qtype = "USER";
746         id = *(int *)argv[1];
747     }
748
749     EXEC SQL REPEATED SELECT quota INTO :quota FROM quota
750       WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
751     EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys 
752       WHERE filsys_id = :fs;
753     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :quota
754       WHERE nfsphys_id = :physid;
755
756     if (ingres_errno) return(mr_errcode);
757     return(MR_SUCCESS);
758 }
759
760
761 /* setup_sshi: don't exclusive lock the machine table during
762  * set_server_host_internal.
763  */
764 /** Not allowed under (INGRES) SQL **/
765 setup_sshi(q, argv, cl)
766     struct query  *q;
767     char **argv;
768     client *cl;
769 {
770 #if 0
771 #ifsql INGRES
772     EXEC SQL set lockmode session where readlock = system;
773 #endsql
774 #endif
775     return(MR_SUCCESS);
776 }
777
778
779 /* setup add_kerberos_user_mapping: add the string to the string
780  * table if necessary.
781  */
782
783 setup_akum(q, argv, cl)
784 struct query *q;
785 char **argv;
786 client *cl;
787 {
788     EXEC SQL BEGIN DECLARE SECTION;
789     int id, rowcount;
790     char *name;
791     EXEC SQL END DECLARE SECTION;
792
793     name = argv[1];
794     if (name_to_id(name, "STRING", &id) != MR_SUCCESS) {
795         if (q->type != APPEND) return(MR_STRING);
796         id=add_string(name);
797         cache_entry(name, "STRING", id);
798     }
799     if (ingres_errno) return(mr_errcode);
800     *(int *)argv[1] = id;
801     return(MR_SUCCESS);
802 }
803
804
805 /* prefetch_value():
806  * This routine fetches an appropriate value from the numvalues table.
807  * It is a little hack to get around the fact that SQL doesn't let you
808  * do something like INSERT INTO table (foo) VALUES (other_table.bar).
809  *
810  * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or
811  * from within a setup_...() routine with the appropriate arguments.
812  *
813  * Correct functioning of this routine may depend on the assumption
814  * that this query is an APPEND.
815  */
816
817 prefetch_value(q,argv,cl)
818     struct query *q;
819     char **argv;
820     client *cl;
821 {
822     EXEC SQL BEGIN DECLARE SECTION;
823     char *name = q->validate->object_id;
824     int value;
825     EXEC SQL END DECLARE SECTION;
826     int status, limit, argc;
827
828     /* set next object id, limiting it if necessary */
829     if(!strcmp(name, "uid") || !strcmp(name, "gid"))
830       limit = 1; /* So far as I know, this isn't needed.  Just CMA. */
831     else
832       limit = 0;
833     if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
834       return(status);
835
836     /* fetch object id */
837     EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name;
838     if(ingres_errno) return(mr_errcode);
839     if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL);
840
841     argc = q->argc + q->vcnt;   /* end of Argv for APPENDs */
842     sprintf(argv[argc],"%d",value);  /** Could save this step by changing tlist from %s to %d **/
843
844     return(MR_SUCCESS);
845 }
846
847 /* prefetch_filesys():
848  * Fetches the phys_id from filesys based on the filsys_id in argv[0].
849  * Appends the filsys_id and the phys_id to the argv so they can be
850  * referenced in an INSERT into a table other than filesys.  Also
851  * see comments at prefetch_value().
852  *
853  * Assumes the existence of a row where filsys_id = argv[0], since a
854  * filesys label has already been resolved to a filsys_id.
855  */
856 prefetch_filesys(q,argv,cl)
857     struct query *q;
858     char **argv;
859     client *cl;
860 {
861     EXEC SQL BEGIN DECLARE SECTION;
862     int fid,phid;
863     EXEC SQL END DECLARE SECTION;
864     int argc;
865
866     fid = *(int *)argv[0];
867     EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
868     if(ingres_errno) return(mr_errcode);
869
870     argc=q->argc+q->vcnt;
871     sprintf(argv[argc++],"%d",phid);
872     sprintf(argv[argc],"%d",fid);
873
874     return(MR_SUCCESS);
875 }
876
877
878 /* setup_ahst():
879  */
880
881 setup_ahst(q,argv,cl)
882     struct query *q;
883     char **argv;
884     client *cl;
885 {
886     EXEC SQL BEGIN DECLARE SECTION;
887     char *name;
888     int value, id, addr, mask, high, low, cnt;
889     EXEC SQL END DECLARE SECTION;
890     char buf[BUFSIZ];
891     int row;
892     extern int host_access_level, privileged;
893
894     if (!strcmp(q->shortname, "uhst"))
895       row = 1;
896     else
897       row = 0;
898
899     /* sanity check name: must start with a letter, contain only
900      * letters, numerals, and hyphen, and not end with a hyphen.
901      */
902     if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
903         char *p = argv[row];
904
905         if (!isalpha(*p)) return(MR_BAD_CHAR);
906         for (; *p; p++) {
907             if ((!isalnum(*p) && *p != '-' && *p != '.') ||
908                 (*p == '-' && p[1] == '.'))
909               return(MR_BAD_CHAR);
910         }
911         if (*(p-1) == '-') return(MR_BAD_CHAR);
912     }
913
914     /* sanity check host vendor: must start with a letter, contain only
915      * letters, numerals, and hyphen, and end with an alphanumeric.
916      */
917     if (*argv[row+1] && (row == 0 || strcmp(argv[2], cl->args->mr_argv[2]))) {
918         char *p = argv[row+1];
919
920         if (!isalpha(*p)) return(MR_BAD_CHAR);
921         for (; *p; p++) {
922             if ((!isalnum(*p) && *p != '-' && *p != '.') ||
923                 (*p == '-' && p[1] == '.'))
924               return(MR_BAD_CHAR);
925         }
926         if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
927     }
928
929     /* sanity check host type: must start with a letter, contain only
930      * letters, numerals, and hyphen, and end with an alphanumeric.
931      */
932     if (*argv[row+2] && (row == 0 || strcmp(argv[3], cl->args->mr_argv[3]))) {
933         char *p = argv[row+2];
934
935         if (!isalpha(*p)) return(MR_BAD_CHAR);
936         for (; *p; p++) {
937             if ((!isalnum(*p) && *p != '-' && *p != '.') ||
938                 (*p == '-' && p[1] == '.'))
939               return(MR_BAD_CHAR);
940         }
941         if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
942     }
943
944     /* sanity check host vendor: must start with a letter, contain only
945      * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
946      */
947     if (*argv[row+3] && (row == 0 || strcmp(argv[4], cl->args->mr_argv[4]))) {
948         char *p = argv[row+3];
949
950         if (!isalpha(*p)) return(MR_BAD_CHAR);
951         for (; *p; p++) {
952             if ((!isalnum(*p) && *p != '-' && *p != '.') ||
953                 (*p == '-' && p[1] == '.'))
954               return(MR_BAD_CHAR);
955         }
956         if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
957     }
958
959     /* check for duplicate name */
960     name = argv[row];
961     EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
962       WHERE name = :name;
963     if (ingres_errno) return(mr_errcode);
964     if (cnt != 0) return(MR_EXISTS);
965
966     /* check address */
967     if (!strcmp(argv[9+row], "unassigned"))
968       value = -1;
969     else if (!strcmp(argv[9+row], "unique")) {
970         if (*(int *)argv[8+row] == 0)
971           value = -1;
972         else
973           value = -2;
974     } else {
975         value = ntohl(inet_addr(argv[9+row]));
976         if (value == -1) return(MR_ADDRESS);
977     }
978     if (value == 0) return(MR_ADDRESS);
979     if (value != -1) {
980         id = *(int *)argv[8+row];
981         EXEC SQL SELECT saddr, mask, high, low INTO :addr, :mask, :high, :low
982           FROM subnet WHERE snet_id = :id;
983         if (ingres_errno) return(mr_errcode);
984         if (value != -2) {
985             if ((value & mask) != addr) return(MR_ADDRESS);
986             name = argv[9+row];
987             EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
988               WHERE address = :name;
989             if (ingres_errno) return(mr_errcode);
990             if (cnt > 0) {
991                 if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
992                 if (row == 1 && cnt == 1) {
993                     EXEC SQL SELECT mach_id INTO :id FROM machine
994                       WHERE address = :name;
995                     if (id != *(int *)argv[0]) return(MR_ADDRESS);
996                 }
997             }
998         } else {
999             for (id = low; id <= high; id++) {
1000                 if (((id & 0xff) == 0) ||
1001                     ((id & 0xff) == 255))
1002                   continue;
1003                 value = htonl(id);
1004                 name = (char *)inet_ntoa(value);
1005                 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1006                   WHERE address = :name;
1007                 if (ingres_errno) return(mr_errcode);
1008                 if (cnt == 0) break;
1009             }
1010             if (cnt != 0)
1011               return(MR_ADDRESS);
1012             else
1013               value = htonl(value);
1014         }
1015         value = htonl(value);
1016         strcpy(argv[9+row], inet_ntoa(value));
1017     } else {
1018         strcpy(argv[9+row], "unassigned");
1019     }
1020
1021     /* status checking */
1022     value = atoi(argv[7+row]);
1023     if (row == 0 && !(value == 1 || value == 0))
1024       return(MR_TYPE);
1025     if (row == 1) {
1026         id = *(int *)argv[0];
1027         EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
1028         if (ingres_errno) return(mr_errcode);
1029         if (value != cnt) {
1030             EXEC SQL UPDATE machine SET statuschange = date('now')
1031                  WHERE mach_id = :id;
1032         }
1033     }
1034
1035     if (row == 0 && !privileged) {
1036         /* subnet owner is adding a host */
1037         /* Non-query owner must set use to zero */
1038         if (atoi(argv[6]) != 0) return(MR_PERM);
1039     } else if (row == 1 && !privileged) {
1040         EXEC SQL BEGIN DECLARE SECTION;
1041         int i8, i12, i13, i7, i9, i14;
1042         char s6[33], s10[33], s11[9];
1043         EXEC SQL END DECLARE SECTION;
1044         /* Non-query owner is restricted in changes that can be made */
1045         id = *(int *)argv[0];
1046         EXEC SQL SELECT contact, status, address, owner_type, owner_id, 
1047           acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11, :i12,
1048           :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
1049         if (ingres_errno) return(mr_errcode);
1050         /* subnet owner cannot change use, comment, or network */
1051         if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]) ||
1052             (i9 != *(int *)argv[9]))
1053           return(MR_PERM);
1054         /* host owner cannot change contact, status, address, owner_type,
1055          * owner_id, acomment, or subnet */
1056         if (host_access_level == 2 &&
1057             (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
1058              strcmp(argv[10], strtrim(s10)) ||strcmp(argv[11], strtrim(s11)) ||
1059              (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
1060              (i9 != *(int *)argv[9])))
1061           return(MR_PERM);
1062     }
1063
1064     /*
1065      * If this is an update_host query, we're done.
1066      */
1067     if (row == 1)
1068         return(MR_SUCCESS);
1069
1070     /*
1071      * For an add_host query, allocate and fill in a new machine id,
1072      * and then insert the creator id.
1073      */
1074     if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1075       return(mr_errcode);
1076
1077     sprintf(argv[q->argc + q->vcnt + 1], "%d",cl->client_id);
1078     return(MR_SUCCESS);
1079 }
1080
1081
1082 /* setup_ahal():
1083  */
1084
1085 setup_ahal(q,argv,cl)
1086     struct query *q;
1087     char **argv;
1088     client *cl;
1089 {
1090     EXEC SQL BEGIN DECLARE SECTION;
1091     char *name;
1092     int cnt;
1093     EXEC SQL END DECLARE SECTION;
1094     char *p;
1095
1096     p = name = argv[0];
1097     if (!isalpha(*p)) return(MR_BAD_CHAR);
1098     for (; *p; p++) {
1099         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1100             (*p == '-' && p[1] == '.'))
1101           return(MR_BAD_CHAR);
1102     }
1103     if (*(p-1) == '-') return(MR_BAD_CHAR);
1104
1105     EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
1106       name = :name;
1107     if (ingres_errno) return(mr_errcode);
1108     if (cnt > 0) return(MR_EXISTS);
1109
1110     return(MR_SUCCESS);
1111 }
This page took 0.141952 seconds and 5 git commands to generate.