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