]>
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")) { | |
71 | EXEC SQL SELECT users_id INTO :id FROM users u, strings str | |
72 | WHERE u.login LIKE :argv[0] AND u.users_id != 0 | |
73 | AND u.comments = str.string_id; | |
74 | } else if (!strcmp(q->shortname, "gubl")) { | |
75 | EXEC SQL SELECT users_id INTO :id FROM users u | |
76 | WHERE u.login LIKE :argv[0] AND u.users_id != 0; | |
77 | } else if (!strcmp(q->shortname, "guau")) { | |
78 | EXEC SQL SELECT users_id INTO :id FROM users u, strings str | |
79 | WHERE u.unix_uid = :argv[0] AND u.users_id != 0 | |
80 | AND u.comments = str.string_id; | |
81 | } else if(!strcmp(q->shortname, "gubu")) { | |
82 | EXEC SQL SELECT users_id INTO :id FROM users u | |
83 | WHERE u.unix_uid = :argv[0] AND u.users_id != 0; | |
73cf66ba | 84 | } |
85 | ||
86 | if (sqlca.sqlerrd[2] != 1 || id != cl->users_id) | |
87 | return(MR_PERM); | |
88 | else | |
89 | return(MR_SUCCESS); | |
90 | } | |
91 | ||
92 | ||
93 | ||
94 | /* access_list - check access for most list operations | |
95 | * | |
96 | * Inputs: argv[0] - list_id | |
97 | * q - query name | |
98 | * argv[2] - member ID (only for queries "amtl" and "dmfl") | |
99 | * argv[7] - group IID (only for query "ulis") | |
100 | * cl - client name | |
101 | * | |
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 | |
105 | */ | |
106 | ||
03c05291 | 107 | int access_list(q, argv, cl) |
108 | struct query *q; | |
109 | char *argv[]; | |
110 | client *cl; | |
73cf66ba | 111 | { |
112 | EXEC SQL BEGIN DECLARE SECTION; | |
113 | int list_id, acl_id, flags, gid; | |
114 | char acl_type[9]; | |
115 | EXEC SQL END DECLARE SECTION; | |
116 | char *client_type; | |
117 | int client_id, status; | |
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 | ||
128 | /* parse client structure */ | |
129 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
130 | return(status); | |
131 | ||
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)) { | |
03c05291 | 139 | if (!strcmp(argv[7], UNIQUE_GID)) { |
140 | if(gid != -1) return MR_PERM; | |
141 | } else { | |
142 | if(gid != atoi(argv[7])) return MR_PERM; | |
143 | } | |
73cf66ba | 144 | } |
145 | ||
146 | /* check for client in access control list */ | |
03c05291 | 147 | status = find_member(acl_type, acl_id, client_type, client_id); |
73cf66ba | 148 | if (!status) return(MR_PERM); |
149 | ||
150 | return(MR_SUCCESS); | |
151 | } | |
152 | ||
153 | ||
154 | /* access_visible_list - allow access to list only if it is not hidden, | |
155 | * or if the client is on the ACL | |
156 | * | |
157 | * Inputs: argv[0] - list_id | |
158 | * cl - client identifier | |
159 | */ | |
160 | ||
03c05291 | 161 | int access_visible_list(q, argv, cl) |
162 | struct query *q; | |
163 | char *argv[]; | |
164 | client *cl; | |
73cf66ba | 165 | { |
166 | EXEC SQL BEGIN DECLARE SECTION; | |
167 | int list_id, acl_id, flags ; | |
168 | char acl_type[9]; | |
169 | EXEC SQL END DECLARE SECTION; | |
170 | char *client_type; | |
171 | int client_id, status; | |
172 | ||
173 | list_id = *(int *)argv[0]; | |
174 | EXEC SQL SELECT hidden, acl_id, acl_type | |
175 | INTO :flags, :acl_id, :acl_type | |
176 | FROM list | |
177 | WHERE list_id = :list_id; | |
178 | if (sqlca.sqlerrd[2] != 1) | |
179 | return(MR_INTERNAL); | |
180 | if (!flags) | |
181 | return(MR_SUCCESS); | |
182 | ||
183 | /* parse client structure */ | |
184 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
185 | return(status); | |
186 | ||
187 | /* check for client in access control list */ | |
03c05291 | 188 | status = find_member(acl_type, acl_id, client_type, client_id); |
73cf66ba | 189 | if (!status) |
190 | return(MR_PERM); | |
191 | ||
192 | return(MR_SUCCESS); | |
193 | } | |
194 | ||
195 | ||
196 | /* access_vis_list_by_name - allow access to list only if it is not hidden, | |
197 | * or if the client is on the ACL | |
198 | * | |
199 | * Inputs: argv[0] - list name | |
200 | * cl - client identifier | |
201 | */ | |
202 | ||
03c05291 | 203 | int access_vis_list_by_name(q, argv, cl) |
204 | struct query *q; | |
205 | char *argv[]; | |
206 | client *cl; | |
73cf66ba | 207 | { |
208 | EXEC SQL BEGIN DECLARE SECTION; | |
209 | int acl_id, flags, rowcount; | |
210 | char acl_type[9], *listname; | |
211 | EXEC SQL END DECLARE SECTION; | |
212 | char *client_type; | |
213 | int client_id, status; | |
214 | ||
215 | listname = argv[0]; | |
216 | EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type | |
217 | FROM list WHERE name = :listname; | |
218 | ||
219 | rowcount=sqlca.sqlerrd[2]; | |
220 | if (rowcount > 1) | |
221 | return(MR_WILDCARD); | |
222 | if (rowcount == 0) | |
223 | return(MR_NO_MATCH); | |
224 | if (!flags) | |
225 | return(MR_SUCCESS); | |
226 | ||
227 | /* parse client structure */ | |
228 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
229 | return(status); | |
230 | ||
231 | /* check for client in access control list */ | |
03c05291 | 232 | status = find_member(acl_type, acl_id, client_type, client_id); |
73cf66ba | 233 | if (!status) |
234 | return(MR_PERM); | |
235 | ||
236 | return(MR_SUCCESS); | |
237 | } | |
238 | ||
239 | ||
240 | /* access_member - allow user to access member of type "USER" and name matches | |
241 | * username, or to access member of type "LIST" and list is one that user is | |
242 | * on the acl of, or the list is visible. | |
243 | */ | |
244 | ||
03c05291 | 245 | int access_member(q, argv, cl) |
246 | struct query *q; | |
247 | char *argv[]; | |
248 | client *cl; | |
73cf66ba | 249 | { |
250 | if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST")) | |
251 | return(access_visible_list(q, &argv[1], cl)); | |
252 | ||
253 | if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) { | |
254 | if (cl->users_id == *(int *)argv[1]) | |
255 | return(MR_SUCCESS); | |
256 | } | |
257 | ||
258 | if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBERO")) { | |
259 | if (cl->client_id == *(int *)argv[1]) | |
260 | return(MR_SUCCESS); | |
261 | } | |
262 | ||
263 | return(MR_PERM); | |
264 | } | |
265 | ||
266 | ||
267 | /* access_qgli - special access routine for Qualified_get_lists. Allows | |
268 | * access iff argv[0] == "TRUE" and argv[2] == "FALSE". | |
269 | */ | |
270 | ||
03c05291 | 271 | int access_qgli(q, argv, cl) |
272 | struct query *q; | |
273 | char *argv[]; | |
274 | client *cl; | |
73cf66ba | 275 | { |
276 | if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE")) | |
277 | return(MR_SUCCESS); | |
278 | return(MR_PERM); | |
279 | } | |
280 | ||
281 | ||
282 | /* access_service - allow access if user is on ACL of service. Don't | |
283 | * allow access if a wildcard is used. | |
284 | */ | |
285 | ||
03c05291 | 286 | int access_service(q, argv, cl) |
287 | struct query *q; | |
288 | char *argv[]; | |
289 | client *cl; | |
73cf66ba | 290 | { |
291 | EXEC SQL BEGIN DECLARE SECTION; | |
292 | int acl_id; | |
293 | char *name, acl_type[9]; | |
294 | EXEC SQL END DECLARE SECTION; | |
295 | int client_id, status; | |
296 | char *client_type, *c; | |
297 | ||
298 | name = argv[0]; | |
299 | for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* uppercasify */ | |
300 | EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers | |
301 | WHERE name = :name; | |
302 | if (sqlca.sqlerrd[2] > 1) | |
303 | return(MR_PERM); | |
304 | ||
305 | /* parse client structure */ | |
306 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
307 | return(status); | |
308 | ||
309 | /* check for client in access control list */ | |
03c05291 | 310 | status = find_member(acl_type, acl_id, client_type, client_id); |
73cf66ba | 311 | if (!status) return(MR_PERM); |
312 | ||
313 | return(MR_SUCCESS); | |
314 | } | |
315 | ||
316 | ||
317 | /* access_filesys - verify that client is owner or on owners list of filesystem | |
318 | * named by argv[0] | |
319 | */ | |
320 | ||
03c05291 | 321 | int access_filesys(q, argv, cl) |
322 | struct query *q; | |
323 | char *argv[]; | |
324 | client *cl; | |
73cf66ba | 325 | { |
326 | EXEC SQL BEGIN DECLARE SECTION; | |
327 | int users_id, list_id; | |
328 | char *name; | |
329 | EXEC SQL END DECLARE SECTION; | |
330 | int status, client_id; | |
331 | char *client_type; | |
332 | ||
333 | name = argv[0]; | |
334 | EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys | |
335 | WHERE label = :name; | |
336 | ||
337 | if (sqlca.sqlerrd[2] != 1) | |
338 | return(MR_PERM); | |
339 | if (users_id == cl->users_id) | |
340 | return(MR_SUCCESS); | |
341 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
342 | return(status); | |
03c05291 | 343 | status = find_member("LIST", list_id, client_type, client_id); |
73cf66ba | 344 | if (status) |
345 | return(MR_SUCCESS); | |
346 | else | |
347 | return(MR_PERM); | |
348 | } | |
349 | ||
1beb5e23 | 350 | |
351 | /* access_host - successful if owner of host, or subnet containing host | |
352 | */ | |
353 | ||
fc2f4a27 | 354 | int host_access_level = 0; /* 1 for network, 2 for host */ |
1beb5e23 | 355 | |
03c05291 | 356 | int access_host(q, argv, cl) |
357 | struct query *q; | |
358 | char *argv[]; | |
359 | client *cl; | |
1beb5e23 | 360 | { |
361 | EXEC SQL BEGIN DECLARE SECTION; | |
03c05291 | 362 | int mid, sid, id; |
363 | char mtype[9], stype[9]; | |
1beb5e23 | 364 | EXEC SQL END DECLARE SECTION; |
365 | int status, client_id; | |
366 | char *client_type; | |
367 | ||
368 | if (q->type == APPEND) { | |
369 | id = *(int *)argv[8]; | |
370 | EXEC SQL SELECT s.owner_type, s.owner_id | |
371 | INTO :stype, :sid FROM subnet s | |
372 | WHERE s.snet_id=:id; | |
373 | mid =0; | |
374 | } else if (q->type == RETRIEVE) { | |
fc2f4a27 | 375 | return(MR_SUCCESS); |
1beb5e23 | 376 | } else { |
377 | id = *(int *)argv[0]; | |
378 | EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id | |
379 | INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s | |
380 | WHERE m.mach_id=:id and s.snet_id=m.snet_id; | |
381 | } | |
382 | if (sqlca.sqlerrd[2] != 1) | |
383 | return(MR_PERM); | |
384 | ||
385 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
386 | return(status); | |
03c05291 | 387 | status = find_member(stype, sid, client_type, client_id); |
1beb5e23 | 388 | if (status) { |
389 | host_access_level = 1; | |
390 | return(MR_SUCCESS); | |
391 | } | |
03c05291 | 392 | status = find_member(mtype, mid, client_type, client_id); |
1beb5e23 | 393 | if (status) { |
394 | host_access_level = 2; | |
395 | return(MR_SUCCESS); | |
396 | } else | |
397 | return(MR_PERM); | |
398 | } | |
399 | ||
400 | ||
401 | /* access_ahal - check for adding a host alias. | |
402 | * successful if host has less then 2 aliases and (client is owner of | |
403 | * host or subnet). | |
404 | * If deleting an alias, any owner will do. | |
405 | */ | |
406 | ||
03c05291 | 407 | int access_ahal(q, argv, cl) |
408 | struct query *q; | |
409 | char *argv[]; | |
410 | client *cl; | |
1beb5e23 | 411 | { |
412 | EXEC SQL BEGIN DECLARE SECTION; | |
413 | int cnt, id, mid, sid; | |
414 | char mtype[256], stype[256]; | |
415 | EXEC SQL END DECLARE SECTION; | |
416 | char *client_type; | |
417 | int status, client_id; | |
418 | ||
27343965 | 419 | if (q->type == RETRIEVE) |
420 | return(MR_SUCCESS); | |
421 | ||
1beb5e23 | 422 | id = *(int *)argv[1]; |
423 | ||
424 | EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id; | |
03c05291 | 425 | if (dbms_errno) return(mr_errcode); |
1beb5e23 | 426 | /* if the type is APPEND, this is ahal and we need to make sure there |
427 | * will be no more than 2 aliases. If it's not, it must be dhal and | |
428 | * any owner will do. | |
429 | */ | |
430 | if (q->type == APPEND && cnt >= 2) | |
431 | return(MR_PERM); | |
1beb5e23 | 432 | EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id |
433 | INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s | |
434 | WHERE m.mach_id=:id and s.snet_id=m.snet_id; | |
435 | if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) | |
436 | return(status); | |
03c05291 | 437 | status = find_member(mtype, mid, client_type, client_id); |
1beb5e23 | 438 | if (status) |
439 | return(MR_SUCCESS); | |
03c05291 | 440 | status = find_member(stype, sid, client_type, client_id); |
1beb5e23 | 441 | if (status) |
442 | return(MR_SUCCESS); | |
443 | else | |
444 | return(MR_PERM); | |
445 | } | |
7cf83f0f | 446 | |
447 | ||
448 | ||
449 | /* access_snt - check for retrieving network structure | |
450 | */ | |
451 | ||
03c05291 | 452 | int access_snt(q, argv, cl) |
453 | struct query *q; | |
454 | char *argv[]; | |
455 | client *cl; | |
7cf83f0f | 456 | { |
457 | if(q->type == RETRIEVE) | |
458 | return(MR_SUCCESS); | |
459 | ||
460 | return(MR_PERM); | |
461 | } |