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