]> andersk Git - moira.git/blame - server/qsetup.pc
.dc -> .pc
[moira.git] / server / qsetup.pc
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>
73cf66ba 17#include "mr_server.h"
03c05291 18#include "query.h"
73cf66ba 19#include <ctype.h>
03c05291 20#include <arpa/inet.h>
73cf66ba 21EXEC SQL INCLUDE sqlca;
73cf66ba 22#include "qrtn.h"
23
24extern char *whoami, *strsave();
03c05291 25extern int dbms_errno, mr_errcode;
73cf66ba 26
27EXEC SQL BEGIN DECLARE SECTION;
28extern char stmt_buf[];
29EXEC SQL END DECLARE SECTION;
30
03c05291 31EXEC SQL WHENEVER SQLERROR DO dbmserr();
32
73cf66ba 33
03c05291 34int prefetch_value(struct query *q, char **argv, client *cl);
35int check_nfs(int mach_idx, char *name, char *access);
73cf66ba 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
03c05291 50int setup_ausr(q, argv, cl)
51 struct query *q;
52 char *argv[];
53 client *cl;
73cf66ba 54{
03c05291 55 int row, err;
73cf66ba 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) {
03c05291 65 if ((err=set_next_object_id("unix_uid", USERS_TABLE, 1)))
66 return(err);
67 EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'unix_uid';
73cf66ba 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)
03c05291 89 struct query *q;
90 char **argv;
73cf66ba 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 */
03c05291 99 EXEC SQL SELECT status INTO :flag FROM users
73cf66ba 100 WHERE users_id = :id;
101 if (flag != 0 && flag != 4)
102 return(MR_IN_USE);
103
03c05291 104 EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type='USER';
105 EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
106 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
73cf66ba 107 WHERE member_id = :id AND member_type = 'USER';
108 if (cnt > 0)
109 return(MR_IN_USE);
03c05291 110 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys
73cf66ba 111 WHERE owner = :id;
112 if (cnt > 0)
113 return(MR_IN_USE);
03c05291 114 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
73cf66ba 115 WHERE acl_id = :id AND acl_type = 'USER';
116 if (cnt > 0)
117 return(MR_IN_USE);
03c05291 118 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
73cf66ba 119 WHERE acl_id = :id AND acl_type = 'USER';
120 if (cnt > 0)
121 return(MR_IN_USE);
03c05291 122 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
73cf66ba 123 WHERE acl_id = :id AND acl_type = 'USER';
124 if (cnt > 0)
125 return(MR_IN_USE);
03c05291 126 if (dbms_errno)
73cf66ba 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)
03c05291 136 struct query *q;
137 char **argv;
73cf66ba 138{
139 EXEC SQL BEGIN DECLARE SECTION;
03c05291 140 int id, mid;
73cf66ba 141 char type[9];
142 EXEC SQL END DECLARE SECTION;
143
144 id = *(int *)argv[0];
03c05291 145 EXEC SQL SELECT potype, pop_id INTO :type, :mid FROM users
73cf66ba 146 WHERE users_id = :id;
147 if(sqlca.sqlerrd[2] = 0)
148 return(MR_MACHINE);
03c05291 149 EXEC SQL SELECT mach_id INTO :mid FROM machine
73cf66ba 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];
03c05291 171 EXEC SQL SELECT potype, pop_id INTO :type, :id FROM users
73cf66ba 172 WHERE users_id = :user;
03c05291 173 if (dbms_errno) return(mr_errcode);
73cf66ba 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)
03c05291 186 struct query *q;
187 char **argv;
73cf66ba 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
03c05291 195 EXEC SQL SELECT status INTO :flag FROM machine
7f426981 196 WHERE mach_id = :id;
197 if (flag != 3)
198 return(MR_IN_USE);
03c05291 199 EXEC SQL SELECT COUNT(login) INTO :cnt FROM users
73cf66ba 200 WHERE potype='POP' AND pop_id = :id;
201 if (cnt > 0)
202 return(MR_IN_USE);
03c05291 203 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
73cf66ba 204 WHERE mach_id = :id;
205 if (cnt > 0)
206 return(MR_IN_USE);
03c05291 207 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
73cf66ba 208 WHERE mach_id = :id;
209 if (cnt > 0)
210 return(MR_IN_USE);
03c05291 211 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
73cf66ba 212 WHERE mach_id = :id;
213 if (cnt > 0)
214 return(MR_IN_USE);
03c05291 215 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printcap
73cf66ba 216 WHERE mach_id = :id;
217 if (cnt > 0)
218 return(MR_IN_USE);
03c05291 219 EXEC SQL SELECT COUNT(quotaserver) INTO :cnt FROM printcap
73cf66ba 220 WHERE quotaserver = :id;
221 if (cnt > 0)
222 return(MR_IN_USE);
03c05291 223 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM palladium
73cf66ba 224 WHERE mach_id = :id;
225 if (cnt > 0)
226 return(MR_IN_USE);
227
03c05291 228 EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
229 if (dbms_errno) return(mr_errcode);
73cf66ba 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)
03c05291 239 struct query *q;
240 char **argv;
73cf66ba 241{
242 EXEC SQL BEGIN DECLARE SECTION;
03c05291 243 int id, cnt = 0;
73cf66ba 244 EXEC SQL END DECLARE SECTION;
245
73cf66ba 246 id = *(int *)argv[0];
03c05291 247 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM machine
73cf66ba 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)
03c05291 260 struct query *q;
261 char **argv;
73cf66ba 262{
263 EXEC SQL BEGIN DECLARE SECTION;
264 int id, cnt;
265 EXEC SQL END DECLARE SECTION;
266
267 id = *(int *)argv[0];
03c05291 268 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcmap
73cf66ba 269 WHERE clu_id = :id;
270 if (cnt > 0)
271 return(MR_IN_USE);
03c05291 272 EXEC SQL SELECT COUNT(clu_id) INTO :cnt FROM svc
73cf66ba 273 WHERE clu_id = :id;
274 if (cnt > 0)
275 return(MR_IN_USE);
03c05291 276 if (dbms_errno)
73cf66ba 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)
03c05291 310 struct query *q;
311 char *argv[];
312 client *cl;
73cf66ba 313{
314 EXEC SQL BEGIN DECLARE SECTION;
315 int ngid;
316 EXEC SQL END DECLARE SECTION;
73cf66ba 317 unsigned char *p;
03c05291 318 int idx, err;
73cf66ba 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])) {
03c05291 331 if ((err=set_next_object_id("gid", LIST_TABLE, 1)))
332 return(err);
333 EXEC SQL SELECT value INTO :ngid FROM numvalues
73cf66ba 334 WHERE name = 'gid';
03c05291 335 if (dbms_errno) return(mr_errcode);
73cf66ba 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)
03c05291 354 struct query *q;
355 char *argv[];
73cf66ba 356{
03c05291 357 int id;
358 EXEC SQL BEGIN DECLARE SECTION;
359 int cnt;
360 EXEC SQL END DECLARE SECTION;
73cf66ba 361
362 id = *(int *)argv[0];
03c05291 363
364 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
365 WHERE member_id = :id AND member_type='LIST';
366 if(cnt>0) return MR_IN_USE;
367
368 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
369 WHERE member_id = :id AND member_type='LIST';
370 if(cnt>0) return MR_IN_USE;
73cf66ba 371
03c05291 372 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
373 WHERE list_id = :id;
374 if(cnt>0) return MR_IN_USE;
73cf66ba 375
03c05291 376 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys WHERE owners = :id;
377 if(cnt>0) return MR_IN_USE;
73cf66ba 378
03c05291 379 EXEC SQL SELECT COUNT(tag) INTO :cnt FROM capacls WHERE list_id = :id;
380 if(cnt>0) return MR_IN_USE;
73cf66ba 381
03c05291 382 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
383 WHERE acl_id = :id AND acl_type='LIST' AND list_id != :id;
384 if(cnt>0) return MR_IN_USE;
73cf66ba 385
03c05291 386 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
387 WHERE acl_id = :id AND acl_type='LIST';
388 if(cnt>0) return MR_IN_USE;
73cf66ba 389
03c05291 390 EXEC SQL SELECT COUNT(entity_id) INTO :cnt FROM quota
391 WHERE entity_id = :id AND type='GROUP';
392 if(cnt>0) return MR_IN_USE;
73cf66ba 393
03c05291 394 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
395 WHERE acl_id = :id AND acl_type='LIST';
396 if(cnt>0) return MR_IN_USE;
73cf66ba 397
03c05291 398 EXEC SQL SELECT COUNT(class) INTO :cnt FROM zephyr z
399 WHERE z.xmt_type = 'LIST' AND z.xmt_id = :id
400 OR z.sub_type = 'LIST' AND z.sub_id = :id
401 OR z.iws_type = 'LIST' AND z.iws_id = :id
402 OR z.iui_type = 'LIST' AND z.iui_id = :id;
403 if(cnt>0) return MR_IN_USE;
73cf66ba 404
405 return(MR_SUCCESS);
406}
407
408
409/* setup_dsin - verify that the service is no longer being referenced
410 * and may safely be deleted.
411 */
412
413int setup_dsin(q, argv)
03c05291 414 struct query *q;
415 char **argv;
73cf66ba 416{
417 EXEC SQL BEGIN DECLARE SECTION;
03c05291 418 int ec, cnt;
73cf66ba 419 char *svrname;
420 EXEC SQL END DECLARE SECTION;
421
73cf66ba 422 svrname=argv[0];
03c05291 423 EXEC SQL SELECT COUNT(service) INTO :cnt FROM serverhosts
424 WHERE service = UPPER(:svrname);
425 if(cnt>0) return MR_IN_USE;
426
73cf66ba 427 EXEC SQL SELECT inprogress INTO :ec FROM servers
03c05291 428 WHERE name=UPPER(:svrname);
429 if(dbms_errno)
73cf66ba 430 return(mr_errcode);
431 if(ec)
432 return(MR_IN_USE);
433
434 return(MR_SUCCESS);
435}
436
437
438/* setup_dshi - verify that the service-host is no longer being referenced
439 * and may safely be deleted.
440 */
441
442int setup_dshi(q, argv)
03c05291 443 struct query *q;
444 char **argv;
73cf66ba 445{
446 EXEC SQL BEGIN DECLARE SECTION;
447 int id, ec;
448 char *svrname;
449 EXEC SQL END DECLARE SECTION;
450
451 svrname=argv[0];
452 id = *(int *)argv[1];
453
454 EXEC SQL SELECT inprogress INTO :ec FROM serverhosts
03c05291 455 WHERE service=UPPER(:svrname) AND mach_id = :id;
456 if(dbms_errno)
73cf66ba 457 return(mr_errcode);
458 if(ec)
459 return(MR_IN_USE);
460
461
462 return(MR_SUCCESS);
463}
464
465
466/**
467 ** setup_add_filesys - verify existance of referenced file systems
468 **
469 ** Inputs: Add
470 ** argv[1] - type
471 ** argv[2] - mach_id
472 ** argv[3] - name
03c05291 473 ** argv[5] - rwaccess
73cf66ba 474 **
475 ** Description:
476 ** - for type = RVD:
477 ** * allow anything
478 ** - for type = NFS:
479 ** * extract directory prefix from name
480 ** * verify mach_id/dir in nfsphys
03c05291 481 ** * verify rwaccess in {r, w, R, W}
73cf66ba 482 **
483 ** Side effect: sets variable _var_phys_id to the ID of the physical
484 ** filesystem (nfsphys_id for NFS, 0 for RVD)
485 **
486 ** Errors:
487 ** MR_NFS - specified directory not exported
488 ** MR_FILESYS_ACCESS - invalid filesys access
489 **
490 **/
491
492EXEC SQL BEGIN DECLARE SECTION;
493int _var_phys_id;
494EXEC SQL END DECLARE SECTION;
495
03c05291 496int setup_afil(q, argv, cl)
497 struct query *q;
498 char *argv[];
499 client *cl;
73cf66ba 500{
501 char *type, *name;
502 int mach_id;
503 EXEC SQL BEGIN DECLARE SECTION;
504 int ok;
03c05291 505 char ftype[32], *rwaccess;
73cf66ba 506 EXEC SQL END DECLARE SECTION;
507
508 type = argv[1];
509 mach_id = *(int *)argv[2];
510 name = argv[3];
03c05291 511 rwaccess = argv[5];
73cf66ba 512 _var_phys_id = 0;
513
514 sprintf(ftype, "fs_access_%s", type);
515 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
03c05291 516 WHERE name = :ftype AND type = 'TYPE' and trans = :rwaccess;
517 if (dbms_errno) return(mr_errcode);
73cf66ba 518 if (ok == 0) return(MR_FILESYS_ACCESS);
519
520 if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
521 return(mr_errcode);
522
523 if (!strcmp(type, "NFS"))
03c05291 524 return (check_nfs(mach_id, name, rwaccess));
73cf66ba 525
526 return(MR_SUCCESS);
527}
528
529
530/* Verify the arguments, depending on the FStype. Also, if this is an
531 * NFS filesystem, then update any quotas for that filesystem to reflect
532 * the new phys_id.
533 */
534
03c05291 535int setup_ufil(q, argv, cl)
536 struct query *q;
537 char *argv[];
538 client *cl;
73cf66ba 539{
540 int mach_id, status;
541 char *type, *name;
542 EXEC SQL BEGIN DECLARE SECTION;
543 int fid, total, who, ok;
544 char *entity, ftype[32], *access;
545 short int total_null;
546 EXEC SQL END DECLARE SECTION;
547
548 _var_phys_id = 0;
549 type = argv[2];
550 mach_id = *(int *)argv[3];
551 name = argv[4];
552 access = argv[6];
553 fid = *(int *)argv[0];
554 who = cl->client_id;
555 entity = cl->entity;
556
557 sprintf(ftype, "fs_access_%s", type);
558 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
559 WHERE name = :ftype AND type='TYPE' AND trans = :access;
03c05291 560 if (dbms_errno) return(mr_errcode);
73cf66ba 561 if (ok == 0) return(MR_FILESYS_ACCESS);
562
563 EXEC SQL SELECT type INTO :ftype FROM filesys
564 WHERE filsys_id = :fid;
03c05291 565 if (dbms_errno) return(mr_errcode);
73cf66ba 566
567 if (!strcmp(type, "NFS")) {
568 status = check_nfs(mach_id, name, access);
569 EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
570 WHERE filsys_id = :fid;
03c05291 571 if (dbms_errno) return(mr_errcode);
73cf66ba 572 return(status);
03c05291 573 } else if (!strcmp(type, "AFS") && strcmp(strtrim(ftype), "AFS")) {
73cf66ba 574 total = 0;
03c05291 575 EXEC SQL DELETE FROM quota
73cf66ba 576 WHERE type = 'ANY' AND filsys_id = :fid;
577 EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
578 WHERE filsys_id = :fid AND phys_id != 0;
03c05291 579 if (dbms_errno) return(mr_errcode);
73cf66ba 580 if (!total_null && (total != 0)) {
581/*
582 * append quota (quota = total, filsys_id = fid,
583 * phys_id = 0, entity_id = 0, type = "ANY",
584 * modtime = "now", modby = who, modwith = entity)
585 */
586 EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
587 type, modtime, modby, modwith)
588 VALUES (:total, :fid, 0, 0,
03c05291 589 'ANY', SYSDATE, :who, :entity) ;
590 if (dbms_errno) return(mr_errcode);
73cf66ba 591 }
592 } else {
593 EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
03c05291 594 if (dbms_errno) return(mr_errcode);
73cf66ba 595 }
596 return(MR_SUCCESS);
597}
598
599
600/* Find the NFS physical partition that the named directory is on.
601 * This is done by comparing the dir against the mount point of the
602 * partition. To make sure we get the correct match when there is
603 * more than one, we sort the query in reverse order by dir name.
604 */
605
03c05291 606int check_nfs(mach_id, name, access)
607EXEC SQL BEGIN DECLARE SECTION;
73cf66ba 608 int mach_id;
03c05291 609EXEC SQL END DECLARE SECTION;
610 char *name, *access;
73cf66ba 611{
612 EXEC SQL BEGIN DECLARE SECTION;
613 char dir[81];
614 EXEC SQL END DECLARE SECTION;
73cf66ba 615 register int status;
616 register char *cp1;
617 register char *cp2;
618
619 status = MR_NFS;
620 EXEC SQL DECLARE csr101 CURSOR FOR
03c05291 621 SELECT nfsphys_id, dir FROM nfsphys
73cf66ba 622 WHERE mach_id = :mach_id
623 ORDER BY 2 DESC;
03c05291 624 if (dbms_errno)
73cf66ba 625 return(mr_errcode);
626 EXEC SQL OPEN csr101;
03c05291 627 if (dbms_errno)
73cf66ba 628 return(mr_errcode);
629 while(1) {
630 EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
631 if(sqlca.sqlcode != 0) break;
632 cp1 = name;
03c05291 633 cp2 = strtrim(dir);
73cf66ba 634 while (*cp2) {
635 if (*cp1++ != *cp2) break;
636 cp2++;
637 }
638 if (*cp2 == 0) {
639 status = MR_SUCCESS;
640 break;
641 }
642 }
643 EXEC SQL CLOSE csr101;
03c05291 644 if (dbms_errno)
73cf66ba 645 return(mr_errcode);
646 return(status);
647}
648
649
650/* setup_dfil: free any quota records and fsgroup info associated with
651 * a filesystem when it is deleted. Also adjust the allocation numbers.
652 */
653
03c05291 654int setup_dfil(q, argv, cl)
655 struct query *q;
656 char **argv;
657 client *cl;
73cf66ba 658{
659 EXEC SQL BEGIN DECLARE SECTION;
660 int id, total, phys_id;
661 short int none;
662 EXEC SQL END DECLARE SECTION;
663
664 id = *(int *)argv[0];
03c05291 665 EXEC SQL SELECT SUM (quota) INTO :total:none FROM quota
73cf66ba 666 WHERE filsys_id = :id;
667
668 if(none) total=0;
669
670 /** What if there are multiple phys_id's per f/s? (bad data) **/
03c05291 671 EXEC SQL SELECT phys_id INTO :phys_id FROM filesys
73cf66ba 672 WHERE filsys_id = :id;
03c05291 673 EXEC SQL UPDATE nfsphys SET allocated = allocated - :total
73cf66ba 674 WHERE nfsphys_id = :phys_id;
675
676 if(!none) {
03c05291 677 EXEC SQL DELETE FROM quota WHERE filsys_id = :id;
73cf66ba 678 }
03c05291 679 EXEC SQL DELETE FROM fsgroup WHERE filsys_id = :id;
680 EXEC SQL DELETE FROM fsgroup WHERE group_id = :id;
681 if (dbms_errno) return(mr_errcode);
73cf66ba 682 return(MR_SUCCESS);
683}
684
685
686/* setup_dnfp: check to see that the nfs physical partition does not have
687 * any filesystems assigned to it before allowing it to be deleted.
688 */
689
03c05291 690int setup_dnfp(q, argv, cl)
691 struct query *q;
692 char **argv;
693 client *cl;
73cf66ba 694{
695 EXEC SQL BEGIN DECLARE SECTION;
696 int id, cnt;
697 char *dir;
698 EXEC SQL END DECLARE SECTION;
699
700 id = *(int *)argv[0];
701 dir = argv[1];
03c05291 702 EXEC SQL SELECT count(fs.rowid) INTO :cnt FROM filesys fs, nfsphys np
73cf66ba 703 WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
704 AND np.mach_id = :id AND np.dir = :dir;
705 if (cnt > 0)
706 return(MR_IN_USE);
03c05291 707 if (dbms_errno)
73cf66ba 708 return(mr_errcode);
709 return(MR_SUCCESS);
710}
711
712
713/* setup_dqot: Remove allocation from nfsphys before deleting quota.
714 * argv[0] = filsys_id
715 * argv[1] = type if "update_quota" or "delete_quota"
716 * argv[2 or 1] = users_id or list_id
717 */
718
03c05291 719int setup_dqot(q, argv, cl)
720 struct query *q;
721 char **argv;
722 client *cl;
73cf66ba 723{
724 EXEC SQL BEGIN DECLARE SECTION;
725 int quota, fs, id, physid;
726 char *qtype;
727 EXEC SQL END DECLARE SECTION;
728
729 fs = *(int *)argv[0];
730 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
731 qtype = argv[1];
732 id = *(int *)argv[2];
733 } else {
734 qtype = "USER";
735 id = *(int *)argv[1];
736 }
737
03c05291 738 EXEC SQL SELECT quota INTO :quota FROM quota
73cf66ba 739 WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
03c05291 740 EXEC SQL SELECT phys_id INTO :physid FROM filesys
73cf66ba 741 WHERE filsys_id = :fs;
03c05291 742 EXEC SQL UPDATE nfsphys SET allocated = allocated - :quota
73cf66ba 743 WHERE nfsphys_id = :physid;
744
03c05291 745 if (dbms_errno) return(mr_errcode);
73cf66ba 746 return(MR_SUCCESS);
747}
748
749
750/* setup add_kerberos_user_mapping: add the string to the string
751 * table if necessary.
752 */
753
03c05291 754int setup_akum(q, argv, cl)
755 struct query *q;
756 char **argv;
757 client *cl;
73cf66ba 758{
759 EXEC SQL BEGIN DECLARE SECTION;
03c05291 760 int id;
73cf66ba 761 char *name;
762 EXEC SQL END DECLARE SECTION;
763
764 name = argv[1];
03c05291 765 if (name_to_id(name, STRINGS_TABLE, &id) != MR_SUCCESS) {
73cf66ba 766 if (q->type != APPEND) return(MR_STRING);
767 id=add_string(name);
03c05291 768 cache_entry(name, STRINGS_TABLE, id);
73cf66ba 769 }
03c05291 770 if (dbms_errno) return(mr_errcode);
73cf66ba 771 *(int *)argv[1] = id;
772 return(MR_SUCCESS);
773}
774
7f426981 775
776/* prefetch_value():
777 * This routine fetches an appropriate value from the numvalues table.
778 * It is a little hack to get around the fact that SQL doesn't let you
779 * do something like INSERT INTO table (foo) VALUES (other_table.bar).
780 *
781 * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or
782 * from within a setup_...() routine with the appropriate arguments.
783 *
784 * Correct functioning of this routine may depend on the assumption
785 * that this query is an APPEND.
786 */
787
03c05291 788int prefetch_value(q, argv, cl)
789 struct query *q;
790 char **argv;
791 client *cl;
7f426981 792{
793 EXEC SQL BEGIN DECLARE SECTION;
794 char *name = q->validate->object_id;
795 int value;
796 EXEC SQL END DECLARE SECTION;
797 int status, limit, argc;
798
799 /* set next object id, limiting it if necessary */
03c05291 800 if(!strcmp(name, "unix_uid") || !strcmp(name, "gid"))
7f426981 801 limit = 1; /* So far as I know, this isn't needed. Just CMA. */
802 else
803 limit = 0;
804 if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
805 return(status);
806
807 /* fetch object id */
808 EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name;
03c05291 809 if(dbms_errno) return(mr_errcode);
7f426981 810 if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL);
811
812 argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
813 sprintf(argv[argc],"%d",value); /** Could save this step by changing tlist from %s to %d **/
814
815 return(MR_SUCCESS);
816}
817
818/* prefetch_filesys():
819 * Fetches the phys_id from filesys based on the filsys_id in argv[0].
820 * Appends the filsys_id and the phys_id to the argv so they can be
821 * referenced in an INSERT into a table other than filesys. Also
822 * see comments at prefetch_value().
823 *
824 * Assumes the existence of a row where filsys_id = argv[0], since a
825 * filesys label has already been resolved to a filsys_id.
826 */
03c05291 827int prefetch_filesys(q, argv, cl)
828 struct query *q;
829 char **argv;
830 client *cl;
7f426981 831{
832 EXEC SQL BEGIN DECLARE SECTION;
833 int fid,phid;
834 EXEC SQL END DECLARE SECTION;
835 int argc;
836
837 fid = *(int *)argv[0];
838 EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
03c05291 839 if(dbms_errno) return(mr_errcode);
7f426981 840
841 argc=q->argc+q->vcnt;
842 sprintf(argv[argc++],"%d",phid);
843 sprintf(argv[argc],"%d",fid);
844
845 return(MR_SUCCESS);
846}
847
848
849/* setup_ahst():
850 */
851
03c05291 852int setup_ahst(q, argv, cl)
853 struct query *q;
854 char **argv;
855 client *cl;
7f426981 856{
857 EXEC SQL BEGIN DECLARE SECTION;
858 char *name;
03c05291 859 int value, id, saddr, mask, high, low, cnt;
7f426981 860 EXEC SQL END DECLARE SECTION;
7f426981 861 int row;
03c05291 862 struct in_addr addr;
7f426981 863 extern int host_access_level, privileged;
864
865 if (!strcmp(q->shortname, "uhst"))
866 row = 1;
867 else
868 row = 0;
869
870 /* sanity check name: must start with a letter, contain only
871 * letters, numerals, and hyphen, and not end with a hyphen.
872 */
873 if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
874 char *p = argv[row];
875
876 if (!isalpha(*p)) return(MR_BAD_CHAR);
877 for (; *p; p++) {
878 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
879 (*p == '-' && p[1] == '.'))
880 return(MR_BAD_CHAR);
881 }
882 if (*(p-1) == '-') return(MR_BAD_CHAR);
883 }
884
8ca3e341 885 /* sanity check host vendor: must start with a letter, contain only
886 * letters, numerals, and hyphen, and end with an alphanumeric.
887 */
888 if (*argv[row+1] && (row == 0 || strcmp(argv[2], cl->args->mr_argv[2]))) {
889 char *p = argv[row+1];
890
891 if (!isalpha(*p)) return(MR_BAD_CHAR);
892 for (; *p; p++) {
893 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
894 (*p == '-' && p[1] == '.'))
895 return(MR_BAD_CHAR);
896 }
897 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
898 }
899
900 /* sanity check host type: must start with a letter, contain only
901 * letters, numerals, and hyphen, and end with an alphanumeric.
902 */
903 if (*argv[row+2] && (row == 0 || strcmp(argv[3], cl->args->mr_argv[3]))) {
904 char *p = argv[row+2];
905
200e522b 906 if (!isalnum(*p)) return(MR_BAD_CHAR);
8ca3e341 907 for (; *p; p++) {
908 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
909 (*p == '-' && p[1] == '.'))
910 return(MR_BAD_CHAR);
911 }
912 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
913 }
914
915 /* sanity check host vendor: must start with a letter, contain only
916 * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
917 */
918 if (*argv[row+3] && (row == 0 || strcmp(argv[4], cl->args->mr_argv[4]))) {
919 char *p = argv[row+3];
920
921 if (!isalpha(*p)) return(MR_BAD_CHAR);
922 for (; *p; p++) {
923 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
924 (*p == '-' && p[1] == '.'))
925 return(MR_BAD_CHAR);
926 }
927 if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
928 }
929
7f426981 930 /* check for duplicate name */
931 name = argv[row];
932 EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
933 WHERE name = :name;
03c05291 934 if (dbms_errno) return(mr_errcode);
7f426981 935 if (cnt != 0) return(MR_EXISTS);
936
937 /* check address */
938 if (!strcmp(argv[9+row], "unassigned"))
939 value = -1;
940 else if (!strcmp(argv[9+row], "unique")) {
941 if (*(int *)argv[8+row] == 0)
942 value = -1;
943 else
944 value = -2;
5482f508 945 } else {
946 value = ntohl(inet_addr(argv[9+row]));
947 if (value == -1) return(MR_ADDRESS);
948 }
7f426981 949 if (value == 0) return(MR_ADDRESS);
950 if (value != -1) {
99127110 951 /*
952 * an address or unique was specified.
953 */
7f426981 954 id = *(int *)argv[8+row];
03c05291 955 EXEC SQL SELECT saddr, mask, high, low INTO :saddr, :mask, :high, :low
7f426981 956 FROM subnet WHERE snet_id = :id;
03c05291 957 if (dbms_errno) return(mr_errcode);
7f426981 958 if (value != -2) {
99127110 959 /*
960 * someone specified an IP address for the host record
961 */
03c05291 962 if ((value & mask) != saddr) return(MR_ADDRESS);
99127110 963 /*
964 * run the address argument through inet_addr(). This
965 * has the effect that any out of bounds host addrs will
966 * be converted to a valid host addr. We do this now
967 * so that the uniqueness check works. We should also
968 * link in an inet_addr() that returns an error for
969 * this case.
970 */
03c05291 971 addr.s_addr=inet_addr(argv[9+row]);
972 name = inet_ntoa(addr);
7f426981 973 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
974 WHERE address = :name;
03c05291 975 if (dbms_errno) return(mr_errcode);
7f426981 976 if (cnt > 0) {
99127110 977 /*
978 * make IP address is unique. If this a modify request
979 * (row == 1), then we expect one record to exist.
980 */
7f426981 981 if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
982 if (row == 1 && cnt == 1) {
983 EXEC SQL SELECT mach_id INTO :id FROM machine
984 WHERE address = :name;
985 if (id != *(int *)argv[0]) return(MR_ADDRESS);
986 }
987 }
988 } else {
99127110 989 /*
990 * a "unique" address was specified. Walk through the
991 * range specified in the network record, return
992 * error if no room left.
993 */
7f426981 994 for (id = low; id <= high; id++) {
995 if (((id & 0xff) == 0) ||
996 ((id & 0xff) == 255))
997 continue;
03c05291 998 addr.s_addr = htonl(id);
999 name = (char *)inet_ntoa(addr);
7f426981 1000 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1001 WHERE address = :name;
03c05291 1002 if (dbms_errno) return(mr_errcode);
7f426981 1003 if (cnt == 0) break;
1004 }
1005 if (cnt != 0)
1006 return(MR_ADDRESS);
1007 else
03c05291 1008 value = htonl(id);
7f426981 1009 }
99127110 1010 /*
1011 * we have an address in value. Convert it to a string and store it.
1012 */
03c05291 1013 addr.s_addr = htonl(value);
1014 strcpy(argv[9+row], inet_ntoa(addr));
7f426981 1015 } else {
ac56da7d 1016 strcpy(argv[9+row], "unassigned");
7f426981 1017 }
1018
1019 /* status checking */
1020 value = atoi(argv[7+row]);
1195dd6a 1021 if (row == 0 && !(value == 1 || value == 0))
7f426981 1022 return(MR_TYPE);
1023 if (row == 1) {
1024 id = *(int *)argv[0];
1025 EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
03c05291 1026 if (dbms_errno) return(mr_errcode);
7f426981 1027 if (value != cnt) {
03c05291 1028 EXEC SQL UPDATE machine SET statuschange = SYSDATE
1195dd6a 1029 WHERE mach_id = :id;
7f426981 1030 }
1031 }
1032
1033 if (row == 0 && !privileged) {
1034 /* subnet owner is adding a host */
1035 /* Non-query owner must set use to zero */
1036 if (atoi(argv[6]) != 0) return(MR_PERM);
1037 } else if (row == 1 && !privileged) {
1038 EXEC SQL BEGIN DECLARE SECTION;
1039 int i8, i12, i13, i7, i9, i14;
1040 char s6[33], s10[33], s11[9];
1041 EXEC SQL END DECLARE SECTION;
1042 /* Non-query owner is restricted in changes that can be made */
1043 id = *(int *)argv[0];
03c05291 1044 EXEC SQL SELECT contact, status, address, owner_type, owner_id,
1045 acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11,
1046 :i12, :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
1047 if (dbms_errno) return(mr_errcode);
8ca3e341 1048 /* subnet owner cannot change use, comment, or network */
1049 if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]) ||
1050 (i9 != *(int *)argv[9]))
7f426981 1051 return(MR_PERM);
1052 /* host owner cannot change contact, status, address, owner_type,
1053 * owner_id, acomment, or subnet */
1054 if (host_access_level == 2 &&
1055 (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
8ca3e341 1056 strcmp(argv[10], strtrim(s10)) ||strcmp(argv[11], strtrim(s11)) ||
7f426981 1057 (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
8ca3e341 1058 (i9 != *(int *)argv[9])))
7f426981 1059 return(MR_PERM);
1060 }
1061
ac56da7d 1062 /*
1063 * If this is an update_host query, we're done.
1064 */
1065 if (row == 1)
1066 return(MR_SUCCESS);
1067
1068 /*
1069 * For an add_host query, allocate and fill in a new machine id,
1070 * and then insert the creator id.
1071 */
7f426981 1072 if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
1073 return(mr_errcode);
1074
ac56da7d 1075 sprintf(argv[q->argc + q->vcnt + 1], "%d",cl->client_id);
7f426981 1076 return(MR_SUCCESS);
1077}
1078
1079
1080/* setup_ahal():
1081 */
1082
03c05291 1083int setup_ahal(q, argv, cl)
1084 struct query *q;
1085 char **argv;
1086 client *cl;
7f426981 1087{
1088 EXEC SQL BEGIN DECLARE SECTION;
1089 char *name;
1090 int cnt;
1091 EXEC SQL END DECLARE SECTION;
1092 char *p;
1093
1094 p = name = argv[0];
1095 if (!isalpha(*p)) return(MR_BAD_CHAR);
1096 for (; *p; p++) {
1097 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1098 (*p == '-' && p[1] == '.'))
1099 return(MR_BAD_CHAR);
1100 }
1101 if (*(p-1) == '-') return(MR_BAD_CHAR);
1102
1103 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
1104 name = :name;
03c05291 1105 if (dbms_errno) return(mr_errcode);
7f426981 1106 if (cnt > 0) return(MR_EXISTS);
1107
1108 return(MR_SUCCESS);
1109}
This page took 0.212537 seconds and 5 git commands to generate.