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