]> andersk Git - moira.git/blame - server/qsetup.dc
mucked with host table authorization checks...
[moira.git] / server / qsetup.dc
CommitLineData
73cf66ba 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
13static 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 */
23EXEC SQL INCLUDE sqlca;
24EXEC SQL INCLUDE sqlda;
25#include "qrtn.h"
26
27extern char *whoami, *strsave();
28extern int ingres_errno, mr_errcode;
29
30EXEC SQL BEGIN DECLARE SECTION;
31extern char stmt_buf[];
32EXEC SQL END DECLARE SECTION;
33
34EXEC 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
50setup_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
88int 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 */
135int setup_spop(q, argv)
136struct query *q;
137char **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 */
161int 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
185int 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];
7f426981 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);
73cf66ba 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
238int 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
73cf66ba 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);
73cf66ba 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
259int 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
290static 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
309int 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;
73cf66ba 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
353int 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 \
401WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \
402OR z.sub_type = 'LIST' AND z.sub_id = %d \
403OR z.iws_type = 'LIST' AND z.iws_id = %d \
404OR 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
417int 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
450int 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
500EXEC SQL BEGIN DECLARE SECTION;
501int _var_phys_id;
502EXEC SQL END DECLARE SECTION;
503
504setup_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
543setup_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
615check_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
665setup_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
701setup_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];
db091735 713 EXEC SQL REPEATED SELECT count(fs.tid) INTO :cnt FROM filesys fs, nfsphys np
73cf66ba 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
730setup_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 **/
765setup_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
783setup_akum(q, argv, cl)
784struct query *q;
785char **argv;
786client *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
7f426981 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
817prefetch_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 */
856prefetch_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
881setup_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
8ca3e341 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
7f426981 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;
5482f508 974 } else {
975 value = ntohl(inet_addr(argv[9+row]));
976 if (value == -1) return(MR_ADDRESS);
977 }
7f426981 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);
ac56da7d 1016 strcpy(argv[9+row], inet_ntoa(value));
7f426981 1017 } else {
ac56da7d 1018 strcpy(argv[9+row], "unassigned");
7f426981 1019 }
1020
1021 /* status checking */
1022 value = atoi(argv[7+row]);
1195dd6a 1023 if (row == 0 && !(value == 1 || value == 0))
7f426981 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) {
1195dd6a 1030 EXEC SQL UPDATE machine SET statuschange = date('now')
1031 WHERE mach_id = :id;
7f426981 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);
8ca3e341 1050 /* subnet owner cannot change use, comment, or network */
1051 if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]) ||
1052 (i9 != *(int *)argv[9]))
7f426981 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])) ||
8ca3e341 1058 strcmp(argv[10], strtrim(s10)) ||strcmp(argv[11], strtrim(s11)) ||
7f426981 1059 (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
8ca3e341 1060 (i9 != *(int *)argv[9])))
7f426981 1061 return(MR_PERM);
1062 }
1063
ac56da7d 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 */
7f426981 1074 if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1075 return(mr_errcode);
1076
ac56da7d 1077 sprintf(argv[q->argc + q->vcnt + 1], "%d",cl->client_id);
7f426981 1078 return(MR_SUCCESS);
1079}
1080
1081
1082/* setup_ahal():
1083 */
1084
1085setup_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.903869 seconds and 5 git commands to generate.