OPENAFS-SA-2018-002 ptserver: prevent PR_ListEntries information leak
[openafs.git] / src / ptserver / ptprocs.c
index 462c5af..4ce1cbf 100644 (file)
@@ -161,6 +161,8 @@ CreateOK(struct ubik_trans *ut, afs_int32 cid, afs_int32 oid, afs_int32 flag,
                return 0;
        }
     } else {                   /* creating a user */
+       if (oid == ANONYMOUSID)
+           return 0;
        if (!admin && !pr_noAuth)
            return 0;
     }
@@ -312,6 +314,7 @@ newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
     afs_int32 code;
     struct ubik_trans *tt;
     int admin;
+    int foreign = 0;
     char cname[PR_MAXNAMELEN];
     stolower(aname);
 
@@ -324,18 +327,31 @@ newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
      * automatic id assignment.
      */
     code = WhoIsThisWithName(call, tt, cid, cname);
-    if (code != 2) {           /* 2 specifies that this is a foreign cell request */
-       if (code)
-           ABORT_WITH(tt, PRPERM);
-       admin = IsAMemberOf(tt, *cid, SYSADMINID);
-    } else {
-       admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
-       oid = *cid = SYSADMINID;
+    if (code && code != 2)
+       ABORT_WITH(tt, PRPERM);
+    admin = IsAMemberOf(tt, *cid, SYSADMINID);
+    if (code == 2 /* foreign cell request */) {
+       foreign = 1;
+
+       if (!restricted && (strcmp(aname, cname) == 0)) {
+           /* can't autoregister while providing an owner id */
+           if (oid != 0)
+               ABORT_WITH(tt, PRPERM);
+
+           admin = 1;
+           oid = SYSADMINID;
+       }
     }
     if (!CreateOK(tt, *cid, oid, flag, admin))
        ABORT_WITH(tt, PRPERM);
 
     code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
+    /*
+     * If this was an autoregistration then be sure to audit log
+     * the proper id as the creator.
+     */
+    if (foreign && code == 0 && *aid > 0)
+       *cid = *aid;
     if (code != PRSUCCESS)
        ABORT_WITH(tt, code);
 
@@ -572,7 +588,7 @@ nameToID(struct rx_call *call, namelist *aname, idlist *aid)
 
        if (cell && *cell) {
            code = afsconf_IsLocalRealmMatch(prdir, &islocal, nameinst, NULL, cell);
-           ViceLog(0,
+           ViceLog(125,
                    ("PTS_NameToID: afsconf_IsLocalRealmMatch(); code=%d, nameinst=%s, cell=%s\n",
                     code, nameinst, cell));
        }
@@ -635,7 +651,7 @@ idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid)
        return 0;
     if (size < 0 || size > INT_MAX / PR_MAXNAMELEN)
        return PRTOOMANY;
-    aname->namelist_val = malloc(size * PR_MAXNAMELEN);
+    aname->namelist_val = calloc(size, PR_MAXNAMELEN);
     aname->namelist_len = 0;
     if (aname->namelist_val == 0)
        return PRNOMEM;
@@ -1222,7 +1238,7 @@ SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist,
 
     code = getHostCPS(call, ahost, alist, over, &cid);
     osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, htonl(ahost), AUD_END);
-    ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d\n", code, ahost));
+    ViceLog(125, ("PTS_GetHostCPS: code %d ahost %u (0x%x)\n", code, ahost, ahost));
     return code;
 }
 
@@ -1522,6 +1538,7 @@ put_prentries(struct prentry *tentry, prentries *bulkentries)
     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 =
@@ -1536,7 +1553,6 @@ put_prentries(struct prentry *tentry, prentries *bulkentries)
     entry->nusers = tentry->nusers;
     entry->count = tentry->count;
     strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
-    memset(entry->reserved, 0, sizeof(entry->reserved));
     bulkentries->prentries_len++;
     return 0;
 }