]> andersk Git - moira.git/blame - server/qsetup.pc
Make gtlc version 7; it didn't change any interfaces so we don't need
[moira.git] / server / qsetup.pc
CommitLineData
7ac48069 1/* $Id$
73cf66ba 2 *
7ac48069 3 * Query setup routines
73cf66ba 4 *
7ac48069 5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
73cf66ba 8 */
9
73cf66ba 10#include <mit-copyright.h>
73cf66ba 11#include "mr_server.h"
03c05291 12#include "query.h"
7ac48069 13#include "qrtn.h"
14
03c05291 15#include <arpa/inet.h>
7ac48069 16#include <netinet/in.h>
17
18#include <ctype.h>
19#include <stdlib.h>
20#include <string.h>
21
73cf66ba 22EXEC SQL INCLUDE sqlca;
73cf66ba 23
7ac48069 24RCSID("$Header$");
25
26extern char *whoami;
03c05291 27extern int dbms_errno, mr_errcode;
73cf66ba 28
29EXEC SQL BEGIN DECLARE SECTION;
30extern char stmt_buf[];
31EXEC SQL END DECLARE SECTION;
32
03c05291 33EXEC SQL WHENEVER SQLERROR DO dbmserr();
34
17f585b5 35int hostname_check(char *name);
36int hostinfo_check(char *name, int num);
03c05291 37int prefetch_value(struct query *q, char **argv, client *cl);
38int check_nfs(int mach_idx, char *name, char *access);
73cf66ba 39
40/* Setup Routines */
41
42/* Setup routine for add_user
43 *
44 * Inputs: argv[0] - login
45 * argv[1] - uid
46 *
47 * Description:
48 *
49 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
50 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
51 */
52
5eaef520 53int setup_ausr(struct query *q, char *argv[], client *cl)
73cf66ba 54{
5eaef520 55 int row, err;
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;
cca8e7ef 64
186dd63b 65 if (q->version > 2)
66 {
67 if (strlen(argv[row + 3]) + strlen(argv[row + 4]) +
68 strlen(argv[row + 5]) + 2 > USERS_FULLNAME_SIZE)
69 return MR_ARG_TOO_LONG;
70 }
71 else
72 {
73 if (strlen(argv[row + 2]) + strlen(argv[row + 3]) +
74 strlen(argv[row + 4]) + 2 > USERS_FULLNAME_SIZE)
75 return MR_ARG_TOO_LONG;
76 }
cca8e7ef 77
5eaef520 78 if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1)
79 {
80 if ((err = set_next_object_id("unix_uid", USERS_TABLE, 1)))
81 return err;
82 EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'unix_uid';
83 if (sqlca.sqlerrd[2] != 1)
84 return MR_INTERNAL;
85 sprintf(argv[row], "%d", nuid);
73cf66ba 86 }
87
5eaef520 88 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[row]) == -1)
89 sprintf(argv[0], "#%s", argv[row]);
73cf66ba 90
5eaef520 91 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
92 return mr_errcode;
73cf66ba 93
5eaef520 94 return MR_SUCCESS;
73cf66ba 95}
96
97
98/* setup_dusr - verify that the user is no longer being referenced
99 * and may safely be deleted.
100 */
101
7ac48069 102int setup_dusr(struct query *q, char *argv[], client *cl)
73cf66ba 103{
5eaef520 104 EXEC SQL BEGIN DECLARE SECTION;
105 int flag, id, cnt;
00c3d0fe 106 char resv[USERS_RESERVATIONS_SIZE];
5eaef520 107 EXEC SQL END DECLARE SECTION;
108
109 id = *(int *)argv[0];
110
00c3d0fe 111 /* For now, only allow users to be deleted if their status is 0
112 * and we have no reservations about deleting them.
113 */
114 EXEC SQL SELECT status, reservations INTO :flag, :resv
115 FROM users WHERE users_id = :id;
116 if ((flag != 0 && flag != 4) || *resv)
5eaef520 117 return MR_IN_USE;
118
5eaef520 119 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
120 WHERE member_id = :id AND member_type = 'USER';
121 if (cnt > 0)
122 return MR_IN_USE;
123 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys
124 WHERE owner = :id;
125 if (cnt > 0)
126 return MR_IN_USE;
127 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
128 WHERE acl_id = :id AND acl_type = 'USER';
129 if (cnt > 0)
130 return MR_IN_USE;
131 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
132 WHERE acl_id = :id AND acl_type = 'USER';
133 if (cnt > 0)
134 return MR_IN_USE;
135 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
136 WHERE acl_id = :id AND acl_type = 'USER';
137 if (cnt > 0)
138 return MR_IN_USE;
139 if (dbms_errno)
140 return mr_errcode;
00c3d0fe 141
142 EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
143 EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
5eaef520 144 return MR_SUCCESS;
73cf66ba 145}
146
147
73cf66ba 148/* setup_dpob: Take care of keeping track of the post office usage.
149 */
7ac48069 150int setup_dpob(struct query *q, char *argv[], client *cl)
73cf66ba 151{
5eaef520 152 EXEC SQL BEGIN DECLARE SECTION;
153 int id, user;
e688520a 154 char type[USERS_POTYPE_SIZE];
5eaef520 155 EXEC SQL END DECLARE SECTION;
156
157 user = *(int *)argv[0];
158 EXEC SQL SELECT potype, pop_id INTO :type, :id FROM users
159 WHERE users_id = :user;
160 if (dbms_errno)
161 return mr_errcode;
162
163 if (!strcmp(strtrim(type), "POP"))
164 set_pop_usage(id, -1);
165 return MR_SUCCESS;
73cf66ba 166}
167
168
169/* setup_dmac - verify that the machine is no longer being referenced
170 * and may safely be deleted.
171 */
172
7ac48069 173int setup_dmac(struct query *q, char *argv[], client *cl)
73cf66ba 174{
5eaef520 175 EXEC SQL BEGIN DECLARE SECTION;
176 int flag, id, cnt;
177 EXEC SQL END DECLARE SECTION;
178
179 id = *(int *)argv[0];
180
181 EXEC SQL SELECT status INTO :flag FROM machine
182 WHERE mach_id = :id;
183 if (flag != 3)
184 return MR_IN_USE;
185 EXEC SQL SELECT COUNT(login) INTO :cnt FROM users
186 WHERE potype = 'POP' AND pop_id = :id;
187 if (cnt > 0)
188 return MR_IN_USE;
189 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
190 WHERE mach_id = :id;
191 if (cnt > 0)
192 return MR_IN_USE;
193 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
194 WHERE mach_id = :id;
195 if (cnt > 0)
196 return MR_IN_USE;
197 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
198 WHERE mach_id = :id;
199 if (cnt > 0)
200 return MR_IN_USE;
2884200f 201 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printers
5eaef520 202 WHERE mach_id = :id;
203 if (cnt > 0)
204 return MR_IN_USE;
2884200f 205 EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
206 WHERE rm = :id;
207 if (cnt > 0)
208 return MR_IN_USE;
209 EXEC SQL SELECT COUNT(rq) INTO :cnt FROM printers
210 WHERE rq = :id;
5eaef520 211 if (cnt > 0)
212 return MR_IN_USE;
1a9a0a59 213 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
5eaef520 214 WHERE mach_id = :id;
215 if (cnt > 0)
216 return MR_IN_USE;
217 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostalias
218 WHERE mach_id = :id;
219 if (cnt > 0)
220 return MR_IN_USE;
221
222 EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
2fb668b0 223 if (dbms_errno)
224 return mr_errcode;
225
226 EXEC SQL DELETE FROM mcntmap WHERE mach_id = :id;
5eaef520 227 if (dbms_errno)
228 return mr_errcode;
229 return MR_SUCCESS;
73cf66ba 230}
231
232
233/* setup_dsnt - verify that the subnet is no longer being referenced
234 * and may safely be deleted.
235 */
236
7ac48069 237int setup_dsnt(struct query *q, char *argv[], client *cl)
73cf66ba 238{
5eaef520 239 EXEC SQL BEGIN DECLARE SECTION;
240 int id, cnt = 0;
241 EXEC SQL END DECLARE SECTION;
242
243 id = *(int *)argv[0];
244 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM machine
245 WHERE snet_id = :id;
246 if (cnt > 0)
247 return MR_IN_USE;
248 return MR_SUCCESS;
73cf66ba 249}
250
251
252/* setup_dclu - verify that the cluster is no longer being referenced
253 * and may safely be deleted.
254 */
255
7ac48069 256int setup_dclu(struct query *q, char *argv[], client *cl)
73cf66ba 257{
5eaef520 258 EXEC SQL BEGIN DECLARE SECTION;
259 int id, cnt;
260 EXEC SQL END DECLARE SECTION;
261
262 id = *(int *)argv[0];
263 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcmap
264 WHERE clu_id = :id;
265 if (cnt > 0)
266 return MR_IN_USE;
267 EXEC SQL SELECT COUNT(clu_id) INTO :cnt FROM svc
268 WHERE clu_id = :id;
269 if (cnt > 0)
270 return MR_IN_USE;
271 if (dbms_errno)
272 return mr_errcode;
273 return MR_SUCCESS;
73cf66ba 274}
275
276
277/* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
278 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
279 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
280 * a -1 there. Remember that this is also used for ulis, with the indexes
281 * at 6 & 7. Also check that the list name does not contain uppercase
282 * characters, control characters, @, or :.
8e45963f 283 *
284 * Newlines in list descriptions do bad things to the aliases file
285 * moira generates, so make sure the description doesn't contain any, too.
73cf66ba 286 */
287
288static int badlistchars[] = {
5eaef520 289 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
290 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
771397b1 291 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
0b452293 292 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5eaef520 293 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
0b452293 294 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5eaef520 295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
0b452293 296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5eaef520 297 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
298 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
73cf66ba 305};
306
5eaef520 307int setup_alis(struct query *q, char *argv[], client *cl)
73cf66ba 308{
5eaef520 309 EXEC SQL BEGIN DECLARE SECTION;
17f585b5 310 int ngid, cnt;
8e45963f 311 char *name, *desc;
5eaef520 312 EXEC SQL END DECLARE SECTION;
313 unsigned char *p;
314 int idx, err;
315
316 if (!strcmp(q->shortname, "alis"))
317 idx = 0;
318 else if (!strcmp(q->shortname, "ulis"))
319 idx = 1;
17f585b5 320 name = argv[idx];
771397b1 321
322 if (q->version == 2)
323 desc = argv[9 + idx];
324 else if (q->version == 3)
325 desc = argv[10 + idx];
326 else if (q->version >= 4)
327 desc = argv[12 + idx];
5eaef520 328
5a22fdf5 329 if (idx == 1)
330 {
331 EXEC SQL BEGIN DECLARE SECTION;
332 int lid = *(int *)argv[0];
333 EXEC SQL END DECLARE SECTION;
334
335 if (acl_access_check(lid, cl))
336 return MR_PERM;
337 }
338
17f585b5 339 for (p = (unsigned char *) name; *p; p++)
5eaef520 340 {
73cf66ba 341 if (badlistchars[*p])
5eaef520 342 return MR_BAD_CHAR;
343 }
344
8e45963f 345 for (p = (unsigned char *) desc; *p; p++)
346 {
347 if (*p == '\n')
348 return MR_BAD_CHAR;
349 }
350
17f585b5 351 /* Check that it doesn't conflict with a pre-existing weirdly-cased
352 * name. */
353 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
20315440 354 WHERE LOWER(name) = :name AND name != :name;
17f585b5 355 if (cnt)
356 return MR_EXISTS;
357
5eaef520 358 if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1)
359 {
360 if (atoi(argv[5 + idx]))
361 {
362 if ((err = set_next_object_id("gid", LIST_TABLE, 1)))
363 return err;
364 EXEC SQL SELECT value INTO :ngid FROM numvalues
365 WHERE name = 'gid';
366 if (dbms_errno)
367 return mr_errcode;
368 sprintf(argv[6 + idx], "%d", ngid);
73cf66ba 369 }
5eaef520 370 else
371 strcpy(argv[6 + idx], "-1");
73cf66ba 372 }
373
5eaef520 374 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
375 return mr_errcode;
73cf66ba 376
5eaef520 377 return MR_SUCCESS;
73cf66ba 378}
379
380
381/* setup_dlis - verify that the list is no longer being referenced
382 * and may safely be deleted.
383 */
384
7ac48069 385int setup_dlis(struct query *q, char *argv[], client *cl)
73cf66ba 386{
5eaef520 387 int id;
388 EXEC SQL BEGIN DECLARE SECTION;
389 int cnt;
390 EXEC SQL END DECLARE SECTION;
391
392 id = *(int *)argv[0];
393
394 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
395 WHERE member_id = :id AND member_type = 'LIST';
396 if (cnt > 0)
397 return MR_IN_USE;
398
399 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
400 WHERE member_id = :id AND member_type = 'LIST';
401 if (cnt > 0)
402 return MR_IN_USE;
403
404 EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
405 WHERE list_id = :id;
406 if (cnt > 0)
407 return MR_IN_USE;
408
409 EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys WHERE owners = :id;
410 if (cnt > 0)
411 return MR_IN_USE;
412
413 EXEC SQL SELECT COUNT(tag) INTO :cnt FROM capacls WHERE list_id = :id;
414 if (cnt > 0)
415 return MR_IN_USE;
416
417 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
418 WHERE acl_id = :id AND acl_type = 'LIST' AND list_id != :id;
419 if (cnt > 0)
420 return MR_IN_USE;
421
40a6abf9 422 EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
423 WHERE memacl_id = :id AND memacl_type = 'LIST' AND list_id != :id;
424 if (cnt > 0)
425 return MR_IN_USE;
426
5eaef520 427 EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
428 WHERE acl_id = :id AND acl_type = 'LIST';
429 if (cnt > 0)
430 return MR_IN_USE;
431
432 EXEC SQL SELECT COUNT(entity_id) INTO :cnt FROM quota
433 WHERE entity_id = :id AND type = 'GROUP';
434 if (cnt > 0)
435 return MR_IN_USE;
436
437 EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
438 WHERE acl_id = :id AND acl_type = 'LIST';
439 if (cnt > 0)
440 return MR_IN_USE;
441
442 EXEC SQL SELECT COUNT(class) INTO :cnt FROM zephyr z
443 WHERE z.xmt_type = 'LIST' AND z.xmt_id = :id
444 OR z.sub_type = 'LIST' AND z.sub_id = :id
445 OR z.iws_type = 'LIST' AND z.iws_id = :id
34463187 446 OR z.iui_type = 'LIST' AND z.iui_id = :id
447 OR z.owner_type = 'LIST' and z.owner_id = :id;
5eaef520 448 if (cnt > 0)
449 return MR_IN_USE;
450
1a9a0a59 451 EXEC SQL SELECT COUNT(name) INTO :cnt FROM printers
452 WHERE lpc_acl = :id OR ac = :id;
453 if (cnt > 0)
454 return MR_IN_USE;
455
456 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
457 WHERE owner_type = 'LIST' AND owner_id = :id
458 OR lpc_acl = :id;
459 if (cnt > 0)
460 return MR_IN_USE;
461
5eaef520 462 return MR_SUCCESS;
73cf66ba 463}
464
465
466/* setup_dsin - verify that the service is no longer being referenced
467 * and may safely be deleted.
468 */
469
7ac48069 470int setup_dsin(struct query *q, char *argv[], client *cl)
73cf66ba 471{
5eaef520 472 EXEC SQL BEGIN DECLARE SECTION;
473 int ec, cnt;
474 char *svrname;
475 EXEC SQL END DECLARE SECTION;
476
477 svrname = argv[0];
478 EXEC SQL SELECT COUNT(service) INTO :cnt FROM serverhosts
479 WHERE service = UPPER(:svrname);
480 if (cnt > 0)
481 return MR_IN_USE;
482
483 EXEC SQL SELECT inprogress INTO :ec FROM servers
484 WHERE name = UPPER(:svrname);
485 if (dbms_errno)
486 return mr_errcode;
487 if (ec)
488 return MR_IN_USE;
489
490 return MR_SUCCESS;
73cf66ba 491}
492
493
494/* setup_dshi - verify that the service-host is no longer being referenced
495 * and may safely be deleted.
496 */
497
7ac48069 498int setup_dshi(struct query *q, char *argv[], client *cl)
73cf66ba 499{
5eaef520 500 EXEC SQL BEGIN DECLARE SECTION;
501 int id, ec;
502 char *svrname;
503 EXEC SQL END DECLARE SECTION;
504
505 svrname = argv[0];
506 id = *(int *)argv[1];
507
508 EXEC SQL SELECT inprogress INTO :ec FROM serverhosts
509 WHERE service = UPPER(:svrname) AND mach_id = :id;
510 if (dbms_errno)
511 return mr_errcode;
512 if (ec)
513 return MR_IN_USE;
514
515 return MR_SUCCESS;
73cf66ba 516}
517
518
519/**
520 ** setup_add_filesys - verify existance of referenced file systems
521 **
522 ** Inputs: Add
523 ** argv[1] - type
524 ** argv[2] - mach_id
525 ** argv[3] - name
03c05291 526 ** argv[5] - rwaccess
73cf66ba 527 **
528 ** Description:
529 ** - for type = RVD:
530 ** * allow anything
cc1bca5c 531 ** - for type = NFS/IMAP:
73cf66ba 532 ** * extract directory prefix from name
533 ** * verify mach_id/dir in nfsphys
03c05291 534 ** * verify rwaccess in {r, w, R, W}
73cf66ba 535 **
536 ** Side effect: sets variable _var_phys_id to the ID of the physical
537 ** filesystem (nfsphys_id for NFS, 0 for RVD)
538 **
539 ** Errors:
540 ** MR_NFS - specified directory not exported
541 ** MR_FILESYS_ACCESS - invalid filesys access
542 **
543 **/
544
545EXEC SQL BEGIN DECLARE SECTION;
546int _var_phys_id;
547EXEC SQL END DECLARE SECTION;
548
5eaef520 549int setup_afil(struct query *q, char *argv[], client *cl)
73cf66ba 550{
5eaef520 551 char *type, *name;
552 int mach_id;
553 EXEC SQL BEGIN DECLARE SECTION;
554 int ok;
e688520a 555 char ftype[FILESYS_TYPE_SIZE + 10], *rwaccess;
5eaef520 556 EXEC SQL END DECLARE SECTION;
557
558 type = argv[1];
559 mach_id = *(int *)argv[2];
560 name = argv[3];
561 rwaccess = argv[5];
562 _var_phys_id = 0;
563
564 sprintf(ftype, "fs_access_%s", type);
565 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
566 WHERE name = :ftype AND type = 'TYPE' and trans = :rwaccess;
567 if (dbms_errno)
568 return mr_errcode;
569 if (ok == 0)
570 return MR_FILESYS_ACCESS;
571
572 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
573 return mr_errcode;
574
cc1bca5c 575 if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
5eaef520 576 return check_nfs(mach_id, name, rwaccess);
577
578 return MR_SUCCESS;
73cf66ba 579}
580
581
582/* Verify the arguments, depending on the FStype. Also, if this is an
583 * NFS filesystem, then update any quotas for that filesystem to reflect
584 * the new phys_id.
585 */
586
5eaef520 587int setup_ufil(struct query *q, char *argv[], client *cl)
73cf66ba 588{
5eaef520 589 int mach_id, status;
590 char *type, *name;
591 EXEC SQL BEGIN DECLARE SECTION;
592 int fid, total, who, ok;
e688520a 593 char *entity, ftype[FILESYS_TYPE_SIZE + 10], *access;
5eaef520 594 short int total_null;
595 EXEC SQL END DECLARE SECTION;
596
597 _var_phys_id = 0;
598 type = argv[2];
599 mach_id = *(int *)argv[3];
600 name = argv[4];
601 access = argv[6];
602 fid = *(int *)argv[0];
603 who = cl->client_id;
604 entity = cl->entity;
605
606 sprintf(ftype, "fs_access_%s", type);
607 EXEC SQL SELECT COUNT(trans) INTO :ok FROM alias
608 WHERE name = :ftype AND type = 'TYPE' AND trans = :access;
609 if (dbms_errno)
610 return mr_errcode;
611 if (ok == 0)
612 return MR_FILESYS_ACCESS;
613
614 EXEC SQL SELECT type INTO :ftype FROM filesys
615 WHERE filsys_id = :fid;
616 if (dbms_errno)
617 return mr_errcode;
618
cc1bca5c 619 if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
5eaef520 620 {
621 status = check_nfs(mach_id, name, access);
622 EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
623 WHERE filsys_id = :fid;
624 if (dbms_errno)
625 return mr_errcode;
626 return status;
627 }
628 else if (!strcmp(type, "AFS") && strcmp(strtrim(ftype), "AFS")
629 && strcmp(strtrim(ftype), "ERR"))
630 {
631 total = 0;
632 EXEC SQL DELETE FROM quota
633 WHERE type = 'ANY' AND filsys_id = :fid;
634 EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota
635 WHERE filsys_id = :fid AND phys_id != 0;
636 if (dbms_errno)
637 return mr_errcode;
638 if (!total_null && (total != 0))
639 {
640 EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id,
641 type, modtime, modby, modwith)
642 VALUES (:total, :fid, 0, 0, 'ANY', SYSDATE, :who, :entity);
643 if (dbms_errno)
644 return mr_errcode;
73cf66ba 645 }
73cf66ba 646 }
5eaef520 647 else
648 {
649 EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
650 if (dbms_errno)
651 return mr_errcode;
652 }
653 return MR_SUCCESS;
73cf66ba 654}
655
656
657/* Find the NFS physical partition that the named directory is on.
658 * This is done by comparing the dir against the mount point of the
659 * partition. To make sure we get the correct match when there is
660 * more than one, we sort the query in reverse order by dir name.
661 */
662
5eaef520 663int check_nfs(int mach_id, char *name, char *access)
73cf66ba 664{
5eaef520 665 EXEC SQL BEGIN DECLARE SECTION;
e688520a 666 char dir[NFSPHYS_DIR_SIZE];
5eaef520 667 int mid = mach_id;
668 EXEC SQL END DECLARE SECTION;
44d12d58 669 int status;
670 char *cp1;
671 char *cp2;
5eaef520 672
673 status = MR_NFS;
674 EXEC SQL DECLARE csr101 CURSOR FOR
675 SELECT nfsphys_id, dir FROM nfsphys
676 WHERE mach_id = :mid
677 ORDER BY 2 DESC;
678 if (dbms_errno)
679 return mr_errcode;
680 EXEC SQL OPEN csr101;
681 if (dbms_errno)
682 return mr_errcode;
683 while (1)
684 {
685 EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
686 if (sqlca.sqlcode)
687 break;
688 cp1 = name;
689 cp2 = strtrim(dir);
690 while (*cp2)
691 {
692 if (*cp1++ != *cp2)
73cf66ba 693 break;
5eaef520 694 cp2++;
695 }
696 if (!*cp2)
697 {
698 status = MR_SUCCESS;
699 break;
73cf66ba 700 }
701 }
5eaef520 702 EXEC SQL CLOSE csr101;
703 if (dbms_errno)
704 return mr_errcode;
705 return status;
73cf66ba 706}
707
708
709/* setup_dfil: free any quota records and fsgroup info associated with
710 * a filesystem when it is deleted. Also adjust the allocation numbers.
711 */
712
5eaef520 713int setup_dfil(struct query *q, char **argv, client *cl)
73cf66ba 714{
5eaef520 715 EXEC SQL BEGIN DECLARE SECTION;
716 int id, total, phys_id;
717 short int none;
718 EXEC SQL END DECLARE SECTION;
719
720 id = *(int *)argv[0];
721 EXEC SQL SELECT SUM (quota) INTO :total:none FROM quota
722 WHERE filsys_id = :id;
723
724 if (none)
725 total = 0;
726
727 /** What if there are multiple phys_id's per f/s? (bad data) **/
728 EXEC SQL SELECT phys_id INTO :phys_id FROM filesys
729 WHERE filsys_id = :id;
730 EXEC SQL UPDATE nfsphys SET allocated = allocated - :total
731 WHERE nfsphys_id = :phys_id;
732
733 if (!none)
734 EXEC SQL DELETE FROM quota WHERE filsys_id = :id;
735 EXEC SQL DELETE FROM fsgroup WHERE filsys_id = :id;
736 EXEC SQL DELETE FROM fsgroup WHERE group_id = :id;
737 if (dbms_errno)
738 return mr_errcode;
739 return MR_SUCCESS;
73cf66ba 740}
741
742
743/* setup_dnfp: check to see that the nfs physical partition does not have
744 * any filesystems assigned to it before allowing it to be deleted.
745 */
746
5eaef520 747int setup_dnfp(struct query *q, char **argv, client *cl)
73cf66ba 748{
5eaef520 749 EXEC SQL BEGIN DECLARE SECTION;
750 int id, cnt;
751 char *dir;
752 EXEC SQL END DECLARE SECTION;
753
754 id = *(int *)argv[0];
755 dir = argv[1];
756 EXEC SQL SELECT count(fs.rowid) INTO :cnt FROM filesys fs, nfsphys np
757 WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id
758 AND np.mach_id = :id AND np.dir = :dir;
759 if (cnt > 0)
760 return MR_IN_USE;
761 if (dbms_errno)
762 return mr_errcode;
763 return MR_SUCCESS;
73cf66ba 764}
765
766
767/* setup_dqot: Remove allocation from nfsphys before deleting quota.
768 * argv[0] = filsys_id
769 * argv[1] = type if "update_quota" or "delete_quota"
770 * argv[2 or 1] = users_id or list_id
771 */
772
5eaef520 773int setup_dqot(struct query *q, char **argv, client *cl)
73cf66ba 774{
5eaef520 775 EXEC SQL BEGIN DECLARE SECTION;
776 int quota, fs, id, physid;
777 char *qtype;
778 EXEC SQL END DECLARE SECTION;
779
780 fs = *(int *)argv[0];
781 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota"))
782 {
783 qtype = argv[1];
784 id = *(int *)argv[2];
785 }
786 else
787 {
788 qtype = "USER";
789 id = *(int *)argv[1];
73cf66ba 790 }
791
5eaef520 792 EXEC SQL SELECT quota INTO :quota FROM quota
793 WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
794 EXEC SQL SELECT phys_id INTO :physid FROM filesys
795 WHERE filsys_id = :fs;
796 EXEC SQL UPDATE nfsphys SET allocated = allocated - :quota
797 WHERE nfsphys_id = :physid;
73cf66ba 798
5eaef520 799 if (dbms_errno)
800 return mr_errcode;
801 return MR_SUCCESS;
73cf66ba 802}
803
804
7f426981 805/* prefetch_value():
806 * This routine fetches an appropriate value from the numvalues table.
807 * It is a little hack to get around the fact that SQL doesn't let you
808 * do something like INSERT INTO table (foo) VALUES (other_table.bar).
809 *
5eaef520 810 * It is called from the query table as (*v->pre_rtn)(q, Argv, cl) or
7f426981 811 * from within a setup_...() routine with the appropriate arguments.
812 *
813 * Correct functioning of this routine may depend on the assumption
814 * that this query is an APPEND.
815 */
816
5eaef520 817int prefetch_value(struct query *q, char **argv, client *cl)
7f426981 818{
5eaef520 819 EXEC SQL BEGIN DECLARE SECTION;
820 char *name = q->validate->object_id;
821 int value;
822 EXEC SQL END DECLARE SECTION;
823 int status, limit, argc;
824
825 /* set next object id, limiting it if necessary */
826 if (!strcmp(name, "unix_uid") || !strcmp(name, "gid"))
827 limit = 1; /* So far as I know, this isn't needed. Just CMA. */
828 else
829 limit = 0;
830 if ((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS)
831 return status;
832
833 /* fetch object id */
834 EXEC SQL SELECT value INTO :value FROM numvalues WHERE name = :name;
835 if (dbms_errno)
836 return mr_errcode;
837 if (sqlca.sqlerrd[2] != 1)
838 return MR_INTERNAL;
839
840 argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
841 sprintf(argv[argc], "%d", value);
842
843 return MR_SUCCESS;
7f426981 844}
845
846/* prefetch_filesys():
847 * Fetches the phys_id from filesys based on the filsys_id in argv[0].
848 * Appends the filsys_id and the phys_id to the argv so they can be
849 * referenced in an INSERT into a table other than filesys. Also
850 * see comments at prefetch_value().
851 *
852 * Assumes the existence of a row where filsys_id = argv[0], since a
853 * filesys label has already been resolved to a filsys_id.
854 */
5eaef520 855int prefetch_filesys(struct query *q, char **argv, client *cl)
7f426981 856{
5eaef520 857 EXEC SQL BEGIN DECLARE SECTION;
858 int fid, phid;
859 EXEC SQL END DECLARE SECTION;
860 int argc;
7f426981 861
5eaef520 862 fid = *(int *)argv[0];
863 EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid;
864 if (dbms_errno)
865 return mr_errcode;
7f426981 866
5eaef520 867 argc = q->argc + q->vcnt;
868 sprintf(argv[argc++], "%d", phid);
869 sprintf(argv[argc], "%d", fid);
7f426981 870
5eaef520 871 return MR_SUCCESS;
7f426981 872}
873
874
875/* setup_ahst():
876 */
877
5eaef520 878int setup_ahst(struct query *q, char **argv, client *cl)
7f426981 879{
5eaef520 880 EXEC SQL BEGIN DECLARE SECTION;
e688520a 881 char *name, oldname[MACHINE_NAME_SIZE], vendor[MACHINE_VENDOR_SIZE];
db9491c6 882 char model[MACHINE_MODEL_SIZE], os[MACHINE_OS_SIZE];
ff98438b 883 int value, id, ssaddr, smask, shigh, slow, cnt;
884 unsigned int saddr, mask, high, low;
5eaef520 885 EXEC SQL END DECLARE SECTION;
e4ae0190 886 int row, idx;
5eaef520 887 struct in_addr addr;
5eaef520 888
fde09f2c 889 id = *(int *)argv[0];
890
5eaef520 891 if (!strcmp(q->shortname, "uhst"))
85330553 892 {
893 row = 1;
894 EXEC SQL SELECT name, vendor, model, os
895 INTO :oldname, :vendor, :model, :os
896 FROM machine WHERE mach_id = :id;
897 }
5eaef520 898 else
899 row = 0;
900
e4ae0190 901 if (q->version < 6)
902 idx = 0;
903 else
904 idx = 1;
905
9e252e6f 906 /* Sanity check name, vendor, model, and os. */
907 if ((row == 0 || strcasecmp(argv[1], oldname)) &&
908 !hostname_check(argv[row]))
909 return MR_BAD_CHAR;
910 if ((row == 0 || strcasecmp(argv[2], vendor)) &&
17f585b5 911 !hostinfo_check(argv[row + 1], 0))
9e252e6f 912 return MR_BAD_CHAR;
913 if ((row == 0 || strcasecmp(argv[3], model)) &&
17f585b5 914 !hostinfo_check(argv[row + 2], 1))
9e252e6f 915 return MR_BAD_CHAR;
916 if ((row == 0 || strcasecmp(argv[4], os)) &&
17f585b5 917 !hostinfo_check(argv[row + 3], 0))
9e252e6f 918 return MR_BAD_CHAR;
8ca3e341 919
5eaef520 920 /* check for duplicate name */
921 name = argv[row];
922 EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
ad06a10e 923 WHERE name = UPPER(:name);
5eaef520 924 if (dbms_errno)
925 return mr_errcode;
926 if (cnt != 0)
927 return MR_EXISTS;
928
929 /* check address */
e4ae0190 930 if (!strcmp(argv[9 + row + idx], "unassigned"))
5eaef520 931 value = -1;
e4ae0190 932 else if (!strcmp(argv[9 + row + idx], "unique"))
5eaef520 933 {
e4ae0190 934 if (*(int *)argv[8 + row + idx] == 0)
5eaef520 935 value = -1;
936 else
937 value = -2;
938 }
939 else
940 {
e4ae0190 941 value = ntohl(inet_addr(argv[9 + row + idx]));
5eaef520 942 if (value == -1)
943 return MR_ADDRESS;
5482f508 944 }
5eaef520 945 if (value == 0)
946 return MR_ADDRESS;
947 if (value != -1)
948 {
949 /*
950 * an address or unique was specified.
951 */
e4ae0190 952 id = *(int *)argv[8 + row + idx];
ff98438b 953 EXEC SQL SELECT saddr, mask, high, low INTO :ssaddr, :smask,
954 :shigh, :slow FROM subnet WHERE snet_id = :id;
5eaef520 955 if (dbms_errno)
956 return mr_errcode;
ff98438b 957 saddr = (unsigned) ssaddr;
958 mask = (unsigned) smask;
959 high = (unsigned) shigh;
960 low = (unsigned) slow;
5eaef520 961 if (value != -2)
962 {
963 /*
964 * someone specified an IP address for the host record
965 */
082466aa 966 if ((value & mask) != saddr || value < low || value > high)
5eaef520 967 return MR_ADDRESS;
968 /*
969 * run the address argument through inet_addr(). This
970 * has the effect that any out of bounds host addrs will
971 * be converted to a valid host addr. We do this now
972 * so that the uniqueness check works. We should also
973 * link in an inet_addr() that returns an error for
974 * this case.
975 */
e4ae0190 976 addr.s_addr = inet_addr(argv[9 + row + idx]);
5eaef520 977 name = inet_ntoa(addr);
978 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
979 WHERE address = :name;
980 if (dbms_errno)
981 return mr_errcode;
982 if (cnt > 0)
983 {
984 /*
985 * make IP address is unique. If this a modify request
986 * (row == 1), then we expect one record to exist.
987 */
7ac48069 988 if (row == 0 || (row == 1 && cnt > 1))
5eaef520 989 return MR_ADDRESS;
990 if (row == 1 && cnt == 1)
991 {
992 EXEC SQL SELECT mach_id INTO :id FROM machine
993 WHERE address = :name;
994 if (id != *(int *)argv[0])
995 return MR_ADDRESS;
7f426981 996 }
997 }
5eaef520 998 }
999 else
1000 {
1001 /*
1002 * a "unique" address was specified. Walk through the
1003 * range specified in the network record, return
1004 * error if no room left.
1005 */
1006 for (id = low; id <= high; id++)
1007 {
1008 if (((id & 0xff) == 0) || ((id & 0xff) == 255))
1009 continue;
1010 addr.s_addr = htonl(id);
7ac48069 1011 name = inet_ntoa(addr);
5eaef520 1012 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
1013 WHERE address = :name;
1014 if (dbms_errno)
1015 return mr_errcode;
1016 if (cnt == 0)
1017 break;
7f426981 1018 }
5eaef520 1019 if (cnt != 0)
6715bac2 1020 return MR_NO_ID;
5eaef520 1021 else
1022 value = htonl(id);
7f426981 1023 }
5eaef520 1024 /*
1025 * we have an address in value. Convert it to a string and store it.
1026 */
1027 addr.s_addr = htonl(value);
e4ae0190 1028 strcpy(argv[9 + row + idx], inet_ntoa(addr));
7f426981 1029 }
5eaef520 1030 else
e4ae0190 1031 strcpy(argv[9 + row + idx], "unassigned");
5eaef520 1032
1033 /* status checking */
e4ae0190 1034 value = atoi(argv[7 + row + idx]);
5eaef520 1035 if (row == 0 && !(value == 1 || value == 0))
1036 return MR_TYPE;
1037 if (row == 1)
1038 {
1039 id = *(int *)argv[0];
1040 EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
1041 if (dbms_errno)
1042 return mr_errcode;
1043 if (value != cnt)
1044 {
1045 EXEC SQL UPDATE machine SET statuschange = SYSDATE
1046 WHERE mach_id = :id;
7f426981 1047 }
1048 }
1049
5eaef520 1050 /*
1051 * If this is an update_host query, we're done.
1052 */
1053 if (row == 1)
1054 return MR_SUCCESS;
1055
1056 /*
1057 * For an add_host query, allocate and fill in a new machine id,
1058 * and then insert the creator id.
1059 */
1060 if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
1061 return mr_errcode;
1062
1063 sprintf(argv[q->argc + q->vcnt + 1], "%d", cl->client_id);
1064 return MR_SUCCESS;
7f426981 1065}
1066
1067
1068/* setup_ahal():
1069 */
1070
5eaef520 1071int setup_ahal(struct query *q, char **argv, client *cl)
7f426981 1072{
5eaef520 1073 EXEC SQL BEGIN DECLARE SECTION;
1074 char *name;
1075 int cnt;
1076 EXEC SQL END DECLARE SECTION;
1077 char *p;
1078
84f3d463 1079 name = argv[0];
1080 if (!hostname_check(argv[0]))
5eaef520 1081 return MR_BAD_CHAR;
7f426981 1082
5eaef520 1083 EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
ad06a10e 1084 name = UPPER(:name);
5eaef520 1085 if (dbms_errno)
1086 return mr_errcode;
1087 if (cnt > 0)
1088 return MR_EXISTS;
7f426981 1089
5eaef520 1090 return MR_SUCCESS;
7f426981 1091}
84f3d463 1092
2884200f 1093/* setup_uhha(): Check characters in hwaddr, and make sure it's not
1094 * a duplicate.
1095 */
1096int setup_uhha(struct query *q, char **argv, client *cl)
1097{
1098 EXEC SQL BEGIN DECLARE SECTION;
1099 char *hwaddr = argv[1];
1100 int count;
1101 EXEC SQL END DECLARE SECTION;
1102 char *p;
1103
1104 if (*hwaddr && strcasecmp(hwaddr, "unknown"))
1105 {
1106 for (p = hwaddr; *p; p++)
1107 {
1108 if (isupper(*p))
1109 *p = tolower(*p);
1110 if (!isxdigit(*p))
1111 return MR_BAD_CHAR;
1112 }
1113 if (p != hwaddr + 12)
1114 return MR_ADDRESS;
1115
1116 EXEC SQL SELECT COUNT(hwaddr) INTO :count
1117 FROM machine WHERE hwaddr = :hwaddr;
1118 if (count)
1119 return MR_NOT_UNIQUE;
1120 }
1121
1122 return MR_SUCCESS;
1123}
1124
1125/* setup_aprn(): Make sure name/duplexname don't conflict with
1126 * anything. If [ANY] was specified for the spooling host, pick the
1127 * least loaded print server that serves this kind of printer.
1128 */
1129int setup_aprn(struct query *q, char **argv, client *cl)
1130{
1a9a0a59 1131 int best = -1, row;
2884200f 1132 char *p;
1133 EXEC SQL BEGIN DECLARE SECTION;
1134 int mid, usage, count;
1a9a0a59 1135 char types[STRINGS_STRING_SIZE], *hwaddr, *name, *duplexname, *oldname;
2884200f 1136 EXEC SQL END DECLARE SECTION;
1137
1a9a0a59 1138 /* Check for aprn or uprn. */
1139 if (q->type == APPEND)
1140 row = 0;
1141 else
1142 row = 1;
1143
1144 name = argv[PRN_NAME + row];
1145 duplexname = argv[PRN_DUPLEXNAME + row];
1146 oldname = argv[0];
1147
2884200f 1148 if (!*name)
1149 return MR_BAD_CHAR;
1150 else
1151 {
1a9a0a59 1152 if (q->type == APPEND)
1153 {
1154 EXEC SQL SELECT COUNT(name) INTO :count FROM printers
1155 WHERE name = :name OR duplexname = :name;
1156 }
1157 else
1158 {
1159 EXEC SQL SELECT COUNT(name) INTO :count FROM printers
1160 WHERE ( name = :name OR duplexname = :name )
1161 AND name != :oldname;
1162 }
2884200f 1163 if (dbms_errno)
1164 return mr_errcode;
1165 if (count)
1166 return MR_NOT_UNIQUE;
1167 }
1168
1a9a0a59 1169 if (*duplexname)
2884200f 1170 {
1a9a0a59 1171 if (q->type == APPEND)
1172 {
1173 EXEC SQL SELECT COUNT(name) INTO :count FROM printers
1174 WHERE name = :duplexname OR duplexname = :duplexname;
1175 }
1176 else
1177 {
1178 EXEC SQL SELECT COUNT(name) INTO :count FROM printers
1179 WHERE ( name = :duplexname OR duplexname = :duplexname )
1180 AND name != :oldname;
1181 }
1182
2884200f 1183 if (dbms_errno)
1184 return mr_errcode;
1185 if (count)
1186 return MR_NOT_UNIQUE;
1187 }
1188
1a9a0a59 1189 if (!strcmp(name, duplexname))
1190 return MR_NOT_UNIQUE;
1191
1192 mid = *(int *)argv[PRN_RM + row];
1193 if (mid == -1)
2884200f 1194 {
1195 EXEC SQL DECLARE csr_rm CURSOR FOR
1a9a0a59 1196 SELECT ps.mach_id, s.string FROM printservers ps, strings s
b3e26217 1197 WHERE ps.mach_id IN
1198 ( SELECT mach_id FROM serverhosts WHERE service = 'PRINT'
1199 AND enable = 1 )
1200 AND ps.printer_types = s.string_id;
2884200f 1201 if (dbms_errno)
1202 return mr_errcode;
1203 EXEC SQL OPEN csr_rm;
1204 if (dbms_errno)
1205 return mr_errcode;
1206
1207 while (1)
1208 {
1a9a0a59 1209 EXEC SQL FETCH csr_rm INTO :mid, :types;
2884200f 1210 if (sqlca.sqlcode)
1211 break;
1212
2884200f 1213 for (p = strtok(types, ", "); p; p = strtok(NULL, ", "))
1214 {
1a9a0a59 1215 if (!strcasecmp(argv[PRN_TYPE + row], p))
2884200f 1216 {
1a9a0a59 1217 EXEC SQL SELECT COUNT(name) INTO :usage
cc0ea77e 1218 FROM printers WHERE rm = :mid;
1a9a0a59 1219
119230bb 1220 if (best < 0 || usage < best)
1a9a0a59 1221 {
1222 best = usage;
1223 *(int *)argv[PRN_RM + row] = mid;
1224 break;
1225 }
2884200f 1226 }
1227 }
1228 }
1229 EXEC SQL CLOSE csr_rm;
1230 if (dbms_errno)
1231 return mr_errcode;
1232
1233 if (best == -1)
1234 return MR_SERVICE;
1235 }
2681538c 1236 else
1237 {
1238 EXEC SQL SELECT mach_id INTO :mid FROM printservers
1239 WHERE mach_id = :mid;
1240 if (sqlca.sqlcode)
1241 return MR_SERVICE;
1242 }
2884200f 1243
1244 return MR_SUCCESS;
1245}
1246
1a9a0a59 1247int setup_dpsv(struct query *q, char **argv, client *cl)
1248{
1249 int id;
1250 EXEC SQL BEGIN DECLARE SECTION;
1251 int cnt;
1252 EXEC SQL END DECLARE SECTION;
1253
1254 id = *(int *)argv[0];
1255
1256 EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
1257 WHERE rm = :id;
1258 if (cnt > 0)
1259 return MR_IN_USE;
1260
1261 return MR_SUCCESS;
1262}
1263
2fb668b0 1264int setup_dcon(struct query *q, char *argv[], client *cl)
1265{
1266 EXEC SQL BEGIN DECLARE SECTION;
1267 int id, cnt;
1268 char containername[CONTAINERS_NAME_SIZE];
1269 EXEC SQL END DECLARE SECTION;
1270
1271 id = *(int *)argv[0];
1272 /* check to see if there are machines in this container */
1273 EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcntmap
1274 WHERE cnt_id = :id;
1275 if (cnt > 0)
1276 return MR_IN_USE;
1277
1278 /* check to see if there are subcontainers in this container */
1279
1280 /* get the container name */
1281
1282 EXEC SQL SELECT name INTO :containername
1283 FROM containers
1284 WHERE cnt_id = :id;
1285
1286 /* trim off the trailing spaces */
1287 strcpy(containername, strtrim(containername));
1288
1289 EXEC SQL SELECT COUNT(cnt_id) INTO :cnt FROM containers
1290 WHERE name LIKE :containername || '/' || '%';
1291
1292 if (cnt > 0)
1293 return MR_IN_USE;
1294
1295 if (dbms_errno)
1296 return mr_errcode;
1297 return MR_SUCCESS;
1298}
1299
84f3d463 1300/* hostname_check()
9e252e6f 1301 * validate the rfc1035/rfc1123-ness of a hostname
84f3d463 1302 */
1303
1304int hostname_check(char *name)
1305{
1306 char *p;
1307 int count;
1308
9e252e6f 1309 /* Sanity check name: must contain only letters, numerals, and
1310 * hyphen, and not start or end with a hyphen. Also make sure no
16affa56 1311 * label (the thing the .s seperate) is longer than 63 characters,
1312 * or empty.
84f3d463 1313 */
1314
9e252e6f 1315 for (p = name, count = 0; *p; p++)
84f3d463 1316 {
1317 count++;
1318 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1319 (*p == '-' && p[1] == '.'))
1320 return 0;
1321 if (*p == '.')
16affa56 1322 {
1323 if (count == 1)
1324 return 0;
1325 count = 0;
1326 }
84f3d463 1327 if (count == 64)
1328 return 0;
1329 }
1330 if (*(p - 1) == '-')
1331 return 0;
1332 return 1;
1333}
9e252e6f 1334
17f585b5 1335int hostinfo_check(char *info, int num)
9e252e6f 1336{
1337 char *p;
1338
1339 if (!*info)
1340 return 1;
1341
17f585b5 1342 /* Sanity check host hostinfo: must start with a letter (or number
1343 * if num is true), contain only letters, numerals, and hyphen, and
1344 * not end with a hyphen.
9e252e6f 1345 */
1346
17f585b5 1347 if (!isalpha(*info) && (!num || !isdigit(*info)))
9e252e6f 1348 return 0;
1349 for (p = info; *p; p++)
1350 {
1351 if ((!isalnum(*p) && *p != '-' && *p != '.') ||
1352 (*p == '-' && p[1] == '.'))
1353 return 0;
1354 }
1355 if (!isalnum(*(p - 1)))
1356 return 1;
1357}
This page took 0.342916 seconds and 5 git commands to generate.