From: Jeffrey Altman Date: Fri, 9 Sep 2005 20:47:03 +0000 (+0000) Subject: windows-detect-uuid-cloning-20050909 X-Git-Tag: openafs-devel-1_5_0~331 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=870d414e6c3765ff52a65d1c06fbc5ddfb254f17 windows-detect-uuid-cloning-20050909 Begin to store the Disk Volume Serial Number and Machine SID in the AFSCache file for use in detecting system clones. Clones must get a new UUID for the AFS Client. --- diff --git a/src/WINNT/afsd/cm_memmap.c b/src/WINNT/afsd/cm_memmap.c index 50ae0b4..a9ad74f 100644 --- a/src/WINNT/afsd/cm_memmap.c +++ b/src/WINNT/afsd/cm_memmap.c @@ -1,4 +1,5 @@ #include +#include #include "afsd.h" #include "cm_memmap.h" @@ -408,6 +409,179 @@ cm_ValidateMappedMemory(char * cachePath) return 0; } +DWORD +GetVolSerialNumber(char * cachePath) +{ + char rootpath[128]; + int i = 0; + DWORD serial = 0; + + if ( cachePath[0] == '\\' && cachePath[1] == '\\' || + cachePath[0] == '/' && cachePath[1] == '/' ) + { + rootpath[0]=rootpath[1]='\\'; + for ( i=2; cachePath[i]; i++ ) { + rootpath[i] = cachePath[i]; + if ( cachePath[i] == '\\' || cachePath[i] == '/' ) { + i++; + break; + } + } + } else if ( cachePath[1] == ':' ) { + rootpath[0] = cachePath[0]; + rootpath[1] = ':'; + i = 2; + } + + for ( ; cachePath[i]; i++ ) { + rootpath[i] = cachePath[i]; + if ( cachePath[i] == '\\' || cachePath[i] == '/' ) { + i++; + break; + } + } + rootpath[i] = '\0'; + + GetVolumeInformation(rootpath, NULL, 0, &serial, NULL, NULL, NULL, 0); + return serial; +} + +BOOL GetTextualSid( PSID pSid, PBYTE TextualSid, LPDWORD lpdwBufferLen ) +{ + PSID_IDENTIFIER_AUTHORITY psia; + DWORD dwSubAuthorities; + DWORD dwSidRev=SID_REVISION; + DWORD dwCounter; + DWORD dwSidSize; + + // Validate the binary SID. + if(!IsValidSid(pSid)) + return FALSE; + + // Get the identifier authority value from the SID. + + psia = GetSidIdentifierAuthority(pSid); + + // Get the number of subauthorities in the SID. + + dwSubAuthorities = *GetSidSubAuthorityCount(pSid); + + // Compute the buffer length. + // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL + + dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1); + + // Check input buffer length. + // If too small, indicate the proper size and set the last error. + + if (*lpdwBufferLen < dwSidSize) + { + *lpdwBufferLen = dwSidSize; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + // Add 'S' prefix and revision number to the string. + dwSidSize=sprintf(TextualSid, "S-%lu-", dwSidRev ); + + // Add a SID identifier authority to the string. + if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) + { + dwSidSize+=sprintf(TextualSid + strlen(TextualSid), + "0x%02hx%02hx%02hx%02hx%02hx%02hx", + (USHORT)psia->Value[0], + (USHORT)psia->Value[1], + (USHORT)psia->Value[2], + (USHORT)psia->Value[3], + (USHORT)psia->Value[4], + (USHORT)psia->Value[5]); + } + else + { + dwSidSize+=sprintf(TextualSid + strlen(TextualSid), + "%lu", + (ULONG)(psia->Value[5] ) + + (ULONG)(psia->Value[4] << 8) + + (ULONG)(psia->Value[3] << 16) + + (ULONG)(psia->Value[2] << 24) ); + } + + // Add SID subauthorities to the string. + // + for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) + { + dwSidSize+=sprintf(TextualSid + dwSidSize, "-%lu", + *GetSidSubAuthority(pSid, dwCounter) ); + } + + return TRUE; +} + +PBYTE +IsSubAuthValid( PBYTE SidData, DWORD SidLength ) +{ + PBYTE sidPtr; + + sidPtr = NULL; + if ( SidLength % sizeof(DWORD) == 0 ) { + for ( sidPtr = SidData + SidLength - 5*sizeof(DWORD); + sidPtr >= SidData; + sidPtr -= sizeof(DWORD) ) + if ( ((PDWORD)sidPtr)[1] == 0x05000000 && + ((PDWORD)sidPtr)[2] == 0x00000015 ) + break; + if ( sidPtr < SidData ) + sidPtr = NULL; + } + return sidPtr; +} + +BOOL +GetMachineSid(PBYTE SidBuffer, DWORD SidSize) +{ + HKEY hKey; + PBYTE vData; + DWORD dwType; + DWORD dwLen; + PBYTE pSid; + DWORD dwStatus; + + if (!SidBuffer) + return FALSE; + + // + // Read the last subauthority of the current computer SID + // + if( RegOpenKey( HKEY_LOCAL_MACHINE, "SECURITY\\SAM\\Domains\\Account", + &hKey) != ERROR_SUCCESS ) { + return FALSE; + } + dwLen = 0; + vData = NULL; + RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen ); + vData = (PBYTE) malloc( dwLen ); + dwStatus = RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen ); + RegCloseKey( hKey ); + if( dwStatus != ERROR_SUCCESS ) { + return FALSE; + } + + // + // Make sure that we're dealing with a SID we understand + // + pSid = IsSubAuthValid( vData, dwLen ); + + if( !pSid || SidSize < dwLen - (pSid - vData)) { + free(vData); + return FALSE; + } + + memset(SidBuffer, 0, SidSize); + memcpy(SidBuffer, pSid, dwLen - (pSid - vData) ); + free(vData); + return TRUE; +} + int cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chunkSize, DWORD cacheBlocks) { @@ -417,10 +591,17 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu DWORD mappingSize; DWORD maxVols = stats/2; DWORD maxCells = stats/4; + DWORD volumeSerialNumber = 0; + DWORD sidStringSize = 0; + DWORD rc; + CHAR machineSid[6 * sizeof(DWORD)]=""; char * baseAddress = NULL; cm_config_data_t * config_data_p; char * p; + volumeSerialNumber = GetVolSerialNumber(cachePath); + GetMachineSid(machineSid, sizeof(machineSid)); + mappingSize = ComputeSizeOfMappingFile(stats, maxVols, maxCells, chunkSize, cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE); if ( !virtualCache ) { @@ -644,10 +825,52 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chu cm_data.bufDataBaseAddress = (char *) baseAddress; baseAddress += ComputeSizeOfDataBuffers(cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE); cm_data.bufEndOfData = (char *) baseAddress; - cm_data.fakeDirVersion = 0x8; - UuidCreate((UUID *)&cm_data.Uuid); + cm_data.volSerialNumber = volumeSerialNumber; + memcpy(cm_data.Sid, machineSid, sizeof(machineSid)); + } else { + int gennew = 0; + + if ( volumeSerialNumber == 0 || volumeSerialNumber != cm_data.volSerialNumber ) { + gennew = 1; + afsi_log("Volume serial number change, generating new UUID"); + afsi_log("Old volume Serial Number: 0x%x", cm_data.volSerialNumber); + } else if ( machineSid[0] && memcmp(machineSid, cm_data.Sid, sizeof(machineSid))) { + gennew = 1; + afsi_log("Machine Sid changed, generating new UUID"); + GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize ); + if (sidStringSize) { + p = malloc(sidStringSize * sizeof(TCHAR)); + if (p) { + rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize ); + afsi_log("Old Machine SID: %s", rc ? p : "unknown"); + free(p); + } + } else { + afsi_log("Old Machine SID: unknown"); + } + } + + if (gennew) { + UuidCreate((UUID *)&cm_data.Uuid); + cm_data.volSerialNumber = volumeSerialNumber; + memcpy(cm_data.Sid, machineSid, sizeof(machineSid)); + } + } + + afsi_log("Volume Serial Number: 0x%x", cm_data.volSerialNumber); + + GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize ); + if (sidStringSize) { + p = malloc(sidStringSize * sizeof(TCHAR)); + if (p) { + rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize ); + afsi_log("Machine SID: %s", rc ? p : "unknown"); + free(p); + } + } else { + afsi_log("Machine SID: unknown"); } UuidToString((UUID *)&cm_data.Uuid, &p); diff --git a/src/WINNT/afsd/cm_memmap.h b/src/WINNT/afsd/cm_memmap.h index 45686c8..18e2e61 100644 --- a/src/WINNT/afsd/cm_memmap.h +++ b/src/WINNT/afsd/cm_memmap.h @@ -78,6 +78,8 @@ typedef struct cm_config_data { time_t mountRootGen; afsUUID Uuid; + DWORD volSerialNumber; + CHAR Sid[6 * sizeof(DWORD)]; } cm_config_data_t; extern cm_config_data_t cm_data; @@ -93,7 +95,7 @@ DWORD ComputeSizeOfDNLCache(void); DWORD ComputeSizeOfDataBuffers(DWORD cacheBlocks, DWORD blockSize); DWORD ComputeSizeOfDataHT(void); DWORD ComputeSizeOfDataHeaders(DWORD cacheBlocks); -DWORD ComputeSizeOfMappingFile(DWORD stats, DWORD chunkSize, DWORD cacheBlocks, DWORD blockSize); +DWORD ComputeSizeOfMappingFile(DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, DWORD cacheBlocks, DWORD blockSize); PSECURITY_ATTRIBUTES CreateCacheFileSA(); VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa); int cm_ShutdownMappedMemory(void);