]> andersk Git - moira.git/blame - server/qsupport.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / server / qsupport.qc
CommitLineData
05cdd922 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
05cdd922 9 *
05cdd922 10 */
11
12#ifndef lint
13static char *rcsid_qsupport_qc = "$Header$";
14#endif lint
15
c801de4c 16#include <mit-copyright.h>
05cdd922 17#include "query.h"
d548a4e7 18#include "mr_server.h"
05cdd922 19#include <ctype.h>
20
05cdd922 21
822a6eba 22extern char *whoami, *strsave();
d548a4e7 23extern int ingres_errno, mr_errcode;
822a6eba 24
05cdd922 25
26/* Specialized Access Routines */
27
822a6eba 28/* access_user - verify that client name equals specified login name
29 *
30 * - since field validation routines are called first, a users_id is
31 * now in argv[0] instead of the login name.
32 */
05cdd922 33
34access_user(q, argv, cl)
35 struct query *q;
36 char *argv[];
37 client *cl;
822a6eba 38{
39 if (cl->users_id != *(int *)argv[0])
d548a4e7 40 return(MR_PERM);
822a6eba 41 else
d548a4e7 42 return(MR_SUCCESS);
822a6eba 43}
05cdd922 44
05cdd922 45
30967516 46
822a6eba 47/* access_login - verify that client name equals specified login name
48 *
49 * argv[0...n] contain search info. q->
50 */
51
52access_login(q, argv, cl)
30967516 53 struct query *q;
54 char *argv[];
55 client *cl;
56##{
822a6eba 57## int rowcount, id;
58## char qual[256];
59
60 build_qual(q->qual, q->argc, argv, qual);
711660a5 61## range of u is users
822a6eba 62## retrieve (id = u.users_id) where qual
63## inquire_equel(rowcount = "rowcount")
64 if (rowcount != 1 || id != cl->users_id)
d548a4e7 65 return(MR_PERM);
822a6eba 66 else
d548a4e7 67 return(MR_SUCCESS);
30967516 68##}
69
822a6eba 70
71
72/* access_list - check access for most list operations
73 *
74 * Inputs: argv[0] - list_id
75 * q - query name
76 * argv[2] - member ID (only for queries "amtl" and "dmfl")
4179b9ce 77 * argv[7] - group IID (only for query "ulis")
78 * cl - client name
822a6eba 79 *
80 * - check that client is a member of the access control list
81 * - OR, if the query is add_member_to_list or delete_member_from_list
82 * and the list is public, allow access if client = member
83 */
05cdd922 84
85access_list(q, argv, cl)
86 struct query *q;
87 char *argv[];
88 client *cl;
89##{
4179b9ce 90## int list_id, acl_id, flags, rowcount, gid;
822a6eba 91## char acl_type[9];
05cdd922 92 char *client_type;
822a6eba 93 int client_id, status;
05cdd922 94
95 list_id = *(int *)argv[0];
822a6eba 96## repeat retrieve (acl_id = list.#acl_id, acl_type = list.#acl_type,
4179b9ce 97## gid = list.#gid, flags = list.#public)
05cdd922 98## where list.#list_id = @list_id
822a6eba 99## inquire_equel(rowcount = "rowcount")
100 if (rowcount != 1)
d548a4e7 101 return(MR_INTERNAL);
05cdd922 102
103 /* parse client structure */
d548a4e7 104 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
822a6eba 105 return(status);
05cdd922 106
107 /* if amtl or dmfl and list is public allow client to add or delete self */
a6683dad 108 if (((!strcmp("amtl", q->shortname) && flags) ||
109 (!strcmp("dmfl", q->shortname))) &&
110 (!strcmp("USER", argv[1]))) {
d548a4e7 111 if (*(int *)argv[2] == client_id) return(MR_SUCCESS);
4179b9ce 112 /* if update_list, don't allow them to change the GID */
113 } else if (!strcmp("ulis", q->shortname)) {
114 if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
115 (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
d548a4e7 116 return(MR_PERM);
05cdd922 117 }
118
119 /* check for client in access control list */
822a6eba 120 status = find_member(acl_type, acl_id, client_type, client_id, 0);
d548a4e7 121 if (!status) return(MR_PERM);
05cdd922 122
d548a4e7 123 return(MR_SUCCESS);
05cdd922 124##}
92a943d6 125
a6cb4d4c 126
822a6eba 127/* access_visible_list - allow access to list only if it is not hidden,
128 * or if the client is on the ACL
129 *
130 * Inputs: argv[0] - list_id
131 * cl - client identifier
132 */
133
134access_visible_list(q, argv, cl)
a6cb4d4c 135 struct query *q;
136 char *argv[];
137 client *cl;
138##{
822a6eba 139## int list_id, acl_id, flags, rowcount;
140## char acl_type[9];
141 char *client_type;
142 int client_id, status;
a6cb4d4c 143
144 list_id = *(int *)argv[0];
822a6eba 145## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
146## acl_type = list.#acl_type) where list.#list_id = @list_id
147## inquire_equel(rowcount = "rowcount")
148 if (rowcount != 1)
d548a4e7 149 return(MR_INTERNAL);
822a6eba 150 if (!flags)
d548a4e7 151 return(MR_SUCCESS);
822a6eba 152
711660a5 153
822a6eba 154 /* parse client structure */
d548a4e7 155 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
822a6eba 156 return(status);
157
158 /* check for client in access control list */
159 status = find_member(acl_type, acl_id, client_type, client_id, 0);
160 if (!status)
d548a4e7 161 return(MR_PERM);
822a6eba 162
d548a4e7 163 return(MR_SUCCESS);
a6cb4d4c 164##}
165
92a943d6 166
822a6eba 167/* access_vis_list_by_name - allow access to list only if it is not hidden,
168 * or if the client is on the ACL
169 *
170 * Inputs: argv[0] - list name
171 * cl - client identifier
172 */
173
174access_vis_list_by_name(q, argv, cl)
92a943d6 175 struct query *q;
176 char *argv[];
177 client *cl;
92a943d6 178##{
822a6eba 179## int acl_id, flags, rowcount;
180## char acl_type[9], *listname;
181 char *client_type;
182 int client_id, status;
183
184 listname = argv[0];
185## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
186## acl_type = list.#acl_type) where list.#name = @listname
187## inquire_equel(rowcount = "rowcount");
188 if (rowcount > 1)
d548a4e7 189 return(MR_WILDCARD);
822a6eba 190 if (rowcount == 0)
d548a4e7 191 return(MR_NO_MATCH);
822a6eba 192 if (!flags)
d548a4e7 193 return(MR_SUCCESS);
92a943d6 194
822a6eba 195 /* parse client structure */
d548a4e7 196 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
822a6eba 197 return(status);
198
199 /* check for client in access control list */
200 status = find_member(acl_type, acl_id, client_type, client_id, 0);
201 if (!status)
d548a4e7 202 return(MR_PERM);
822a6eba 203
d548a4e7 204 return(MR_SUCCESS);
92a943d6 205##}
05cdd922 206
822a6eba 207
208/* access_member - allow user to access member of type "USER" and name matches
209 * username, or to access member of type "LIST" and list is one that user is
210 * on the acl of, or the list is visible.
211 */
212
213access_member(q, argv, cl)
05cdd922 214 struct query *q;
822a6eba 215 char *argv[];
05cdd922 216 client *cl;
822a6eba 217{
218 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
219 return(access_visible_list(q, &argv[1], cl));
05cdd922 220
822a6eba 221 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
4179b9ce 222 if (cl->users_id == *(int *)argv[1])
d548a4e7 223 return(MR_SUCCESS);
05cdd922 224 }
225
d548a4e7 226 return(MR_PERM);
822a6eba 227}
05cdd922 228
05cdd922 229
822a6eba 230/* access_qgli - special access routine for Qualified_get_lists. Allows
231 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
232 */
233
234access_qgli(q, argv, cl)
235 struct query *q;
236 char *argv[];
237 client *cl;
238{
239 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
d548a4e7 240 return(MR_SUCCESS);
241 return(MR_PERM);
822a6eba 242}
243
244
245/* access_service - allow access if user is on ACL of service. Don't
246 * allow access if a wildcard is used.
247 */
05cdd922 248
822a6eba 249access_service(q, argv, cl)
05cdd922 250 struct query *q;
251 char *argv[];
822a6eba 252 client *cl;
05cdd922 253##{
822a6eba 254## int acl_id, rowcount;
255## char *name, acl_type[9];
256 int client_id, status;
257 char *client_type;
05cdd922 258
822a6eba 259 name = argv[0];
260## repeat retrieve (acl_id = servers.#acl_id, acl_type = servers.#acl_type)
44bd6f44 261## where servers.#name = uppercase(@name)
822a6eba 262## inquire_equel(rowcount = "rowcount")
263 if (rowcount > 1)
d548a4e7 264 return(MR_PERM);
05cdd922 265
822a6eba 266 /* parse client structure */
d548a4e7 267 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
822a6eba 268 return(status);
92a943d6 269
822a6eba 270 /* check for client in access control list */
271 status = find_member(acl_type, acl_id, client_type, client_id, 0);
d548a4e7 272 if (!status) return(MR_PERM);
05cdd922 273
d548a4e7 274 return(MR_SUCCESS);
92a943d6 275##}
276
822a6eba 277
278
279/* access_filesys - verify that client is owner or on owners list of filesystem
280 * named by argv[0]
281 */
282
283access_filesys(q, argv, cl)
92a943d6 284 struct query *q;
285 char *argv[];
822a6eba 286 client *cl;
92a943d6 287##{
822a6eba 288## int rowcount, users_id, list_id;
289## char *name;
290 int status, client_id;
291 char *client_type;
92a943d6 292
822a6eba 293 name = argv[0];
294## repeat retrieve (users_id = filesys.owner, list_id = filesys.owners)
295## where filesys.label = @name
296## inquire_equel(rowcount = "rowcount")
297
298 if (rowcount != 1)
d548a4e7 299 return(MR_PERM);
822a6eba 300 if (users_id == cl->users_id)
d548a4e7 301 return(MR_SUCCESS);
302 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
db8a5dda 303 return(status);
304 status = find_member("LIST", list_id, client_type, client_id, 0);
305 if (status)
d548a4e7 306 return(MR_SUCCESS);
db8a5dda 307 else
d548a4e7 308 return(MR_PERM);
05cdd922 309##}
822a6eba 310
311
05cdd922 312\f
822a6eba 313/* Setup Routines */
314
315/* Setup routine for add_user
316 *
317 * Inputs: argv[0] - login
318 * argv[1] - uid
319 *
320 * Description:
321 *
322 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
323 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
324 */
c2408bd5 325
822a6eba 326setup_ausr(q, argv, cl)
c2408bd5 327 struct query *q;
822a6eba 328 register char *argv[];
329 client *cl;
330##{
331## int nuid, rowcount;
c928f249 332## char *mit_id;
333
2ff2da4a 334#ifdef notdef
335 /* this is currently disabled because we need an index on ID's
336 * before it can run in finite time.
337 */
c928f249 338 mit_id = argv[U_MITID];
339## retrieve (rowcount = any(u.#mit_id where u.#mit_id = mit_id))
340 if (ingres_errno) return(mr_errcode);
341 if (rowcount) return(MR_EXISTS);
2ff2da4a 342#endif notdef
822a6eba 343
344 if (!strcmp(argv[1], UNIQUE_UID) || atoi(argv[1]) == -1) {
345 if (set_next_object_id("uid", "users"))
d548a4e7 346 return(MR_INGRES_ERR);
822a6eba 347## repeat retrieve (nuid = values.value) where values.name = "uid"
348## inquire_equel(rowcount = "rowcount")
349 if (rowcount != 1)
d548a4e7 350 return(MR_INTERNAL);
822a6eba 351 sprintf(argv[1], "%d", nuid);
352 }
c2408bd5 353
822a6eba 354 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[1]) == -1) {
355 sprintf(argv[0], "#%s", argv[1]);
356 }
c2408bd5 357
d548a4e7 358 return(MR_SUCCESS);
822a6eba 359##}
c2408bd5 360
c2408bd5 361
822a6eba 362/* setup_dusr - verify that the user is no longer being referenced
363 * and may safely be deleted.
364 */
c2408bd5 365
822a6eba 366int setup_dusr(q, argv)
367 struct query *q;
368 char **argv;
369##{
370## int flag, id;
371
372 id = *(int *)argv[0];
331b982e 373
374 /* For now, only allow users to be deleted if their status is 0 */
375## repeat retrieve (flag = u.status) where u.users_id = @id
711660a5 376 if (flag != 0 && flag != 4)
d548a4e7 377 return(MR_IN_USE);
331b982e 378
368be132 379## repeat delete quota where quota.entity_id = @id and quota.type = "USER"
711660a5 380## repeat delete krbmap where krbmap.users_id = @id
a6683dad 381## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
382## and imembers.member_type = "USER"))
822a6eba 383 if (flag)
d548a4e7 384 return(MR_IN_USE);
822a6eba 385## repeat retrieve (flag = any(filesys.label where filesys.owner=@id))
386 if (flag)
d548a4e7 387 return(MR_IN_USE);
822a6eba 388## repeat retrieve (flag = any(list.name where list.acl_id=@id and
389## list.acl_type = "USER"))
390 if (flag)
d548a4e7 391 return(MR_IN_USE);
822a6eba 392## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
393## servers.acl_type = "USER"))
394 if (flag)
d548a4e7 395 return(MR_IN_USE);
44bd6f44 396## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
397## hostaccess.acl_type = "USER"))
398 if (flag)
d548a4e7 399 return(MR_IN_USE);
02ccf7ad 400 if (ingres_errno)
d548a4e7 401 return(mr_errcode);
402 return(MR_SUCCESS);
822a6eba 403##}
c2408bd5 404
822a6eba 405
406/* setup_spop: verify that there is already a valid POP machine_id in the
407 * pop_id field. Also take care of keeping track of the post office usage.
408 */
409int setup_spop(q, argv)
410struct query *q;
411char **argv;
c2408bd5 412##{
e7fa3293 413## int id, mid, flag;
822a6eba 414## char type[9];
415
416 id = *(int *)argv[0];
e7fa3293 417## repeat retrieve (type = u.potype, mid = u.pop_id,
418## flag = any(machine.name where machine.mach_id = u.pop_id
419## and u.pop_id != 0 and u.users_id = @id))
4f16dc86 420## where u.users_id = @id
822a6eba 421 if (!flag)
d548a4e7 422 return(MR_MACHINE);
e7fa3293 423 if (strcmp(strtrim(type), "POP"))
424 set_pop_usage(mid, 1);
d548a4e7 425 return(MR_SUCCESS);
822a6eba 426##}
c2408bd5 427
c2408bd5 428
822a6eba 429/* setup_dpob: Take care of keeping track of the post office usage.
430 */
431int setup_dpob(q, argv)
432struct query *q;
433char **argv;
434##{
435## int id, user;
436## char type[9];
437
438 user = *(int *)argv[0];
439## repeat retrieve (type = u.potype, id = u.pop_id)
440## where u.users_id = @user
d548a4e7 441 if (ingres_errno) return(mr_errcode);
c2408bd5 442
e7fa3293 443 if (!strcmp(strtrim(type), "POP"))
822a6eba 444 set_pop_usage(id, -1);
d548a4e7 445 return(MR_SUCCESS);
c2408bd5 446##}
447
c2408bd5 448
822a6eba 449/* setup_dmac - verify that the machine is no longer being referenced
450 * and may safely be deleted.
451 */
c2408bd5 452
822a6eba 453int setup_dmac(q, argv)
05cdd922 454 struct query *q;
822a6eba 455 char **argv;
05cdd922 456##{
822a6eba 457## int flag, id;
458
459 id = *(int *)argv[0];
460## repeat retrieve (flag = any(users.login where users.potype = "POP"
461## and users.pop_id=@id))
462 if (flag)
d548a4e7 463 return(MR_IN_USE);
822a6eba 464## repeat retrieve (flag = any(serverhosts.mach_id
465## where serverhosts.mach_id=@id))
466 if (flag)
d548a4e7 467 return(MR_IN_USE);
822a6eba 468## repeat retrieve (flag = any(nfsphys.mach_id where nfsphys.mach_id=@id))
469 if (flag)
d548a4e7 470 return(MR_IN_USE);
822a6eba 471## repeat retrieve (flag = any(hostaccess.mach_id where hostaccess.mach_id=@id))
472 if (flag)
d548a4e7 473 return(MR_IN_USE);
e7fa3293 474## repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
331b982e 475 if (flag)
d548a4e7 476 return(MR_IN_USE);
4ebd65d7 477## repeat retrieve (flag = any(printcap.quotaserver where printcap.quotaserver=@id))
478 if (flag)
479 return(MR_IN_USE);
711660a5 480## repeat retrieve (flag = any(palladium.mach_id where palladium.mach_id=@id))
481 if (flag)
d548a4e7 482 return(MR_IN_USE);
44bd6f44 483
484## repeat delete mcmap where mcmap.mach_id = @id
d548a4e7 485 if (ingres_errno) return(mr_errcode);
486 return(MR_SUCCESS);
05cdd922 487##}
488
05cdd922 489
822a6eba 490/* setup_dclu - verify that the cluster is no longer being referenced
491 * and may safely be deleted.
492 */
05cdd922 493
822a6eba 494int setup_dclu(q, argv)
05cdd922 495 struct query *q;
822a6eba 496 char **argv;
05cdd922 497##{
822a6eba 498## int flag, id;
499
500 id = *(int *)argv[0];
501## repeat retrieve (flag = any(mcmap.mach_id where mcmap.clu_id=@id))
502 if (flag)
d548a4e7 503 return(MR_IN_USE);
822a6eba 504## repeat retrieve (flag = any(svc.clu_id where svc.clu_id=@id))
505 if (flag)
d548a4e7 506 return(MR_IN_USE);
02ccf7ad 507 if (ingres_errno)
d548a4e7 508 return(mr_errcode);
509 return(MR_SUCCESS);
05cdd922 510##}
511
05cdd922 512
822a6eba 513/* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
514 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
515 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
516 * a -1 there. Remember that this is also used for ulis, with the indexes
517 * at 6 & 7.
518 */
05cdd922 519
822a6eba 520int setup_alis(q, argv)
521struct query *q;
522char **argv;
05cdd922 523##{
822a6eba 524## int ngid;
525 char *malloc();
526 int idx;
527
528 if (!strcmp(q->shortname, "alis"))
529 idx = 6;
530 else if (!strcmp(q->shortname, "ulis"))
531 idx = 7;
532
533 if (!strcmp(argv[idx], UNIQUE_GID) || atoi(argv[idx]) == -1) {
534 if (atoi(argv[idx - 1])) {
535 if (set_next_object_id("gid", "list"))
d548a4e7 536 return(MR_INGRES_ERR);
822a6eba 537## repeat retrieve (ngid = values.value) where values.name = "gid"
d548a4e7 538 if (ingres_errno) return(mr_errcode);
822a6eba 539 sprintf(argv[idx], "%d", ngid);
540 } else {
541 strcpy(argv[idx], "-1");
542 }
543 }
05cdd922 544
d548a4e7 545 return(MR_SUCCESS);
05cdd922 546##}
a6cb4d4c 547
822a6eba 548
549/* setup_dlist - verify that the list is no longer being referenced
550 * and may safely be deleted.
551 */
552
553int setup_dlis(q, argv)
a6cb4d4c 554 struct query *q;
822a6eba 555 char **argv;
a6cb4d4c 556##{
822a6eba 557## int flag, id;
558
559 id = *(int *)argv[0];
a6683dad 560## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
561## and imembers.member_type = "LIST"))
822a6eba 562 if (flag)
d548a4e7 563 return(MR_IN_USE);
a6683dad 564## repeat retrieve (flag = any(imembers.member_id where imembers.list_id=@id))
822a6eba 565 if (flag)
d548a4e7 566 return(MR_IN_USE);
822a6eba 567## repeat retrieve (flag = any(filesys.label where filesys.owners=@id))
568 if (flag)
d548a4e7 569 return(MR_IN_USE);
822a6eba 570## repeat retrieve (flag = any(capacls.tag where capacls.list_id=@id))
571 if (flag)
d548a4e7 572 return(MR_IN_USE);
822a6eba 573## repeat retrieve (flag = any(list.name where list.acl_id=@id and
4f16dc86 574## list.acl_type = "LIST" and list.list_id != @id))
822a6eba 575 if (flag)
d548a4e7 576 return(MR_IN_USE);
822a6eba 577## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
578## servers.acl_type = "LIST"))
579 if (flag)
d548a4e7 580 return(MR_IN_USE);
0c614667 581## repeat retrieve (flag = any(quota.entity_id where quota.entity_id=@id and
582## quota.type = "GROUP"))
4ebd65d7 583 if (flag)
584 return(MR_IN_USE);
44bd6f44 585## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
586## hostaccess.acl_type = "LIST"))
587 if (flag)
d548a4e7 588 return(MR_IN_USE);
822a6eba 589## repeat retrieve (flag = any(zephyr.class
590## where zephyr.xmt_type = "LIST" and zephyr.xmt_id = @id or
591## zephyr.sub_type = "LIST" and zephyr.sub_id = @id or
592## zephyr.iws_type = "LIST" and zephyr.iws_id = @id or
593## zephyr.iui_type = "LIST" and zephyr.iui_id = @id))
594 if (flag)
d548a4e7 595 return(MR_IN_USE);
02ccf7ad 596 if (ingres_errno)
d548a4e7 597 return(mr_errcode);
598 return(MR_SUCCESS);
822a6eba 599##}
a6cb4d4c 600
a6cb4d4c 601
822a6eba 602/* setup_dsin - verify that the service is no longer being referenced
603 * and may safely be deleted.
604 */
a6cb4d4c 605
822a6eba 606int setup_dsin(q, argv)
607 struct query *q;
608 char **argv;
609##{
610## int flag;
611## char *name;
612
613 name = argv[0];
44bd6f44 614## repeat retrieve (flag = any(serverhosts.service
615## where serverhosts.service=uppercase(@name)))
822a6eba 616 if (flag)
d548a4e7 617 return(MR_IN_USE);
822a6eba 618## repeat retrieve (flag = servers.inprogress) where servers.#name = @name
619 if (flag)
d548a4e7 620 return(MR_IN_USE);
02ccf7ad 621 if (ingres_errno)
d548a4e7 622 return(mr_errcode);
623 return(MR_SUCCESS);
822a6eba 624##}
a6cb4d4c 625
a6cb4d4c 626
822a6eba 627/* setup_dshi - verify that the service-host is no longer being referenced
628 * and may safely be deleted.
629 */
a6cb4d4c 630
822a6eba 631int setup_dshi(q, argv)
632 struct query *q;
633 char **argv;
634##{
635## int flag, id;
636## char *name;
a6cb4d4c 637
822a6eba 638 name = argv[0];
639 id = *(int *)argv[1];
640## repeat retrieve (flag=serverhosts.inprogress)
44bd6f44 641## where serverhosts.service=uppercase(@name) and serverhosts.mach_id=@id
822a6eba 642 if (flag)
d548a4e7 643 return(MR_IN_USE);
02ccf7ad 644 if (ingres_errno)
d548a4e7 645 return(mr_errcode);
646 return(MR_SUCCESS);
a6cb4d4c 647##}
822a6eba 648
649
a6cb4d4c 650/**
822a6eba 651 ** setup_add_filesys - verify existance of referenced file systems
652 **
653 ** Inputs: Add
654 ** argv[1] - type
655 ** argv[2] - mach_id
656 ** argv[3] - name
657 ** argv[5] - access
a6cb4d4c 658 **
659 ** Description:
822a6eba 660 ** - for type = RVD:
661 ** * allow anything
662 ** - for type = NFS:
663 ** * extract directory prefix from name
664 ** * verify mach_id/dir in nfsphys
665 ** * verify access in {r, w, R, W}
666 **
667 ** Side effect: sets variable var_phys_id to the ID of the physical
668 ** filesystem (nfsphys_id for NFS, 0 for RVD)
a6cb4d4c 669 **
822a6eba 670 ** Errors:
d548a4e7 671 ** MR_NFS - specified directory not exported
672 ** MR_FILESYS_ACCESS - invalid filesys access
a6cb4d4c 673 **
674 **/
675
822a6eba 676##static int var_phys_id;
a6cb4d4c 677
822a6eba 678setup_afil(q, argv)
a6cb4d4c 679 struct query *q;
680 char *argv[];
4ebd65d7 681##{
682 char *type, *name;
822a6eba 683 int mach_id;
4ebd65d7 684## int ok;
685## char ftype[32], *access;
a6cb4d4c 686
a6cb4d4c 687 type = argv[1];
688 mach_id = *(int *)argv[2];
822a6eba 689 name = argv[3];
690 access = argv[5];
691 var_phys_id = 0;
a6cb4d4c 692
4ebd65d7 693 sprintf(ftype, "fs_access_%s", type);
694## retrieve (ok = any(alias.trans where alias.name = ftype and
695## alias.type = "TYPE" and alias.trans = access))
696 if (ingres_errno) return(mr_errcode);
697 if (ok == 0) return(MR_FILESYS_ACCESS);
698
822a6eba 699 if (!strcmp(type, "NFS"))
700 return (check_nfs(mach_id, name, access));
701 else
d548a4e7 702 return(MR_SUCCESS);
4ebd65d7 703##}
05cdd922 704
30967516 705
e7fa3293 706/* Verify the arguments, depending on the FStype. Also, if this is an
707 * NFS filesystem, then update any quotas for that filesystem to reflect
708 * the new phys_id.
709 */
710
368be132 711setup_ufil(q, argv, cl)
30967516 712 struct query *q;
713 char *argv[];
368be132 714 client *cl;
e7fa3293 715##{
716 int mach_id, status;
4ebd65d7 717 char *type, *name;
368be132 718## int fid, total, who;
4ebd65d7 719## char *entity, ftype[32], *access;
30967516 720
822a6eba 721 type = argv[2];
722 mach_id = *(int *)argv[3];
723 name = argv[4];
724 access = argv[6];
725 var_phys_id = 0;
49189928 726 fid = *(int *)argv[0];
368be132 727 who = cl->client_id;
728 entity = cl->entity;
a6cb4d4c 729
4ebd65d7 730 sprintf(ftype, "fs_access_%s", type);
731## retrieve (total = any(alias.trans where alias.name = ftype and
732## alias.type = "TYPE" and alias.trans = access))
733 if (ingres_errno) return(mr_errcode);
734 if (total == 0) return(MR_FILESYS_ACCESS);
735
e7fa3293 736 if (!strcmp(type, "NFS")) {
737 status = check_nfs(mach_id, name, access);
368be132 738## replace quota (phys_id = var_phys_id) where quota.filsys_id = fid
d548a4e7 739 if (ingres_errno) return(mr_errcode);
e7fa3293 740 return(status);
49189928 741 } else if (!strcmp(type, "AFS")) {
742 total = 0;
4ebd65d7 743## retrieve (total = sum(quota.quota where quota.filsys_id = fid
744## and quota.phys_id != 0))
d548a4e7 745 if (ingres_errno) return(mr_errcode);
49189928 746 if (total != 0) {
368be132 747## append quota (quota = total, filsys_id = fid,
748## phys_id = 0, entity_id = 0, type = "ANY",
749## modtime = "now", modby = who, modwith = entity)
d548a4e7 750 if (ingres_errno) return(mr_errcode);
49189928 751 }
752 } else {
368be132 753## replace quota (phys_id = 0) where quota.filsys_id = fid
d548a4e7 754 if (ingres_errno) return(mr_errcode);
49189928 755 }
d548a4e7 756 return(MR_SUCCESS);
e7fa3293 757##}
30967516 758
a6cb4d4c 759
822a6eba 760/* Find the NFS physical partition that the named directory is on.
761 * This is done by comparing the dir against the mount point of the
762 * partition. To make sure we get the correct match when there is
763 * more than one, we sort the query in reverse order by dir name.
764 */
a6cb4d4c 765
822a6eba 766##check_nfs(mach_id, name, access)
a6cb4d4c 767## int mach_id;
822a6eba 768 char *name;
769 char *access;
770##{
a30e1c62 771## char dir[81];
822a6eba 772 char caccess;
773 register int status;
774 register char *cp1;
775 register char *cp2;
a6cb4d4c 776
d548a4e7 777 status = MR_NFS;
822a6eba 778## range of np is nfsphys
779## repeat retrieve (var_phys_id = np.#nfsphys_id, dir = trim(np.#dir))
780## where np.#mach_id = @mach_id sort by #dir:d {
781 cp1 = name;
782 cp2 = dir;
783 while (*cp2) {
784 if (*cp1++ != *cp2) break;
785 cp2++;
786 }
787 if (*cp2 == 0) {
d548a4e7 788 status = MR_SUCCESS;
a6cb4d4c 789## endretrieve
790 }
791## }
02ccf7ad 792 if (ingres_errno)
d548a4e7 793 return(mr_errcode);
822a6eba 794 return(status);
30967516 795##}
a6cb4d4c 796
92a943d6 797
f49f997e 798/* setup_dfil: free any quota records and fsgroup info associated with
799 * a filesystem when it is deleted. Also adjust the allocation numbers.
822a6eba 800 */
92a943d6 801
822a6eba 802setup_dfil(q, argv, cl)
803 struct query *q;
804 char **argv;
805 client *cl;
806##{
807## int id;
92a943d6 808
822a6eba 809 id = *(int *)argv[0];
368be132 810## range of q is quota
44bd6f44 811## range of n is nfsphys
812## repeat replace n (allocated=n.allocated-sum(q.quota where q.filsys_id=@id))
cc588c08 813## where n.nfsphys_id = filesys.phys_id and filesys.filsys_id = @id
92a943d6 814
822a6eba 815## repeat delete q where q.filsys_id = @id
f49f997e 816## repeat delete fsgroup where fsgroup.filsys_id = @id
817## repeat delete fsgroup where fsgroup.group_id = @id
d548a4e7 818 if (ingres_errno) return(mr_errcode);
819 return(MR_SUCCESS);
92a943d6 820##}
30967516 821
822a6eba 822
823/* setup_dnfp: check to see that the nfs physical partition does not have
824 * any filesystems assigned to it before allowing it to be deleted.
825 */
826
827setup_dnfp(q, argv, cl)
828 struct query *q;
829 char **argv;
92a943d6 830 client *cl;
92a943d6 831##{
822a6eba 832## int id, exists;
92a943d6 833
822a6eba 834 id = *(int *)argv[0];
835## repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
836 if (exists)
d548a4e7 837 return(MR_IN_USE);
02ccf7ad 838 if (ingres_errno)
d548a4e7 839 return(mr_errcode);
840 return(MR_SUCCESS);
92a943d6 841##}
4b890cc4 842
4b890cc4 843
368be132 844/* setup_dqot: Remove allocation from nfsphys before deleting quota.
822a6eba 845 * argv[0] = filsys_id
368be132 846 * argv[1] = type if "update_quota" or "delete_quota"
847 * argv[2 or 1] = users_id or list_id
822a6eba 848 */
849
368be132 850setup_dqot(q, argv, cl)
822a6eba 851 struct query *q;
852 char **argv;
853 client *cl;
854##{
368be132 855## int quota, fs, id;
856## char *qtype;
822a6eba 857
858 fs = *(int *)argv[0];
368be132 859 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
860 qtype = argv[1];
861 id = *(int *)argv[2];
862 } else {
863 qtype = "USER";
864 id = *(int *)argv[1];
865 }
822a6eba 866
368be132 867## range of q is #quota
868## repeat retrieve (quota = q.#quota) where q.type = @qtype and
869## q.entity_id = @id and q.filsys_id = @fs
822a6eba 870## repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
871## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
d548a4e7 872 if (ingres_errno) return(mr_errcode);
873 return(MR_SUCCESS);
822a6eba 874##}
875
876
67d7b959 877/* setup_sshi: don't exclusive lock the machine table during
878 * set_server_host_internal.
879 */
880
881setup_sshi(q, argv, cl)
882 struct query *q;
883 char **argv;
884 client *cl;
885##{
886## set lockmode session where readlock = system
887##}
888
889
711660a5 890/* setup add_kerberos_user_mapping: add the string to the string
891 * table if necessary.
892 */
893
894setup_akum(q, argv, cl)
895struct query *q;
896char **argv;
897client *cl;
898##{
899## int id, rowcount;
900## char *name;
901
902 name = argv[1];
d548a4e7 903 if (name_to_id(name, "STRING", &id) != MR_SUCCESS) {
904 if (q->type != APPEND) return(MR_STRING);
711660a5 905## range of v is values
906## retrieve (id = v.value) where v.#name = "strings_id"
907 id++;
908## replace v (value = id) where v.#name = "strings_id"
909## append to strings (string_id = id, string = name)
cc588c08 910 cache_entry(name, "STRING", id);
711660a5 911 }
d548a4e7 912 if (ingres_errno) return(mr_errcode);
711660a5 913 *(int *)argv[1] = id;
d548a4e7 914 return(MR_SUCCESS);
711660a5 915##}
916
917
822a6eba 918\f
919/* FOLLOWUP ROUTINES */
920
921/* generic set_modtime routine. This takes the table name from the query,
922 * and will update the modtime, modby, and modwho fields in the entry in
923 * the table whose name field matches argv[0].
924 */
925
926set_modtime(q, argv, cl)
4b890cc4 927 struct query *q;
928 char *argv[];
822a6eba 929 client *cl;
4b890cc4 930##{
822a6eba 931## char *name, *entity, *table;
932## int who;
4b890cc4 933
822a6eba 934 entity = cl->entity;
711660a5 935 who = cl->client_id;
822a6eba 936 table = q->rtable;
937 name = argv[0];
4b890cc4 938
822a6eba 939## replace table (modtime = "now", modby = who, modwith = entity)
940## where table.#name = name
d548a4e7 941 return(MR_SUCCESS);
4b890cc4 942##}
943
822a6eba 944/* generic set_modtime_by_id routine. This takes the table name from
945 * the query, and the id name from the validate record,
946 * and will update the modtime, modby, and modwho fields in the entry in
947 * the table whose id matches argv[0].
948 */
949
950set_modtime_by_id(q, argv, cl)
4b890cc4 951 struct query *q;
822a6eba 952 char **argv;
953 client *cl;
4b890cc4 954##{
822a6eba 955## char *entity, *table, *id_name;
956## int who, id;
957
958 entity = cl->entity;
711660a5 959 who = cl->client_id;
822a6eba 960 table = q->rtable;
961 id_name = q->validate->object_id;
4b890cc4 962
822a6eba 963 id = *(int *)argv[0];
964## replace table (modtime = "now", modby = who, modwith = entity)
965## where table.id_name = id
d548a4e7 966 return(MR_SUCCESS);
4b890cc4 967##}
968
822a6eba 969
970/* Sets the finger modtime on a user record. The users_id will be in argv[0].
971 */
972
973set_finger_modtime(q, argv, cl)
4b890cc4 974 struct query *q;
975 char *argv[];
822a6eba 976 client *cl;
4b890cc4 977##{
822a6eba 978## int users_id, who;
979## char *entity;
980
981 entity = cl->entity;
711660a5 982 who = cl->client_id;
822a6eba 983 users_id = *(int *)argv[0];
4b890cc4 984
822a6eba 985## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
986## where u.#users_id = @users_id
d548a4e7 987 return(MR_SUCCESS);
4b890cc4 988##}
05cdd922 989
822a6eba 990
991/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
992 */
993
994set_pobox_modtime(q, argv, cl)
05cdd922 995 struct query *q;
822a6eba 996 char **argv;
997 client *cl;
05cdd922 998##{
822a6eba 999## int users_id, who;
1000## char *entity;
05cdd922 1001
822a6eba 1002 entity = cl->entity;
711660a5 1003 who = cl->client_id;
822a6eba 1004 users_id = *(int *)argv[0];
05cdd922 1005
822a6eba 1006## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
1007## where users.#users_id = @users_id
d548a4e7 1008 return(MR_SUCCESS);
822a6eba 1009##}
05cdd922 1010
05cdd922 1011
3c7c4a07 1012/* Like set_modtime, but uppercases the name first.
822a6eba 1013 */
1014
3c7c4a07 1015set_uppercase_modtime(q, argv, cl)
822a6eba 1016 struct query *q;
1017 char **argv;
1018 client *cl;
1019##{
3c7c4a07 1020## char *name, *entity, *table;
822a6eba 1021## int who;
1022
1023 entity = cl->entity;
711660a5 1024 who = cl->client_id;
3c7c4a07 1025 table = q->rtable;
1026 name = argv[0];
05cdd922 1027
3c7c4a07 1028## replace table (modtime = "now", modby = who, modwith = entity)
1029## where table.#name = uppercase(name)
d548a4e7 1030 return(MR_SUCCESS);
05cdd922 1031##}
05cdd922 1032
822a6eba 1033
1034/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
1035 * is necessary for add_machine_to_cluster becuase the table that query
1036 * operates on is "mcm", not "machine".
1037 */
1038
1039set_mach_modtime_by_id(q, argv, cl)
05cdd922 1040 struct query *q;
05cdd922 1041 char **argv;
822a6eba 1042 client *cl;
1043##{
1044## char *entity;
1045## int who, id;
05cdd922 1046
822a6eba 1047 entity = cl->entity;
711660a5 1048 who = cl->client_id;
05cdd922 1049
822a6eba 1050 id = *(int *)argv[0];
cc588c08 1051## repeat replace machine (modtime = "now", modby = @who, modwith = @entity)
1052## where machine.mach_id = @id
d548a4e7 1053 return(MR_SUCCESS);
822a6eba 1054##}
05cdd922 1055
05cdd922 1056
822a6eba 1057/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
1058 * is necessary for add_cluster_data and delete_cluster_data becuase the
1059 * table that query operates on is "svc", not "cluster".
1060 */
1061
1062set_cluster_modtime_by_id(q, argv, cl)
1063 struct query *q;
1064 char **argv;
1065 client *cl;
1066##{
1067## char *entity;
1068## int who, id;
1069
1070 entity = cl->entity;
711660a5 1071 who = cl->client_id;
822a6eba 1072
1073 id = *(int *)argv[0];
cc588c08 1074## repeat replace cluster (modtime = "now", modby = @who, modwith = @entity)
1075## where cluster.clu_id = @id
d548a4e7 1076 return(MR_SUCCESS);
05cdd922 1077##}
1078
822a6eba 1079
1080/* sets the modtime on the serverhost where the service name is in argv[0]
1081 * and the mach_id is in argv[1].
1082 */
1083
1084set_serverhost_modtime(q, argv, cl)
92a943d6 1085 struct query *q;
822a6eba 1086 char **argv;
1087 client *cl;
92a943d6 1088##{
822a6eba 1089## char *entity, *serv;
1090## int who, id;
1091
1092 entity = cl->entity;
711660a5 1093 who = cl->client_id;
822a6eba 1094
1095 serv = argv[0];
1096 id = *(int *)argv[1];
1097## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 1098## where sh.service = uppercase(@serv) and sh.mach_id = @id
d548a4e7 1099 return(MR_SUCCESS);
822a6eba 1100##}
1101
1102
1103/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
1104 * directory name is in argv[1].
1105 */
1106
1107set_nfsphys_modtime(q, argv, cl)
1108 struct query *q;
92a943d6 1109 char **argv;
822a6eba 1110 client *cl;
1111##{
1112## char *entity, *dir;
1113## int who, id;
92a943d6 1114
822a6eba 1115 entity = cl->entity;
711660a5 1116 who = cl->client_id;
92a943d6 1117
822a6eba 1118 id = *(int *)argv[0];
1119 dir = argv[1];
1120## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1121## where np.#dir = @dir and np.mach_id = @id
d548a4e7 1122 return(MR_SUCCESS);
822a6eba 1123##}
92a943d6 1124
92a943d6 1125
822a6eba 1126/* sets the modtime on a filesystem, where argv[0] contains the filesys
1127 * label.
1128 */
1129
1130set_filesys_modtime(q, argv, cl)
1131 struct query *q;
1132 char *argv[];
1133 client *cl;
1134##{
1135## char *label, *entity;
1136## int who;
1137
1138 entity = cl->entity;
711660a5 1139 who = cl->client_id;
822a6eba 1140
1141 label = argv[0];
1142 if (!strcmp(q->shortname, "ufil"))
1143 label = argv[1];
1144
1145## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1146## #phys_id = @var_phys_id) where fs.#label = @label
d548a4e7 1147 return(MR_SUCCESS);
92a943d6 1148##}
05cdd922 1149
822a6eba 1150
1151/* sets the modtime on a zephyr class, where argv[0] contains the class
1152 * name.
1153 */
1154
1155set_zephyr_modtime(q, argv, cl)
1156 struct query *q;
1157 char *argv[];
1158 client *cl;
05cdd922 1159##{
822a6eba 1160## char *class, *entity;
1161## int who;
1162
1163 entity = cl->entity;
711660a5 1164 who = cl->client_id;
822a6eba 1165
1166 class = argv[0];
1167
1168## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1169## where z.#class = @class
d548a4e7 1170 return(MR_SUCCESS);
822a6eba 1171##}
1172
1173
1174/* fixes the modby field. This will be the second to last thing in the
1175 * argv, the argv length is determined from the query structure. It is
1176 * passed as a pointer to an integer. This will either turn it into a
1177 * username, or # + the users_id.
1178 */
1179followup_fix_modby(q, sq, v, action, actarg, cl)
1180 struct query *q;
1181 register struct save_queue *sq;
1182 struct validate *v;
1183 register int (*action)();
1184 register int actarg;
1185 client *cl;
cc588c08 1186{
822a6eba 1187 register int i, j;
1188 char **argv, *malloc();
cc588c08 1189 int id, status;
05cdd922 1190
822a6eba 1191 i = q->vcnt - 2;
1192 while (sq_get_data(sq, &argv)) {
1193 id = atoi(argv[i]);
711660a5 1194 if (id > 0)
cc588c08 1195 status = id_to_name(id, "USER", &argv[i]);
1196 else
1197 status = id_to_name(-id, "STRING", &argv[i]);
d548a4e7 1198 if (status && status != MR_NO_MATCH)
cc588c08 1199 return(status);
822a6eba 1200 (*action)(q->vcnt, argv, actarg);
1201 for (j = 0; j < q->vcnt; j++)
1202 free(argv[j]);
1203 free(argv);
1204 }
1205 sq_destroy(sq);
d548a4e7 1206 return(MR_SUCCESS);
cc588c08 1207}
30967516 1208
822a6eba 1209
30967516 1210/**
822a6eba 1211 ** followup_ausr - add finger and pobox entries, set_user_modtime
30967516 1212 **
1213 ** Inputs:
822a6eba 1214 ** argv[0] - login (add_user)
1215 ** argv[3] - last name
1216 ** argv[4] - first name
1217 ** argv[5] - middle name
30967516 1218 **
1219 **/
1220
822a6eba 1221followup_ausr(q, argv, cl)
30967516 1222 struct query *q;
822a6eba 1223 char *argv[];
1224 client *cl;
30967516 1225##{
822a6eba 1226## int who;
1227## char *login, *entity;
1228## char fullname[129];
30967516 1229
822a6eba 1230 login = argv[0];
711660a5 1231 who = cl->client_id;
822a6eba 1232 entity = cl->entity;
30967516 1233
822a6eba 1234 /* build fullname */
1235 if (strlen(argv[4]) && strlen(argv[5]))
1236 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1237 else if (strlen(argv[4]))
1238 sprintf(fullname, "%s %s", argv[4], argv[3]);
1239 else
1240 sprintf(fullname, "%s", argv[3]);
30967516 1241
822a6eba 1242 /* create finger entry, pobox & set modtime on user */
1243## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1244## #fullname=@fullname, mit_affil = u.mit_year,
1245## fmodtime="now", fmodby=@who, fmodwith=@entity,
1246## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1247## where u.#login = @login
30967516 1248
d548a4e7 1249 return(MR_SUCCESS);
05cdd922 1250##}
1251
822a6eba 1252
1253/* followup_gpob: fixes argv[2] based on the IDs currently there and the
1254 * type in argv[1]. Then completes the upcall to the user.
1255 *
1256 * argv[2] is of the form "123:234" where the first integer is the machine
1257 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1258 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1259 * are skipped.
1260 */
1261
1262followup_gpob(q, sq, v, action, actarg, cl)
1263 register struct query *q;
1264 register struct save_queue *sq;
1265 register struct validate *v;
1266 register int (*action)();
1267 int actarg;
1268 client *cl;
cc588c08 1269{
822a6eba 1270 char **argv, *index();
1271 char *ptype, *p;
cc588c08 1272 int mid, sid, status;
822a6eba 1273
1274 /* for each row */
1275 while (sq_get_data(sq, &argv)) {
d548a4e7 1276 mr_trim_args(2, argv);
822a6eba 1277 ptype = argv[1];
1278 p = index(argv[2], ':');
1279 *p++ = 0;
1280 mid = atoi(argv[2]);
1281 sid = atoi(p);
822a6eba 1282
1283 if (!strcmp(ptype, "POP")) {
cc588c08 1284 status = id_to_name(mid, "MACHINE", &argv[2]);
d548a4e7 1285 if (status == MR_NO_MATCH)
1286 return(MR_MACHINE);
822a6eba 1287 } else if (!strcmp(ptype, "SMTP")) {
cc588c08 1288 status = id_to_name(sid, "STRING", &argv[2]);
d548a4e7 1289 if (status == MR_NO_MATCH)
1290 return(MR_STRING);
822a6eba 1291 } else /* ptype == "NONE" */ {
1292 goto skip;
1293 }
cc588c08 1294 if (status) return(status);
822a6eba 1295
1296 if (!strcmp(q->shortname, "gpob")) {
1297 sid = atoi(argv[4]);
711660a5 1298 if (sid > 0)
cc588c08 1299 status = id_to_name(sid, "USER", &argv[4]);
1300 else
1301 status = id_to_name(-sid, "STRING", &argv[4]);
822a6eba 1302 }
d548a4e7 1303 if (status && status != MR_NO_MATCH) return(status);
822a6eba 1304
822a6eba 1305 (*action)(q->vcnt, argv, actarg);
1306 skip:
1307 /* free saved data */
1308 free(argv[0]);
1309 free(argv[1]);
711660a5 1310 free(argv[4]);
822a6eba 1311 free(argv);
1312 }
1313
1314 sq_destroy(sq);
d548a4e7 1315 return (MR_SUCCESS);
cc588c08 1316}
822a6eba 1317
1318
44bd6f44 1319/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1320 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1321 * proper name based on the type, and repace that string in the argv.
1322 * Also fixes the modby field by called followup_fix_modby.
1323 */
1324
1325followup_glin(q, sq, v, action, actarg, cl)
1326 register struct query *q;
1327 register struct save_queue *sq;
1328 register struct validate *v;
1329 register int (*action)();
1330 int actarg;
1331 client *cl;
cc588c08 1332{
822a6eba 1333 char **argv, *malloc(), *realloc(), *type;
cc588c08 1334 int id, i, idx, status;
822a6eba 1335
1336 idx = 8;
1337 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1338 idx = 12;
822a6eba 1339
1340 while (sq_get_data(sq, &argv)) {
d548a4e7 1341 mr_trim_args(q->vcnt, argv);
822a6eba 1342
1343 id = atoi(argv[i = q->vcnt - 2]);
711660a5 1344 if (id > 0)
cc588c08 1345 status = id_to_name(id, "USER", &argv[i]);
1346 else
1347 status = id_to_name(-id, "STRING", &argv[i]);
d548a4e7 1348 if (status && status != MR_NO_MATCH)
cc588c08 1349 return(status);
822a6eba 1350
1351 id = atoi(argv[idx]);
1352 type = argv[idx - 1];
822a6eba 1353
1354 if (!strcmp(type, "LIST")) {
cc588c08 1355 status = id_to_name(id, "LIST", &argv[idx]);
822a6eba 1356 } else if (!strcmp(type, "USER")) {
cc588c08 1357 status = id_to_name(id, "USER", &argv[idx]);
f0516942 1358 } else if (!strcmp(type, "KERBEROS")) {
cc588c08 1359 status = id_to_name(id, "STRING", &argv[idx]);
822a6eba 1360 } else if (!strcmp(type, "NONE")) {
cc588c08 1361 status = 0;
1362 free(argv[idx]);
1363 argv[idx] = strsave("NONE");
1364 } else {
1365 status = 0;
1366 free(argv[idx]);
1367 argv[idx] = strsave("???");
1368 }
d548a4e7 1369 if (status && status != MR_NO_MATCH)
cc588c08 1370 return(status);
822a6eba 1371
1372 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1373 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1374 strcpy(argv[6], UNIQUE_GID);
1375 }
1376
1377 /* send the data */
1378 (*action)(q->vcnt, argv, actarg);
1379
1380 /* free saved data */
1381 for (i = 0; i < q->vcnt; i++)
1382 free(argv[i]);
1383 free(argv);
1384 }
1385
1386 sq_destroy(sq);
d548a4e7 1387 return (MR_SUCCESS);
cc588c08 1388}
822a6eba 1389
1390
368be132 1391/* followup_gqot: Fix the entity name, directory name & modby fields
711660a5 1392 * argv[0] = filsys_id
368be132 1393 * argv[1] = type
1394 * argv[2] = entity_id
1395 * argv[3] = ascii(quota)
711660a5 1396 */
1397
368be132 1398followup_gqot(q, sq, v, action, actarg, cl)
711660a5 1399 struct query *q;
1400 register struct save_queue *sq;
1401 struct validate *v;
1402 register int (*action)();
1403 register int actarg;
1404 client *cl;
1405##{
1406 register int j;
1407 char **argv, *malloc();
1408## int id, rowcount;
1409## char *name, *label;
368be132 1410 int status, idx;
711660a5 1411
368be132 1412 if (!strcmp(q->name, "get_quota") ||
1413 !strcmp(q->name, "get_quota_by_filesys"))
1414 idx = 4;
1415 else
1416 idx = 3;
711660a5 1417 while (sq_get_data(sq, &argv)) {
368be132 1418 if (idx == 4) {
1419 switch (argv[1][0]) {
1420 case 'U':
1421 status = id_to_name(atoi(argv[2]), "USER", &argv[2]);
1422 break;
1423 case 'G':
1424 case 'L':
1425 status = id_to_name(atoi(argv[2]), "LIST", &argv[2]);
1426 break;
1427 case 'A':
1428 free(argv[2]);
1429 argv[2] = strsave("system:anyuser");
1430 break;
1431 default:
1432 id = atoi(argv[2]);
1433 argv[2] = malloc(8);
1434 sprintf(argv[2], "%d", id);
1435 }
1436 }
1437 id = atoi(argv[idx]);
1438 free(argv[idx]);
1439 argv[idx] = malloc(256);
1440 name = argv[idx];
711660a5 1441 if (id == 0) {
1442 label = argv[0];
1443## repeat retrieve (name = filesys.#name) where filesys.#label = @label
1444 } else {
1445## repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
1446 }
1447## inquire_equel(rowcount = "rowcount")
1448 if (rowcount != 1) {
368be132 1449 sprintf(argv[idx], "#%d", id);
711660a5 1450 }
1451
368be132 1452 id = atoi(argv[idx+3]);
711660a5 1453 if (id > 0)
368be132 1454 status = id_to_name(id, "USER", &argv[idx+3]);
cc588c08 1455 else
368be132 1456 status = id_to_name(-id, "STRING", &argv[idx+3]);
d548a4e7 1457 if (status && status != MR_NO_MATCH)
cc588c08 1458 return(status);
711660a5 1459 (*action)(q->vcnt, argv, actarg);
1460 for (j = 0; j < q->vcnt; j++)
1461 free(argv[j]);
1462 free(argv);
1463 }
1464 sq_destroy(sq);
d548a4e7 1465 return(MR_SUCCESS);
711660a5 1466##}
1467
1468
368be132 1469/* followup_aqot: Add allocation to nfsphys after creating quota.
822a6eba 1470 * argv[0] = filsys_id
368be132 1471 * argv[1] = type if "add_quota" or "update_quota"
1472 * argv[2 or 1] = id
1473 * argv[3 or 2] = ascii(quota)
822a6eba 1474 */
1475
368be132 1476followup_aqot(q, argv, cl)
822a6eba 1477 struct query *q;
1478 char **argv;
1479 client *cl;
1480##{
368be132 1481## int quota, id, fs, who;
1482## char *entity, *qtype;
822a6eba 1483
1484 fs = *(int *)argv[0];
368be132 1485 if (!strcmp(q->name, "add_quota") || !strcmp(q->name, "update_quota")) {
1486 qtype = argv[1];
1487 id = *(int *)argv[2];
1488 quota = atoi(argv[3]);
1489 } else {
1490 qtype = "USER";
1491 id = *(int *)argv[1];
1492 quota = atoi(argv[2]);
1493 }
711660a5 1494 who = cl->client_id;
822a6eba 1495 entity = cl->entity;
1496
368be132 1497## repeat replace q (modtime = "now", modby = @who, modwith = @entity)
1498## where q.filsys_id = @fs and q.type = @qtype and q.entity_id = @id
822a6eba 1499## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1500## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
d548a4e7 1501 if (ingres_errno) return(mr_errcode);
1502 return(MR_SUCCESS);
822a6eba 1503##}
1504
1505
b5c60d20 1506followup_gpce(q, sq, v, action, actarg, cl)
1507 struct query *q;
1508 register struct save_queue *sq;
1509 struct validate *v;
1510 register int (*action)();
1511 register int actarg;
1512 client *cl;
1513{
1514 register int i, j;
1515 char **argv, *malloc();
1516 int id, status;
1517
1518 i = q->vcnt - 2;
1519 while (sq_get_data(sq, &argv)) {
1520 id = atoi(argv[PCAP_QSERVER]);
1521 status = id_to_name(id, "MACHINE", &argv[PCAP_QSERVER]);
1522 if (status) return (status);
1523 id = atoi(argv[i]);
1524 if (id > 0)
1525 status = id_to_name(id, "USER", &argv[i]);
1526 else
1527 status = id_to_name(-id, "STRING", &argv[i]);
1528 if (status && status != MR_NO_MATCH)
1529 return(status);
1530 (*action)(q->vcnt, argv, actarg);
1531 for (j = 0; j < q->vcnt; j++)
1532 free(argv[j]);
1533 free(argv);
1534 }
1535 sq_destroy(sq);
1536 return(MR_SUCCESS);
1537}
1538
1539
822a6eba 1540/* followup_gzcl:
1541 */
1542
1543followup_gzcl(q, sq, v, action, actarg, cl)
1544 register struct query *q;
1545 register struct save_queue *sq;
1546 register struct validate *v;
1547 register int (*action)();
92a943d6 1548 int actarg;
822a6eba 1549 client *cl;
cc588c08 1550{
1551 int id, i, status;
822a6eba 1552 char **argv;
92a943d6 1553
822a6eba 1554 while (sq_get_data(sq, &argv)) {
d548a4e7 1555 mr_trim_args(q->vcnt, argv);
92a943d6 1556
822a6eba 1557 id = atoi(argv[i = q->vcnt - 2]);
711660a5 1558 if (id > 0)
cc588c08 1559 status = id_to_name(id, "USER", &argv[i]);
1560 else
1561 status = id_to_name(-id, "STRING", &argv[i]);
d548a4e7 1562 if (status && status != MR_NO_MATCH)
cc588c08 1563 return(status);
822a6eba 1564
1565 for (i = 1; i < 8; i+=2) {
1566 id = atoi(argv[i+1]);
822a6eba 1567 if (!strcmp(argv[i], "LIST")) {
cc588c08 1568 status = id_to_name(id, "LIST", &argv[i+1]);
822a6eba 1569 } else if (!strcmp(argv[i], "USER")) {
cc588c08 1570 status = id_to_name(id, "USER", &argv[i+1]);
f0516942 1571 } else if (!strcmp(argv[i], "KERBEROS")) {
cc588c08 1572 status = id_to_name(id, "STRING", &argv[i+1]);
822a6eba 1573 } else if (!strcmp(argv[i], "NONE")) {
cc588c08 1574 status = 0;
1575 free(argv[i+1]);
1576 argv[i+1] = strsave("NONE");
822a6eba 1577 } else {
cc588c08 1578 status = 0;
1579 free(argv[i+1]);
1580 argv[i+1] = strsave("???");
822a6eba 1581 }
d548a4e7 1582 if (status && status != MR_NO_MATCH)
cc588c08 1583 return(status);
822a6eba 1584 }
92a943d6 1585
822a6eba 1586 /* send the data */
1587 (*action)(q->vcnt, argv, actarg);
1588
1589 /* free saved data */
1590 for (i = 0; i < q->vcnt; i++)
1591 free(argv[i]);
1592 free(argv);
1593 }
1594 sq_destroy(sq);
d548a4e7 1595 return(MR_SUCCESS);
cc588c08 1596}
92a943d6 1597
05cdd922 1598
822a6eba 1599/* followup_gsha:
1600 */
1601
1602followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1603 register struct query *q;
822a6eba 1604 register struct save_queue *sq;
1605 register struct validate *v;
1606 register int (*action)();
1607 int actarg;
1608 client *cl;
cc588c08 1609{
822a6eba 1610 char **argv;
cc588c08 1611 int i, id, status;
05cdd922 1612
822a6eba 1613 while (sq_get_data(sq, &argv)) {
d548a4e7 1614 mr_trim_args(q->vcnt, argv);
05cdd922 1615
822a6eba 1616 id = atoi(argv[4]);
711660a5 1617 if (id > 0)
cc588c08 1618 status = id_to_name(id, "USER", &argv[4]);
1619 else
1620 status = id_to_name(-id, "STRING", &argv[4]);
d548a4e7 1621 if (status && status != MR_NO_MATCH)
cc588c08 1622 return(status);
822a6eba 1623
1624 id = atoi(argv[2]);
822a6eba 1625 if (!strcmp(argv[1], "LIST")) {
cc588c08 1626 status = id_to_name(id, "LIST", &argv[2]);
822a6eba 1627 } else if (!strcmp(argv[1], "USER")) {
cc588c08 1628 status = id_to_name(id, "USER", &argv[2]);
f0516942 1629 } else if (!strcmp(argv[1], "KERBEROS")) {
cc588c08 1630 status = id_to_name(id, "STRING", &argv[2]);
822a6eba 1631 } else if (!strcmp(argv[1], "NONE")) {
cc588c08 1632 status = 0;
1633 free(argv[2]);
1634 argv[2] = strsave("NONE");
822a6eba 1635 } else {
cc588c08 1636 status = 0;
1637 free(argv[2]);
1638 argv[2] = strsave("???");
822a6eba 1639 }
d548a4e7 1640 if (status && status != MR_NO_MATCH)
cc588c08 1641 return(status);
05cdd922 1642
822a6eba 1643 /* send the data */
1644 (*action)(q->vcnt, argv, actarg);
1645
1646 /* free saved data */
1647 for (i = 0; i < q->vcnt; i++)
1648 free(argv[i]);
1649 free(argv);
1650 }
1651 sq_destroy(sq);
d548a4e7 1652 return(MR_SUCCESS);
cc588c08 1653}
05cdd922 1654
05cdd922 1655
822a6eba 1656\f
1657/* Special query routines */
30967516 1658
822a6eba 1659/* set_pobox - this does all of the real work.
1660 * argv = user_id, type, box
1661 * if type is POP, then box should be a machine, and its ID should be put in
1662 * pop_id. If type is SMTP, then box should be a string and its ID should
1663 * be put in box_id. If type is NONE, then box doesn't matter.
1664 */
1665
1666int set_pobox(q, argv, cl)
1667 struct query *q;
1668 char **argv;
1669 client *cl;
1670##{
1671## int user, id, rowcount;
1672## char *box, potype[9];
cc588c08 1673 int status;
822a6eba 1674
1675 box = argv[2];
1676 user = *(int *)argv[0];
1677
1678## repeat retrieve (id = users.pop_id, potype = users.#potype)
1679## where users.users_id = @user
d548a4e7 1680 if (ingres_errno) return(mr_errcode);
e7fa3293 1681 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1682 set_pop_usage(id, -1);
1683
1684 if (!strcmp(argv[1], "POP")) {
cc588c08 1685 status = name_to_id(box, "MACHINE", &id);
d548a4e7 1686 if (status == MR_NO_MATCH)
1687 return(MR_MACHINE);
cc588c08 1688 else if (status)
1689 return(status);
822a6eba 1690## repeat replace users (#potype = "POP", pop_id = @id)
1691## where users.users_id = @user
1692 set_pop_usage(id, 1);
1693 } else if (!strcmp(argv[1], "SMTP")) {
353cb0da 1694 if (index(box, '/') || index(box, '|'))
d548a4e7 1695 return(MR_BAD_CHAR);
cc588c08 1696 status = name_to_id(box, "STRING", &id);
d548a4e7 1697 if (status == MR_NO_MATCH) {
cc588c08 1698## repeat retrieve (id = values.value) where values.name = "strings_id"
822a6eba 1699 id++;
cc588c08 1700## repeat replace values (value = @id) where values.name = "strings_id"
822a6eba 1701## append to strings (string_id = id, string = box)
cc588c08 1702 } else if (status)
1703 return(status);
822a6eba 1704## repeat replace users (#potype = "SMTP", box_id = @id)
1705## where users.users_id = @user
1706 } else /* argv[1] == "NONE" */ {
1707## repeat replace users (#potype = "NONE") where users.users_id = @user
1708 }
1709
1710 set_pobox_modtime(q, argv, cl);
1711## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1712## where tblstats.#table = "users"
d548a4e7 1713 if (ingres_errno) return(mr_errcode);
1714 return(MR_SUCCESS);
30967516 1715##}
1716
30967516 1717
822a6eba 1718/* get_list_info: passed a wildcard list name, returns lots of stuff about
1719 * each list. This is tricky: first build a queue of all requested
44bd6f44 1720 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1721 */
1722
1723get_list_info(q, aargv, cl, action, actarg)
30967516 1724 register struct query *q;
822a6eba 1725 char **aargv;
1726 client *cl;
1727 register int (*action)();
1728 int actarg;
30967516 1729##{
822a6eba 1730 char *argv[13], *malloc(), *realloc();
1731## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
49189928 1732## char maillist[5], group[5], gid[6], acl_name[256], desc[256], modtime[27];
711660a5 1733## char modby[256], modwith[9];
822a6eba 1734## int id, rowcount, acl_id, hid, modby_id;
cc588c08 1735 int returned, status;
822a6eba 1736 struct save_queue *sq, *sq_create();
30967516 1737
822a6eba 1738 returned = rowcount = 0;
1739 name = aargv[0];
30967516 1740
822a6eba 1741 sq = sq_create();
1742## range of l is list
1743## repeat retrieve (id = l.list_id) where l.#name = @name {
1744 sq_save_data(sq, id);
1745 rowcount++;
1746## }
d548a4e7 1747 if (ingres_errno) return(mr_errcode);
822a6eba 1748 if (rowcount == 0)
d548a4e7 1749 return(MR_NO_MATCH);
822a6eba 1750
1751 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1752 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
cc588c08 1753 argv[9] = desc; argv[10] = modtime; argv[12] = modwith;
822a6eba 1754
1755 while (sq_get_data(sq, &id)) {
1756 if (id == 0)
1757 continue;
1758 argv[6] = gid;
1759## repeat retrieve (listname = l.#name, active = text(l.#active),
1760## public = text(l.#public), hidden = text(l.#hidden),
1761## hid = l.#hidden, maillist = text(l.#maillist),
1762## group = text(l.#group), gid = text(l.#gid),
1763## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1764## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1765## modwith =l.#modwith)
1766## where l.list_id = @id
d548a4e7 1767 if (ingres_errno) return(mr_errcode);
822a6eba 1768
1769 if (atoi(gid) == -1)
1770 argv[6] = UNIQUE_GID;
1771
cc588c08 1772 argv[8] = malloc(0);
822a6eba 1773 if (!strcmp(acl_type, "LIST")) {
cc588c08 1774 status = id_to_name(acl_id, "LIST", &argv[8]);
822a6eba 1775 } else if (!strcmp(acl_type, "USER")) {
cc588c08 1776 status = id_to_name(acl_id, "USER", &argv[8]);
f0516942 1777 } else if (!strcmp(acl_type, "KERBEROS")) {
cc588c08 1778 status = id_to_name(acl_id, "STRING", &argv[8]);
822a6eba 1779 } else if (!strcmp(acl_type, "NONE")) {
cc588c08 1780 status = 0;
1781 free(argv[8]);
1782 argv[8] = strsave("NONE");
1783 } else {
1784 status = 0;
1785 free(argv[8]);
1786 argv[8] = strsave("???");
1787 }
d548a4e7 1788 if (status && status != MR_NO_MATCH) return(status);
822a6eba 1789
cc588c08 1790 argv[11] = malloc(0);
711660a5 1791 if (modby_id > 0)
cc588c08 1792 status = id_to_name(modby_id, "USER", &argv[11]);
1793 else
1794 status = id_to_name(-modby_id, "STRING", &argv[11]);
d548a4e7 1795 if (status && status != MR_NO_MATCH) return(status);
822a6eba 1796
d548a4e7 1797 mr_trim_args(q->vcnt, argv);
822a6eba 1798 returned++;
1799 (*action)(q->vcnt, argv, actarg);
cc588c08 1800 free(argv[8]);
1801 free(argv[11]);
822a6eba 1802 }
30967516 1803
822a6eba 1804 sq_destroy(sq);
d548a4e7 1805 if (ingres_errno) return(mr_errcode);
1806 return (MR_SUCCESS);
822a6eba 1807##}
1808
1809
a6683dad 1810/* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is
1811 * how many different ancestors a member is allowed to have.
1812 */
1813
2ff2da4a 1814#define MAXLISTDEPTH 1024
a6683dad 1815
1816int add_member_to_list(q, argv, cl)
1817 struct query *q;
1818 char **argv;
1819 client *cl;
1820##{
49189928 1821## int id, lid, mid, exists, error, who, ref;
cc588c08 1822## char *mtype, dtype[9], *entity;
49189928 1823 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1824 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
cc588c08 1825 int status;
a6683dad 1826 char *dtypes[MAXLISTDEPTH];
cc588c08 1827 char *iargv[3], *buf;
a6683dad 1828
1829## range of m is imembers
1830 lid = *(int *)argv[0];
1831 mtype = argv[1];
1832 mid = *(int *)argv[2];
49189928 1833 /* if the member is already a direct member of the list, punt */
a6683dad 1834## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1835## m.member_id = @mid and m.member_type = @mtype
1836## and m.direct = 1))
1837 if (exists)
d548a4e7 1838 return(MR_EXISTS);
353cb0da 1839 if (!strcasecmp(mtype, "STRING")) {
cc588c08 1840 buf = malloc(0);
1841 status = id_to_name(mid, "STRING", &buf);
1842 if (status) return(status);
1843 if (index(buf, '/') || index(buf, '|')) {
1844 free(buf);
d548a4e7 1845 return(MR_BAD_CHAR);
cc588c08 1846 }
1847 free(buf);
353cb0da 1848 }
1849
a6683dad 1850 ancestors[0] = lid;
49189928 1851 aref[0] = 1;
a6683dad 1852 acount = 1;
49189928 1853## repeat retrieve (id = m.list_id, ref = m.ref_count)
a6683dad 1854## where m.member_id = @lid and m.member_type = "LIST" {
49189928 1855 aref[acount] = ref;
a6683dad 1856 ancestors[acount++] = id;
1857 if (acount >= MAXLISTDEPTH) {
1858## endretrieve
1859 }
1860## }
d548a4e7 1861 if (ingres_errno) return(mr_errcode);
a6683dad 1862 if (acount >= MAXLISTDEPTH) {
d548a4e7 1863 return(MR_INTERNAL);
a6683dad 1864 }
1865 descendants[0] = mid;
1866 dtypes[0] = mtype;
49189928 1867 dref[0] = 1;
a6683dad 1868 dcount = 1;
1869 error = 0;
1870 if (!strcmp(mtype, "LIST")) {
49189928 1871## repeat retrieve (id = m.member_id, dtype = m.member_type,
1872## ref = m.ref_count)
a6683dad 1873## where m.list_id = @mid {
1874 switch (dtype[0]) {
1875 case 'L':
1876 dtypes[dcount] = "LIST";
1877 break;
1878 case 'U':
1879 dtypes[dcount] = "USER";
1880 break;
1881 case 'S':
1882 dtypes[dcount] = "STRING";
1883 break;
1884 case 'K':
1885 dtypes[dcount] = "KERBEROS";
1886 break;
1887 default:
1888 error++;
1889## endretrieve
1890 }
49189928 1891 dref[dcount] = ref;
a6683dad 1892 descendants[dcount++] = id;
1893 if (dcount >= MAXLISTDEPTH) {
1894 error++;
1895## endretrieve
1896 }
1897## }
d548a4e7 1898 if (ingres_errno) return(mr_errcode);
a6683dad 1899 if (error)
d548a4e7 1900 return(MR_INTERNAL);
a6683dad 1901 }
1902 for (a = 0; a < acount; a++) {
1903 lid = ancestors[a];
1904 for (d = 0; d < dcount; d++) {
1905 mid = descendants[d];
1906 mtype = dtypes[d];
1907 if (mid == lid && !strcmp(mtype, "LIST")) {
d548a4e7 1908 return(MR_LISTLOOP);
a6683dad 1909 }
1910## repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
1911## and m.member_id = @mid
1912## and m.member_type = @mtype))
49189928 1913 ref = aref[a] * dref[d];
a6683dad 1914 if (exists) {
1915 if (a == 0 && d == 0)
49189928 1916## replace m (ref_count = m.ref_count+ref, direct = 1)
a6683dad 1917## where m.list_id = lid and m.member_id = mid and
1918## m.member_type = mtype
1919 else
49189928 1920## replace m (ref_count = m.ref_count+ref)
a6683dad 1921## where m.list_id = lid and m.member_id = mid and
1922## m.member_type = mtype
1923 } else {
711660a5 1924 incremental_clear_before();
a6683dad 1925 if (a == 0 && d == 0)
1926## append imembers (list_id=lid, member_id = mid, direct = 1,
1927## member_type=mtype, ref_count = 1)
1928 else
1929## append imembers (list_id=lid, member_id = mid,
49189928 1930## member_type=mtype, ref_count = ref)
711660a5 1931 iargv[0] = (char *)lid;
1932 iargv[1] = mtype;
1933 iargv[2] = (char *)mid;
1934 incremental_after("members", 0, iargv);
a6683dad 1935 }
1936 }
1937 }
189bd6e7 1938 lid = *(int *)argv[0];
1939 entity = cl->entity;
1940 who = cl->client_id;
1941## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
1942## where list.#list_id = @lid
d548a4e7 1943 if (ingres_errno) return(mr_errcode);
1944 return(MR_SUCCESS);
a6683dad 1945##}
1946
1947
1948/* Delete_member_from_list: do list flattening as we go!
1949 */
1950
1951int delete_member_from_list(q, argv, cl)
1952 struct query *q;
1953 char **argv;
1954 client *cl;
1955##{
49189928 1956## int id, lid, mid, cnt, exists, error, who, ref;
189bd6e7 1957## char *mtype, dtype[9], *entity;
49189928 1958 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1959 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
a6683dad 1960 char *dtypes[MAXLISTDEPTH];
711660a5 1961 char *iargv[3];
a6683dad 1962
1963## range of m is imembers
1964 lid = *(int *)argv[0];
1965 mtype = argv[1];
1966 mid = *(int *)argv[2];
49189928 1967 /* if the member is not a direct member of the list, punt */
a6683dad 1968## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1969## m.member_id = @mid and m.member_type = @mtype
1970## and m.direct = 1))
d548a4e7 1971 if (ingres_errno) return(mr_errcode);
a6683dad 1972 if (!exists)
d548a4e7 1973 return(MR_NO_MATCH);
a6683dad 1974 ancestors[0] = lid;
49189928 1975 aref[0] = 1;
a6683dad 1976 acount = 1;
49189928 1977## repeat retrieve (id = m.list_id, ref = m.ref_count)
a6683dad 1978## where m.member_id = @lid and m.member_type = "LIST" {
49189928 1979 aref[acount] = ref;
a6683dad 1980 ancestors[acount++] = id;
1981 if (acount >= MAXLISTDEPTH)
1982## endretrieve
1983## }
d548a4e7 1984 if (ingres_errno) return(mr_errcode);
a6683dad 1985 if (acount >= MAXLISTDEPTH)
d548a4e7 1986 return(MR_INTERNAL);
a6683dad 1987 descendants[0] = mid;
1988 dtypes[0] = mtype;
49189928 1989 dref[0] = 1;
a6683dad 1990 dcount = 1;
1991 error = 0;
1992 if (!strcmp(mtype, "LIST")) {
49189928 1993## repeat retrieve (id = m.member_id, dtype = m.member_type,
1994## ref = m.ref_count)
a6683dad 1995## where m.list_id = @mid {
1996 switch (dtype[0]) {
1997 case 'L':
1998 dtypes[dcount] = "LIST";
1999 break;
2000 case 'U':
2001 dtypes[dcount] = "USER";
2002 break;
2003 case 'S':
2004 dtypes[dcount] = "STRING";
2005 break;
2006 case 'K':
2007 dtypes[dcount] = "KERBEROS";
2008 break;
2009 default:
2010 error++;
2011## endretrieve
2012 }
49189928 2013 dref[dcount] = ref;
a6683dad 2014 descendants[dcount++] = id;
2015 if (dcount >= MAXLISTDEPTH)
2016## endretrieve
2017## }
d548a4e7 2018 if (ingres_errno) return(mr_errcode);
a6683dad 2019 if (error)
d548a4e7 2020 return(MR_INTERNAL);
a6683dad 2021 }
2022 for (a = 0; a < acount; a++) {
2023 lid = ancestors[a];
2024 for (d = 0; d < dcount; d++) {
2025 mid = descendants[d];
2026 mtype = dtypes[d];
2027 if (mid == lid && !strcmp(mtype, "LIST")) {
d548a4e7 2028 return(MR_LISTLOOP);
a6683dad 2029 }
2030## repeat retrieve (cnt = m.ref_count)
2031## where m.list_id = @lid and m.member_id = @mid
2032## and m.member_type = @mtype
49189928 2033 ref = aref[a] * dref[d];
2034 if (cnt <= ref) {
711660a5 2035 iargv[0] = (char *)lid;
2036 iargv[1] = mtype;
2037 iargv[2] = (char *)mid;
2038 incremental_before("members", 0, iargv);
a6683dad 2039## delete m where m.list_id = lid and m.member_id = mid and
2040## m.member_type = mtype
711660a5 2041 incremental_clear_after();
a6683dad 2042 } else if (a == 0 && d == 0) {
49189928 2043## replace m (ref_count = m.ref_count-ref, direct = 0)
a6683dad 2044## where m.list_id = lid and m.member_id = mid and
2045## m.member_type = mtype
2046 } else {
49189928 2047## replace m (ref_count = m.ref_count-ref)
353cb0da 2048## where m.list_id = lid and m.member_id = mid and
a6683dad 2049## m.member_type = mtype
2050 }
2051 }
2052 }
189bd6e7 2053 lid = *(int *)argv[0];
2054 entity = cl->entity;
2055 who = cl->client_id;
2056## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
2057## where list.#list_id = @lid
d548a4e7 2058 if (ingres_errno) return(mr_errcode);
2059 return(MR_SUCCESS);
a6683dad 2060##}
2061
2062
44bd6f44 2063/* get_ace_use - given a type and a name, return a type and a name.
2064 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 2065 * and argv[1] will contain the ID of the entity in question. The R*
2066 * types mean to recursively look at every containing list, not just
2067 * when the object in question is a direct member. On return, the
2068 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
2069 */
2070
44bd6f44 2071int get_ace_use(q, argv, cl, action, actarg)
822a6eba 2072 struct query *q;
2073 char *argv[];
2074 client *cl;
2075 int (*action)();
2076 int actarg;
2077##{
2078 int found = 0;
2079## char *atype;
2080## int aid, listid, id;
2081 struct save_queue *sq, *sq_create();
2082
a6683dad 2083## range of m is imembers
822a6eba 2084 atype = argv[0];
2085 aid = *(int *)argv[1];
f0516942 2086 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
2087 !strcmp(atype, "KERBEROS")) {
44bd6f44 2088 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 2089 }
2090
2091 sq = sq_create();
2092 if (!strcmp(atype, "RLIST")) {
2093 sq_save_data(sq, aid);
2094 /* get all the list_id's of containing lists */
a6683dad 2095## repeat retrieve (listid = m.list_id)
822a6eba 2096## where m.member_type = "LIST" and m.member_id = @id {
a6683dad 2097 sq_save_unique_data(sq, listid);
2098## }
822a6eba 2099 /* now process each one */
2100 while (sq_get_data(sq, &id)) {
d548a4e7 2101 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
822a6eba 2102 found++;
2103 }
2104 }
2105
2106 if (!strcmp(atype, "RUSER")) {
822a6eba 2107## repeat retrieve (listid = m.list_id)
2108## where m.member_type = "USER" and m.member_id = @aid {
2109 sq_save_data(sq, listid);
2110## }
822a6eba 2111 /* now process each one */
2112 while (sq_get_data(sq, &id)) {
d548a4e7 2113 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
822a6eba 2114 found++;
2115 }
d548a4e7 2116 if (get_ace_internal("USER", aid, action, actarg) == MR_SUCCESS)
822a6eba 2117 found++;
2118 }
05cdd922 2119
f0516942 2120 if (!strcmp(atype, "RKERBERO")) {
f0516942 2121## repeat retrieve (listid = m.list_id)
2122## where m.member_type = "KERBEROS" and m.member_id = @aid {
2123 sq_save_data(sq, listid);
2124## }
f0516942 2125 /* now process each one */
2126 while (sq_get_data(sq, &id)) {
d548a4e7 2127 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
f0516942 2128 found++;
2129 }
d548a4e7 2130 if (get_ace_internal("KERBEROS", aid, action, actarg) == MR_SUCCESS)
f0516942 2131 found++;
2132 }
2133
822a6eba 2134 sq_destroy(sq);
d548a4e7 2135 if (ingres_errno) return(mr_errcode);
2136 if (!found) return(MR_NO_MATCH);
2137 return(MR_SUCCESS);
05cdd922 2138##}
92a943d6 2139
822a6eba 2140
44bd6f44 2141/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 2142 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 2143 * by get_ace_use above.
822a6eba 2144 */
2145
44bd6f44 2146##get_ace_internal(atype, aid, action, actarg)
822a6eba 2147## char *atype;
2148## int aid;
2149 int (*action)();
2150 int actarg;
2151##{
2152 char *rargv[2];
2153 int found = 0;
2154## char name[33];
2155
2156 rargv[1] = name;
2157 if (!strcmp(atype, "LIST")) {
2158 rargv[0] = "FILESYS";
2159## repeat retrieve (name = filesys.label)
2160## where filesys.owners = @aid {
2161 (*action)(2, rargv, actarg);
2162 found++;
2163## }
2164
2165 rargv[0] = "QUERY";
2166## repeat retrieve (name = capacls.capability)
2167## where capacls.list_id = @aid {
2168 (*action)(2, rargv, actarg);
2169 found++;
2170## }
2171 } else if (!strcmp(atype, "USER")) {
2172 rargv[0] = "FILESYS";
2173## repeat retrieve (name = filesys.label)
2174## where filesys.owner = @aid {
2175 (*action)(2, rargv, actarg);
2176 found++;
2177## }
2178 }
2179
2180 rargv[0] = "LIST";
2181## repeat retrieve (name = list.#name)
2182## where list.acl_type = @atype and list.acl_id = @aid {
2183 (*action)(2, rargv, actarg);
2184 found++;
2185## }
2186
2187 rargv[0] = "SERVICE";
2188## repeat retrieve (name = servers.#name)
2189## where servers.acl_type = @atype and servers.acl_id = @aid {
2190 (*action)(2, rargv, actarg);
2191 found++;
2192## }
2193
2194 rargv[0] = "HOSTACCESS";
2195## repeat retrieve (name = machine.#name)
2196## where machine.mach_id = hostaccess.mach_id and
2197## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
2198 (*action)(2, rargv, actarg);
2199 found++;
2200## }
2201 rargv[0] = "ZEPHYR";
2202## repeat retrieve (name = zephyr.class)
2203## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
2204## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
2205## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
2206## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
2207 (*action)(2, rargv, actarg);
2208 found++;
2209## }
2210
d548a4e7 2211 if (!found) return(MR_NO_MATCH);
2212 return(MR_SUCCESS);
822a6eba 2213##}
2214
2215
2216/* get_lists_of_member - given a type and a name, return the name and flags
2217 * of all of the lists of the given member. The member_type is one of
2218 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
2219 * and argv[1] will contain the ID of the entity in question. The R*
2220 * types mean to recursively look at every containing list, not just
2221 * when the object in question is a direct member.
2222 */
2223
2224int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 2225 struct query *q;
2226 char *argv[];
822a6eba 2227 client *cl;
2228 int (*action)();
2229 int actarg;
92a943d6 2230##{
a6683dad 2231 int found = 0, direct = 1;
2232 char *rargv[6];
822a6eba 2233## char *atype;
2234## int aid, listid, id;
a6683dad 2235## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
822a6eba 2236
2237 atype = argv[0];
2238 aid = *(int *)argv[1];
822a6eba 2239 if (!strcmp(atype, "RLIST")) {
a6683dad 2240 atype = "LIST";
2241 direct = 0;
822a6eba 2242 }
822a6eba 2243 if (!strcmp(atype, "RUSER")) {
a6683dad 2244 atype = "USER";
2245 direct = 0;
822a6eba 2246 }
822a6eba 2247 if (!strcmp(atype, "RSTRING")) {
a6683dad 2248 atype = "STRING";
2249 direct = 0;
92a943d6 2250 }
a6683dad 2251 if (!strcmp(atype, "RKERBEROS")) {
2252 atype = "KERBEROS";
2253 direct = 0;
f0516942 2254 }
2255
822a6eba 2256 rargv[0] = name;
2257 rargv[1] = active;
2258 rargv[2] = public;
2259 rargv[3] = hidden;
2260 rargv[4] = maillist;
2261 rargv[5] = group;
9bcb4bf5 2262## range of m is imembers
a6683dad 2263 if (direct) {
2264## repeat retrieve (name = list.#name, active = text(list.#active),
2265## public = text(list.#public), hidden = text(list.#hidden),
2266## maillist = text(list.#maillist), group = text(list.#group))
2267## where list.list_id = m.list_id and m.direct = 1 and
2268## m.member_type = @atype and m.member_id = @aid {
2269 (*action)(6, rargv, actarg);
2270 found++;
2271## }
2272 } else {
2273## repeat retrieve (name = list.#name, active = text(list.#active),
822a6eba 2274## public = text(list.#public), hidden = text(list.#hidden),
2275## maillist = text(list.#maillist), group = text(list.#group))
2276## where list.list_id = m.list_id and
2277## m.member_type = @atype and m.member_id = @aid {
2278 (*action)(6, rargv, actarg);
2279 found++;
a6683dad 2280## }
2281 }
92a943d6 2282
d548a4e7 2283 if (ingres_errno) return(mr_errcode);
2284 if (!found) return(MR_NO_MATCH);
2285 return(MR_SUCCESS);
92a943d6 2286##}
2287
822a6eba 2288
2289/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
2290 * the five flags associated with each list. It will return the name of
2291 * each list that meets the quailifications. It does this by building a
2292 * where clause based on the arguments, then doing a retrieve.
2293 */
2294
2295static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
2296
2297int qualified_get_lists(q, argv, cl, action, actarg)
2298 struct query *q;
2299 char *argv[];
2300 client *cl;
2301 int (*action)();
2302 int actarg;
2303{
2304 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
2305 "l", "name", lflags));
2306}
2307
2308
2309/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 2310 **
2311 ** Inputs:
2312 ** argv[0] - list_id
2313 **
2314 ** Description:
2315 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 2316 **/
2317
822a6eba 2318get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 2319 struct query *q;
2320 char *argv[];
822a6eba 2321 client *cl;
c2408bd5 2322 int (*action)();
2323 int actarg;
2324##{
6cfc6477 2325## int list_id, member_id;
2326## char member_name[129], member_type[9];
c2408bd5 2327 char *targv[2];
6cfc6477 2328 int members;
2329 struct save_queue *sq;
c2408bd5 2330
2331 list_id = *(int *)argv[0];
6cfc6477 2332 members = 0;
2333 sq = sq_create();
c2408bd5 2334
6cfc6477 2335## repeat retrieve (member_type = imembers.#member_type,
2336## member_id = imembers.#member_id)
2337## where imembers.#list_id = @list_id and imembers.direct = 1 {
2338 if (members++ > 49)
2339## endretrieve
2340 sq_save_data(sq, (member_type[0] << 24) | (member_id & 0xffffff));
2341## }
2342 if (members <= 49) {
2343 targv[1] = malloc(0);
2344 while (sq_remove_data(sq, &member_id)) {
2345 switch (member_id >> 24) {
2346 case 'U':
2347 targv[0] = "USER";
2348 id_to_name(member_id & 0xffffff, "USER", &targv[1]);
2349 (*action)(2, targv, actarg);
2350 break;
2351 case 'L':
2352 targv[0] = "LIST";
2353 id_to_name(member_id & 0xffffff, "LIST", &targv[1]);
2354 (*action)(2, targv, actarg);
2355 break;
2356 case 'S':
2357 targv[0] = "STRING";
2358 id_to_name(member_id & 0xffffff, "STRING", &targv[1]);
2359 (*action)(2, targv, actarg);
2360 break;
2361 case 'K':
2362 targv[0] = "KERBEROS";
2363 id_to_name(member_id & 0xffffff, "STRING", &targv[1]);
2364 (*action)(2, targv, actarg);
2365 break;
2366 default:
2367 sq_destroy(sq);
d548a4e7 2368 return(MR_INTERNAL);
6cfc6477 2369 }
2370 }
2371 free(targv[1]);
2372 sq_destroy(sq);
d548a4e7 2373 return(MR_SUCCESS);
6cfc6477 2374 }
2375 sq_destroy(sq);
2376
2377 targv[1] = member_name;
2378 targv[0] = "USER";
a6683dad 2379## range of m is imembers
c2408bd5 2380## repeat retrieve (member_name = users.login)
6cfc6477 2381## where m.#list_id = @list_id and m.#member_type = "USER"
2382## and m.#member_id = users.users_id and m.direct = 1
92a943d6 2383## sort by #member_name
c2408bd5 2384## {
2385 (*action)(2, targv, actarg);
2386## }
d548a4e7 2387 if (ingres_errno) return(mr_errcode);
c2408bd5 2388
2389 targv[0] = "LIST";
2390## repeat retrieve (member_name = list.name)
6cfc6477 2391## where m.#list_id = @list_id and m.#member_type = "LIST"
2392## and m.#member_id = list.#list_id and m.direct = 1
92a943d6 2393## sort by #member_name
c2408bd5 2394## {
2395 (*action)(2, targv, actarg);
2396## }
d548a4e7 2397 if (ingres_errno) return(mr_errcode);
c2408bd5 2398
2399 targv[0] = "STRING";
2400## repeat retrieve (member_name = strings.string)
6cfc6477 2401## where m.#list_id = @list_id and m.#member_type = "STRING"
2402## and m.#member_id = strings.string_id and m.direct = 1
92a943d6 2403## sort by #member_name
f0516942 2404## {
2405 (*action)(2, targv, actarg);
2406## }
d548a4e7 2407 if (ingres_errno) return(mr_errcode);
f0516942 2408
2409 targv[0] = "KERBEROS";
2410## repeat retrieve (member_name = strings.string)
6cfc6477 2411## where m.#list_id = @list_id and m.#member_type = "KERBEROS"
2412## and m.#member_id = strings.string_id and m.direct = 1
f0516942 2413## sort by #member_name
c2408bd5 2414## {
2415 (*action)(2, targv, actarg);
2416## }
d548a4e7 2417 if (ingres_errno) return(mr_errcode);
c2408bd5 2418
d548a4e7 2419 return(MR_SUCCESS);
c2408bd5 2420##}
2421
92a943d6 2422
822a6eba 2423/* count_members_of_list: this is a simple query, but it cannot be done
2424 * through the dispatch table.
2425 */
2426
2427int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 2428 struct query *q;
2429 char *argv[];
822a6eba 2430 client *cl;
92a943d6 2431 int (*action)();
2432 int actarg;
2433##{
822a6eba 2434## int list, ct = 0;
2435 char *rargv[1], countbuf[5];
2436
2437 list = *(int *)argv[0];
2438 rargv[0] = countbuf;
a6683dad 2439## repeat retrieve (ct = count(imembers.list_id
2440## where imembers.list_id = @list and
2441## imembers.direct = 1))
d548a4e7 2442 if (ingres_errno) return(mr_errcode);
822a6eba 2443 sprintf(countbuf, "%d", ct);
2444 (*action)(1, rargv, actarg);
d548a4e7 2445 return(MR_SUCCESS);
822a6eba 2446##}
92a943d6 2447
92a943d6 2448
822a6eba 2449/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2450 * the three flags associated with each service. It will return the name of
2451 * each service that meets the quailifications. It does this by building a
2452 * where clause based on the arguments, then doing a retrieve.
2453 */
92a943d6 2454
822a6eba 2455static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2456
822a6eba 2457int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2458 struct query *q;
2459 char *argv[];
822a6eba 2460 client *cl;
a6cb4d4c 2461 int (*action)();
2462 int actarg;
822a6eba 2463{
2464 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2465 "s", "name", sflags));
2466}
a6cb4d4c 2467
a6cb4d4c 2468
822a6eba 2469/* generic qualified get routine, used by qualified_get_lists,
2470 * qualified_get_server, and qualified_get_serverhost.
2471 * Args:
2472 * start - a simple where clause, must not be empty
2473 * range - the name of the range variable
2474 * field - the field to return
2475 * flags - an array of strings, names of the flag variables
2476 */
c2408bd5 2477
822a6eba 2478int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2479 struct query *q;
2480 char *argv[];
2481 int (*action)();
2482 int actarg;
822a6eba 2483 char *start;
2484 char *range;
2485 char *field;
2486 char *flags[];
c2408bd5 2487##{
822a6eba 2488## char name[33], qual[256], *rvar, *rtbl, *rfield;
2489 char *rargv[1], buf[32];
2490## int rowcount, i;
2491
2492 strcpy(qual, start);
2493 for (i = 0; i < q->argc; i++) {
2494 if (!strcmp(argv[i], "TRUE")) {
2495 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2496 (void) strcat(qual, buf);
2497 } else if (!strcmp(argv[i], "FALSE")) {
2498 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2499 (void) strcat(qual, buf);
2500 }
2501 }
2502
2503 rargv[0] = name;
2504 rvar = range;
2505 rtbl = q->rtable;
2506 rfield = field;
2507## range of rvar is rtbl
2508## retrieve (name = rvar.rfield) where qual {
2509 (*action)(1, rargv, actarg);
c2408bd5 2510## }
d548a4e7 2511 if (ingres_errno) return(mr_errcode);
822a6eba 2512## inquire_equel(rowcount = "rowcount")
822a6eba 2513 if (rowcount == 0)
d548a4e7 2514 return(MR_NO_MATCH);
2515 return(MR_SUCCESS);
822a6eba 2516##}
c2408bd5 2517
c2408bd5 2518
822a6eba 2519/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2520 * the five flags associated with each serverhost. It will return the name of
2521 * each service and host that meets the quailifications. It does this by
2522 * building a where clause based on the arguments, then doing a retrieve.
2523 */
c2408bd5 2524
822a6eba 2525static char *shflags[6] = { "service", "enable", "override", "success",
2526 "inprogress", "hosterror" };
a6cb4d4c 2527
822a6eba 2528int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2529 struct query *q;
2530 char *argv[];
822a6eba 2531 client *cl;
a6cb4d4c 2532 int (*action)();
2533 int actarg;
2534##{
822a6eba 2535## char sname[33], mname[33], qual[256];
2536 char *rargv[2], buf[32];
2537## int rowcount, i;
2538
44bd6f44 2539 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2540 argv[0]);
2541 for (i = 1; i < q->argc; i++) {
2542 if (!strcmp(argv[i], "TRUE")) {
2543 sprintf(buf, " and sh.%s != 0", shflags[i]);
2544 strcat(qual, buf);
2545 } else if (!strcmp(argv[i], "FALSE")) {
2546 sprintf(buf, " and sh.%s = 0", shflags[i]);
2547 strcat(qual, buf);
2548 }
2549 }
2550
2551 rargv[0] = sname;
2552 rargv[1] = mname;
2553## range of sh is serverhosts
2554## retrieve (sname = sh.service, mname = machine.name) where qual {
2555 (*action)(2, rargv, actarg);
a6cb4d4c 2556## }
d548a4e7 2557 if (ingres_errno) return(mr_errcode);
822a6eba 2558## inquire_equel(rowcount = "rowcount")
822a6eba 2559 if (rowcount == 0)
d548a4e7 2560 return(MR_NO_MATCH);
2561 return(MR_SUCCESS);
822a6eba 2562##}
a6cb4d4c 2563
a6cb4d4c 2564
822a6eba 2565/* register_user - change user's login name and allocate a pobox, group,
2566 * filesystem, and quota for them. The user's status must start out as 0,
2567 * and is left as 2. Arguments are: user's UID, new login name, and user's
d548a4e7 2568 * type for filesystem allocation (MR_FS_STUDENT, MR_FS_FACULTY,
2569 * MR_FS_STAFF, MR_FS_MISC).
822a6eba 2570 */
2571
2572register_user(q, argv, cl)
2573 struct query *q;
2574 char **argv;
2575 client *cl;
2576##{
2577## char *login, dir[65], *entity, *directory, machname[33];
2578## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2579## int size, alloc, pid, m_id;
711660a5 2580 char buffer[256], *aargv[3];
822a6eba 2581 int maxsize;
2582
2583 entity = cl->entity;
711660a5 2584 who = cl->client_id;
822a6eba 2585
2586 uid = atoi(argv[0]);
2587 login = argv[1];
2588 utype = atoi(argv[2]);
2589
2590## range of u is users
2591## range of l is list
2592## range of sh is serverhosts
2593## range of n is nfsphys
2594## range of m is machine
2595
2596 /* find user */
2597## repeat retrieve (users_id = u.#users_id)
c928f249 2598## where u.#uid = @uid and (u.status = 0 or u.status = 5 or u.status = 6)
822a6eba 2599## inquire_equel(rowcount = "rowcount");
2600 if (rowcount == 0)
d548a4e7 2601 return(MR_NO_MATCH);
822a6eba 2602 if (rowcount > 1)
d548a4e7 2603 return(MR_NOT_UNIQUE);
822a6eba 2604
2605 /* check new login name */
711660a5 2606## repeat retrieve (flag = any(u.#login where u.#login = @login and
2607## u.#users_id != users_id))
d548a4e7 2608 if (ingres_errno) return(mr_errcode);
2609 if (flag) return(MR_IN_USE);
4f16dc86 2610## repeat retrieve (flag = any(l.#name where l.#name = @login))
d548a4e7 2611 if (ingres_errno) return(mr_errcode);
2612 if (flag) return(MR_IN_USE);
99a288b9 2613## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
d548a4e7 2614 if (ingres_errno) return(mr_errcode);
2615 if (flag) return(MR_IN_USE);
822a6eba 2616 com_err(whoami, 0, "new login name OK");
2617
2618 /* choose place for pobox, put in mid */
2619## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2620## where sh.service = "POP" and m.mach_id = sh.mach_id and
2621## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
d548a4e7 2622 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2623## inquire_equel(rowcount = "rowcount");
822a6eba 2624 if (rowcount == 0)
d548a4e7 2625 return(MR_NO_POBOX);
822a6eba 2626
2627 /* change login name, set pobox */
711660a5 2628 sprintf(buffer, "u.users_id = %d", users_id);
2629 incremental_before("users", buffer, 0);
822a6eba 2630## repeat replace u (#login = @login, status = 2, modtime = "now",
2631## modby = @who, modwith = @entity, potype="POP",
2632## pop_id = @mid, pmodtime="now", pmodby=@who,
2633## pmodwith=@entity)
2634## where u.#users_id = @users_id
8ac9ee7a 2635## inquire_equel(rowcount = "rowcount");
d548a4e7 2636 if (ingres_errno) return(mr_errcode);
822a6eba 2637 if (rowcount != 1)
d548a4e7 2638 return(MR_INTERNAL);
822a6eba 2639 set_pop_usage(mid, 1);
2640 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
711660a5 2641 strtrim(machname));
2642 incremental_after("users", buffer, 0);
822a6eba 2643
2644 /* create group list */
2645 if (set_next_object_id("gid", "list"))
d548a4e7 2646 return(MR_NO_ID);
822a6eba 2647 if (set_next_object_id("list_id", "list"))
d548a4e7 2648 return(MR_NO_ID);
822a6eba 2649## repeat retrieve (list_id = values.value) where values.name = "list_id"
d548a4e7 2650 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2651## inquire_equel(rowcount = "rowcount");
822a6eba 2652 if (rowcount != 1)
d548a4e7 2653 return(MR_INTERNAL);
711660a5 2654 incremental_clear_before();
822a6eba 2655## repeat append list (name = @login, #list_id = @list_id, active = 1,
2656## public = 0, hidden = 0, maillist = 0, group = 1,
2657## #gid = values.value, desc = "User Group",
2658## acl_type = "USER", acl_id = @users_id, modtime = "now",
2659## modby = @who, modwith = @entity)
2660## where values.name = "gid"
d548a4e7 2661 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2662## inquire_equel(rowcount = "rowcount");
44bd6f44 2663 if (rowcount != 1)
d548a4e7 2664 return(MR_INTERNAL);
711660a5 2665 sprintf(buffer, "l.list_id = %d", list_id);
2666 incremental_after("list", buffer, 0);
2667 aargv[0] = (char *) list_id;
2668 aargv[1] = "USER";
2669 aargv[2] = (char *) users_id;
2670 incremental_clear_before();
a6683dad 2671## repeat append imembers (#list_id = @list_id, member_type = "USER",
2672## member_id = @users_id, ref_count = 1, direct = 1)
d548a4e7 2673 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2674## inquire_equel(rowcount = "rowcount");
822a6eba 2675 if (rowcount != 1)
d548a4e7 2676 return(MR_INTERNAL);
60610bc7 2677 incremental_after("members", 0, aargv);
822a6eba 2678 com_err(whoami, 0, "group list created");
2679
2680 /* decide where to put filesystem */
2681 maxsize = 0;
2682 directory = NULL;
2683## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2684## flag = n.status, size = n.#size, alloc = n.allocated) {
2685 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2686 maxsize = size - alloc;
2687 if (directory)
2688 free(directory);
2689 directory = strsave(dir);
2690 pid = nid;
2691 m_id = mid;
2692 }
a6cb4d4c 2693## }
d548a4e7 2694 if (ingres_errno) return(mr_errcode);
822a6eba 2695 if (maxsize == 0)
d548a4e7 2696 return(MR_NO_FILESYS);
822a6eba 2697
2698 /* create filesystem */
2699 if (set_next_object_id("filsys_id", "filesys"))
d548a4e7 2700 return(MR_NO_ID);
711660a5 2701 incremental_clear_before();
822a6eba 2702## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2703## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2704## name = @directory + "/" + @login,
2705## mount = "/mit/" + @login,
822a6eba 2706## access = "w", comments = "User Locker",
2707## owner = @users_id, owners = @list_id, createflg = 1,
2708## lockertype = "HOMEDIR", modtime = "now",
2709## modby = @who, modwith = @entity)
2710## where values.name = "filsys_id"
d548a4e7 2711 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2712## inquire_equel(rowcount = "rowcount");
822a6eba 2713 if (rowcount != 1)
d548a4e7 2714 return(MR_INTERNAL);
711660a5 2715 incremental_after("filesys",
2716 "fs.filsys_id = values.value and values.name = \"filsys_id\"",
2717 0);
822a6eba 2718 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2719 directory, login);
822a6eba 2720
2721 /* set quota */
2722## repeat retrieve (quota = values.value) where values.name = "def_quota"
d548a4e7 2723 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2724## inquire_equel(rowcount = "rowcount");
822a6eba 2725 if (rowcount != 1)
d548a4e7 2726 return(MR_NO_QUOTA);
711660a5 2727 incremental_clear_before();
368be132 2728## repeat append #quota (entity_id = @users_id, filsys_id = values.value,
2729## type = "USER",
2730## #quota = @quota, phys_id = @pid, modtime = "now",
2731## modby = @who, modwith = @entity)
822a6eba 2732## where values.name = "filsys_id"
d548a4e7 2733 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2734## inquire_equel(rowcount = "rowcount");
822a6eba 2735 if (rowcount != 1)
d548a4e7 2736 return(MR_INTERNAL);
822a6eba 2737## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2738## where nfsphys.nfsphys_id = filesys.#phys_id and
2739## filesys.filsys_id = values.value and values.name = "filsys_id"
d548a4e7 2740 if (ingres_errno) return(mr_errcode);
8ac9ee7a 2741## inquire_equel(rowcount = "rowcount");
822a6eba 2742 if (rowcount != 1)
d548a4e7 2743 return(MR_INTERNAL);
711660a5 2744 aargv[0] = login;
0c614667 2745 aargv[1] = "USER";
2746 aargv[2] = login;
368be132 2747 sprintf(buffer, "q.entity_id = %d and q.filsys_id = values.value and q.type = \"USER\" and values.name = \"filsys_id\"", users_id);
2748 incremental_after("quota", buffer, aargv);
822a6eba 2749 com_err(whoami, 0, "quota of %d assigned", quota);
d548a4e7 2750 if (ingres_errno) return(mr_errcode);
822a6eba 2751
cc588c08 2752 cache_entry(login, "USER", users_id);
2753
4f16dc86 2754## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2755## where tblstats.table = "users"
2756## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2757## where tblstats.table = "list" or tblstats.table = "filesys" or
368be132 2758## tblstats.table = "quota"
d548a4e7 2759 if (ingres_errno) return(mr_errcode);
2760 return(MR_SUCCESS);
822a6eba 2761##}
2762
2763
2764
2765/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2766 **
2767 ** Inputs:
2768 ** id of machine
2769 ** delta (will be +/- 1)
2770 **
2771 ** Description:
2772 ** - incr/decr value field in serverhosts table for pop/mach_id
2773 **
2774 **/
2775
2776static int set_pop_usage(id, count)
2777int id;
2778int count;
2779##{
2780## int mach_id = id;
2781## int n = count;
2782
cc588c08 2783## repeat replace serverhosts (value1 = serverhosts.value1 + @n)
2784## where serverhosts.service = "POP" and serverhosts.#mach_id = @mach_id
a6cb4d4c 2785
d548a4e7 2786 if (ingres_errno) return(mr_errcode);
2787 return(MR_SUCCESS);
a6cb4d4c 2788##}
822a6eba 2789
2790
c2408bd5 2791\f
05cdd922 2792/* Validation Routines */
2793
2794validate_row(q, argv, v)
2795 register struct query *q;
2796 char *argv[];
2797 register struct validate *v;
2798##{
2799## char *rvar;
2800## char *table;
2801## char *name;
2802## char qual[128];
2803## int rowcount;
2804
2805 /* build where clause */
2806 build_qual(v->qual, v->argc, argv, qual);
2807
2808 /* setup ingres variables */
2809 rvar = q->rvar;
2810 table = q->rtable;
2811 name = v->field;
2812
6388c51a 2813 if (log_flags & LOG_VALID)
b4182127 2814 /* tell the logfile what we're doing */
2815 com_err(whoami, 0, "validating row: %s", qual);
2816
05cdd922 2817 /* look for the record */
2818## range of rvar is table
2819## retrieve (rowcount = count(rvar.name where qual))
d548a4e7 2820 if (ingres_errno) return(mr_errcode);
2821 if (rowcount == 0) return(MR_NO_MATCH);
2822 if (rowcount > 1) return(MR_NOT_UNIQUE);
2823 return(MR_EXISTS);
05cdd922 2824##}
2825
2826validate_fields(q, argv, vo, n)
2827 struct query *q;
2828 register char *argv[];
2829 register struct valobj *vo;
2830 register int n;
2831{
2832 register int status;
05cdd922 2833
2834 while (--n >= 0) {
2835 switch (vo->type) {
2836 case V_NAME:
6388c51a 2837 if (log_flags & LOG_VALID)
b4182127 2838 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2839 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2840 status = validate_name(argv, vo);
2841 break;
2842
2843 case V_ID:
6388c51a 2844 if (log_flags & LOG_VALID)
b4182127 2845 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2846 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2847 status = validate_id(argv, vo);
2848 break;
2849
92a943d6 2850 case V_DATE:
6388c51a 2851 if (log_flags & LOG_VALID)
92a943d6 2852 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2853 status = validate_date(argv, vo);
2854 break;
2855
05cdd922 2856 case V_TYPE:
6388c51a 2857 if (log_flags & LOG_VALID)
b4182127 2858 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2859 vo->table, argv[vo->index]);
05cdd922 2860 status = validate_type(argv, vo);
2861 break;
2862
2863 case V_TYPEDATA:
6388c51a 2864 if (log_flags & LOG_VALID)
92a943d6 2865 com_err(whoami, 0, "validating typed data (%s): %s",
2866 argv[vo->index - 1], argv[vo->index]);
05cdd922 2867 status = validate_typedata(q, argv, vo);
2868 break;
2869
822a6eba 2870 case V_RENAME:
6388c51a 2871 if (log_flags & LOG_VALID)
822a6eba 2872 com_err(whoami, 0, "validating rename %s in %s",
2873 argv[vo->index], vo->table);
2874 status = validate_rename(argv, vo);
2875 break;
2876
2877 case V_CHAR:
6388c51a 2878 if (log_flags & LOG_VALID)
822a6eba 2879 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2880 status = validate_chars(argv[vo->index]);
05cdd922 2881 break;
2882
92a943d6 2883 case V_SORT:
d548a4e7 2884 status = MR_EXISTS;
92a943d6 2885 break;
2886
e1795ce1 2887 case V_LOCK:
2888 status = lock_table(vo);
2889 break;
05cdd922 2890 }
2891
d548a4e7 2892 if (status != MR_EXISTS) return(status);
05cdd922 2893 vo++;
2894 }
2895
d548a4e7 2896 if (ingres_errno) return(mr_errcode);
2897 return(MR_SUCCESS);
05cdd922 2898}
2899
822a6eba 2900
2901/* validate_chars: verify that there are no illegal characters in
2902 * the string. Legal characters are printing chars other than
331b982e 2903 * ", *, ?, \, [ and ].
822a6eba 2904 */
2905static int illegalchars[] = {
2906 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2907 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2908 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2909 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2910 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2911 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2912 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2914 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2915 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2916 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2917 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2918 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2919 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2920 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2921 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2922};
2923
2924validate_chars(s)
2925register char *s;
2926{
2927 while (*s)
2928 if (illegalchars[*s++])
d548a4e7 2929 return(MR_BAD_CHAR);
2930 return(MR_EXISTS);
822a6eba 2931}
2932
2933
05cdd922 2934validate_id(argv, vo)
2935 char *argv[];
2936 register struct valobj *vo;
2937##{
2938## char *name;
2939## char *table;
2940## char *namefield;
2941## char *idfield;
cc588c08 2942## int id, rowcount;
2943 int status;
122ec372 2944 register char *c;
05cdd922 2945
cc588c08 2946
05cdd922 2947 name = argv[vo->index];
2948 table = vo->table;
2949 namefield = vo->namefield;
2950 idfield = vo->idfield;
cc588c08 2951
2952 if ((!strcmp(table, "users") && !strcmp(namefield, "login")) ||
2953 !strcmp(table, "machine") ||
2954 !strcmp(table, "filesys") ||
2955 !strcmp(table, "list") ||
2956 !strcmp(table, "cluster") ||
2957 !strcmp(table, "string")) {
2958 if (!strcmp(table, "machine"))
2959 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2960 status = name_to_id(name, table, &id);
2961 if (status == 0) {
2962 *(int *)argv[vo->index] = id;
d548a4e7 2963 return(MR_EXISTS);
2964 } else if (status == MR_NO_MATCH || status == MR_NOT_UNIQUE)
cc588c08 2965 return(vo->error);
2966 else
2967 return(status);
2968 }
2969
822a6eba 2970 if (!strcmp(namefield, "uid")) {
9119288e 2971## retrieve (id = table.idfield) where table.namefield = int4(name)
d548a4e7 2972 if (ingres_errno) return(mr_errcode);
9119288e 2973## inquire_equel (rowcount = "rowcount")
2974 } else {
2975## retrieve (id = table.idfield) where table.namefield = name
d548a4e7 2976 if (ingres_errno) return(mr_errcode);
9119288e 2977## inquire_equel (rowcount = "rowcount")
2978 }
05cdd922 2979 if (rowcount != 1) return(vo->error);
2980 *(int *)argv[vo->index] = id;
d548a4e7 2981 return(MR_EXISTS);
05cdd922 2982##}
2983
2984validate_name(argv, vo)
2985 char *argv[];
2986 register struct valobj *vo;
2987##{
2988## char *name;
2989## char *table;
2990## char *namefield;
2991## int rowcount;
44bd6f44 2992 register char *c;
05cdd922 2993
2994 name = argv[vo->index];
2995 table = vo->table;
2996 namefield = vo->namefield;
44bd6f44 2997 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2998 for (c = name; *c; c++)
2999 if (islower(*c))
3000 *c = toupper(*c);
3001 }
05cdd922 3002## retrieve (rowcount = countu(table.namefield
3003## where table.namefield = name))
d548a4e7 3004 if (ingres_errno) return(mr_errcode);
3005 return ((rowcount == 1) ? MR_EXISTS : vo->error);
05cdd922 3006##}
3007
92a943d6 3008validate_date(argv, vo)
3009 char *argv[];
3010 struct valobj *vo;
3011##{
3012## char *idate;
3013## double dd;
3014## int errorno;
3015
3016 idate = argv[vo->index];
3017
3018## retrieve (dd = interval("years", date(idate) - date("today")))
3019## inquire_equel (errorno = "errorno")
d548a4e7 3020 if (errorno != 0 || dd > 5.0) return(MR_DATE);
3021 return(MR_EXISTS);
92a943d6 3022##}
3023
822a6eba 3024
3025validate_rename(argv, vo)
3026char *argv[];
3027struct valobj *vo;
3028##{
3029## char *name, *table, *namefield, *idfield;
3030## int id;
cc588c08 3031 int status;
822a6eba 3032 register char *c;
3033
3034 c = name = argv[vo->index];
3035 while (*c)
3036 if (illegalchars[*c++])
d548a4e7 3037 return(MR_BAD_CHAR);
822a6eba 3038 table = vo->table;
3039 /* minor kludge to upcasify machine names */
3040 if (!strcmp(table, "machine"))
3041 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
3042 namefield = vo->namefield;
3043 idfield = vo->idfield;
3044 id = -1;
3045 if (idfield == 0) {
3046 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
d548a4e7 3047 return(MR_EXISTS);
822a6eba 3048## retrieve (id = any(table.namefield where table.namefield = name))
d548a4e7 3049 if (ingres_errno) return(mr_errcode);
822a6eba 3050 if (id)
3051 return(vo->error);
3052 else
d548a4e7 3053 return(MR_EXISTS);
822a6eba 3054 }
cc588c08 3055 status = name_to_id(name, table, &id);
d548a4e7 3056 if (status == MR_NO_MATCH || id == *(int *)argv[vo->index - 1])
3057 return(MR_EXISTS);
822a6eba 3058 else
3059 return(vo->error);
3060##}
3061
3062
05cdd922 3063validate_type(argv, vo)
3064 char *argv[];
3065 register struct valobj *vo;
3066##{
3067## char *typename;
3068## char *value;
822a6eba 3069## int exists;
05cdd922 3070 register char *c;
3071
3072 typename = vo->table;
822a6eba 3073 c = value = argv[vo->index];
3074 while (*c)
3075 if (illegalchars[*c++])
d548a4e7 3076 return(MR_BAD_CHAR);
05cdd922 3077
3078 /* uppercase type fields */
3079 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
3080
cc588c08 3081## repeat retrieve (exists = any(alias.trans where alias.name = @typename and
3082## alias.type = "TYPE" and alias.trans = @value))
d548a4e7 3083 if (ingres_errno) return(mr_errcode);
3084 return (exists ? MR_EXISTS : vo->error);
05cdd922 3085##}
3086
3087/* validate member or type-specific data field */
3088
3089validate_typedata(q, argv, vo)
3090 register struct query *q;
3091 register char *argv[];
3092 register struct valobj *vo;
3093##{
3094## char *name;
3095## char *field_type;
822a6eba 3096## char data_type[129];
cc588c08 3097## int id, rowcount;
3098 int status;
822a6eba 3099 char *index();
a6cb4d4c 3100 register char *c;
05cdd922 3101
3102 /* get named object */
3103 name = argv[vo->index];
3104
3105 /* get field type string (known to be at index-1) */
3106 field_type = argv[vo->index-1];
3107
3108 /* get corresponding data type associated with field type name */
3109## repeat retrieve (data_type = alias.trans)
3110## where alias.#name = @field_type and alias.type = "TYPEDATA"
d548a4e7 3111 if (ingres_errno) return(mr_errcode);
05cdd922 3112## inquire_equel (rowcount = "rowcount")
d548a4e7 3113 if (rowcount != 1) return(MR_TYPE);
05cdd922 3114
3115 /* now retrieve the record id corresponding to the named object */
822a6eba 3116 if (index(data_type, ' '))
3117 *index(data_type, ' ') = 0;
05cdd922 3118 if (!strcmp(data_type, "user")) {
3119 /* USER */
cc588c08 3120 status = name_to_id(name, data_type, &id);
d548a4e7 3121 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
3122 return(MR_USER);
cc588c08 3123 if (status) return(status);
05cdd922 3124 } else if (!strcmp(data_type, "list")) {
3125 /* LIST */
cc588c08 3126 status = name_to_id(name, data_type, &id);
d548a4e7 3127 if (status && status == MR_NOT_UNIQUE)
3128 return(MR_LIST);
3129 if (status == MR_NO_MATCH) {
822a6eba 3130 /* if idfield is non-zero, then if argv[0] matches the string
3131 * that we're trying to resolve, we should get the value of
3132 * values.[idfield] for the id.
3133 */
3134 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 3135 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 3136 name = vo->idfield;
4f16dc86 3137## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 3138## inquire_equel(rowcount = "rowcount")
d548a4e7 3139 if (rowcount != 1) return(MR_LIST);
822a6eba 3140 } else
d548a4e7 3141 return(MR_LIST);
cc588c08 3142 } else if (status) return(status);
05cdd922 3143 } else if (!strcmp(data_type, "machine")) {
3144 /* MACHINE */
a6cb4d4c 3145 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
cc588c08 3146 status = name_to_id(name, data_type, &id);
d548a4e7 3147 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
3148 return(MR_MACHINE);
cc588c08 3149 if (status) return(status);
05cdd922 3150 } else if (!strcmp(data_type, "string")) {
3151 /* STRING */
cc588c08 3152 status = name_to_id(name, data_type, &id);
d548a4e7 3153 if (status && status == MR_NOT_UNIQUE)
3154 return(MR_STRING);
3155 if (status == MR_NO_MATCH) {
3156 if (q->type != APPEND && q->type != UPDATE) return(MR_STRING);
cc588c08 3157## retrieve (id = values.value) where values.#name = "strings_id"
05cdd922 3158 id++;
cc588c08 3159## replace values (value = id) where values.#name = "strings_id"
822a6eba 3160## append to strings (string_id = id, string = name)
cc588c08 3161 } else if (status) return(status);
822a6eba 3162 } else if (!strcmp(data_type, "none")) {
3163 id = 0;
05cdd922 3164 } else {
d548a4e7 3165 return(MR_TYPE);
05cdd922 3166 }
3167
3168 /* now set value in argv */
3169 *(int *)argv[vo->index] = id;
3170
d548a4e7 3171 return (MR_EXISTS);
05cdd922 3172##}
3173
05cdd922 3174
e1795ce1 3175/* Lock the table named by the validation object */
3176
3177lock_table(vo)
3178struct valobj *vo;
3179##{
3180## char *table, *idfield;
3181## int rowcount;
3182
3183 table = vo->table;
3184 idfield = vo->idfield;
3185## replace table (modtime = "now") where table.idfield = 0
d548a4e7 3186 if (ingres_errno) return(mr_errcode);
e1795ce1 3187## inquire_equel (rowcount = "rowcount")
3188 if (rowcount != 1)
3189 return(vo->error);
3190 else
d548a4e7 3191 return(MR_EXISTS);
e1795ce1 3192##}
3193
3194
822a6eba 3195/* Check the database at startup time. For now this just resets the
3196 * inprogress flags that the DCM uses.
3197 */
05cdd922 3198
822a6eba 3199sanity_check_database()
3200##{
05cdd922 3201##}
This page took 0.908979 seconds and 5 git commands to generate.