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;
70 build_qual(q->qual, q->argc, argv, qual);
71 if (!strncmp(q->name,"get_user_account",strlen("get_user_account"))) {
72 EXEC SQL SELECT users_id INTO :id FROM users u, strings str WHERE :qual;
74 EXEC SQL SELECT users_id INTO :id FROM users u WHERE :qual;
77 if (sqlca.sqlerrd[2] != 1 || id != cl->users_id)
85 /* access_list - check access for most list operations
87 * Inputs: argv[0] - list_id
89 * argv[2] - member ID (only for queries "amtl" and "dmfl")
90 * argv[7] - group IID (only for query "ulis")
93 * - check that client is a member of the access control list
94 * - OR, if the query is add_member_to_list or delete_member_from_list
95 * and the list is public, allow access if client = member
98 access_list(q, argv, cl)
103 EXEC SQL BEGIN DECLARE SECTION;
104 int list_id, acl_id, flags, gid;
106 EXEC SQL END DECLARE SECTION;
108 int client_id, status;
110 list_id = *(int *)argv[0];
111 EXEC SQL SELECT acl_id, acl_type, gid, publicflg
112 INTO :acl_id, :acl_type, :gid, :flags
114 WHERE list_id = :list_id;
116 if (sqlca.sqlerrd[2] != 1)
119 /* parse client structure */
120 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
123 /* if amtl or dmfl and list is public allow client to add or delete self */
124 if (((!strcmp("amtl", q->shortname) && flags) ||
125 (!strcmp("dmfl", q->shortname))) &&
126 (!strcmp("USER", argv[1]))) {
127 if (*(int *)argv[2] == client_id) return(MR_SUCCESS);
128 /* if update_list, don't allow them to change the GID */
129 } else if (!strcmp("ulis", q->shortname)) {
130 if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
131 (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
135 /* check for client in access control list */
136 status = find_member(acl_type, acl_id, client_type, client_id, 0);
137 if (!status) return(MR_PERM);
143 /* access_visible_list - allow access to list only if it is not hidden,
144 * or if the client is on the ACL
146 * Inputs: argv[0] - list_id
147 * cl - client identifier
150 access_visible_list(q, argv, cl)
155 EXEC SQL BEGIN DECLARE SECTION;
156 int list_id, acl_id, flags ;
158 EXEC SQL END DECLARE SECTION;
160 int client_id, status;
162 list_id = *(int *)argv[0];
163 EXEC SQL SELECT hidden, acl_id, acl_type
164 INTO :flags, :acl_id, :acl_type
166 WHERE list_id = :list_id;
167 if (sqlca.sqlerrd[2] != 1)
172 /* parse client structure */
173 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
176 /* check for client in access control list */
177 status = find_member(acl_type, acl_id, client_type, client_id, 0);
185 /* access_vis_list_by_name - allow access to list only if it is not hidden,
186 * or if the client is on the ACL
188 * Inputs: argv[0] - list name
189 * cl - client identifier
192 access_vis_list_by_name(q, argv, cl)
197 EXEC SQL BEGIN DECLARE SECTION;
198 int acl_id, flags, rowcount;
199 char acl_type[9], *listname;
200 EXEC SQL END DECLARE SECTION;
202 int client_id, status;
205 EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type
206 FROM list WHERE name = :listname;
208 rowcount=sqlca.sqlerrd[2];
216 /* parse client structure */
217 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
220 /* check for client in access control list */
221 status = find_member(acl_type, acl_id, client_type, client_id, 0);
229 /* access_member - allow user to access member of type "USER" and name matches
230 * username, or to access member of type "LIST" and list is one that user is
231 * on the acl of, or the list is visible.
234 access_member(q, argv, cl)
239 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
240 return(access_visible_list(q, &argv[1], cl));
242 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
243 if (cl->users_id == *(int *)argv[1])
247 if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBERO")) {
248 if (cl->client_id == *(int *)argv[1])
256 /* access_qgli - special access routine for Qualified_get_lists. Allows
257 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
260 access_qgli(q, argv, cl)
265 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
271 /* access_service - allow access if user is on ACL of service. Don't
272 * allow access if a wildcard is used.
275 access_service(q, argv, cl)
280 EXEC SQL BEGIN DECLARE SECTION;
282 char *name, acl_type[9];
283 EXEC SQL END DECLARE SECTION;
284 int client_id, status;
285 char *client_type, *c;
288 for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* uppercasify */
289 EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
291 if (sqlca.sqlerrd[2] > 1)
294 /* parse client structure */
295 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
298 /* check for client in access control list */
299 status = find_member(acl_type, acl_id, client_type, client_id, 0);
300 if (!status) return(MR_PERM);
306 /* access_filesys - verify that client is owner or on owners list of filesystem
310 access_filesys(q, argv, cl)
315 EXEC SQL BEGIN DECLARE SECTION;
316 int users_id, list_id;
318 EXEC SQL END DECLARE SECTION;
319 int status, client_id;
323 EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
326 if (sqlca.sqlerrd[2] != 1)
328 if (users_id == cl->users_id)
330 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
332 status = find_member("LIST", list_id, client_type, client_id, 0);
340 /* access_host - successful if owner of host, or subnet containing host
343 int host_access_level = 0; /* 1 for network, 2 for host */
345 access_host(q, argv, cl)
350 EXEC SQL BEGIN DECLARE SECTION;
351 int mid, sid, users_id, id;
352 char mtype[9], stype[9], *name;
353 EXEC SQL END DECLARE SECTION;
354 int status, client_id;
357 if (q->type == APPEND) {
358 id = *(int *)argv[8];
359 EXEC SQL SELECT s.owner_type, s.owner_id
360 INTO :stype, :sid FROM subnet s
363 } else if (q->type == RETRIEVE) {
366 id = *(int *)argv[0];
367 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
368 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
369 WHERE m.mach_id=:id and s.snet_id=m.snet_id;
371 if (sqlca.sqlerrd[2] != 1)
374 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
376 status = find_member(stype, sid, client_type, client_id, 0);
378 host_access_level = 1;
381 status = find_member(mtype, mid, client_type, client_id, 0);
383 host_access_level = 2;
390 /* access_ahal - check for adding a host alias.
391 * successful if host has less then 2 aliases and (client is owner of
393 * If deleting an alias, any owner will do.
396 access_ahal(q, argv, cl)
401 EXEC SQL BEGIN DECLARE SECTION;
402 int cnt, id, mid, sid;
403 char mtype[256], stype[256];
404 EXEC SQL END DECLARE SECTION;
406 int status, client_id;
408 id = *(int *)argv[1];
410 EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
411 if (ingres_errno) return(mr_errcode);
412 /* if the type is APPEND, this is ahal and we need to make sure there
413 * will be no more than 2 aliases. If it's not, it must be dhal and
416 if (q->type == APPEND && cnt >= 2)
419 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
420 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
421 WHERE m.mach_id=:id and s.snet_id=m.snet_id;
422 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
424 status = find_member(mtype, mid, client_type, client_id, 0);
427 status = find_member(stype, sid, client_type, client_id, 0);