]>
Commit | Line | Data |
---|---|---|
73cf66ba | 1 | /* |
2 | * $Source$ | |
3 | * $Author$ | |
4 | * $Header$ | |
5 | * | |
6 | * Copyright (C) 1987 by the Massachusetts Institute of Technology | |
7 | * For copying and distribution information, please see the file | |
8 | * <mit-copyright.h>. | |
9 | * | |
10 | */ | |
11 | ||
12 | #ifndef lint | |
13 | static char *rcsid_qsupport_dc = "$Header$"; | |
14 | #endif lint | |
15 | ||
16 | #include <mit-copyright.h> | |
73cf66ba | 17 | #include "mr_server.h" |
03c05291 | 18 | #include "query.h" |
73cf66ba | 19 | #include <ctype.h> |
20 | EXEC SQL INCLUDE sqlca; | |
73cf66ba | 21 | #include "qrtn.h" |
22 | ||
23 | extern char *whoami; | |
03c05291 | 24 | extern int dbms_errno, mr_errcode; |
73cf66ba | 25 | |
26 | EXEC SQL BEGIN DECLARE SECTION; | |
27 | extern char stmt_buf[]; | |
28 | EXEC SQL END DECLARE SECTION; | |
29 | ||
03c05291 | 30 | EXEC SQL WHENEVER SQLERROR DO dbmserr(); |
73cf66ba | 31 | |
32 | ||
33 | /* Specialized Access Routines */ | |
34 | ||
35 | /* access_user - verify that client name equals specified login name | |
36 | * | |
37 | * - since field validation routines are called first, a users_id is | |
38 | * now in argv[0] instead of the login name. | |
39 | */ | |
40 | ||
03c05291 | 41 | int access_user(q, argv, cl) |
42 | struct query *q; | |
43 | char *argv[]; | |
44 | client *cl; | |
73cf66ba | 45 | { |
46 | if (cl->users_id != *(int *)argv[0]) | |
47 | return(MR_PERM); | |
48 | else | |
49 | return(MR_SUCCESS); | |
50 | } | |
51 | ||
52 | ||
53 | ||
54 | /* access_login - verify that client name equals specified login name | |
55 | * | |
56 | * argv[0...n] contain search info. q-> | |
57 | */ | |
58 | ||
03c05291 | 59 | int access_login(q, argv, cl) |
60 | struct query *q; | |
61 | char *argv[]; | |
62 | client *cl; | |
73cf66ba | 63 | { |
64 | EXEC SQL BEGIN DECLARE SECTION; | |
65 | int id; | |
73cf66ba | 66 | EXEC SQL END DECLARE SECTION; |
67 | ||
03c05291 | 68 | if(q->argc != 1) return MR_ARGS; |
69 | ||
70 | if(!strcmp(q->shortname, "gual")) { | |
5906749e | 71 | EXEC SQL SELECT users_id INTO :id FROM users |
72 | WHERE login LIKE :argv[0] AND users_id != 0; | |
03c05291 | 73 | } else if (!strcmp(q->shortname, "gubl")) { |
74 | EXEC SQL SELECT users_id INTO :id FROM users u | |
75 | WHERE u.login LIKE :argv[0] AND u.users_id != 0; | |
76 | } else if (!strcmp(q->shortname, "guau")) { | |
5906749e | 77 | EXEC SQL SELECT users_id INTO :id FROM users |
78 | WHERE unix_uid = :argv[0] AND users_id != 0; | |
03c05291 | 79 | } else if(!strcmp(q->shortname, "gubu")) { |
80 | EXEC SQL SELECT users_id INTO :id FROM users u | |
81 | WHERE u.unix_uid = :argv[0] AND u.users_id != 0; | |
73cf66ba | 82 | } |
83 | ||
d83ee5a2 | 84 | if (sqlca.sqlcode == SQL_NO_MATCH) |
85 | return(MR_NO_MATCH); /* ought to be MR_USER, but this is what | |
86 | gual returns, so we have to be consistent */ | |
87 | else if (sqlca.sqlerrd[2] != 1 || id != cl->users_id) | |
73cf66ba | 88 | return(MR_PERM); |
89 | else | |
90 | return(MR_SUCCESS); | |
91 | } | |
92 | ||
93 | ||
94 | ||
95 | /* access_list - check access for most list operations | |
96 | * | |
97 | * Inputs: argv[0] - list_id | |
98 | * q - query name | |
99 | * argv[2] - member ID (only for queries "amtl" and "dmfl") | |
100 | * argv[7] - group IID (only for query "ulis") | |
101 | * cl - client name | |
102 | * | |
103 | * - check that client is a member of the access control list | |
104 | * - OR, if the query is add_member_to_list or delete_member_from_list | |
105 | * and the list is public, allow access if client = member | |
106 | */ | |
107 | ||
03c05291 | 108 | int access_list(q, argv, cl) |
109 | struct query *q; | |
110 | char *argv[]; | |
111 | client *cl; | |
73cf66ba | 112 | { |
113 | EXEC SQL BEGIN DECLARE SECTION; | |
d83ee5a2 | 114 | int list_id, acl_id, flags, gid, users_id; |
115 | char acl_type[9], *newname; | |
73cf66ba | 116 | EXEC SQL END DECLARE SECTION; |
f3c08a60 | 117 | int status; |
73cf66ba | 118 | |
119 | list_id = *(int *)argv[0]; | |
120 | EXEC SQL SELECT acl_id, acl_type, gid, publicflg | |
121 | INTO :acl_id, :acl_type, :gid, :flags | |
122 | FROM list | |
123 | WHERE list_id = :list_id; | |
124 | ||
125 | if (sqlca.sqlerrd[2] != 1) | |
126 | return(MR_INTERNAL); | |
127 | ||
73cf66ba | 128 | /* if amtl or dmfl and list is public allow client to add or delete self */ |
129 | if (((!strcmp("amtl", q->shortname) && flags) || | |
f3c08a60 | 130 | (!strcmp("dmfl", q->shortname)))) { |
131 | if (!strcmp("USER", argv[1]) && *(int *)argv[2] == cl->users_id) | |
132 | return(MR_SUCCESS); | |
133 | if (!strcmp("KERBEROS", argv[1]) && *(int *)argv[2] == -cl->client_id) | |
134 | return(MR_SUCCESS); | |
d83ee5a2 | 135 | /* if update_list, don't allow them to change the GID or rename to |
136 | a username other than their own */ | |
73cf66ba | 137 | } else if (!strcmp("ulis", q->shortname)) { |
03c05291 | 138 | if (!strcmp(argv[7], UNIQUE_GID)) { |
139 | if(gid != -1) return MR_PERM; | |
140 | } else { | |
141 | if(gid != atoi(argv[7])) return MR_PERM; | |
142 | } | |
d83ee5a2 | 143 | newname = argv[1]; |
144 | EXEC SQL SELECT users_id INTO :users_id FROM users | |
145 | WHERE login=:newname; | |
f3c08a60 | 146 | if ((sqlca.sqlcode != SQL_NO_MATCH) && (users_id != cl->users_id)) |
d83ee5a2 | 147 | return MR_PERM; |
73cf66ba | 148 | } |
149 | ||
150 | /* check for client in access control list */ | |
f3c08a60 | 151 | status = find_member(acl_type, acl_id, cl); |
73cf66ba | 152 | if (!status) return(MR_PERM); |
153 | ||
154 | return(MR_SUCCESS); | |
155 | } | |
156 | ||
157 | ||
158 | /* access_visible_list - allow access to list only if it is not hidden, | |
159 | * or if the client is on the ACL | |
160 | * | |
161 | * Inputs: argv[0] - list_id | |
162 | * cl - client identifier | |
163 | */ | |
164 | ||
03c05291 | 165 | int access_visible_list(q, argv, cl) |
166 | struct query *q; | |
167 | char *argv[]; | |
168 | client *cl; | |
73cf66ba | 169 | { |
170 | EXEC SQL BEGIN DECLARE SECTION; | |
171 | int list_id, acl_id, flags ; | |
172 | char acl_type[9]; | |
173 | EXEC SQL END DECLARE SECTION; | |
f3c08a60 | 174 | int status; |
73cf66ba | 175 | |
176 | list_id = *(int *)argv[0]; | |
177 | EXEC SQL SELECT hidden, acl_id, acl_type | |
178 | INTO :flags, :acl_id, :acl_type | |
179 | FROM list | |
180 | WHERE list_id = :list_id; | |
181 | if (sqlca.sqlerrd[2] != 1) | |
182 | return(MR_INTERNAL); | |
183 | if (!flags) | |
184 | return(MR_SUCCESS); | |
185 | ||
73cf66ba | 186 | /* check for client in access control list */ |
f3c08a60 | 187 | status = find_member(acl_type, acl_id, cl); |
73cf66ba | 188 | if (!status) |
189 | return(MR_PERM); | |
190 | ||
191 | return(MR_SUCCESS); | |
192 | } | |
193 | ||
194 | ||
195 | /* access_vis_list_by_name - allow access to list only if it is not hidden, | |
196 | * or if the client is on the ACL | |
197 | * | |
198 | * Inputs: argv[0] - list name | |
199 | * cl - client identifier | |
200 | */ | |
201 | ||
03c05291 | 202 | int access_vis_list_by_name(q, argv, cl) |
203 | struct query *q; | |
204 | char *argv[]; | |
205 | client *cl; | |
73cf66ba | 206 | { |
207 | EXEC SQL BEGIN DECLARE SECTION; | |
208 | int acl_id, flags, rowcount; | |
209 | char acl_type[9], *listname; | |
210 | EXEC SQL END DECLARE SECTION; | |
f3c08a60 | 211 | int status; |
73cf66ba | 212 | |
213 | listname = argv[0]; | |
214 | EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type | |
215 | FROM list WHERE name = :listname; | |
216 | ||
217 | rowcount=sqlca.sqlerrd[2]; | |
218 | if (rowcount > 1) | |
219 | return(MR_WILDCARD); | |
220 | if (rowcount == 0) | |
221 | return(MR_NO_MATCH); | |
222 | if (!flags) | |
223 | return(MR_SUCCESS); | |
224 | ||
73cf66ba | 225 | /* check for client in access control list */ |
f3c08a60 | 226 | status = find_member(acl_type, acl_id, cl); |
73cf66ba | 227 | if (!status) |
228 | return(MR_PERM); | |
229 | ||
230 | return(MR_SUCCESS); | |
231 | } | |
232 | ||
233 | ||
234 | /* access_member - allow user to access member of type "USER" and name matches | |
f3c08a60 | 235 | * username, or to access member of type "KERBEROS" and the principal matches |
236 | * the user, or to access member of type "LIST" and list is one that user is | |
73cf66ba | 237 | * on the acl of, or the list is visible. |
238 | */ | |
239 | ||
03c05291 | 240 | int access_member(q, argv, cl) |
241 | struct query *q; | |
242 | char *argv[]; | |
243 | client *cl; | |
73cf66ba | 244 | { |
245 | if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST")) | |
246 | return(access_visible_list(q, &argv[1], cl)); | |
247 | ||
248 | if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) { | |
249 | if (cl->users_id == *(int *)argv[1]) | |
250 | return(MR_SUCCESS); | |
251 | } | |
252 | ||
f3c08a60 | 253 | if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBEROS")) { |
254 | if (cl->client_id == -*(int *)argv[1]) | |
73cf66ba | 255 | return(MR_SUCCESS); |
256 | } | |
257 | ||
258 | return(MR_PERM); | |
259 | } | |
260 | ||
261 | ||
262 | /* access_qgli - special access routine for Qualified_get_lists. Allows | |
263 | * access iff argv[0] == "TRUE" and argv[2] == "FALSE". | |
264 | */ | |
265 | ||
03c05291 | 266 | int access_qgli(q, argv, cl) |
267 | struct query *q; | |
268 | char *argv[]; | |
269 | client *cl; | |
73cf66ba | 270 | { |
271 | if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE")) | |
272 | return(MR_SUCCESS); | |
273 | return(MR_PERM); | |
274 | } | |
275 | ||
276 | ||
277 | /* access_service - allow access if user is on ACL of service. Don't | |
278 | * allow access if a wildcard is used. | |
279 | */ | |
280 | ||
03c05291 | 281 | int access_service(q, argv, cl) |
282 | struct query *q; | |
283 | char *argv[]; | |
284 | client *cl; | |
73cf66ba | 285 | { |
286 | EXEC SQL BEGIN DECLARE SECTION; | |
287 | int acl_id; | |
288 | char *name, acl_type[9]; | |
289 | EXEC SQL END DECLARE SECTION; | |
f3c08a60 | 290 | int status; |
291 | char *c; | |
73cf66ba | 292 | |
293 | name = argv[0]; | |
294 | for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* uppercasify */ | |
295 | EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers | |
296 | WHERE name = :name; | |
297 | if (sqlca.sqlerrd[2] > 1) | |
298 | return(MR_PERM); | |
299 | ||
73cf66ba | 300 | /* check for client in access control list */ |
f3c08a60 | 301 | status = find_member(acl_type, acl_id, cl); |
73cf66ba | 302 | if (!status) return(MR_PERM); |
303 | ||
304 | return(MR_SUCCESS); | |
305 | } | |
306 | ||
307 | ||
308 | /* access_filesys - verify that client is owner or on owners list of filesystem | |
309 | * named by argv[0] | |
310 | */ | |
311 | ||
03c05291 | 312 | int access_filesys(q, argv, cl) |
313 | struct query *q; | |
314 | char *argv[]; | |
315 | client *cl; | |
73cf66ba | 316 | { |
317 | EXEC SQL BEGIN DECLARE SECTION; | |
318 | int users_id, list_id; | |
319 | char *name; | |
320 | EXEC SQL END DECLARE SECTION; | |
f3c08a60 | 321 | int status; |
73cf66ba | 322 | |
323 | name = argv[0]; | |
324 | EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys | |
325 | WHERE label = :name; | |
326 | ||
327 | if (sqlca.sqlerrd[2] != 1) | |
328 | return(MR_PERM); | |
329 | if (users_id == cl->users_id) | |
330 | return(MR_SUCCESS); | |
f3c08a60 | 331 | status = find_member("LIST", list_id, cl); |
73cf66ba | 332 | if (status) |
333 | return(MR_SUCCESS); | |
334 | else | |
335 | return(MR_PERM); | |
336 | } | |
337 | ||
1beb5e23 | 338 | |
339 | /* access_host - successful if owner of host, or subnet containing host | |
340 | */ | |
341 | ||
fc2f4a27 | 342 | int host_access_level = 0; /* 1 for network, 2 for host */ |
1beb5e23 | 343 | |
03c05291 | 344 | int access_host(q, argv, cl) |
345 | struct query *q; | |
346 | char *argv[]; | |
347 | client *cl; | |
1beb5e23 | 348 | { |
349 | EXEC SQL BEGIN DECLARE SECTION; | |
03c05291 | 350 | int mid, sid, id; |
351 | char mtype[9], stype[9]; | |
1beb5e23 | 352 | EXEC SQL END DECLARE SECTION; |
f3c08a60 | 353 | int status; |
1beb5e23 | 354 | |
355 | if (q->type == APPEND) { | |
356 | id = *(int *)argv[8]; | |
357 | EXEC SQL SELECT s.owner_type, s.owner_id | |
358 | INTO :stype, :sid FROM subnet s | |
359 | WHERE s.snet_id=:id; | |
360 | mid =0; | |
361 | } else if (q->type == RETRIEVE) { | |
6aece3c5 | 362 | if (strcmp(argv[0], "*") || strcmp(argv[1], "*") || |
363 | strcmp(argv[2], "*") || strcmp(argv[3], "*")) | |
364 | return(MR_SUCCESS); | |
365 | else | |
366 | return(MR_PERM); | |
1beb5e23 | 367 | } else { |
368 | id = *(int *)argv[0]; | |
369 | EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id | |
370 | INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s | |
371 | WHERE m.mach_id=:id and s.snet_id=m.snet_id; | |
372 | } | |
373 | if (sqlca.sqlerrd[2] != 1) | |
374 | return(MR_PERM); | |
375 | ||
f3c08a60 | 376 | status = find_member(stype, sid, cl); |
1beb5e23 | 377 | if (status) { |
378 | host_access_level = 1; | |
379 | return(MR_SUCCESS); | |
380 | } | |
f3c08a60 | 381 | status = find_member(mtype, mid, cl); |
1beb5e23 | 382 | if (status) { |
383 | host_access_level = 2; | |
384 | return(MR_SUCCESS); | |
385 | } else | |
386 | return(MR_PERM); | |
387 | } | |
388 | ||
389 | ||
390 | /* access_ahal - check for adding a host alias. | |
391 | * successful if host has less then 2 aliases and (client is owner of | |
392 | * host or subnet). | |
393 | * If deleting an alias, any owner will do. | |
394 | */ | |
395 | ||
03c05291 | 396 | int access_ahal(q, argv, cl) |
397 | struct query *q; | |
398 | char *argv[]; | |
399 | client *cl; | |
1beb5e23 | 400 | { |
401 | EXEC SQL BEGIN DECLARE SECTION; | |
402 | int cnt, id, mid, sid; | |
403 | char mtype[256], stype[256]; | |
404 | EXEC SQL END DECLARE SECTION; | |
f3c08a60 | 405 | int status; |
1beb5e23 | 406 | |
27343965 | 407 | if (q->type == RETRIEVE) |
408 | return(MR_SUCCESS); | |
409 | ||
1beb5e23 | 410 | id = *(int *)argv[1]; |
411 | ||
412 | EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id; | |
03c05291 | 413 | if (dbms_errno) return(mr_errcode); |
1beb5e23 | 414 | /* if the type is APPEND, this is ahal and we need to make sure there |
415 | * will be no more than 2 aliases. If it's not, it must be dhal and | |
416 | * any owner will do. | |
417 | */ | |
418 | if (q->type == APPEND && cnt >= 2) | |
419 | return(MR_PERM); | |
1beb5e23 | 420 | EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id |
421 | INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s | |
422 | WHERE m.mach_id=:id and s.snet_id=m.snet_id; | |
f3c08a60 | 423 | status = find_member(mtype, mid, cl); |
1beb5e23 | 424 | if (status) |
425 | return(MR_SUCCESS); | |
f3c08a60 | 426 | status = find_member(stype, sid, cl); |
1beb5e23 | 427 | if (status) |
428 | return(MR_SUCCESS); | |
429 | else | |
430 | return(MR_PERM); | |
431 | } | |
7cf83f0f | 432 | |
433 | ||
434 | ||
435 | /* access_snt - check for retrieving network structure | |
436 | */ | |
437 | ||
03c05291 | 438 | int access_snt(q, argv, cl) |
439 | struct query *q; | |
440 | char *argv[]; | |
441 | client *cl; | |
7cf83f0f | 442 | { |
443 | if(q->type == RETRIEVE) | |
444 | return(MR_SUCCESS); | |
445 | ||
446 | return(MR_PERM); | |
447 | } |