/*++ Copyright (c) 1992 Microsoft Corporation Module Name: Takeown.c Abstract: Implements a recovery scheme to give an Administrator access to a file that has been denied to all. Author: Robert Reichel (robertre) 22-Jun-1992 Environment: Must be run from an Administrator account in order to perform reliably. Revision History: --*/ #include #include #include BOOL AssertTakeOwnership( HANDLE TokenHandle ); BOOL GetTokenHandle( PHANDLE TokenHandle ); BOOL VariableInitialization(); #define VERBOSE 0 PSID AliasAdminsSid = NULL; PSID SeWorldSid; static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY; static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY; VOID __cdecl main (int argc, char *argv[]) { BOOL Result; LPSTR lpFileName; SECURITY_DESCRIPTOR SecurityDescriptor; // CHAR Dacl[256]; HANDLE TokenHandle; // // We expect a file... // if (argc <= 1) { printf("Must specify a file name"); return; } lpFileName = argv[1]; #if VERBOSE printf("Filename is %s\n", lpFileName ); #endif Result = VariableInitialization(); if ( !Result ) { printf("Out of memory\n"); return; } Result = GetTokenHandle( &TokenHandle ); if ( !Result ) { // // This should not happen // printf("Unable to obtain the handle to our token, exiting\n"); return; } // // Attempt to put a NULL Dacl on the object // InitializeSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); // Result = InitializeAcl ( (PACL)Dacl, 256, ACL_REVISION2 ); // // if ( !Result ) { // printf("Unable to initialize Acl, exiting\n"); // return; // } // // // Result = AddAccessAllowedAce ( // (PACL)Dacl, // ACL_REVISION2, // GENERIC_ALL, // AliasAdminsSid // ); // // // // if ( !Result ) { // printf("Unable to create required ACL, error code = %d\n", GetLastError()); // printf("Exiting\n"); // return; // } Result = SetSecurityDescriptorDacl ( &SecurityDescriptor, TRUE, NULL, FALSE ); if ( !Result ) { printf("SetSecurityDescriptorDacl failed, error code = %d\n", GetLastError()); printf("Exiting\n"); return; } Result = SetFileSecurity( lpFileName, DACL_SECURITY_INFORMATION, &SecurityDescriptor ); if ( !Result ) { #if VERBOSE printf("SetFileSecurity failed, error code = %d\n", GetLastError()); #endif } else { printf("Successful, protection removed\n"); return; } // // That didn't work. // // // Attempt to make Administrator the owner of the file. // Result = SetSecurityDescriptorOwner ( &SecurityDescriptor, AliasAdminsSid, FALSE ); if ( !Result ) { printf("SetSecurityDescriptorOwner failed, lasterror = %d\n", GetLastError()); return; } Result = SetFileSecurity( lpFileName, OWNER_SECURITY_INFORMATION, &SecurityDescriptor ); if ( Result ) { #if VERBOSE printf("Owner successfully changed to Admin\n"); #endif } else { // // That didn't work either. // #if VERBOSE printf("Opening file for WRITE_OWNER failed\n"); printf("Attempting to assert TakeOwnership privilege\n"); #endif // // Assert TakeOwnership privilege, then try again // Result = AssertTakeOwnership( TokenHandle ); if ( !Result ) { printf("Could not enable SeTakeOwnership privilege\n"); printf("Log on as Administrator and try again\n"); return; } Result = SetFileSecurity( lpFileName, OWNER_SECURITY_INFORMATION, &SecurityDescriptor ); if ( Result ) { #if VERBOSE printf("Owner successfully changed to Administrator\n"); #endif } else { printf("Unable to assign Administrator as owner\n"); printf("Log on as Administrator and try again\n"); return; } } // // Try to put a benign DACL onto the file again // Result = SetFileSecurity( lpFileName, DACL_SECURITY_INFORMATION, &SecurityDescriptor ); if ( !Result ) { // // something is wrong // printf("SetFileSecurity unexpectedly failed, error code = %d\n", GetLastError()); } else { printf("Successful, protection removed\n"); return; } } BOOL GetTokenHandle( PHANDLE TokenHandle ) { HANDLE ProcessHandle; BOOL Result; ProcessHandle = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId() ); if ( ProcessHandle == NULL ) { // // This should not happen // return( FALSE ); } Result = OpenProcessToken ( ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TokenHandle ); if ( !Result ) { CloseHandle(ProcessHandle); // // This should not happen // return FALSE; } CloseHandle(ProcessHandle); return( TRUE ); } BOOL AssertTakeOwnership( HANDLE TokenHandle ) { LUID TakeOwnershipValue; BOOL Result; TOKEN_PRIVILEGES TokenPrivileges; // // First, assert TakeOwnership privilege // Result = LookupPrivilegeValue( NULL, "SeTakeOwnershipPrivilege", &TakeOwnershipValue ); if ( !Result ) { // // This should not happen // printf("Unable to obtain value of TakeOwnership privilege\n"); printf("Error = %d\n",GetLastError()); printf("Exiting\n"); return FALSE; } // // Set up the privilege set we will need // TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Luid = TakeOwnershipValue; TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; (VOID) AdjustTokenPrivileges ( TokenHandle, FALSE, &TokenPrivileges, sizeof( TOKEN_PRIVILEGES ), NULL, NULL ); if ( GetLastError() != NO_ERROR ) { #if VERBOSE printf("GetLastError returned %d from AdjustTokenPrivileges\n", GetLastError() ); #endif return FALSE; } else { #if VERBOSE printf("TakeOwnership privilege enabled\n"); #endif } return( TRUE ); } BOOL VariableInitialization() { BOOL Result; Result = AllocateAndInitializeSid( &SepNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AliasAdminsSid ); if ( !Result ) { return( FALSE ); } Result = AllocateAndInitializeSid( &SepWorldSidAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &SeWorldSid ); if ( !Result ) { return( FALSE ); } return( TRUE ); }