|
|
1.1 root 1: 1.1.1.2 ! root 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: ! 12: /*++ 1.1 root 13: 14: Module Name: 15: 16: Takeown.c 17: 18: Abstract: 19: 20: Implements a recovery scheme to give an Administrator access to a 21: file that has been denied to all. 22: 23: Environment: 24: 25: Must be run from an Administrator account in order to perform 26: reliably. 27: 28: --*/ 29: #include <windows.h> 30: #include <stdio.h> 31: #include <malloc.h> 32: 33: BOOL 34: AssertTakeOwnership( 35: HANDLE TokenHandle 36: ); 37: 38: BOOL 39: GetTokenHandle( 40: PHANDLE TokenHandle 41: ); 42: 43: BOOL 44: VariableInitialization(); 45: 46: 47: 48: 49: PSID AliasAdminsSid = NULL; 50: PSID SeWorldSid; 51: 52: static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY; 53: static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY; 54: 55: 56: 57: 58: void main (int argc, char *argv[]) 59: { 60: 61: 62: BOOL Result; 63: LPSTR lpFileName; 64: SECURITY_DESCRIPTOR SecurityDescriptor; 65: HANDLE TokenHandle; 66: 67: 68: // 69: // We expect a file... 70: // 71: if (argc <= 1) { 72: 73: printf("Must specify a file name"); 74: return; 75: } 76: 77: 78: lpFileName = argv[1]; 79: 80: 81: Result = VariableInitialization(); 82: 83: if ( !Result ) { 84: printf("Out of memory\n"); 85: return; 86: } 87: 88: 89: 90: 91: Result = GetTokenHandle( &TokenHandle ); 92: 93: if ( !Result ) { 94: 95: // 96: // This should not happen 97: // 98: 99: printf("Unable to obtain the handle to our token, exiting\n"); 100: return; 101: } 102: 103: 104: 105: 106: 107: 108: // 109: // Attempt to put a NULL Dacl on the object 110: // 111: 112: InitializeSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); 113: 114: 115: Result = SetSecurityDescriptorDacl ( 116: &SecurityDescriptor, 117: TRUE, 118: NULL, 119: FALSE 120: ); 121: 122: 123: 124: if ( !Result ) { 125: printf("SetSecurityDescriptorDacl failed, error code = %d\n", GetLastError()); 126: printf("Exiting\n"); 127: return; 128: } 129: 130: Result = SetFileSecurity( 131: lpFileName, 132: DACL_SECURITY_INFORMATION, 133: &SecurityDescriptor 134: ); 135: 136: if ( Result ) { 137: 138: printf("Successful, protection removed\n"); 139: return; 140: } 141: 142: 143: // 144: // That didn't work. 145: // 146: 147: 148: // 149: // Attempt to make Administrator the owner of the file. 150: // 151: 152: 153: Result = SetSecurityDescriptorOwner ( 154: &SecurityDescriptor, 155: AliasAdminsSid, 156: FALSE 157: ); 158: 159: if ( !Result ) { 160: printf("SetSecurityDescriptorOwner failed, lasterror = %d\n", GetLastError()); 161: return; 162: } 163: 164: 165: Result = SetFileSecurity( 166: lpFileName, 167: OWNER_SECURITY_INFORMATION, 168: &SecurityDescriptor 169: ); 170: 171: if ( !Result ) { 172: 173: 174: // 175: // That didn't work either. 176: // 177: 178: 179: 180: // 181: // Assert TakeOwnership privilege, then try again. Note that 182: // since the privilege is only enabled for the duration of 183: // this process, we don't have to worry about turning it off 184: // again. 185: // 186: 187: Result = AssertTakeOwnership( TokenHandle ); 188: 189: if ( !Result ) { 190: printf("Could not enable SeTakeOwnership privilege\n"); 191: printf("Log on as Administrator and try again\n"); 192: return; 193: } 194: 195: 196: Result = SetFileSecurity( 197: lpFileName, 198: OWNER_SECURITY_INFORMATION, 199: &SecurityDescriptor 200: ); 201: 202: if ( !Result ) { 203: 204: printf("Unable to assign Administrator as owner\n"); 205: printf("Log on as Administrator and try again\n"); 206: return; 207: 208: } 209: } 210: 211: // 212: // Try to put a benign DACL onto the file again 213: // 214: 215: Result = SetFileSecurity( 216: lpFileName, 217: DACL_SECURITY_INFORMATION, 218: &SecurityDescriptor 219: ); 220: 221: if ( !Result ) { 222: 223: // 224: // This should not happen. 225: // 226: 227: printf("SetFileSecurity unexpectedly failed, error code = %d\n", GetLastError()); 228: 229: } else { 230: 231: printf("Successful, protection removed\n"); 232: return; 233: } 234: } 235: 236: 237: 238: 239: 240: BOOL 241: GetTokenHandle( 242: PHANDLE TokenHandle 243: ) 244: // 245: // This routine will open the current process and return 246: // a handle to its token. 247: // 248: // These handles will be closed for us when the process 249: // exits. 250: // 251: { 252: 253: HANDLE ProcessHandle; 254: BOOL Result; 255: 256: ProcessHandle = OpenProcess( 257: PROCESS_QUERY_INFORMATION, 258: FALSE, 259: GetCurrentProcessId() 260: ); 261: 262: if ( ProcessHandle == NULL ) { 263: 264: // 265: // This should not happen 266: // 267: 268: return( FALSE ); 269: } 270: 271: 272: Result = OpenProcessToken ( 273: ProcessHandle, 274: TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 275: TokenHandle 276: ); 277: 278: if ( !Result ) { 279: 280: // 281: // This should not happen 282: // 283: 284: return( FALSE ); 285: 286: } 287: 288: return( TRUE ); 289: } 290: 291: 292: BOOL 293: AssertTakeOwnership( 294: HANDLE TokenHandle 295: ) 296: // 297: // This routine turns on SeTakeOwnershipPrivilege in the current 298: // token. Once that has been accomplished, we can open the file 299: // for WRITE_OWNER even if we are denied that access by the ACL 300: // on the file. 301: 302: { 303: LUID TakeOwnershipValue; 304: BOOL Result; 305: TOKEN_PRIVILEGES TokenPrivileges; 306: 307: 308: // 309: // First, find out the value of TakeOwnershipPrivilege 310: // 311: 312: 313: Result = LookupPrivilegeValue( 314: NULL, 315: "SeTakeOwnershipPrivilege", 316: &TakeOwnershipValue 317: ); 318: 319: if ( !Result ) { 320: 321: // 322: // This should not happen 323: // 324: 325: printf("Unable to obtain value of TakeOwnership privilege\n"); 326: printf("Error = %d\n",GetLastError()); 327: printf("Exiting\n"); 328: return FALSE; 329: } 330: 331: // 332: // Set up the privilege set we will need 333: // 334: 335: TokenPrivileges.PrivilegeCount = 1; 336: TokenPrivileges.Privileges[0].Luid = TakeOwnershipValue; 337: TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 338: 339: 340: 341: 342: (VOID) AdjustTokenPrivileges ( 343: TokenHandle, 344: FALSE, 345: &TokenPrivileges, 346: sizeof( TOKEN_PRIVILEGES ), 347: NULL, 348: NULL 349: ); 350: 351: if ( GetLastError() != NO_ERROR ) { 352: 353: return( FALSE ); 354: 355: } else { 356: 357: return( TRUE ); 358: } 359: 360: } 361: 362: 363: 364: BOOL 365: VariableInitialization() 366: 367: // 368: // Create some useful SIDs. 369: // 370: 371: { 372: 373: BOOL Result; 374: 375: Result = AllocateAndInitializeSid( 376: &SepNtAuthority, 377: 2, 378: SECURITY_BUILTIN_DOMAIN_RID, 379: DOMAIN_ALIAS_RID_ADMINS, 380: 0, 381: 0, 382: 0, 383: 0, 384: 0, 385: 0, 386: &AliasAdminsSid 387: ); 388: 389: if ( !Result ) { 390: return( FALSE ); 391: } 392: 393: 394: Result = AllocateAndInitializeSid( 395: &SepWorldSidAuthority, 396: 1, 397: SECURITY_WORLD_RID, 398: 0, 399: 0, 400: 0, 401: 0, 402: 0, 403: 0, 404: 0, 405: &SeWorldSid 406: ); 407: 408: if ( !Result ) { 409: return( FALSE ); 410: } 411: 412: return( TRUE ); 413: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.