]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-windows-misc-20050418
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 19 Apr 2005 06:11:17 +0000 (06:11 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 19 Apr 2005 06:11:17 +0000 (06:11 +0000)
Support for WinLogon "logon" event handler to allow use in multi-domain
forests with a cross-realm trust between a MIT realm and a root domain
with workstations in a sub-domain.

Add support for rx_StartClientThread

Prepare for allowing maxVolumes and maxCells to be configurable via
the registry.

src/WINNT/afsd/afskfw.c
src/WINNT/afsd/afskfw.h
src/WINNT/afsd/afslogon.c
src/WINNT/afsd/cm_aclent.c
src/WINNT/afsd/cm_daemon.c
src/WINNT/afsd/cm_memmap.c
src/WINNT/afsd/cm_vnodeops.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h
src/WINNT/afsd/smb3.c

index a1fc846c3f646411a9b71d57bfa4a5b231fe0216..adc85870551900d5b967f6f80f09efa4984f8cac 100644 (file)
@@ -3409,3 +3409,49 @@ BOOL KFW_probe_kdc(struct afsconf_cell * cellconfig)
     return serverReachable;
 }
 
+BOOL
+KFW_AFS_get_lsa_principal(char * szUser, DWORD *dwSize)
+{
+    krb5_context   ctx = 0;
+    krb5_error_code code;
+    krb5_ccache mslsa_ccache=0;
+    krb5_principal princ = 0;
+    char * pname = 0;
+    BOOL success = 0;
+
+    if (!KFW_is_available())
+        return FALSE;
+
+    if (code = pkrb5_init_context(&ctx))
+        goto cleanup;
+
+    if (code = pkrb5_cc_resolve(ctx, "MSLSA:", &mslsa_ccache))
+        goto cleanup;
+
+    if (code = pkrb5_cc_get_principal(ctx, mslsa_ccache, &princ))
+        goto cleanup;
+
+    if (code = pkrb5_unparse_name(ctx, princ, &pname))
+        goto cleanup;
+
+    if ( strlen(pname) < *dwSize ) {
+        strncpy(szUser, pname, *dwSize);
+        szUser[*dwSize-1] = '\0';
+        success = 1;
+    }
+    *dwSize = strlen(pname);
+
+  cleanup:
+    if (pname)
+        pkrb5_free_unparsed_name(ctx, pname);
+
+    if (princ)
+        pkrb5_free_principal(ctx, princ);
+
+    if (mslsa_ccache)
+        pkrb5_cc_close(ctx, mslsa_ccache);
+
+    if (ctx)
+        pkrb5_free_context(ctx);
+    return success;
+}
\ No newline at end of file
index 995d038fb418edad7200b01177eba468c1a8f3d7..352e0595a506ca4f08bca3d762067799190056cb 100644 (file)
@@ -60,6 +60,7 @@ BOOL KFW_AFS_wait_for_service_start(void);
 BOOL KFW_probe_kdc(struct afsconf_cell *);
 int  KFW_AFS_get_cellconfig(char *, struct afsconf_cell *, char *);
 void KFW_import_windows_lsa(void);
+BOOL KFW_AFS_get_lsa_principal(char *, DWORD *);
 
 /* From afs/krb_prot.h */
 /* values for kerb error codes */
index 0e9788ee2cd865d62b090a2f5aa1ebebaa0ac37f..34833aa800a53f51a7068c63286426764ecc9a41 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <winsock2.h>
 #include <lm.h>
+#include <nb30.h>
 
 #include <afs/param.h>
 #include <afs/stds.h>
@@ -26,6 +27,7 @@
 #include "cm_config.h"
 #include "krb.h"
 #include "afskfw.h"
+#include "lanahelper.h"
 
 #include <WINNT\afsreg.h>
 
@@ -561,8 +563,6 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     }
 
     if (hkTemp) {
-        HRESULT hr;
-        size_t len;
         CHAR * thesecells;
 
         /* dwSize still has the size of the required buffer in bytes. */
@@ -988,12 +988,11 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
     DWORD  len = 1024;
     PTOKEN_USER  tokenUser = NULL;
     DWORD  retLen;
-    HANDLE hToken;
 
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
-    DebugEvent0("AFS_Logoff_Event - Starting");
+    DebugEvent0("AFS_Logoff_Event - Start");
 
     if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
     {
@@ -1002,7 +1001,7 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
 
             if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
             {
-                DebugEvent("GetTokenInformation failed: GLE = %lX", GetLastError());
+                DebugEvent("AFS_Logoff_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
             }
         }
     }
@@ -1020,7 +1019,7 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
     }
     
     if (strlen(profileDir)) {
-        DebugEvent("Profile Directory: %s", profileDir);
+        DebugEvent("AFS_Logoff_Event - Profile Directory: %s", profileDir);
         if (!IsPathInAfs(profileDir)) {
             if (code = ktc_ForgetAllTokens())
                 DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
@@ -1035,5 +1034,92 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
 
     if ( tokenUser )
         LocalFree(tokenUser);
+
+    DebugEvent0("AFS_Logoff_Event - End");
 }   
 
+VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
+{
+    DWORD code;
+    TCHAR profileDir[1024] = TEXT("");
+    DWORD  len = 1024;
+    PTOKEN_USER  tokenUser = NULL;
+    DWORD  retLen;
+    HANDLE hToken;
+
+    WCHAR szUserW[128] = L"";
+    char  szUserA[128] = "";
+    char  szClient[MAX_PATH];
+    char szPath[MAX_PATH] = "";
+    NETRESOURCE nr;
+    DWORD res;
+    DWORD gle;
+    DWORD dwSize;
+
+    /* Make sure the AFS Libraries are initialized */
+    AfsLogonInit();
+
+    DebugEvent0("AFS_Logon_Event - Start");
+
+    if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
+    {
+        if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
+            tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
+
+            if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
+            {
+                DebugEvent("AFS_Logon_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
+            }
+        }
+    }
+
+    /* We can't use pInfo->Domain for the domain since in the cross realm case 
+     * this is source domain and not the destination domain.
+     */
+    if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
+        WCHAR Domain[64]=L"";
+        GetLocalShortDomain(Domain, sizeof(Domain));
+        if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
+            if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
+                GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
+        }
+    }
+    
+    if (strlen(profileDir)) {
+        DebugEvent("AFS_Logon_Event - Profile Directory: %s", profileDir);
+    } else {
+        DebugEvent0("AFS_Logon_Event - Unable to load profile");
+    }
+
+    dwSize = sizeof(szUserA);
+    if (!KFW_AFS_get_lsa_principal(szUserA, &dwSize)) {
+        StringCbPrintfW(szUserW, sizeof(szUserW), L"%s\\%s", pInfo->Domain, pInfo->UserName);
+        WideCharToMultiByte(CP_ACP, 0, szUserW, -1, szUserA, MAX_PATH, NULL, NULL);
+    }
+
+    if (szUserA[0])
+    {
+        lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
+        StringCbPrintf(szPath, sizeof(szPath), "\\\\%s", szClient);
+
+        DebugEvent("AFS_Logon_Event - Logon Name: %s", szUserA);
+
+        memset (&nr, 0x00, sizeof(NETRESOURCE));
+        nr.dwType=RESOURCETYPE_DISK;
+        nr.lpLocalName=0;
+        nr.lpRemoteName=szPath;
+        res = WNetAddConnection2(&nr,NULL,szUserA,0);
+        if (res)
+            DebugEvent("AFS_Logon_Event - WNetAddConnection2(%s,%s) failed: 0x%X",
+                        szPath, szUserA,res);
+        else
+            DebugEvent0("AFS_Logon_Event - WNetAddConnection2() succeeded");
+    } else 
+        DebugEvent("AFS_Logon_Event - User name conversion failed: GLE = 0x%X",GetLastError());
+
+    if ( tokenUser )
+        LocalFree(tokenUser);
+
+    DebugEvent0("AFS_Logon_Event - End");
+}
+
index b0f9a6dc69ff69ca9bff74189d7bdbc487a7706b..52e635e64ca07db13ac0315e578cda31ad9313e1 100644 (file)
@@ -37,17 +37,20 @@ static void CleanupACLEnt(cm_aclent_t * aclp)
     cm_aclent_t **laclpp;
         
     if (aclp->backp) {
-        /* 
-         * Remove the entry from the vnode's list 
-         */
-        laclpp = &aclp->backp->randomACLp;
-        for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) {
-            if (taclp == aclp) 
-                break;
+        if (aclp->backp->randomACLp) {
+            /* 
+             * Remove the entry from the vnode's list 
+             */
+            lock_AssertMutex(&aclp->backp->mx);
+            laclpp = &aclp->backp->randomACLp;
+            for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) {
+                if (taclp == aclp) 
+                    break;
+            }
+            if (!taclp) 
+                osi_panic("CleanupACLEnt race", __FILE__, __LINE__);
+            *laclpp = aclp->nextp;                     /* remove from vnode list */
         }
-        if (!taclp) 
-            osi_panic("CleanupACLEnt race", __FILE__, __LINE__);
-        *laclpp = aclp->nextp;                 /* remove from vnode list */
         aclp->backp = NULL;
     }
 
@@ -110,10 +113,11 @@ long cm_FindACLCache(cm_scache_t *scp, cm_user_t *userp, long *rightsp)
  * This function returns a free (not in the LRU queue) acl cache entry.
  * It must be called with the cm_aclLock lock held
  */
-static cm_aclent_t *GetFreeACLEnt(void)
+static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp)
 {
     cm_aclent_t *aclp;
-
+    cm_scache_t *ascp = 0;
+       
     if (cm_data.aclLRUp == NULL)
         osi_panic("empty aclent LRU", __FILE__, __LINE__);
 
@@ -121,8 +125,14 @@ static cm_aclent_t *GetFreeACLEnt(void)
     cm_data.aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
     osi_QRemove((osi_queue_t **) &cm_data.aclLRUp, &aclp->q);
 
+    if (aclp->backp && scp != aclp->backp) {
+        ascp = aclp->backp;
+        lock_ObtainMutex(&ascp->mx);
+    }
     CleanupACLEnt(aclp);
 
+    if (ascp)
+        lock_ReleaseMutex(&ascp->mx);
     return aclp;
 }
 
@@ -153,7 +163,7 @@ long cm_AddACLCache(cm_scache_t *scp, cm_user_t *userp, long rights)
      * and  reuse. But first try the free list and see if there's already 
      * someone there.
      */
-    aclp = GetFreeACLEnt();             /* can't fail, panics instead */
+    aclp = GetFreeACLEnt(scp);          /* can't fail, panics instead */
     osi_QAddH((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q);
     aclp->backp = scp;
     aclp->nextp = scp->randomACLp;
index 5a0106dcd794c31a7c05895ff314275cb4033ea7..81ba1459c0e191a2e127af68b38bd98a59ef2b89 100644 (file)
@@ -42,6 +42,8 @@ void cm_BkgDaemon(long parm)
 {
     cm_bkgRequest_t *rp;
 
+    rx_StartClientThread();
+
     lock_ObtainWrite(&cm_daemonLock);
     while (daemon_ShutdownFlag == 0) {
         if (!cm_bkgListEndp) {
index 89b387b9f3367d7ec50c39560c31e97560349567..8f63d7e0f46106a1f2c435e17c7b6c2d82dd54bd 100644 (file)
@@ -102,13 +102,13 @@ ComputeSizeOfDataHeaders(DWORD cacheBlocks)
 }
 
 DWORD
-ComputeSizeOfMappingFile(DWORD stats, DWORD chunkSize, DWORD cacheBlocks, DWORD blockSize)
+ComputeSizeOfMappingFile(DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, DWORD cacheBlocks, DWORD blockSize)
 {
     DWORD size;
     
     size       =  ComputeSizeOfConfigData()
-               +  ComputeSizeOfVolumes(stats/2
-               +  ComputeSizeOfCells(stats/4
+               +  ComputeSizeOfVolumes(maxVols
+               +  ComputeSizeOfCells(maxCells
                +  ComputeSizeOfACLCache(stats)
                +  ComputeSizeOfSCache(stats)
                +  ComputeSizeOfSCacheHT(stats)
@@ -417,11 +417,13 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu
     PSECURITY_ATTRIBUTES psa;
     int newFile = 1;
     DWORD mappingSize;
+    DWORD maxVols = stats/2;
+    DWORD maxCells = stats/4;
     char * baseAddress = NULL;
     cm_config_data_t * config_data_p;
     char * p;
 
-    mappingSize = ComputeSizeOfMappingFile(stats, chunkSize, cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE);
+    mappingSize = ComputeSizeOfMappingFile(stats, maxVols, maxCells, chunkSize, cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE);
 
     if ( !virtualCache ) {
         psa = CreateCacheFileSA();
@@ -529,6 +531,8 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu
             if ( config_data_p->size == sizeof(cm_config_data_t) &&
                  config_data_p->magic == CM_CONFIG_DATA_MAGIC &&
                  config_data_p->stats == stats &&
+                 config_data_p->maxVolumes == maxVols &&
+                 config_data_p->maxCells == maxCells &&
                  config_data_p->chunkSize == chunkSize &&
                  config_data_p->buf_nbuffers == cacheBlocks &&
                  config_data_p->blockSize == CM_CONFIGDEFAULT_BLOCKSIZE &&
@@ -622,9 +626,9 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu
 
         baseAddress += ComputeSizeOfConfigData();
         cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress;
-        baseAddress += ComputeSizeOfVolumes(stats/2);
+        baseAddress += ComputeSizeOfVolumes(maxVols);
         cm_data.cellBaseAddress = (cm_cell_t *) baseAddress;
-        baseAddress += ComputeSizeOfCells(stats/4);
+        baseAddress += ComputeSizeOfCells(maxCells);
         cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress;
         baseAddress += ComputeSizeOfACLCache(stats);
         cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress;
@@ -653,10 +657,10 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu
     RpcStringFree(&p);
 
     afsi_log("Initializing Volume Data");
-    cm_InitVolume(newFile, stats/2);
+    cm_InitVolume(newFile, maxVols);
 
     afsi_log("Initializing Cell Data");
-    cm_InitCell(newFile, stats/4);
+    cm_InitCell(newFile, maxCells);
 
     afsi_log("Initializing ACL Data");
     cm_InitACLCache(newFile, 2*stats);
index 7cdecdc7bc25a7d5e76059e44a143a5a14ffc279..20872df2b562f9247f045db485e3089f0fc8d983 100644 (file)
@@ -2692,7 +2692,7 @@ long cm_Lock(cm_scache_t *scp, unsigned char LockType,
               void **lockpp)
 {
     long code;
-    int Which = ((LockType & 0x1) ? LockRead : LockWrite);
+    int Which = ((LockType & LOCKING_ANDX_SHARED_LOCK) ? LockRead : LockWrite);
     AFSFid tfid;
     AFSVolSync volSync;
     cm_conn_t *connp;
@@ -2706,13 +2706,10 @@ long cm_Lock(cm_scache_t *scp, unsigned char LockType,
      */
     q = scp->fileLocks;
     while (q) {
-        fileLock = (cm_file_lock_t *)
-            ((char *) q - offsetof(cm_file_lock_t, fileq));
-        if ((fileLock->flags &
-              (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING))
-             == 0) {
-            if ((LockType & 0x1) == 0
-                 || (fileLock->LockType & 0x1) == 0)
+        fileLock = (cm_file_lock_t *)((char *) q - offsetof(cm_file_lock_t, fileq));
+        if ((fileLock->flags & (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING)) == 0) {
+            if ((LockType & LOCKING_ANDX_SHARED_LOCK) == 0 ||
+                (fileLock->LockType & LOCKING_ANDX_SHARED_LOCK) == 0)
                 return CM_ERROR_WOULDBLOCK;
             found = 1;
         }
@@ -2766,7 +2763,7 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType,
                 cm_user_t *userp, cm_req_t *reqp)
 {
     long code = 0;
-    int Which = ((LockType & 0x1) ? LockRead : LockWrite);
+    int Which = ((LockType & LOCKING_ANDX_SHARED_LOCK) ? LockRead : LockWrite);
     AFSFid tfid;
     AFSVolSync volSync;
     cm_conn_t *connp;
@@ -2795,7 +2792,7 @@ long cm_Unlock(cm_scache_t *scp, unsigned char LockType,
             ourLock = fileLock;
             qq = q;
         }
-        else if (fileLock->LockType & 0x1)
+        else if (fileLock->LockType & LOCKING_ANDX_SHARED_LOCK)
             anotherReader = 1;
         q = osi_QNext(q);
     }
@@ -2907,7 +2904,7 @@ void cm_CheckLocks()
 long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead)
 {
     long code;
-    int Which = ((oldFileLock->LockType & 0x1) ? LockRead : LockWrite);
+    int Which = ((oldFileLock->LockType & LOCKING_ANDX_SHARED_LOCK) ? LockRead : LockWrite);
     cm_scache_t *scp;
     AFSFid tfid;
     AFSVolSync volSync;
@@ -2939,8 +2936,8 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead)
         if ((fileLock->flags &
               (CM_FILELOCK_FLAG_INVALID | CM_FILELOCK_FLAG_WAITING))
              == 0) {
-            if ((oldFileLock->LockType & 0x1) == 0
-                 || (fileLock->LockType & 0x1) == 0) {
+            if ((oldFileLock->LockType & LOCKING_ANDX_SHARED_LOCK) == 0
+                 || (fileLock->LockType & LOCKING_ANDX_SHARED_LOCK) == 0) {
                 cm_ReleaseSCache(scp);
                 return CM_ERROR_WOULDBLOCK;
             }
index df404130f7788c7013aa7d178fc2b9cdc08b6275..f7f7c5e98df7ecb30cc8194548de01ab91d7e86b 100644 (file)
@@ -6956,6 +6956,8 @@ void smb_Server(VOID *parmp)
     dos_ptr dos_ncb;
 #endif /* DJGPP */
 
+    rx_StartClientThread();
+
     outncbp = GetNCB();
     outbufp = GetPacket();
     outbufp->ncbp = outncbp;
index 78a145d4f7a88a62d30a849ad977d8a6b4aa42ea..4a8e3cca0a87d4feb96f0b8b4b96b1332cebe52b 100644 (file)
@@ -365,6 +365,12 @@ typedef struct smb_fid {
 #define SMB_ATTR_NOT_CONTENT_INDEXED 0x2000
 #define SMB_ATTR_ENCRYPTED      0x4000
 
+#define LOCKING_ANDX_SHARED_LOCK        0x01 /* Read-only lock */
+#define LOCKING_ANDX_OPLOCK_RELEASE     0x02 /* Oplock break notification */
+#define LOCKING_ANDX_CHANGE_LOCKTYPE    0x04 /* Change lock type */
+#define LOCKING_ANDX_CANCEL_LOCK        0x08 /* Cancel outstanding request */
+#define LOCKING_ANDX_LARGE_FILES        0x10 /* Large file locking format */
+
 /* for tracking in-progress directory searches */
 typedef struct smb_dirSearch {
     osi_queue_t q;                     /* queue of all outstanding cookies */
index 13989b4908fd56029c742bf23dd706442a832d61..cbdf54fe49d91b92d4c5dd00ba1e5db13638096d 100644 (file)
@@ -4832,7 +4832,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     op = smb_GetSMBData(inp, NULL);
 
     for (i=0; i<NumberOfUnlocks; i++) {
-        if (LockType & 0x10) {
+        if (LockType & LOCKING_ANDX_LARGE_FILES) {
             /* Large Files */
             LOffset.HighPart = *((LONG *)(op + 4));
             LOffset.LowPart = *((DWORD *)(op + 8));
@@ -4857,7 +4857,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     }       
 
     for (i=0; i<NumberOfLocks; i++) {
-        if (LockType & 0x10) {
+        if (LockType & LOCKING_ANDX_LARGE_FILES) {
             /* Large Files */
             LOffset.HighPart = *((LONG *)(op + 4));
             LOffset.LowPart = *((DWORD *)(op + 8));