]>
Commit | Line | Data |
---|---|---|
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 |
34 | static long WhoIsThisWithName(); | |
14e9d059 | 35 | #endif |
dba0cf81 | 36 | |
1ef1bd73 | 37 | |
38 | RCSID ("$Header$") | |
39 | ||
dba0cf81 | 40 | extern struct ubik_dbase *dbase; |
41 | extern long Initdb(); | |
14e9d059 | 42 | extern int pr_noAuth; |
1ef1bd73 | 43 | extern char *prdir; |
dba0cf81 | 44 | |
14e9d059 | 45 | static 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 | 65 | long 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 | |
136 | long 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 | 189 | long 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 | ||
252 | PR_WhereIsIt(call,aid,apos) | |
253 | struct rx_call *call; | |
254 | long aid; | |
255 | long *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 | ||
282 | PR_DumpEntry(call,apos, aentry) | |
283 | struct rx_call *call; | |
284 | long apos; | |
285 | struct 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 | ||
316 | PR_AddToGroup(call,aid,gid) | |
317 | struct rx_call *call; | |
318 | long aid; | |
319 | long 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 | 397 | long 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 | 437 | long 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 | 479 | long 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, ¢ry); | |
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 | ||
613 | PR_RemoveFromGroup(call,aid,gid) | |
614 | struct rx_call *call; | |
615 | long aid; | |
616 | long 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 | 689 | long 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 | ||
736 | done: | |
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 | ||
743 | PR_ListMax(call,uid,gid) | |
744 | struct rx_call *call; | |
745 | long *uid; | |
746 | long *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 | ||
770 | PR_SetMax(call,aid,gflag) | |
771 | struct rx_call *call; | |
772 | long aid; | |
773 | long 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 | ||
814 | PR_ListEntry(call,aid,aentry) | |
815 | struct rx_call *call; | |
816 | long aid; | |
817 | struct 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 | ||
871 | PR_ChangeEntry(call,aid,name,oid,newid) | |
872 | struct rx_call *call; | |
873 | long aid; | |
874 | char *name; | |
875 | long oid; | |
876 | long 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 | 916 | PR_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 | ||
995 | long 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 | ||
1042 | done: | |
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 | ||
1051 | PR_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 | ||
1104 | done: | |
1105 | if (!alist->prlist_val) | |
1106 | alist->prlist_val = (long *) malloc(0); /* make calling stub happy */ | |
1107 | return code; | |
1108 | } | |
1109 | ||
14e9d059 | 1110 | PR_IsAMemberOf(call,uid,gid,flag) |
1111 | struct rx_call *call; | |
1112 | long uid; | |
1113 | long gid; | |
1114 | long *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 | 1163 | static stolower(s) |
1164 | register 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 | |
1174 | static 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 | } | |
1233 | done: | |
1234 | if (code && !pr_noAuth) return -1; | |
1235 | return 0; | |
1236 | } | |
1237 | #endif |