* $Header$
*
* Copyright (C) 1987 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*
*/
static char *rcsid_qsupport_qc = "$Header$";
#endif lint
+#include <mit-copyright.h>
#include "query.h"
#include "sms_server.h"
#include <ctype.h>
extern char *whoami, *strsave();
+extern int ingres_errno, sms_errcode;
/* Specialized Access Routines */
* Inputs: argv[0] - list_id
* q - query name
* argv[2] - member ID (only for queries "amtl" and "dmfl")
- * cl - client name
+ * argv[7] - group IID (only for query "ulis")
+ * cl - client name
*
* - check that client is a member of the access control list
* - OR, if the query is add_member_to_list or delete_member_from_list
char *argv[];
client *cl;
##{
-## int list_id, acl_id, flags, rowcount;
+## int list_id, acl_id, flags, rowcount, gid;
## char acl_type[9];
char *client_type;
int client_id, status;
list_id = *(int *)argv[0];
## repeat retrieve (acl_id = list.#acl_id, acl_type = list.#acl_type,
-## flags = list.#public)
+## gid = list.#gid, flags = list.#public)
## where list.#list_id = @list_id
## inquire_equel(rowcount = "rowcount")
if (rowcount != 1)
if ((!strcmp("amtl", q->shortname) || !strcmp("dmfl", q->shortname)) &&
(flags && !strcmp("USER", argv[1]))) {
if (*(int *)argv[2] == client_id) return(SMS_SUCCESS);
+ /* if update_list, don't allow them to change the GID */
+ } else if (!strcmp("ulis", q->shortname)) {
+ if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
+ (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
+ return(SMS_PERM);
}
/* check for client in access control list */
return(access_visible_list(q, &argv[1], cl));
if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
- if (!strcmp(cl->kname.name, argv[1]))
+ if (cl->users_id == *(int *)argv[1])
return(SMS_SUCCESS);
}
## int flag, id;
id = *(int *)argv[0];
+
+ /* For now, only allow users to be deleted if their status is 0 */
+## repeat retrieve (flag = u.status) where u.users_id = @id
+ if (flag != 0)
+ return(SMS_IN_USE);
+
## repeat delete nfsquota where nfsquota.users_id = @id
## repeat retrieve (flag = any(members.member_id where members.member_id=@id
## and members.member_type = "USER"))
struct query *q;
char **argv;
##{
-## int id, flag;
+## int id, mid, flag;
## char type[9];
id = *(int *)argv[0];
-## repeat retrieve (type = u.potype, flag = any(machine.name
-## where machine.mach_id = u.pop_id
-## and u.pop_id != 0
-## and u.users_id = @id))
+## repeat retrieve (type = u.potype, mid = u.pop_id,
+## flag = any(machine.name where machine.mach_id = u.pop_id
+## and u.pop_id != 0 and u.users_id = @id))
## where u.users_id = @id
if (!flag)
return(SMS_MACHINE);
- if (strcmp(type, "POP"))
- set_pop_usage(id, 1);
+ if (strcmp(strtrim(type), "POP"))
+ set_pop_usage(mid, 1);
return(SMS_SUCCESS);
##}
## repeat retrieve (type = u.potype, id = u.pop_id)
## where u.users_id = @user
- if (strcmp(type, "POP"))
+ if (!strcmp(strtrim(type), "POP"))
set_pop_usage(id, -1);
return(SMS_SUCCESS);
##}
## repeat retrieve (flag = any(hostaccess.mach_id where hostaccess.mach_id=@id))
if (flag)
return(SMS_IN_USE);
+## repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
+ if (flag)
+ return(SMS_IN_USE);
## repeat delete mcmap where mcmap.mach_id = @id
return(SMS_SUCCESS);
}
+/* Verify the arguments, depending on the FStype. Also, if this is an
+ * NFS filesystem, then update any quotas for that filesystem to reflect
+ * the new phys_id.
+ */
+
setup_ufil(q, argv)
struct query *q;
char *argv[];
-{
- char *type;
- int mach_id;
- char *name;
- char *access;
+##{
+ int mach_id, status;
+ char *type, *name, *access;
+## int fid;
type = argv[2];
mach_id = *(int *)argv[3];
access = argv[6];
var_phys_id = 0;
- if (!strcmp(type, "NFS"))
- return (check_nfs(mach_id, name, access));
- else
- return(SMS_SUCCESS);
-}
+ if (!strcmp(type, "NFS")) {
+ status = check_nfs(mach_id, name, access);
+ fid = *(int *)argv[0];
+## replace nfsquota (phys_id = var_phys_id) where nfsquota.filsys_id = fid
+ return(status);
+ } else
+ return(SMS_SUCCESS);
+##}
/* Find the NFS physical partition that the named directory is on.
##}
-/* setup_dfil: free any quota records associated with a filesystem
- * when it is deleted.
+/* setup_dfil: free any quota records and fsgroup info associated with
+ * a filesystem when it is deleted. Also adjust the allocation numbers.
*/
setup_dfil(q, argv, cl)
## where n.nfsphys_id = fs.phys_id and fs.filsys_id = @id
## repeat delete q where q.filsys_id = @id
+## repeat delete fsgroup where fsgroup.filsys_id = @id
+## repeat delete fsgroup where fsgroup.group_id = @id
return(SMS_SUCCESS);
##}
##}
-/* Sets the modtime on a machine record. The machine name is in argv[0].
- * This routine is different from the generic set_modtime in that the
- * name is uppercased first.
+/* Like set_modtime, but uppercases the name first.
*/
-set_mach_modtime(q, argv, cl)
+set_uppercase_modtime(q, argv, cl)
struct query *q;
char **argv;
client *cl;
##{
-## char *host, *entity;
+## char *name, *entity, *table;
## int who;
entity = cl->entity;
who = cl->users_id;
+ table = q->rtable;
+ name = argv[0];
- host = argv[0];
-## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
-## where m.name = uppercase(@host)
+## replace table (modtime = "now", modby = who, modwith = entity)
+## where table.#name = uppercase(name)
return(SMS_SUCCESS);
##}
strcpy(name, "???");
} else if (!strcmp(type, "USER")) {
## repeat retrieve (name = users.login) where users.users_id = @id
+## inquire_equel(rowcount = "rowcount")
+ if (rowcount != 1)
+ strcpy(name, "???");
+ } else if (!strcmp(type, "KERBEROS")) {
+## repeat retrieve (name = strings.string) where strings.string_id = @id
## inquire_equel(rowcount = "rowcount")
if (rowcount != 1)
strcpy(name, "???");
strcpy(name, "???");
} else if (!strcmp(argv[i], "USER")) {
## repeat retrieve (name = users.login) where users.users_id = @id
+## inquire_equel(rowcount = "rowcount")
+ if (rowcount != 1)
+ strcpy(name, "???");
+ } else if (!strcmp(argv[i], "KERBEROS")) {
+## repeat retrieve (name = strings.string) where strings.string_id = @id
## inquire_equel(rowcount = "rowcount")
if (rowcount != 1)
strcpy(name, "???");
strcpy(name, "???");
} else if (!strcmp(argv[1], "USER")) {
## repeat retrieve (name = users.login) where users.users_id = @id
+## inquire_equel(rowcount = "rowcount")
+ if (rowcount != 1)
+ strcpy(name, "???");
+ } else if (!strcmp(argv[1], "KERBEROS")) {
+## repeat retrieve (name = strings.string) where strings.string_id = @id
## inquire_equel(rowcount = "rowcount")
if (rowcount != 1)
strcpy(name, "???");
## repeat retrieve (id = users.pop_id, potype = users.#potype)
## where users.users_id = @user
- if (!strcmp(potype, "POP"))
+ if (!strcmp(strtrim(potype), "POP"))
set_pop_usage(id, -1);
if (!strcmp(argv[1], "POP")) {
} else if (!strcmp(acl_type, "USER")) {
## repeat retrieve (acl_name = users.#login)
## where users.users_id = @acl_id
+## inquire_equel(rowcount = "rowcount")
+ if (rowcount != 1)
+ strcpy(acl_name, "???");
+ } else if (!strcmp(acl_type, "KERBEROS")) {
+## repeat retrieve (acl_name = strings.string)
+## where strings.string_id = @acl_id
## inquire_equel(rowcount = "rowcount")
if (rowcount != 1)
strcpy(acl_name, "???");
atype = argv[0];
aid = *(int *)argv[1];
- if (!strcmp(atype, "LIST") || !strcmp(atype, "USER")) {
+ if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
+ !strcmp(atype, "KERBEROS")) {
return(get_ace_internal(atype, aid, action, actarg));
}
found++;
}
+ if (!strcmp(atype, "RKERBERO")) {
+## range of m is members
+## repeat retrieve (listid = m.list_id)
+## where m.member_type = "KERBEROS" and m.member_id = @aid {
+ sq_save_data(sq, listid);
+## }
+ /* get all the list_id's of containing lists */
+ while (sq_get_data(sq, &id)) {
+## repeat retrieve (listid = m.list_id)
+## where m.member_type = "LIST" and m.member_id = @id {
+ sq_save_unique_data(sq, listid);
+## }
+ }
+ /* now process each one */
+ while (sq_get_data(sq, &id)) {
+ if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
+ found++;
+ }
+ if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
+ found++;
+ }
+
sq_destroy(sq);
if (!found) return(SMS_NO_MATCH);
return(SMS_SUCCESS);
aid = *(int *)argv[1];
if (!strcmp(atype, "LIST") ||
!strcmp(atype, "USER") ||
- !strcmp(atype, "STRING")) {
+ !strcmp(atype, "STRING") ||
+ !strcmp(atype, "KERBEROS")) {
return(glom_internal(atype, aid, action, actarg));
}
found++;
}
+ if (!strcmp(atype, "RKERBERO")) {
+## range of m is members
+## repeat retrieve (listid = m.list_id)
+## where m.member_type = "KERBEROS" and m.member_id = @aid {
+ sq_save_data(sq, listid);
+## }
+ /* get all the list_id's of containing lists */
+ while (sq_get_data(sq, &id)) {
+## repeat retrieve (listid = m.list_id)
+## where m.member_type = "LIST" and m.member_id = @id {
+ sq_save_unique_data(sq, listid);
+## }
+ }
+ /* now process each one */
+ while (sq_get_data(sq, &id)) {
+ if (glom_internal("LIST", id, action, actarg) == SMS_SUCCESS)
+ found++;
+ }
+ if (glom_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
+ found++;
+ }
+
## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
## where tblstats.#table = "members"
sq_destroy(sq);
## where m.#list_id = @list_id and m.member_type = "STRING"
## and m.member_id = strings.string_id
## sort by #member_name
+## {
+ (*action)(2, targv, actarg);
+## }
+
+ targv[0] = "KERBEROS";
+## repeat retrieve (member_name = strings.string)
+## where m.#list_id = @list_id and m.member_type = "KERBEROS"
+## and m.member_id = strings.string_id
+## sort by #member_name
## {
(*action)(2, targv, actarg);
## }
/* check new login name */
## repeat retrieve (flag = any(u.#login where u.#login = @login))
- if (flag)
- return(SMS_IN_USE);
+ if (ingres_errno) return(sms_errcode);
+ if (flag) return(SMS_IN_USE);
## repeat retrieve (flag = any(l.#name where l.#name = @login))
- if (flag)
- return(SMS_IN_USE);
-## repeat retrieve (flag = any(filesys.#name where filesys.#name = @login))
- if (flag)
- return(SMS_IN_USE);
+ if (ingres_errno) return(sms_errcode);
+ if (flag) return(SMS_IN_USE);
+## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
+ if (ingres_errno) return(sms_errcode);
+ if (flag) return(SMS_IN_USE);
com_err(whoami, 0, "new login name OK");
/* choose place for pobox, put in mid */
if (rowcount != 1)
return(SMS_NO_QUOTA);
## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
-## #quota = @quota, modtime = "now", modby = @who,
-## modwith = @entity)
+## #quota = @quota, phys_id = @pid, modtime = "now",
+## modby = @who, modwith = @entity)
## where values.name = "filsys_id"
## inquire_equel(rowcount = "rowcount");
if (rowcount != 1)
table = q->rtable;
name = v->field;
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
/* tell the logfile what we're doing */
com_err(whoami, 0, "validating row: %s", qual);
/* look for the record */
## range of rvar is table
## retrieve (rowcount = count(rvar.name where qual))
+ if (ingres_errno) return(sms_errcode);
if (rowcount == 0) return(SMS_NO_MATCH);
if (rowcount > 1) return(SMS_NOT_UNIQUE);
return(SMS_EXISTS);
while (--n >= 0) {
switch (vo->type) {
case V_NAME:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating %s in %s: %s",
vo->namefield, vo->table, argv[vo->index]);
status = validate_name(argv, vo);
break;
case V_ID:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating %s in %s: %s",
vo->idfield, vo->table, argv[vo->index]);
status = validate_id(argv, vo);
break;
case V_DATE:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating date: %s", argv[vo->index]);
status = validate_date(argv, vo);
break;
case V_TYPE:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating %s type: %s",
vo->table, argv[vo->index]);
status = validate_type(argv, vo);
break;
case V_TYPEDATA:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating typed data (%s): %s",
argv[vo->index - 1], argv[vo->index]);
status = validate_typedata(q, argv, vo);
break;
case V_RENAME:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating rename %s in %s",
argv[vo->index], vo->table);
status = validate_rename(argv, vo);
break;
case V_CHAR:
- if (log_flags & LOG_RES)
+ if (log_flags & LOG_VALID)
com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
status = validate_chars(argv[vo->index]);
break;
status = SMS_EXISTS;
break;
+ case V_LOCK:
+ status = lock_table(vo);
+ break;
}
if (status != SMS_EXISTS) return(status);
/* validate_chars: verify that there are no illegal characters in
* the string. Legal characters are printing chars other than
- * ", *, ?, [ and ].
+ * ", *, ?, \, [ and ].
*/
static int illegalchars[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, /* P - _ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
idfield = vo->idfield;
if (!strcmp(namefield, "uid")) {
## retrieve (id = table.idfield) where table.namefield = int4(name)
+ if (ingres_errno) return(sms_errcode);
## inquire_equel (rowcount = "rowcount")
} else {
## retrieve (id = table.idfield) where table.namefield = name
+ if (ingres_errno) return(sms_errcode);
## inquire_equel (rowcount = "rowcount")
}
if (rowcount != 1) return(vo->error);
}
## retrieve (rowcount = countu(table.namefield
## where table.namefield = name))
+ if (ingres_errno) return(sms_errcode);
return ((rowcount == 1) ? SMS_EXISTS : vo->error);
##}
if (!strcmp(argv[vo->index], argv[vo->index - 1]))
return(SMS_EXISTS);
## retrieve (id = any(table.namefield where table.namefield = name))
+ if (ingres_errno) return(sms_errcode);
if (id)
return(vo->error);
else
return(SMS_EXISTS);
}
## retrieve (id = table.idfield) where table.namefield = name
+ if (ingres_errno) return(sms_errcode);
if (id == -1 || id == *(int *)argv[vo->index - 1])
return(SMS_EXISTS);
else
## repeat retrieve (exists = any(a.trans where a.name = @typename and
## a.type = "TYPE" and
## a.trans = @value))
+ if (ingres_errno) return(sms_errcode);
return (exists ? SMS_EXISTS : vo->error);
##}
/* get corresponding data type associated with field type name */
## repeat retrieve (data_type = alias.trans)
## where alias.#name = @field_type and alias.type = "TYPEDATA"
+ if (ingres_errno) return(sms_errcode);
## inquire_equel (rowcount = "rowcount")
if (rowcount != 1) return(SMS_TYPE);
##}
+/* Lock the table named by the validation object */
+
+lock_table(vo)
+struct valobj *vo;
+##{
+## char *table, *idfield;
+## int rowcount;
+
+ table = vo->table;
+ idfield = vo->idfield;
+## replace table (modtime = "now") where table.idfield = 0
+ if (ingres_errno) return(sms_errcode);
+## inquire_equel (rowcount = "rowcount")
+ if (rowcount != 1)
+ return(vo->error);
+ else
+ return(SMS_EXISTS);
+##}
+
+
/* This looks up a login name and returns the SMS internal ID. It is used
* by authenticate to put the users_id in the client structure.
*/
sanity_check_database()
##{
-## replace servers (inprogress = 0)
-## replace serverhosts (inprogress = 0)
##}