]> andersk Git - moira.git/blob - server/qsetup.dc
invalid addresses entered for hosts cause MR_ADDRESS error
[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     char *malloc();
318     unsigned char *p;
319     int idx;
320
321     if (!strcmp(q->shortname, "alis"))
322       idx = 0;
323     else if (!strcmp(q->shortname, "ulis"))
324       idx = 1;
325
326     for (p = (unsigned char *) argv[idx]; *p; p++)
327       if (badlistchars[*p])
328         return(MR_BAD_CHAR);
329  
330     if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1) {
331         if (atoi(argv[5 + idx])) {
332             if (set_next_object_id("gid", "list", 1))
333               return(MR_INGRES_ERR);
334             EXEC SQL REPEATED SELECT value INTO :ngid FROM numvalues
335               WHERE name = 'gid';
336             if (ingres_errno) return(mr_errcode);
337             sprintf(argv[6 + idx], "%d", ngid);
338         } else {
339             strcpy(argv[6 + idx], "-1");
340         }
341     }
342
343     if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
344       return(mr_errcode);
345
346     return(MR_SUCCESS);
347 }
348
349
350 /* setup_dlis - verify that the list is no longer being referenced
351  * and may safely be deleted.
352  */
353
354 int setup_dlis(q, argv)
355     struct query *q;
356     char *argv[];
357 {
358     int flag, id, ec;
359
360     id = *(int *)argv[0];
361     sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE member_id = %d AND member_type='LIST'",id);
362     if(ec=mr_select_any(stmt_buf)) {
363         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
364     }
365     
366     sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE list_id = %d",id);
367     if(ec=mr_select_any(stmt_buf)) {
368         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
369     }
370
371     sprintf(stmt_buf,"SELECT label FROM filesys WHERE owners = %d",id);
372     if(ec=mr_select_any(stmt_buf)) {
373         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
374     }
375
376     sprintf(stmt_buf,"SELECT tag FROM capacls WHERE list_id = %d",id);
377     if(ec=mr_select_any(stmt_buf)) {
378         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
379     }
380
381     sprintf(stmt_buf,"SELECT name FROM list WHERE acl_id = %d AND acl_type='LIST' AND list_id != %d",id,id);
382     if(ec=mr_select_any(stmt_buf)) {
383         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
384     }
385
386     sprintf(stmt_buf,"SELECT name FROM servers WHERE acl_id = %d AND acl_type='LIST'",id);
387     if(ec=mr_select_any(stmt_buf)) {
388         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
389     }
390
391     sprintf(stmt_buf,"SELECT entity_id FROM quota WHERE entity_id = %d AND type='GROUP'",id);
392     if(ec=mr_select_any(stmt_buf)) {
393         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
394     }
395  
396     sprintf(stmt_buf,"SELECT acl_id  FROM hostaccess WHERE acl_id = %d AND acl_type='LIST'",id);
397     if(ec=mr_select_any(stmt_buf)) {
398         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
399     }
400
401     sprintf(stmt_buf,"SELECT class FROM zephyr z \
402 WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \
403 OR z.sub_type = 'LIST' AND z.sub_id = %d \
404 OR z.iws_type = 'LIST' AND z.iws_id = %d \
405 OR z.iui_type = 'LIST' AND z.iui_id = %d",id,id,id,id);
406     if(ec=mr_select_any(stmt_buf)) {
407         if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec);
408     }
409
410     return(MR_SUCCESS);
411 }
412
413
414 /* setup_dsin - verify that the service is no longer being referenced
415  * and may safely be deleted.
416  */
417
418 int setup_dsin(q, argv)
419     struct query *q;
420     char **argv;
421 {
422     EXEC SQL BEGIN DECLARE SECTION;     
423     int ec;
424     char *svrname;
425     EXEC SQL END DECLARE SECTION;
426
427     sprintf(stmt_buf,"SELECT service FROM serverhosts WHERE service = UPPERCASE('%s')",argv[0]);
428     if(ec=mr_select_any(stmt_buf)) {
429         if(ec==MR_EXISTS) 
430             return(MR_IN_USE); 
431         else 
432             return(ec);
433     }
434
435     svrname=argv[0];
436     EXEC SQL SELECT inprogress INTO :ec FROM servers 
437       WHERE name=UPPERCASE(:svrname);
438     if(ingres_errno) 
439         return(mr_errcode);
440     if(ec) 
441         return(MR_IN_USE); 
442
443     return(MR_SUCCESS);
444 }
445
446
447 /* setup_dshi - verify that the service-host is no longer being referenced
448  * and may safely be deleted.
449  */
450
451 int setup_dshi(q, argv)
452     struct query *q;
453     char **argv;
454 {
455     EXEC SQL BEGIN DECLARE SECTION;
456     int id, ec;
457     char *svrname;
458     EXEC SQL END DECLARE SECTION;
459
460     svrname=argv[0];
461     id = *(int *)argv[1];
462
463     EXEC SQL SELECT inprogress INTO :ec FROM serverhosts 
464       WHERE service=UPPERCASE(:svrname) AND mach_id = :id;
465     if(ingres_errno) 
466         return(mr_errcode);
467     if(ec) 
468         return(MR_IN_USE); 
469
470
471     return(MR_SUCCESS);
472 }
473
474
475 /**
476  ** setup_add_filesys - verify existance of referenced file systems
477  **
478  ** Inputs:     Add
479  **   argv[1] - type
480  **   argv[2] - mach_id
481  **   argv[3] - name
482  **   argv[5] - access
483  **
484  ** Description:
485  **   - for type = RVD:
486  **        * allow anything
487  **   - for type = NFS:
488  **        * extract directory prefix from name
489  **        * verify mach_id/dir in nfsphys
490  **        * verify access in {r, w, R, W}
491  **
492  **  Side effect: sets variable _var_phys_id to the ID of the physical
493  **     filesystem (nfsphys_id for NFS, 0 for RVD)
494  **
495  ** Errors:
496  **   MR_NFS - specified directory not exported
497  **   MR_FILESYS_ACCESS - invalid filesys access
498  **
499  **/
500
501 EXEC SQL BEGIN DECLARE SECTION;
502 int _var_phys_id;
503 EXEC SQL END DECLARE SECTION;
504
505 setup_afil(q, argv, cl)
506     struct query *q;
507     char *argv[];
508     client *cl;
509 {
510     char *type, *name;
511     int mach_id;
512     EXEC SQL BEGIN DECLARE SECTION;
513     int ok;
514     char ftype[32], *access;
515     EXEC SQL END DECLARE SECTION;
516
517     type = argv[1];
518     mach_id = *(int *)argv[2];
519     name = argv[3];
520     access = argv[5];
521     _var_phys_id = 0;
522
523     sprintf(ftype, "fs_access_%s", type);
524     EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
525         WHERE name = :ftype AND type = 'TYPE' and trans = :access;   
526     if (ingres_errno) return(mr_errcode);
527     if (ok == 0) return(MR_FILESYS_ACCESS);
528
529     if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
530       return(mr_errcode);
531
532     if (!strcmp(type, "NFS"))
533         return (check_nfs(mach_id, name, access));
534
535     return(MR_SUCCESS);
536 }
537
538
539 /* Verify the arguments, depending on the FStype.  Also, if this is an
540  * NFS filesystem, then update any quotas for that filesystem to reflect
541  * the new phys_id.
542  */
543
544 setup_ufil(q, argv, cl)
545     struct query *q;
546     char *argv[];
547     client *cl;
548 {
549     int mach_id, status;
550     char *type, *name;
551     EXEC SQL BEGIN DECLARE SECTION;
552     int fid, total, who, ok;
553     char *entity, ftype[32], *access;
554     short int total_null;
555     EXEC SQL END DECLARE SECTION;
556
557     _var_phys_id = 0;
558     type = argv[2];
559     mach_id = *(int *)argv[3];
560     name = argv[4];
561     access = argv[6];
562     fid = *(int *)argv[0];
563     who = cl->client_id;
564     entity = cl->entity;
565
566     sprintf(ftype, "fs_access_%s", type);
567     EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
568       WHERE name = :ftype AND type='TYPE' AND trans = :access;
569     if (ingres_errno) return(mr_errcode);
570     if (ok == 0) return(MR_FILESYS_ACCESS);
571
572     EXEC SQL SELECT type INTO :ftype FROM filesys
573       WHERE filsys_id = :fid;
574     strtrim(ftype);
575     if (ingres_errno) return(mr_errcode);
576
577     if (!strcmp(type, "NFS")) {
578         status = check_nfs(mach_id, name, access);
579         EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
580           WHERE filsys_id = :fid;
581         if (ingres_errno) return(mr_errcode);
582         return(status);
583     } else if (!strcmp(type, "AFS") && strcmp(ftype, "AFS")) {
584         total = 0;
585         EXEC SQL REPEATED DELETE FROM quota
586           WHERE type = 'ANY' AND filsys_id = :fid;
587         EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
588           WHERE filsys_id = :fid AND phys_id != 0;
589         if (ingres_errno) return(mr_errcode);
590         if (!total_null && (total != 0)) {
591 /*
592  *             append quota (quota = total, filsys_id = fid,
593  *                           phys_id = 0, entity_id = 0, type = "ANY",
594  *                           modtime = "now", modby = who, modwith = entity)
595  */
596             EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
597                                         type, modtime, modby, modwith)
598               VALUES (:total, :fid, 0, 0,
599                       'ANY', 'now', :who, :entity) ;
600             if (ingres_errno) return(mr_errcode);
601         }
602     } else {
603         EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
604         if (ingres_errno) return(mr_errcode);
605     }
606     return(MR_SUCCESS);
607 }
608
609
610 /* Find the NFS physical partition that the named directory is on.
611  * This is done by comparing the dir against the mount point of the
612  * partition.  To make sure we get the correct match when there is
613  * more than one, we sort the query in reverse order by dir name.
614  */
615
616 check_nfs(mach_id, name, access)
617     EXEC SQL BEGIN DECLARE SECTION;
618     int mach_id;
619     EXEC SQL END DECLARE SECTION;
620     char *name;
621     char *access;
622 {
623     EXEC SQL BEGIN DECLARE SECTION;
624     char dir[81];
625     EXEC SQL END DECLARE SECTION;
626     char caccess;
627     register int status;
628     register char *cp1;
629     register char *cp2;
630
631     status = MR_NFS;
632     EXEC SQL DECLARE csr101 CURSOR FOR
633       SELECT nfsphys_id, TRIM (dir) FROM nfsphys
634         WHERE mach_id = :mach_id
635         ORDER BY 2 DESC;
636     if (ingres_errno)
637         return(mr_errcode);
638     EXEC SQL OPEN csr101;
639     if (ingres_errno)
640         return(mr_errcode);
641     while(1) {
642         EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
643         if(sqlca.sqlcode != 0) break;
644         cp1 = name;
645         cp2 = dir;
646         while (*cp2) {
647             if (*cp1++ != *cp2) break;
648             cp2++;
649         }
650         if (*cp2 == 0) {
651             status = MR_SUCCESS;
652             break;
653         }
654     }
655     EXEC SQL CLOSE csr101;
656     if (ingres_errno)
657         return(mr_errcode);
658     return(status);
659 }
660
661
662 /* setup_dfil: free any quota records and fsgroup info associated with
663  * a filesystem when it is deleted.  Also adjust the allocation numbers.
664  */
665
666 setup_dfil(q, argv, cl)
667     struct query  *q;
668     char **argv;
669     client *cl;
670 {
671     EXEC SQL BEGIN DECLARE SECTION;
672     int id, total, phys_id;
673     short int none;
674     EXEC SQL END DECLARE SECTION;
675
676     id = *(int *)argv[0];
677     EXEC SQL REPEATED SELECT SUM (quota) INTO :total:none FROM quota
678       WHERE filsys_id = :id;
679
680     if(none) total=0;
681
682     /** What if there are multiple phys_id's per f/s? (bad data) **/
683     EXEC SQL REPEATED SELECT phys_id INTO :phys_id FROM filesys
684       WHERE filsys_id = :id;
685     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :total
686       WHERE nfsphys_id = :phys_id;
687
688     if(!none) {
689         EXEC SQL REPEATED DELETE FROM quota WHERE filsys_id = :id;
690     }
691     EXEC SQL REPEATED DELETE FROM fsgroup WHERE filsys_id = :id;
692     EXEC SQL REPEATED DELETE FROM fsgroup WHERE group_id = :id;
693     if (ingres_errno) return(mr_errcode);
694     return(MR_SUCCESS);
695 }
696
697
698 /* setup_dnfp: check to see that the nfs physical partition does not have
699  * any filesystems assigned to it before allowing it to be deleted.
700  */
701
702 setup_dnfp(q, argv, cl)
703     struct query  *q;
704     char **argv;
705     client *cl;
706 {
707     EXEC SQL BEGIN DECLARE SECTION;
708     int id, cnt;
709     char *dir;
710     EXEC SQL END DECLARE SECTION;
711
712     id = *(int *)argv[0];
713     dir = argv[1];
714     EXEC SQL REPEATED SELECT count(fs.tid) INTO :cnt FROM filesys fs, nfsphys np
715       WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
716         AND np.mach_id = :id AND np.dir = :dir;
717     if (cnt > 0)
718       return(MR_IN_USE);
719     if (ingres_errno)
720       return(mr_errcode);
721     return(MR_SUCCESS);
722 }
723
724
725 /* setup_dqot: Remove allocation from nfsphys before deleting quota.
726  *   argv[0] = filsys_id
727  *   argv[1] = type if "update_quota" or "delete_quota"
728  *   argv[2 or 1] = users_id or list_id
729  */
730
731 setup_dqot(q, argv, cl)
732     struct query  *q;
733     char **argv;
734     client *cl;
735 {
736     EXEC SQL BEGIN DECLARE SECTION;
737     int quota, fs, id, physid;
738     char *qtype;
739     EXEC SQL END DECLARE SECTION;
740
741     fs = *(int *)argv[0];
742     if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
743         qtype = argv[1];
744         id = *(int *)argv[2];
745     } else {
746         qtype = "USER";
747         id = *(int *)argv[1];
748     }
749
750     EXEC SQL REPEATED SELECT quota INTO :quota FROM quota
751       WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
752     EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys 
753       WHERE filsys_id = :fs;
754     EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :quota
755       WHERE nfsphys_id = :physid;
756
757     if (ingres_errno) return(mr_errcode);
758     return(MR_SUCCESS);
759 }
760
761
762 /* setup_sshi: don't exclusive lock the machine table during
763  * set_server_host_internal.
764  */
765 /** Not allowed under (INGRES) SQL **/
766 setup_sshi(q, argv, cl)
767     struct query  *q;
768     char **argv;
769     client *cl;
770 {
771 #if 0
772 #ifsql INGRES
773     EXEC SQL set lockmode session where readlock = system;
774 #endsql
775 #endif
776     return(MR_SUCCESS);
777 }
778
779
780 /* setup add_kerberos_user_mapping: add the string to the string
781  * table if necessary.
782  */
783
784 setup_akum(q, argv, cl)
785 struct query *q;
786 char **argv;
787 client *cl;
788 {
789     EXEC SQL BEGIN DECLARE SECTION;
790     int id, rowcount;
791     char *name;
792     EXEC SQL END DECLARE SECTION;
793
794     name = argv[1];
795     if (name_to_id(name, "STRING", &id) != MR_SUCCESS) {
796         if (q->type != APPEND) return(MR_STRING);
797         id=add_string(name);
798         cache_entry(name, "STRING", id);
799     }
800     if (ingres_errno) return(mr_errcode);
801     *(int *)argv[1] = id;
802     return(MR_SUCCESS);
803 }
804
805
806 /* prefetch_value():
807  * This routine fetches an appropriate value from the numvalues table.
808  * It is a little hack to get around the fact that SQL doesn't let you
809  * do something like INSERT INTO table (foo) VALUES (other_table.bar).
810  *
811  * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or
812  * from within a setup_...() routine with the appropriate arguments.
813  *
814  * Correct functioning of this routine may depend on the assumption
815  * that this query is an APPEND.
816  */
817
818 prefetch_value(q,argv,cl)
819     struct query *q;
820     char **argv;
821     client *cl;
822 {
823     EXEC SQL BEGIN DECLARE SECTION;
824     char *name = q->validate->object_id;
825     int value;
826     EXEC SQL END DECLARE SECTION;
827     int status, limit, argc;
828
829     /* set next object id, limiting it if necessary */
830     if(!strcmp(name, "uid") || !strcmp(name, "gid"))
831       limit = 1; /* So far as I know, this isn't needed.  Just CMA. */
832     else
833       limit = 0;
834     if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
835       return(status);
836
837     /* fetch object id */
838     EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name;
839     if(ingres_errno) return(mr_errcode);
840     if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL);
841
842     argc = q->argc + q->vcnt;   /* end of Argv for APPENDs */
843     sprintf(argv[argc],"%d",value);  /** Could save this step by changing tlist from %s to %d **/
844
845     return(MR_SUCCESS);
846 }
847
848 /* prefetch_filesys():
849  * Fetches the phys_id from filesys based on the filsys_id in argv[0].
850  * Appends the filsys_id and the phys_id to the argv so they can be
851  * referenced in an INSERT into a table other than filesys.  Also
852  * see comments at prefetch_value().
853  *
854  * Assumes the existence of a row where filsys_id = argv[0], since a
855  * filesys label has already been resolved to a filsys_id.
856  */
857 prefetch_filesys(q,argv,cl)
858     struct query *q;
859     char **argv;
860     client *cl;
861 {
862     EXEC SQL BEGIN DECLARE SECTION;
863     int fid,phid;
864     EXEC SQL END DECLARE SECTION;
865     int argc;
866
867     fid = *(int *)argv[0];
868     EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
869     if(ingres_errno) return(mr_errcode);
870
871     argc=q->argc+q->vcnt;
872     sprintf(argv[argc++],"%d",phid);
873     sprintf(argv[argc],"%d",fid);
874
875     return(MR_SUCCESS);
876 }
877
878
879 /* setup_ahst():
880  */
881
882 setup_ahst(q,argv,cl)
883     struct query *q;
884     char **argv;
885     client *cl;
886 {
887     EXEC SQL BEGIN DECLARE SECTION;
888     char *name;
889     int value, id, addr, mask, high, low, cnt;
890     EXEC SQL END DECLARE SECTION;
891     char buf[BUFSIZ];
892     int row;
893     extern int host_access_level, privileged;
894
895     if (!strcmp(q->shortname, "uhst"))
896       row = 1;
897     else
898       row = 0;
899
900     /* sanity check name: must start with a letter, contain only
901      * letters, numerals, and hyphen, and not end with a hyphen.
902      */
903     if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
904         char *p = argv[row];
905
906         if (!isalpha(*p)) return(MR_BAD_CHAR);
907         for (; *p; p++) {
908             if ((!isalnum(*p) && *p != '-' && *p != '.') ||
909                 (*p == '-' && p[1] == '.'))
910               return(MR_BAD_CHAR);
911         }
912         if (*(p-1) == '-') return(MR_BAD_CHAR);
913     }
914
915     /* check for duplicate name */
916     name = argv[row];
917     EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
918       WHERE name = :name;
919     if (ingres_errno) return(mr_errcode);
920     if (cnt != 0) return(MR_EXISTS);
921
922     /* check address */
923     if (!strcmp(argv[9+row], "unassigned"))
924       value = -1;
925     else if (!strcmp(argv[9+row], "unique")) {
926         if (*(int *)argv[8+row] == 0)
927           value = -1;
928         else
929           value = -2;
930     } else {
931         value = ntohl(inet_addr(argv[9+row]));
932         if (value == -1) return(MR_ADDRESS);
933     }
934     if (value == 0) return(MR_ADDRESS);
935     if (value != -1) {
936         id = *(int *)argv[8+row];
937         EXEC SQL SELECT saddr, mask, high, low INTO :addr, :mask, :high, :low
938           FROM subnet WHERE snet_id = :id;
939         if (ingres_errno) return(mr_errcode);
940         if (value != -2) {
941             if ((value & mask) != addr) return(MR_ADDRESS);
942             name = argv[9+row];
943             EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
944               WHERE address = :name;
945             if (ingres_errno) return(mr_errcode);
946             if (cnt > 0) {
947                 if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
948                 if (row == 1 && cnt == 1) {
949                     EXEC SQL SELECT mach_id INTO :id FROM machine
950                       WHERE address = :name;
951                     if (id != *(int *)argv[0]) return(MR_ADDRESS);
952                 }
953             }
954         } else {
955             for (id = low; id <= high; id++) {
956                 if (((id & 0xff) == 0) ||
957                     ((id & 0xff) == 255))
958                   continue;
959                 value = htonl(id);
960                 name = (char *)inet_ntoa(value);
961                 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
962                   WHERE address = :name;
963                 if (ingres_errno) return(mr_errcode);
964                 if (cnt == 0) break;
965             }
966             if (cnt != 0)
967               return(MR_ADDRESS);
968             else
969               value = htonl(value);
970         }
971         value = htonl(value);
972         argv[9+row] = strsave(inet_ntoa(value));
973     } else {
974         argv[9+row] = strsave("unassigned");
975     }
976
977     /* status checking */
978     value = atoi(argv[7+row]);
979     if (row == 0 && !(value == 1 || value == 3))
980       return(MR_TYPE);
981     if (row == 1) {
982         id = *(int *)argv[0];
983         EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
984         if (ingres_errno) return(mr_errcode);
985         if (value != cnt) {
986             EXEC SQL UPDATE machine SET statuschange = date('now');
987         }
988     }
989
990     if (row == 0 && !privileged) {
991         /* subnet owner is adding a host */
992         /* Non-query owner must set use to zero */
993         if (atoi(argv[6]) != 0) return(MR_PERM);
994     } else if (row == 1 && !privileged) {
995         EXEC SQL BEGIN DECLARE SECTION;
996         int i8, i12, i13, i7, i9, i14;
997         char s6[33], s10[33], s11[9];
998         EXEC SQL END DECLARE SECTION;
999         /* Non-query owner is restricted in changes that can be made */
1000         id = *(int *)argv[0];
1001         EXEC SQL SELECT contact, status, address, owner_type, owner_id, 
1002           acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11, :i12,
1003           :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
1004         if (ingres_errno) return(mr_errcode);
1005         /* subnet owner cannot change use or ocomment */
1006         if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]))
1007           return(MR_PERM);
1008         /* host owner cannot change contact, status, address, owner_type,
1009          * owner_id, acomment, or subnet */
1010         if (host_access_level == 2 &&
1011             (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
1012              strcmp(argv[10], strtrim(s10)) || strcmp(argv[11], strtrim(s11)) ||
1013              (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
1014              (i9 = *(int *)argv[9])))
1015           return(MR_PERM);
1016     }
1017
1018     if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1019       return(mr_errcode);
1020
1021     row = q->argc + q->vcnt + 1;
1022     sprintf(buf, "%d",cl->client_id);
1023     argv[row] = strsave(buf);
1024     argv[row+1] = NULL;
1025     return(MR_SUCCESS);
1026 }
1027
1028
1029 /* setup_ahal():
1030  */
1031
1032 setup_ahal(q,argv,cl)
1033     struct query *q;
1034     char **argv;
1035     client *cl;
1036 {
1037     EXEC SQL BEGIN DECLARE SECTION;
1038     char *name;
1039     int cnt;
1040     EXEC SQL END DECLARE SECTION;
1041     char *p;
1042
1043     p = name = argv[0];
1044     if (!isalpha(*p)) return(MR_BAD_CHAR);
1045     for (; *p; p++) {
1046         if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1047             (*p == '-' && p[1] == '.'))
1048           return(MR_BAD_CHAR);
1049     }
1050     if (*(p-1) == '-') return(MR_BAD_CHAR);
1051
1052     EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
1053       name = :name;
1054     if (ingres_errno) return(mr_errcode);
1055     if (cnt > 0) return(MR_EXISTS);
1056
1057     return(MR_SUCCESS);
1058 }
This page took 0.136817 seconds and 5 git commands to generate.