Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Takeown.c
  5. Abstract:
  6. Implements a recovery scheme to give an Administrator
  7. access to a file that has been denied to all.
  8. Author:
  9. Robert Reichel (robertre) 22-Jun-1992
  10. Environment:
  11. Must be run from an Administrator account in order
  12. to perform reliably.
  13. Revision History:
  14. --*/
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. BOOL
  19. AssertTakeOwnership(
  20. HANDLE TokenHandle
  21. );
  22. BOOL
  23. GetTokenHandle(
  24. PHANDLE TokenHandle
  25. );
  26. BOOL
  27. VariableInitialization();
  28. #define VERBOSE 0
  29. PSID AliasAdminsSid = NULL;
  30. PSID SeWorldSid;
  31. static SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY;
  32. static SID_IDENTIFIER_AUTHORITY SepWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  33. VOID __cdecl
  34. main (int argc, char *argv[])
  35. {
  36. BOOL Result;
  37. LPSTR lpFileName;
  38. SECURITY_DESCRIPTOR SecurityDescriptor;
  39. // CHAR Dacl[256];
  40. HANDLE TokenHandle;
  41. //
  42. // We expect a file...
  43. //
  44. if (argc <= 1) {
  45. printf("Must specify a file name");
  46. return;
  47. }
  48. lpFileName = argv[1];
  49. #if VERBOSE
  50. printf("Filename is %s\n", lpFileName );
  51. #endif
  52. Result = VariableInitialization();
  53. if ( !Result ) {
  54. printf("Out of memory\n");
  55. return;
  56. }
  57. Result = GetTokenHandle( &TokenHandle );
  58. if ( !Result ) {
  59. //
  60. // This should not happen
  61. //
  62. printf("Unable to obtain the handle to our token, exiting\n");
  63. return;
  64. }
  65. //
  66. // Attempt to put a NULL Dacl on the object
  67. //
  68. InitializeSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
  69. // Result = InitializeAcl ( (PACL)Dacl, 256, ACL_REVISION2 );
  70. //
  71. // if ( !Result ) {
  72. // printf("Unable to initialize Acl, exiting\n");
  73. // return;
  74. // }
  75. //
  76. //
  77. // Result = AddAccessAllowedAce (
  78. // (PACL)Dacl,
  79. // ACL_REVISION2,
  80. // GENERIC_ALL,
  81. // AliasAdminsSid
  82. // );
  83. //
  84. //
  85. //
  86. // if ( !Result ) {
  87. // printf("Unable to create required ACL, error code = %d\n", GetLastError());
  88. // printf("Exiting\n");
  89. // return;
  90. // }
  91. Result = SetSecurityDescriptorDacl (
  92. &SecurityDescriptor,
  93. TRUE,
  94. NULL,
  95. FALSE
  96. );
  97. if ( !Result ) {
  98. printf("SetSecurityDescriptorDacl failed, error code = %d\n", GetLastError());
  99. printf("Exiting\n");
  100. return;
  101. }
  102. Result = SetFileSecurity(
  103. lpFileName,
  104. DACL_SECURITY_INFORMATION,
  105. &SecurityDescriptor
  106. );
  107. if ( !Result ) {
  108. #if VERBOSE
  109. printf("SetFileSecurity failed, error code = %d\n", GetLastError());
  110. #endif
  111. } else {
  112. printf("Successful, protection removed\n");
  113. return;
  114. }
  115. //
  116. // That didn't work.
  117. //
  118. //
  119. // Attempt to make Administrator the owner of the file.
  120. //
  121. Result = SetSecurityDescriptorOwner (
  122. &SecurityDescriptor,
  123. AliasAdminsSid,
  124. FALSE
  125. );
  126. if ( !Result ) {
  127. printf("SetSecurityDescriptorOwner failed, lasterror = %d\n", GetLastError());
  128. return;
  129. }
  130. Result = SetFileSecurity(
  131. lpFileName,
  132. OWNER_SECURITY_INFORMATION,
  133. &SecurityDescriptor
  134. );
  135. if ( Result ) {
  136. #if VERBOSE
  137. printf("Owner successfully changed to Admin\n");
  138. #endif
  139. } else {
  140. //
  141. // That didn't work either.
  142. //
  143. #if VERBOSE
  144. printf("Opening file for WRITE_OWNER failed\n");
  145. printf("Attempting to assert TakeOwnership privilege\n");
  146. #endif
  147. //
  148. // Assert TakeOwnership privilege, then try again
  149. //
  150. Result = AssertTakeOwnership( TokenHandle );
  151. if ( !Result ) {
  152. printf("Could not enable SeTakeOwnership privilege\n");
  153. printf("Log on as Administrator and try again\n");
  154. return;
  155. }
  156. Result = SetFileSecurity(
  157. lpFileName,
  158. OWNER_SECURITY_INFORMATION,
  159. &SecurityDescriptor
  160. );
  161. if ( Result ) {
  162. #if VERBOSE
  163. printf("Owner successfully changed to Administrator\n");
  164. #endif
  165. } else {
  166. printf("Unable to assign Administrator as owner\n");
  167. printf("Log on as Administrator and try again\n");
  168. return;
  169. }
  170. }
  171. //
  172. // Try to put a benign DACL onto the file again
  173. //
  174. Result = SetFileSecurity(
  175. lpFileName,
  176. DACL_SECURITY_INFORMATION,
  177. &SecurityDescriptor
  178. );
  179. if ( !Result ) {
  180. //
  181. // something is wrong
  182. //
  183. printf("SetFileSecurity unexpectedly failed, error code = %d\n", GetLastError());
  184. } else {
  185. printf("Successful, protection removed\n");
  186. return;
  187. }
  188. }
  189. BOOL
  190. GetTokenHandle(
  191. PHANDLE TokenHandle
  192. )
  193. {
  194. HANDLE ProcessHandle;
  195. BOOL Result;
  196. ProcessHandle = OpenProcess(
  197. PROCESS_QUERY_INFORMATION,
  198. FALSE,
  199. GetCurrentProcessId()
  200. );
  201. if ( ProcessHandle == NULL ) {
  202. //
  203. // This should not happen
  204. //
  205. return( FALSE );
  206. }
  207. Result = OpenProcessToken (
  208. ProcessHandle,
  209. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  210. TokenHandle
  211. );
  212. if ( !Result ) {
  213. CloseHandle(ProcessHandle);
  214. //
  215. // This should not happen
  216. //
  217. return FALSE;
  218. }
  219. CloseHandle(ProcessHandle);
  220. return( TRUE );
  221. }
  222. BOOL
  223. AssertTakeOwnership(
  224. HANDLE TokenHandle
  225. )
  226. {
  227. LUID TakeOwnershipValue;
  228. BOOL Result;
  229. TOKEN_PRIVILEGES TokenPrivileges;
  230. //
  231. // First, assert TakeOwnership privilege
  232. //
  233. Result = LookupPrivilegeValue(
  234. NULL,
  235. "SeTakeOwnershipPrivilege",
  236. &TakeOwnershipValue
  237. );
  238. if ( !Result ) {
  239. //
  240. // This should not happen
  241. //
  242. printf("Unable to obtain value of TakeOwnership privilege\n");
  243. printf("Error = %d\n",GetLastError());
  244. printf("Exiting\n");
  245. return FALSE;
  246. }
  247. //
  248. // Set up the privilege set we will need
  249. //
  250. TokenPrivileges.PrivilegeCount = 1;
  251. TokenPrivileges.Privileges[0].Luid = TakeOwnershipValue;
  252. TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  253. (VOID) AdjustTokenPrivileges (
  254. TokenHandle,
  255. FALSE,
  256. &TokenPrivileges,
  257. sizeof( TOKEN_PRIVILEGES ),
  258. NULL,
  259. NULL
  260. );
  261. if ( GetLastError() != NO_ERROR ) {
  262. #if VERBOSE
  263. printf("GetLastError returned %d from AdjustTokenPrivileges\n", GetLastError() );
  264. #endif
  265. return FALSE;
  266. } else {
  267. #if VERBOSE
  268. printf("TakeOwnership privilege enabled\n");
  269. #endif
  270. }
  271. return( TRUE );
  272. }
  273. BOOL
  274. VariableInitialization()
  275. {
  276. BOOL Result;
  277. Result = AllocateAndInitializeSid(
  278. &SepNtAuthority,
  279. 2,
  280. SECURITY_BUILTIN_DOMAIN_RID,
  281. DOMAIN_ALIAS_RID_ADMINS,
  282. 0,
  283. 0,
  284. 0,
  285. 0,
  286. 0,
  287. 0,
  288. &AliasAdminsSid
  289. );
  290. if ( !Result ) {
  291. return( FALSE );
  292. }
  293. Result = AllocateAndInitializeSid(
  294. &SepWorldSidAuthority,
  295. 1,
  296. SECURITY_WORLD_RID,
  297. 0,
  298. 0,
  299. 0,
  300. 0,
  301. 0,
  302. 0,
  303. 0,
  304. &SeWorldSid
  305. );
  306. if ( !Result ) {
  307. return( FALSE );
  308. }
  309. return( TRUE );
  310. }