windows-nt/Source/XPSP1/NT/sdktools/takeown/takeown.c
2020-09-26 16:20:57 +08:00

467 lines
8 KiB
C

/*++
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 <windows.h>
#include <stdio.h>
#include <malloc.h>
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 );
}