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