windows-aclent-remove-extraneous-code-20071024
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 25 Oct 2007 05:47:23 +0000 (05:47 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 25 Oct 2007 05:47:23 +0000 (05:47 +0000)
Microsoft provided a dump showing cm_data.aclLRUEndp == NULL in
GetFreeACLEnt().  Couldn't find any reason why that would be true.
However, there is extraneous code that manipulates the value of
aclLRUEndp when it should be left to osi_QRemoveHT() to update
the pointer values.

Also add an additional explicit test for aclLRUEndp == NULL in
GetFreeACLEnt().

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_aclent.c
src/WINNT/afsd/cm_btree.c
src/WINNT/afsd/cm_btree.h
src/WINNT/afsd/cm_user.c

index acec6c1..f75679f 100644 (file)
@@ -1362,7 +1362,6 @@ int afsd_InitSMB(char **reasonP, void *aMBfunc)
 
 void afsd_printStack(HANDLE hThread, CONTEXT *c)
 {
-#if defined(_X86_)
     HANDLE hProcess = GetCurrentProcess();
     int frameNum;
 #if defined(_AMD64_)
@@ -1409,9 +1408,9 @@ void afsd_printStack(HANDLE hThread, CONTEXT *c)
 #error The STACKFRAME initialization in afsd_printStack() for this platform
 #error must be properly configured
 #elif defined(_AMD64_)
-    s.AddrPC.Offset = 0;
+    s.AddrPC.Offset = c->Rip;
     s.AddrPC.Mode = AddrModeFlat;
-    s.AddrFrame.Offset = 0;
+    s.AddrFrame.Offset = c->Rbp;
     s.AddrFrame.Mode = AddrModeFlat;
 #else
     s.AddrPC.Offset = c->Eip;
@@ -1511,7 +1510,6 @@ void afsd_printStack(HANDLE hThread, CONTEXT *c)
   
     SymCleanup(hProcess);
     GlobalFree(pSym);
-#endif /* _X86_ */
 }
 
 #ifdef _DEBUG
@@ -1661,6 +1659,9 @@ LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep)
 #if defined(_X86)    
         ep->ContextRecord->Eip++;
 #endif
+#if defined(_AMD64_)
+        ep->ContextRecord->Rip++;
+#endif
         return EXCEPTION_CONTINUE_EXECUTION;
     }
     else
index 5ae9cf3..7a14e26 100644 (file)
@@ -90,9 +90,6 @@ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, afs_uint32 *rightsp)
             } else {
                 *rightsp = aclp->randomAccess;
                if (cm_data.aclLRUp != aclp) {
-                   if (cm_data.aclLRUEndp == aclp)
-                       cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
-
                    /* move to the head of the LRU queue */
                    osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
                    osi_QAddH((osi_queue_t **) &cm_data.aclLRUp,
@@ -121,8 +118,10 @@ static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp)
     if (cm_data.aclLRUp == NULL)
         osi_panic("empty aclent LRU", __FILE__, __LINE__);
 
+    if (cm_data.aclLRUEndp == NULL)
+        osi_panic("inconsistent aclent LRUEndp == NULL", __FILE__, __LINE__);
+
     aclp = cm_data.aclLRUEndp;
-    cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
     osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
 
     if (aclp->backp && scp != aclp->backp) {
index 884f9fd..7d86371 100644 (file)
@@ -1743,6 +1743,9 @@ long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp)
 
     bplus_build_time += (end.QuadPart - start.QuadPart);
 
+#if 0
+    cm_BPlusDirEnumTest(scp, 1);
+#endif
     return rc;
 }
 
@@ -1802,4 +1805,260 @@ void cm_BPlusDumpStats(void)
     afsi_log("            Build: %-16I64d", bplus_build_time);
     afsi_log("             Free: %-16I64d", bplus_free_time);
 }
+
+static cm_direnum_t * 
+cm_BPlusEnumAlloc(afs_uint32 entries)
+{
+    cm_direnum_t * enump;
+    size_t        size;
+
+    if (entries == 0)
+       return NULL;
+
+    size = sizeof(cm_direnum_t)+(entries-1)*sizeof(cm_direnum_entry_t);
+    enump = (cm_direnum_t *)malloc(size);
+    memset(enump, 0, size);
+    enump->count = entries;
+    return enump;
+}
+
+long 
+cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, 
+                     char * maskp, cm_direnum_t **enumpp)
+{
+    afs_uint32 count = 0, slot, numentries;
+    Nptr leafNode = NONODE, nextLeafNode;
+    Nptr firstDataNode, dataNode, nextDataNode;
+    cm_direnum_t * enump;
+    long rc = 0;
+    char buffer[512];
+
+    OutputDebugString("cm_BPlusDirEnumerate start");
+
+    /* Read lock the bplus tree so the data can't change */
+    if (!locked)
+       lock_ObtainRead(&scp->dirlock);
+
+    if (scp->dirBplus == NULL) {
+       OutputDebugString("cm_BPlusDirEnumerate No BPlus Tree");
+       goto done;
+    }
+
+    /* Compute the number of entries */
+    for (count = 0, leafNode = getleaf(scp->dirBplus); leafNode; leafNode = nextLeafNode) {
+
+       for ( slot = 1, numentries = numentries(leafNode); slot <= numentries; slot++) {
+           firstDataNode = getnode(leafNode, slot);
+
+           for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) {
+                if (maskp == NULL) {
+                    /* name is in getdatakey(dataNode) */
+                    if (getdatavalue(dataNode).longname != NULL ||
+                        cm_Is8Dot3(getdatakey(dataNode).name))
+                        count++;
+                } else {
+                   if (cm_Is8Dot3(getdatakey(dataNode).name) && 
+                        smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) ||
+                        getdatavalue(dataNode).longname == NULL &&
+                        smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD))
+                        count++;
+                }
+               nextDataNode = getdatanext(dataNode);
+           }
+       }
+
+       nextLeafNode = getnextnode(leafNode);
+    }   
+
+    sprintf(buffer, "BPlusTreeEnumerate count = %d", count);
+    OutputDebugString(buffer);
+
+    /* Allocate the enumeration object */
+    enump = cm_BPlusEnumAlloc(count);
+    if (enump == NULL) {
+       OutputDebugString("cm_BPlusDirEnumerate Alloc failed");
+       rc = ENOMEM;
+       goto done;
+    }
+       
+    /* Copy the name and fid for each longname entry into the enumeration */
+    for (count = 0, leafNode = getleaf(scp->dirBplus); leafNode; leafNode = nextLeafNode) {
+
+       for ( slot = 1, numentries = numentries(leafNode); slot <= numentries; slot++) {
+           firstDataNode = getnode(leafNode, slot);
+
+           for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) {
+                char * name;
+                int hasShortName;
+                int includeIt = 0;
+
+                if (maskp == NULL) {
+                    if (getdatavalue(dataNode).longname != NULL ||
+                         cm_Is8Dot3(getdatakey(dataNode).name)) 
+                    {
+                        includeIt = 1;
+                    }
+                } else {
+                   if (cm_Is8Dot3(getdatakey(dataNode).name) && 
+                        smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) ||
+                        getdatavalue(dataNode).longname == NULL &&
+                         smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD)) 
+                    {
+                        includeIt = 1;
+                    }
+                }
+
+                if (includeIt) {
+                    if (getdatavalue(dataNode).longname) {
+                        name = strdup(getdatavalue(dataNode).longname);
+                        hasShortName = 1;
+                    } else {
+                        name = strdup(getdatakey(dataNode).name);
+                        hasShortName = 0;
+                    }
+
+                    if (name == NULL) {
+                        OutputDebugString("cm_BPlusDirEnumerate strdup failed");
+                        rc = ENOMEM;
+                        goto done;
+                    }
+                    enump->entry[count].name = name;
+                    enump->entry[count].fid  = getdatavalue(dataNode).fid;
+                    if (hasShortName)
+                        strncpy(enump->entry[count].shortName, getdatakey(dataNode).name, 
+                                sizeof(enump->entry[count].shortName));
+                    else
+                        enump->entry[count].shortName[0] = '\0';
+                    count++;
+                }
+               nextDataNode = getdatanext(dataNode);
+           }
+       }
+
+       nextLeafNode = getnextnode(leafNode);
+    }   
+
+  done:
+    if (!locked)
+       lock_ReleaseRead(&scp->dirlock);
+
+    /* if we failed, cleanup any mess */
+    if (rc != 0) {
+       OutputDebugString("cm_BPlusDirEnumerate rc != 0");
+       if (enump) {
+           for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
+               free(enump->entry[count].name);
+           }
+           free(enump);
+           enump = NULL;
+       }
+    }
+
+    OutputDebugString("cm_BPlusDirEnumerate end");
+    *enumpp = enump;
+    return rc;
+}
+
+long 
+cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp)
+{      
+    if (enump == NULL || entrypp == NULL || enump->next > enump->count) {
+       if (entrypp)
+           *entrypp = NULL;
+       OutputDebugString("cm_BPlusDirNextEnumEntry invalid input");
+       return CM_ERROR_INVAL;                        \
+    }
+
+    *entrypp = &enump->entry[enump->next++];
+    if ( enump->next == enump->count ) {
+       OutputDebugString("cm_BPlusDirNextEnumEntry STOPNOW");
+       return CM_ERROR_STOPNOW;
+    }
+    else {
+       OutputDebugString("cm_BPlusDirNextEnumEntry SUCCESS");
+       return 0;
+    }
+}
+
+long 
+cm_BPlusDirFreeEnumeration(cm_direnum_t *enump)
+{
+    afs_uint32 count;
+
+    OutputDebugString("cm_BPlusDirFreeEnumeration");
+
+    if (enump) {
+       for ( count = 0; count < enump->count && enump->entry[count].name; count++ ) {
+           free(enump->entry[count].name);
+       }
+       free(enump);
+    }
+    return 0;
+}
+
+long
+cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked)
+{
+    cm_direnum_t *      enump = NULL;
+    cm_direnum_entry_t * entryp;
+    long                code;
+
+    OutputDebugString("cm_BPlusDirEnumTest start");
+
+    for (code = cm_BPlusDirEnumerate(dscp, locked, NULL, &enump); code == 0; ) {
+       code = cm_BPlusDirNextEnumEntry(enump, &entryp);
+       if (code == 0 || code == CM_ERROR_STOPNOW) {
+           char buffer[1024];
+           cm_scache_t *scp;
+           char * type = "ScpNotFound";
+           afs_int32 dv = -1;
+
+           scp = cm_FindSCache(&entryp->fid);
+           if (scp) {
+               switch (scp->fileType) {
+               case CM_SCACHETYPE_FILE :
+                   type = "File";
+                   break;
+               case CM_SCACHETYPE_DIRECTORY    :
+                   type = "Directory";
+                   break;
+               case CM_SCACHETYPE_SYMLINK      :
+                   type = "Symlink";
+                   break;
+               case CM_SCACHETYPE_MOUNTPOINT:
+                   type = "MountPoint";
+                   break;
+               case CM_SCACHETYPE_DFSLINK   :
+                   type = "Dfs";
+                   break;
+               case CM_SCACHETYPE_INVALID   :
+                   type = "Invalid";
+                   break;
+               default:
+                   type = "Unknown";
+                   break;
+               }
+
+               dv = scp->dataVersion;
+           cm_ReleaseSCache(scp);
+           }
+
+           sprintf(buffer, "'%s' Fid = (%d,%d,%d,%d) Short = '%s' Type %s DV %d",
+                   entryp->name,
+                   entryp->fid.cell, entryp->fid.volume, entryp->fid.vnode, entryp->fid.unique,
+                   entryp->shortName,
+                   type, 
+                   dv);
+
+           OutputDebugString(buffer);
+       }
+    }
+
+    if (enump)
+       cm_BPlusDirFreeEnumeration(enump);
+
+    OutputDebugString("cm_BPlusDirEnumTest end");
+
+    return 0;
+}
 #endif /* USE_BPLUS */
index b157e58..61ad785 100644 (file)
@@ -145,6 +145,25 @@ long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp);
 void cm_BPlusDumpStats(void);
 int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock);
 
+
+/******************* directory enumeration operations ****************/
+typedef struct cm_direnum_entry {
+    char *     name;
+    cm_fid_t   fid;
+    char        shortName[13];
+} cm_direnum_entry_t;
+
+typedef struct cm_direnum {
+    afs_uint32         count;
+    afs_uint32         next;
+    cm_direnum_entry_t         entry[1];
+} cm_direnum_t;
+
+long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, char *maskp, cm_direnum_t **enumpp);
+long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp);
+long cm_BPlusDirFreeEnumeration(cm_direnum_t *enump);
+long cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked);
+
 extern afs_uint32 bplus_free_tree;
 extern afs_uint32 bplus_dv_error;
 extern afs_uint64 bplus_free_time;
index 2c6b174..4e4f4ea 100644 (file)
@@ -194,3 +194,20 @@ void cm_CheckTokenCache(time_t now)
     }
     lock_ReleaseWrite(&smb_rctLock);
 }
+
+#ifdef USE_ROOT_TOKENS
+/*
+ * Service/Parameters/RootTokens/<cellname>/
+ * -> UseLSA
+ * -> Keytab (required if UseLSA is 0)
+ * -> Principal (required if there is more than one principal in the keytab)
+ * -> Realm (required if realm is not upper-case of <cellname>
+ * -> RequireEncryption 
+ */
+
+void
+cm_RefreshRootTokens(void)
+{
+
+}
+#endif