#include <rx/xdr.h>
#include <rx/rx.h>
#include <rx/rxkad.h>
+#include <rx/rx_identity.h>
#include <afs/auth.h>
#include <afs/cellconfig.h>
static afs_int32 listEntries(struct rx_call *call, afs_int32 flag,
afs_int32 startindex, prentries *bulkentries,
afs_int32 *nextstartindex, afs_int32 *cid);
-static afs_int32 put_prentries(struct prentry *tentry, prentries *bulkentries);
+static void put_prentries(struct prentry *tentry, prentries *bulkentries);
static afs_int32 changeEntry(struct rx_call *call, afs_int32 aid, char *name,
afs_int32 oid, afs_int32 newid, afs_int32 *cid);
static afs_int32 setFieldsEntry(struct rx_call *call, afs_int32 id,
if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
ABORT_WITH(tt, PRPERM);
- /* Since prdebugentry is in the form of a prentry not a coentry, we will
- * return the coentry slots in network order where the string is. */
-#if 0
- if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
- code = pr_ReadCoEntry(tt, 0, apos, aentry);
- if (code)
- ABORT_WITH(tt, code);
- }
-#endif
code = ubik_EndTrans(tt);
if (code)
return code;
&& !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
ABORT_WITH(tt, PRPERM);
+ if (restricted && !IsAMemberOf(tt, *cid, SYSADMINID)) {
+ ABORT_WITH(tt, PRPERM);
+ }
+
/* Delete each continuation block as a separate transaction so that no one
* transaction become to large to complete. */
nptr = tentry.next;
return code;
}
+#define PR_MAXENTRIES 500
static afs_int32
listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
prentries *bulkentries, afs_int32 *nextstartindex, afs_int32 *cid)
eof = ntohl(cheader.eofPtr) - sizeof(cheader);
maxentries = eof / sizeof(struct prentry);
+
+ bulkentries->prentries_val = calloc(PR_MAXENTRIES,
+ sizeof(bulkentries->prentries_val[0]));
+ if (!bulkentries->prentries_val)
+ ABORT_WITH(tt, PRNOMEM);
+
for (i = startindex; i < maxentries; i++) {
pos = i * sizeof(struct prentry) + sizeof(cheader);
code = pr_ReadEntry(tt, 0, pos, &tentry);
f = (tentry.flags & PRTYPE);
if (((flag & PRUSERS) && (f == 0)) || /* User entry */
((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
- code = put_prentries(&tentry, bulkentries);
- if (code == -1)
- break; /* Filled return array */
- if (code)
- goto done;
+ put_prentries(&tentry, bulkentries);
+ if (bulkentries->prentries_len >= PR_MAXENTRIES)
+ break;
}
}
code = 0;
return PRSUCCESS;
}
-#define PR_MAXENTRIES 500
-static afs_int32
+static void
put_prentries(struct prentry *tentry, prentries *bulkentries)
{
struct prlistentries *entry;
- if (bulkentries->prentries_val == 0) {
- bulkentries->prentries_len = 0;
- bulkentries->prentries_val = malloc(PR_MAXENTRIES *
- sizeof(struct prlistentries));
- if (!bulkentries->prentries_val) {
- return (PRNOMEM);
- }
- }
-
- if (bulkentries->prentries_len >= PR_MAXENTRIES) {
- return (-1);
- }
-
entry = bulkentries->prentries_val;
entry += bulkentries->prentries_len;
- memset(entry, 0, sizeof(*entry));
entry->flags = tentry->flags >> PRIVATE_SHIFT;
if (entry->flags == 0) {
entry->flags =
entry->count = tentry->count;
strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
bulkentries->prentries_len++;
- return 0;
}
afs_int32
if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
ABORT_WITH(tt, PRPERM);
- code = ubik_SetLock(tt, 1, 1, LOCKREAD);
- if (code)
- ABORT_WITH(tt, code);
-
temp = FindByID(tt, aid);
if (!temp)
ABORT_WITH(tt, PRNOENT);
strcat(vname, inst);
}
if (!islocal) {
- if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
+ if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
goto done;
- strcat(vname, "@");
- strcat(vname, tcell);
- lcstring(vname, vname, sizeof(vname));
- NameToID(at, vname, aid);
- if (aname)
+ strcat(vname, "@");
+ strcat(vname, tcell);
+ lcstring(vname, vname, sizeof(vname));
+ NameToID(at, vname, aid);
+ if (aname)
strcpy(aname, vname);
- return 2;
+ return 2;
}
if (strcmp(AUTH_SUPERUSER, vname) == 0)
lcstring(vname, vname, sizeof(vname));
code = NameToID(at, vname, aid);
}
+
+ } else {
+ /* If we reached here, we don't understand the security class of the
+ * given call. But if the calling user is RX_ID_SUPERUSER, we can check
+ * that without even needing to understand the security class. Remember
+ * to only check for RX_ID_SUPERUSER specifically; we do not use
+ * SYSADMINID for other admins. */
+ int is_super;
+ struct rx_identity *id = NULL;
+ is_super = afsconf_SuperIdentity(prdir, acall, &id);
+ if (is_super && id->kind == RX_ID_SUPERUSER) {
+ *aid = SYSADMINID;
+ code = 0;
+ } else {
+ code = -1;
+ }
+ if (id != NULL) {
+ rx_identity_free(&id);
+ }
}
done:
if (code && !pr_noAuth)