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