]> andersk Git - moira.git/blame - afssync/ptprocs.c
replaced WhoIsThis (probe)
[moira.git] / afssync / ptprocs.c
CommitLineData
14e9d059 1/* Copyright (C) 1989 Transarc Corporation - All rights reserved */
dba0cf81 2
3/*
4 * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
5 * LICENSED MATERIALS - PROPERTY OF IBM
6 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
7 */
8
14e9d059 9#ifndef lint
10static char rcsid[] = "$Header$";
11#endif
12
dba0cf81 13/*
14 Sherri Nichols
15 Information Technology Center
16 November, 1988
17*/
18
14e9d059 19#include <afs/param.h>
dba0cf81 20#include <ctype.h>
21#include <stdio.h>
22#include <lock.h>
23#include <ubik.h>
24#include <rx/xdr.h>
25#include <rx/rx.h>
14e9d059 26#include <rx/rx_vab.h>
27#include <rx/rxkad.h>
28#include <afs/auth.h>
29#include <netinet/in.h>
30#include "ptserver.h"
31#include "pterror.h"
32#include <strings.h>
33
34#ifdef AFS_ATHENA_STDENV
35#include <krb.h>
36#endif
dba0cf81 37
38extern struct ubik_dbase *dbase;
39extern long Initdb();
14e9d059 40extern int pr_noAuth;
dba0cf81 41
14e9d059 42static int CreateOK (ut, cid, oid, flag, admin)
43 struct ubik_trans *ut;
44 long cid; /* id of caller */
45 long oid; /* id of owner */
46 long flag; /* indicates type of entry */
47 int admin; /* sysadmin membership */
dba0cf81 48{
14e9d059 49 if (flag & (PRGRP | PRFOREIGN)) {
50 /* Allow anonymous group creation only if owner specified and running
51 * noAuth. */
52 if (cid == ANONYMOUSID) {
53 if ((oid == 0) || !pr_noAuth) return 0;
54 }
55 }
56 else { /* creating a user */
57 if (!admin && !pr_noAuth) return 0;
58 }
59 return 1; /* OK! */
60}
61
62#if 0
63/*
64 * WhoIsThis() has been replaced for the Moira-AFS synchronization.
65 */
66long WhoIsThis (acall, at, aid)
67 struct rx_call *acall;
68 struct ubik_trans *at;
69 long *aid;
70{
71 /* aid is set to the identity of the caller, if known, ANONYMOUSID otherwise */
72 /* returns -1 and sets aid to ANONYMOUSID on any failure */
73 register struct rx_connection *tconn;
74 struct rxvab_conn *tc;
75 register long code;
76 char tcell[MAXKTCREALMLEN];
77 long exp;
78 char name[MAXKTCNAMELEN];
79 char inst[MAXKTCNAMELEN];
80 int ilen;
81 char vname[256];
82
83 *aid = ANONYMOUSID;
84 tconn = rx_ConnectionOf(acall);
85 code = rx_SecurityClassOf(tconn);
86 if (code == 0) return 0;
87 else if (code == 1) { /* vab class */
88 tc = (struct rxvab_conn *) tconn->securityData;
89 if (!tc) goto done;
90 *aid = ntohl(tc->viceID);
91 code = 0;
92 }
93 else if (code == 2) { /* kad class */
94 if (code = rxkad_GetServerInfo
95 (acall->conn, (long *) 0, &exp, name, inst, tcell, (long *) 0))
96 goto done;
97 if (exp < FT_ApproxTime()) goto done;
98 if (strlen (tcell)) {
99 extern char *pr_realmName;
100#ifdef AFS_ATHENA_STDENV
101 static char local_realm[REALM_SZ] = "";
102 if (!local_realm[0]) {
103 krb_get_lrealm (local_realm, 0);
104 }
105#endif
106 if (
107#ifdef AFS_ATHENA_STDENV
108 strcasecmp (local_realm, tcell) &&
109#endif
110 strcasecmp (pr_realmName, tcell))
111 goto done;
112
113 }
114 strncpy (vname, name, sizeof(vname));
115 if (ilen = strlen (inst)) {
116 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
117 strcat (vname, ".");
118 strcat (vname, inst);
119 }
120 lcstring(vname, vname, sizeof(vname));
121 code = NameToID(at,vname,aid);
122 }
123 done:
124 if (code && !pr_noAuth) return -1;
125 return 0;
126}
127#else /* AFS-Moira synchronization */
128#define USERSMS 14487
129
130long WhoIsThis(acall, at, aid)
131struct rx_call *acall;
132struct ubik_trans *at;
133long *aid;
134{
135 *aid = USERSMS;
136 return 0;
137}
138#endif
139
140long PR_INewEntry(call,aname,aid,oid)
141 struct rx_call *call;
142 char aname[PR_MAXNAMELEN];
143 long aid;
144 long oid;
145{
146 /* used primarily for conversion - not intended to be used as usual means
147 of entering people into the database. */
dba0cf81 148 struct ubik_trans *tt;
149 register long code;
150 long gflag = 0;
151 long cid;
14e9d059 152 int admin;
153
154#define abort_with(code) return (ubik_AbortTrans(tt),code)
155
dba0cf81 156 stolower(aname);
157 code = Initdb();
158 if (code != PRSUCCESS) return code;
159 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
160 if (code) return code;
161 code = ubik_SetLock(tt, 1,1,LOCKWRITE);
14e9d059 162 if (code) abort_with (code);
163
dba0cf81 164 code = WhoIsThis(call,tt,&cid);
14e9d059 165 if (code) abort_with (PRPERM);
166 admin = IsAMemberOf(tt,cid,SYSADMINID);
dba0cf81 167
14e9d059 168 /* first verify the id is good */
169 if (aid == 0) abort_with (PRPERM);
170 if (aid < 0) {
171 gflag |= PRGRP;
172 /* only sysadmin can reuse a group id */
173 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
174 abort_with (PRPERM);
ffd72c73 175 }
14e9d059 176 if (FindByID (tt, aid)) abort_with (PRIDEXIST);
dba0cf81 177
14e9d059 178 /* check a few other things */
179 if (!CreateOK (tt, cid, oid, gflag, admin)) abort_with (PRPERM);
180
181 code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
dba0cf81 182 if (code != PRSUCCESS) {
183 ubik_AbortTrans(tt);
184 return code;
185 }
186 /* finally, commit transaction */
187 code = ubik_EndTrans(tt);
188 if (code) return code;
189 return PRSUCCESS;
190}
191
192
14e9d059 193long PR_NewEntry (call, aname, flag, oid, aid)
194 struct rx_call *call;
195 char aname[PR_MAXNAMELEN];
196 long flag;
197 long oid;
198 long *aid;
dba0cf81 199{
200 register long code;
201 struct ubik_trans *tt;
202 long cid;
14e9d059 203 int admin;
dba0cf81 204
205 stolower(aname);
206 code = Initdb();
14e9d059 207 if (code) return code;
dba0cf81 208 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
209 if (code) return code;
210 code = ubik_SetLock(tt,1,1,LOCKWRITE);
211 if (code) {
14e9d059 212 abort:
dba0cf81 213 ubik_AbortTrans(tt);
214 return code;
215 }
216 code = WhoIsThis(call,tt,&cid);
14e9d059 217 if (code) {
218 perm:
dba0cf81 219 ubik_AbortTrans(tt);
220 return PRPERM;
221 }
14e9d059 222 admin = IsAMemberOf(tt,cid,SYSADMINID);
223
224 if (!CreateOK (tt, cid, oid, flag, admin)) goto perm;
225
226 code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
227 if (code != PRSUCCESS) goto abort;
228
dba0cf81 229 code = ubik_EndTrans(tt);
230 if (code) return code;
231 return PRSUCCESS;
232}
233
234
235
236PR_WhereIsIt(call,aid,apos)
237struct rx_call *call;
238long aid;
239long *apos;
240{
241 register long code;
242 struct ubik_trans *tt;
243 long temp;
244
245 code = Initdb();
246 if (code != PRSUCCESS) return code;
247 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
248 if (code) return code;
249 code = ubik_SetLock(tt,1,1,LOCKREAD);
250 if (code) {
251 ubik_AbortTrans(tt);
252 return code;
253 }
254 temp = FindByID(tt,aid);
255 if (!temp) {
256 ubik_AbortTrans(tt);
257 return PRNOENT;
258 }
259 *apos = temp;
260 code = ubik_EndTrans(tt);
261 if (code) return code;
262 return PRSUCCESS;
263}
264
265
266PR_DumpEntry(call,apos, aentry)
267struct rx_call *call;
268long apos;
269struct prdebugentry *aentry;
270{
271 register long code;
272 struct ubik_trans *tt;
273
274 code = Initdb();
275 if (code != PRSUCCESS) return code;
276 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
277 if (code) return code;
278 code = ubik_SetLock(tt,1,1,LOCKREAD);
279 if (code) {
14e9d059 280 abort:
dba0cf81 281 ubik_AbortTrans(tt);
282 return code;
283 }
284 code = pr_ReadEntry(tt, 0, apos, aentry);
14e9d059 285 if (code) goto abort;
286
287 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
288 code = pr_ReadCoEntry(tt, 0, apos, aentry);
289 if (code) goto abort;
dba0cf81 290 }
291 code = ubik_EndTrans(tt);
292 if (code) return code;
293 return PRSUCCESS;
294}
295
296PR_AddToGroup(call,aid,gid)
297struct rx_call *call;
298long aid;
299long gid;
300{
301 register long code;
302 struct ubik_trans *tt;
303 long tempu;
304 long tempg;
305 struct prentry tentry;
306 struct prentry uentry;
307 long cid;
308
309 code = Initdb();
310 if (code != PRSUCCESS) return code;
311 if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
312 if (aid == ANONYMOUSID) return PRPERM;
313 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
314 if (code) return code;
315 code = ubik_SetLock(tt,1,1,LOCKWRITE);
316 if (code) {
317 ubik_AbortTrans(tt);
318 return code;
319 }
320 code = WhoIsThis(call, tt, &cid);
14e9d059 321 if (code) {
dba0cf81 322 ubik_AbortTrans(tt);
323 return PRPERM;
324 }
325 tempu = FindByID(tt,aid);
326 if (!tempu) {
327 ubik_AbortTrans(tt);
328 return PRNOENT;
329 }
330 bzero(&uentry,sizeof(uentry));
331 code = pr_ReadEntry(tt,0,tempu,&uentry);
332 if (code != 0) {
333 ubik_AbortTrans(tt);
334 return code;
335 }
336 /* we don't allow groups as members of groups at present */
337 if (uentry.flags & PRGRP) {
338 ubik_AbortTrans(tt);
339 return PRNOTUSER;
340 }
341 tempg = FindByID(tt,gid);
342 if (!tempg) {
343 ubik_AbortTrans(tt);
344 return PRNOENT;
345 }
346 code = pr_ReadEntry(tt,0,tempg,&tentry);
347 if (code != 0) {
348 ubik_AbortTrans(tt);
349 return code;
350 }
351 /* make sure that this is a group */
352 if (!(tentry.flags & PRGRP)) {
353 ubik_AbortTrans(tt);
354 return PRNOTGROUP;
355 }
14e9d059 356 if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) {
dba0cf81 357 ubik_AbortTrans(tt);
358 return PRPERM;
359 }
360
14e9d059 361 code = AddToEntry (tt, &tentry, tempg, aid);
dba0cf81 362 if (code != PRSUCCESS) {
363 ubik_AbortTrans(tt);
364 return code;
365 }
366 /* now, modify the user's entry as well */
14e9d059 367 code = AddToEntry (tt, &uentry, tempu, gid);
dba0cf81 368 if (code != PRSUCCESS) {
369 ubik_AbortTrans(tt);
370 return code;
371 }
372 code = ubik_EndTrans(tt);
373 if (code) return code;
374 return PRSUCCESS;
375}
376
14e9d059 377long PR_NameToID (call, aname, aid)
378 struct rx_call *call;
379 namelist *aname;
380 idlist *aid;
dba0cf81 381{
382 register long code;
383 struct ubik_trans *tt;
384 long i;
14e9d059 385 int size;
386 int count = 0;
dba0cf81 387
388 /* must do this first for RPC stub to work */
14e9d059 389 size = aname->namelist_len;
390 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
391 aid->idlist_val = (long *)malloc(size*sizeof(long));
dba0cf81 392 aid->idlist_len = 0;
14e9d059 393 if (aname->namelist_len == 0) return 0;
394 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
dba0cf81 395
396 code = Initdb();
397 if (code != PRSUCCESS) return code;
398 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
399 if (code) return code;
400 code = ubik_SetLock(tt,1,1,LOCKREAD);
401 if (code) {
402 ubik_AbortTrans(tt);
403 return code;
404 }
405 for (i=0;i<aname->namelist_len;i++) {
406 code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
407 if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
14e9d059 408 if (count++ > 50) IOMGR_Poll(), count = 0;
dba0cf81 409 }
14e9d059 410 aid->idlist_len = aname->namelist_len;
411
dba0cf81 412 code = ubik_EndTrans(tt);
14e9d059 413 if (code) return code;
dba0cf81 414 return PRSUCCESS;
415}
416
14e9d059 417long PR_IDToName (call, aid, aname)
418 struct rx_call *call;
419 idlist *aid;
420 namelist *aname;
dba0cf81 421{
422 register long code;
423 struct ubik_trans *tt;
424 long i;
14e9d059 425 int size;
426 int count = 0;
dba0cf81 427
428 /* leave this first for rpc stub */
14e9d059 429 size = aid->idlist_len;
430 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
431 aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
dba0cf81 432 aname->namelist_len = 0;
14e9d059 433 if (aid->idlist_len == 0) return 0;
434 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
dba0cf81 435
436 code = Initdb();
437 if (code != PRSUCCESS) return code;
438 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
439 if (code) return code;
440 code = ubik_SetLock(tt,1,1,LOCKREAD);
441 if (code) {
442 ubik_AbortTrans(tt);
443 return code;
444 }
445 for (i=0;i<aid->idlist_len;i++) {
446 /* interface won't allow more than PR_MAXLIST to be sent in */
447 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
448 if (code != PRSUCCESS)
449 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
14e9d059 450 if (count++ > 50) IOMGR_Poll(), count = 0;
dba0cf81 451 }
14e9d059 452 aname->namelist_len = aid->idlist_len;
453
dba0cf81 454 code = ubik_EndTrans(tt);
455 if (code) return code;
456 return PRSUCCESS;
457}
458
14e9d059 459long PR_Delete (call, aid)
460 struct rx_call *call;
461 long aid;
dba0cf81 462{
463 register long code;
464 struct ubik_trans *tt;
465 long cid;
14e9d059 466 struct prentry tentry;
467 long loc, nptr;
468 int count;
dba0cf81 469
470 code = Initdb();
14e9d059 471 if (code) return code;
dba0cf81 472 if (code != PRSUCCESS) return code;
473 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID) return PRPERM;
474 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
475 if (code) return code;
476 code = ubik_SetLock(tt,1,1,LOCKWRITE);
477 if (code) {
14e9d059 478 abort:
dba0cf81 479 ubik_AbortTrans(tt);
480 return code;
481 }
482 code = WhoIsThis(call,tt,&cid);
14e9d059 483 if (code) {
dba0cf81 484 ubik_AbortTrans(tt);
485 return PRPERM;
486 }
14e9d059 487
488 /* Read in entry to be deleted */
489 loc = FindByID (tt, aid);
490 if (loc == 0) {code = PRNOENT; goto abort;}
491 code = pr_ReadEntry (tt, 0, loc, &tentry);
492 if (code) {code = PRDBFAIL; goto abort;}
493
494 /* Do some access checking */
495 if (tentry.owner != cid &&
496 !IsAMemberOf (tt, cid, SYSADMINID) &&
497 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
498 {code = PRPERM; goto abort;}
499
500 /* Delete each continuation block as a separate transaction so that no one
501 * transaction become to large to complete. */
502 nptr = tentry.next;
503 while (nptr != NULL) {
504 struct contentry centry;
505 int i;
506
507 code = pr_ReadCoEntry(tt, 0, nptr, &centry);
508 if (code != 0) {code = PRDBFAIL; goto abort;}
509 for (i=0;i<COSIZE;i++) {
510 if (centry.entries[i] == PRBADID) continue;
511 if (centry.entries[i] == 0) break;
512 code = RemoveFromEntry (tt, aid, centry.entries[i]);
513 if (code) goto abort;
514 tentry.count--; /* maintain count */
515 if ((i&3) == 0) IOMGR_Poll();
516 }
517 tentry.next = centry.next; /* thread out this block */
518 code = FreeBlock (tt, nptr); /* free continuation block */
519 if (code) goto abort;
520 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
521 if (code) goto abort;
522
523 /* end this trans and start a new one */
524 code = ubik_EndTrans(tt);
525 if (code) return code;
526 IOMGR_Poll(); /* just to keep the connection alive */
527 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
528 if (code) return code;
529 code = ubik_SetLock(tt,1,1,LOCKWRITE);
530 if (code) goto abort;
531
532 /* re-read entry to get consistent uptodate info */
533 loc = FindByID (tt, aid);
534 if (loc == 0) {code = PRNOENT; goto abort;}
535 code = pr_ReadEntry (tt, 0, loc, &tentry);
536 if (code) {code = PRDBFAIL; goto abort;}
537
538 nptr = tentry.next;
539 }
540
541 /* Then move the owned chain, except possibly ourself to the orphan list.
542 * Because this list can be very long and so exceed the size of a ubik
543 * transaction, we start a new transaction every 50 entries. */
544 count = 0;
545 nptr = tentry.owned;
546 while (nptr != NULL) {
547 struct prentry nentry;
548
549 code = pr_ReadEntry (tt, 0, nptr, &nentry);
550 if (code) {code = PRDBFAIL; goto abort;}
551 nptr = tentry.owned = nentry.nextOwned; /* thread out */
552
553 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
554 code = AddToOrphan (tt, nentry.id);
555 if (code) goto abort;
556 count++;
557 if ((count & 3) == 0) IOMGR_Poll();
558 }
559 if (count < 50) continue;
560 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
561 if (code) goto abort;
562
563 /* end this trans and start a new one */
564 code = ubik_EndTrans(tt);
565 if (code) return code;
566 IOMGR_Poll(); /* just to keep the connection alive */
567 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
568 if (code) return code;
569 code = ubik_SetLock(tt,1,1,LOCKWRITE);
570 if (code) goto abort;
571
572 /* re-read entry to get consistent uptodate info */
573 loc = FindByID (tt, aid);
574 if (loc == 0) {code = PRNOENT; goto abort;}
575 code = pr_ReadEntry (tt, 0, loc, &tentry);
576 if (code) {code = PRDBFAIL; goto abort;}
577
578 nptr = tentry.owned;
579 }
580
581 /* now do what's left of the deletion stuff */
582 code = DeleteEntry (tt, &tentry, loc);
dba0cf81 583 if (code != PRSUCCESS) {
584 ubik_AbortTrans(tt);
585 return code;
586 }
587 code = ubik_EndTrans(tt);
588 if (code) return code;
589 return PRSUCCESS;
590}
591
592PR_RemoveFromGroup(call,aid,gid)
593struct rx_call *call;
594long aid;
595long gid;
596{
597 register long code;
598 struct ubik_trans *tt;
599 long tempu;
600 long tempg;
601 struct prentry uentry;
602 struct prentry gentry;
603 long cid;
604
605 code = Initdb();
606 if (code != PRSUCCESS) return code;
607 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
608 if (code) return code;
609 code = ubik_SetLock(tt,1,1,LOCKWRITE);
610 if (code) {
611 ubik_AbortTrans(tt);
612 return code;
613 }
614 code = WhoIsThis(call,tt,&cid);
14e9d059 615 if (code) {
dba0cf81 616 ubik_AbortTrans(tt);
617 return PRPERM;
618 }
619 tempu = FindByID(tt,aid);
620 if (!tempu) {
621 ubik_AbortTrans(tt);
622 return PRNOENT;
623 }
624 tempg = FindByID(tt,gid);
625 if (!tempg) {
626 ubik_AbortTrans(tt);
627 return PRNOENT;
628 }
629 bzero(&uentry,sizeof(uentry));
630 bzero(&gentry,sizeof(gentry));
631 code = pr_ReadEntry(tt,0,tempu,&uentry);
632 if (code != 0) {
633 ubik_AbortTrans(tt);
634 return code;
635 }
636 code = pr_ReadEntry(tt,0,tempg,&gentry);
637 if (code != 0) {
638 ubik_AbortTrans(tt);
639 return code;
640 }
641 if (!(gentry.flags & PRGRP)) {
642 ubik_AbortTrans(tt);
643 return PRNOTGROUP;
644 }
645 if (uentry.flags & PRGRP) {
646 ubik_AbortTrans(tt);
647 return PRNOTUSER;
648 }
14e9d059 649 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) {
dba0cf81 650 ubik_AbortTrans(tt);
651 return PRPERM;
652 }
653 code = RemoveFromEntry(tt,aid,gid);
654 if (code != PRSUCCESS) {
655 ubik_AbortTrans(tt);
656 return code;
657 }
658 code = RemoveFromEntry(tt,gid,aid);
659 if (code != PRSUCCESS) {
660 ubik_AbortTrans(tt);
661 return code;
662 }
663 code = ubik_EndTrans(tt);
664 if (code) return code;
665 return PRSUCCESS;
666}
667
14e9d059 668long PR_GetCPS (call, aid, alist, over)
669 struct rx_call *call;
670 long aid;
671 prlist *alist;
672 long *over;
dba0cf81 673{
674 register long code;
675 struct ubik_trans *tt;
14e9d059 676 long temp;
677 long cid;
678 struct prentry tentry;
dba0cf81 679
680 alist->prlist_len = 0;
681 alist->prlist_val = (long *) 0;
682 code = Initdb();
683 if (code != PRSUCCESS) goto done;
684 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
685 if (code) goto done;
686 code = ubik_SetLock(tt,1,1,LOCKREAD);
687 if (code) {
14e9d059 688 abort:
dba0cf81 689 ubik_AbortTrans(tt);
690 goto done;
691 }
14e9d059 692
693
694 temp = FindByID(tt,aid);
695 if (!temp) {code = PRNOENT; goto abort;}
696 code = pr_ReadEntry (tt, 0, temp, &tentry);
697 if (code) goto abort;
698
699 if (0) { /* afs doesn't authenticate yet */
700 code = WhoIsThis (call, tt, &cid);
701 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) {
702 code = PRPERM;
703 goto abort;
704 }
705 }
706
707 code = GetList(tt, &tentry, alist, 1);
dba0cf81 708 *over = 0;
14e9d059 709 if (code == PRTOOMANY) *over = 1;
710 else if (code != PRSUCCESS) {
dba0cf81 711 ubik_AbortTrans(tt);
712 goto done;
713 }
14e9d059 714
dba0cf81 715 code = ubik_EndTrans(tt);
716
717done:
718 /* return code, making sure that prlist_val points to malloc'd memory */
719 if (!alist->prlist_val)
720 alist->prlist_val = (long *) malloc(0); /* make xdr stub happy */
721 return code;
722}
723
724PR_ListMax(call,uid,gid)
725struct rx_call *call;
726long *uid;
727long *gid;
728{
729 register long code;
730 struct ubik_trans *tt;
731
732 code = Initdb();
733 if (code != PRSUCCESS) return code;
734 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
735 if (code) return code;
736 code = ubik_SetLock(tt,1,1,LOCKREAD);
737 if (code) {
738 ubik_AbortTrans(tt);
739 return code;
740 }
741 code = GetMax(tt,uid,gid);
742 if (code != PRSUCCESS) {
743 ubik_AbortTrans(tt);
744 return code;
745 }
746 code = ubik_EndTrans(tt);
747 if (code) return code;
748 return PRSUCCESS;
749}
750
751PR_SetMax(call,aid,gflag)
752struct rx_call *call;
753long aid;
754long gflag;
755{
756 register long code;
757 struct ubik_trans *tt;
758 long cid;
759
760 code = Initdb();
761 if (code != PRSUCCESS) return code;
762 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
763 if (code) return code;
764 code = ubik_SetLock(tt,1,1,LOCKWRITE);
765 if (code) {
766 ubik_AbortTrans(tt);
767 return code;
768 }
769 code = WhoIsThis(call,tt,&cid);
14e9d059 770 if (code) {
dba0cf81 771 ubik_AbortTrans(tt);
772 return PRPERM;
773 }
14e9d059 774 if (!AccessOK (tt, cid, 0, 0, 0)) {
dba0cf81 775 ubik_AbortTrans(tt);
776 return PRPERM;
777 }
14e9d059 778 if (((gflag & PRGRP) && (aid > 0)) ||
779 (!(gflag & PRGRP) && (aid < 0))) {
780 code = PRBADARG;
781 goto abort;
782 }
783
dba0cf81 784 code = SetMax(tt,aid,gflag);
785 if (code != PRSUCCESS) {
14e9d059 786 abort:
dba0cf81 787 ubik_AbortTrans(tt);
788 return code;
789 }
790 code = ubik_EndTrans(tt);
791 if (code) return code;
792 return PRSUCCESS;
793}
794
795PR_ListEntry(call,aid,aentry)
796struct rx_call *call;
797long aid;
798struct prcheckentry *aentry;
799{
800 register long code;
801 struct ubik_trans *tt;
14e9d059 802 long cid;
dba0cf81 803 long temp;
804 struct prentry tentry;
805
806 code = Initdb();
807 if (code != PRSUCCESS) return code;
808 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
809 if (code) return code;
810 code = ubik_SetLock(tt,1,1,LOCKREAD);
811 if (code) {
812 ubik_AbortTrans(tt);
813 return code;
814 }
14e9d059 815 code = WhoIsThis(call,tt,&cid);
816 if (code) {
817 perm:
818 ubik_AbortTrans(tt);
819 return PRPERM;
820 }
dba0cf81 821 temp = FindByID(tt,aid);
822 if (!temp) {
823 ubik_AbortTrans(tt);
824 return PRNOENT;
825 }
826 code = pr_ReadEntry(tt, 0, temp, &tentry);
827 if (code != 0) {
828 ubik_AbortTrans(tt);
829 return code;
830 }
14e9d059 831 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY)) goto perm;
832
833 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
834 if (aentry->flags == 0)
835 if (tentry.flags & PRGRP)
836 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
837 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
838 aentry->flags;
dba0cf81 839 aentry->owner = tentry.owner;
840 aentry->id = tentry.id;
841 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
842 aentry->creator = tentry.creator;
843 aentry->ngroups = tentry.ngroups;
844 aentry->nusers = tentry.nusers;
14e9d059 845 aentry->count = tentry.count;
846 bzero (aentry->reserved, sizeof(aentry->reserved));
dba0cf81 847 code = ubik_EndTrans(tt);
848 if (code) return code;
849 return PRSUCCESS;
850}
851
852PR_ChangeEntry(call,aid,name,oid,newid)
853struct rx_call *call;
854long aid;
855char *name;
856long oid;
857long newid;
858{
859 register long code;
860 struct ubik_trans *tt;
861 long pos;
862 long cid;
863
864 stolower(name);
865 code = Initdb();
14e9d059 866 if (code) return code;
dba0cf81 867 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID || aid == SYSADMINID) return PRPERM;
868 if (code != PRSUCCESS) return code;
869 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
870 if (code) return code;
871 code = ubik_SetLock(tt,1,1,LOCKWRITE);
872 if (code) {
873 ubik_AbortTrans(tt);
874 return code;
875 }
876 code = WhoIsThis(call,tt,&cid);
14e9d059 877 if (code) {
dba0cf81 878 ubik_AbortTrans(tt);
879 return PRPERM;
880 }
881 pos = FindByID(tt,aid);
882 if (!pos) {
883 ubik_AbortTrans(tt);
884 return PRNOENT;
885 }
886 /* protection check in changeentry */
887 code = ChangeEntry(tt,aid,cid,name,oid,newid);
888 if (code != PRSUCCESS) {
889 ubik_AbortTrans(tt);
890 return code;
891 }
892 code = ubik_EndTrans(tt);
893 return code;
894}
895
14e9d059 896PR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
897 struct rx_call *call;
898 long id;
899 long mask; /* specify which fields to update */
900 long flags, ngroups, nusers;
901 long spare1, spare2;
dba0cf81 902{
903 register long code;
904 struct ubik_trans *tt;
14e9d059 905 long pos;
906 long cid;
907 struct prentry tentry;
908 long tflags;
909
910 if (mask == 0) return 0; /* no-op */
911 code = Initdb();
912 if (code) return code;
913 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
914 return PRPERM;
915 if (code != PRSUCCESS) return code;
916 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
917 if (code) return code;
918 code = ubik_SetLock(tt,1,1,LOCKWRITE);
919 if (code) {
920 abort:
921 ubik_AbortTrans(tt);
922 return code;
923 }
924 code = WhoIsThis(call,tt,&cid);
925 if (code) {
926 perm:
927 ubik_AbortTrans(tt);
928 return PRPERM;
929 }
930 pos = FindByID(tt,id);
931 if (!pos) {
932 ubik_AbortTrans(tt);
933 return PRNOENT;
934 }
935 code = pr_ReadEntry (tt, 0, pos, &tentry);
936 if (code) goto abort;
937 tflags = tentry.flags;
938
939 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
940 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
941 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
942 tentry.ngroups = tentry.nusers = 20;
943 }
944 } else {
945 if (!AccessOK (tt, cid, &tentry, 0, 0)) goto perm;
946 }
947
948 if (mask & 0xffff) { /* if setting flag bits */
949 long flagsMask = mask & 0xffff;
950 tflags &= ~(flagsMask << PRIVATE_SHIFT);
951 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
952 tflags |= PRACCESS;
953 }
954
955 if (mask & PR_SF_NGROUPS) { /* setting group limit */
956 if (ngroups < 0) {code = PRBADARG; goto abort;}
957 tentry.ngroups = ngroups;
958 tflags |= PRQUOTA;
959 }
960
961 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
962 if (nusers < 0) {code = PRBADARG; goto abort;}
963 tentry.nusers = nusers;
964 tflags |= PRQUOTA;
965 }
966 tentry.flags = tflags;
967
968 code = pr_WriteEntry (tt, 0, pos, &tentry);
969 if (code) goto abort;
970
971 code = ubik_EndTrans(tt);
972 return code;
973}
974
975long PR_ListElements (call, aid, alist, over)
976 struct rx_call *call;
977 long aid;
978 prlist *alist;
979 long *over;
980{
981 register long code;
982 struct ubik_trans *tt;
983 long cid;
984 long temp;
985 struct prentry tentry;
dba0cf81 986
987 alist->prlist_len = 0;
988 alist->prlist_val = (long *) 0;
989
990 code = Initdb();
991 if (code != PRSUCCESS) goto done;
992 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
993 if (code) goto done;
994 code = ubik_SetLock(tt,1,1,LOCKREAD);
995 if (code) {
14e9d059 996 abort:
dba0cf81 997 ubik_AbortTrans(tt);
998 goto done;
999 }
14e9d059 1000 code = WhoIsThis(call,tt,&cid);
1001 if (code) {
1002 perm:
1003 code = PRPERM;
1004 ubik_AbortTrans(tt);
1005 goto done;
1006 }
1007
1008 temp = FindByID(tt,aid);
1009 if (!temp) {code = PRNOENT; goto abort;}
1010 code = pr_ReadEntry (tt, 0, temp, &tentry);
1011 if (code) goto abort;
1012 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1013 goto perm;
1014
1015 code = GetList (tt, &tentry, alist, 0);
1016 *over = 0;
1017 if (code == PRTOOMANY) *over = 1;
1018 else if (code != PRSUCCESS) goto abort;
1019
1020 code = ubik_EndTrans(tt);
1021
1022done:
1023 if (!alist->prlist_val)
1024 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1025 return code;
1026}
1027
1028/* List the entries owned by this id. If the id is zero return the orphans
1029 * list. */
1030
1031PR_ListOwned (call, aid, alist, over)
1032 struct rx_call *call;
1033 long aid;
1034 prlist *alist;
1035 long *over;
1036{
1037 register long code;
1038 struct ubik_trans *tt;
1039 long cid;
1040 struct prentry tentry;
1041 long head;
1042
1043 alist->prlist_len = 0;
1044 alist->prlist_val = (long *) 0;
1045
1046 code = Initdb();
1047 if (code != PRSUCCESS) goto done;
1048 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1049 if (code) goto done;
1050 code = ubik_SetLock(tt,1,1,LOCKREAD);
1051 if (code) {
1052 abort:
1053 ubik_AbortTrans(tt);
1054 goto done;
1055 }
1056 code = WhoIsThis(call,tt,&cid);
1057 if (code) {
1058 perm:
1059 code = PRPERM;
dba0cf81 1060 ubik_AbortTrans(tt);
1061 goto done;
1062 }
14e9d059 1063
1064 if (aid) {
1065 long loc = FindByID (tt, aid);
1066 if (loc == 0) { code = PRNOENT; goto abort; }
1067 code = pr_ReadEntry (tt, 0, loc, &tentry);
1068 if (code) goto abort;
1069;
1070 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY)) goto perm;
1071 head = tentry.owned;
1072 } else {
1073 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
1074 head = ntohl(cheader.orphan);
1075 }
1076
1077 code = GetOwnedChain (tt, head, alist);
1078 *over = 0;
1079 if (code == PRTOOMANY) *over = 1;
1080 else if (code) goto abort;
1081
dba0cf81 1082 code = ubik_EndTrans(tt);
1083
1084done:
1085 if (!alist->prlist_val)
1086 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1087 return code;
1088}
1089
14e9d059 1090PR_IsAMemberOf(call,uid,gid,flag)
1091struct rx_call *call;
1092long uid;
1093long gid;
1094long *flag;
1095{
1096 register long code;
1097 struct ubik_trans *tt;
1098
1099 code = Initdb();
1100 if (code != PRSUCCESS) return code;
1101 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1102 if (code) return code;
1103 code = ubik_SetLock(tt,1,1,LOCKREAD);
1104 if (code) {
1105 abort:
1106 ubik_AbortTrans(tt);
1107 return code;
1108 }
1109 { long cid;
1110 long uloc = FindByID (tt, uid);
1111 long gloc = FindByID (tt, gid);
1112 struct prentry uentry, gentry;
1113
1114 if (!uloc || !gloc) {
1115 code = PRNOENT;
1116 goto abort;
1117 }
1118 code = WhoIsThis(call, tt, &cid);
1119 if (code) {
1120 perm:
1121 code = PRPERM;
1122 goto abort;
1123 }
1124 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1125 if (code) goto abort;
1126 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1127 if (code) goto abort;
1128 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) {
1129 code = PRBADARG;
1130 goto abort;
1131 }
1132 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1133 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) goto perm;
1134 }
1135
1136 *flag = IsAMemberOf(tt,uid,gid);
1137 code = ubik_EndTrans(tt);
1138 return code;
1139}
1140
1141
dba0cf81 1142static stolower(s)
1143register char *s;
1144{
1145 register int tc;
1146 while (tc = *s) {
1147 if (isupper(tc)) *s = tolower(tc);
1148 s++;
1149 }
1150}
This page took 0.288611 seconds and 5 git commands to generate.