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