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