2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * (3) function addToGroup
13 * 1. Eliminate the code that tests for adding groups
14 * to groups. This is an error in normal AFS.
15 * 2. If adding a group to a group call AddToSGEntry
16 * to add the id of the group it's a member of.
20 * 1. Print a messsage if an error is returned from
21 * FindByID() and PTDEBUG is defined.
22 * 2. If removing a group from a group call
23 * RemoveFromSGEntry to remove the id of the
24 * group it's a member of.
25 * 3. Remove supergroup continuation records.
27 * (5) function RemoveFromGroup
29 * 1. Eliminate the code that tests for adding groups
30 * to groups. This is an error in normal AFS.
31 * 2. If removing a group from a group call
32 * RemoveFromSGEntry to remove the id of the
33 * group it's a member of.
35 * (6) Add new functions PR_ListSuperGroups and
38 * (7) function isAMemberOf
40 * 1. Allow groups to be members of groups.
42 * Transarc does not currently use opcodes past 520, but
43 * they *could* decide at any time to use more opcodes.
44 * If they did, then one part of our local mods,
45 * ListSupergroups, would break. I've therefore
46 * renumbered it to 530, and put logic in to enable the
47 * old opcode to work (for now).
50 #include <afsconfig.h>
51 #include <afs/param.h>
60 #include <afs/afsutil.h>
66 #include <afs/cellconfig.h>
70 #include "ptprototypes.h"
71 #include "afs/audit.h"
73 extern int restricted
;
74 extern int restrict_anonymous
;
75 extern struct ubik_dbase
*dbase
;
77 extern int prp_group_default
;
78 extern int prp_user_default
;
79 extern struct afsconf_dir
*prdir
;
81 static afs_int32
iNewEntry(struct rx_call
*call
, char aname
[], afs_int32 aid
,
82 afs_int32 oid
, afs_int32
*cid
);
83 static afs_int32
newEntry(struct rx_call
*call
, char aname
[], afs_int32 flag
,
84 afs_int32 oid
, afs_int32
*aid
, afs_int32
*cid
);
85 static afs_int32
whereIsIt(struct rx_call
*call
, afs_int32 aid
, afs_int32
*apos
,
87 static afs_int32
dumpEntry(struct rx_call
*call
, afs_int32 apos
,
88 struct prdebugentry
*aentry
, afs_int32
*cid
);
89 static afs_int32
addToGroup(struct rx_call
*call
, afs_int32 aid
, afs_int32 gid
,
91 static afs_int32
nameToID(struct rx_call
*call
, namelist
*aname
, idlist
*aid
);
92 static afs_int32
idToName(struct rx_call
*call
, idlist
*aid
, namelist
*aname
, afs_int32
*cid
);
93 static afs_int32
Delete(struct rx_call
*call
, afs_int32 aid
, afs_int32
*cid
);
94 static afs_int32
UpdateEntry(struct rx_call
*call
, afs_int32 aid
, char *name
,
95 struct PrUpdateEntry
*uentry
, afs_int32
*cid
);
96 static afs_int32
removeFromGroup(struct rx_call
*call
, afs_int32 aid
,
97 afs_int32 gid
, afs_int32
*cid
);
98 static afs_int32
getCPS(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
99 afs_int32
*over
, afs_int32
*cid
);
100 static afs_int32
getCPS2(struct rx_call
*call
, afs_int32 aid
, afs_uint32 ahost
,
101 prlist
*alist
, afs_int32
*over
, afs_int32
*cid
);
102 static afs_int32
getHostCPS(struct rx_call
*call
, afs_uint32 ahost
,
103 prlist
*alist
, afs_int32
*over
, afs_int32
*cid
);
104 static afs_int32
listMax(struct rx_call
*call
, afs_int32
*uid
, afs_int32
*gid
, afs_int32
*cid
);
105 static afs_int32
setMax(struct rx_call
*call
, afs_int32 aid
, afs_int32 gflag
,
107 static afs_int32
listEntry(struct rx_call
*call
, afs_int32 aid
,
108 struct prcheckentry
*aentry
, afs_int32
*cid
);
109 static afs_int32
listEntries(struct rx_call
*call
, afs_int32 flag
,
110 afs_int32 startindex
, prentries
*bulkentries
,
111 afs_int32
*nextstartindex
, afs_int32
*cid
);
112 static afs_int32
put_prentries(struct prentry
*tentry
, prentries
*bulkentries
);
113 static afs_int32
changeEntry(struct rx_call
*call
, afs_int32 aid
, char *name
,
114 afs_int32 oid
, afs_int32 newid
, afs_int32
*cid
);
115 static afs_int32
setFieldsEntry(struct rx_call
*call
, afs_int32 id
,
116 afs_int32 mask
, afs_int32 flags
,
117 afs_int32 ngroups
, afs_int32 nusers
,
118 afs_int32 spare1
, afs_int32 spare2
,
120 static afs_int32
listElements(struct rx_call
*call
, afs_int32 aid
,
121 prlist
*alist
, afs_int32
*over
, afs_int32
*cid
);
122 #if defined(SUPERGROUPS)
123 static afs_int32
listSuperGroups(struct rx_call
*call
, afs_int32 aid
,
124 prlist
*alist
, afs_int32
*over
,
127 static afs_int32
listOwned(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
128 afs_int32
*lastP
, afs_int32
*cid
);
129 static afs_int32
isAMemberOf(struct rx_call
*call
, afs_int32 uid
, afs_int32 gid
,
130 afs_int32
*flag
, afs_int32
*cid
);
131 static afs_int32
addWildCards(struct ubik_trans
*tt
, prlist
*alist
,
133 static afs_int32
WhoIsThisWithName(struct rx_call
*acall
,
134 struct ubik_trans
*at
, afs_int32
*aid
,
137 /* when we abort, the ubik cachedVersion will be reset, so we'll read in the
138 * header on the next call.
139 * Abort the transaction and return the code.
141 #define ABORT_WITH(tt,code) return(ubik_AbortTrans(tt),code)
144 CreateOK(struct ubik_trans
*ut
, afs_int32 cid
, afs_int32 oid
, afs_int32 flag
,
147 if (restricted
&& !admin
)
150 if (flag
& PRFOREIGN
) {
151 /* Foreign users are recognized by the '@' sign and
152 * not by the PRFOREIGN flag.
155 } else if (flag
& PRGRP
) {
156 /* Allow anonymous group creation only if owner specified
157 * and running noAuth.
159 if (cid
== ANONYMOUSID
) {
160 if ((oid
== 0) || !pr_noAuth
)
163 } else { /* creating a user */
164 if (oid
== ANONYMOUSID
)
166 if (!admin
&& !pr_noAuth
)
173 WhoIsThis(struct rx_call
*acall
, struct ubik_trans
*at
, afs_int32
*aid
)
175 int code
= WhoIsThisWithName(acall
, at
, aid
, NULL
);
176 if (code
== 2 && *aid
== ANONYMOUSID
)
182 WritePreamble(struct ubik_trans
**tt
)
190 code
= ubik_BeginTrans(dbase
, UBIK_WRITETRANS
, tt
);
194 code
= ubik_SetLock(*tt
, 1, 1, LOCKWRITE
);
198 code
= read_DbHeader(*tt
);
202 ubik_AbortTrans(*tt
);
208 ReadPreamble(struct ubik_trans
**tt
)
216 code
= ubik_BeginTransReadAny(dbase
, UBIK_READTRANS
, tt
);
220 code
= ubik_SetLock(*tt
, 1, 1, LOCKREAD
);
224 code
= read_DbHeader(*tt
);
228 ubik_AbortTrans(*tt
);
234 SPR_INewEntry(struct rx_call
*call
, char aname
[], afs_int32 aid
, afs_int32 oid
)
237 afs_int32 cid
= ANONYMOUSID
;
239 code
= iNewEntry(call
, aname
, aid
, oid
, &cid
);
240 osi_auditU(call
, PTS_INewEntEvent
, code
, AUD_ID
, aid
, AUD_STR
, aname
,
241 AUD_ID
, oid
, AUD_END
);
242 ViceLog(5, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d\n", code
, cid
, aid
, aname
, oid
));
247 iNewEntry(struct rx_call
*call
, char aname
[], afs_int32 aid
, afs_int32 oid
,
250 /* used primarily for conversion - not intended to be used as usual means
251 * of entering people into the database. */
252 struct ubik_trans
*tt
;
259 code
= WritePreamble(&tt
);
263 code
= WhoIsThis(call
, tt
, cid
);
265 ABORT_WITH(tt
, PRPERM
);
266 admin
= IsAMemberOf(tt
, *cid
, SYSADMINID
);
268 /* first verify the id is good */
270 ABORT_WITH(tt
, PRPERM
);
273 /* only sysadmin can reuse a group id */
274 if (!admin
&& !pr_noAuth
&& (aid
!= ntohl(cheader
.maxGroup
) - 1))
275 ABORT_WITH(tt
, PRPERM
);
277 if (FindByID(tt
, aid
))
278 ABORT_WITH(tt
, PRIDEXIST
);
280 /* check a few other things */
281 if (!CreateOK(tt
, *cid
, oid
, gflag
, admin
))
282 ABORT_WITH(tt
, PRPERM
);
284 code
= CreateEntry(tt
, aname
, &aid
, 1, gflag
, oid
, *cid
);
285 if (code
!= PRSUCCESS
)
286 ABORT_WITH(tt
, code
);
288 /* finally, commit transaction */
289 code
= ubik_EndTrans(tt
);
297 SPR_NewEntry(struct rx_call
*call
, char aname
[], afs_int32 flag
, afs_int32 oid
,
301 afs_int32 cid
= ANONYMOUSID
;
303 code
= newEntry(call
, aname
, flag
, oid
, aid
, &cid
);
304 osi_auditU(call
, PTS_NewEntEvent
, code
, AUD_ID
, *aid
, AUD_STR
, aname
,
305 AUD_ID
, oid
, AUD_END
);
306 ViceLog(5, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d\n", code
, cid
, *aid
, aname
, oid
));
311 newEntry(struct rx_call
*call
, char aname
[], afs_int32 flag
, afs_int32 oid
,
312 afs_int32
*aid
, afs_int32
*cid
)
315 struct ubik_trans
*tt
;
318 char cname
[PR_MAXNAMELEN
];
321 code
= WritePreamble(&tt
);
325 /* this is for cross-cell self registration. It is not added in the
326 * SPR_INewEntry because we want self-registration to only do
327 * automatic id assignment.
329 code
= WhoIsThisWithName(call
, tt
, cid
, cname
);
330 if (code
&& code
!= 2)
331 ABORT_WITH(tt
, PRPERM
);
332 admin
= IsAMemberOf(tt
, *cid
, SYSADMINID
);
333 if (code
== 2 /* foreign cell request */) {
336 if (!restricted
&& (strcmp(aname
, cname
) == 0)) {
337 /* can't autoregister while providing an owner id */
339 ABORT_WITH(tt
, PRPERM
);
345 if (!CreateOK(tt
, *cid
, oid
, flag
, admin
))
346 ABORT_WITH(tt
, PRPERM
);
348 code
= CreateEntry(tt
, aname
, aid
, 0, flag
, oid
, *cid
);
350 * If this was an autoregistration then be sure to audit log
351 * the proper id as the creator.
353 if (foreign
&& code
== 0 && *aid
> 0)
355 if (code
!= PRSUCCESS
)
356 ABORT_WITH(tt
, code
);
358 code
= ubik_EndTrans(tt
);
367 SPR_WhereIsIt(struct rx_call
*call
, afs_int32 aid
, afs_int32
*apos
)
370 afs_int32 cid
= ANONYMOUSID
;
372 code
= whereIsIt(call
, aid
, apos
, &cid
);
373 osi_auditU(call
, PTS_WheIsItEvent
, code
, AUD_ID
, aid
, AUD_LONG
, *apos
,
375 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d\n", code
, cid
, aid
, *apos
));
380 whereIsIt(struct rx_call
*call
, afs_int32 aid
, afs_int32
*apos
, afs_int32
*cid
)
383 struct ubik_trans
*tt
;
386 code
= ReadPreamble(&tt
);
390 code
= WhoIsThis(call
, tt
, cid
);
392 ABORT_WITH(tt
, PRPERM
);
393 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
394 ABORT_WITH(tt
, PRPERM
);
396 temp
= FindByID(tt
, aid
);
398 ABORT_WITH(tt
, PRNOENT
);
400 code
= ubik_EndTrans(tt
);
408 SPR_DumpEntry(struct rx_call
*call
, afs_int32 apos
,
409 struct prdebugentry
*aentry
)
412 afs_int32 cid
= ANONYMOUSID
;
414 code
= dumpEntry(call
, apos
, aentry
, &cid
);
415 osi_auditU(call
, PTS_DmpEntEvent
, code
, AUD_LONG
, apos
, AUD_END
);
416 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d\n", code
, cid
, apos
));
421 dumpEntry(struct rx_call
*call
, afs_int32 apos
, struct prdebugentry
*aentry
,
425 struct ubik_trans
*tt
;
427 code
= ReadPreamble(&tt
);
431 code
= WhoIsThis(call
, tt
, cid
);
433 ABORT_WITH(tt
, PRPERM
);
434 code
= pr_ReadEntry(tt
, 0, apos
, (struct prentry
*)aentry
);
436 ABORT_WITH(tt
, code
);
438 if (!AccessOK(tt
, *cid
, 0, PRP_STATUS_MEM
, 0))
439 ABORT_WITH(tt
, PRPERM
);
441 /* Since prdebugentry is in the form of a prentry not a coentry, we will
442 * return the coentry slots in network order where the string is. */
444 if (aentry
->flags
& PRCONT
) { /* wrong type, get coentry instead */
445 code
= pr_ReadCoEntry(tt
, 0, apos
, aentry
);
447 ABORT_WITH(tt
, code
);
450 code
= ubik_EndTrans(tt
);
457 SPR_AddToGroup(struct rx_call
*call
, afs_int32 aid
, afs_int32 gid
)
460 afs_int32 cid
= ANONYMOUSID
;
462 code
= addToGroup(call
, aid
, gid
, &cid
);
463 osi_auditU(call
, PTS_AdToGrpEvent
, code
, AUD_ID
, gid
, AUD_ID
, aid
,
465 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d\n", code
, cid
, gid
, aid
));
470 addToGroup(struct rx_call
*call
, afs_int32 aid
, afs_int32 gid
, afs_int32
*cid
)
473 struct ubik_trans
*tt
;
476 struct prentry tentry
;
477 struct prentry uentry
;
479 if (gid
== ANYUSERID
|| gid
== AUTHUSERID
)
481 if (aid
== ANONYMOUSID
)
484 code
= WritePreamble(&tt
);
488 code
= WhoIsThis(call
, tt
, cid
);
490 ABORT_WITH(tt
, PRPERM
);
491 tempu
= FindByID(tt
, aid
);
493 ABORT_WITH(tt
, PRNOENT
);
494 memset(&uentry
, 0, sizeof(uentry
));
495 code
= pr_ReadEntry(tt
, 0, tempu
, &uentry
);
497 ABORT_WITH(tt
, code
);
499 #if !defined(SUPERGROUPS)
500 /* we don't allow groups as members of groups at present */
501 if (uentry
.flags
& PRGRP
)
502 ABORT_WITH(tt
, PRNOTUSER
);
505 tempg
= FindByID(tt
, gid
);
507 ABORT_WITH(tt
, PRNOENT
);
508 code
= pr_ReadEntry(tt
, 0, tempg
, &tentry
);
510 ABORT_WITH(tt
, code
);
511 /* make sure that this is a group */
512 if (!(tentry
.flags
& PRGRP
))
513 ABORT_WITH(tt
, PRNOTGROUP
);
514 if (!AccessOK(tt
, *cid
, &tentry
, PRP_ADD_MEM
, PRP_ADD_ANY
))
515 ABORT_WITH(tt
, PRPERM
);
517 code
= AddToEntry(tt
, &tentry
, tempg
, aid
);
518 if (code
!= PRSUCCESS
)
519 ABORT_WITH(tt
, code
);
521 #if defined(SUPERGROUPS)
522 if (uentry
.flags
& PRGRP
)
523 code
= AddToSGEntry(tt
, &uentry
, tempu
, gid
); /* mod group to be in sg */
526 /* now, modify the user's entry as well */
527 code
= AddToEntry(tt
, &uentry
, tempu
, gid
);
528 if (code
!= PRSUCCESS
)
529 ABORT_WITH(tt
, code
);
530 code
= ubik_EndTrans(tt
);
537 SPR_NameToID(struct rx_call
*call
, namelist
*aname
, idlist
*aid
)
541 code
= nameToID(call
, aname
, aid
);
542 osi_auditU(call
, PTS_NmToIdEvent
, code
, AUD_END
);
543 ViceLog(125, ("PTS_NameToID: code %d\n", code
));
548 nameToID(struct rx_call
*call
, namelist
*aname
, idlist
*aid
)
551 struct ubik_trans
*tt
;
556 /* Initialize return struct */
558 aid
->idlist_val
= NULL
;
560 size
= aname
->namelist_len
;
566 aid
->idlist_val
= malloc(size
* sizeof(afs_int32
));
567 if (!aid
->idlist_val
)
570 code
= ReadPreamble(&tt
);
574 for (i
= 0; i
< aname
->namelist_len
; i
++) {
576 char *nameinst
, *cell
;
577 afs_int32 islocal
= 1;
579 strncpy(vname
, aname
->namelist_val
[i
], sizeof(vname
));
580 vname
[sizeof(vname
)-1] ='\0';
583 cell
= strchr(vname
, '@');
590 code
= afsconf_IsLocalRealmMatch(prdir
, &islocal
, nameinst
, NULL
, cell
);
592 ("PTS_NameToID: afsconf_IsLocalRealmMatch(); code=%d, nameinst=%s, cell=%s\n",
593 code
, nameinst
, cell
));
596 code
= NameToID(tt
, nameinst
, &aid
->idlist_val
[i
]);
598 code
= NameToID(tt
, aname
->namelist_val
[i
], &aid
->idlist_val
[i
]);
600 if (code
!= PRSUCCESS
)
601 aid
->idlist_val
[i
] = ANONYMOUSID
;
602 osi_audit(PTS_NmToIdEvent
, code
, AUD_STR
,
603 aname
->namelist_val
[i
], AUD_ID
, aid
->idlist_val
[i
],
605 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d\n", code
,
606 aname
->namelist_val
[i
], aid
->idlist_val
[i
]));
608 #ifndef AFS_PTHREAD_ENV
614 aid
->idlist_len
= aname
->namelist_len
;
616 code
= ubik_EndTrans(tt
);
624 * Given an array of ids, find the name for each of them.
625 * The array of ids and names is unlimited.
628 SPR_IDToName(struct rx_call
*call
, idlist
*aid
, namelist
*aname
)
631 afs_int32 cid
= ANONYMOUSID
;
633 code
= idToName(call
, aid
, aname
, &cid
);
634 osi_auditU(call
, PTS_IdToNmEvent
, code
, AUD_END
);
635 ViceLog(125, ("PTS_IDToName: code %d\n", code
));
640 idToName(struct rx_call
*call
, idlist
*aid
, namelist
*aname
, afs_int32
*cid
)
643 struct ubik_trans
*tt
;
648 /* leave this first for rpc stub */
649 size
= aid
->idlist_len
;
652 if (size
< 0 || size
> INT_MAX
/ PR_MAXNAMELEN
)
654 aname
->namelist_val
= calloc(size
, PR_MAXNAMELEN
);
655 aname
->namelist_len
= 0;
656 if (aname
->namelist_val
== 0)
658 if (aid
->idlist_len
== 0)
661 return PRTOOMANY
; /* rxgen will probably handle this */
663 code
= ReadPreamble(&tt
);
667 code
= WhoIsThis(call
, tt
, cid
);
669 ABORT_WITH(tt
, PRPERM
);
670 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
671 ABORT_WITH(tt
, PRPERM
);
673 for (i
= 0; i
< aid
->idlist_len
; i
++) {
674 code
= IDToName(tt
, aid
->idlist_val
[i
], aname
->namelist_val
[i
]);
675 if (code
!= PRSUCCESS
)
676 sprintf(aname
->namelist_val
[i
], "%d", aid
->idlist_val
[i
]);
677 osi_audit(PTS_IdToNmEvent
, code
, AUD_ID
, aid
->idlist_val
[i
],
678 AUD_STR
, aname
->namelist_val
[i
], AUD_END
);
679 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s\n", code
,
680 aid
->idlist_val
[i
], aname
->namelist_val
[i
]));
682 #ifndef AFS_PTHREAD_ENV
688 aname
->namelist_len
= aid
->idlist_len
;
690 code
= ubik_EndTrans(tt
);
697 SPR_Delete(struct rx_call
*call
, afs_int32 aid
)
700 afs_int32 cid
= ANONYMOUSID
;
702 code
= Delete(call
, aid
, &cid
);
703 osi_auditU(call
, PTS_DelEvent
, code
, AUD_ID
, aid
, AUD_END
);
704 ViceLog(5, ("PTS_Delete: code %d cid %d aid %d\n", code
, cid
, aid
));
709 Delete(struct rx_call
*call
, afs_int32 aid
, afs_int32
*cid
)
712 struct ubik_trans
*tt
;
713 struct prentry tentry
;
717 if (aid
== SYSADMINID
|| aid
== ANYUSERID
|| aid
== AUTHUSERID
718 || aid
== ANONYMOUSID
)
721 code
= WritePreamble(&tt
);
725 code
= WhoIsThis(call
, tt
, cid
);
727 ABORT_WITH(tt
, PRPERM
);
729 /* Read in entry to be deleted */
730 loc
= FindByID(tt
, aid
);
732 ABORT_WITH(tt
, PRNOENT
);
733 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
735 ABORT_WITH(tt
, PRDBFAIL
);
737 /* Do some access checking */
738 if (tentry
.owner
!= *cid
&& !IsAMemberOf(tt
, *cid
, SYSADMINID
)
739 && !IsAMemberOf(tt
, *cid
, tentry
.owner
) && !pr_noAuth
)
740 ABORT_WITH(tt
, PRPERM
);
742 if (restricted
&& !IsAMemberOf(tt
, *cid
, SYSADMINID
)) {
743 ABORT_WITH(tt
, PRPERM
);
746 /* Delete each continuation block as a separate transaction so that no one
747 * transaction become to large to complete. */
750 struct contentry centry
;
753 code
= pr_ReadCoEntry(tt
, 0, nptr
, ¢ry
);
755 ABORT_WITH(tt
, PRDBFAIL
);
756 for (i
= 0; i
< COSIZE
; i
++) {
757 if (centry
.entries
[i
] == PRBADID
)
759 if (centry
.entries
[i
] == 0)
761 #if defined(SUPERGROUPS)
762 if (aid
< 0 && centry
.entries
[i
] < 0) /* Supergroup */
763 code
= RemoveFromSGEntry(tt
, aid
, centry
.entries
[i
]);
766 code
= RemoveFromEntry(tt
, aid
, centry
.entries
[i
]);
768 ABORT_WITH(tt
, code
);
769 tentry
.count
--; /* maintain count */
770 #ifndef AFS_PTHREAD_ENV
775 tentry
.next
= centry
.next
; /* thread out this block */
776 code
= FreeBlock(tt
, nptr
); /* free continuation block */
778 ABORT_WITH(tt
, code
);
779 code
= pr_WriteEntry(tt
, 0, loc
, &tentry
); /* update main entry */
781 ABORT_WITH(tt
, code
);
783 /* end this trans and start a new one */
784 code
= ubik_EndTrans(tt
);
787 #ifndef AFS_PTHREAD_ENV
788 IOMGR_Poll(); /* just to keep the connection alive */
790 code
= ubik_BeginTrans(dbase
, UBIK_WRITETRANS
, &tt
);
793 code
= ubik_SetLock(tt
, 1, 1, LOCKWRITE
);
795 ABORT_WITH(tt
, code
);
797 /* re-read entry to get consistent uptodate info */
798 loc
= FindByID(tt
, aid
);
800 ABORT_WITH(tt
, PRNOENT
);
801 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
803 ABORT_WITH(tt
, PRDBFAIL
);
808 #if defined(SUPERGROUPS)
809 /* Delete each continuation block as a separate transaction
810 * so that no one transaction become too large to complete. */
812 struct prentryg
*tentryg
= (struct prentryg
*)&tentry
;
813 nptr
= tentryg
->nextsg
;
815 struct contentry centry
;
818 code
= pr_ReadCoEntry(tt
, 0, nptr
, ¢ry
);
820 ABORT_WITH(tt
, PRDBFAIL
);
821 for (i
= 0; i
< COSIZE
; i
++) {
822 if (centry
.entries
[i
] == PRBADID
)
824 if (centry
.entries
[i
] == 0)
826 code
= RemoveFromEntry(tt
, aid
, centry
.entries
[i
]);
828 ABORT_WITH(tt
, code
);
829 tentryg
->countsg
--; /* maintain count */
830 #ifndef AFS_PTHREAD_ENV
835 tentryg
->nextsg
= centry
.next
; /* thread out this block */
836 code
= FreeBlock(tt
, nptr
); /* free continuation block */
838 ABORT_WITH(tt
, code
);
839 code
= pr_WriteEntry(tt
, 0, loc
, &tentry
); /* update main entry */
841 ABORT_WITH(tt
, code
);
843 /* end this trans and start a new one */
844 code
= ubik_EndTrans(tt
);
847 #ifndef AFS_PTHREAD_ENV
848 IOMGR_Poll(); /* just to keep the connection alive */
851 code
= ubik_BeginTrans(dbase
, UBIK_WRITETRANS
, &tt
);
854 code
= ubik_SetLock(tt
, 1, 1, LOCKWRITE
);
856 ABORT_WITH(tt
, code
);
858 /* re-read entry to get consistent uptodate info */
859 loc
= FindByID(tt
, aid
);
861 ABORT_WITH(tt
, PRNOENT
);
862 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
864 ABORT_WITH(tt
, PRDBFAIL
);
866 nptr
= tentryg
->nextsg
;
870 #endif /* SUPERGROUPS */
872 /* Then move the owned chain, except possibly ourself to the orphan list.
873 * Because this list can be very long and so exceed the size of a ubik
874 * transaction, we start a new transaction every 50 entries. */
878 struct prentry nentry
;
880 code
= pr_ReadEntry(tt
, 0, nptr
, &nentry
);
882 ABORT_WITH(tt
, PRDBFAIL
);
883 nptr
= tentry
.owned
= nentry
.nextOwned
; /* thread out */
885 if (nentry
.id
!= tentry
.id
) { /* don't add us to orphan chain! */
886 code
= AddToOrphan(tt
, nentry
.id
);
888 ABORT_WITH(tt
, code
);
890 #ifndef AFS_PTHREAD_ENV
891 if ((count
& 3) == 0)
897 code
= pr_WriteEntry(tt
, 0, loc
, &tentry
); /* update main entry */
899 ABORT_WITH(tt
, code
);
901 /* end this trans and start a new one */
902 code
= ubik_EndTrans(tt
);
905 #ifndef AFS_PTHREAD_ENV
906 IOMGR_Poll(); /* just to keep the connection alive */
908 code
= ubik_BeginTrans(dbase
, UBIK_WRITETRANS
, &tt
);
911 code
= ubik_SetLock(tt
, 1, 1, LOCKWRITE
);
913 ABORT_WITH(tt
, code
);
915 /* re-read entry to get consistent uptodate info */
916 loc
= FindByID(tt
, aid
);
918 ABORT_WITH(tt
, PRNOENT
);
919 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
921 ABORT_WITH(tt
, PRDBFAIL
);
926 /* now do what's left of the deletion stuff */
927 code
= DeleteEntry(tt
, &tentry
, loc
);
928 if (code
!= PRSUCCESS
)
929 ABORT_WITH(tt
, code
);
931 code
= ubik_EndTrans(tt
);
938 SPR_UpdateEntry(struct rx_call
*call
, afs_int32 aid
, char *name
,
939 struct PrUpdateEntry
*uentry
)
942 afs_int32 cid
= ANONYMOUSID
;
944 code
= UpdateEntry(call
, aid
, name
, uentry
, &cid
);
945 osi_auditU(call
, PTS_UpdEntEvent
, code
, AUD_ID
, aid
, AUD_STR
, name
, AUD_END
);
946 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s\n", code
, cid
, aid
, name
));
951 UpdateEntry(struct rx_call
*call
, afs_int32 aid
, char *name
,
952 struct PrUpdateEntry
*uentry
, afs_int32
*cid
)
955 struct ubik_trans
*tt
;
956 struct prentry tentry
;
962 if (aid
== SYSADMINID
|| aid
== ANYUSERID
|| aid
== AUTHUSERID
963 || aid
== ANONYMOUSID
)
967 code
= WritePreamble(&tt
);
971 code
= WhoIsThis(call
, tt
, cid
);
973 ABORT_WITH(tt
, PRPERM
);
974 code
= IsAMemberOf(tt
, *cid
, SYSADMINID
);
975 if (!code
&& !pr_noAuth
)
976 ABORT_WITH(tt
, PRPERM
);
978 /* Read in entry to be deleted */
980 loc
= FindByID(tt
, aid
);
982 loc
= FindByName(tt
, name
, &tentry
);
985 ABORT_WITH(tt
, PRNOENT
);
986 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
988 ABORT_WITH(tt
, PRDBFAIL
);
990 if (uentry
->Mask
& PRUPDATE_NAMEHASH
) {
992 code
= RemoveFromNameHash(tt
, tentry
.name
, &tloc
);
993 if (code
!= PRSUCCESS
)
994 ABORT_WITH(tt
, PRDBFAIL
);
995 code
= AddToNameHash(tt
, tentry
.name
, loc
);
997 ABORT_WITH(tt
, code
);
1000 if (uentry
->Mask
& PRUPDATE_IDHASH
) {
1004 code
= RemoveFromIDHash(tt
, id
, &tloc
);
1005 if (code
!= PRSUCCESS
)
1006 ABORT_WITH(tt
, PRDBFAIL
);
1007 code
= AddToIDHash(tt
, id
, loc
);
1009 ABORT_WITH(tt
, code
);
1012 code
= ubik_EndTrans(tt
);
1019 SPR_RemoveFromGroup(struct rx_call
*call
, afs_int32 aid
, afs_int32 gid
)
1022 afs_int32 cid
= ANONYMOUSID
;
1024 code
= removeFromGroup(call
, aid
, gid
, &cid
);
1025 osi_auditU(call
, PTS_RmFmGrpEvent
, code
, AUD_ID
, gid
, AUD_ID
, aid
,
1027 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d\n", code
, cid
, gid
, aid
));
1032 removeFromGroup(struct rx_call
*call
, afs_int32 aid
, afs_int32 gid
,
1036 struct ubik_trans
*tt
;
1039 struct prentry uentry
;
1040 struct prentry gentry
;
1042 code
= WritePreamble(&tt
);
1046 code
= WhoIsThis(call
, tt
, cid
);
1048 ABORT_WITH(tt
, PRPERM
);
1049 tempu
= FindByID(tt
, aid
);
1051 ABORT_WITH(tt
, PRNOENT
);
1052 tempg
= FindByID(tt
, gid
);
1054 ABORT_WITH(tt
, PRNOENT
);
1055 memset(&uentry
, 0, sizeof(uentry
));
1056 memset(&gentry
, 0, sizeof(gentry
));
1057 code
= pr_ReadEntry(tt
, 0, tempu
, &uentry
);
1059 ABORT_WITH(tt
, code
);
1060 code
= pr_ReadEntry(tt
, 0, tempg
, &gentry
);
1062 ABORT_WITH(tt
, code
);
1063 if (!(gentry
.flags
& PRGRP
))
1064 ABORT_WITH(tt
, PRNOTGROUP
);
1065 #if !defined(SUPERGROUPS)
1066 if (uentry
.flags
& PRGRP
)
1067 ABORT_WITH(tt
, PRNOTUSER
);
1069 if (!AccessOK(tt
, *cid
, &gentry
, PRP_REMOVE_MEM
, 0))
1070 ABORT_WITH(tt
, PRPERM
);
1071 code
= RemoveFromEntry(tt
, aid
, gid
);
1072 if (code
!= PRSUCCESS
)
1073 ABORT_WITH(tt
, code
);
1074 #if defined(SUPERGROUPS)
1075 if (!(uentry
.flags
& PRGRP
))
1077 code
= RemoveFromEntry(tt
, gid
, aid
);
1078 #if defined(SUPERGROUPS)
1080 code
= RemoveFromSGEntry(tt
, gid
, aid
);
1082 if (code
!= PRSUCCESS
)
1083 ABORT_WITH(tt
, code
);
1085 code
= ubik_EndTrans(tt
);
1093 SPR_GetCPS(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
, afs_int32
*over
)
1096 afs_int32 cid
= ANONYMOUSID
;
1098 code
= getCPS(call
, aid
, alist
, over
, &cid
);
1099 osi_auditU(call
, PTS_GetCPSEvent
, code
, AUD_ID
, aid
, AUD_END
);
1100 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d\n", code
, cid
, aid
));
1105 getCPS(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
, afs_int32
*over
,
1109 struct ubik_trans
*tt
;
1111 struct prentry tentry
;
1114 alist
->prlist_len
= 0;
1115 alist
->prlist_val
= NULL
;
1117 code
= ReadPreamble(&tt
);
1121 code
= WhoIsThis(call
, tt
, cid
);
1123 ABORT_WITH(tt
, PRPERM
);
1124 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
1125 ABORT_WITH(tt
, PRPERM
);
1127 temp
= FindByID(tt
, aid
);
1129 ABORT_WITH(tt
, PRNOENT
);
1130 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1132 ABORT_WITH(tt
, code
);
1134 if (!AccessOK(tt
, *cid
, &tentry
, PRP_MEMBER_MEM
, PRP_MEMBER_ANY
))
1135 ABORT_WITH(tt
, PRPERM
);
1137 code
= GetList(tt
, &tentry
, alist
, 1);
1138 if (code
!= PRSUCCESS
)
1139 ABORT_WITH(tt
, code
);
1141 code
= ubik_EndTrans(tt
);
1147 inCPS(prlist CPS
, afs_int32 id
)
1151 for (i
= (CPS
.prlist_len
- 1); i
>= 0; i
--) {
1152 if (CPS
.prlist_val
[i
] == id
)
1160 SPR_GetCPS2(struct rx_call
*call
, afs_int32 aid
, afs_int32 ahost
,
1161 prlist
*alist
, afs_int32
*over
)
1164 afs_int32 cid
= ANONYMOUSID
;
1166 code
= getCPS2(call
, aid
, ahost
, alist
, over
, &cid
);
1167 osi_auditU(call
, PTS_GetCPS2Event
, code
, AUD_ID
, aid
, AUD_HOST
, htonl(ahost
),
1169 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d\n", code
, cid
, aid
, ahost
));
1174 getCPS2(struct rx_call
*call
, afs_int32 aid
, afs_uint32 ahost
, prlist
*alist
,
1175 afs_int32
*over
, afs_int32
*cid
)
1178 struct ubik_trans
*tt
;
1180 struct prentry tentry
;
1181 struct prentry host_tentry
;
1184 struct in_addr iaddr
;
1188 iaddr
.s_addr
= ntohl(ahost
);
1189 alist
->prlist_len
= 0;
1190 alist
->prlist_val
= NULL
;
1192 code
= ReadPreamble(&tt
);
1196 if (aid
!= PRBADID
) {
1197 temp
= FindByID(tt
, aid
);
1199 ABORT_WITH(tt
, PRNOENT
);
1200 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1202 ABORT_WITH(tt
, code
);
1204 /* afs does authenticate now */
1205 code
= WhoIsThis(call
, tt
, cid
);
1207 || !AccessOK(tt
, *cid
, &tentry
, PRP_MEMBER_MEM
, PRP_MEMBER_ANY
))
1208 ABORT_WITH(tt
, PRPERM
);
1210 code
= NameToID(tt
, afs_inet_ntoa_r(iaddr
.s_addr
, hoststr
), &hostid
);
1211 if (code
== PRSUCCESS
&& hostid
!= 0) {
1212 temp
= FindByID(tt
, hostid
);
1214 code
= pr_ReadEntry(tt
, 0, temp
, &host_tentry
);
1215 if (code
== PRSUCCESS
)
1218 fprintf(stderr
, "pr_ReadEntry returned %d\n", code
);
1220 fprintf(stderr
, "FindByID Failed -- Not found\n");
1223 code
= GetList2(tt
, &tentry
, &host_tentry
, alist
, 1);
1225 code
= GetList(tt
, &tentry
, alist
, 1);
1227 code
= addWildCards(tt
, alist
, ntohl(ahost
));
1228 if (code
!= PRSUCCESS
)
1229 ABORT_WITH(tt
, code
);
1231 code
= ubik_EndTrans(tt
);
1237 SPR_GetHostCPS(struct rx_call
*call
, afs_int32 ahost
, prlist
*alist
,
1241 afs_int32 cid
= ANONYMOUSID
;
1243 code
= getHostCPS(call
, ahost
, alist
, over
, &cid
);
1244 osi_auditU(call
, PTS_GetHCPSEvent
, code
, AUD_HOST
, htonl(ahost
), AUD_END
);
1245 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %u (0x%x)\n", code
, ahost
, ahost
));
1250 getHostCPS(struct rx_call
*call
, afs_uint32 ahost
, prlist
*alist
,
1251 afs_int32
*over
, afs_int32
*cid
)
1253 afs_int32 code
, temp
;
1254 struct ubik_trans
*tt
;
1255 struct prentry host_tentry
;
1257 struct in_addr iaddr
;
1261 iaddr
.s_addr
= ntohl(ahost
);
1262 alist
->prlist_len
= 0;
1263 alist
->prlist_val
= NULL
;
1265 code
= ReadPreamble(&tt
);
1269 code
= WhoIsThis(call
, tt
, cid
);
1271 ABORT_WITH(tt
, PRPERM
);
1272 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
1273 ABORT_WITH(tt
, PRPERM
);
1275 code
= NameToID(tt
, afs_inet_ntoa_r(iaddr
.s_addr
, hoststr
), &hostid
);
1276 if (code
== PRSUCCESS
&& hostid
!= 0) {
1277 temp
= FindByID(tt
, hostid
);
1279 code
= pr_ReadEntry(tt
, 0, temp
, &host_tentry
);
1280 if (code
== PRSUCCESS
) {
1281 code
= GetList(tt
, &host_tentry
, alist
, 0);
1285 fprintf(stderr
, "pr_ReadEntry returned %d\n", code
);
1287 fprintf(stderr
, "FindByID Failed -- Not found\n");
1289 code
= addWildCards(tt
, alist
, ntohl(ahost
));
1291 if (code
!= PRSUCCESS
)
1292 ABORT_WITH(tt
, code
);
1294 code
= ubik_EndTrans(tt
);
1300 SPR_ListMax(struct rx_call
*call
, afs_int32
*uid
, afs_int32
*gid
)
1303 afs_int32 cid
= ANONYMOUSID
;
1305 code
= listMax(call
, uid
, gid
, &cid
);
1306 osi_auditU(call
, PTS_LstMaxEvent
, code
, AUD_END
);
1307 ViceLog(125, ("PTS_ListMax: code %d\n", code
));
1312 listMax(struct rx_call
*call
, afs_int32
*uid
, afs_int32
*gid
, afs_int32
*cid
)
1315 struct ubik_trans
*tt
;
1317 code
= ReadPreamble(&tt
);
1321 code
= WhoIsThis(call
, tt
, cid
);
1323 ABORT_WITH(tt
, PRPERM
);
1324 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
1325 ABORT_WITH(tt
, PRPERM
);
1327 code
= GetMax(tt
, uid
, gid
);
1328 if (code
!= PRSUCCESS
)
1329 ABORT_WITH(tt
, code
);
1331 code
= ubik_EndTrans(tt
);
1338 SPR_SetMax(struct rx_call
*call
, afs_int32 aid
, afs_int32 gflag
)
1341 afs_int32 cid
= ANONYMOUSID
;
1343 code
= setMax(call
, aid
, gflag
, &cid
);
1344 osi_auditU(call
, PTS_SetMaxEvent
, code
, AUD_ID
, aid
, AUD_LONG
, gflag
,
1346 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d\n", code
, cid
, aid
, gflag
));
1351 setMax(struct rx_call
*call
, afs_int32 aid
, afs_int32 gflag
, afs_int32
*cid
)
1354 struct ubik_trans
*tt
;
1356 code
= WritePreamble(&tt
);
1360 code
= WhoIsThis(call
, tt
, cid
);
1362 ABORT_WITH(tt
, PRPERM
);
1363 if (!AccessOK(tt
, *cid
, 0, 0, 0))
1364 ABORT_WITH(tt
, PRPERM
);
1365 if (((gflag
& PRGRP
) && (aid
> 0)) || (!(gflag
& PRGRP
) && (aid
< 0)))
1366 ABORT_WITH(tt
, PRBADARG
);
1368 code
= SetMax(tt
, aid
, gflag
);
1369 if (code
!= PRSUCCESS
)
1370 ABORT_WITH(tt
, code
);
1372 code
= ubik_EndTrans(tt
);
1379 SPR_ListEntry(struct rx_call
*call
, afs_int32 aid
, struct prcheckentry
*aentry
)
1382 afs_int32 cid
= ANONYMOUSID
;
1384 code
= listEntry(call
, aid
, aentry
, &cid
);
1385 osi_auditU(call
, PTS_LstEntEvent
, code
, AUD_ID
, aid
, AUD_END
);
1386 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d\n", code
, cid
, aid
));
1391 listEntry(struct rx_call
*call
, afs_int32 aid
, struct prcheckentry
*aentry
,
1395 struct ubik_trans
*tt
;
1397 struct prentry tentry
;
1399 code
= ReadPreamble(&tt
);
1403 code
= WhoIsThis(call
, tt
, cid
);
1405 ABORT_WITH(tt
, PRPERM
);
1406 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
1407 ABORT_WITH(tt
, PRPERM
);
1408 temp
= FindByID(tt
, aid
);
1410 ABORT_WITH(tt
, PRNOENT
);
1411 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1413 ABORT_WITH(tt
, code
);
1414 if (!AccessOK(tt
, *cid
, &tentry
, PRP_STATUS_MEM
, PRP_STATUS_ANY
))
1415 ABORT_WITH(tt
, PRPERM
);
1417 aentry
->flags
= tentry
.flags
>> PRIVATE_SHIFT
;
1418 if (aentry
->flags
== 0) {
1419 if (tentry
.flags
& PRGRP
)
1420 aentry
->flags
= prp_group_default
>> PRIVATE_SHIFT
;
1422 aentry
->flags
= prp_user_default
>> PRIVATE_SHIFT
;
1424 aentry
->owner
= tentry
.owner
;
1425 aentry
->id
= tentry
.id
;
1426 strncpy(aentry
->name
, tentry
.name
, PR_MAXNAMELEN
);
1427 aentry
->creator
= tentry
.creator
;
1428 aentry
->ngroups
= tentry
.ngroups
;
1429 aentry
->nusers
= tentry
.nusers
;
1430 aentry
->count
= tentry
.count
;
1431 memset(aentry
->reserved
, 0, sizeof(aentry
->reserved
));
1432 code
= ubik_EndTrans(tt
);
1439 SPR_ListEntries(struct rx_call
*call
, afs_int32 flag
, afs_int32 startindex
,
1440 prentries
*bulkentries
, afs_int32
*nextstartindex
)
1443 afs_int32 cid
= ANONYMOUSID
;
1445 code
= listEntries(call
, flag
, startindex
, bulkentries
, nextstartindex
, &cid
);
1446 osi_auditU(call
, PTS_LstEntsEvent
, code
, AUD_LONG
, flag
, AUD_END
);
1447 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d\n", code
, cid
, flag
));
1452 listEntries(struct rx_call
*call
, afs_int32 flag
, afs_int32 startindex
,
1453 prentries
*bulkentries
, afs_int32
*nextstartindex
, afs_int32
*cid
)
1456 struct ubik_trans
*tt
;
1457 afs_int32 i
, eof
, pos
, maxentries
, f
;
1458 struct prentry tentry
;
1459 afs_int32 pollcount
= 0;
1461 *nextstartindex
= -1;
1462 bulkentries
->prentries_val
= 0;
1463 bulkentries
->prentries_len
= 0;
1465 code
= ReadPreamble(&tt
);
1469 /* Make sure we are an authenticated caller and that we are on the
1472 code
= WhoIsThis(call
, tt
, cid
);
1474 ABORT_WITH(tt
, PRPERM
);
1475 code
= IsAMemberOf(tt
, *cid
, SYSADMINID
);
1476 if (!code
&& !pr_noAuth
)
1477 ABORT_WITH(tt
, PRPERM
);
1479 eof
= ntohl(cheader
.eofPtr
) - sizeof(cheader
);
1480 maxentries
= eof
/ sizeof(struct prentry
);
1481 for (i
= startindex
; i
< maxentries
; i
++) {
1482 pos
= i
* sizeof(struct prentry
) + sizeof(cheader
);
1483 code
= pr_ReadEntry(tt
, 0, pos
, &tentry
);
1487 if (++pollcount
> 50) {
1488 #ifndef AFS_PTHREAD_ENV
1494 f
= (tentry
.flags
& PRTYPE
);
1495 if (((flag
& PRUSERS
) && (f
== 0)) || /* User entry */
1496 ((flag
& PRGROUPS
) && (f
& PRGRP
))) { /* Group entry */
1497 code
= put_prentries(&tentry
, bulkentries
);
1499 break; /* Filled return array */
1506 *nextstartindex
= i
;
1510 if (bulkentries
->prentries_val
)
1511 free(bulkentries
->prentries_val
);
1512 bulkentries
->prentries_val
= 0;
1513 bulkentries
->prentries_len
= 0;
1514 ABORT_WITH(tt
, code
);
1516 code
= ubik_EndTrans(tt
);
1523 #define PR_MAXENTRIES 500
1525 put_prentries(struct prentry
*tentry
, prentries
*bulkentries
)
1527 struct prlistentries
*entry
;
1529 if (bulkentries
->prentries_val
== 0) {
1530 bulkentries
->prentries_len
= 0;
1531 bulkentries
->prentries_val
= malloc(PR_MAXENTRIES
*
1532 sizeof(struct prlistentries
));
1533 if (!bulkentries
->prentries_val
) {
1538 if (bulkentries
->prentries_len
>= PR_MAXENTRIES
) {
1542 entry
= bulkentries
->prentries_val
;
1543 entry
+= bulkentries
->prentries_len
;
1545 memset(entry
, 0, sizeof(*entry
));
1546 entry
->flags
= tentry
->flags
>> PRIVATE_SHIFT
;
1547 if (entry
->flags
== 0) {
1550 flags
& PRGRP
) ? prp_group_default
: prp_user_default
) >>
1553 entry
->owner
= tentry
->owner
;
1554 entry
->id
= tentry
->id
;
1555 entry
->creator
= tentry
->creator
;
1556 entry
->ngroups
= tentry
->ngroups
;
1557 entry
->nusers
= tentry
->nusers
;
1558 entry
->count
= tentry
->count
;
1559 strncpy(entry
->name
, tentry
->name
, PR_MAXNAMELEN
);
1560 bulkentries
->prentries_len
++;
1565 SPR_ChangeEntry(struct rx_call
*call
, afs_int32 aid
, char *name
, afs_int32 oid
,
1569 afs_int32 cid
= ANONYMOUSID
;
1571 code
= changeEntry(call
, aid
, name
, oid
, newid
, &cid
);
1572 osi_auditU(call
, PTS_ChgEntEvent
, code
, AUD_ID
, aid
, AUD_STR
, name
,
1573 AUD_LONG
, oid
, AUD_LONG
, newid
, AUD_END
);
1574 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d\n", code
, cid
, aid
, name
, oid
, newid
));
1579 changeEntry(struct rx_call
*call
, afs_int32 aid
, char *name
, afs_int32 oid
,
1580 afs_int32 newid
, afs_int32
*cid
)
1583 struct ubik_trans
*tt
;
1590 if (aid
== ANYUSERID
|| aid
== AUTHUSERID
|| aid
== ANONYMOUSID
1591 || aid
== SYSADMINID
)
1594 code
= WritePreamble(&tt
);
1598 code
= WhoIsThis(call
, tt
, cid
);
1600 ABORT_WITH(tt
, PRPERM
);
1601 pos
= FindByID(tt
, aid
);
1603 ABORT_WITH(tt
, PRNOENT
);
1604 /* protection check in changeentry */
1605 code
= ChangeEntry(tt
, aid
, *cid
, name
, oid
, newid
);
1606 if (code
!= PRSUCCESS
)
1607 ABORT_WITH(tt
, code
);
1609 code
= ubik_EndTrans(tt
);
1614 SPR_SetFieldsEntry(struct rx_call
*call
,
1616 afs_int32 mask
, /* specify which fields to update */
1617 afs_int32 flags
, afs_int32 ngroups
, afs_int32 nusers
,
1618 afs_int32 spare1
, afs_int32 spare2
)
1621 afs_int32 cid
= ANONYMOUSID
;
1624 setFieldsEntry(call
, id
, mask
, flags
, ngroups
, nusers
, spare1
,
1626 osi_auditU(call
, PTS_SetFldEntEvent
, code
, AUD_ID
, id
, AUD_END
);
1627 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d\n", code
, cid
, id
));
1632 setFieldsEntry(struct rx_call
*call
,
1634 afs_int32 mask
, /* specify which fields to update */
1635 afs_int32 flags
, afs_int32 ngroups
, afs_int32 nusers
,
1636 afs_int32 spare1
, afs_int32 spare2
, afs_int32
*cid
)
1639 struct ubik_trans
*tt
;
1641 struct prentry tentry
;
1645 return 0; /* no-op */
1647 if (id
== ANYUSERID
|| id
== AUTHUSERID
|| id
== ANONYMOUSID
)
1650 code
= WritePreamble(&tt
);
1654 code
= WhoIsThis(call
, tt
, cid
);
1656 ABORT_WITH(tt
, PRPERM
);
1657 pos
= FindByID(tt
, id
);
1659 ABORT_WITH(tt
, PRNOENT
);
1660 code
= pr_ReadEntry(tt
, 0, pos
, &tentry
);
1662 ABORT_WITH(tt
, code
);
1663 tflags
= tentry
.flags
;
1665 if (mask
& (PR_SF_NGROUPS
| PR_SF_NUSERS
)) {
1666 if (!AccessOK(tt
, *cid
, 0, 0, 0))
1667 ABORT_WITH(tt
, PRPERM
);
1668 if ((tflags
& PRQUOTA
) == 0) { /* default if only setting one */
1669 tentry
.ngroups
= tentry
.nusers
= 20;
1672 if (!AccessOK(tt
, *cid
, &tentry
, 0, 0))
1673 ABORT_WITH(tt
, PRPERM
);
1676 if (mask
& 0xffff) { /* if setting flag bits */
1677 afs_int32 flagsMask
= mask
& 0xffff;
1678 tflags
&= ~(flagsMask
<< PRIVATE_SHIFT
);
1679 tflags
|= (flags
& flagsMask
) << PRIVATE_SHIFT
;
1683 if (mask
& PR_SF_NGROUPS
) { /* setting group limit */
1685 ABORT_WITH(tt
, PRBADARG
);
1686 tentry
.ngroups
= ngroups
;
1690 if (mask
& PR_SF_NUSERS
) { /* setting foreign user limit */
1692 ABORT_WITH(tt
, PRBADARG
);
1693 tentry
.nusers
= nusers
;
1696 tentry
.flags
= tflags
;
1698 code
= pr_WriteEntry(tt
, 0, pos
, &tentry
);
1700 ABORT_WITH(tt
, code
);
1702 code
= ubik_EndTrans(tt
);
1707 SPR_ListElements(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
1711 afs_int32 cid
= ANONYMOUSID
;
1713 code
= listElements(call
, aid
, alist
, over
, &cid
);
1714 osi_auditU(call
, PTS_LstEleEvent
, code
, AUD_ID
, aid
, AUD_END
);
1715 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d\n", code
, cid
, aid
));
1720 listElements(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
1721 afs_int32
*over
, afs_int32
*cid
)
1724 struct ubik_trans
*tt
;
1726 struct prentry tentry
;
1729 alist
->prlist_len
= 0;
1730 alist
->prlist_val
= NULL
;
1732 code
= ReadPreamble(&tt
);
1736 code
= WhoIsThis(call
, tt
, cid
);
1738 ABORT_WITH(tt
, PRPERM
);
1740 temp
= FindByID(tt
, aid
);
1742 ABORT_WITH(tt
, PRNOENT
);
1743 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1745 ABORT_WITH(tt
, code
);
1746 if (!AccessOK(tt
, *cid
, &tentry
, PRP_MEMBER_MEM
, PRP_MEMBER_ANY
))
1747 ABORT_WITH(tt
, PRPERM
);
1749 code
= GetList(tt
, &tentry
, alist
, 0);
1750 if (code
!= PRSUCCESS
)
1751 ABORT_WITH(tt
, code
);
1753 code
= ubik_EndTrans(tt
);
1759 SPR_ListSuperGroups(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
1762 #if defined(SUPERGROUPS)
1764 afs_int32 cid
= ANONYMOUSID
;
1766 code
= listSuperGroups(call
, aid
, alist
, over
, &cid
);
1767 osi_auditU(call
, PTS_LstSGrps
, code
, AUD_ID
, aid
, AUD_END
);
1768 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d\n", code
, cid
, aid
));
1771 return RXGEN_OPCODE
;
1775 #if defined(SUPERGROUPS)
1777 listSuperGroups(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
1778 afs_int32
*over
, afs_int32
*cid
)
1781 struct ubik_trans
*tt
;
1783 struct prentry tentry
;
1785 alist
->prlist_len
= 0;
1786 alist
->prlist_val
= (afs_int32
*) 0;
1788 code
= ReadPreamble(&tt
);
1792 code
= WhoIsThis(call
, tt
, cid
);
1794 ABORT_WITH(tt
, PRPERM
);
1795 if (!pr_noAuth
&& restrict_anonymous
&& *cid
== ANONYMOUSID
)
1796 ABORT_WITH(tt
, PRPERM
);
1798 code
= ubik_SetLock(tt
, 1, 1, LOCKREAD
);
1800 ABORT_WITH(tt
, code
);
1802 temp
= FindByID(tt
, aid
);
1804 ABORT_WITH(tt
, PRNOENT
);
1805 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1807 ABORT_WITH(tt
, code
);
1808 if (!AccessOK(tt
, *cid
, &tentry
, PRP_MEMBER_MEM
, PRP_MEMBER_ANY
))
1809 ABORT_WITH(tt
, PRPERM
);
1811 code
= GetSGList(tt
, &tentry
, alist
);
1813 if (code
== PRTOOMANY
)
1815 else if (code
!= PRSUCCESS
)
1816 ABORT_WITH(tt
, code
);
1818 code
= ubik_EndTrans(tt
);
1823 #endif /* SUPERGROUPS */
1827 * List the entries owned by this id. If the id is zero,
1828 * return the orphans list. This will return up to PR_MAXGROUPS
1829 * at a time with the lastP available to get the rest. The
1830 * maximum value is enforced in GetOwnedChain().
1833 SPR_ListOwned(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
,
1837 afs_int32 cid
= ANONYMOUSID
;
1839 code
= listOwned(call
, aid
, alist
, lastP
, &cid
);
1840 osi_auditU(call
, PTS_LstOwnEvent
, code
, AUD_ID
, aid
, AUD_END
);
1841 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d\n", code
, cid
, aid
));
1846 listOwned(struct rx_call
*call
, afs_int32 aid
, prlist
*alist
, afs_int32
*lastP
,
1850 struct ubik_trans
*tt
;
1851 struct prentry tentry
;
1855 alist
->prlist_len
= 0;
1856 alist
->prlist_val
= NULL
;
1863 code
= ReadPreamble(&tt
);
1867 code
= WhoIsThis(call
, tt
, cid
);
1869 ABORT_WITH(tt
, PRPERM
);
1872 code
= pr_ReadEntry(tt
, 0, start
, &tentry
);
1873 if (!code
&& (tentry
.owner
== aid
))
1874 head
= start
; /* pick up where we left off */
1879 afs_int32 loc
= FindByID(tt
, aid
);
1881 ABORT_WITH(tt
, PRNOENT
);
1882 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
1884 ABORT_WITH(tt
, code
);
1886 if (!AccessOK(tt
, *cid
, &tentry
, -1, PRP_OWNED_ANY
))
1887 ABORT_WITH(tt
, PRPERM
);
1888 head
= tentry
.owned
;
1890 if (!AccessOK(tt
, *cid
, 0, 0, 0))
1891 ABORT_WITH(tt
, PRPERM
);
1892 head
= ntohl(cheader
.orphan
);
1896 code
= GetOwnedChain(tt
, &head
, alist
);
1898 if (code
== PRTOOMANY
)
1901 ABORT_WITH(tt
, code
);
1904 code
= ubik_EndTrans(tt
);
1909 SPR_IsAMemberOf(struct rx_call
*call
, afs_int32 uid
, afs_int32 gid
,
1913 afs_int32 cid
= ANONYMOUSID
;
1915 code
= isAMemberOf(call
, uid
, gid
, flag
, &cid
);
1916 osi_auditU(call
, PTS_IsMemOfEvent
, code
, AUD_LONG
, uid
, AUD_LONG
, gid
,
1918 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d\n", code
, cid
, uid
, gid
));
1923 isAMemberOf(struct rx_call
*call
, afs_int32 uid
, afs_int32 gid
, afs_int32
*flag
,
1927 struct ubik_trans
*tt
;
1929 code
= ReadPreamble(&tt
);
1934 afs_int32 uloc
= FindByID(tt
, uid
);
1935 afs_int32 gloc
= FindByID(tt
, gid
);
1936 struct prentry uentry
, gentry
;
1939 ABORT_WITH(tt
, PRNOENT
);
1940 code
= WhoIsThis(call
, tt
, cid
);
1942 ABORT_WITH(tt
, PRPERM
);
1943 code
= pr_ReadEntry(tt
, 0, uloc
, &uentry
);
1945 ABORT_WITH(tt
, code
);
1946 code
= pr_ReadEntry(tt
, 0, gloc
, &gentry
);
1948 ABORT_WITH(tt
, code
);
1949 #if !defined(SUPERGROUPS)
1950 if ((uentry
.flags
& PRGRP
) || !(gentry
.flags
& PRGRP
))
1951 ABORT_WITH(tt
, PRBADARG
);
1953 if (!(gentry
.flags
& PRGRP
))
1954 ABORT_WITH(tt
, PRBADARG
);
1956 if (!AccessOK(tt
, *cid
, &uentry
, 0, PRP_MEMBER_ANY
)
1957 && !AccessOK(tt
, *cid
, &gentry
, PRP_MEMBER_MEM
, PRP_MEMBER_ANY
))
1958 ABORT_WITH(tt
, PRPERM
);
1961 *flag
= IsAMemberOf(tt
, uid
, gid
);
1962 code
= ubik_EndTrans(tt
);
1967 addWildCards(struct ubik_trans
*tt
, prlist
*alist
, afs_uint32 host
)
1970 struct prentry tentry
;
1972 unsigned wild
= htonl(0xffffff00);
1973 struct in_addr iaddr
;
1975 int size
= 0, i
, code
;
1979 while ((host
= (host
& wild
))) {
1980 wild
= htonl(ntohl(wild
) << 8);
1981 iaddr
.s_addr
= host
;
1982 code
= NameToID(tt
, afs_inet_ntoa_r(iaddr
.s_addr
, hoststr
), &hostid
);
1983 if (code
== PRSUCCESS
&& hostid
!= 0) {
1984 temp
= FindByID(tt
, hostid
);
1986 code
= pr_ReadEntry(tt
, 0, temp
, &tentry
);
1987 if (code
!= PRSUCCESS
)
1993 wlist
.prlist_len
= 0;
1994 wlist
.prlist_val
= NULL
;
1996 code
= GetList(tt
, &tentry
, &wlist
, 0);
1999 added
+= wlist
.prlist_len
;
2000 for (i
= 0; i
< wlist
.prlist_len
; i
++) {
2001 if (!inCPS(*alist
, wlist
.prlist_val
[i
]))
2002 if ((code
= AddToPRList(alist
, &size
, wlist
.prlist_val
[i
]))) {
2003 free(wlist
.prlist_val
);
2007 if (wlist
.prlist_val
)
2008 free(wlist
.prlist_val
);
2011 qsort(alist
->prlist_val
, alist
->prlist_len
, sizeof(afs_int32
), IDCmp
);
2016 WhoIsThisWithName(struct rx_call
*acall
, struct ubik_trans
*at
, afs_int32
*aid
,
2019 afs_int32 islocal
= 1;
2020 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2021 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2022 struct rx_connection
*tconn
;
2024 char tcell
[MAXKTCREALMLEN
];
2025 char name
[MAXKTCNAMELEN
];
2026 char inst
[MAXKTCNAMELEN
];
2031 tconn
= rx_ConnectionOf(acall
);
2032 code
= rx_SecurityClassOf(tconn
);
2033 if (code
== RX_SECIDX_NULL
)
2035 else if (code
== RX_SECIDX_VAB
) {
2036 goto done
; /* no longer supported */
2037 } else if (code
== RX_SECIDX_KAD
) {
2038 if ((code
= rxkad_GetServerInfo(rx_ConnectionOf(acall
), NULL
, NULL
,
2039 name
, inst
, tcell
, NULL
)))
2043 code
= afsconf_IsLocalRealmMatch(prdir
, &islocal
, name
, inst
, tcell
);
2047 strncpy(vname
, name
, sizeof(vname
));
2048 if ((ilen
= strlen(inst
))) {
2049 if (strlen(vname
) + 1 + ilen
>= sizeof(vname
))
2052 strcat(vname
, inst
);
2055 if (strlen(vname
) + strlen(tcell
) + 1 >= sizeof(vname
))
2058 strcat(vname
, tcell
);
2059 lcstring(vname
, vname
, sizeof(vname
));
2060 NameToID(at
, vname
, aid
);
2062 strcpy(aname
, vname
);
2066 if (strcmp(AUTH_SUPERUSER
, vname
) == 0)
2067 *aid
= SYSADMINID
; /* special case for the fileserver */
2069 lcstring(vname
, vname
, sizeof(vname
));
2070 code
= NameToID(at
, vname
, aid
);
2074 if (code
&& !pr_noAuth
)