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.

319 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. rtsetsec.c
  5. Abstract:
  6. NT level registry security test program
  7. Assigns a world read-only security descriptor to an existing registry
  8. key object.
  9. rtsetsec <KeyPath>
  10. Example:
  11. rtsetsec \REGISTRY\MACHINE\TEST\read_only
  12. Author:
  13. John Vert (jvert) 28-Jan-92
  14. Revision History:
  15. Richard Ward (richardw) 14 April 92 Changed ACE_HEADER
  16. --*/
  17. #include "cmp.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. PSID
  22. GetMySid(
  23. VOID
  24. );
  25. PSECURITY_DESCRIPTOR
  26. GenerateDescriptor(
  27. VOID
  28. );
  29. void
  30. __cdecl main(
  31. int argc,
  32. char *argv[]
  33. )
  34. {
  35. NTSTATUS Status;
  36. OBJECT_ATTRIBUTES ObjectAttributes;
  37. UNICODE_STRING KeyName;
  38. ANSI_STRING AnsiKeyName;
  39. HANDLE KeyHandle;
  40. PSECURITY_DESCRIPTOR NewSecurityDescriptor;
  41. //
  42. // Process args
  43. //
  44. if (argc != 2) {
  45. printf("Usage: %s <KeyPath>\n",argv[0]);
  46. exit(1);
  47. }
  48. RtlInitAnsiString(&AnsiKeyName, argv[1]);
  49. Status = RtlAnsiStringToUnicodeString(&KeyName, &AnsiKeyName, TRUE);
  50. if (!NT_SUCCESS(Status)) {
  51. printf("RtlAnsiStringToUnicodeString failed %lx\n",Status);
  52. exit(1);
  53. }
  54. printf("rtsetsec: starting\n");
  55. //
  56. // Open node that we want to change the security descriptor for.
  57. //
  58. InitializeObjectAttributes(
  59. &ObjectAttributes,
  60. &KeyName,
  61. 0,
  62. (HANDLE)NULL,
  63. NULL
  64. );
  65. ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
  66. Status = NtOpenKey(
  67. &KeyHandle,
  68. WRITE_DAC,
  69. &ObjectAttributes
  70. );
  71. if (!NT_SUCCESS(Status)) {
  72. printf("rtsetsec: NtOpenKey failed: %08lx\n", Status);
  73. exit(1);
  74. }
  75. NewSecurityDescriptor = GenerateDescriptor();
  76. Status = NtSetSecurityObject( KeyHandle,
  77. DACL_SECURITY_INFORMATION,
  78. NewSecurityDescriptor);
  79. if (!NT_SUCCESS(Status)) {
  80. printf("rtsetsec: NtSetSecurity failed: %08lx\n",Status);
  81. exit(1);
  82. }
  83. Status = NtClose(KeyHandle);
  84. if (!NT_SUCCESS(Status)) {
  85. printf("rtsetsec: NtClose failed: %08lx\n", Status);
  86. exit(1);
  87. }
  88. printf("rtsetsec: successful\n");
  89. }
  90. PSECURITY_DESCRIPTOR
  91. GenerateDescriptor(
  92. VOID
  93. )
  94. {
  95. PSECURITY_DESCRIPTOR SecurityDescriptor;
  96. PACL Acl;
  97. PSID WorldSid, CreatorSid;
  98. SID_IDENTIFIER_AUTHORITY WorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
  99. ULONG OwnerAceLength, WorldAceLength;
  100. ULONG AclLength;
  101. NTSTATUS Status;
  102. PACCESS_ALLOWED_ACE OwnerAce;
  103. PACCESS_ALLOWED_ACE WorldAce;
  104. WorldSid = malloc(RtlLengthRequiredSid(1));
  105. if (WorldSid == NULL) {
  106. printf("rtsetsec: GenerateDescriptor() couldn't malloc WorldSID\n");
  107. exit(1);
  108. }
  109. RtlInitializeSid(WorldSid, &WorldAuthority, 1);
  110. *(RtlSubAuthoritySid(WorldSid, 0)) = SECURITY_WORLD_RID;
  111. if (!RtlValidSid(WorldSid)) {
  112. printf("rtsetsec: GenerateDescriptor() created invalid World SID\n");
  113. exit(1);
  114. }
  115. CreatorSid = GetMySid();
  116. //
  117. // Since the ACCESS_DENIED_ACE already contains a ULONG for the
  118. // SID, we subtract this back out when calculating the size of the ACE
  119. //
  120. WorldAceLength = SeLengthSid(WorldSid) -
  121. sizeof(ULONG) +
  122. sizeof(ACCESS_ALLOWED_ACE) ;
  123. WorldAce = malloc(WorldAceLength);
  124. if (WorldAce == NULL) {
  125. printf("rtsetsec: GenerateDescriptor() couldn't malloc WorldAce\n");
  126. exit(1);
  127. }
  128. OwnerAceLength = SeLengthSid(CreatorSid) -
  129. sizeof(ULONG) +
  130. sizeof(ACCESS_ALLOWED_ACE);
  131. OwnerAce = malloc( OwnerAceLength );
  132. if (OwnerAce == NULL) {
  133. printf("rtsetsec: GenerateDescriptor() couldn't malloc OwnerAce\n");
  134. exit(1);
  135. }
  136. AclLength = OwnerAceLength + WorldAceLength + sizeof(ACL);
  137. Acl = malloc(AclLength);
  138. if (Acl == NULL) {
  139. printf("rtsetsec: GenerateDescriptor() couldn't malloc ACL\n");
  140. exit(1);
  141. }
  142. Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
  143. if (!NT_SUCCESS(Status)) {
  144. printf("rtsetsec: RtlCreateAcl failed status %08lx\n", Status);
  145. exit(1);
  146. }
  147. //
  148. // Fill in ACE fields
  149. //
  150. WorldAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  151. WorldAce->Header.AceSize = (USHORT)WorldAceLength;
  152. WorldAce->Header.AceFlags = 0; // clear audit and inherit flags
  153. WorldAce->Mask = KEY_READ;
  154. Status = RtlCopySid( SeLengthSid(WorldSid),
  155. &WorldAce->SidStart,
  156. WorldSid );
  157. if (!NT_SUCCESS(Status)) {
  158. printf("rtsetsec: RtlCopySid failed status %08lx\n", Status);
  159. exit(1);
  160. }
  161. OwnerAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  162. OwnerAce->Header.AceSize = (USHORT)OwnerAceLength;
  163. OwnerAce->Header.AceFlags = 0; // clear audit and inherit flags
  164. OwnerAce->Mask = KEY_ALL_ACCESS;
  165. Status = RtlCopySid( SeLengthSid(CreatorSid),
  166. &OwnerAce->SidStart,
  167. CreatorSid );
  168. if (!NT_SUCCESS(Status)) {
  169. printf("rtsetsec: RtlCopySid failed status %08lx\n", Status);
  170. exit(1);
  171. }
  172. free(WorldSid);
  173. //
  174. // Now add the ACE to the beginning of the ACL.
  175. //
  176. Status = RtlAddAce( Acl,
  177. ACL_REVISION,
  178. 0,
  179. WorldAce,
  180. WorldAceLength );
  181. if (!NT_SUCCESS(Status)) {
  182. printf("rtsetsec: RtlAddAce (world ace) failed status %08lx\n", Status);
  183. exit(1);
  184. }
  185. Status = RtlAddAce( Acl,
  186. ACL_REVISION,
  187. 0,
  188. OwnerAce,
  189. OwnerAceLength );
  190. if (!NT_SUCCESS(Status)) {
  191. printf("rtsetsec: RtlAddAce (owner ace) failed status %08lx\n", Status);
  192. exit(1);
  193. }
  194. free(OwnerAce);
  195. free(WorldAce);
  196. //
  197. // Allocate and initialize the Security Descriptor
  198. //
  199. SecurityDescriptor = malloc(sizeof(SECURITY_DESCRIPTOR));
  200. Status = RtlCreateSecurityDescriptor( SecurityDescriptor,
  201. SECURITY_DESCRIPTOR_REVISION );
  202. if (!NT_SUCCESS(Status)) {
  203. printf("rtsetsec: RtlCreateSecurityDescriptor failed status %08lx\n",Status);
  204. exit(1);
  205. }
  206. Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor,
  207. TRUE,
  208. Acl,
  209. FALSE );
  210. if (!NT_SUCCESS(Status)) {
  211. printf("rtsetsec: RtlSetDaclSecurityDescriptor failed status %08lx\n",Status);
  212. exit(1);
  213. }
  214. //
  215. // FINALLY we are finished!
  216. //
  217. return(SecurityDescriptor);
  218. }
  219. PSID
  220. GetMySid(
  221. VOID
  222. )
  223. {
  224. NTSTATUS Status;
  225. HANDLE Token;
  226. PTOKEN_OWNER Owner;
  227. ULONG Length;
  228. Status = NtOpenProcessToken( NtCurrentProcess(),
  229. TOKEN_QUERY,
  230. &Token );
  231. if (!NT_SUCCESS(Status)) {
  232. printf("rtsetsec: GetMySid() NtOpenProcessToken failed status %08lx\n",Status);
  233. exit(1);
  234. }
  235. Status = NtQueryInformationToken( Token,
  236. TokenOwner,
  237. Owner,
  238. 0,
  239. &Length );
  240. if (Status != STATUS_BUFFER_TOO_SMALL) {
  241. printf("rtsetsec: GetMySid() NtQueryInformationToken failed status %08lx\n",Status);
  242. exit(1);
  243. }
  244. Owner = malloc(Length);
  245. if (Owner==NULL) {
  246. printf("rtsetsec: GetMySid() Couldn't malloc TOKEN_OWNER buffer\n");
  247. exit(1);
  248. }
  249. Status = NtQueryInformationToken( Token,
  250. TokenOwner,
  251. Owner,
  252. Length,
  253. &Length );
  254. if (!NT_SUCCESS(Status)) {
  255. printf("rtsetsec: GetMySid() NtQueryInformationToken failed status %08lx\n",Status);
  256. exit(1);
  257. }
  258. NtClose(Token);
  259. return(Owner->Owner);
  260. }