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