]>
Commit | Line | Data |
---|---|---|
b070f8a1 | 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 | |
5d677c81 | 13 | static char *rcsid_qsupport_dc = "$Header$"; |
b070f8a1 | 14 | #endif lint |
15 | ||
16 | #include <mit-copyright.h> | |
b070f8a1 | 17 | #include "mr_server.h" |
03c05291 | 18 | #include "query.h" |
b070f8a1 | 19 | #include <ctype.h> |
03c05291 | 20 | #include <string.h> |
5d677c81 | 21 | EXEC SQL INCLUDE sqlca; |
5d677c81 | 22 | #include "qrtn.h" |
b070f8a1 | 23 | |
03c05291 | 24 | extern char *whoami, *table_name[]; |
25 | extern int dbms_errno, mr_errcode; | |
b070f8a1 | 26 | |
0fc7ab46 | 27 | EXEC SQL BEGIN DECLARE SECTION; |
45bf7573 | 28 | extern char stmt_buf[]; |
0fc7ab46 | 29 | EXEC SQL END DECLARE SECTION; |
5d677c81 | 30 | |
03c05291 | 31 | EXEC SQL WHENEVER SQLERROR DO dbmserr(); |
32 | ||
33 | int get_ace_internal(char *atypex, int aid, int (*action)(), int actarg); | |
34 | int gmol_internal(struct query *q, char *argv[], client *cl, | |
35 | int (*action)(), int actarg, int flag); | |
36 | int qualified_get(struct query *q, char *argv[], int (*action)(), int actarg, | |
37 | char *start, char *range, char *field, char *flags[]); | |
453b99fe | 38 | |
0fc7ab46 | 39 | |
0659551f | 40 | /* Special query routines */ |
b070f8a1 | 41 | |
0659551f | 42 | /* set_pobox - this does all of the real work. |
43 | * argv = user_id, type, box | |
44 | * if type is POP, then box should be a machine, and its ID should be put in | |
45 | * pop_id. If type is SMTP, then box should be a string and its ID should | |
46 | * be put in box_id. If type is NONE, then box doesn't matter. | |
0fc7ab46 | 47 | */ |
b070f8a1 | 48 | |
03c05291 | 49 | |
0659551f | 50 | int set_pobox(q, argv, cl) |
03c05291 | 51 | struct query *q; |
52 | char **argv; | |
53 | client *cl; | |
5d677c81 | 54 | { |
0fc7ab46 | 55 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 56 | int user, id; |
57 | char *box, potype[9]; | |
0fc7ab46 | 58 | EXEC SQL END DECLARE SECTION; |
0659551f | 59 | int status; |
5d677c81 | 60 | |
0659551f | 61 | box = argv[2]; |
62 | user = *(int *)argv[0]; | |
b070f8a1 | 63 | |
03c05291 | 64 | EXEC SQL SELECT pop_id, potype INTO :id, :potype FROM users |
0659551f | 65 | WHERE users_id = :user; |
03c05291 | 66 | if (dbms_errno) return(mr_errcode); |
0659551f | 67 | if (!strcmp(strtrim(potype), "POP")) |
68 | set_pop_usage(id, -1); | |
b070f8a1 | 69 | |
0659551f | 70 | if (!strcmp(argv[1], "POP")) { |
03c05291 | 71 | status = name_to_id(box, MACHINE_TABLE, &id); |
0659551f | 72 | if (status == MR_NO_MATCH) |
73 | return(MR_MACHINE); | |
74 | else if (status) | |
75 | return(status); | |
03c05291 | 76 | EXEC SQL UPDATE users SET potype = 'POP', pop_id = :id |
0659551f | 77 | WHERE users_id = :user; |
78 | set_pop_usage(id, 1); | |
79 | } else if (!strcmp(argv[1], "SMTP")) { | |
03c05291 | 80 | if (strchr(box, '/') || strchr(box, '|')) |
0659551f | 81 | return(MR_BAD_CHAR); |
03c05291 | 82 | status = name_to_id(box, STRINGS_TABLE, &id); |
0659551f | 83 | if (status == MR_NO_MATCH) { |
84 | id=add_string(box); | |
85 | } else if (status) | |
86 | return(status); | |
03c05291 | 87 | EXEC SQL UPDATE users SET potype='SMTP', box_id = :id |
0659551f | 88 | WHERE users_id = :user; |
89 | } else /* argv[1] == "NONE" */ { | |
03c05291 | 90 | EXEC SQL UPDATE users SET potype='NONE' |
0659551f | 91 | WHERE users_id = :user; |
b070f8a1 | 92 | } |
93 | ||
0659551f | 94 | set_pobox_modtime(q, argv, cl); |
03c05291 | 95 | EXEC SQL UPDATE tblstats SET updates = updates+1, modtime=SYSDATE |
0659551f | 96 | WHERE table_name='users'; |
03c05291 | 97 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 98 | return(MR_SUCCESS); |
5d677c81 | 99 | } |
b070f8a1 | 100 | |
101 | ||
0659551f | 102 | /* get_list_info: passed a wildcard list name, returns lots of stuff about |
103 | * each list. This is tricky: first build a queue of all requested | |
104 | * data. Rest of processing consists of fixing gid, ace_name, and modby. | |
0fc7ab46 | 105 | */ |
b070f8a1 | 106 | |
03c05291 | 107 | int get_list_info(q, aargv, cl, action, actarg) |
108 | struct query *q; | |
109 | char **aargv; | |
110 | client *cl; | |
111 | int (*action)(), actarg; | |
5d677c81 | 112 | { |
e448f08d | 113 | char *argv[13]; |
0fc7ab46 | 114 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 115 | char *name, acl_type[9], listname[33], active[5], public[5], hidden[5]; |
03c05291 | 116 | char maillist[5], grouplist[5], gid_str[6], desc[256]; |
117 | char modtime[27], modwith[9]; | |
0659551f | 118 | int id, rowcount, acl_id, hid, modby_id; |
0fc7ab46 | 119 | EXEC SQL END DECLARE SECTION; |
0659551f | 120 | int returned, status; |
121 | struct save_queue *sq, *sq_create(); | |
b070f8a1 | 122 | |
0659551f | 123 | returned = rowcount = 0; |
124 | name = aargv[0]; | |
125 | convert_wildcards(name); | |
b070f8a1 | 126 | |
0659551f | 127 | sq = sq_create(); |
0659551f | 128 | EXEC SQL DECLARE csr102 CURSOR FOR SELECT list_id FROM list |
03c05291 | 129 | WHERE name LIKE :name ESCAPE '*'; |
130 | if (dbms_errno) | |
0659551f | 131 | return(mr_errcode); |
132 | EXEC SQL OPEN csr102; | |
03c05291 | 133 | if (dbms_errno) |
0659551f | 134 | return(mr_errcode); |
135 | while(1) | |
136 | { | |
137 | EXEC SQL FETCH csr102 INTO :id; | |
138 | if(sqlca.sqlcode!=0) break; | |
139 | sq_save_data(sq, id); | |
140 | rowcount++; | |
141 | } | |
142 | EXEC SQL CLOSE csr102; | |
5d677c81 | 143 | |
03c05291 | 144 | if (dbms_errno) return(mr_errcode); |
1a41acb7 | 145 | if (rowcount == 0) |
146 | return(MR_NO_MATCH); | |
b070f8a1 | 147 | |
0659551f | 148 | argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden; |
149 | argv[4] = maillist; argv[5] = grouplist; argv[6] = gid_str; | |
150 | argv[7] = acl_type; argv[9] = desc; argv[10] = modtime; argv[12] = modwith; | |
b070f8a1 | 151 | |
0659551f | 152 | while (sq_get_data(sq, &id)) { |
153 | if (id == 0) | |
154 | continue; | |
155 | argv[6] = gid_str; | |
03c05291 | 156 | EXEC SQL SELECT name, active, publicflg, |
157 | hidden, hidden, maillist, grouplist, gid, | |
158 | acl_type, acl_id, description, | |
159 | TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith | |
0659551f | 160 | INTO :listname, :active, :public, :hidden, :hid, :maillist, |
161 | :grouplist, :gid_str, :acl_type, :acl_id, :desc, | |
162 | :modtime, :modby_id, :modwith | |
163 | FROM list WHERE list_id = :id; | |
b070f8a1 | 164 | |
03c05291 | 165 | if (dbms_errno) return(mr_errcode); |
166 | strtrim(acl_type); | |
b070f8a1 | 167 | |
0659551f | 168 | if (atoi(gid_str) == -1) |
169 | argv[6] = UNIQUE_GID; | |
b070f8a1 | 170 | |
0659551f | 171 | argv[8] = malloc(0); |
172 | if (!strcmp(acl_type, "LIST")) { | |
03c05291 | 173 | status = id_to_name(acl_id, LIST_TABLE, &argv[8]); |
0659551f | 174 | } else if (!strcmp(acl_type, "USER")) { |
03c05291 | 175 | status = id_to_name(acl_id, USERS_TABLE, &argv[8]); |
0659551f | 176 | } else if (!strcmp(acl_type, "KERBEROS")) { |
03c05291 | 177 | status = id_to_name(acl_id, STRINGS_TABLE, &argv[8]); |
0659551f | 178 | } else if (!strcmp(acl_type, "NONE")) { |
179 | status = 0; | |
180 | free(argv[8]); | |
181 | argv[8] = strsave("NONE"); | |
182 | } else { | |
183 | status = 0; | |
184 | free(argv[8]); | |
185 | argv[8] = strsave("???"); | |
186 | } | |
187 | if (status && status != MR_NO_MATCH) return(status); | |
b070f8a1 | 188 | |
0659551f | 189 | argv[11] = malloc(0); |
190 | if (modby_id > 0) | |
03c05291 | 191 | status = id_to_name(modby_id, USERS_TABLE, &argv[11]); |
0659551f | 192 | else |
03c05291 | 193 | status = id_to_name(-modby_id, STRINGS_TABLE, &argv[11]); |
0659551f | 194 | if (status && status != MR_NO_MATCH) return(status); |
b070f8a1 | 195 | |
0659551f | 196 | mr_trim_args(q->vcnt, argv); |
197 | returned++; | |
198 | (*action)(q->vcnt, argv, actarg); | |
199 | free(argv[8]); | |
200 | free(argv[11]); | |
0fc7ab46 | 201 | } |
202 | ||
0659551f | 203 | sq_destroy(sq); |
03c05291 | 204 | if (dbms_errno) return(mr_errcode); |
0659551f | 205 | return (MR_SUCCESS); |
b070f8a1 | 206 | } |
207 | ||
208 | ||
0659551f | 209 | /* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is |
210 | * how many different ancestors a member is allowed to have. | |
b070f8a1 | 211 | */ |
212 | ||
0659551f | 213 | #define MAXLISTDEPTH 1024 |
b070f8a1 | 214 | |
0659551f | 215 | int add_member_to_list(q, argv, cl) |
03c05291 | 216 | struct query *q; |
217 | char **argv; | |
218 | client *cl; | |
5d677c81 | 219 | { |
0fc7ab46 | 220 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 221 | int id, lid, mid, error, who, ref, rowcnt; |
222 | char *mtype, dtype[9], *entity; | |
0fc7ab46 | 223 | EXEC SQL END DECLARE SECTION; |
0659551f | 224 | int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a; |
225 | int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d; | |
226 | int status; | |
227 | char *dtypes[MAXLISTDEPTH]; | |
228 | char *iargv[3], *buf; | |
b070f8a1 | 229 | |
0659551f | 230 | lid = *(int *)argv[0]; |
231 | mtype = argv[1]; | |
232 | mid = *(int *)argv[2]; | |
233 | /* if the member is already a direct member of the list, punt */ | |
03c05291 | 234 | EXEC SQL SELECT COUNT(list_id) INTO :rowcnt FROM imembers |
0659551f | 235 | WHERE list_id = :lid AND member_id = :mid |
236 | AND member_type = :mtype AND direct = 1; | |
237 | if (rowcnt > 0) | |
238 | return(MR_EXISTS); | |
239 | if (!strcasecmp(mtype, "STRING")) { | |
240 | buf = malloc(0); | |
03c05291 | 241 | status = id_to_name(mid, STRINGS_TABLE, &buf); |
0659551f | 242 | if (status) return(status); |
03c05291 | 243 | if (strchr(buf, '/') || strchr(buf, '|')) { |
0659551f | 244 | free(buf); |
245 | return(MR_BAD_CHAR); | |
246 | } | |
247 | free(buf); | |
248 | } | |
b070f8a1 | 249 | |
0659551f | 250 | ancestors[0] = lid; |
251 | aref[0] = 1; | |
252 | acount = 1; | |
253 | EXEC SQL DECLARE csr103 CURSOR FOR | |
254 | SELECT list_id, ref_count FROM imembers | |
255 | WHERE member_id = :lid AND member_type='LIST'; | |
03c05291 | 256 | if (dbms_errno) |
0659551f | 257 | return(mr_errcode); |
258 | EXEC SQL OPEN csr103; | |
03c05291 | 259 | if (dbms_errno) |
0659551f | 260 | return(mr_errcode); |
261 | while(1) { | |
262 | EXEC SQL FETCH csr103 INTO :id, :ref; | |
263 | if(sqlca.sqlcode != 0) break; | |
264 | aref[acount] = ref; | |
265 | ancestors[acount++] = id; | |
266 | if (acount >= MAXLISTDEPTH) break; | |
267 | } | |
268 | EXEC SQL CLOSE csr103; | |
03c05291 | 269 | if (dbms_errno) return(mr_errcode); |
0659551f | 270 | if (acount >= MAXLISTDEPTH) { |
271 | return(MR_INTERNAL); | |
272 | } | |
273 | descendants[0] = mid; | |
274 | dtypes[0] = mtype; | |
275 | dref[0] = 1; | |
276 | dcount = 1; | |
277 | error = 0; | |
278 | if (!strcmp(mtype, "LIST")) { | |
279 | EXEC SQL DECLARE csr104 CURSOR FOR | |
280 | SELECT member_id, member_type, ref_count | |
281 | FROM imembers | |
282 | WHERE list_id = :mid; | |
03c05291 | 283 | if (dbms_errno) |
0659551f | 284 | return(mr_errcode); |
285 | EXEC SQL OPEN csr104; | |
03c05291 | 286 | if (dbms_errno) |
0659551f | 287 | return(mr_errcode); |
288 | while(1) { | |
289 | EXEC SQL FETCH csr104 INTO :id, :dtype, :ref; | |
290 | if(sqlca.sqlcode != 0) break; | |
291 | switch (dtype[0]) { | |
292 | case 'L': | |
293 | dtypes[dcount] = "LIST"; | |
294 | break; | |
295 | case 'U': | |
296 | dtypes[dcount] = "USER"; | |
297 | break; | |
298 | case 'S': | |
299 | dtypes[dcount] = "STRING"; | |
300 | break; | |
301 | case 'K': | |
302 | dtypes[dcount] = "KERBEROS"; | |
303 | break; | |
304 | default: | |
305 | error++; | |
306 | break; | |
307 | } | |
308 | dref[dcount] = ref; | |
309 | descendants[dcount++] = id; | |
310 | if (dcount >= MAXLISTDEPTH) { | |
311 | error++; | |
312 | break; | |
313 | } | |
314 | } | |
315 | EXEC SQL CLOSE csr104; | |
03c05291 | 316 | if (dbms_errno) return(mr_errcode); |
0659551f | 317 | if (error) |
b070f8a1 | 318 | return(MR_INTERNAL); |
b070f8a1 | 319 | } |
0659551f | 320 | for (a = 0; a < acount; a++) { |
321 | lid = ancestors[a]; | |
322 | for (d = 0; d < dcount; d++) { | |
323 | mid = descendants[d]; | |
324 | mtype = dtypes[d]; | |
325 | if (mid == lid && !strcmp(mtype, "LIST")) { | |
326 | return(MR_LISTLOOP); | |
327 | } | |
03c05291 | 328 | EXEC SQL SELECT COUNT(ref_count) INTO :rowcnt |
0659551f | 329 | FROM imembers |
330 | WHERE list_id = :lid AND member_id = :mid | |
331 | AND member_type = :mtype; | |
332 | ref = aref[a] * dref[d]; | |
333 | if (rowcnt > 0) { | |
334 | if (a == 0 && d == 0) { | |
335 | EXEC SQL UPDATE imembers | |
336 | SET ref_count = ref_count+:ref, direct=1 | |
337 | WHERE list_id = :lid AND member_id = :mid | |
338 | AND member_type = :mtype; | |
339 | } else { | |
340 | EXEC SQL UPDATE imembers | |
341 | SET ref_count = ref_count+:ref | |
342 | WHERE list_id = :lid AND member_id = :mid | |
343 | AND member_type = :mtype; | |
344 | } | |
345 | } else { | |
346 | incremental_clear_before(); | |
347 | if (a == 0 && d == 0) { | |
03c05291 | 348 | EXEC SQL INSERT INTO imembers |
349 | (list_id, member_id, direct, member_type, ref_count) | |
350 | VALUES (:lid, :mid, 1, :mtype, 1); | |
0659551f | 351 | } else { |
03c05291 | 352 | EXEC SQL INSERT INTO imembers |
353 | (list_id, member_id, direct, member_type, ref_count) | |
354 | VALUES (:lid, :mid, 0, :mtype, 1); | |
0659551f | 355 | } |
356 | iargv[0] = (char *)lid; | |
357 | iargv[1] = mtype; | |
358 | iargv[2] = (char *)mid; | |
03c05291 | 359 | incremental_after(IMEMBERS_TABLE, 0, iargv); |
0659551f | 360 | } |
361 | } | |
b070f8a1 | 362 | } |
0659551f | 363 | lid = *(int *)argv[0]; |
364 | entity = cl->entity; | |
365 | who = cl->client_id; | |
03c05291 | 366 | EXEC SQL UPDATE list |
367 | SET modtime=SYSDATE, modby = :who, modwith = :entity | |
0659551f | 368 | WHERE list_id = :lid; |
03c05291 | 369 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 370 | return(MR_SUCCESS); |
5d677c81 | 371 | } |
b070f8a1 | 372 | |
373 | ||
0659551f | 374 | /* Delete_member_from_list: do list flattening as we go! |
b070f8a1 | 375 | */ |
376 | ||
0659551f | 377 | int delete_member_from_list(q, argv, cl) |
03c05291 | 378 | struct query *q; |
379 | char **argv; | |
380 | client *cl; | |
5d677c81 | 381 | { |
0fc7ab46 | 382 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 383 | int id, lid, mid, cnt, error, who, ref; |
384 | char *mtype, dtype[9], *entity; | |
5d677c81 | 385 | EXEC SQL END DECLARE SECTION; |
0659551f | 386 | int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a; |
387 | int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d; | |
388 | char *dtypes[MAXLISTDEPTH]; | |
389 | char *iargv[3]; | |
b070f8a1 | 390 | |
0659551f | 391 | lid = *(int *)argv[0]; |
392 | mtype = argv[1]; | |
393 | mid = *(int *)argv[2]; | |
394 | /* if the member is not a direct member of the list, punt */ | |
03c05291 | 395 | EXEC SQL SELECT COUNT(list_id) INTO :cnt FROM imembers |
0659551f | 396 | WHERE list_id = :lid AND member_id = :mid |
397 | AND member_type = :mtype AND direct = 1; | |
03c05291 | 398 | if (dbms_errno) return(mr_errcode); |
0659551f | 399 | if (cnt == 0) |
400 | return(MR_NO_MATCH); | |
401 | ancestors[0] = lid; | |
402 | aref[0] = 1; | |
403 | acount = 1; | |
404 | EXEC SQL DECLARE csr105 CURSOR FOR | |
405 | SELECT list_id, ref_count FROM imembers | |
406 | WHERE member_id = :lid AND member_type = 'LIST'; | |
03c05291 | 407 | if (dbms_errno) |
b070f8a1 | 408 | return(mr_errcode); |
0659551f | 409 | EXEC SQL OPEN csr105; |
03c05291 | 410 | if (dbms_errno) |
0659551f | 411 | return(mr_errcode); |
412 | while(1) { | |
413 | EXEC SQL FETCH csr105 INTO :id, :ref; | |
414 | if(sqlca.sqlcode!=0) break; | |
415 | aref[acount] = ref; | |
416 | ancestors[acount++] = id; | |
417 | if (acount >= MAXLISTDEPTH) break; | |
b070f8a1 | 418 | } |
0659551f | 419 | EXEC SQL CLOSE csr105; |
03c05291 | 420 | if (dbms_errno) |
45bf7573 | 421 | return(mr_errcode); |
0659551f | 422 | if (acount >= MAXLISTDEPTH) |
423 | return(MR_INTERNAL); | |
424 | descendants[0] = mid; | |
425 | dtypes[0] = mtype; | |
426 | dref[0] = 1; | |
427 | dcount = 1; | |
428 | error = 0; | |
429 | if (!strcmp(mtype, "LIST")) { | |
430 | EXEC SQL DECLARE csr106 CURSOR FOR | |
431 | SELECT member_id, member_type, ref_count FROM imembers | |
432 | WHERE list_id = :mid; | |
03c05291 | 433 | if (dbms_errno) |
0659551f | 434 | return(mr_errcode); |
435 | EXEC SQL OPEN csr106; | |
03c05291 | 436 | if (dbms_errno) |
0659551f | 437 | return(mr_errcode); |
438 | while(1) { | |
439 | EXEC SQL FETCH csr106 INTO :id, :dtype, :ref; | |
440 | if(sqlca.sqlcode!=0) break; | |
441 | switch (dtype[0]) { | |
442 | case 'L': | |
443 | dtypes[dcount] = "LIST"; | |
444 | break; | |
445 | case 'U': | |
446 | dtypes[dcount] = "USER"; | |
447 | break; | |
448 | case 'S': | |
449 | dtypes[dcount] = "STRING"; | |
450 | break; | |
451 | case 'K': | |
452 | dtypes[dcount] = "KERBEROS"; | |
453 | break; | |
454 | default: | |
455 | error++; | |
456 | break; | |
457 | } | |
458 | dref[dcount] = ref; | |
459 | descendants[dcount++] = id; | |
460 | if (dcount >= MAXLISTDEPTH) break; | |
461 | } | |
462 | EXEC SQL CLOSE csr106; | |
03c05291 | 463 | if (dbms_errno) |
0659551f | 464 | return(mr_errcode); |
465 | if (error) | |
466 | return(MR_INTERNAL); | |
3beadd83 | 467 | } |
0659551f | 468 | for (a = 0; a < acount; a++) { |
469 | lid = ancestors[a]; | |
470 | for (d = 0; d < dcount; d++) { | |
471 | mid = descendants[d]; | |
472 | mtype = dtypes[d]; | |
473 | if (mid == lid && !strcmp(mtype, "LIST")) { | |
474 | return(MR_LISTLOOP); | |
475 | } | |
03c05291 | 476 | EXEC SQL SELECT ref_count INTO :cnt FROM imembers |
0659551f | 477 | WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype; |
478 | ref = aref[a] * dref[d]; | |
479 | if (cnt <= ref) { | |
480 | iargv[0] = (char *)lid; | |
481 | iargv[1] = mtype; | |
482 | iargv[2] = (char *)mid; | |
03c05291 | 483 | incremental_before(IMEMBERS_TABLE, 0, iargv); |
0659551f | 484 | EXEC SQL DELETE FROM imembers |
485 | WHERE list_id = :lid AND member_id = :mid | |
486 | AND member_type= :mtype; | |
487 | incremental_clear_after(); | |
488 | } else if (a == 0 && d == 0) { | |
489 | EXEC SQL UPDATE imembers | |
490 | SET ref_count = ref_count - :ref, direct = 0 | |
491 | WHERE list_id = :lid AND member_id = :mid | |
492 | AND member_type = :mtype; | |
493 | } else { | |
494 | EXEC SQL UPDATE imembers | |
495 | SET ref_count = ref_count - :ref | |
496 | WHERE list_id = :lid AND member_id = :mid | |
497 | AND member_type = :mtype; | |
498 | } | |
499 | } | |
3beadd83 | 500 | } |
0659551f | 501 | lid = *(int *)argv[0]; |
502 | entity = cl->entity; | |
503 | who = cl->client_id; | |
03c05291 | 504 | EXEC SQL UPDATE list SET modtime = SYSDATE, modby = :who, modwith = :entity |
0659551f | 505 | WHERE list_id = :lid; |
03c05291 | 506 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 507 | return(MR_SUCCESS); |
5d677c81 | 508 | } |
b070f8a1 | 509 | |
510 | ||
0659551f | 511 | /* get_ace_use - given a type and a name, return a type and a name. |
512 | * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0], | |
513 | * and argv[1] will contain the ID of the entity in question. The R* | |
514 | * types mean to recursively look at every containing list, not just | |
515 | * when the object in question is a direct member. On return, the | |
516 | * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR. | |
b070f8a1 | 517 | */ |
518 | ||
0659551f | 519 | int get_ace_use(q, argv, cl, action, actarg) |
03c05291 | 520 | struct query *q; |
521 | char *argv[]; | |
522 | client *cl; | |
523 | int (*action)(), actarg; | |
5d677c81 | 524 | { |
0659551f | 525 | int found = 0; |
0fc7ab46 | 526 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 527 | char *atype; |
528 | int aid, listid, id; | |
0fc7ab46 | 529 | EXEC SQL END DECLARE SECTION; |
0659551f | 530 | struct save_queue *sq, *sq_create(); |
b070f8a1 | 531 | |
0659551f | 532 | atype = argv[0]; |
533 | aid = *(int *)argv[1]; | |
534 | if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") || | |
535 | !strcmp(atype, "KERBEROS")) { | |
536 | return(get_ace_internal(atype, aid, action, actarg)); | |
537 | } | |
b070f8a1 | 538 | |
0659551f | 539 | sq = sq_create(); |
540 | if (!strcmp(atype, "RLIST")) { | |
541 | sq_save_data(sq, aid); | |
542 | /* get all the list_id's of containing lists */ | |
543 | EXEC SQL DECLARE csr107 CURSOR FOR | |
544 | SELECT list_id FROM imembers | |
545 | WHERE member_type='LIST' AND member_id = :aid; | |
03c05291 | 546 | if (dbms_errno) |
0659551f | 547 | return(mr_errcode); |
548 | EXEC SQL OPEN csr107; | |
03c05291 | 549 | if (dbms_errno) |
0659551f | 550 | return(mr_errcode); |
551 | while(1) { | |
552 | EXEC SQL FETCH csr107 INTO :listid; | |
553 | if(sqlca.sqlcode != 0) break; | |
554 | sq_save_unique_data(sq, listid); | |
555 | } | |
556 | EXEC SQL CLOSE csr107; | |
557 | /* now process each one */ | |
558 | while (sq_get_data(sq, &id)) { | |
559 | if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS) | |
560 | found++; | |
561 | } | |
562 | } | |
b070f8a1 | 563 | |
0659551f | 564 | if (!strcmp(atype, "RUSER")) { |
565 | EXEC SQL DECLARE csr108 CURSOR FOR | |
566 | SELECT list_id FROM imembers | |
567 | WHERE member_type='USER' AND member_id = :aid; | |
03c05291 | 568 | if (dbms_errno) |
0659551f | 569 | return(mr_errcode); |
570 | EXEC SQL OPEN csr108; | |
03c05291 | 571 | if (dbms_errno) |
0659551f | 572 | return(mr_errcode); |
573 | while(1) { | |
574 | EXEC SQL FETCH csr108 INTO :listid; | |
575 | if(sqlca.sqlcode != 0) break; | |
576 | sq_save_data(sq, listid); | |
577 | } | |
578 | EXEC SQL CLOSE csr108; | |
579 | /* now process each one */ | |
580 | while (sq_get_data(sq, &id)) { | |
581 | if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS) | |
582 | found++; | |
583 | } | |
584 | if (get_ace_internal("USER", aid, action, actarg) == MR_SUCCESS) | |
585 | found++; | |
586 | } | |
45bf7573 | 587 | |
0659551f | 588 | if (!strcmp(atype, "RKERBERO")) { |
589 | EXEC SQL DECLARE csr109 CURSOR FOR | |
590 | SELECT list_id FROM imembers | |
591 | WHERE member_type='KERBEROS' AND member_id = :aid; | |
03c05291 | 592 | if (dbms_errno) |
0659551f | 593 | return(mr_errcode); |
594 | EXEC SQL OPEN csr109; | |
03c05291 | 595 | if (dbms_errno) |
0659551f | 596 | return(mr_errcode); |
597 | while(1) { | |
598 | EXEC SQL FETCH csr109 INTO :listid; | |
599 | if(sqlca.sqlcode != 0) break; | |
600 | sq_save_data(sq, listid); | |
601 | } | |
602 | EXEC SQL CLOSE csr109; | |
603 | /* now process each one */ | |
604 | while (sq_get_data(sq, &id)) { | |
605 | if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS) | |
606 | found++; | |
607 | } | |
608 | if (get_ace_internal("KERBEROS", aid, action, actarg) == MR_SUCCESS) | |
609 | found++; | |
610 | } | |
b3ce33fe | 611 | |
0659551f | 612 | sq_destroy(sq); |
03c05291 | 613 | if (dbms_errno) return(mr_errcode); |
0659551f | 614 | if (!found) return(MR_NO_MATCH); |
45bf7573 | 615 | return(MR_SUCCESS); |
5d677c81 | 616 | } |
b070f8a1 | 617 | |
618 | ||
0659551f | 619 | /* This looks up a single list or user for ace use. atype must be "USER" |
620 | * or "LIST", and aid is the ID of the corresponding object. This is used | |
621 | * by get_ace_use above. | |
b070f8a1 | 622 | */ |
623 | ||
03c05291 | 624 | int get_ace_internal(atype, aid, action, actarg) |
625 | EXEC SQL BEGIN DECLARE SECTION; | |
626 | char *atype; | |
627 | EXEC SQL END DECLARE SECTION; | |
628 | int aid, (*action)(), actarg; | |
5d677c81 | 629 | { |
0659551f | 630 | char *rargv[2]; |
631 | int found = 0; | |
0fc7ab46 | 632 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 633 | char name[33]; |
0fc7ab46 | 634 | EXEC SQL END DECLARE SECTION; |
b070f8a1 | 635 | |
0659551f | 636 | rargv[1] = name; |
637 | if (!strcmp(atype, "LIST")) { | |
638 | rargv[0] = "FILESYS"; | |
639 | EXEC SQL DECLARE csr110 CURSOR FOR | |
640 | SELECT label FROM filesys | |
641 | WHERE owners = :aid; | |
03c05291 | 642 | if (dbms_errno) |
0659551f | 643 | return(mr_errcode); |
644 | EXEC SQL OPEN csr110; | |
03c05291 | 645 | if (dbms_errno) |
0659551f | 646 | return(mr_errcode); |
647 | while(1) { | |
648 | EXEC SQL FETCH csr110 INTO :name; | |
649 | if(sqlca.sqlcode != 0) break; | |
650 | (*action)(2, rargv, actarg); | |
651 | found++; | |
b070f8a1 | 652 | } |
0659551f | 653 | EXEC SQL CLOSE csr110; |
b94e861b | 654 | |
0659551f | 655 | rargv[0] = "QUERY"; |
656 | EXEC SQL DECLARE csr111 CURSOR FOR | |
657 | SELECT capability FROM capacls | |
658 | WHERE list_id = :aid ; | |
03c05291 | 659 | if (dbms_errno) |
0659551f | 660 | return(mr_errcode); |
661 | EXEC SQL OPEN csr111; | |
03c05291 | 662 | if (dbms_errno) |
0659551f | 663 | return(mr_errcode); |
664 | while(1) { | |
665 | EXEC SQL FETCH csr111 INTO :name ; | |
666 | if(sqlca.sqlcode != 0) break; | |
667 | (*action)(2, rargv, actarg); | |
668 | found++; | |
b070f8a1 | 669 | } |
0659551f | 670 | EXEC SQL CLOSE csr111; |
671 | } else if (!strcmp(atype, "USER")) { | |
672 | rargv[0] = "FILESYS"; | |
673 | EXEC SQL DECLARE csr112 CURSOR FOR | |
674 | SELECT label FROM filesys | |
675 | WHERE owner = :aid; | |
03c05291 | 676 | if (dbms_errno) |
0659551f | 677 | return(mr_errcode); |
678 | EXEC SQL OPEN csr112; | |
03c05291 | 679 | if (dbms_errno) |
0659551f | 680 | return(mr_errcode); |
681 | while(1) { | |
682 | EXEC SQL FETCH csr112 INTO :name ; | |
683 | if(sqlca.sqlcode != 0) break; | |
684 | (*action)(2, rargv, actarg); | |
685 | found++; | |
b070f8a1 | 686 | } |
0659551f | 687 | EXEC SQL CLOSE csr112; |
b070f8a1 | 688 | } |
0fc7ab46 | 689 | |
0659551f | 690 | rargv[0] = "LIST"; |
691 | EXEC SQL DECLARE csr113 CURSOR FOR | |
692 | SELECT name FROM list | |
693 | WHERE acl_type = :atype AND acl_id = :aid; | |
03c05291 | 694 | if (dbms_errno) |
835aabee | 695 | return(mr_errcode); |
0659551f | 696 | EXEC SQL OPEN csr113; |
03c05291 | 697 | if (dbms_errno) |
835aabee | 698 | return(mr_errcode); |
5d677c81 | 699 | while(1) { |
0659551f | 700 | EXEC SQL FETCH csr113 INTO :name; |
5d677c81 | 701 | if(sqlca.sqlcode != 0) break; |
b070f8a1 | 702 | (*action)(2, rargv, actarg); |
0659551f | 703 | found++; |
5d677c81 | 704 | } |
0659551f | 705 | EXEC SQL CLOSE csr113; |
b070f8a1 | 706 | |
0659551f | 707 | rargv[0] = "SERVICE"; |
708 | EXEC SQL DECLARE csr114 CURSOR FOR | |
709 | SELECT name FROM servers | |
710 | WHERE acl_type = :atype AND acl_id = :aid; | |
03c05291 | 711 | if (dbms_errno) |
835aabee | 712 | return(mr_errcode); |
0659551f | 713 | EXEC SQL OPEN csr114; |
03c05291 | 714 | if (dbms_errno) |
835aabee | 715 | return(mr_errcode); |
0659551f | 716 | while(1) { |
717 | EXEC SQL FETCH csr114 INTO :name; | |
718 | if(sqlca.sqlcode != 0) break; | |
719 | (*action)(2, rargv, actarg); | |
720 | found++; | |
0fc7ab46 | 721 | } |
0659551f | 722 | EXEC SQL CLOSE csr114; |
b070f8a1 | 723 | |
0659551f | 724 | rargv[0] = "HOSTACCESS"; |
725 | EXEC SQL DECLARE csr115 CURSOR FOR | |
726 | SELECT name FROM machine m, hostaccess ha | |
727 | WHERE m.mach_id = ha.mach_id AND ha.acl_type = :atype | |
728 | AND ha.acl_id = :aid; | |
03c05291 | 729 | if (dbms_errno) |
0659551f | 730 | return(mr_errcode); |
731 | EXEC SQL OPEN csr115; | |
03c05291 | 732 | if (dbms_errno) |
0659551f | 733 | return(mr_errcode); |
734 | while(1) { | |
735 | EXEC SQL FETCH csr115 INTO :name; | |
736 | if(sqlca.sqlcode != 0) break; | |
737 | (*action)(2, rargv, actarg); | |
738 | found++; | |
0fc7ab46 | 739 | } |
0659551f | 740 | EXEC SQL CLOSE csr115; |
b070f8a1 | 741 | |
0659551f | 742 | rargv[0] = "ZEPHYR"; |
743 | EXEC SQL DECLARE csr116 CURSOR FOR | |
744 | SELECT class FROM zephyr z | |
745 | WHERE z.xmt_type = :atype AND z.xmt_id = :aid | |
746 | OR z.sub_type = :atype AND z.sub_id = :aid | |
747 | OR z.iws_type = :atype AND z.iws_id = :aid | |
748 | OR z.iui_type = :atype AND z.iui_id = :aid; | |
03c05291 | 749 | if (dbms_errno) |
0659551f | 750 | return(mr_errcode); |
751 | EXEC SQL OPEN csr116; | |
03c05291 | 752 | if (dbms_errno) |
0659551f | 753 | return(mr_errcode); |
754 | while(1) { | |
755 | EXEC SQL FETCH csr116 INTO :name; | |
756 | if(sqlca.sqlcode != 0) break; | |
757 | (*action)(2, rargv, actarg); | |
758 | found++; | |
759 | } | |
760 | EXEC SQL CLOSE csr116; | |
b070f8a1 | 761 | |
0659551f | 762 | if (!found) return(MR_NO_MATCH); |
b070f8a1 | 763 | return(MR_SUCCESS); |
5d677c81 | 764 | } |
b070f8a1 | 765 | |
766 | ||
0659551f | 767 | /* get_lists_of_member - given a type and a name, return the name and flags |
768 | * of all of the lists of the given member. The member_type is one of | |
769 | * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0], | |
770 | * and argv[1] will contain the ID of the entity in question. The R* | |
771 | * types mean to recursively look at every containing list, not just | |
772 | * when the object in question is a direct member. | |
773 | */ | |
b070f8a1 | 774 | |
0659551f | 775 | int get_lists_of_member(q, argv, cl, action, actarg) |
03c05291 | 776 | struct query *q; |
777 | char *argv[]; | |
778 | client *cl; | |
779 | int (*action)(), actarg; | |
0659551f | 780 | { |
781 | int found = 0, direct = 1; | |
782 | char *rargv[6]; | |
0fc7ab46 | 783 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 784 | char *atype; |
03c05291 | 785 | int aid; |
0659551f | 786 | char name[33], active[5], public[5], hidden[5], maillist[5], grouplist[5]; |
0fc7ab46 | 787 | EXEC SQL END DECLARE SECTION; |
0fc7ab46 | 788 | |
0659551f | 789 | atype = argv[0]; |
790 | aid = *(int *)argv[1]; | |
791 | if (!strcmp(atype, "RLIST")) { | |
792 | atype = "LIST"; | |
793 | direct = 0; | |
794 | } | |
795 | if (!strcmp(atype, "RUSER")) { | |
796 | atype = "USER"; | |
797 | direct = 0; | |
798 | } | |
799 | if (!strcmp(atype, "RSTRING")) { | |
800 | atype = "STRING"; | |
801 | direct = 0; | |
802 | } | |
803 | if (!strcmp(atype, "RKERBEROS")) { | |
804 | atype = "KERBEROS"; | |
805 | direct = 0; | |
806 | } | |
b070f8a1 | 807 | |
0659551f | 808 | rargv[0] = name; |
809 | rargv[1] = active; | |
810 | rargv[2] = public; | |
811 | rargv[3] = hidden; | |
812 | rargv[4] = maillist; | |
813 | rargv[5] = grouplist; | |
814 | if (direct) { | |
815 | EXEC SQL DECLARE csr117a CURSOR FOR | |
03c05291 | 816 | SELECT l.name, l.active, l.publicflg, l.hidden, |
817 | l.maillist, l.grouplist | |
0659551f | 818 | FROM list l, imembers im |
819 | WHERE l.list_id = im.list_id AND im.direct = 1 | |
820 | AND im.member_type = :atype AND im.member_id = :aid; | |
03c05291 | 821 | if (dbms_errno) |
0659551f | 822 | return(mr_errcode); |
823 | EXEC SQL OPEN csr117a; | |
03c05291 | 824 | if (dbms_errno) |
0659551f | 825 | return(mr_errcode); |
826 | while(1) { | |
827 | EXEC SQL FETCH csr117a | |
828 | INTO :name, :active, :public, :hidden, :maillist, :grouplist; | |
829 | if(sqlca.sqlcode != 0) break; | |
830 | (*action)(6, rargv, actarg); | |
831 | found++; | |
832 | } | |
833 | EXEC SQL CLOSE csr117a; | |
038fd8a4 | 834 | } else { |
0659551f | 835 | EXEC SQL DECLARE csr117b CURSOR FOR |
03c05291 | 836 | SELECT l.name, l.active, l.publicflg, l.hidden, |
837 | l.maillist, l.grouplist | |
0659551f | 838 | FROM list l, imembers im |
839 | WHERE l.list_id = im.list_id | |
840 | AND im.member_type = :atype AND im.member_id = :aid; | |
03c05291 | 841 | if (dbms_errno) |
0659551f | 842 | return(mr_errcode); |
843 | EXEC SQL OPEN csr117b; | |
03c05291 | 844 | if (dbms_errno) |
0659551f | 845 | return(mr_errcode); |
846 | while(1) { | |
847 | EXEC SQL FETCH csr117b | |
848 | INTO :name, :active, :public, :hidden, :maillist, :grouplist; | |
849 | if(sqlca.sqlcode != 0) break; | |
850 | (*action)(6, rargv, actarg); | |
851 | found++; | |
852 | } | |
853 | EXEC SQL CLOSE csr117b; | |
038fd8a4 | 854 | } |
0659551f | 855 | |
03c05291 | 856 | if (dbms_errno) return(mr_errcode); |
0659551f | 857 | if (!found) return(MR_NO_MATCH); |
3afb5524 | 858 | return(MR_SUCCESS); |
038fd8a4 | 859 | } |
860 | ||
b070f8a1 | 861 | |
0659551f | 862 | /* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of |
863 | * the five flags associated with each list. It will return the name of | |
864 | * each list that meets the quailifications. It does this by building a | |
865 | * where clause based on the arguments, then doing a retrieve. | |
866 | */ | |
867 | ||
868 | static char *lflags[5] = { "active", "publicflg", "hidden", "maillist", "grouplist" }; | |
b070f8a1 | 869 | |
0659551f | 870 | int qualified_get_lists(q, argv, cl, action, actarg) |
03c05291 | 871 | struct query *q; |
872 | char *argv[]; | |
873 | client *cl; | |
874 | int (*action)(), actarg; | |
5d677c81 | 875 | { |
0659551f | 876 | return(qualified_get(q, argv, action, actarg, "l.list_id != 0", |
877 | "l", "name", lflags)); | |
878 | } | |
0fc7ab46 | 879 | |
5d677c81 | 880 | |
0659551f | 881 | /* get_members_of_list - this gets only direct members */ |
882 | ||
03c05291 | 883 | int get_members_of_list(q, argv, cl, action, actarg) |
884 | struct query *q; | |
885 | char *argv[]; | |
886 | client *cl; | |
887 | int (*action)(), actarg; | |
0659551f | 888 | { |
889 | return(gmol_internal(q, argv, cl, action, actarg, 1)); | |
5d677c81 | 890 | } |
0659551f | 891 | |
892 | /* get_end_members_of_list - this gets direct or indirect members */ | |
893 | ||
03c05291 | 894 | int get_end_members_of_list(q, argv, cl, action, actarg) |
895 | struct query *q; | |
896 | char *argv[]; | |
897 | client *cl; | |
898 | int (*action)(), actarg; | |
b070f8a1 | 899 | { |
0659551f | 900 | return(gmol_internal(q, argv, cl, action, actarg, 0)); |
901 | } | |
902 | ||
903 | /** gmol_internal - optimized query for retrieval of list members | |
904 | ** used by both get_members_of_list and get_end_members_of_list | |
905 | ** | |
906 | ** Inputs: | |
907 | ** argv[0] - list_id | |
908 | ** | |
909 | ** Description: | |
910 | ** - retrieve USER members, then LIST members, then STRING members | |
911 | **/ | |
b070f8a1 | 912 | |
03c05291 | 913 | int gmol_internal(q, argv, cl, action, actarg, flag) |
914 | struct query *q; | |
915 | char *argv[]; | |
916 | client *cl; | |
917 | int (*action)(), actarg, flag; | |
0659551f | 918 | { |
919 | EXEC SQL BEGIN DECLARE SECTION; | |
920 | int list_id, member_id, direct; | |
921 | char member_name[129], member_type[9]; | |
922 | EXEC SQL END DECLARE SECTION; | |
923 | char *targv[2]; | |
924 | int members; | |
925 | struct save_queue *sq; | |
b070f8a1 | 926 | |
0659551f | 927 | /* true/false flag indicates whether to display only direct members. */ |
928 | if (flag) | |
929 | direct = 0; | |
930 | else | |
931 | direct = -1; | |
99e09b48 | 932 | |
0659551f | 933 | list_id = *(int *)argv[0]; |
934 | members = 0; | |
935 | sq = sq_create(); | |
99e09b48 | 936 | |
0659551f | 937 | EXEC SQL DECLARE csr118 CURSOR FOR |
938 | SELECT member_type, member_id FROM imembers | |
939 | WHERE list_id = :list_id AND direct > :direct; | |
03c05291 | 940 | if (dbms_errno) |
0659551f | 941 | return(mr_errcode); |
942 | EXEC SQL OPEN csr118; | |
03c05291 | 943 | if (dbms_errno) |
0659551f | 944 | return(mr_errcode); |
945 | while(1) { | |
946 | EXEC SQL FETCH csr118 INTO :member_type, :member_id; | |
947 | if (sqlca.sqlcode != 0) break; | |
948 | if (members++ > 49) | |
949 | break; | |
950 | sq_save_data(sq, ((int)member_type[0] << 24) | (member_id & 0xffffff)); | |
951 | } | |
952 | EXEC SQL CLOSE csr118; | |
99e09b48 | 953 | |
0659551f | 954 | if (members <= 49) { |
955 | targv[1] = malloc(0); | |
956 | while (sq_remove_data(sq, &member_id)) { | |
957 | switch (member_id >> 24) { | |
958 | case 'U': | |
959 | targv[0] = "USER"; | |
03c05291 | 960 | id_to_name(member_id & 0xffffff, USERS_TABLE, &targv[1]); |
0659551f | 961 | (*action)(2, targv, actarg); |
962 | break; | |
963 | case 'L': | |
964 | targv[0] = "LIST"; | |
03c05291 | 965 | id_to_name(member_id & 0xffffff, LIST_TABLE, &targv[1]); |
0659551f | 966 | (*action)(2, targv, actarg); |
967 | break; | |
968 | case 'S': | |
969 | targv[0] = "STRING"; | |
03c05291 | 970 | id_to_name(member_id & 0xffffff, STRINGS_TABLE, &targv[1]); |
0659551f | 971 | (*action)(2, targv, actarg); |
972 | break; | |
973 | case 'K': | |
974 | targv[0] = "KERBEROS"; | |
03c05291 | 975 | id_to_name(member_id & 0xffffff, STRINGS_TABLE, &targv[1]); |
0659551f | 976 | (*action)(2, targv, actarg); |
977 | break; | |
978 | default: | |
979 | sq_destroy(sq); | |
980 | return(MR_INTERNAL); | |
981 | } | |
b070f8a1 | 982 | } |
0659551f | 983 | free(targv[1]); |
984 | sq_destroy(sq); | |
985 | return(MR_SUCCESS); | |
986 | } | |
987 | sq_destroy(sq); | |
b070f8a1 | 988 | |
0659551f | 989 | targv[1] = member_name; |
990 | targv[0] = "USER"; | |
991 | EXEC SQL DECLARE csr119 CURSOR FOR | |
992 | SELECT u.login FROM users u, imembers im | |
993 | WHERE im.list_id = :list_id AND im.member_type = 'USER' | |
994 | AND im.member_id = u.users_id AND im.direct > :direct | |
995 | ORDER BY 1; | |
03c05291 | 996 | if (dbms_errno) |
0659551f | 997 | return(mr_errcode); |
998 | EXEC SQL OPEN csr119; | |
03c05291 | 999 | if (dbms_errno) |
0659551f | 1000 | return(mr_errcode); |
1001 | while(1) { | |
1002 | EXEC SQL FETCH csr119 INTO :member_name; | |
1003 | if(sqlca.sqlcode != 0) break; | |
1004 | (*action)(2, targv, actarg); | |
b070f8a1 | 1005 | } |
0659551f | 1006 | EXEC SQL CLOSE csr119; |
03c05291 | 1007 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 1008 | |
0659551f | 1009 | targv[0] = "LIST"; |
1010 | EXEC SQL DECLARE csr120 CURSOR FOR | |
1011 | SELECT l.name FROM list l, imembers im | |
1012 | WHERE im.list_id = :list_id AND im.member_type='LIST' | |
1013 | AND im.member_id = l.list_id AND im.direct > :direct | |
1014 | ORDER BY 1; | |
03c05291 | 1015 | if (dbms_errno) |
0659551f | 1016 | return(mr_errcode); |
1017 | EXEC SQL OPEN csr120; | |
03c05291 | 1018 | if (dbms_errno) |
0659551f | 1019 | return(mr_errcode); |
1020 | while(1) { | |
1021 | EXEC SQL FETCH csr120 INTO :member_name; | |
1022 | if(sqlca.sqlcode != 0) break; | |
1023 | (*action)(2, targv, actarg); | |
b070f8a1 | 1024 | } |
0659551f | 1025 | EXEC SQL CLOSE csr120; |
03c05291 | 1026 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 1027 | |
0659551f | 1028 | targv[0] = "STRING"; |
1029 | EXEC SQL DECLARE csr121 CURSOR FOR | |
03c05291 | 1030 | SELECT str.string FROM strings str, imembers im |
0659551f | 1031 | WHERE im.list_id = :list_id AND im.member_type='STRING' |
1032 | AND im.member_id = str.string_id AND im.direct > :direct | |
1033 | ORDER BY 1; | |
03c05291 | 1034 | if (dbms_errno) |
0659551f | 1035 | return(mr_errcode); |
1036 | EXEC SQL OPEN csr121; | |
03c05291 | 1037 | if (dbms_errno) |
0659551f | 1038 | return(mr_errcode); |
1039 | while(1) { | |
1040 | EXEC SQL FETCH csr121 INTO :member_name; | |
1041 | if(sqlca.sqlcode != 0) break; | |
1042 | (*action)(2, targv, actarg); | |
b070f8a1 | 1043 | } |
0659551f | 1044 | EXEC SQL CLOSE csr121; |
03c05291 | 1045 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 1046 | |
0659551f | 1047 | targv[0] = "KERBEROS"; |
1048 | EXEC SQL DECLARE csr122 CURSOR FOR | |
03c05291 | 1049 | SELECT str.string FROM strings str, imembers im |
0659551f | 1050 | WHERE im.list_id = :list_id AND im.member_type='KERBEROS' |
1051 | AND im.member_id = str.string_id | |
1052 | AND im.direct > :direct | |
1053 | ORDER BY 1; | |
03c05291 | 1054 | if (dbms_errno) |
0659551f | 1055 | return(mr_errcode); |
1056 | EXEC SQL OPEN csr122; | |
03c05291 | 1057 | if (dbms_errno) |
0659551f | 1058 | return(mr_errcode); |
1059 | while(1) { | |
1060 | EXEC SQL FETCH csr122 INTO :member_name; | |
1061 | if(sqlca.sqlcode != 0) break; | |
1062 | (*action)(2, targv, actarg); | |
1063 | } | |
1064 | EXEC SQL CLOSE csr122; | |
03c05291 | 1065 | if (dbms_errno) return(mr_errcode); |
b070f8a1 | 1066 | |
0659551f | 1067 | return(MR_SUCCESS); |
5d677c81 | 1068 | } |
b070f8a1 | 1069 | |
1070 | ||
0659551f | 1071 | /* count_members_of_list: this is a simple query, but it cannot be done |
1072 | * through the dispatch table. | |
1073 | */ | |
b070f8a1 | 1074 | |
0659551f | 1075 | int count_members_of_list(q, argv, cl, action, actarg) |
03c05291 | 1076 | struct query *q; |
1077 | char *argv[]; | |
1078 | client *cl; | |
1079 | int (*action)(), actarg; | |
5d677c81 | 1080 | { |
0fc7ab46 | 1081 | EXEC SQL BEGIN DECLARE SECTION; |
0659551f | 1082 | int list, ct = 0; |
0fc7ab46 | 1083 | EXEC SQL END DECLARE SECTION; |
0659551f | 1084 | char *rargv[1], countbuf[5]; |
b070f8a1 | 1085 | |
0659551f | 1086 | list = *(int *)argv[0]; |
1087 | rargv[0] = countbuf; | |
03c05291 | 1088 | EXEC SQL SELECT count (*) INTO :ct FROM imembers |
0659551f | 1089 | WHERE list_id = :list AND direct=1; |
03c05291 | 1090 | if (dbms_errno) return(mr_errcode); |
0659551f | 1091 | sprintf(countbuf, "%d", ct); |
1092 | (*action)(1, rargv, actarg); | |
1093 | return(MR_SUCCESS); | |
5d677c81 | 1094 | } |
b070f8a1 | 1095 | |
b070f8a1 | 1096 | |
0659551f | 1097 | /* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of |
1098 | * the three flags associated with each service. It will return the name of | |
1099 | * each service that meets the quailifications. It does this by building a | |
1100 | * where clause based on the arguments, then doing a retrieve. | |
1101 | */ | |
b070f8a1 | 1102 | |
0659551f | 1103 | static char *sflags[3] = { "enable", "inprogress", "harderror" }; |
b070f8a1 | 1104 | |
0659551f | 1105 | int qualified_get_server(q, argv, cl, action, actarg) |
03c05291 | 1106 | struct query *q; |
1107 | char *argv[]; | |
1108 | client *cl; | |
1109 | int (*action)(), actarg; | |
5d677c81 | 1110 | { |
03c05291 | 1111 | return(qualified_get(q, argv, action, actarg, "s.name is not null", |
0659551f | 1112 | "s", "name", sflags)); |
03c05291 | 1113 | /* of course, name will never be null, but we need something there |
1114 | to make qualified_get happy */ | |
5d677c81 | 1115 | } |
b070f8a1 | 1116 | |
1117 | ||
0659551f | 1118 | /* generic qualified get routine, used by qualified_get_lists, |
1119 | * qualified_get_server, and qualified_get_serverhost. | |
1120 | * Args: | |
1121 | * start - a simple where clause, must not be empty | |
1122 | * range - the name of the range variable | |
1123 | * field - the field to return | |
1124 | * flags - an array of strings, names of the flag variables | |
b070f8a1 | 1125 | */ |
1126 | ||
0659551f | 1127 | int qualified_get(q, argv, action, actarg, start, range, field, flags) |
03c05291 | 1128 | struct query *q; |
1129 | char *argv[], *start, *range, *field, *flags[]; | |
1130 | int (*action)(), actarg; | |
453b99fe | 1131 | { |
03c05291 | 1132 | char qual[256]; |
1133 | int i; | |
1134 | char buf[32]; | |
453b99fe | 1135 | |
0659551f | 1136 | strcpy(qual, start); |
1137 | for (i = 0; i < q->argc; i++) { | |
1138 | if (!strcmp(argv[i], "TRUE")) { | |
1139 | sprintf(buf, " AND %s.%s != 0", range, flags[i]); | |
1140 | (void) strcat(qual, buf); | |
1141 | } else if (!strcmp(argv[i], "FALSE")) { | |
1142 | sprintf(buf, " AND %s.%s = 0", range, flags[i]); | |
1143 | (void) strcat(qual, buf); | |
1144 | } | |
453b99fe | 1145 | } |
1146 | ||
03c05291 | 1147 | sprintf(stmt_buf,"SELECT %s.%s FROM %s %s WHERE %s",range,field, |
1148 | table_name[q->rtable],range,qual); | |
1149 | return do_for_all_rows(stmt_buf, 1, action, actarg); | |
453b99fe | 1150 | } |
1151 | ||
1152 | ||
0659551f | 1153 | /* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of |
1154 | * the five flags associated with each serverhost. It will return the name of | |
1155 | * each service and host that meets the quailifications. It does this by | |
1156 | * building a where clause based on the arguments, then doing a retrieve. | |
45bf7573 | 1157 | */ |
45bf7573 | 1158 | |
0659551f | 1159 | static char *shflags[6] = { "service", "enable", "override", "success", |
1160 | "inprogress", "hosterror" }; | |
45bf7573 | 1161 | |
0659551f | 1162 | int qualified_get_serverhost(q, argv, cl, action, actarg) |
03c05291 | 1163 | struct query *q; |
1164 | char *argv[]; | |
1165 | client *cl; | |
1166 | int (*action)(), actarg; | |
45bf7573 | 1167 | { |
03c05291 | 1168 | char qual[256], buf[32]; |
1169 | int i; | |
45bf7573 | 1170 | |
03c05291 | 1171 | sprintf(qual, "m.mach_id = sh.mach_id AND sh.service = UPPER('%s')", |
0659551f | 1172 | argv[0]); |
1173 | for (i = 1; i < q->argc; i++) { | |
1174 | if (!strcmp(argv[i], "TRUE")) { | |
1175 | sprintf(buf, " AND sh.%s != 0", shflags[i]); | |
1176 | strcat(qual, buf); | |
1177 | } else if (!strcmp(argv[i], "FALSE")) { | |
1178 | sprintf(buf, " AND sh.%s = 0", shflags[i]); | |
1179 | strcat(qual, buf); | |
1180 | } | |
1181 | } | |
45bf7573 | 1182 | |
03c05291 | 1183 | sprintf(stmt_buf, "SELECT sh.service, m.name FROM serverhosts sh, " |
1184 | "machine m WHERE %s", qual); | |
1185 | return do_for_all_rows(stmt_buf, 2, action, actarg); | |
45bf7573 | 1186 | } |
1187 | ||
0659551f | 1188 | |
1189 | /* register_user - change user's login name and allocate a pobox, group, | |
1190 | * filesystem, and quota for them. The user's status must start out as 0, | |
1191 | * and is left as 2. Arguments are: user's UID, new login name, and user's | |
1192 | * type for filesystem allocation (MR_FS_STUDENT, MR_FS_FACULTY, | |
1193 | * MR_FS_STAFF, MR_FS_MISC). | |
99e09b48 | 1194 | */ |
0659551f | 1195 | |
03c05291 | 1196 | int register_user(q, argv, cl) |
1197 | struct query *q; | |
1198 | char **argv; | |
1199 | client *cl; | |
99e09b48 | 1200 | { |
0fc7ab46 | 1201 | EXEC SQL BEGIN DECLARE SECTION; |
03c05291 | 1202 | char *login, *entity, directory[129], machname[33]; |
1203 | int who, rowcount, mid, uid, users_id, utype, list_id; | |
1204 | int ostatus, nstatus, gidval, fsidval; | |
0659551f | 1205 | static int m_id = 0, def_quota = 0; |
0fc7ab46 | 1206 | EXEC SQL END DECLARE SECTION; |
0659551f | 1207 | char buffer[256], *aargv[3]; |
99e09b48 | 1208 | |
0659551f | 1209 | entity = cl->entity; |
1210 | who = cl->client_id; | |
99e09b48 | 1211 | |
0659551f | 1212 | uid = atoi(argv[0]); |
1213 | login = argv[1]; | |
1214 | utype = atoi(argv[2]); | |
99e09b48 | 1215 | |
0659551f | 1216 | /* find user */ |
03c05291 | 1217 | EXEC SQL SELECT users_id, status INTO :users_id, :ostatus |
0659551f | 1218 | FROM users |
03c05291 | 1219 | WHERE unix_uid = :uid AND (status=0 OR status=5 OR status=6); |
99e09b48 | 1220 | |
0659551f | 1221 | if (sqlca.sqlerrd[2] == 0) |
1222 | return(MR_NO_MATCH); | |
1223 | if (sqlca.sqlerrd[2] > 1) | |
1224 | return(MR_NOT_UNIQUE); | |
99e09b48 | 1225 | |
0659551f | 1226 | /* check new login name */ |
03c05291 | 1227 | EXEC SQL SELECT COUNT(login) INTO :rowcount FROM users |
0659551f | 1228 | WHERE login = :login AND users_id != :users_id; |
03c05291 | 1229 | if (dbms_errno) return(mr_errcode); |
0659551f | 1230 | if (rowcount > 0) return(MR_IN_USE); |
03c05291 | 1231 | EXEC SQL SELECT COUNT(name) INTO :rowcount FROM list |
0659551f | 1232 | WHERE name = :login; |
03c05291 | 1233 | if (dbms_errno) return(mr_errcode); |
0659551f | 1234 | if (rowcount > 0) return(MR_IN_USE); |
03c05291 | 1235 | EXEC SQL SELECT COUNT(label) INTO :rowcount FROM filesys |
0659551f | 1236 | WHERE label = :login; |
03c05291 | 1237 | if (dbms_errno) return(mr_errcode); |
0659551f | 1238 | if (rowcount > 0) return(MR_IN_USE); |
1239 | com_err(whoami, 0, "login name OK"); | |
99e09b48 | 1240 | |
0659551f | 1241 | /* choose place for pobox, put in mid */ |
1242 | EXEC SQL DECLARE csr130 CURSOR FOR | |
1243 | SELECT sh.mach_id, m.name FROM serverhosts sh, machine m | |
1244 | WHERE sh.service='POP' AND sh.mach_id=m.mach_id | |
1245 | AND sh.value2 - sh.value1 = | |
1246 | (SELECT MAX(value2 - value1) FROM serverhosts | |
1247 | WHERE service = 'POP'); | |
03c05291 | 1248 | if (dbms_errno) |
0659551f | 1249 | return(mr_errcode); |
1250 | EXEC SQL OPEN csr130; | |
03c05291 | 1251 | if (dbms_errno) |
0659551f | 1252 | return(mr_errcode); |
1253 | EXEC SQL FETCH csr130 INTO :mid, :machname; | |
1254 | if (sqlca.sqlerrd[2] == 0) { | |
1255 | EXEC SQL CLOSE csr130; | |
03c05291 | 1256 | if (dbms_errno) return(mr_errcode); |
0659551f | 1257 | return(MR_NO_POBOX); |
1258 | } else { | |
1259 | EXEC SQL CLOSE csr130; | |
03c05291 | 1260 | if (dbms_errno) return(mr_errcode); |
99e09b48 | 1261 | } |
99e09b48 | 1262 | |
0659551f | 1263 | /* change login name, set pobox */ |
1264 | sprintf(buffer, "u.users_id = %d", users_id); | |
03c05291 | 1265 | incremental_before(USERS_TABLE, buffer, 0); |
0659551f | 1266 | nstatus = 2; |
1267 | if (ostatus == 5 || ostatus == 6) | |
1268 | nstatus = 1; | |
03c05291 | 1269 | EXEC SQL UPDATE users SET login = :login, status = :nstatus, |
1270 | modtime=SYSDATE, modby = :who, modwith = :entity, potype='POP', | |
1271 | pop_id = :mid, pmodtime=SYSDATE, pmodby = :who, pmodwith = :entity | |
0659551f | 1272 | WHERE users_id = :users_id; |
0fc7ab46 | 1273 | |
03c05291 | 1274 | if (dbms_errno) return(mr_errcode); |
0659551f | 1275 | if (sqlca.sqlerrd[2] != 1) |
1276 | return(MR_INTERNAL); | |
1277 | set_pop_usage(mid, 1); | |
1278 | com_err(whoami, 0, "set login name to %s and pobox to %s", login, | |
1279 | strtrim(machname)); | |
03c05291 | 1280 | incremental_after(USERS_TABLE, buffer, 0); |
99e09b48 | 1281 | |
0659551f | 1282 | /* create group list */ |
03c05291 | 1283 | if (set_next_object_id("gid", LIST_TABLE, 1)) |
0659551f | 1284 | return(MR_NO_ID); |
03c05291 | 1285 | if (set_next_object_id("list_id", LIST_TABLE, 0)) |
0659551f | 1286 | return(MR_NO_ID); |
03c05291 | 1287 | EXEC SQL SELECT value INTO :list_id FROM numvalues |
0659551f | 1288 | WHERE name='list_id'; |
03c05291 | 1289 | if (dbms_errno) return(mr_errcode); |
0659551f | 1290 | if (sqlca.sqlerrd[2] != 1) |
1291 | return(MR_INTERNAL); | |
1292 | incremental_clear_before(); | |
1293 | EXEC SQL SELECT value INTO :gidval FROM numvalues WHERE name = 'gid'; | |
03c05291 | 1294 | EXEC SQL INSERT INTO list |
1295 | (name, list_id, active, publicflg, hidden, maillist, grouplist, | |
1296 | gid, description, acl_type, acl_id, | |
1297 | modtime, modby, modwith) | |
0659551f | 1298 | VALUES (:login, :list_id, 1, 0, 0, 0, 1, |
1299 | :gidval, 'User Group', 'USER', :users_id, | |
03c05291 | 1300 | SYSDATE, :who, :entity); |
1301 | if (dbms_errno) return(mr_errcode); | |
0659551f | 1302 | if (sqlca.sqlerrd[2] != 1) |
1303 | return(MR_INTERNAL); | |
1304 | sprintf(buffer, "l.list_id = %d", list_id); | |
03c05291 | 1305 | incremental_after(LIST_TABLE, buffer, 0); |
0659551f | 1306 | aargv[0] = (char *) list_id; |
1307 | aargv[1] = "USER"; | |
1308 | aargv[2] = (char *) users_id; | |
1309 | incremental_clear_before(); | |
03c05291 | 1310 | EXEC SQL INSERT INTO imembers |
0659551f | 1311 | (list_id, member_type, member_id, ref_count, direct) |
1312 | VALUES (:list_id, 'USER', :users_id, 1, 1); | |
03c05291 | 1313 | if (dbms_errno) return(mr_errcode); |
0659551f | 1314 | if (sqlca.sqlerrd[2] != 1) |
1315 | return(MR_INTERNAL); | |
03c05291 | 1316 | incremental_after(IMEMBERS_TABLE, 0, aargv); |
3beadd83 | 1317 | |
0659551f | 1318 | if (m_id == 0) { |
1319 | /* Cell Name (I know, it shouldn't be hard coded...) */ | |
1320 | strcpy(machname, "ATHENA.MIT.EDU"); | |
1321 | EXEC SQL SELECT mach_id INTO :m_id FROM machine | |
1322 | WHERE name = :machname; | |
1323 | } | |
3beadd83 | 1324 | |
0659551f | 1325 | /* create filesystem */ |
03c05291 | 1326 | if (set_next_object_id("filsys_id", FILESYS_TABLE, 0)) |
0659551f | 1327 | return(MR_NO_ID); |
1328 | incremental_clear_before(); | |
1329 | if (islower(login[0]) && islower(login[1])) { | |
1330 | sprintf(directory, "/afs/athena.mit.edu/user/%c/%c/%s", | |
1331 | login[0], login[1], login); | |
1332 | } else { | |
1333 | sprintf(directory, "/afs/athena.mit.edu/user/other/%s", login); | |
1334 | } | |
1335 | ||
1336 | EXEC SQL SELECT value INTO :fsidval FROM numvalues | |
1337 | WHERE numvalues.name='filsys_id'; | |
03c05291 | 1338 | EXEC SQL INSERT INTO filesys |
0659551f | 1339 | (filsys_id, phys_id, label, type, mach_id, name, |
03c05291 | 1340 | mount, rwaccess, comments, owner, owners, createflg, |
0659551f | 1341 | lockertype, modtime, modby, modwith) |
1342 | VALUES | |
1343 | (:fsidval, 0, :login, 'AFS', :m_id, :directory, | |
03c05291 | 1344 | '/mit/' || :login, 'w', 'User Locker', :users_id, :list_id, 1, |
1345 | 'HOMEDIR', SYSDATE, :who, :entity); | |
3beadd83 | 1346 | |
03c05291 | 1347 | if (dbms_errno) return(mr_errcode); |
0659551f | 1348 | if (sqlca.sqlerrd[2] != 1) |
1349 | return(MR_INTERNAL); | |
1350 | sprintf(buffer,"fs.filsys_id = %d",fsidval); | |
03c05291 | 1351 | incremental_after(FILESYS_TABLE, buffer, 0); |
3beadd83 | 1352 | |
0659551f | 1353 | /* set quota */ |
1354 | if (def_quota == 0) { | |
03c05291 | 1355 | EXEC SQL SELECT value INTO :def_quota FROM numvalues |
0659551f | 1356 | WHERE name='def_quota'; |
03c05291 | 1357 | if (dbms_errno) return(mr_errcode); |
0659551f | 1358 | if (sqlca.sqlerrd[2] != 1) |
1359 | return(MR_NO_QUOTA); | |
1360 | ||
1361 | } | |
1362 | incremental_clear_before(); | |
03c05291 | 1363 | EXEC SQL INSERT INTO quota |
0659551f | 1364 | (entity_id, filsys_id, type, quota, phys_id, modtime, modby, modwith) |
1365 | VALUES | |
03c05291 | 1366 | (0, :fsidval, 'ANY', :def_quota, 0, SYSDATE, :who, :entity); |
1367 | if (dbms_errno) return(mr_errcode); | |
0659551f | 1368 | if (sqlca.sqlerrd[2] != 1) |
1369 | return(MR_INTERNAL); | |
1370 | aargv[0] = login; | |
1371 | aargv[1] = "ANY"; | |
1372 | aargv[2] = login; | |
1373 | sprintf(buffer, "q.entity_id = 0 and q.filsys_id = %d and q.type = 'ANY'", fsidval); | |
03c05291 | 1374 | incremental_after(QUOTA_TABLE, buffer, aargv); |
0659551f | 1375 | com_err(whoami, 0, "quota of %d assigned", def_quota); |
03c05291 | 1376 | if (dbms_errno) return(mr_errcode); |
3afb5524 | 1377 | |
03c05291 | 1378 | cache_entry(login, USERS_TABLE, users_id); |
3afb5524 | 1379 | |
03c05291 | 1380 | EXEC SQL UPDATE tblstats SET updates=updates+1, modtime=SYSDATE |
0659551f | 1381 | WHERE table_name='users'; |
03c05291 | 1382 | EXEC SQL UPDATE tblstats SET appends=appends+1, modtime=SYSDATE |
0659551f | 1383 | WHERE table_name='list' OR table_name='filesys' OR table_name='quota'; |
03c05291 | 1384 | if (dbms_errno) return(mr_errcode); |
0659551f | 1385 | return(MR_SUCCESS); |
3afb5524 | 1386 | } |
1387 | ||
835aabee | 1388 | |
1389 | ||
0659551f | 1390 | /** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe |
1391 | ** | |
1392 | ** Inputs: | |
1393 | ** id of machine | |
1394 | ** delta (will be +/- 1) | |
1395 | ** | |
1396 | ** Description: | |
1397 | ** - incr/decr value field in serverhosts table for pop/mach_id | |
1398 | ** | |
1399 | **/ | |
1400 | ||
1401 | int set_pop_usage(id, cnt) | |
03c05291 | 1402 | EXEC SQL BEGIN DECLARE SECTION; |
1403 | int id, cnt; | |
1404 | EXEC SQL END DECLARE SECTION; | |
0659551f | 1405 | { |
03c05291 | 1406 | |
1407 | EXEC SQL UPDATE serverhosts SET value1 = value1 + :cnt | |
0659551f | 1408 | WHERE serverhosts.service = 'POP' AND serverhosts.mach_id = :id; |
835aabee | 1409 | |
03c05291 | 1410 | if (dbms_errno) return(mr_errcode); |
0659551f | 1411 | return(MR_SUCCESS); |
835aabee | 1412 | } |
1413 |