Source code of Windows XP (NT5)
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.

453 lines
12 KiB

  1. /****************************************************************************
  2. PROGRAM: TOKEN.C
  3. PURPOSE: Contains routines that manipulate tokens
  4. ****************************************************************************/
  5. #include "SECEDIT.h"
  6. #include <sedapi.h>
  7. BOOL
  8. EditTokenDefaultAcl(
  9. HWND Owner,
  10. HANDLE Instance,
  11. LPWSTR ObjectName,
  12. HANDLE Token,
  13. PSECURITY_DESCRIPTOR SecurityDescriptor,
  14. DWORD *EditResult
  15. );
  16. /***************************************************************************\
  17. * ApplySecurity
  18. *
  19. * Purpose : Called by ACL editor to set new default DACL on token
  20. *
  21. * Returns ERROR_SUCCESS or win error code.
  22. *
  23. * History:
  24. * 09-17-92 Davidc Created.
  25. \***************************************************************************/
  26. DWORD
  27. ApplySecurity(
  28. HWND hwndParent,
  29. HANDLE hInstance,
  30. ULONG CallbackContext,
  31. PSECURITY_DESCRIPTOR SecDesc,
  32. PSECURITY_DESCRIPTOR SecDescNewObjects,
  33. BOOLEAN ApplyToSubContainers,
  34. BOOLEAN ApplyToSubObjects,
  35. LPDWORD StatusReturn
  36. )
  37. {
  38. HANDLE MyToken = (HANDLE)CallbackContext;
  39. HANDLE Token = NULL;
  40. PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
  41. NTSTATUS Status;
  42. BOOLEAN DaclPresent;
  43. BOOLEAN DaclDefaulted;
  44. *StatusReturn = SED_STATUS_FAILED_TO_MODIFY;
  45. //
  46. // Get a handle to the token
  47. //
  48. Token = OpenToken(MyToken, TOKEN_ADJUST_DEFAULT);
  49. if (Token == NULL) {
  50. DbgPrint("SECEDIT : Failed to open the token for TOKEN_ADJUST_DEFAULT access\n");
  51. goto CleanupAndExit;
  52. }
  53. DefaultDacl = Alloc(sizeof(TOKEN_DEFAULT_DACL));
  54. if (DefaultDacl == NULL) {
  55. goto CleanupAndExit;
  56. }
  57. Status = RtlGetDaclSecurityDescriptor (
  58. SecDesc,
  59. &DaclPresent,
  60. &DefaultDacl->DefaultDacl,
  61. &DaclDefaulted
  62. );
  63. ASSERT(NT_SUCCESS(Status));
  64. ASSERT(DaclPresent);
  65. if (SetTokenInfo(Token, TokenDefaultDacl, (PVOID)DefaultDacl)) {
  66. *StatusReturn = SED_STATUS_MODIFIED;
  67. }
  68. CleanupAndExit:
  69. if (Token != NULL) {
  70. CloseToken(Token);
  71. }
  72. if (DefaultDacl != NULL) {
  73. Free(DefaultDacl);
  74. }
  75. if (*StatusReturn != SED_STATUS_MODIFIED) {
  76. MessageBox(hwndParent, "Failed to set default DACL", NULL, MB_ICONSTOP | MB_APPLMODAL | MB_OK);
  77. }
  78. return(ERROR_SUCCESS);
  79. }
  80. /***************************************************************************\
  81. * EditDefaultAcl
  82. *
  83. * Purpose : Displays and allows the user to edit the default Acl on the
  84. * passed token.
  85. *
  86. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  87. *
  88. * History:
  89. * 09-17-92 Davidc Created.
  90. \***************************************************************************/
  91. BOOL
  92. EditDefaultDacl(
  93. HWND hwndOwner,
  94. HANDLE Instance,
  95. HANDLE MyToken
  96. )
  97. {
  98. NTSTATUS Status;
  99. BOOL Success = FALSE;
  100. DWORD EditResult;
  101. HANDLE Token = NULL;
  102. PTOKEN_DEFAULT_DACL DefaultDacl = NULL;
  103. PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  104. PTOKEN_OWNER Owner = NULL;
  105. PTOKEN_PRIMARY_GROUP PrimaryGroup = NULL;
  106. WCHAR string[MAX_STRING_LENGTH];
  107. //
  108. // Get the window text so we can use it as the token name
  109. //
  110. GetWindowTextW(((PMYTOKEN)MyToken)->hwnd, string, sizeof(string)/sizeof(*string));
  111. //
  112. // Get a handle to the token
  113. //
  114. Token = OpenToken(MyToken, TOKEN_QUERY);
  115. if (Token == NULL) {
  116. DbgPrint("SECEDIT : Failed to open the token with TOKEN_QUERY access\n");
  117. goto CleanupAndExit;
  118. }
  119. //
  120. // Read the default DACL from the token
  121. //
  122. if (!GetTokenInfo(Token, TokenDefaultDacl, (PPVOID)&DefaultDacl)) {
  123. DbgPrint("SECEDIT : Failed to read default DACL from token\n");
  124. goto CleanupAndExit;
  125. }
  126. //
  127. // Get the owner and group of the token
  128. //
  129. if (!GetTokenInfo(Token, TokenOwner, (PPVOID)&Owner)) {
  130. DbgPrint("SECEDIT : Failed to read owner from token\n");
  131. goto CleanupAndExit;
  132. }
  133. if (!GetTokenInfo(Token, TokenPrimaryGroup, (PPVOID)&PrimaryGroup)) {
  134. DbgPrint("SECEDIT : Failed to read primary group from token\n");
  135. goto CleanupAndExit;
  136. }
  137. //
  138. // Create a security descriptor
  139. //
  140. SecurityDescriptor = Alloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
  141. if (SecurityDescriptor == NULL) {
  142. DbgPrint("SECEDIT : Failed to allocate security descriptor\n");
  143. goto CleanupAndExit;
  144. }
  145. Status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
  146. ASSERT(NT_SUCCESS(Status));
  147. //
  148. // Set the DACL on the security descriptor
  149. //
  150. Status = RtlSetDaclSecurityDescriptor(
  151. SecurityDescriptor,
  152. TRUE, // DACL present
  153. DefaultDacl->DefaultDacl,
  154. FALSE // DACL defaulted
  155. );
  156. ASSERT(NT_SUCCESS(Status));
  157. //
  158. // Put the owner and group in the security descriptor to keep the
  159. // ACL editor happy
  160. //
  161. Status = RtlSetOwnerSecurityDescriptor(
  162. SecurityDescriptor,
  163. Owner->Owner,
  164. FALSE // Owner defaulted
  165. );
  166. ASSERT(NT_SUCCESS(Status));
  167. Status = RtlSetGroupSecurityDescriptor(
  168. SecurityDescriptor,
  169. PrimaryGroup->PrimaryGroup,
  170. FALSE // Owner defaulted
  171. );
  172. ASSERT(NT_SUCCESS(Status));
  173. ASSERT(RtlValidSecurityDescriptor(SecurityDescriptor));
  174. //
  175. // Call the ACL editor, it will call our ApplySecurity function
  176. // to store any ACL changes in the token.
  177. //
  178. Success = EditTokenDefaultAcl(
  179. hwndOwner,
  180. Instance,
  181. string,
  182. MyToken,
  183. SecurityDescriptor,
  184. &EditResult
  185. );
  186. if (!Success) {
  187. DbgPrint("SECEDIT: Failed to edit token DACL\n");
  188. }
  189. CleanupAndExit:
  190. if (DefaultDacl != NULL) {
  191. FreeTokenInfo(DefaultDacl);
  192. }
  193. if (SecurityDescriptor != NULL) {
  194. FreeTokenInfo(SecurityDescriptor);
  195. }
  196. if (PrimaryGroup != NULL) {
  197. FreeTokenInfo(PrimaryGroup);
  198. }
  199. if (Owner != NULL) {
  200. FreeTokenInfo(Owner);
  201. }
  202. if (Token != NULL) {
  203. CloseToken(Token);
  204. }
  205. return(Success);
  206. }
  207. /***************************************************************************\
  208. * EditTokenDefaultAcl
  209. *
  210. * Purpose : Displays and allows the user to edit the default Acl on the
  211. * passed token.
  212. *
  213. * Returns TRUE on success, FALSE on failure (Use GetLastError for detail)
  214. *
  215. * History:
  216. * 09-17-92 Davidc Created.
  217. \***************************************************************************/
  218. BOOL
  219. EditTokenDefaultAcl(
  220. HWND Owner,
  221. HANDLE Instance,
  222. LPWSTR ObjectName,
  223. HANDLE MyToken,
  224. PSECURITY_DESCRIPTOR SecurityDescriptor,
  225. DWORD *EditResult
  226. )
  227. {
  228. DWORD Result;
  229. SED_OBJECT_TYPE_DESCRIPTOR sedobjdesc;
  230. GENERIC_MAPPING GenericMapping;
  231. SED_HELP_INFO sedhelpinfo ;
  232. SED_APPLICATION_ACCESSES SedAppAccesses ;
  233. SED_APPLICATION_ACCESS SedAppAccess[20];
  234. ULONG i;
  235. //
  236. // Initialize the application accesses
  237. //
  238. i=0;
  239. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  240. SedAppAccess[i].AccessMask1 = TOKEN_ASSIGN_PRIMARY;
  241. SedAppAccess[i].AccessMask2 = 0;
  242. SedAppAccess[i].PermissionTitle = L"Assign Primary";
  243. i++;
  244. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  245. SedAppAccess[i].AccessMask1 = TOKEN_DUPLICATE;
  246. SedAppAccess[i].AccessMask2 = 0;
  247. SedAppAccess[i].PermissionTitle = L"Duplicate";
  248. i++;
  249. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  250. SedAppAccess[i].AccessMask1 = TOKEN_IMPERSONATE;
  251. SedAppAccess[i].AccessMask2 = 0;
  252. SedAppAccess[i].PermissionTitle = L"Impersonate";
  253. i++;
  254. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  255. SedAppAccess[i].AccessMask1 = TOKEN_QUERY;
  256. SedAppAccess[i].AccessMask2 = 0;
  257. SedAppAccess[i].PermissionTitle = L"Query";
  258. i++;
  259. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  260. SedAppAccess[i].AccessMask1 = TOKEN_QUERY_SOURCE;
  261. SedAppAccess[i].AccessMask2 = 0;
  262. SedAppAccess[i].PermissionTitle = L"Query source";
  263. i++;
  264. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  265. SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_PRIVILEGES;
  266. SedAppAccess[i].AccessMask2 = 0;
  267. SedAppAccess[i].PermissionTitle = L"Adjust Privileges";
  268. i++;
  269. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  270. SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_GROUPS;
  271. SedAppAccess[i].AccessMask2 = 0;
  272. SedAppAccess[i].PermissionTitle = L"Adjust Groups";
  273. i++;
  274. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE_SPECIAL;
  275. SedAppAccess[i].AccessMask1 = TOKEN_ADJUST_DEFAULT;
  276. SedAppAccess[i].AccessMask2 = 0;
  277. SedAppAccess[i].PermissionTitle = L"Adjust Default";
  278. i++;
  279. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
  280. SedAppAccess[i].AccessMask1 = GENERIC_ALL;
  281. SedAppAccess[i].AccessMask2 = 0;
  282. SedAppAccess[i].PermissionTitle = L"All Access";
  283. i++;
  284. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
  285. SedAppAccess[i].AccessMask1 = TOKEN_READ;
  286. SedAppAccess[i].AccessMask2 = 0;
  287. SedAppAccess[i].PermissionTitle = L"Read";
  288. i++;
  289. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
  290. SedAppAccess[i].AccessMask1 = TOKEN_WRITE;
  291. SedAppAccess[i].AccessMask2 = 0;
  292. SedAppAccess[i].PermissionTitle = L"Write";
  293. i++;
  294. SedAppAccess[i].Type = SED_DESC_TYPE_RESOURCE;
  295. SedAppAccess[i].AccessMask1 = 0;
  296. SedAppAccess[i].AccessMask2 = 0;
  297. SedAppAccess[i].PermissionTitle = L"None";
  298. i++;
  299. ASSERT((sizeof(SedAppAccess)/sizeof(*SedAppAccess)) >= i);
  300. SedAppAccesses.Count = i;
  301. SedAppAccesses.AccessGroup = SedAppAccess;
  302. SedAppAccesses.DefaultPermName = L"Read";
  303. //
  304. // Initialize generic mapping
  305. //
  306. GenericMapping.GenericRead = TOKEN_READ;
  307. GenericMapping.GenericWrite = TOKEN_WRITE;
  308. GenericMapping.GenericExecute = TOKEN_EXECUTE;
  309. GenericMapping.GenericAll = TOKEN_ALL_ACCESS;
  310. //
  311. // Initialize help info
  312. //
  313. sedhelpinfo.pszHelpFileName = L"secedit.hlp";
  314. sedhelpinfo.aulHelpContext[HC_MAIN_DLG] = 0 ;
  315. sedhelpinfo.aulHelpContext[HC_SPECIAL_ACCESS_DLG] = 0 ;
  316. sedhelpinfo.aulHelpContext[HC_NEW_ITEM_SPECIAL_ACCESS_DLG] = 0 ;
  317. sedhelpinfo.aulHelpContext[HC_ADD_USER_DLG] = 0 ;
  318. //
  319. // Initialize object description
  320. //
  321. sedobjdesc.Revision = SED_REVISION1;
  322. sedobjdesc.IsContainer = FALSE;
  323. sedobjdesc.AllowNewObjectPerms = FALSE;
  324. sedobjdesc.MapSpecificPermsToGeneric = FALSE;
  325. sedobjdesc.GenericMapping = &GenericMapping;
  326. sedobjdesc.GenericMappingNewObjects = &GenericMapping;
  327. sedobjdesc.HelpInfo = &sedhelpinfo;
  328. sedobjdesc.ObjectTypeName = L"Token";
  329. sedobjdesc.ApplyToSubContainerTitle = L"ApplyToSubContainerTitle";
  330. sedobjdesc.ApplyToSubContainerHelpText = L"ApplyToSubContainerHelpText";
  331. sedobjdesc.ApplyToSubContainerConfirmation = L"ApplyToSubContainerConfirmation";
  332. sedobjdesc.SpecialObjectAccessTitle = L"Special...";
  333. sedobjdesc.SpecialNewObjectAccessTitle = L"SpecialNewObjectAccessTitle";
  334. //
  335. // Call the ACL editor, it will call our ApplySecurity function
  336. // to store any ACL changes in the token.
  337. //
  338. Result = SedDiscretionaryAclEditor(
  339. Owner,
  340. Instance,
  341. NULL, // server
  342. &sedobjdesc, // object type
  343. &SedAppAccesses, // application accesses
  344. ObjectName,
  345. ApplySecurity, // Callback
  346. (ULONG_PTR)MyToken, // Context
  347. SecurityDescriptor,
  348. FALSE, // Couldn't read DACL
  349. EditResult
  350. );
  351. if (Result != ERROR_SUCCESS) {
  352. DbgPrint("SECEDIT: Acleditor failed, error = %d\n", Result);
  353. SetLastError(Result);
  354. }
  355. return (Result == ERROR_SUCCESS);
  356. }