From e8660f0a90abd4c0768e0cae2a406b019293aff8 Mon Sep 17 00:00:00 2001 From: mar Date: Thu, 30 Jun 1988 12:46:01 +0000 Subject: [PATCH] Initial revision --- server/qoldsup.qc | 678 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 server/qoldsup.qc diff --git a/server/qoldsup.qc b/server/qoldsup.qc new file mode 100644 index 00000000..dcf3bc15 --- /dev/null +++ b/server/qoldsup.qc @@ -0,0 +1,678 @@ +/* + * These are query support routines that are specific to the old version + * of the protocol. This file may be removed once support for the old + * protocol has been discontinued. + * + * $Source$ + * $Author$ + * $Header$ + * + * Copyright (C) 1987 by the Massachusetts Institute of Technology + * + */ + +#ifndef lint +static char *rcsid_qsupport_qc = "$Header$"; +#endif lint + +#include "query.h" +#include "sms_server.h" +#include + + +extern char *whoami; + + +add_locker() { return(SMS_UNKNOWN_PROC); } +add_user_group() { return(SMS_UNKNOWN_PROC); } + + +/* Specialized Access Routines */ + + +/** + ** access_maillist - access_list + disallow adding user-group to maillists + ** + ** Inputs: + ** argv[0] - list_id + ** cl - client name + ** + **/ + +access_maillist(q, argv, cl) + struct query *q; + char *argv[]; + client *cl; +##{ +## int list_id; +## int exists; +## char list_name[32]; + int status; + + if ((status = access_list(q, argv, cl)) != SMS_SUCCESS) + return(status); + if (strcmp(q->name, "add_maillist")) + return(status); + + list_id = *(int *)argv[0]; +## range of l is list +## repeat retrieve (exists = any(l.#list_id +## where l.group != 0 and l.#list_id = @list_id)) + if (!exists) return(SMS_SUCCESS); +## repeat retrieve (exists = any(users.login where users.login = l.name and +## l.#list_id = @list_id)) + return ((exists) ? SMS_USER_GROUP : SMS_SUCCESS); +##} + + + +/* Setup Routines */ + + + +/* FOLLOWUP ROUTINES */ + +/* followup_gpob: fixes argv[2] based on the IDs currently there and the + * type in argv[1]. Then completes the upcall to the user. + * + * argv[2] is of the form "123:234" where the first integer is the machine + * ID if it is a pop box, and the second is the string ID if it is an SMTP + * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE + * are skipped. + * + * followup_old_gpob does the same thing for old style queries. The format + * is a little different and there is one more argument, but the idea is + * the same. + */ + +followup_old_gpob(q, sq, v, action, actarg, cl) + register struct query *q; + register struct save_queue *sq; + register struct validate *v; + register int (*action)(); + int actarg; + client *cl; +##{ + char **argv, *p, *index(); + char *ptype; +## char mach[129], box[129]; +## int id, rowcount; + + /* for each row */ + while (sq_get_data(sq, &argv)) { + ptype = argv[1]; + sms_trim_args(2, argv); + + if (!strcmp(ptype, "POP")) { + id = atoi(argv[2]); +## repeat retrieve (mach=machine.name) where machine.mach_id=@id + strcpy(box, argv[0]); + } else if (!strcmp(ptype, "SMTP")) { + id = atoi(argv[3]); +## repeat retrieve (box=strings.string) where strings.string_id=@id +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + return(SMS_STRING); + p = index(box, '@'); + if (p) { + *p++ = 0; + strcpy(mach, p); + } else + strcpy(mach, ""); + } else /* ptype == "NONE" */ { + goto skip; + } + + free(argv[2]); + argv[2] = mach; + free(argv[3]); + argv[3] = box; + (*action)(q->vcnt, argv, actarg); + skip: + /* free saved data */ + free(argv[0]); + free(argv[1]); + free(argv); + } + + sq_destroy(sq); + return (SMS_SUCCESS); +##} + + +/* Specialized query routines */ + +/* set_user_pobox - this does all of the real work. + * argv = user_id, type, machine, box + */ +int set_user_pobox(q, argv, cl) + struct query *q; + char **argv; + client *cl; +##{ +## int user, id, rowcount; +## char *host; +## char buffer[256]; + + host = argv[2]; + user = *(int *)argv[0]; + + if (!strcmp(argv[1], "POP")) { +## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@host) +## inquire_equel(rowcount = "rowcount") + if (rowcount == 0) + return(SMS_MACHINE); +## replace users (potype="POP", pop_id=id) where users.users_id = user + } else if (!strcmp(argv[1], "SMTP")) { + sprintf(buffer, "%s@%s", argv[3], host); +## range of s is strings +## repeat retrieve (id = s.string_id) where s.string = @buffer +## inquire_equel (rowcount = "rowcount") + if (rowcount == 0) { +## range of v is values +## repeat retrieve (id = v.value) where v.name = "strings_id" + id++; +## repeat replace v (value = @id) where v.name = "strings_id" +## append to strings (string_id = id, string = buffer) + } +## repeat replace users (potype="SMTP",box_id=@id) +## where users.users_id = @user + } else /* argv[1] == "NONE" */ { +## repeat replace users (potype="NONE") where users.users_id = @user + } + set_old_pop_usage(q, argv, 1); + set_pobox_modtime(q, argv, cl); + return(SMS_SUCCESS); +##} + +followup_delete_pobox(q, argv, cl) + struct query *q; + char *argv[]; + client *cl; +{ + set_old_pop_usage(q, argv, -1); + set_pobox_modtime(q, argv, cl); + return(SMS_SUCCESS); +} + +/** set_old_pop_usage - incr/decr usage count for pop server in serverhosts + ** table + ** + ** Inputs: + ** q->name - "add_pobox" or "delete_pobox" + ** argv[1] - type + ** argv[2] - mach_id + ** + ** Description: + ** - incr/decr value field in serverhosts table for pop/mach_id + ** + **/ + +set_old_pop_usage(q, argv, count) + struct query *q; + char *argv[]; +##{ +## int mach_id; +## int n; + + if (bcmp(argv[1], "POP", 3)) return(SMS_SUCCESS); + + mach_id = *(int *)argv[2]; + n = count; + +## range of sh is serverhosts +## repeat replace sh (value1 = sh.value1 + @n) +## where sh.service = "pop" and sh.#mach_id = @mach_id + + return(SMS_SUCCESS); +##} + + +/* Finds "acl_type:acl_name" in the argv (index depends on query) and + * replaces it with the list or user name. + */ + +followup_fix_acl(q, sq, v, action, actarg, cl) + register struct query *q; + register struct save_queue *sq; + register struct validate *v; + register int (*action)(); + int actarg; + client *cl; +##{ + char **argv, *p, *index(), *malloc(); +## char *name, *acl; +## int id, i, rowcount; + int idx; + + if (!strcmp(q->shortname, "gaml")) + idx = 1; + else if (!strcmp(q->shortname, "gamd")) + idx = 1; + else + idx = 2; + + while (sq_get_data(sq, &argv)) { + name = argv[idx]; + p = index(name, ':'); + *p++ = 0; + id = atoi(p); + if ((acl = malloc(33)) == NULL) + return(SMS_NO_MEM); + if (!strcmp(name, "LIST")) { +## repeat retrieve (acl = list.#name) where list.list_id = @id +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + strcpy(acl, "???"); + } else if (!strcmp(name, "USER")) { +## repeat retrieve (acl = users.login) where users.users_id = @id +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + strcpy(acl, "???"); + } else + strcpy(acl, "???"); + free(argv[idx]); + argv[idx] = acl; + + /* send the data */ + (*action)(q->vcnt, argv, actarg); + + /* free saved data */ + for (i = 0; i < q->vcnt; i++) + free(argv[i]); + free(argv); + } + + sq_destroy(sq); + return (SMS_SUCCESS); +##} + + +/** + ** get_list_is_group + ** get_list_is_maillist + ** + ** Inputs: + ** argv[0] - list_id + ** + ** Returns: + ** {true | false} + ** + **/ + +get_list_is_group(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +##{ +## int exists, list_id, rowcount; + char *result; + + list_id = *(int *)argv[0]; + +## range of l is list +## repeat retrieve (exists = l.group) where l.#list_id = @list_id +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + return(SMS_NOT_UNIQUE); + + result = (exists) ? "true" : "false"; + (*action)(1, &result, actarg); + return(SMS_SUCCESS); +##} + +get_list_is_maillist(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +##{ +## int exists, list_id, rowcount; + char *result; + + list_id = *(int *)argv[0]; + +## range of l is list +## repeat retrieve (exists = l.maillist) where l.#list_id = @list_id +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + return(SMS_NOT_UNIQUE); + + result = (exists) ? "true" : "false"; + (*action)(1, &result, actarg); + return(SMS_SUCCESS); +##} + + +/* implements the get lists of administrator query. It's fairly + * straightforward, but too complex for the regular query table. + * First retrieve any lists with a USER acl which matches the + * specified user. Then retrieve any lists with an acl which is a + * list which has the specified user as a member. + */ + +get_lists_of_administrator(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +##{ +## int user; +## char name[33]; + char *args; + +## range of l is list +## range of m is members + user = *(int *) argv[0]; + args = name; + +## repeat retrieve (name = l.#name) +## where l.acl_type = "USER" and l.acl_id = @user { + (*action)(1, &args, actarg); +## } + +## repeat retrieve (name = l.#name) +## where l.acl_type = "LIST" and l.acl_id = m.#list_id +## and m.member_type = "USER" and m.member_id = @user { + (*action)(1, &args, actarg); +## } + return(SMS_SUCCESS); +##} + + +/** + ** Setup routine for add_group + ** + ** Inputs: none + ** + ** Description: allocate next gid and store in values table + ** + **/ + +setup_add_group(q, argv, cl) + struct query *q; + char *argv[]; + client *cl; +##{ +## int ngid, exists, rowcount, list_id; + int status; + +## range of l is list +## range of v is values + list_id = *(int *)argv[0]; + +## repeat retrieve (exists = l.group) where l.#list_id = @list_id + if (exists) + return(SMS_EXISTS); + +## repeat retrieve (ngid = v.value) where v.name = "gid" + exists = 1; + while (exists) { + ngid++; +## repeat retrieve (exists = any(l.#gid where l.#gid = @ngid)) + } + +## repeat replace v (value = @ngid) where v.name = "gid" +## inquire_equel (rowcount = "rowcount") + if (rowcount != 1) return SMS_INGRES_ERR; + else return(SMS_SUCCESS); +##} + +/** + ** get_groups_of_user - optimized query for retrieval of all groups to + ** which a user belongs + ** + **/ + +get_groups_of_user(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +##{ +## int users_id; +## char list_name[33]; +## char gid[11]; +## int rowcount; + char *targv[2]; + + users_id = *(int *)argv[0]; + targv[0] = list_name; + targv[1] = gid; + +## range of m is members +## range of l is list + +## repeat retrieve (list_name = l.name, gid = text(l.#gid)) +## where m.member_id = @users_id and m.member_type = "USER" and +## m.list_id = l.list_id and l.group != 0 +## sort by #list_name +## { + (*action)(2, targv, actarg); +## } +## inquire_equel (rowcount = "rowcount") + + return ((rowcount = 0) ? SMS_NO_MATCH : SMS_SUCCESS); +##} + +get_groups_of_all_users(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +##{ +## char login[9]; +## char group[33]; +## char gid[11]; + char *targv[3]; +## int errorno; + + targv[0] = login; + targv[1] = group; + targv[2] = gid; + +## range of u is users +## range of l is list +## range of m is members + +## set lockmode session where readlock = nolock + +## repeat retrieve (login = u.#login, group = l.name, gid = text(l.#gid)) +## where m.member_type = "USER" and m.member_id = u.users_id and +## u.status != 0 and m.list_id = l.list_id and l.group != 0 +## sort by #login, #group +## { + (*action)(3, targv, actarg); +## } + +## inquire_equel (errorno = "errorno") +## set lockmode session where readlock = system + + return((errorno) ? SMS_INGRES_ERR : SMS_SUCCESS); +##} + + +/* expand_list_flags - takes the flag value stuffed into list.active of + * the list just created, and expands that value into hidden & public, + * then sets the modtime on the list. + */ +expand_list_flags(q, argv, cl) + struct query *q; + char **argv; + client *cl; +##{ +## int id, flags, active, public, hidden, who; +## char *entity; + + if (!strcmp(q->shortname, "ulis")) { + id = *(int *)argv[0]; + } else { +## repeat retrieve (id = values.value) where values.name = "list_id" + } + +## repeat retrieve (flags = l.#active) where l.list_id = @id + active = flags & 1; + public = (flags & 2) >> 1; + hidden = (flags & 4) >> 2; + entity = cl->entity; + who = cl->users_id; +## repeat replace l (#active = @active, #public = @public, #hidden = @hidden, +## modtime = "now", modby = @who, modwith = @entity) +## where l.list_id = @id + return(SMS_SUCCESS); +##} + + +/** + ** add_new_quota + ** delete_current_quota - adjust nfsphys values on xxx_quota queries. + ** + ** Inputs: + ** argv[0] - mach_id + ** argv[1] - device + ** argv[2] - users_id + ** argv[3] - quota (add_new_quota only) + ** + ** Description: + ** delete_current_quota: + ** - find nfsquota entry + ** - decrement nfsphys.allocated by nfsquota.quota + ** add_new_quota + ** - increment nfsphys.allocated by quota + ** + **/ + +add_new_quota(q, argv, cl) + struct query *q; + register char *argv[]; + client *cl; +##{ +## int mach_id; +## char *device; +## int quota; + + mach_id = *(int*)argv[0]; + device = argv[1]; + quota = *(int *)argv[3]; + +## range of np is nfsphys +## repeat replace np (allocated = np.allocated + @quota) +## where np.#mach_id = @mach_id and np.#device = @device + + return(SMS_SUCCESS); +##} + +delete_current_quota(q, argv, cl) + struct query *q; + register char *argv[]; + client *cl; +##{ +## int mach_id; +## int users_id; +## char *device; +## int quota; + + mach_id = *(int *)argv[0]; + device = argv[1]; + users_id = *(int *)argv[2]; + +## range of np is nfsphys +## range of nq is nfsquota +## repeat retrieve (quota = nq.#quota) +## where nq.#mach_id = @mach_id and nq.#device = @device and +## nq.#users_id = @users_id +## repeat replace np (allocated = np.allocated - @quota) +## where np.#mach_id = @mach_id and np.#device = @device + + return(SMS_SUCCESS); +##} + + +/** + ** delete_locker - special query routine for deleting a user locker + ** + ** Inputs: + ** argv[0] - users_id + ** + ** Description: + ** - get login name from users_id + ** - get filesys entry from login + ** - use filesys.mach_id and filesys.name to determine machine/device + ** pair for nfsphys and nfsquota + ** - delete filesys entry (label=) + ** - decrement allocated in nfsphys by quota + ** - delete nfsquota entry + ** + ** Errors: + ** - SMS_FILESYS - no filesys exists for user + ** + **/ + +delete_locker(q, argv) + register struct query *q; + register char *argv[]; +##{ +## int users_id; +## int mach_id; +## int quota; +## int rowcount; +## char login[9]; +## char lname[64]; +## char ndev[32]; + char *rindex(); + register char *c; + + /* copy arguments */ + users_id = *(int *)argv[0]; + +## range of u is users +## range of f is filesys +## range of np is nfsphys +## range of nq is nfsquota +## range of tbs is tblstats + + /* get login name */ +## repeat retrieve (login = u.#login) where u.#users_id = @users_id + + /* get mach_id and locker name from filesys entry; then delete it */ +## repeat retrieve (mach_id = f.#mach_id, lname = f.#name) +## where f.#label = @login +## inquire_equel (rowcount = "rowcount") + if (rowcount == 0) return(SMS_FILESYS); +## repeat delete f where f.#label = @login + + /* get prefix directory */ + c = rindex(lname, '/'); + *c = 0; + + /* get nfs device */ +## repeat retrieve (ndev = np.device) +## where np.#mach_id = @mach_id and np.dir = @lname + + /* get quota from nfsquota entry; then delete entry */ +## repeat retrieve (quota = nq.#quota) +## where nq.#mach_id = @mach_id and nq.#device = @ndev and +## nq.#users_id = @users_id +## repeat delete nq where nq.#mach_id = @mach_id and nq.#device = @ndev and +## nq.#users_id = @users_id + + /* decrement nfsphys.allocated */ +## repeat replace np (allocated = np.allocated - @quota) +## where np.#mach_id = @mach_id and np.#device = @ndev + + /* adjust table statistics */ +## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now") +## where tbs.table = "filesys" +## repeat replace tbs (updates = tbs.updates + 1, modtime = "now") +## where tbs.table = "nfsphys" +## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now") +## where tbs.table = "nfsquota" + + return(SMS_SUCCESS); +##} -- 2.45.2