6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 * For copying and distribution information, please see the file
13 static char *rcsid_qsupport_dc = "$Header$";
16 #include <mit-copyright.h>
18 #include "mr_server.h"
20 EXEC SQL INCLUDE sqlca;
21 EXEC SQL INCLUDE sqlda;
25 extern int ingres_errno, mr_errcode;
27 EXEC SQL BEGIN DECLARE SECTION;
28 extern char stmt_buf[];
29 EXEC SQL END DECLARE SECTION;
31 EXEC SQL WHENEVER SQLERROR CALL ingerr;
34 /* Specialized Access Routines */
36 /* access_user - verify that client name equals specified login name
38 * - since field validation routines are called first, a users_id is
39 * now in argv[0] instead of the login name.
42 access_user(q, argv, cl)
47 if (cl->users_id != *(int *)argv[0])
55 /* access_login - verify that client name equals specified login name
57 * argv[0...n] contain search info. q->
60 access_login(q, argv, cl)
65 EXEC SQL BEGIN DECLARE SECTION;
68 EXEC SQL END DECLARE SECTION;
71 Ingres will lose horribly if you try to look up a user with
72 a username > 8 chars (which some old versions of the moira client
73 still sometimes do). This routine is only called by gubl/gual and
74 gubu/guau, so we know argv[0] must be <=8 chars in a correct
75 query, so verify that first */
76 if(strlen(argv[0])>8) return MR_ARG_TOO_LONG;
79 build_qual(q->qual, q->argc, argv, qual);
80 if (!strncmp(q->name,"get_user_account",strlen("get_user_account"))) {
81 EXEC SQL SELECT users_id INTO :id FROM users u, strings str WHERE :qual;
83 EXEC SQL SELECT users_id INTO :id FROM users u WHERE :qual;
86 if (sqlca.sqlerrd[2] != 1 || id != cl->users_id)
94 /* access_list - check access for most list operations
96 * Inputs: argv[0] - list_id
98 * argv[2] - member ID (only for queries "amtl" and "dmfl")
99 * argv[7] - group IID (only for query "ulis")
102 * - check that client is a member of the access control list
103 * - OR, if the query is add_member_to_list or delete_member_from_list
104 * and the list is public, allow access if client = member
107 access_list(q, argv, cl)
112 EXEC SQL BEGIN DECLARE SECTION;
113 int list_id, acl_id, flags, gid;
115 EXEC SQL END DECLARE SECTION;
117 int client_id, status;
119 list_id = *(int *)argv[0];
120 EXEC SQL SELECT acl_id, acl_type, gid, publicflg
121 INTO :acl_id, :acl_type, :gid, :flags
123 WHERE list_id = :list_id;
125 if (sqlca.sqlerrd[2] != 1)
128 /* parse client structure */
129 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
132 /* if amtl or dmfl and list is public allow client to add or delete self */
133 if (((!strcmp("amtl", q->shortname) && flags) ||
134 (!strcmp("dmfl", q->shortname))) &&
135 (!strcmp("USER", argv[1]))) {
136 if (*(int *)argv[2] == client_id) return(MR_SUCCESS);
137 /* if update_list, don't allow them to change the GID */
138 } else if (!strcmp("ulis", q->shortname)) {
139 if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
140 (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
144 /* check for client in access control list */
145 status = find_member(acl_type, acl_id, client_type, client_id, 0);
146 if (!status) return(MR_PERM);
152 /* access_visible_list - allow access to list only if it is not hidden,
153 * or if the client is on the ACL
155 * Inputs: argv[0] - list_id
156 * cl - client identifier
159 access_visible_list(q, argv, cl)
164 EXEC SQL BEGIN DECLARE SECTION;
165 int list_id, acl_id, flags ;
167 EXEC SQL END DECLARE SECTION;
169 int client_id, status;
171 list_id = *(int *)argv[0];
172 EXEC SQL SELECT hidden, acl_id, acl_type
173 INTO :flags, :acl_id, :acl_type
175 WHERE list_id = :list_id;
176 if (sqlca.sqlerrd[2] != 1)
181 /* parse client structure */
182 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
185 /* check for client in access control list */
186 status = find_member(acl_type, acl_id, client_type, client_id, 0);
194 /* access_vis_list_by_name - allow access to list only if it is not hidden,
195 * or if the client is on the ACL
197 * Inputs: argv[0] - list name
198 * cl - client identifier
201 access_vis_list_by_name(q, argv, cl)
206 EXEC SQL BEGIN DECLARE SECTION;
207 int acl_id, flags, rowcount;
208 char acl_type[9], *listname;
209 EXEC SQL END DECLARE SECTION;
211 int client_id, status;
214 EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type
215 FROM list WHERE name = :listname;
217 rowcount=sqlca.sqlerrd[2];
225 /* parse client structure */
226 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
229 /* check for client in access control list */
230 status = find_member(acl_type, acl_id, client_type, client_id, 0);
238 /* access_member - allow user to access member of type "USER" and name matches
239 * username, or to access member of type "LIST" and list is one that user is
240 * on the acl of, or the list is visible.
243 access_member(q, argv, cl)
248 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
249 return(access_visible_list(q, &argv[1], cl));
251 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
252 if (cl->users_id == *(int *)argv[1])
256 if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBERO")) {
257 if (cl->client_id == *(int *)argv[1])
265 /* access_qgli - special access routine for Qualified_get_lists. Allows
266 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
269 access_qgli(q, argv, cl)
274 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
280 /* access_service - allow access if user is on ACL of service. Don't
281 * allow access if a wildcard is used.
284 access_service(q, argv, cl)
289 EXEC SQL BEGIN DECLARE SECTION;
291 char *name, acl_type[9];
292 EXEC SQL END DECLARE SECTION;
293 int client_id, status;
294 char *client_type, *c;
297 for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* uppercasify */
298 EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
300 if (sqlca.sqlerrd[2] > 1)
303 /* parse client structure */
304 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
307 /* check for client in access control list */
308 status = find_member(acl_type, acl_id, client_type, client_id, 0);
309 if (!status) return(MR_PERM);
315 /* access_filesys - verify that client is owner or on owners list of filesystem
319 access_filesys(q, argv, cl)
324 EXEC SQL BEGIN DECLARE SECTION;
325 int users_id, list_id;
327 EXEC SQL END DECLARE SECTION;
328 int status, client_id;
332 EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
335 if (sqlca.sqlerrd[2] != 1)
337 if (users_id == cl->users_id)
339 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
341 status = find_member("LIST", list_id, client_type, client_id, 0);
349 /* access_host - successful if owner of host, or subnet containing host
352 int host_access_level = 0; /* 1 for network, 2 for host */
354 access_host(q, argv, cl)
359 EXEC SQL BEGIN DECLARE SECTION;
360 int mid, sid, users_id, id;
361 char mtype[9], stype[9], *name;
362 EXEC SQL END DECLARE SECTION;
363 int status, client_id;
366 if (q->type == APPEND) {
367 id = *(int *)argv[8];
368 EXEC SQL SELECT s.owner_type, s.owner_id
369 INTO :stype, :sid FROM subnet s
372 } else if (q->type == RETRIEVE) {
375 id = *(int *)argv[0];
376 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
377 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
378 WHERE m.mach_id=:id and s.snet_id=m.snet_id;
380 if (sqlca.sqlerrd[2] != 1)
383 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
385 status = find_member(stype, sid, client_type, client_id, 0);
387 host_access_level = 1;
390 status = find_member(mtype, mid, client_type, client_id, 0);
392 host_access_level = 2;
399 /* access_ahal - check for adding a host alias.
400 * successful if host has less then 2 aliases and (client is owner of
402 * If deleting an alias, any owner will do.
405 access_ahal(q, argv, cl)
410 EXEC SQL BEGIN DECLARE SECTION;
411 int cnt, id, mid, sid;
412 char mtype[256], stype[256];
413 EXEC SQL END DECLARE SECTION;
415 int status, client_id;
417 if (q->type == RETRIEVE)
420 id = *(int *)argv[1];
422 EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
423 if (ingres_errno) return(mr_errcode);
424 /* if the type is APPEND, this is ahal and we need to make sure there
425 * will be no more than 2 aliases. If it's not, it must be dhal and
428 if (q->type == APPEND && cnt >= 2)
430 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
431 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
432 WHERE m.mach_id=:id and s.snet_id=m.snet_id;
433 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
435 status = find_member(mtype, mid, client_type, client_id, 0);
438 status = find_member(stype, sid, client_type, client_id, 0);
447 /* access_snt - check for retrieving network structure
450 access_snt(q, argv, cl)
455 if(q->type == RETRIEVE)