|
|
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.