ptserver: move allocation out of put_prentries() into listEntries()
[openafs.git] / src / ptserver / ptprocs.c
index a3ad9c5..90416ab 100644 (file)
@@ -62,6 +62,7 @@
 #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>
 
@@ -109,7 +110,7 @@ static afs_int32 listEntry(struct rx_call *call, afs_int32 aid,
 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,
@@ -438,15 +439,6 @@ dumpEntry(struct rx_call *call, afs_int32 apos, struct prdebugentry *aentry,
     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;
@@ -1448,6 +1440,7 @@ SPR_ListEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
     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)
@@ -1478,6 +1471,12 @@ listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
 
     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);
@@ -1494,11 +1493,9 @@ listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
        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;
@@ -1520,29 +1517,14 @@ listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
     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 =
@@ -1558,7 +1540,6 @@ put_prentries(struct prentry *tentry, prentries *bulkentries)
     entry->count = tentry->count;
     strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
     bulkentries->prentries_len++;
-    return 0;
 }
 
 afs_int32
@@ -1795,10 +1776,6 @@ listSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
     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);
@@ -2052,15 +2029,15 @@ WhoIsThisWithName(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid,
            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)
@@ -2069,6 +2046,25 @@ WhoIsThisWithName(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid,
            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)