]> andersk Git - moira.git/blame - server/qsupport.qc
changed sshi to not lock the machine table exclusively
[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##{
706## char dir[32];
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
803\f
804/* FOLLOWUP ROUTINES */
805
806/* generic set_modtime routine. This takes the table name from the query,
807 * and will update the modtime, modby, and modwho fields in the entry in
808 * the table whose name field matches argv[0].
809 */
810
811set_modtime(q, argv, cl)
4b890cc4 812 struct query *q;
813 char *argv[];
822a6eba 814 client *cl;
4b890cc4 815##{
822a6eba 816## char *name, *entity, *table;
817## int who;
4b890cc4 818
822a6eba 819 entity = cl->entity;
820 who = cl->users_id;
821 table = q->rtable;
822 name = argv[0];
4b890cc4 823
822a6eba 824## replace table (modtime = "now", modby = who, modwith = entity)
825## where table.#name = name
4b890cc4 826 return(SMS_SUCCESS);
827##}
828
822a6eba 829/* generic set_modtime_by_id routine. This takes the table name from
830 * the query, and the id name from the validate record,
831 * and will update the modtime, modby, and modwho fields in the entry in
832 * the table whose id matches argv[0].
833 */
834
835set_modtime_by_id(q, argv, cl)
4b890cc4 836 struct query *q;
822a6eba 837 char **argv;
838 client *cl;
4b890cc4 839##{
822a6eba 840## char *entity, *table, *id_name;
841## int who, id;
842
843 entity = cl->entity;
844 who = cl->users_id;
845 table = q->rtable;
846 id_name = q->validate->object_id;
4b890cc4 847
822a6eba 848 id = *(int *)argv[0];
849## replace table (modtime = "now", modby = who, modwith = entity)
850## where table.id_name = id
4b890cc4 851 return(SMS_SUCCESS);
852##}
853
822a6eba 854
855/* Sets the finger modtime on a user record. The users_id will be in argv[0].
856 */
857
858set_finger_modtime(q, argv, cl)
4b890cc4 859 struct query *q;
860 char *argv[];
822a6eba 861 client *cl;
4b890cc4 862##{
822a6eba 863## int users_id, who;
864## char *entity;
865
866 entity = cl->entity;
867 who = cl->users_id;
868 users_id = *(int *)argv[0];
4b890cc4 869
822a6eba 870## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
871## where u.#users_id = @users_id
4b890cc4 872 return(SMS_SUCCESS);
873##}
05cdd922 874
822a6eba 875
876/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
877 */
878
879set_pobox_modtime(q, argv, cl)
05cdd922 880 struct query *q;
822a6eba 881 char **argv;
882 client *cl;
05cdd922 883##{
822a6eba 884## int users_id, who;
885## char *entity;
05cdd922 886
822a6eba 887 entity = cl->entity;
888 who = cl->users_id;
889 users_id = *(int *)argv[0];
05cdd922 890
822a6eba 891## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
892## where users.#users_id = @users_id
893 return(SMS_SUCCESS);
894##}
05cdd922 895
05cdd922 896
3c7c4a07 897/* Like set_modtime, but uppercases the name first.
822a6eba 898 */
899
3c7c4a07 900set_uppercase_modtime(q, argv, cl)
822a6eba 901 struct query *q;
902 char **argv;
903 client *cl;
904##{
3c7c4a07 905## char *name, *entity, *table;
822a6eba 906## int who;
907
908 entity = cl->entity;
909 who = cl->users_id;
3c7c4a07 910 table = q->rtable;
911 name = argv[0];
05cdd922 912
3c7c4a07 913## replace table (modtime = "now", modby = who, modwith = entity)
914## where table.#name = uppercase(name)
05cdd922 915 return(SMS_SUCCESS);
916##}
05cdd922 917
822a6eba 918
919/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
920 * is necessary for add_machine_to_cluster becuase the table that query
921 * operates on is "mcm", not "machine".
922 */
923
924set_mach_modtime_by_id(q, argv, cl)
05cdd922 925 struct query *q;
05cdd922 926 char **argv;
822a6eba 927 client *cl;
928##{
929## char *entity;
930## int who, id;
05cdd922 931
822a6eba 932 entity = cl->entity;
933 who = cl->users_id;
05cdd922 934
822a6eba 935 id = *(int *)argv[0];
936## range of m is machine
937## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
938## where m.mach_id = @id
939 return(SMS_SUCCESS);
940##}
05cdd922 941
05cdd922 942
822a6eba 943/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
944 * is necessary for add_cluster_data and delete_cluster_data becuase the
945 * table that query operates on is "svc", not "cluster".
946 */
947
948set_cluster_modtime_by_id(q, argv, cl)
949 struct query *q;
950 char **argv;
951 client *cl;
952##{
953## char *entity;
954## int who, id;
955
956 entity = cl->entity;
957 who = cl->users_id;
958
959 id = *(int *)argv[0];
960## range of c is cluster
961## repeat replace c (modtime = "now", modby = @who, modwith = @entity)
962## where c.clu_id = @id
05cdd922 963 return(SMS_SUCCESS);
964##}
965
822a6eba 966
967/* sets the modtime on the serverhost where the service name is in argv[0]
968 * and the mach_id is in argv[1].
969 */
970
971set_serverhost_modtime(q, argv, cl)
92a943d6 972 struct query *q;
822a6eba 973 char **argv;
974 client *cl;
92a943d6 975##{
822a6eba 976## char *entity, *serv;
977## int who, id;
978
979 entity = cl->entity;
980 who = cl->users_id;
981
982 serv = argv[0];
983 id = *(int *)argv[1];
984## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 985## where sh.service = uppercase(@serv) and sh.mach_id = @id
822a6eba 986 return(SMS_SUCCESS);
987##}
988
989
990/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
991 * directory name is in argv[1].
992 */
993
994set_nfsphys_modtime(q, argv, cl)
995 struct query *q;
92a943d6 996 char **argv;
822a6eba 997 client *cl;
998##{
999## char *entity, *dir;
1000## int who, id;
92a943d6 1001
822a6eba 1002 entity = cl->entity;
1003 who = cl->users_id;
92a943d6 1004
822a6eba 1005 id = *(int *)argv[0];
1006 dir = argv[1];
1007## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1008## where np.#dir = @dir and np.mach_id = @id
1009 return(SMS_SUCCESS);
1010##}
92a943d6 1011
92a943d6 1012
822a6eba 1013/* sets the modtime on a filesystem, where argv[0] contains the filesys
1014 * label.
1015 */
1016
1017set_filesys_modtime(q, argv, cl)
1018 struct query *q;
1019 char *argv[];
1020 client *cl;
1021##{
1022## char *label, *entity;
1023## int who;
1024
1025 entity = cl->entity;
1026 who = cl->users_id;
1027
1028 label = argv[0];
1029 if (!strcmp(q->shortname, "ufil"))
1030 label = argv[1];
1031
1032## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1033## #phys_id = @var_phys_id) where fs.#label = @label
92a943d6 1034 return(SMS_SUCCESS);
1035##}
05cdd922 1036
822a6eba 1037
1038/* sets the modtime on a zephyr class, where argv[0] contains the class
1039 * name.
1040 */
1041
1042set_zephyr_modtime(q, argv, cl)
1043 struct query *q;
1044 char *argv[];
1045 client *cl;
05cdd922 1046##{
822a6eba 1047## char *class, *entity;
1048## int who;
1049
1050 entity = cl->entity;
1051 who = cl->users_id;
1052
1053 class = argv[0];
1054
1055## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1056## where z.#class = @class
1057 return(SMS_SUCCESS);
1058##}
1059
1060
1061/* fixes the modby field. This will be the second to last thing in the
1062 * argv, the argv length is determined from the query structure. It is
1063 * passed as a pointer to an integer. This will either turn it into a
1064 * username, or # + the users_id.
1065 */
1066followup_fix_modby(q, sq, v, action, actarg, cl)
1067 struct query *q;
1068 register struct save_queue *sq;
1069 struct validate *v;
1070 register int (*action)();
1071 register int actarg;
1072 client *cl;
1073##{
1074 register int i, j;
1075 char **argv, *malloc();
1076## int id, rowcount;
05cdd922 1077## char *name;
05cdd922 1078
822a6eba 1079 i = q->vcnt - 2;
1080 while (sq_get_data(sq, &argv)) {
1081 id = atoi(argv[i]);
1082 free(argv[i]);
1083 argv[i] = malloc(9);
1084 name = argv[i];
1085## repeat retrieve (name = users.login) where users.users_id = @id
1086## inquire_equel(rowcount = "rowcount")
1087 if (rowcount != 1) {
1088 sprintf(argv[i], "#%d", id);
1089 }
1090 (*action)(q->vcnt, argv, actarg);
1091 for (j = 0; j < q->vcnt; j++)
1092 free(argv[j]);
1093 free(argv);
1094 }
1095 sq_destroy(sq);
1096 return(SMS_SUCCESS);
30967516 1097##}
1098
822a6eba 1099
30967516 1100/**
822a6eba 1101 ** followup_ausr - add finger and pobox entries, set_user_modtime
30967516 1102 **
1103 ** Inputs:
822a6eba 1104 ** argv[0] - login (add_user)
1105 ** argv[3] - last name
1106 ** argv[4] - first name
1107 ** argv[5] - middle name
30967516 1108 **
1109 **/
1110
822a6eba 1111followup_ausr(q, argv, cl)
30967516 1112 struct query *q;
822a6eba 1113 char *argv[];
1114 client *cl;
30967516 1115##{
822a6eba 1116## int who;
1117## char *login, *entity;
1118## char fullname[129];
30967516 1119
822a6eba 1120 login = argv[0];
1121 who = cl->users_id;
1122 entity = cl->entity;
30967516 1123
822a6eba 1124 /* build fullname */
1125 if (strlen(argv[4]) && strlen(argv[5]))
1126 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1127 else if (strlen(argv[4]))
1128 sprintf(fullname, "%s %s", argv[4], argv[3]);
1129 else
1130 sprintf(fullname, "%s", argv[3]);
30967516 1131
822a6eba 1132 /* create finger entry, pobox & set modtime on user */
1133## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1134## #fullname=@fullname, mit_affil = u.mit_year,
1135## fmodtime="now", fmodby=@who, fmodwith=@entity,
1136## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1137## where u.#login = @login
30967516 1138
05cdd922 1139 return(SMS_SUCCESS);
1140##}
1141
822a6eba 1142
1143/* followup_gpob: fixes argv[2] based on the IDs currently there and the
1144 * type in argv[1]. Then completes the upcall to the user.
1145 *
1146 * argv[2] is of the form "123:234" where the first integer is the machine
1147 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1148 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1149 * are skipped.
1150 */
1151
1152followup_gpob(q, sq, v, action, actarg, cl)
1153 register struct query *q;
1154 register struct save_queue *sq;
1155 register struct validate *v;
1156 register int (*action)();
1157 int actarg;
1158 client *cl;
1159##{
1160 char **argv, *index();
1161 char *ptype, *p;
1162## char box[129], *name;
1163## int mid, sid, rowcount;
1164
1165 /* for each row */
1166 while (sq_get_data(sq, &argv)) {
1167 sms_trim_args(2, argv);
1168 ptype = argv[1];
1169 p = index(argv[2], ':');
1170 *p++ = 0;
1171 mid = atoi(argv[2]);
1172 sid = atoi(p);
1173 free(argv[2]);
1174
1175 if (!strcmp(ptype, "POP")) {
1176## repeat retrieve (box=machine.#name) where machine.mach_id=@mid
1177## inquire_equel(rowcount = "rowcount")
1178 if (rowcount != 1)
1179 return(SMS_MACHINE);
1180 } else if (!strcmp(ptype, "SMTP")) {
1181## repeat retrieve (box=strings.string) where strings.string_id=@sid
1182## inquire_equel(rowcount = "rowcount")
1183 if (rowcount != 1)
1184 return(SMS_STRING);
1185 } else /* ptype == "NONE" */ {
1186 goto skip;
1187 }
1188
1189 if (!strcmp(q->shortname, "gpob")) {
1190 sid = atoi(argv[4]);
1191 free(argv[4]);
1192 argv[4] = malloc(9);
1193 name = argv[4];
1194## repeat retrieve (name = users.login) where users.users_id = @sid
1195## inquire_equel(rowcount = "rowcount")
1196 if (rowcount != 1)
1197 sprintf(name, "#%d", sid);
1198 }
1199
1200 argv[2] = box;
1201 (*action)(q->vcnt, argv, actarg);
1202 skip:
1203 /* free saved data */
1204 free(argv[0]);
1205 free(argv[1]);
1206 free(argv);
1207 }
1208
1209 sq_destroy(sq);
1210 return (SMS_SUCCESS);
1211##}
1212
1213
44bd6f44 1214/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1215 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1216 * proper name based on the type, and repace that string in the argv.
1217 * Also fixes the modby field by called followup_fix_modby.
1218 */
1219
1220followup_glin(q, sq, v, action, actarg, cl)
1221 register struct query *q;
1222 register struct save_queue *sq;
1223 register struct validate *v;
1224 register int (*action)();
1225 int actarg;
1226 client *cl;
1227##{
1228 char **argv, *malloc(), *realloc(), *type;
1229## char *name;
1230## int id, rowcount;
1231 int i, idx;
1232
1233 idx = 8;
1234 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1235 idx = 12;
822a6eba 1236
1237 while (sq_get_data(sq, &argv)) {
1238 sms_trim_args(q->vcnt, argv);
1239
1240 id = atoi(argv[i = q->vcnt - 2]);
1241 free(argv[i]);
1242 name = argv[i] = malloc(9);
1243## repeat retrieve (name = users.login) where users.users_id = @id
1244## inquire_equel(rowcount = "rowcount")
1245 if (rowcount != 1)
1246 sprintf(argv[i], "#%d", id);
1247
1248 id = atoi(argv[idx]);
1249 type = argv[idx - 1];
1250 if ((name = malloc(33)) == NULL)
1251 return(SMS_NO_MEM);
1252
1253 if (!strcmp(type, "LIST")) {
1254## repeat retrieve (name = list.#name) where list.list_id = @id
1255## inquire_equel(rowcount = "rowcount")
1256 if (rowcount != 1)
1257 strcpy(name, "???");
1258 } else if (!strcmp(type, "USER")) {
1259## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1260## inquire_equel(rowcount = "rowcount")
1261 if (rowcount != 1)
1262 strcpy(name, "???");
1263 } else if (!strcmp(type, "KERBEROS")) {
1264## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1265## inquire_equel(rowcount = "rowcount")
1266 if (rowcount != 1)
1267 strcpy(name, "???");
1268 } else if (!strcmp(type, "NONE")) {
1269 strcpy(name, "NONE");
1270 } else
1271 strcpy(name, "???");
1272 free(argv[idx]);
1273 argv[idx] = name;
1274
1275 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1276 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1277 strcpy(argv[6], UNIQUE_GID);
1278 }
1279
1280 /* send the data */
1281 (*action)(q->vcnt, argv, actarg);
1282
1283 /* free saved data */
1284 for (i = 0; i < q->vcnt; i++)
1285 free(argv[i]);
1286 free(argv);
1287 }
1288
1289 sq_destroy(sq);
1290 return (SMS_SUCCESS);
1291##}
1292
1293
1294/** followup_amtl - followup for amtl and dmfl; when adding a list
1295 ** member to a maillist, make member list a maillist also
1296 ** unless list is a user-group.
1297 ** Then set_list_modtime_by_id.
92a943d6 1298 **
1299 ** Inputs:
1300 ** argv[0] - list_id
822a6eba 1301 ** argv[1] - member_type
1302 ** argv[2] - member_id
92a943d6 1303 **
1304 **/
1305
822a6eba 1306followup_amtl(q, argv, cl)
92a943d6 1307 struct query *q;
1308 char *argv[];
822a6eba 1309 client *cl;
92a943d6 1310##{
92a943d6 1311## int list_id;
822a6eba 1312## int member_id;
1313## int exists, who;
1314## char *entity;
92a943d6 1315
1316 list_id = *(int *)argv[0];
822a6eba 1317 entity = cl->entity;
1318 who = cl->users_id;
1319
1320## range of l is list
1321## repeat replace l (modtime = "now", modby = @who, modwith = @entity)
1322## where l.#list_id = @list_id
92a943d6 1323
822a6eba 1324 /* if query is not amtl or if member_type is not LIST then return */
1325 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
1326 return(SMS_SUCCESS);
92a943d6 1327
822a6eba 1328 member_id = *(int *)argv[2];
1329
1330 /* is parent list a mailing list? */
1331## repeat retrieve (exists = l.maillist) where l.#list_id=@list_id
1332 if (!exists)
1333 return(SMS_SUCCESS);
1334
1335 /* list is not a user-group; add list to maillist table */
1336## repeat replace l (maillist = 1) where l.#list_id = @member_id
92a943d6 1337 return(SMS_SUCCESS);
1338##}
1339
822a6eba 1340
1341/* followup_anfq: Add allocation to nfsphys after creating quota.
1342 * argv[0] = filsys_id
1343 * argv[2] = ascii(quota)
1344 */
1345
1346followup_anfq(q, argv, cl)
1347 struct query *q;
1348 char **argv;
1349 client *cl;
1350##{
1351## int quota, user, fs, who;
1352## char *entity;
1353
1354 fs = *(int *)argv[0];
1355 user = *(int *)argv[1];
1356 quota = atoi(argv[2]);
1357 who = cl->users_id;
1358 entity = cl->entity;
1359
1360## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1361## where nq.filsys_id = @fs and nq.users_id = @user
1362## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1363## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
1364 return(SMS_SUCCESS);
1365##}
1366
1367
1368/* followup_gzcl:
1369 */
1370
1371followup_gzcl(q, sq, v, action, actarg, cl)
1372 register struct query *q;
1373 register struct save_queue *sq;
1374 register struct validate *v;
1375 register int (*action)();
92a943d6 1376 int actarg;
822a6eba 1377 client *cl;
92a943d6 1378##{
822a6eba 1379## char *name;
1380## int rowcount, id;
1381 char **argv;
1382 int i;
92a943d6 1383
822a6eba 1384 while (sq_get_data(sq, &argv)) {
1385 sms_trim_args(q->vcnt, argv);
92a943d6 1386
822a6eba 1387 id = atoi(argv[i = q->vcnt - 2]);
1388 free(argv[i]);
1389 name = argv[i] = malloc(9);
1390## repeat retrieve (name = users.login) where users.users_id = @id
1391## inquire_equel(rowcount = "rowcount")
1392 if (rowcount != 1)
1393 sprintf(argv[i], "#%d", id);
1394
1395 for (i = 1; i < 8; i+=2) {
1396 id = atoi(argv[i+1]);
1397 free(argv[i+1]);
1398 if ((name = argv[i+1] = malloc(33)) == NULL)
1399 return(SMS_NO_MEM);
1400 if (!strcmp(argv[i], "LIST")) {
1401## repeat retrieve (name = list.#name) where list.list_id = @id
1402## inquire_equel(rowcount = "rowcount")
1403 if (rowcount != 1)
1404 strcpy(name, "???");
1405 } else if (!strcmp(argv[i], "USER")) {
1406## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1407## inquire_equel(rowcount = "rowcount")
1408 if (rowcount != 1)
1409 strcpy(name, "???");
1410 } else if (!strcmp(argv[i], "KERBEROS")) {
1411## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1412## inquire_equel(rowcount = "rowcount")
1413 if (rowcount != 1)
1414 strcpy(name, "???");
1415 } else if (!strcmp(argv[i], "NONE")) {
1416 strcpy(name, "NONE");
1417 } else {
1418 strcpy(name, "???");
1419 }
1420 }
92a943d6 1421
822a6eba 1422 /* send the data */
1423 (*action)(q->vcnt, argv, actarg);
1424
1425 /* free saved data */
1426 for (i = 0; i < q->vcnt; i++)
1427 free(argv[i]);
1428 free(argv);
1429 }
1430 sq_destroy(sq);
92a943d6 1431 return(SMS_SUCCESS);
1432##}
1433
05cdd922 1434
822a6eba 1435/* followup_gsha:
1436 */
1437
1438followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1439 register struct query *q;
822a6eba 1440 register struct save_queue *sq;
1441 register struct validate *v;
1442 register int (*action)();
1443 int actarg;
1444 client *cl;
05cdd922 1445##{
822a6eba 1446## char *name;
1447## int rowcount, id;
1448 char **argv;
1449 int i;
05cdd922 1450
822a6eba 1451 while (sq_get_data(sq, &argv)) {
1452 sms_trim_args(q->vcnt, argv);
05cdd922 1453
822a6eba 1454 id = atoi(argv[4]);
1455 free(argv[4]);
1456 name = argv[4] = malloc(9);
1457## repeat retrieve (name = users.login) where users.users_id = @id
1458## inquire_equel(rowcount = "rowcount")
1459 if (rowcount != 1)
1460 sprintf(argv[4], "#%d", id);
1461
1462 id = atoi(argv[2]);
1463 free(argv[2]);
1464 if ((name = argv[2] = malloc(33)) == NULL)
1465 return(SMS_NO_MEM);
1466 if (!strcmp(argv[1], "LIST")) {
1467## repeat retrieve (name = list.#name) where list.list_id = @id
1468## inquire_equel(rowcount = "rowcount")
1469 if (rowcount != 1)
1470 strcpy(name, "???");
1471 } else if (!strcmp(argv[1], "USER")) {
1472## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1473## inquire_equel(rowcount = "rowcount")
1474 if (rowcount != 1)
1475 strcpy(name, "???");
1476 } else if (!strcmp(argv[1], "KERBEROS")) {
1477## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1478## inquire_equel(rowcount = "rowcount")
1479 if (rowcount != 1)
1480 strcpy(name, "???");
1481 } else if (!strcmp(argv[1], "NONE")) {
1482 strcpy(name, "NONE");
1483 } else {
1484 strcpy(name, "???");
1485 }
05cdd922 1486
822a6eba 1487 /* send the data */
1488 (*action)(q->vcnt, argv, actarg);
1489
1490 /* free saved data */
1491 for (i = 0; i < q->vcnt; i++)
1492 free(argv[i]);
1493 free(argv);
1494 }
1495 sq_destroy(sq);
1496 return(SMS_SUCCESS);
1497##}
05cdd922 1498
05cdd922 1499
822a6eba 1500\f
1501/* Special query routines */
30967516 1502
822a6eba 1503/* set_pobox - this does all of the real work.
1504 * argv = user_id, type, box
1505 * if type is POP, then box should be a machine, and its ID should be put in
1506 * pop_id. If type is SMTP, then box should be a string and its ID should
1507 * be put in box_id. If type is NONE, then box doesn't matter.
1508 */
1509
1510int set_pobox(q, argv, cl)
1511 struct query *q;
1512 char **argv;
1513 client *cl;
1514##{
1515## int user, id, rowcount;
1516## char *box, potype[9];
1517
1518 box = argv[2];
1519 user = *(int *)argv[0];
1520
1521## repeat retrieve (id = users.pop_id, potype = users.#potype)
1522## where users.users_id = @user
e7fa3293 1523 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1524 set_pop_usage(id, -1);
1525
1526 if (!strcmp(argv[1], "POP")) {
1527## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@box)
1528## inquire_equel(rowcount = "rowcount")
1529 if (rowcount != 1)
1530 return(SMS_MACHINE);
1531## repeat replace users (#potype = "POP", pop_id = @id)
1532## where users.users_id = @user
1533 set_pop_usage(id, 1);
1534 } else if (!strcmp(argv[1], "SMTP")) {
1535## range of s is strings
1536## repeat retrieve (id = s.string_id) where s.string = @box
1537## inquire_equel (rowcount = "rowcount")
1538 if (rowcount == 0) {
1539## range of v is values
1540## repeat retrieve (id = v.value) where v.name = "strings_id"
1541 id++;
1542## repeat replace v (value = @id) where v.name = "strings_id"
1543## append to strings (string_id = id, string = box)
1544 }
1545## repeat replace users (#potype = "SMTP", box_id = @id)
1546## where users.users_id = @user
1547 } else /* argv[1] == "NONE" */ {
1548## repeat replace users (#potype = "NONE") where users.users_id = @user
1549 }
1550
1551 set_pobox_modtime(q, argv, cl);
1552## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1553## where tblstats.#table = "users"
30967516 1554 return(SMS_SUCCESS);
1555##}
1556
30967516 1557
822a6eba 1558/* get_list_info: passed a wildcard list name, returns lots of stuff about
1559 * each list. This is tricky: first build a queue of all requested
44bd6f44 1560 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1561 */
1562
1563get_list_info(q, aargv, cl, action, actarg)
30967516 1564 register struct query *q;
822a6eba 1565 char **aargv;
1566 client *cl;
1567 register int (*action)();
1568 int actarg;
30967516 1569##{
822a6eba 1570 char *argv[13], *malloc(), *realloc();
1571## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1572## char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
1573## char modby[9], modwith[9];
1574## int id, rowcount, acl_id, hid, modby_id;
1575 int returned;
1576 struct save_queue *sq, *sq_create();
30967516 1577
822a6eba 1578 returned = rowcount = 0;
1579 name = aargv[0];
30967516 1580
822a6eba 1581 sq = sq_create();
1582## range of l is list
1583## repeat retrieve (id = l.list_id) where l.#name = @name {
1584 sq_save_data(sq, id);
1585 rowcount++;
1586## }
1587 if (rowcount == 0)
1588 return(SMS_NO_MATCH);
1589
1590 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1591 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1592 argv[8] = acl_name; argv[9] = desc; argv[10] = modtime; argv[11] = modby;
1593 argv[12] = modwith;
1594
1595 while (sq_get_data(sq, &id)) {
1596 if (id == 0)
1597 continue;
1598 argv[6] = gid;
1599## repeat retrieve (listname = l.#name, active = text(l.#active),
1600## public = text(l.#public), hidden = text(l.#hidden),
1601## hid = l.#hidden, maillist = text(l.#maillist),
1602## group = text(l.#group), gid = text(l.#gid),
1603## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1604## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1605## modwith =l.#modwith)
1606## where l.list_id = @id
1607
1608 if (atoi(gid) == -1)
1609 argv[6] = UNIQUE_GID;
1610
1611 if (!strcmp(acl_type, "LIST")) {
1612## repeat retrieve (acl_name = l.#name) where l.list_id = @acl_id
1613## inquire_equel(rowcount = "rowcount")
1614 if (rowcount != 1)
1615 strcpy(acl_name, "???");
1616 } else if (!strcmp(acl_type, "USER")) {
1617## repeat retrieve (acl_name = users.#login)
1618## where users.users_id = @acl_id
f0516942 1619## inquire_equel(rowcount = "rowcount")
1620 if (rowcount != 1)
1621 strcpy(acl_name, "???");
1622 } else if (!strcmp(acl_type, "KERBEROS")) {
1623## repeat retrieve (acl_name = strings.string)
1624## where strings.string_id = @acl_id
822a6eba 1625## inquire_equel(rowcount = "rowcount")
1626 if (rowcount != 1)
1627 strcpy(acl_name, "???");
1628 } else if (!strcmp(acl_type, "NONE")) {
1629 strcpy(acl_name, "NONE");
1630 } else
1631 strcpy(acl_name, "???");
1632
1633## repeat retrieve (modby = users.login) where users.users_id = @modby_id
1634## inquire_equel(rowcount = "rowcount")
1635 if (rowcount != 1)
1636 sprintf(modby, "#%d", id);
1637
1638 sms_trim_args(q->vcnt, argv);
1639 returned++;
1640 (*action)(q->vcnt, argv, actarg);
1641 }
30967516 1642
822a6eba 1643 sq_destroy(sq);
1644## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1645## where tblstats.#table = "list"
5e06ce45 1646
822a6eba 1647 return (SMS_SUCCESS);
1648##}
1649
1650
44bd6f44 1651/* get_ace_use - given a type and a name, return a type and a name.
1652 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 1653 * and argv[1] will contain the ID of the entity in question. The R*
1654 * types mean to recursively look at every containing list, not just
1655 * when the object in question is a direct member. On return, the
1656 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
1657 */
1658
44bd6f44 1659int get_ace_use(q, argv, cl, action, actarg)
822a6eba 1660 struct query *q;
1661 char *argv[];
1662 client *cl;
1663 int (*action)();
1664 int actarg;
1665##{
1666 int found = 0;
1667## char *atype;
1668## int aid, listid, id;
1669 struct save_queue *sq, *sq_create();
1670
1671 atype = argv[0];
1672 aid = *(int *)argv[1];
f0516942 1673 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
1674 !strcmp(atype, "KERBEROS")) {
44bd6f44 1675 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 1676 }
1677
1678 sq = sq_create();
1679 if (!strcmp(atype, "RLIST")) {
1680 sq_save_data(sq, aid);
1681 /* get all the list_id's of containing lists */
1682## range of m is members
1683 while (sq_get_data(sq, &id)) {
1684## repeat retrieve (listid = m.list_id)
1685## where m.member_type = "LIST" and m.member_id = @id {
1686 sq_save_unique_data(sq, listid);
1687## }
1688 }
1689 /* now process each one */
1690 while (sq_get_data(sq, &id)) {
44bd6f44 1691 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1692 found++;
1693 }
1694 }
1695
1696 if (!strcmp(atype, "RUSER")) {
1697## range of m is members
1698## repeat retrieve (listid = m.list_id)
1699## where m.member_type = "USER" and m.member_id = @aid {
1700 sq_save_data(sq, listid);
1701## }
1702 /* get all the list_id's of containing lists */
1703 while (sq_get_data(sq, &id)) {
1704## repeat retrieve (listid = m.list_id)
1705## where m.member_type = "LIST" and m.member_id = @id {
1706 sq_save_unique_data(sq, listid);
1707## }
1708 }
1709 /* now process each one */
1710 while (sq_get_data(sq, &id)) {
44bd6f44 1711 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1712 found++;
1713 }
44bd6f44 1714 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 1715 found++;
1716 }
05cdd922 1717
f0516942 1718 if (!strcmp(atype, "RKERBERO")) {
1719## range of m is members
1720## repeat retrieve (listid = m.list_id)
1721## where m.member_type = "KERBEROS" and m.member_id = @aid {
1722 sq_save_data(sq, listid);
1723## }
1724 /* get all the list_id's of containing lists */
1725 while (sq_get_data(sq, &id)) {
1726## repeat retrieve (listid = m.list_id)
1727## where m.member_type = "LIST" and m.member_id = @id {
1728 sq_save_unique_data(sq, listid);
1729## }
1730 }
1731 /* now process each one */
1732 while (sq_get_data(sq, &id)) {
1733 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1734 found++;
1735 }
1736 if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
1737 found++;
1738 }
1739
822a6eba 1740 sq_destroy(sq);
1741 if (!found) return(SMS_NO_MATCH);
05cdd922 1742 return(SMS_SUCCESS);
1743##}
92a943d6 1744
822a6eba 1745
44bd6f44 1746/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 1747 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 1748 * by get_ace_use above.
822a6eba 1749 */
1750
44bd6f44 1751##get_ace_internal(atype, aid, action, actarg)
822a6eba 1752## char *atype;
1753## int aid;
1754 int (*action)();
1755 int actarg;
1756##{
1757 char *rargv[2];
1758 int found = 0;
1759## char name[33];
1760
1761 rargv[1] = name;
1762 if (!strcmp(atype, "LIST")) {
1763 rargv[0] = "FILESYS";
1764## repeat retrieve (name = filesys.label)
1765## where filesys.owners = @aid {
1766 (*action)(2, rargv, actarg);
1767 found++;
1768## }
1769
1770 rargv[0] = "QUERY";
1771## repeat retrieve (name = capacls.capability)
1772## where capacls.list_id = @aid {
1773 (*action)(2, rargv, actarg);
1774 found++;
1775## }
1776 } else if (!strcmp(atype, "USER")) {
1777 rargv[0] = "FILESYS";
1778## repeat retrieve (name = filesys.label)
1779## where filesys.owner = @aid {
1780 (*action)(2, rargv, actarg);
1781 found++;
1782## }
1783 }
1784
1785 rargv[0] = "LIST";
1786## repeat retrieve (name = list.#name)
1787## where list.acl_type = @atype and list.acl_id = @aid {
1788 (*action)(2, rargv, actarg);
1789 found++;
1790## }
1791
1792 rargv[0] = "SERVICE";
1793## repeat retrieve (name = servers.#name)
1794## where servers.acl_type = @atype and servers.acl_id = @aid {
1795 (*action)(2, rargv, actarg);
1796 found++;
1797## }
1798
1799 rargv[0] = "HOSTACCESS";
1800## repeat retrieve (name = machine.#name)
1801## where machine.mach_id = hostaccess.mach_id and
1802## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
1803 (*action)(2, rargv, actarg);
1804 found++;
1805## }
1806 rargv[0] = "ZEPHYR";
1807## repeat retrieve (name = zephyr.class)
1808## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
1809## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
1810## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
1811## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
1812 (*action)(2, rargv, actarg);
1813 found++;
1814## }
1815
1816 if (!found) return(SMS_NO_MATCH);
1817 return(SMS_SUCCESS);
1818##}
1819
1820
1821/* get_lists_of_member - given a type and a name, return the name and flags
1822 * of all of the lists of the given member. The member_type is one of
1823 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
1824 * and argv[1] will contain the ID of the entity in question. The R*
1825 * types mean to recursively look at every containing list, not just
1826 * when the object in question is a direct member.
1827 */
1828
1829int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 1830 struct query *q;
1831 char *argv[];
822a6eba 1832 client *cl;
1833 int (*action)();
1834 int actarg;
92a943d6 1835##{
822a6eba 1836 int found = 0;
1837## char *atype;
1838## int aid, listid, id;
1839 struct save_queue *sq, *sq_create();
1840
1841 atype = argv[0];
1842 aid = *(int *)argv[1];
1843 if (!strcmp(atype, "LIST") ||
1844 !strcmp(atype, "USER") ||
f0516942 1845 !strcmp(atype, "STRING") ||
1846 !strcmp(atype, "KERBEROS")) {
822a6eba 1847 return(glom_internal(atype, aid, action, actarg));
1848 }
92a943d6 1849
822a6eba 1850 sq = sq_create();
1851 if (!strcmp(atype, "RLIST")) {
1852 sq_save_data(sq, aid);
1853 /* get all the list_id's of containing lists */
1854## range of m is members
1855 while (sq_get_data(sq, &id)) {
1856## repeat retrieve (listid = m.list_id)
1857## where m.member_type = "LIST" and m.member_id = @id {
1858 sq_save_unique_data(sq, listid);
1859## }
1860 }
1861 /* now process each one */
1862 while (sq_get_data(sq, &id)) {
1863 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1864 found++;
1865 }
1866 }
92a943d6 1867
822a6eba 1868 if (!strcmp(atype, "RUSER")) {
1869## range of m is members
1870## repeat retrieve (listid = m.list_id)
1871## where m.member_type = "USER" and m.member_id = @aid {
1872 sq_save_data(sq, listid);
1873## }
1874 /* get all the list_id's of containing lists */
1875 while (sq_get_data(sq, &id)) {
1876## repeat retrieve (listid = m.list_id)
1877## where m.member_type = "LIST" and m.member_id = @id {
1878 sq_save_unique_data(sq, listid);
1879## }
1880 }
1881 /* now process each one */
1882 while (sq_get_data(sq, &id)) {
1883 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1884 found++;
1885 }
1886 if (glom_internal("USER", aid, action, actarg) == SMS_SUCCESS)
1887 found++;
1888 }
92a943d6 1889
822a6eba 1890 if (!strcmp(atype, "RSTRING")) {
1891## range of m is members
1892## repeat retrieve (listid = m.list_id)
1893## where m.member_type = "STRING" and m.member_id = @aid {
1894 sq_save_data(sq, listid);
1895## }
1896 /* get all the list_id's of containing lists */
1897 while (sq_get_data(sq, &id)) {
1898## repeat retrieve (listid = m.list_id)
1899## where m.member_type = "LIST" and m.member_id = @id {
1900 sq_save_unique_data(sq, listid);
1901## }
1902 }
1903 /* now process each one */
1904 while (sq_get_data(sq, &id)) {
1905 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1906 found++;
1907 }
1908 if (glom_internal("STRING", aid, action, actarg) == SMS_SUCCESS)
1909 found++;
92a943d6 1910 }
55534a87 1911
f0516942 1912 if (!strcmp(atype, "RKERBERO")) {
1913## range of m is members
1914## repeat retrieve (listid = m.list_id)
1915## where m.member_type = "KERBEROS" and m.member_id = @aid {
1916 sq_save_data(sq, listid);
1917## }
1918 /* get all the list_id's of containing lists */
1919 while (sq_get_data(sq, &id)) {
1920## repeat retrieve (listid = m.list_id)
1921## where m.member_type = "LIST" and m.member_id = @id {
1922 sq_save_unique_data(sq, listid);
1923## }
1924 }
1925 /* now process each one */
1926 while (sq_get_data(sq, &id)) {
1927 if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
1928 found++;
1929 }
1930 if (glom_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
1931 found++;
1932 }
1933
822a6eba 1934## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1935## where tblstats.#table = "members"
1936 sq_destroy(sq);
1937 if (!found) return(SMS_NO_MATCH);
1938 return(SMS_SUCCESS);
1939##}
1940
55534a87 1941
822a6eba 1942/* This looks up a single list, user, or string as a member. atype must be
1943 * "USER", "LIST", or "STRING" and aid is the ID of the corresponding object.
1944 * This is used by get_lists_of_members above.
1945 */
1946
1947##glom_internal(atype, aid, action, actarg)
1948## char *atype;
1949## int aid;
1950 int (*action)();
1951 int actarg;
1952##{
1953 char *rargv[6];
1954 int found = 0;
1955## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
1956
1957 rargv[0] = name;
1958 rargv[1] = active;
1959 rargv[2] = public;
1960 rargv[3] = hidden;
1961 rargv[4] = maillist;
1962 rargv[5] = group;
1963## repeat retrieve (name = list.#name, active = text(list.#active),
1964## public = text(list.#public), hidden = text(list.#hidden),
1965## maillist = text(list.#maillist), group = text(list.#group))
1966## where list.list_id = m.list_id and
1967## m.member_type = @atype and m.member_id = @aid {
1968 (*action)(6, rargv, actarg);
1969 found++;
1970## }
92a943d6 1971
822a6eba 1972 if (!found) return(SMS_NO_MATCH);
92a943d6 1973 return(SMS_SUCCESS);
1974##}
1975
822a6eba 1976
1977/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
1978 * the five flags associated with each list. It will return the name of
1979 * each list that meets the quailifications. It does this by building a
1980 * where clause based on the arguments, then doing a retrieve.
1981 */
1982
1983static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
1984
1985int qualified_get_lists(q, argv, cl, action, actarg)
1986 struct query *q;
1987 char *argv[];
1988 client *cl;
1989 int (*action)();
1990 int actarg;
1991{
1992 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
1993 "l", "name", lflags));
1994}
1995
1996
1997/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 1998 **
1999 ** Inputs:
2000 ** argv[0] - list_id
2001 **
2002 ** Description:
2003 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 2004 **/
2005
822a6eba 2006get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 2007 struct query *q;
2008 char *argv[];
822a6eba 2009 client *cl;
c2408bd5 2010 int (*action)();
2011 int actarg;
2012##{
2013## int list_id;
2014## char member_name[129];
2015 char *targv[2];
2016
2017 list_id = *(int *)argv[0];
2018 targv[0] = "USER";
2019 targv[1] = member_name;
2020
2021## range of m is members
2022## repeat retrieve (member_name = users.login)
2023## where m.#list_id = @list_id and m.member_type = "USER"
2024## and m.member_id = users.users_id
92a943d6 2025## sort by #member_name
c2408bd5 2026## {
2027 (*action)(2, targv, actarg);
2028## }
2029
2030 targv[0] = "LIST";
2031## repeat retrieve (member_name = list.name)
2032## where m.#list_id = @list_id and m.member_type = "LIST"
2033## and m.member_id = list.#list_id
92a943d6 2034## sort by #member_name
c2408bd5 2035## {
2036 (*action)(2, targv, actarg);
2037## }
2038
2039 targv[0] = "STRING";
2040## repeat retrieve (member_name = strings.string)
2041## where m.#list_id = @list_id and m.member_type = "STRING"
2042## and m.member_id = strings.string_id
92a943d6 2043## sort by #member_name
f0516942 2044## {
2045 (*action)(2, targv, actarg);
2046## }
2047
2048 targv[0] = "KERBEROS";
2049## repeat retrieve (member_name = strings.string)
2050## where m.#list_id = @list_id and m.member_type = "KERBEROS"
2051## and m.member_id = strings.string_id
2052## sort by #member_name
c2408bd5 2053## {
2054 (*action)(2, targv, actarg);
2055## }
2056
822a6eba 2057## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2058## where tblstats.#table = "members"
c2408bd5 2059 return(SMS_SUCCESS);
2060##}
2061
92a943d6 2062
822a6eba 2063/* count_members_of_list: this is a simple query, but it cannot be done
2064 * through the dispatch table.
2065 */
2066
2067int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 2068 struct query *q;
2069 char *argv[];
822a6eba 2070 client *cl;
92a943d6 2071 int (*action)();
2072 int actarg;
2073##{
822a6eba 2074## int list, ct = 0;
2075 char *rargv[1], countbuf[5];
2076
2077 list = *(int *)argv[0];
2078 rargv[0] = countbuf;
2079## repeat retrieve (ct = count(members.list_id where members.list_id = @list))
2080 sprintf(countbuf, "%d", ct);
2081 (*action)(1, rargv, actarg);
2082## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2083## where tblstats.#table = "members"
2084 return(SMS_SUCCESS);
2085##}
92a943d6 2086
92a943d6 2087
822a6eba 2088/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2089 * the three flags associated with each service. It will return the name of
2090 * each service that meets the quailifications. It does this by building a
2091 * where clause based on the arguments, then doing a retrieve.
2092 */
92a943d6 2093
822a6eba 2094static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2095
822a6eba 2096int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2097 struct query *q;
2098 char *argv[];
822a6eba 2099 client *cl;
a6cb4d4c 2100 int (*action)();
2101 int actarg;
822a6eba 2102{
2103 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2104 "s", "name", sflags));
2105}
a6cb4d4c 2106
a6cb4d4c 2107
822a6eba 2108/* generic qualified get routine, used by qualified_get_lists,
2109 * qualified_get_server, and qualified_get_serverhost.
2110 * Args:
2111 * start - a simple where clause, must not be empty
2112 * range - the name of the range variable
2113 * field - the field to return
2114 * flags - an array of strings, names of the flag variables
2115 */
c2408bd5 2116
822a6eba 2117int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2118 struct query *q;
2119 char *argv[];
2120 int (*action)();
2121 int actarg;
822a6eba 2122 char *start;
2123 char *range;
2124 char *field;
2125 char *flags[];
c2408bd5 2126##{
822a6eba 2127## char name[33], qual[256], *rvar, *rtbl, *rfield;
2128 char *rargv[1], buf[32];
2129## int rowcount, i;
2130
2131 strcpy(qual, start);
2132 for (i = 0; i < q->argc; i++) {
2133 if (!strcmp(argv[i], "TRUE")) {
2134 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2135 (void) strcat(qual, buf);
2136 } else if (!strcmp(argv[i], "FALSE")) {
2137 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2138 (void) strcat(qual, buf);
2139 }
2140 }
2141
2142 rargv[0] = name;
2143 rvar = range;
2144 rtbl = q->rtable;
2145 rfield = field;
2146## range of rvar is rtbl
2147## retrieve (name = rvar.rfield) where qual {
2148 (*action)(1, rargv, actarg);
c2408bd5 2149## }
822a6eba 2150## inquire_equel(rowcount = "rowcount")
2151## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2152## where tblstats.#table = @rtbl
2153 if (rowcount == 0)
2154 return(SMS_NO_MATCH);
2155 return(SMS_SUCCESS);
2156##}
c2408bd5 2157
c2408bd5 2158
822a6eba 2159/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2160 * the five flags associated with each serverhost. It will return the name of
2161 * each service and host that meets the quailifications. It does this by
2162 * building a where clause based on the arguments, then doing a retrieve.
2163 */
c2408bd5 2164
822a6eba 2165static char *shflags[6] = { "service", "enable", "override", "success",
2166 "inprogress", "hosterror" };
a6cb4d4c 2167
822a6eba 2168int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2169 struct query *q;
2170 char *argv[];
822a6eba 2171 client *cl;
a6cb4d4c 2172 int (*action)();
2173 int actarg;
2174##{
822a6eba 2175## char sname[33], mname[33], qual[256];
2176 char *rargv[2], buf[32];
2177## int rowcount, i;
2178
44bd6f44 2179 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2180 argv[0]);
2181 for (i = 1; i < q->argc; i++) {
2182 if (!strcmp(argv[i], "TRUE")) {
2183 sprintf(buf, " and sh.%s != 0", shflags[i]);
2184 strcat(qual, buf);
2185 } else if (!strcmp(argv[i], "FALSE")) {
2186 sprintf(buf, " and sh.%s = 0", shflags[i]);
2187 strcat(qual, buf);
2188 }
2189 }
2190
2191 rargv[0] = sname;
2192 rargv[1] = mname;
2193## range of sh is serverhosts
2194## retrieve (sname = sh.service, mname = machine.name) where qual {
2195 (*action)(2, rargv, actarg);
a6cb4d4c 2196## }
822a6eba 2197## inquire_equel(rowcount = "rowcount")
2198## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2199## where tblstats.#table = "serverhosts"
2200 if (rowcount == 0)
2201 return(SMS_NO_MATCH);
2202 return(SMS_SUCCESS);
2203##}
a6cb4d4c 2204
a6cb4d4c 2205
822a6eba 2206/* register_user - change user's login name and allocate a pobox, group,
2207 * filesystem, and quota for them. The user's status must start out as 0,
2208 * and is left as 2. Arguments are: user's UID, new login name, and user's
2209 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2210 * SMS_FS_STAFF, SMS_FS_MISC).
2211 */
2212
2213register_user(q, argv, cl)
2214 struct query *q;
2215 char **argv;
2216 client *cl;
2217##{
2218## char *login, dir[65], *entity, *directory, machname[33];
2219## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2220## int size, alloc, pid, m_id;
2221 int maxsize;
2222
2223 entity = cl->entity;
2224 who = cl->users_id;
2225
2226 uid = atoi(argv[0]);
2227 login = argv[1];
2228 utype = atoi(argv[2]);
2229
2230## range of u is users
2231## range of l is list
2232## range of sh is serverhosts
2233## range of n is nfsphys
2234## range of m is machine
2235
2236 /* find user */
2237## repeat retrieve (users_id = u.#users_id)
2238## where u.#uid = @uid and u.status = 0
2239## inquire_equel(rowcount = "rowcount");
2240 if (rowcount == 0)
2241 return(SMS_NO_MATCH);
2242 if (rowcount > 1)
2243 return(SMS_NOT_UNIQUE);
2244
2245 /* check new login name */
2246## repeat retrieve (flag = any(u.#login where u.#login = @login))
e1795ce1 2247 if (ingres_errno) return(sms_errcode);
2248 if (flag) return(SMS_IN_USE);
4f16dc86 2249## repeat retrieve (flag = any(l.#name where l.#name = @login))
e1795ce1 2250 if (ingres_errno) return(sms_errcode);
2251 if (flag) return(SMS_IN_USE);
99a288b9 2252## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
e1795ce1 2253 if (ingres_errno) return(sms_errcode);
2254 if (flag) return(SMS_IN_USE);
822a6eba 2255 com_err(whoami, 0, "new login name OK");
2256
2257 /* choose place for pobox, put in mid */
2258## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2259## where sh.service = "POP" and m.mach_id = sh.mach_id and
2260## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
8ac9ee7a 2261## inquire_equel(rowcount = "rowcount");
822a6eba 2262 if (rowcount == 0)
44bd6f44 2263 return(SMS_NO_POBOX);
822a6eba 2264
2265 /* change login name, set pobox */
2266## repeat replace u (#login = @login, status = 2, modtime = "now",
2267## modby = @who, modwith = @entity, potype="POP",
2268## pop_id = @mid, pmodtime="now", pmodby=@who,
2269## pmodwith=@entity)
2270## where u.#users_id = @users_id
8ac9ee7a 2271## inquire_equel(rowcount = "rowcount");
822a6eba 2272 if (rowcount != 1)
2273 return(SMS_INTERNAL);
2274 set_pop_usage(mid, 1);
2275 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
2276 trim(machname));
2277
2278 /* create group list */
2279 if (set_next_object_id("gid", "list"))
44bd6f44 2280 return(SMS_NO_ID);
822a6eba 2281 if (set_next_object_id("list_id", "list"))
44bd6f44 2282 return(SMS_NO_ID);
822a6eba 2283## repeat retrieve (list_id = values.value) where values.name = "list_id"
8ac9ee7a 2284## inquire_equel(rowcount = "rowcount");
822a6eba 2285 if (rowcount != 1)
2286 return(SMS_INTERNAL);
2287## repeat append list (name = @login, #list_id = @list_id, active = 1,
2288## public = 0, hidden = 0, maillist = 0, group = 1,
2289## #gid = values.value, desc = "User Group",
2290## acl_type = "USER", acl_id = @users_id, modtime = "now",
2291## modby = @who, modwith = @entity)
2292## where values.name = "gid"
8ac9ee7a 2293## inquire_equel(rowcount = "rowcount");
44bd6f44 2294 if (rowcount != 1)
2295 return(SMS_INTERNAL);
2296## repeat append members (#list_id = @list_id, member_type = "USER",
2297## member_id = @users_id)
8ac9ee7a 2298## inquire_equel(rowcount = "rowcount");
822a6eba 2299 if (rowcount != 1)
2300 return(SMS_INTERNAL);
2301 com_err(whoami, 0, "group list created");
2302
2303 /* decide where to put filesystem */
2304 maxsize = 0;
2305 directory = NULL;
2306## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2307## flag = n.status, size = n.#size, alloc = n.allocated) {
2308 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2309 maxsize = size - alloc;
2310 if (directory)
2311 free(directory);
2312 directory = strsave(dir);
2313 pid = nid;
2314 m_id = mid;
2315 }
a6cb4d4c 2316## }
822a6eba 2317 if (maxsize == 0)
44bd6f44 2318 return(SMS_NO_FILESYS);
822a6eba 2319
2320 /* create filesystem */
2321 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2322 return(SMS_NO_ID);
822a6eba 2323## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2324## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2325## name = @directory + "/" + @login,
2326## mount = "/mit/" + @login,
822a6eba 2327## access = "w", comments = "User Locker",
2328## owner = @users_id, owners = @list_id, createflg = 1,
2329## lockertype = "HOMEDIR", modtime = "now",
2330## modby = @who, modwith = @entity)
2331## where values.name = "filsys_id"
8ac9ee7a 2332## inquire_equel(rowcount = "rowcount");
822a6eba 2333 if (rowcount != 1)
2334 return(SMS_INTERNAL);
2335 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2336 directory, login);
822a6eba 2337
2338 /* set quota */
2339## repeat retrieve (quota = values.value) where values.name = "def_quota"
8ac9ee7a 2340## inquire_equel(rowcount = "rowcount");
822a6eba 2341 if (rowcount != 1)
44bd6f44 2342 return(SMS_NO_QUOTA);
822a6eba 2343## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2344## #quota = @quota, phys_id = @pid, modtime = "now",
2345## modby = @who, modwith = @entity)
822a6eba 2346## where values.name = "filsys_id"
8ac9ee7a 2347## inquire_equel(rowcount = "rowcount");
822a6eba 2348 if (rowcount != 1)
2349 return(SMS_INTERNAL);
2350## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2351## where nfsphys.nfsphys_id = filesys.#phys_id and
2352## filesys.filsys_id = values.value and values.name = "filsys_id"
8ac9ee7a 2353## inquire_equel(rowcount = "rowcount");
822a6eba 2354 if (rowcount != 1)
2355 return(SMS_INTERNAL);
2356 com_err(whoami, 0, "quota of %d assigned", quota);
2357
4f16dc86 2358## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2359## where tblstats.table = "users"
2360## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2361## where tblstats.table = "list" or tblstats.table = "filesys" or
2362## tblstats.table = "nfsquota"
822a6eba 2363 return(SMS_SUCCESS);
2364##}
2365
2366
2367
2368/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2369 **
2370 ** Inputs:
2371 ** id of machine
2372 ** delta (will be +/- 1)
2373 **
2374 ** Description:
2375 ** - incr/decr value field in serverhosts table for pop/mach_id
2376 **
2377 **/
2378
2379static int set_pop_usage(id, count)
2380int id;
2381int count;
2382##{
2383## int mach_id = id;
2384## int n = count;
2385
2386## range of sh is serverhosts
2387## repeat replace sh (value1 = sh.value1 + @n)
44bd6f44 2388## where sh.service = "POP" and sh.#mach_id = @mach_id
a6cb4d4c 2389
2390 return(SMS_SUCCESS);
2391##}
822a6eba 2392
2393
c2408bd5 2394\f
05cdd922 2395/* Validation Routines */
2396
2397validate_row(q, argv, v)
2398 register struct query *q;
2399 char *argv[];
2400 register struct validate *v;
2401##{
2402## char *rvar;
2403## char *table;
2404## char *name;
2405## char qual[128];
2406## int rowcount;
2407
2408 /* build where clause */
2409 build_qual(v->qual, v->argc, argv, qual);
2410
2411 /* setup ingres variables */
2412 rvar = q->rvar;
2413 table = q->rtable;
2414 name = v->field;
2415
6388c51a 2416 if (log_flags & LOG_VALID)
b4182127 2417 /* tell the logfile what we're doing */
2418 com_err(whoami, 0, "validating row: %s", qual);
2419
05cdd922 2420 /* look for the record */
2421## range of rvar is table
2422## retrieve (rowcount = count(rvar.name where qual))
e1795ce1 2423 if (ingres_errno) return(sms_errcode);
05cdd922 2424 if (rowcount == 0) return(SMS_NO_MATCH);
2425 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2426 return(SMS_EXISTS);
2427##}
2428
2429validate_fields(q, argv, vo, n)
2430 struct query *q;
2431 register char *argv[];
2432 register struct valobj *vo;
2433 register int n;
2434{
2435 register int status;
05cdd922 2436
2437 while (--n >= 0) {
2438 switch (vo->type) {
2439 case V_NAME:
6388c51a 2440 if (log_flags & LOG_VALID)
b4182127 2441 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2442 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2443 status = validate_name(argv, vo);
2444 break;
2445
2446 case V_ID:
6388c51a 2447 if (log_flags & LOG_VALID)
b4182127 2448 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2449 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2450 status = validate_id(argv, vo);
2451 break;
2452
92a943d6 2453 case V_DATE:
6388c51a 2454 if (log_flags & LOG_VALID)
92a943d6 2455 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2456 status = validate_date(argv, vo);
2457 break;
2458
05cdd922 2459 case V_TYPE:
6388c51a 2460 if (log_flags & LOG_VALID)
b4182127 2461 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2462 vo->table, argv[vo->index]);
05cdd922 2463 status = validate_type(argv, vo);
2464 break;
2465
2466 case V_TYPEDATA:
6388c51a 2467 if (log_flags & LOG_VALID)
92a943d6 2468 com_err(whoami, 0, "validating typed data (%s): %s",
2469 argv[vo->index - 1], argv[vo->index]);
05cdd922 2470 status = validate_typedata(q, argv, vo);
2471 break;
2472
822a6eba 2473 case V_RENAME:
6388c51a 2474 if (log_flags & LOG_VALID)
822a6eba 2475 com_err(whoami, 0, "validating rename %s in %s",
2476 argv[vo->index], vo->table);
2477 status = validate_rename(argv, vo);
2478 break;
2479
2480 case V_CHAR:
6388c51a 2481 if (log_flags & LOG_VALID)
822a6eba 2482 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2483 status = validate_chars(argv[vo->index]);
05cdd922 2484 break;
2485
92a943d6 2486 case V_SORT:
2487 status = SMS_EXISTS;
2488 break;
2489
e1795ce1 2490 case V_LOCK:
2491 status = lock_table(vo);
2492 break;
05cdd922 2493 }
2494
2495 if (status != SMS_EXISTS) return(status);
2496 vo++;
2497 }
2498
2499 return(SMS_SUCCESS);
2500}
2501
822a6eba 2502
2503/* validate_chars: verify that there are no illegal characters in
2504 * the string. Legal characters are printing chars other than
331b982e 2505 * ", *, ?, \, [ and ].
822a6eba 2506 */
2507static int illegalchars[] = {
2508 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2509 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2510 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2511 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2512 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2513 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2515 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2516 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2517 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2518 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2519 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2520 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2522 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2523 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2524};
2525
2526validate_chars(s)
2527register char *s;
2528{
2529 while (*s)
2530 if (illegalchars[*s++])
2531 return(SMS_BAD_CHAR);
2532 return(SMS_EXISTS);
2533}
2534
2535
05cdd922 2536validate_id(argv, vo)
2537 char *argv[];
2538 register struct valobj *vo;
2539##{
2540## char *name;
2541## char *table;
2542## char *namefield;
2543## char *idfield;
2544## int id;
2545## int rowcount;
122ec372 2546 register char *c;
05cdd922 2547
2548 name = argv[vo->index];
2549 table = vo->table;
122ec372 2550 /* minor kludge to upcasify machine names */
822a6eba 2551 if (!strcmp(table, "machine"))
122ec372 2552 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2553 namefield = vo->namefield;
2554 idfield = vo->idfield;
822a6eba 2555 if (!strcmp(namefield, "uid")) {
9119288e 2556## retrieve (id = table.idfield) where table.namefield = int4(name)
e1795ce1 2557 if (ingres_errno) return(sms_errcode);
9119288e 2558## inquire_equel (rowcount = "rowcount")
2559 } else {
2560## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2561 if (ingres_errno) return(sms_errcode);
9119288e 2562## inquire_equel (rowcount = "rowcount")
2563 }
05cdd922 2564 if (rowcount != 1) return(vo->error);
2565 *(int *)argv[vo->index] = id;
2566 return(SMS_EXISTS);
2567##}
2568
2569validate_name(argv, vo)
2570 char *argv[];
2571 register struct valobj *vo;
2572##{
2573## char *name;
2574## char *table;
2575## char *namefield;
2576## int rowcount;
44bd6f44 2577 register char *c;
05cdd922 2578
2579 name = argv[vo->index];
2580 table = vo->table;
2581 namefield = vo->namefield;
44bd6f44 2582 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2583 for (c = name; *c; c++)
2584 if (islower(*c))
2585 *c = toupper(*c);
2586 }
05cdd922 2587## retrieve (rowcount = countu(table.namefield
2588## where table.namefield = name))
e1795ce1 2589 if (ingres_errno) return(sms_errcode);
05cdd922 2590 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2591##}
2592
92a943d6 2593validate_date(argv, vo)
2594 char *argv[];
2595 struct valobj *vo;
2596##{
2597## char *idate;
2598## double dd;
2599## int errorno;
2600
2601 idate = argv[vo->index];
2602
2603## retrieve (dd = interval("years", date(idate) - date("today")))
2604## inquire_equel (errorno = "errorno")
2605 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2606 return(SMS_EXISTS);
92a943d6 2607##}
2608
822a6eba 2609
2610validate_rename(argv, vo)
2611char *argv[];
2612struct valobj *vo;
2613##{
2614## char *name, *table, *namefield, *idfield;
2615## int id;
2616 register char *c;
2617
2618 c = name = argv[vo->index];
2619 while (*c)
2620 if (illegalchars[*c++])
2621 return(SMS_BAD_CHAR);
2622 table = vo->table;
2623 /* minor kludge to upcasify machine names */
2624 if (!strcmp(table, "machine"))
2625 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2626 namefield = vo->namefield;
2627 idfield = vo->idfield;
2628 id = -1;
2629 if (idfield == 0) {
2630 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2631 return(SMS_EXISTS);
2632## retrieve (id = any(table.namefield where table.namefield = name))
e1795ce1 2633 if (ingres_errno) return(sms_errcode);
822a6eba 2634 if (id)
2635 return(vo->error);
2636 else
2637 return(SMS_EXISTS);
2638 }
2639## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2640 if (ingres_errno) return(sms_errcode);
822a6eba 2641 if (id == -1 || id == *(int *)argv[vo->index - 1])
2642 return(SMS_EXISTS);
2643 else
2644 return(vo->error);
2645##}
2646
2647
05cdd922 2648validate_type(argv, vo)
2649 char *argv[];
2650 register struct valobj *vo;
2651##{
2652## char *typename;
2653## char *value;
822a6eba 2654## int exists;
05cdd922 2655 register char *c;
2656
2657 typename = vo->table;
822a6eba 2658 c = value = argv[vo->index];
2659 while (*c)
2660 if (illegalchars[*c++])
2661 return(SMS_BAD_CHAR);
05cdd922 2662
2663 /* uppercase type fields */
2664 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2665
2666## range of a is alias
822a6eba 2667## repeat retrieve (exists = any(a.trans where a.name = @typename and
05cdd922 2668## a.type = "TYPE" and
2669## a.trans = @value))
e1795ce1 2670 if (ingres_errno) return(sms_errcode);
822a6eba 2671 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2672##}
2673
2674/* validate member or type-specific data field */
2675
2676validate_typedata(q, argv, vo)
2677 register struct query *q;
2678 register char *argv[];
2679 register struct valobj *vo;
2680##{
2681## char *name;
2682## char *field_type;
822a6eba 2683## char data_type[129];
05cdd922 2684## int id;
05cdd922 2685## int rowcount;
822a6eba 2686 char *index();
a6cb4d4c 2687 register char *c;
05cdd922 2688
2689 /* get named object */
2690 name = argv[vo->index];
2691
2692 /* get field type string (known to be at index-1) */
2693 field_type = argv[vo->index-1];
2694
2695 /* get corresponding data type associated with field type name */
2696## repeat retrieve (data_type = alias.trans)
2697## where alias.#name = @field_type and alias.type = "TYPEDATA"
e1795ce1 2698 if (ingres_errno) return(sms_errcode);
05cdd922 2699## inquire_equel (rowcount = "rowcount")
2700 if (rowcount != 1) return(SMS_TYPE);
2701
2702 /* now retrieve the record id corresponding to the named object */
822a6eba 2703 if (index(data_type, ' '))
2704 *index(data_type, ' ') = 0;
05cdd922 2705 if (!strcmp(data_type, "user")) {
2706 /* USER */
2707## repeat retrieve (id = users.users_id) where users.login = @name
2708## inquire_equel (rowcount = "rowcount")
2709 if (rowcount != 1) return(SMS_USER);
2710
2711 } else if (!strcmp(data_type, "list")) {
2712 /* LIST */
2713## repeat retrieve (id = list.list_id) where list.#name = @name
2714## inquire_equel (rowcount = "rowcount")
822a6eba 2715 if (rowcount != 1) {
2716 /* if idfield is non-zero, then if argv[0] matches the string
2717 * that we're trying to resolve, we should get the value of
2718 * values.[idfield] for the id.
2719 */
2720 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 2721 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 2722 name = vo->idfield;
4f16dc86 2723## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 2724## inquire_equel(rowcount = "rowcount")
2725 if (rowcount != 1) return(SMS_LIST);
2726 } else
2727 return(SMS_LIST);
2728 }
05cdd922 2729 } else if (!strcmp(data_type, "machine")) {
2730 /* MACHINE */
a6cb4d4c 2731 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2732## repeat retrieve (id = machine.mach_id) where machine.#name = @name
2733## inquire_equel (rowcount = "rowcount")
2734 if (rowcount != 1) return(SMS_MACHINE);
2735
2736 } else if (!strcmp(data_type, "string")) {
2737 /* STRING */
2738## range of s is strings
822a6eba 2739## repeat retrieve (id = s.string_id) where s.string = @name
05cdd922 2740## inquire_equel (rowcount = "rowcount")
2741 if (rowcount == 0) {
2742 if (q->type != APPEND) return(SMS_STRING);
2743## range of v is values
2744## retrieve (id = v.value) where v.#name = "strings_id"
2745 id++;
2746## replace v (value = id) where v.#name = "strings_id"
822a6eba 2747## append to strings (string_id = id, string = name)
05cdd922 2748 }
822a6eba 2749 } else if (!strcmp(data_type, "none")) {
2750 id = 0;
05cdd922 2751 } else {
2752 return(SMS_TYPE);
2753 }
2754
2755 /* now set value in argv */
2756 *(int *)argv[vo->index] = id;
2757
2758 return (SMS_EXISTS);
2759##}
2760
05cdd922 2761
e1795ce1 2762/* Lock the table named by the validation object */
2763
2764lock_table(vo)
2765struct valobj *vo;
2766##{
2767## char *table, *idfield;
2768## int rowcount;
2769
2770 table = vo->table;
2771 idfield = vo->idfield;
2772## replace table (modtime = "now") where table.idfield = 0
2773 if (ingres_errno) return(sms_errcode);
2774## inquire_equel (rowcount = "rowcount")
2775 if (rowcount != 1)
2776 return(vo->error);
2777 else
2778 return(SMS_EXISTS);
2779##}
2780
2781
822a6eba 2782/* This looks up a login name and returns the SMS internal ID. It is used
2783 * by authenticate to put the users_id in the client structure.
2784 */
05cdd922 2785
822a6eba 2786int get_users_id(name)
2787char *name;
2788##{
2789## int id, rowcount;
2790## char *login;
05cdd922 2791
822a6eba 2792 login = name;
05cdd922 2793
822a6eba 2794## range of u is users
2795## repeat retrieve (id = u.#users_id) where u.#login = @login
2796## inquire_equel (rowcount = "rowcount")
2797
2798 if (rowcount == 1)
2799 return(id);
2800 else
2801 return(0);
2802##}
05cdd922 2803
05cdd922 2804
822a6eba 2805/* Check the database at startup time. For now this just resets the
2806 * inprogress flags that the DCM uses.
2807 */
05cdd922 2808
822a6eba 2809sanity_check_database()
2810##{
05cdd922 2811##}
This page took 0.515481 seconds and 5 git commands to generate.