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