#include "pch.h" //************************************************************* // // CheckSlash() // // Purpose: Checks for an ending slash and adds one if // it is missing. // // Parameters: lpDir - directory // // Return: Pointer to the end of the string // // Comments: // // History: Date Author Comment // 6/19/95 ericflo Created // //************************************************************* LPTSTR CheckSlash (LPTSTR lpDir) { LPTSTR lpEnd; lpEnd = lpDir + lstrlen(lpDir); if (*(lpEnd - 1) != TEXT('\\')) { *lpEnd = TEXT('\\'); lpEnd++; *lpEnd = TEXT('\0'); } return lpEnd; } //************************************************************* // // RegDelnodeRecurse() // // Purpose: Deletes a registry key and all it's subkeys / values. // Called by RegDelnode // // Parameters: hKeyRoot - Root key // lpSubKey - SubKey to delete // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 10/3/95 ericflo Created // //************************************************************* BOOL RegDelnodeRecurse (HKEY hKeyRoot, PWSTR lpSubKey) { PWSTR End; LONG rc; DWORD dwSize; WCHAR szName[MAX_PATH]; HKEY hKey; FILETIME ftWrite; // // First, see if we can delete the key without having // to recurse. // rc = RegDeleteKey(hKeyRoot, lpSubKey); if (rc == ERROR_SUCCESS) { return TRUE; } rc = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); if (rc != ERROR_SUCCESS) { if (rc == ERROR_FILE_NOT_FOUND) { return TRUE; } else { return FALSE; } } End = CheckSlash(lpSubKey); // // Enumerate the keys // dwSize = MAX_PATH; rc = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); if (rc == ERROR_SUCCESS) { do { lstrcpy (End, szName); if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) { break; } // // Enumerate again // dwSize = MAX_PATH; rc = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); } while (rc == ERROR_SUCCESS); } End--; *End = TEXT('\0'); RegCloseKey (hKey); // // Try again to delete the key // rc = RegDeleteKey(hKeyRoot, lpSubKey); if (rc == ERROR_SUCCESS) { return TRUE; } return FALSE; } //************************************************************* // // RegDelnode() // // Purpose: Deletes a registry key and all it's subkeys / values // // Parameters: hKeyRoot - Root key // lpSubKey - SubKey to delete // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 10/3/95 ericflo Created // //************************************************************* BOOL RegDelnode (HKEY hKeyRoot, PWSTR lpSubKey) { WCHAR szDelKey[2 * MAX_PATH]; lstrcpy (szDelKey, lpSubKey); return RegDelnodeRecurse(hKeyRoot, szDelKey); } //************************************************************* // // CreateNestedDirectory() // // Purpose: Creates a subdirectory and all it's parents // if necessary. // // Parameters: lpDirectory - Directory name // lpSecurityAttributes - Security Attributes // // Return: > 0 if successful // 0 if an error occurs // // Comments: // // History: Date Author Comment // 8/08/95 ericflo Created // //************************************************************* UINT CreateNestedDirectory(LPCTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { TCHAR szDirectory[2*MAX_PATH]; LPTSTR lpEnd; PACL Acl; BOOL Present; BOOL Defaulted; // // Check for NULL pointer // if (!lpDirectory || !(*lpDirectory)) { DEBUGMSG ((DM_WARNING, "CreateNestedDirectory: Received a NULL pointer.")); return 0; } // // First, see if we can create the directory without having // to build parent directories. // if (CreateDirectory (lpDirectory, lpSecurityAttributes)) { return 1; } // // If this directory exists already, this is OK too. // if (GetLastError() == ERROR_ALREADY_EXISTS) { // // Update the security // if (lpSecurityAttributes) { if (!GetSecurityDescriptorDacl ( lpSecurityAttributes->lpSecurityDescriptor, &Present, &Acl, &Defaulted )) { Present = FALSE; } if (Present && !Defaulted) { if (!SetNamedSecurityInfo ( (PTSTR) lpDirectory, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, Acl, NULL )) { return GetLastError(); } } } return ERROR_ALREADY_EXISTS; } // // No luck, copy the string to a buffer we can munge // lstrcpy (szDirectory, lpDirectory); // // Find the first subdirectory name // lpEnd = szDirectory; if (szDirectory[1] == TEXT(':')) { lpEnd += 3; } else if (szDirectory[1] == TEXT('\\')) { // // Skip the first two slashes // lpEnd += 2; // // Find the slash between the server name and // the share name. // while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (!(*lpEnd)) { return 0; } // // Skip the slash, and find the slash between // the share name and the directory name. // lpEnd++; while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (!(*lpEnd)) { return 0; } // // Leave pointer at the beginning of the directory. // lpEnd++; } else if (szDirectory[0] == TEXT('\\')) { lpEnd++; } while (*lpEnd) { while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (*lpEnd == TEXT('\\')) { *lpEnd = TEXT('\0'); if (!CreateDirectory (szDirectory, NULL)) { if (GetLastError() != ERROR_ALREADY_EXISTS) { DEBUGMSG ((DM_WARNING, "CreateNestedDirectory: CreateDirectory failed with %d.", GetLastError())); return 0; } } *lpEnd = TEXT('\\'); lpEnd++; } } // // Create the final directory // if (CreateDirectory (szDirectory, lpSecurityAttributes)) { return 1; } if (GetLastError() == ERROR_ALREADY_EXISTS) { return ERROR_ALREADY_EXISTS; } // // Failed // DEBUGMSG ((DM_VERBOSE, "CreateNestedDirectory: Failed to create the directory with error %d.", GetLastError())); return 0; } //************************************************************* // // CreateSecureDirectory() // // Purpose: Creates a secure directory that only the user, // admin, and system have access to in the normal case // and for only the user and system in the restricted case. // // // Parameters: lpDirectory - Directory Name // pSid - Sid (used by CreateUserProfile) // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 7/20/95 ericflo Created // 9/30/98 ushaji added fRestricted flag // //************************************************************* BOOL CreateSecureDirectory (LPTSTR lpDirectory, PSID pSid) { SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sa; PACL pAcl = NULL; BOOL bRetVal = FALSE; // // Verbose Output // DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Entering with <%s>", lpDirectory)); if (!pSid) { // // Attempt to create the directory // if (CreateNestedDirectory(lpDirectory, NULL)) { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Created the directory <%s>", lpDirectory)); bRetVal = TRUE; } else { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Failed to created the directory <%s>", lpDirectory)); } goto Exit; } // // Get the default ACL // pAcl = CreateDefaultAcl (pSid); // // Put together the security descriptor // if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Failed to initialize security descriptor. Error = %d", GetLastError())); goto Exit; } if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Failed to set security descriptor dacl. Error = %d", GetLastError())); goto Exit; } // // Add the security descriptor to the sa structure // sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; // // Attempt to create the directory // if (CreateNestedDirectory(lpDirectory, &sa)) { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Created the directory <%s>", lpDirectory)); bRetVal = TRUE; } else { DEBUGMSG ((DM_VERBOSE, "CreateSecureDirectory: Failed to created the directory <%s>", lpDirectory)); } Exit: FreeDefaultAcl (pAcl); return bRetVal; } PACL CreateDefaultAcl ( PSID pSid ) { SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; PACL pAcl = NULL; PSID psidSystem = NULL, psidAdmin = NULL; DWORD cbAcl, aceIndex; ACE_HEADER * lpAceHeader; BOOL bRetVal = FALSE; BOOL bFreeSid = TRUE; // // Get the system sid // if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psidSystem)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to initialize system sid. Error = %d", GetLastError())); goto Exit; } // // Get the Admin sid // if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to initialize admin sid. Error = %d", GetLastError())); goto Exit; } // // Allocate space for the ACL // cbAcl = (2 * GetLengthSid (pSid)) + (2 * GetLengthSid (psidSystem)) + (2 * GetLengthSid (psidAdmin)) + sizeof(ACL) + (6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))); pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl); if (!pAcl) { goto Exit; } if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to initialize acl. Error = %d", GetLastError())); goto Exit; } // // Add Aces for User, System, and Admin. Non-inheritable ACEs first // aceIndex = 0; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, pSid)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } aceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidSystem)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } aceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } // // Now the inheritable ACEs // aceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to get ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); aceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to get ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); aceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to add ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } if (!GetAce(pAcl, aceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "CreateDefaultAcl: Failed to get ace (%d). Error = %d", aceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); Exit: if (psidSystem) { FreeSid(psidSystem); } if (psidAdmin) { FreeSid(psidAdmin); } return pAcl; } VOID FreeDefaultAcl ( PACL pAcl ) { if (pAcl) { GlobalFree (pAcl); } } BOOL OurConvertSidToStringSid ( IN PSID Sid, OUT PWSTR *SidString ) { UNICODE_STRING UnicodeString; NTSTATUS NtStatus; // // Convert the sid into text format // NtStatus = RtlConvertSidToUnicodeString (&UnicodeString, Sid, TRUE); if (!NT_SUCCESS (NtStatus)) { DEBUGMSG (( DM_WARNING, "CreateUserProfile: RtlConvertSidToUnicodeString failed, status = 0x%x", NtStatus )); return FALSE; } *SidString = UnicodeString.Buffer; return TRUE; } VOID DeleteSidString ( PWSTR SidString ) { UNICODE_STRING String; if (!SidString) { return; } RtlInitUnicodeString (&String, SidString); RtlFreeUnicodeString (&String); } BOOL GetProfileRoot ( IN PSID Sid, OUT PWSTR ProfileDir ) { WCHAR LocalProfileKey[MAX_PATH]; HKEY hKey; DWORD Size; DWORD Type; DWORD Attributes; PWSTR SidString; WCHAR ExpandedRoot[MAX_PATH]; ProfileDir[0] = 0; if (!OurConvertSidToStringSid (Sid, &SidString)) { DEBUGMSG ((DM_WARNING, "GetProfileRoot: Can't convert SID to string")); return FALSE; } // // Check if this user's profile exists // lstrcpy (LocalProfileKey, PROFILE_LIST_PATH); lstrcat (LocalProfileKey, TEXT("\\")); lstrcat (LocalProfileKey, SidString); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, LocalProfileKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { Size = MAX_PATH; RegQueryValueEx (hKey, PROFILE_IMAGE_VALUE_NAME, NULL, &Type, (LPBYTE) ProfileDir, &Size); RegCloseKey (hKey); } if (ProfileDir[0]) { ExpandEnvironmentStrings (ProfileDir, ExpandedRoot, MAX_PATH); Attributes = GetFileAttributes (ExpandedRoot); if (Attributes == 0xFFFFFFFF || !(Attributes & FILE_ATTRIBUTE_DIRECTORY)) { ProfileDir[0] = 0; DEBUGMSG ((DM_VERBOSE, "GetProfileRoot: Profile %s is not vaild", SidString)); } else { lstrcpy (ProfileDir, ExpandedRoot); } } else { DEBUGMSG ((DM_VERBOSE, "GetProfileRoot: SID %s does not have a profile directory", SidString)); } DeleteSidString (SidString); return ProfileDir[0] != 0; } BOOL UpdateProfileSecurity ( PSID Sid ) { WCHAR ProfileDir[MAX_PATH]; WCHAR ExpProfileDir[MAX_PATH]; WCHAR LocalProfileKey[MAX_PATH]; PWSTR SidString = NULL; PWSTR End, Save; LONG rc; DWORD dwError; DWORD dwSize; DWORD dwType; HKEY hKey; BOOL b = FALSE; BOOL UnloadProfile = FALSE; __try { // // Convert the sid into text format // if (!OurConvertSidToStringSid (Sid, &SidString)) { DEBUGMSG (( DM_WARNING, "UpdateProfileSecurity: Can't convert SID to string" )); __leave; } // // Check if this user's profile exists already // lstrcpy(LocalProfileKey, PROFILE_LIST_PATH); lstrcat(LocalProfileKey, TEXT("\\")); lstrcat(LocalProfileKey, SidString); ProfileDir[0] = 0; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, LocalProfileKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(ProfileDir); RegQueryValueEx (hKey, PROFILE_IMAGE_VALUE_NAME, NULL, &dwType, (LPBYTE) ProfileDir, &dwSize); RegCloseKey (hKey); } if (!ProfileDir[0]) { DEBUGMSG ((DM_WARNING, "UpdateProfileSecurity: No profile for specified user")); SetLastError (ERROR_BAD_PROFILE); __leave; } // // The user has a profile, so update the security settings // ExpandEnvironmentStrings ( ProfileDir, ExpProfileDir, ARRAYSIZE(ExpProfileDir) ); // // Load the hive temporary so the security can be fixed // End = CheckSlash (ExpProfileDir); Save = End - 1; lstrcpy (End, L"NTUSER.DAT"); rc = MyRegLoadKey (HKEY_USERS, SidString, ExpProfileDir); *Save = 0; if (rc != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "UpdateProfileSecurity: Failed to load hive, error = %d.", rc)); SetLastError (rc); __leave; } UnloadProfile = TRUE; if (!SetupNewHive (SidString, Sid)) { DEBUGMSG((DM_WARNING, "UpdateProfileSecurity: SetupNewHive failed, error = %d.", GetLastError())); __leave; } // // Fix the file system security // if (!CreateSecureDirectory (ExpProfileDir, Sid)) { DEBUGMSG((DM_WARNING, "UpdateProfileSecurity: CreateSecureDirectory failed, error = %d.", GetLastError())); __leave; } b = TRUE; } __finally { dwError = GetLastError(); if (UnloadProfile) { MyRegUnLoadKey (HKEY_USERS, SidString); } DeleteSidString (SidString); SetLastError (dwError); } return b; } //************************************************************* // // DeleteProfileRegistrySettings() // // Purpose: Deletes the specified profile from the // registry. // // Parameters: lpSidString - Registry subkey // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 6/23/95 ericflo Created // 5/20/99 jimschm Moved out of DeleteProfile // //************************************************************* BOOL DeleteProfileRegistrySettings (LPTSTR lpSidString) { LONG lResult; TCHAR szTemp[MAX_PATH]; TCHAR szUserGuid[MAX_PATH]; HKEY hKey; DWORD dwType, dwSize; if (lpSidString && *lpSidString) { lstrcpy(szTemp, PROFILE_LIST_PATH); lstrcat(szTemp, TEXT("\\")); lstrcat(szTemp, lpSidString); // // get the user guid // lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTemp, 0, KEY_READ, &hKey); if (lResult == ERROR_SUCCESS) { // // Query for the user guid // dwSize = MAX_PATH * sizeof(TCHAR); lResult = RegQueryValueEx (hKey, PROFILE_GUID, NULL, &dwType, (LPBYTE) szUserGuid, &dwSize); if (lResult != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "DeleteProfile: Failed to query profile guid with error %d", lResult)); } else { lstrcpy(szTemp, PROFILE_GUID_PATH); lstrcat(szTemp, TEXT("\\")); lstrcat(szTemp, szUserGuid); // // Delete the profile guid from the guid list // lResult = RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp); if (lResult != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "DeleteProfile: failed to delete profile guid. Error = %d", lResult)); } } RegCloseKey(hKey); } lstrcpy(szTemp, PROFILE_LIST_PATH); lstrcat(szTemp, TEXT("\\")); lstrcat(szTemp, lpSidString); lResult = RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp); if (lResult != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "DeleteProfile: Unable to delete registry entry. Error = %d", lResult)); SetLastError(lResult); return FALSE; } } return TRUE; } /***************************************************************************\ * GetUserSid * * Allocs space for the user sid, fills it in and returns a pointer. Caller * The sid should be freed by calling DeleteUserSid. * * Note the sid returned is the user's real sid, not the per-logon sid. * * Returns pointer to sid or NULL on failure. * * History: * 26-Aug-92 Davidc Created. \***************************************************************************/ PSID GetUserSid (HANDLE UserToken) { PTOKEN_USER pUser, pTemp; PSID pSid; DWORD BytesRequired = 200; NTSTATUS status; // // Allocate space for the user info // pUser = (PTOKEN_USER)LocalAlloc(LMEM_FIXED, BytesRequired); if (pUser == NULL) { DEBUGMSG((DM_WARNING, "GetUserSid: Failed to allocate %d bytes", BytesRequired)); return NULL; } // // Read in the UserInfo // status = NtQueryInformationToken( UserToken, // Handle TokenUser, // TokenInformationClass pUser, // TokenInformation BytesRequired, // TokenInformationLength &BytesRequired // ReturnLength ); if (status == STATUS_BUFFER_TOO_SMALL) { // // Allocate a bigger buffer and try again. // pTemp = LocalReAlloc(pUser, BytesRequired, LMEM_MOVEABLE); if (pTemp == NULL) { DEBUGMSG((DM_WARNING, "GetUserSid: Failed to allocate %d bytes", BytesRequired)); LocalFree (pUser); return NULL; } pUser = pTemp; status = NtQueryInformationToken( UserToken, // Handle TokenUser, // TokenInformationClass pUser, // TokenInformation BytesRequired, // TokenInformationLength &BytesRequired // ReturnLength ); } if (!NT_SUCCESS(status)) { DEBUGMSG((DM_WARNING, "GetUserSid: Failed to query user info from user token, status = 0x%x", status)); LocalFree(pUser); return NULL; } BytesRequired = RtlLengthSid(pUser->User.Sid); pSid = LocalAlloc(LMEM_FIXED, BytesRequired); if (pSid == NULL) { DEBUGMSG((DM_WARNING, "GetUserSid: Failed to allocate %d bytes", BytesRequired)); LocalFree(pUser); return NULL; } status = RtlCopySid(BytesRequired, pSid, pUser->User.Sid); LocalFree(pUser); if (!NT_SUCCESS(status)) { DEBUGMSG((DM_WARNING, "GetUserSid: RtlCopySid Failed. status = %d", status)); LocalFree(pSid); pSid = NULL; } return pSid; } /***************************************************************************\ * DeleteUserSid * * Deletes a user sid previously returned by GetUserSid() * * Returns nothing. * * History: * 26-Aug-92 Davidc Created * \***************************************************************************/ VOID DeleteUserSid(PSID Sid) { LocalFree(Sid); } //************************************************************* // // MyRegLoadKey() // // Purpose: Loads a hive into the registry // // Parameters: hKey - Key to load the hive into // lpSubKey - Subkey name // lpFile - hive filename // // Return: ERROR_SUCCESS if successful // Error number if an error occurs // // Comments: // // History: Date Author Comment // 6/22/95 ericflo Created // //************************************************************* LONG MyRegLoadKey(HKEY hKey, LPTSTR lpSubKey, LPTSTR lpFile) { NTSTATUS Status; BOOLEAN WasEnabled; int error; DWORD dwException; WCHAR szException[20]; __try { // // Enable the restore privilege // Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, TRUE, &WasEnabled); if (NT_SUCCESS(Status)) { error = RegLoadKey(hKey, lpSubKey, lpFile); // // Restore the privilege to its previous state // Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, TRUE, &WasEnabled); if (!NT_SUCCESS(Status)) { DEBUGMSG((DM_WARNING, "MyRegLoadKey: Failed to restore RESTORE privilege to previous enabled state")); } // // Convert a sharing violation error to success since the hive // is already loaded // if (error == ERROR_SHARING_VIOLATION) { error = ERROR_SUCCESS; } // // Check if the hive was loaded // if (error != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "MyRegLoadKey: Failed to load subkey <%s>, error =%d", lpSubKey, error)); } } else { error = ERROR_ACCESS_DENIED; DEBUGMSG((DM_WARNING, "MyRegLoadKey: Failed to enable restore privilege to load registry key, error %u", error)); } } __except(EXCEPTION_EXECUTE_HANDLER) { dwException = GetExceptionCode(); ASSERT(dwException == 0); wsprintf(szException, L"!!!! 0x%x ", dwException); OutputDebugString(szException); OutputDebugString(L"Exception hit in MyRegLoadKey in userenv\n"); ASSERT(dwException == 0); } DEBUGMSG((DM_VERBOSE, "MyRegLoadKey: Returning %d.", error)); return error; } //************************************************************* // // MyRegUnLoadKey() // // Purpose: Unloads a registry key // // Parameters: hKey - Registry handle // lpSubKey - Subkey to be unloaded // // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 6/19/95 ericflo Ported // //************************************************************* BOOL MyRegUnLoadKey(HKEY hKey, LPTSTR lpSubKey) { BOOL bResult = TRUE; LONG error; NTSTATUS Status; BOOLEAN WasEnabled; DWORD dwException; WCHAR szException[20]; __try { // // Enable the restore privilege // Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, TRUE, &WasEnabled); if (NT_SUCCESS(Status)) { error = RegUnLoadKey(hKey, lpSubKey); if ( error != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "MyRegUnLoadKey: Failed to unmount hive %x", error)); SetLastError(error); bResult = FALSE; } // // Restore the privilege to its previous state // Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasEnabled, TRUE, &WasEnabled); if (!NT_SUCCESS(Status)) { DEBUGMSG((DM_WARNING, "MyRegUnLoadKey: Failed to restore RESTORE privilege to previous enabled state")); } } else { DEBUGMSG((DM_WARNING, "MyRegUnloadKey: Failed to enable restore privilege to unload registry key")); Status = ERROR_ACCESS_DENIED; SetLastError(Status); bResult = FALSE; } } __except(EXCEPTION_EXECUTE_HANDLER) { dwException = GetExceptionCode(); ASSERT(dwException == 0); wsprintf(szException, L"!!!! 0x%x ", dwException); OutputDebugString(szException); OutputDebugString(L"Exception hit in MyRegUnLoadKey in userenv\n"); ASSERT(dwException == 0); } DEBUGMSG((DM_VERBOSE, "MyRegUnloadKey: Returning %d, error %u.", bResult, GetLastError())); return bResult; } //************************************************************* // // SetDefaultUserHiveSecurity() // // Purpose: Initializes a user hive with the // appropriate acls // // Parameters: pSid - Sid (used by CreateNewUser) // RootKey - registry handle to hive root // // Return: ERROR_SUCCESS if successful // other error code if an error occurs // // Comments: // // History: Date Author Comment // 7/18/95 ericflo Created as part of // SetupNewHive // 3/29/98 adamed Moved out of SetupNewHive // to this function // //************************************************************* BOOL SetDefaultUserHiveSecurity(PSID pSid, HKEY RootKey) { DWORD Error; SECURITY_DESCRIPTOR sd; SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; PACL pAcl = NULL; PSID psidUser = NULL, psidSystem = NULL, psidAdmin = NULL, psidRestricted = NULL; DWORD cbAcl, AceIndex; ACE_HEADER * lpAceHeader; BOOL bRetVal = FALSE; BOOL bFreeSid = TRUE; // // Verbose Output // DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Entering")); // // Create the security descriptor that will be applied to each key // // // Give the user access by their real sid so they still have access // when they logoff and logon again // psidUser = pSid; bFreeSid = FALSE; if (!psidUser) { DEBUGMSG((DM_WARNING, "SetDefaultUserHiveSecurity: Failed to get user sid")); return FALSE; } // // Get the system sid // if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psidSystem)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to initialize system sid. Error = %d", GetLastError())); goto Exit; } // // Get the admin sid // if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to initialize admin sid. Error = %d", GetLastError())); goto Exit; } // // Get the Restricted sid // if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_RESTRICTED_CODE_RID, 0, 0, 0, 0, 0, 0, 0, &psidRestricted)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to initialize restricted sid. Error = %d", GetLastError())); goto Exit; } // // Allocate space for the ACL // cbAcl = (2 * GetLengthSid (psidUser)) + (2 * GetLengthSid (psidSystem)) + (2 * GetLengthSid (psidAdmin)) + (2*GetLengthSid(psidRestricted)) + sizeof(ACL) + (8 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))); pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl); if (!pAcl) { goto Exit; } if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to initialize acl. Error = %d", GetLastError())); goto Exit; } // // Add Aces for User, System, and Admin. Non-inheritable ACEs first // AceIndex = 0; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidUser)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for user. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidSystem)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for system. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidAdmin)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for admin. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_READ, psidRestricted)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for Restricted. Error = %d", GetLastError())); goto Exit; } // // Now the inheritable ACEs // AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidUser)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for user. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for system. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for admin. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ, psidRestricted)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to add ace for restricted. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); // // Put together the security descriptor // if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to initialize security descriptor. Error = %d", GetLastError())); goto Exit; } if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) { DEBUGMSG((DM_VERBOSE, "SetDefaultUserHiveSecurity: Failed to set security descriptor dacl. Error = %d", GetLastError())); goto Exit; } // // Set the security descriptor on the entire tree // Error = ApplySecurityToRegistryTree(RootKey, &sd); if (ERROR_SUCCESS == Error) { bRetVal = TRUE; } else SetLastError(Error); Exit: // // Free the sids and acl // if (bFreeSid && psidUser) { DeleteUserSid (psidUser); } if (psidSystem) { FreeSid(psidSystem); } if (psidAdmin) { FreeSid(psidAdmin); } if (pAcl) { GlobalFree (pAcl); } return bRetVal; } //************************************************************* // // SetupNewHive() // // Purpose: Initializes the new user hive created by copying // the default hive. // // Parameters: lpSidString - Sid string // pSid - Sid (used by CreateNewUser) // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 7/18/95 ericflo Created // //************************************************************* BOOL SetupNewHive(LPTSTR lpSidString, PSID pSid) { DWORD Error, IgnoreError; HKEY RootKey; BOOL bRetVal = FALSE; // // Verbose Output // DEBUGMSG((DM_VERBOSE, "SetupNewHive: Entering")); // // Open the root of the user's profile // Error = RegOpenKeyEx(HKEY_USERS, lpSidString, 0, WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL, &RootKey); if (Error != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "SetupNewHive: Failed to open root of user registry, error = %d", Error)); } else { // // First Secure the entire hive -- use security that // will be sufficient for most of the hive. // After this, we can add special settings to special // sections of this hive. // if (SetDefaultUserHiveSecurity(pSid, RootKey)) { TCHAR szSubKey[MAX_PATH]; LPTSTR lpEnd; // // Change the security on certain keys in the user's registry // so that only Admin's and the OS have write access. // lstrcpy (szSubKey, lpSidString); lpEnd = CheckSlash(szSubKey); lstrcpy (lpEnd, WINDOWS_POLICIES_KEY); if (!SecureUserKey(szSubKey, pSid)) { DEBUGMSG((DM_WARNING, "SetupNewHive: Failed to secure windows policies key")); } lstrcpy (lpEnd, ROOT_POLICIES_KEY); if (!SecureUserKey(szSubKey, pSid)) { DEBUGMSG((DM_WARNING, "SetupNewHive: Failed to secure root policies key")); } bRetVal = TRUE; } else { Error = GetLastError(); DEBUGMSG((DM_WARNING, "SetupNewHive: Failed to apply security to user registry tree, error = %d", Error)); } RegFlushKey (RootKey); IgnoreError = RegCloseKey(RootKey); if (IgnoreError != ERROR_SUCCESS) { DEBUGMSG((DM_WARNING, "SetupNewHive: Failed to close reg key, error = %d", IgnoreError)); } } // // Verbose Output // DEBUGMSG((DM_VERBOSE, "SetupNewHive: Leaving with a return value of %d, error %u", bRetVal, Error)); if (!bRetVal) SetLastError(Error); return(bRetVal); } //************************************************************* // // ApplySecurityToRegistryTree() // // Purpose: Applies the passed security descriptor to the passed // key and all its descendants. Only the parts of // the descriptor inddicated in the security // info value are actually applied to each registry key. // // Parameters: RootKey - Registry key // pSD - Security Descriptor // // Return: ERROR_SUCCESS if successful // // Comments: // // History: Date Author Comment // 7/19/95 ericflo Created // //************************************************************* DWORD ApplySecurityToRegistryTree(HKEY RootKey, PSECURITY_DESCRIPTOR pSD) { DWORD Error = ERROR_SUCCESS; DWORD SubKeyIndex; LPTSTR SubKeyName; HKEY SubKey; DWORD cchSubKeySize = MAX_PATH + 1; // // First apply security // RegSetKeySecurity(RootKey, DACL_SECURITY_INFORMATION, pSD); // // Open each sub-key and apply security to its sub-tree // SubKeyIndex = 0; SubKeyName = GlobalAlloc (GPTR, cchSubKeySize * sizeof(TCHAR)); if (!SubKeyName) { DEBUGMSG ((DM_WARNING, "ApplySecurityToRegistryTree: Failed to allocate memory, error = %d", GetLastError())); return GetLastError(); } while (TRUE) { // // Get the next sub-key name // Error = RegEnumKey(RootKey, SubKeyIndex, SubKeyName, cchSubKeySize); if (Error != ERROR_SUCCESS) { if (Error == ERROR_NO_MORE_ITEMS) { // // Successful end of enumeration // Error = ERROR_SUCCESS; } else { DEBUGMSG ((DM_WARNING, "ApplySecurityToRegistryTree: Registry enumeration failed with error = %d", Error)); } break; } // // Open the sub-key // Error = RegOpenKeyEx(RootKey, SubKeyName, 0, WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL, &SubKey); if (Error == ERROR_SUCCESS) { // // Apply security to the sub-tree // ApplySecurityToRegistryTree(SubKey, pSD); // // We're finished with the sub-key // RegCloseKey(SubKey); } // // Go enumerate the next sub-key // SubKeyIndex ++; } GlobalFree (SubKeyName); return Error; } //************************************************************* // // SecureUserKey() // // Purpose: Sets security on a key in the user's hive // so only admin's can change it. // // Parameters: lpKey - Key to secure // pSid - Sid (used by CreateNewUser) // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 6/20/95 ericflo Created // //************************************************************* BOOL SecureUserKey(LPTSTR lpKey, PSID pSid) { DWORD Error; HKEY RootKey; SECURITY_DESCRIPTOR sd; SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; PACL pAcl = NULL; PSID psidUser = NULL, psidSystem = NULL, psidAdmin = NULL, psidRestricted = NULL; DWORD cbAcl, AceIndex, dwDisp; ACE_HEADER * lpAceHeader; BOOL bRetVal = FALSE; BOOL bFreeSid = TRUE; // // Verbose Output // DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Entering")); // // Create the security descriptor // // // Give the user access by their real sid so they still have access // when they logoff and logon again // psidUser = pSid; bFreeSid = FALSE; if (!psidUser) { DEBUGMSG ((DM_WARNING, "SecureUserKey: Failed to get user sid")); return FALSE; } // // Get the system sid // if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psidSystem)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to initialize system sid. Error = %d", GetLastError())); goto Exit; } // // Get the admin sid // if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to initialize admin sid. Error = %d", GetLastError())); goto Exit; } // // Get the restricted sid // if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_RESTRICTED_CODE_RID, 0, 0, 0, 0, 0, 0, 0, &psidRestricted)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to initialize restricted sid. Error = %d", GetLastError())); goto Exit; } // // Allocate space for the ACL // cbAcl = (2 * GetLengthSid (psidUser)) + (2 * GetLengthSid (psidSystem)) + (2 * GetLengthSid (psidAdmin)) + (2 * GetLengthSid (psidRestricted)) + sizeof(ACL) + (8 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))); pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl); if (!pAcl) { goto Exit; } if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to initialize acl. Error = %d", GetLastError())); goto Exit; } // // Add Aces for User, System, and Admin. Non-inheritable ACEs first // AceIndex = 0; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_READ, psidUser)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for user. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidSystem)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for system. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for admin. Error = %d", GetLastError())); goto Exit; } AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_READ, psidRestricted)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for restricted. Error = %d", GetLastError())); goto Exit; } // // Now the inheritable ACEs // AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ, psidUser)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for user. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for system. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for admin. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); AceIndex++; if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_READ, psidRestricted)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to add ace for restricted. Error = %d", GetLastError())); goto Exit; } if (!GetAce(pAcl, AceIndex, &lpAceHeader)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to get ace (%d). Error = %d", AceIndex, GetLastError())); goto Exit; } lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); // // Put together the security descriptor // if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to initialize security descriptor. Error = %d", GetLastError())); goto Exit; } if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) { DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Failed to set security descriptor dacl. Error = %d", GetLastError())); goto Exit; } // // Open the root of the user's profile // Error = RegCreateKeyEx(HKEY_USERS, lpKey, 0, NULL, REG_OPTION_NON_VOLATILE, WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL, NULL, &RootKey, &dwDisp); if (Error != ERROR_SUCCESS) { DEBUGMSG ((DM_WARNING, "SecureUserKey: Failed to open root of user registry, error = %d", Error)); } else { // // Set the security descriptor on the key // Error = ApplySecurityToRegistryTree(RootKey, &sd); if (Error == ERROR_SUCCESS) { bRetVal = TRUE; } else { DEBUGMSG ((DM_WARNING, "SecureUserKey: Failed to apply security to registry key, error = %d", Error)); SetLastError(Error); } RegCloseKey(RootKey); } Exit: // // Free the sids and acl // if (bFreeSid && psidUser) { DeleteUserSid (psidUser); } if (psidRestricted) { FreeSid(psidRestricted); } if (psidSystem) { FreeSid(psidSystem); } if (psidAdmin) { FreeSid(psidAdmin); } if (pAcl) { GlobalFree (pAcl); } // // Verbose Output // DEBUGMSG ((DM_VERBOSE, "SecureUserKey: Leaving with a return value of %d", bRetVal)); return(bRetVal); } //************************************************************* // // ProduceWFromA() // // Purpose: Creates a buffer for a Unicode string and copies // the ANSI text into it (converting in the process) // // Parameters: pszA - ANSI string // // // Return: Unicode pointer if successful // NULL if an error occurs // // Comments: The caller needs to free this pointer. // // // History: Date Author Comment // 5/24/95 ericflo Ported // //************************************************************* LPWSTR ProduceWFromA(LPCSTR pszA) { LPWSTR pszW; int cch; if (!pszA) return (LPWSTR)pszA; cch = MultiByteToWideChar(CP_ACP, 0, pszA, -1, NULL, 0); if (cch == 0) cch = 1; pszW = LocalAlloc(LPTR, cch * sizeof(WCHAR)); if (pszW) { if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszA, -1, pszW, cch)) { LocalFree(pszW); pszW = NULL; } } return pszW; } //************************************************************* // // IsUserAnAdminMember() // // Purpose: Determines if the user is a member of the administrators group. // // Parameters: hToken - User's token // // Return: TRUE if user is a admin // FALSE if not // Comments: // // History: Date Author Comment // 7/25/95 ericflo Created // //************************************************************* BOOL IsUserAnAdminMember(HANDLE hToken) { SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; NTSTATUS Status; BOOL FoundAdmins = FALSE; PSID AdminsDomainSid=NULL; HANDLE hImpToken = NULL; // // Create Admins domain sid. // Status = RtlAllocateAndInitializeSid( &authNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminsDomainSid ); if (Status == STATUS_SUCCESS) { // // Test if user is in the Admins domain // if (!DuplicateTokenEx(hToken, TOKEN_IMPERSONATE | TOKEN_QUERY, NULL, SecurityImpersonation, TokenImpersonation, &hImpToken)) { DEBUGMSG((DM_WARNING, "IsUserAnAdminMember: DuplicateTokenEx failed with error %d", GetLastError())); FoundAdmins = FALSE; hImpToken = NULL; goto Exit; } if (!CheckTokenMembership(hImpToken, AdminsDomainSid, &FoundAdmins)) { DEBUGMSG((DM_WARNING, "IsUserAnAdminmember: CheckTokenMembership failed for AdminsDomainSid with error %d", GetLastError())); FoundAdmins = FALSE; } } // // Tidy up // Exit: if (hImpToken) CloseHandle(hImpToken); if (AdminsDomainSid) RtlFreeSid(AdminsDomainSid); return(FoundAdmins); }