in hadoop-common-project/hadoop-common/src/main/winutils/task.c [302:528]
DWORD AddNodeManagerAndUserACEsToObject(
__in HANDLE hObject,
__in LPCWSTR user,
__in ACCESS_MASK accessMask) {
DWORD dwError = ERROR_SUCCESS;
size_t countTokens = 0;
size_t len = 0;
LPCWSTR value = NULL;
WCHAR** tokens = NULL;
DWORD crt = 0;
PACL pDacl = NULL;
PSECURITY_DESCRIPTOR psdProcess = NULL;
LPWSTR lpszOldDacl = NULL, lpszNewDacl = NULL;
ULONG daclLen = 0;
PACL pNewDacl = NULL;
ACL_SIZE_INFORMATION si;
DWORD dwNewAclSize = 0;
PACE_HEADER pTempAce = NULL;
BYTE sidTemp[SECURITY_MAX_SID_SIZE];
DWORD cbSid = SECURITY_MAX_SID_SIZE;
PSID tokenSid = NULL;
// These hard-coded SIDs are allways added
WELL_KNOWN_SID_TYPE forcesSidTypes[] = {
WinLocalSystemSid,
WinBuiltinAdministratorsSid};
BOOL logSDs = IsDebuggerPresent(); // Check only once to avoid attach-while-running
dwError = GetSecurityInfo(hObject,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&pDacl,
NULL,
&psdProcess);
if (dwError) {
ReportErrorCode(L"GetSecurityInfo", dwError);
goto done;
}
// This is debug only output for troubleshooting
if (logSDs) {
if (!ConvertSecurityDescriptorToStringSecurityDescriptor(
psdProcess,
SDDL_REVISION_1,
DACL_SECURITY_INFORMATION,
&lpszOldDacl,
&daclLen)) {
dwError = GetLastError();
ReportErrorCode(L"ConvertSecurityDescriptorToStringSecurityDescriptor", dwError);
goto done;
}
}
ZeroMemory(&si, sizeof(si));
if (!GetAclInformation(pDacl, &si, sizeof(si), AclSizeInformation)) {
dwError = GetLastError();
ReportErrorCode(L"GetAclInformation", dwError);
goto done;
}
dwError = GetConfigValue(wsceConfigRelativePath, NM_WSCE_ALLOWED, &len, &value);
if (ERROR_SUCCESS != dwError) {
ReportErrorCode(L"GetConfigValue", dwError);
goto done;
}
if (0 == len) {
dwError = ERROR_BAD_CONFIGURATION;
ReportErrorCode(L"GetConfigValue", dwError);
goto done;
}
dwError = SplitStringIgnoreSpaceW(len, value, L',', &countTokens, &tokens);
if (ERROR_SUCCESS != dwError) {
ReportErrorCode(L"SplitStringIgnoreSpaceW", dwError);
goto done;
}
// We're gonna add 1 ACE for each token found, +1 for user and +1 for each forcesSidTypes[]
// ACCESS_ALLOWED_ACE struct contains the first DWORD of the SID
//
dwNewAclSize = si.AclBytesInUse +
(DWORD)(countTokens + 1 + sizeof(forcesSidTypes)/sizeof(forcesSidTypes[0])) *
(sizeof(ACCESS_ALLOWED_ACE) + SECURITY_MAX_SID_SIZE - sizeof(DWORD));
pNewDacl = (PSID) LocalAlloc(LPTR, dwNewAclSize);
if (!pNewDacl) {
dwError = ERROR_OUTOFMEMORY;
ReportErrorCode(L"LocalAlloc", dwError);
goto done;
}
if (!InitializeAcl(pNewDacl, dwNewAclSize, ACL_REVISION)) {
dwError = ERROR_OUTOFMEMORY;
ReportErrorCode(L"InitializeAcl", dwError);
goto done;
}
// Copy over old ACEs
for (crt = 0; crt < si.AceCount; ++crt) {
if (!GetAce(pDacl, crt, &pTempAce)) {
dwError = ERROR_OUTOFMEMORY;
ReportErrorCode(L"InitializeAcl", dwError);
goto done;
}
if (!AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pTempAce, pTempAce->AceSize)) {
dwError = ERROR_OUTOFMEMORY;
ReportErrorCode(L"InitializeAcl", dwError);
goto done;
}
}
// Add the configured allowed SIDs
for (crt = 0; crt < countTokens; ++crt) {
dwError = GetSidFromAcctNameW(tokens[crt], &tokenSid);
if (ERROR_SUCCESS != dwError) {
ReportErrorCode(L"GetSidFromAcctNameW", dwError);
goto done;
}
if (!AddAccessAllowedAceEx(
pNewDacl,
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
PROCESS_ALL_ACCESS,
tokenSid)) {
dwError = GetLastError();
ReportErrorCode(L"AddAccessAllowedAceEx:1", dwError);
goto done;
}
LocalFree(tokenSid);
tokenSid = NULL;
}
// add the forced SIDs ACE
for (crt = 0; crt < sizeof(forcesSidTypes)/sizeof(forcesSidTypes[0]); ++crt) {
cbSid = SECURITY_MAX_SID_SIZE;
if (!CreateWellKnownSid(forcesSidTypes[crt], NULL, &sidTemp, &cbSid)) {
dwError = GetLastError();
ReportErrorCode(L"CreateWellKnownSid", dwError);
goto done;
}
if (!AddAccessAllowedAceEx(
pNewDacl,
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
accessMask,
(PSID) sidTemp)) {
dwError = GetLastError();
ReportErrorCode(L"AddAccessAllowedAceEx:2", dwError);
goto done;
}
}
// add the user ACE
dwError = GetSidFromAcctNameW(user, &tokenSid);
if (ERROR_SUCCESS != dwError) {
ReportErrorCode(L"GetSidFromAcctNameW:user", dwError);
goto done;
}
if (!AddAccessAllowedAceEx(
pNewDacl,
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
PROCESS_ALL_ACCESS,
tokenSid)) {
dwError = GetLastError();
ReportErrorCode(L"AddAccessAllowedAceEx:3", dwError);
goto done;
}
LocalFree(tokenSid);
tokenSid = NULL;
dwError = SetSecurityInfo(hObject,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
pNewDacl,
NULL);
if (dwError) {
ReportErrorCode(L"SetSecurityInfo", dwError);
goto done;
}
// This is debug only output for troubleshooting
if (logSDs) {
dwError = GetSecurityInfo(hObject,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&pDacl,
NULL,
&psdProcess);
if (dwError) {
ReportErrorCode(L"GetSecurityInfo:2", dwError);
goto done;
}
if (!ConvertSecurityDescriptorToStringSecurityDescriptor(
psdProcess,
SDDL_REVISION_1,
DACL_SECURITY_INFORMATION,
&lpszNewDacl,
&daclLen)) {
dwError = GetLastError();
ReportErrorCode(L"ConvertSecurityDescriptorToStringSecurityDescriptor:2", dwError);
goto done;
}
LogDebugMessage(L"Old DACL: %ls\nNew DACL: %ls\n", lpszOldDacl, lpszNewDacl);
}
done:
if (tokenSid) LocalFree(tokenSid);
if (pNewDacl) LocalFree(pNewDacl);
if (lpszOldDacl) LocalFree(lpszOldDacl);
if (lpszNewDacl) LocalFree(lpszNewDacl);
if (psdProcess) LocalFree(psdProcess);
return dwError;
}