]> andersk Git - moira.git/blame - server/qsetup.dc
remove bogus "old" list args
[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;
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
354int 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 \
402WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \
403OR z.sub_type = 'LIST' AND z.sub_id = %d \
404OR z.iws_type = 'LIST' AND z.iws_id = %d \
405OR 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
418int 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
451int 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
501EXEC SQL BEGIN DECLARE SECTION;
502int _var_phys_id;
503EXEC SQL END DECLARE SECTION;
504
505setup_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
544setup_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
616check_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
666setup_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
702setup_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];
db091735 714 EXEC SQL REPEATED SELECT count(fs.tid) INTO :cnt FROM filesys fs, nfsphys np
73cf66ba 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
731setup_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 **/
766setup_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
784setup_akum(q, argv, cl)
785struct query *q;
786char **argv;
787client *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
7f426981 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
818prefetch_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 */
857prefetch_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
882setup_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 == 0) return(MR_ADDRESS);
933 if (value != -1) {
934 id = *(int *)argv[8+row];
935 EXEC SQL SELECT saddr, mask, high, low INTO :addr, :mask, :high, :low
936 FROM subnet WHERE snet_id = :id;
937 if (ingres_errno) return(mr_errcode);
938 if (value != -2) {
939 if ((value & mask) != addr) return(MR_ADDRESS);
940 name = argv[9+row];
941 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
942 WHERE address = :name;
943 if (ingres_errno) return(mr_errcode);
944 if (cnt > 0) {
945 if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
946 if (row == 1 && cnt == 1) {
947 EXEC SQL SELECT mach_id INTO :id FROM machine
948 WHERE address = :name;
949 if (id != *(int *)argv[0]) return(MR_ADDRESS);
950 }
951 }
952 } else {
953 for (id = low; id <= high; id++) {
954 if (((id & 0xff) == 0) ||
955 ((id & 0xff) == 255))
956 continue;
957 value = htonl(id);
958 name = (char *)inet_ntoa(value);
959 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
960 WHERE address = :name;
961 if (ingres_errno) return(mr_errcode);
962 if (cnt == 0) break;
963 }
964 if (cnt != 0)
965 return(MR_ADDRESS);
966 else
967 value = htonl(value);
968 }
969 value = htonl(value);
970 argv[9+row] = strsave(inet_ntoa(value));
971 } else {
972 argv[9+row] = strsave("unassigned");
973 }
974
975 /* status checking */
976 value = atoi(argv[7+row]);
977 if (row == 0 && !(value == 1 || value == 3))
978 return(MR_TYPE);
979 if (row == 1) {
980 id = *(int *)argv[0];
981 EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
982 if (ingres_errno) return(mr_errcode);
983 if (value != cnt) {
984 EXEC SQL UPDATE machine SET statuschange = date('now');
985 }
986 }
987
988 if (row == 0 && !privileged) {
989 /* subnet owner is adding a host */
990 /* Non-query owner must set use to zero */
991 if (atoi(argv[6]) != 0) return(MR_PERM);
992 } else if (row == 1 && !privileged) {
993 EXEC SQL BEGIN DECLARE SECTION;
994 int i8, i12, i13, i7, i9, i14;
995 char s6[33], s10[33], s11[9];
996 EXEC SQL END DECLARE SECTION;
997 /* Non-query owner is restricted in changes that can be made */
998 id = *(int *)argv[0];
999 EXEC SQL SELECT contact, status, address, owner_type, owner_id,
1000 acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11, :i12,
1001 :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
1002 if (ingres_errno) return(mr_errcode);
1003 /* subnet owner cannot change use or ocomment */
1004 if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]))
1005 return(MR_PERM);
1006 /* host owner cannot change contact, status, address, owner_type,
1007 * owner_id, acomment, or subnet */
1008 if (host_access_level == 2 &&
1009 (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
1010 strcmp(argv[10], strtrim(s10)) || strcmp(argv[11], strtrim(s11)) ||
1011 (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
1012 (i9 = *(int *)argv[9])))
1013 return(MR_PERM);
1014 }
1015
1016 if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1017 return(mr_errcode);
1018
1019 row = q->argc + q->vcnt + 1;
1020 sprintf(buf, "%d",cl->client_id);
1021 argv[row] = strsave(buf);
1022 argv[row+1] = NULL;
1023 return(MR_SUCCESS);
1024}
1025
1026
1027/* setup_ahal():
1028 */
1029
1030setup_ahal(q,argv,cl)
1031 struct query *q;
1032 char **argv;
1033 client *cl;
1034{
1035 EXEC SQL BEGIN DECLARE SECTION;
1036 char *name;
1037 int cnt;
1038 EXEC SQL END DECLARE SECTION;
1039 char *p;
1040
1041 p = name = argv[0];
1042 if (!isalpha(*p)) return(MR_BAD_CHAR);
1043 for (; *p; p++) {
1044 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1045 (*p == '-' && p[1] == '.'))
1046 return(MR_BAD_CHAR);
1047 }
1048 if (*(p-1) == '-') return(MR_BAD_CHAR);
1049
1050 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
1051 name = :name;
1052 if (ingres_errno) return(mr_errcode);
1053 if (cnt > 0) return(MR_EXISTS);
1054
1055 return(MR_SUCCESS);
1056}
This page took 0.198762 seconds and 5 git commands to generate.