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