diff --git hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h index 1a97a34..dbae74e 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h +++ hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h @@ -213,6 +213,11 @@ DWORD SplitStringIgnoreSpaceW( __in WCHAR deli, __out size_t* count, __out_ecount(count) WCHAR*** out); +DWORD BuildPathRelativeToModule( + __in LPCWSTR relativePath, + __in size_t len, + __out_ecount(len) LPWSTR buffer); + DWORD GetConfigValue( __in LPCWSTR relativePath, __in LPCWSTR keyName, diff --git hadoop-common-project/hadoop-common/src/main/winutils/service.c hadoop-common-project/hadoop-common/src/main/winutils/service.c index 78260e3..3b9b566 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/service.c +++ hadoop-common-project/hadoop-common/src/main/winutils/service.c @@ -170,6 +170,146 @@ VOID ReportSvcMessage(WORD type, WORD category, DWORD msgId) { } //---------------------------------------------------------------------------- +// Function: IsSidInList +// +// Description: +// Finds a SID in an array of SID* +// +BOOL IsSidInList( + __in PSID trustee, + __in size_t cAllowedSids, + __in_ecount(cAllowedSids) PSID* allowedSids) { + + int crtSid = 0; + + for (crtSid = 0; crtSid < cAllowedSids; ++crtSid) { + if (EqualSid(trustee, allowedSids[crtSid])) { + return TRUE; + } + } + return FALSE; +} + + +//---------------------------------------------------------------------------- +// Function: InitLocalDirs +// +// Description: +// Validates that the wsceConfigRelativePath file is only writable by Administrators +// +DWORD ValidateConfigurationFile() { + DWORD dwError = ERROR_SUCCESS; + WCHAR xmlPath[MAX_PATH]; + PSECURITY_DESCRIPTOR pSd = NULL; + BOOL daclPresent = FALSE; + BOOL daclDefaulted = FALSE; + PACL pDacl = NULL; + int crt = 0, crtSid = 0; + WELL_KNOWN_SID_TYPE allowedSidTypes[] = { + WinLocalSystemSid, + WinBuiltinAdministratorsSid}; + ACL_SIZE_INFORMATION aclInfo; + DWORD cbSid = SECURITY_MAX_SID_SIZE; + PSID* allowedSids = NULL; + int cAllowedSids = 0; + BOOL isSidDefaulted; + PSID sidOwner = NULL; + PSID sidGroup = NULL; + + allowedSids = (PSID*) LocalAlloc( + LPTR, + sizeof(PSID) * sizeof(allowedSidTypes) / sizeof(WELL_KNOWN_SID_TYPE)); + if (NULL == allowedSids) { + dwError = ERROR_OUTOFMEMORY; + CHECK_SVC_STATUS_DONE(dwError, L"LocalAlloc"); + } + + for(crt = 0; crt < sizeof(allowedSidTypes) / sizeof(WELL_KNOWN_SID_TYPE); ++crt) { + allowedSids[crt] = LocalAlloc(LPTR, SECURITY_MAX_SID_SIZE); + if (NULL == allowedSids[crt]) { + dwError = ERROR_OUTOFMEMORY; + CHECK_SVC_STATUS_DONE(dwError, L"LocalAlloc"); + } + + cbSid = SECURITY_MAX_SID_SIZE; + + if (!CreateWellKnownSid( + allowedSidTypes[crt], NULL, allowedSids[crt], &cbSid)) { + dwError = GetLastError(); + CHECK_SVC_STATUS_DONE(dwError, L"CreateWellKnownSid"); + } + ++cAllowedSids; + } + + dwError = BuildPathRelativeToModule( + wsceConfigRelativePath, + sizeof(xmlPath)/sizeof(WCHAR), + xmlPath); + CHECK_SVC_STATUS_DONE(dwError, L"BuildPathRelativeToModule"); + + dwError = GetNamedSecurityInfo( + xmlPath, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &pSd); + CHECK_SVC_STATUS_DONE(dwError, L"GetNamedSecurityInfo"); + + if (!GetSecurityDescriptorDacl( + pSd, + &daclPresent, + &pDacl, + &daclDefaulted)) { + dwError = GetLastError(); + CHECK_SVC_STATUS_DONE(dwError, L"GetSecurityDescriptorDacl"); + } + + if (!pDacl) { + dwError = ERROR_BAD_CONFIGURATION; + CHECK_SVC_STATUS_DONE(dwError, L"pDacl"); + } + + ZeroMemory(&aclInfo, sizeof(aclInfo)); + if (!GetAclInformation(pDacl, &aclInfo, sizeof(aclInfo), AclSizeInformation)) { + dwError = GetLastError(); + CHECK_SVC_STATUS_DONE(dwError, L"GetAclInformation"); + } + + // Inspect all ACEs in the file DACL. + // Look at all WRITE GRANTs. Make sure the trustee Sid is one of the approved Sid + // + for(crt = 0; crt < aclInfo.AceCount; ++crt) { + + ACE_HEADER* aceHdr = NULL; + if (!GetAce(pDacl, crt, &aceHdr)) { + dwError = GetLastError(); + CHECK_SVC_STATUS_DONE(dwError, L"GetAce"); + } + + if (ACCESS_ALLOWED_ACE_TYPE == aceHdr->AceType) { + ACCESS_ALLOWED_ACE* pAce = (ACCESS_ALLOWED_ACE*) aceHdr; + if (WinMasks[WIN_WRITE] & pAce->Mask) { + if (!IsSidInList((PSID) &pAce->SidStart, cAllowedSids, allowedSids)) { + dwError = ERROR_BAD_CONFIGURATION; + CHECK_SVC_STATUS_DONE(dwError, L"!validSidFound"); + } + } + } + } + +done: + if (pSd) LocalFree(pSd); + + if (allowedSids) { + while (cAllowedSids) { + LocalFree(allowedSids[cAllowedSids--]); + } + LocalFree(allowedSids); + } + + return dwError; +} + +//---------------------------------------------------------------------------- // Function: InitLocalDirs // // Description: @@ -400,6 +540,13 @@ DWORD SvcInit() { goto done; } + dwError = ValidateConfigurationFile(); + if (dwError) { + LogDebugMessage(L"ValidateConfigurationFile failed: %d", dwError); + SvcError(dwError); + goto done; + } + dwError = AuthInit(); if (ERROR_SUCCESS != dwError) { LogDebugMessage(L"AuthInit failed: %d", dwError);