windows-nt/Source/XPSP1/NT/base/ntos/config/test/rtsetsec.c
2020-09-26 16:20:57 +08:00

320 lines
8.1 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
rtsetsec.c
Abstract:
NT level registry security test program
Assigns a world read-only security descriptor to an existing registry
key object.
rtsetsec <KeyPath>
Example:
rtsetsec \REGISTRY\MACHINE\TEST\read_only
Author:
John Vert (jvert) 28-Jan-92
Revision History:
Richard Ward (richardw) 14 April 92 Changed ACE_HEADER
--*/
#include "cmp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
PSID
GetMySid(
VOID
);
PSECURITY_DESCRIPTOR
GenerateDescriptor(
VOID
);
void
__cdecl main(
int argc,
char *argv[]
)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
ANSI_STRING AnsiKeyName;
HANDLE KeyHandle;
PSECURITY_DESCRIPTOR NewSecurityDescriptor;
//
// Process args
//
if (argc != 2) {
printf("Usage: %s <KeyPath>\n",argv[0]);
exit(1);
}
RtlInitAnsiString(&AnsiKeyName, argv[1]);
Status = RtlAnsiStringToUnicodeString(&KeyName, &AnsiKeyName, TRUE);
if (!NT_SUCCESS(Status)) {
printf("RtlAnsiStringToUnicodeString failed %lx\n",Status);
exit(1);
}
printf("rtsetsec: starting\n");
//
// Open node that we want to change the security descriptor for.
//
InitializeObjectAttributes(
&ObjectAttributes,
&KeyName,
0,
(HANDLE)NULL,
NULL
);
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
Status = NtOpenKey(
&KeyHandle,
WRITE_DAC,
&ObjectAttributes
);
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: NtOpenKey failed: %08lx\n", Status);
exit(1);
}
NewSecurityDescriptor = GenerateDescriptor();
Status = NtSetSecurityObject( KeyHandle,
DACL_SECURITY_INFORMATION,
NewSecurityDescriptor);
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: NtSetSecurity failed: %08lx\n",Status);
exit(1);
}
Status = NtClose(KeyHandle);
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: NtClose failed: %08lx\n", Status);
exit(1);
}
printf("rtsetsec: successful\n");
}
PSECURITY_DESCRIPTOR
GenerateDescriptor(
VOID
)
{
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Acl;
PSID WorldSid, CreatorSid;
SID_IDENTIFIER_AUTHORITY WorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
ULONG OwnerAceLength, WorldAceLength;
ULONG AclLength;
NTSTATUS Status;
PACCESS_ALLOWED_ACE OwnerAce;
PACCESS_ALLOWED_ACE WorldAce;
WorldSid = malloc(RtlLengthRequiredSid(1));
if (WorldSid == NULL) {
printf("rtsetsec: GenerateDescriptor() couldn't malloc WorldSID\n");
exit(1);
}
RtlInitializeSid(WorldSid, &WorldAuthority, 1);
*(RtlSubAuthoritySid(WorldSid, 0)) = SECURITY_WORLD_RID;
if (!RtlValidSid(WorldSid)) {
printf("rtsetsec: GenerateDescriptor() created invalid World SID\n");
exit(1);
}
CreatorSid = GetMySid();
//
// Since the ACCESS_DENIED_ACE already contains a ULONG for the
// SID, we subtract this back out when calculating the size of the ACE
//
WorldAceLength = SeLengthSid(WorldSid) -
sizeof(ULONG) +
sizeof(ACCESS_ALLOWED_ACE) ;
WorldAce = malloc(WorldAceLength);
if (WorldAce == NULL) {
printf("rtsetsec: GenerateDescriptor() couldn't malloc WorldAce\n");
exit(1);
}
OwnerAceLength = SeLengthSid(CreatorSid) -
sizeof(ULONG) +
sizeof(ACCESS_ALLOWED_ACE);
OwnerAce = malloc( OwnerAceLength );
if (OwnerAce == NULL) {
printf("rtsetsec: GenerateDescriptor() couldn't malloc OwnerAce\n");
exit(1);
}
AclLength = OwnerAceLength + WorldAceLength + sizeof(ACL);
Acl = malloc(AclLength);
if (Acl == NULL) {
printf("rtsetsec: GenerateDescriptor() couldn't malloc ACL\n");
exit(1);
}
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlCreateAcl failed status %08lx\n", Status);
exit(1);
}
//
// Fill in ACE fields
//
WorldAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
WorldAce->Header.AceSize = (USHORT)WorldAceLength;
WorldAce->Header.AceFlags = 0; // clear audit and inherit flags
WorldAce->Mask = KEY_READ;
Status = RtlCopySid( SeLengthSid(WorldSid),
&WorldAce->SidStart,
WorldSid );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlCopySid failed status %08lx\n", Status);
exit(1);
}
OwnerAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
OwnerAce->Header.AceSize = (USHORT)OwnerAceLength;
OwnerAce->Header.AceFlags = 0; // clear audit and inherit flags
OwnerAce->Mask = KEY_ALL_ACCESS;
Status = RtlCopySid( SeLengthSid(CreatorSid),
&OwnerAce->SidStart,
CreatorSid );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlCopySid failed status %08lx\n", Status);
exit(1);
}
free(WorldSid);
//
// Now add the ACE to the beginning of the ACL.
//
Status = RtlAddAce( Acl,
ACL_REVISION,
0,
WorldAce,
WorldAceLength );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlAddAce (world ace) failed status %08lx\n", Status);
exit(1);
}
Status = RtlAddAce( Acl,
ACL_REVISION,
0,
OwnerAce,
OwnerAceLength );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlAddAce (owner ace) failed status %08lx\n", Status);
exit(1);
}
free(OwnerAce);
free(WorldAce);
//
// Allocate and initialize the Security Descriptor
//
SecurityDescriptor = malloc(sizeof(SECURITY_DESCRIPTOR));
Status = RtlCreateSecurityDescriptor( SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlCreateSecurityDescriptor failed status %08lx\n",Status);
exit(1);
}
Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor,
TRUE,
Acl,
FALSE );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: RtlSetDaclSecurityDescriptor failed status %08lx\n",Status);
exit(1);
}
//
// FINALLY we are finished!
//
return(SecurityDescriptor);
}
PSID
GetMySid(
VOID
)
{
NTSTATUS Status;
HANDLE Token;
PTOKEN_OWNER Owner;
ULONG Length;
Status = NtOpenProcessToken( NtCurrentProcess(),
TOKEN_QUERY,
&Token );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: GetMySid() NtOpenProcessToken failed status %08lx\n",Status);
exit(1);
}
Status = NtQueryInformationToken( Token,
TokenOwner,
Owner,
0,
&Length );
if (Status != STATUS_BUFFER_TOO_SMALL) {
printf("rtsetsec: GetMySid() NtQueryInformationToken failed status %08lx\n",Status);
exit(1);
}
Owner = malloc(Length);
if (Owner==NULL) {
printf("rtsetsec: GetMySid() Couldn't malloc TOKEN_OWNER buffer\n");
exit(1);
}
Status = NtQueryInformationToken( Token,
TokenOwner,
Owner,
Length,
&Length );
if (!NT_SUCCESS(Status)) {
printf("rtsetsec: GetMySid() NtQueryInformationToken failed status %08lx\n",Status);
exit(1);
}
NtClose(Token);
return(Owner->Owner);
}