499 lines
12 KiB
C
499 lines
12 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
rtlassig.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This Module implements many security rtl routines defined in ntseapi.h
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jim Kelly (JimK) 23-Mar-1990
|
|||
|
Robert Reichel (RobertRe) 1-Mar-1991
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Pure Runtime Library Routine
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "ntrtlp.h"
|
|||
|
#include "seopaque.h"
|
|||
|
#include "sertlp.h"
|
|||
|
|
|||
|
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
|
|||
|
#pragma alloc_text(PAGE,RtlSelfRelativeToAbsoluteSD)
|
|||
|
#pragma alloc_text(PAGE,RtlMakeSelfRelativeSD)
|
|||
|
#pragma alloc_text(PAGE,RtlpQuerySecurityDescriptor)
|
|||
|
#pragma alloc_text(PAGE,RtlAbsoluteToSelfRelativeSD)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
///////////////////////////////////////////////////////////////////////////////
|
|||
|
// //
|
|||
|
// Exported Procedures //
|
|||
|
// //
|
|||
|
///////////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
RtlSelfRelativeToAbsoluteSD(
|
|||
|
IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
|
|||
|
OUT PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
|
|||
|
IN OUT PULONG AbsoluteSecurityDescriptorSize,
|
|||
|
IN OUT PACL Dacl,
|
|||
|
IN OUT PULONG DaclSize,
|
|||
|
IN OUT PACL Sacl,
|
|||
|
IN OUT PULONG SaclSize,
|
|||
|
IN OUT PSID Owner,
|
|||
|
IN OUT PULONG OwnerSize,
|
|||
|
IN OUT PSID PrimaryGroup,
|
|||
|
IN OUT PULONG PrimaryGroupSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Converts a security descriptor from self-relative format to absolute
|
|||
|
format
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SecurityDescriptor - Supplies a pointer to a security descriptor in
|
|||
|
Self-Relative format
|
|||
|
|
|||
|
AbsoluteSecurityDescriptor - A pointer to a buffer in which will be
|
|||
|
placed the main body of the Absolute format security descriptor.
|
|||
|
|
|||
|
Dacl - Supplies a pointer to a buffer that will contain the Dacl of the
|
|||
|
output descriptor. This pointer will be referenced by, not copied
|
|||
|
into, the output descriptor.
|
|||
|
|
|||
|
DaclSize - Supplies the size of the buffer pointed to by Dacl. In case
|
|||
|
of error, it will return the minimum size necessary to contain the
|
|||
|
Dacl.
|
|||
|
|
|||
|
Sacl - Supplies a pointer to a buffer that will contain the Sacl of the
|
|||
|
output descriptor. This pointer will be referenced by, not copied
|
|||
|
into, the output descriptor.
|
|||
|
|
|||
|
SaclSize - Supplies the size of the buffer pointed to by Sacl. In case
|
|||
|
of error, it will return the minimum size necessary to contain the
|
|||
|
Sacl.
|
|||
|
|
|||
|
Owner - Supplies a pointer to a buffer that will contain the Owner of
|
|||
|
the output descriptor. This pointer will be referenced by, not
|
|||
|
copied into, the output descriptor.
|
|||
|
|
|||
|
OwnerSize - Supplies the size of the buffer pointed to by Owner. In
|
|||
|
case of error, it will return the minimum size necessary to contain
|
|||
|
the Owner.
|
|||
|
|
|||
|
PrimaryGroup - Supplies a pointer to a buffer that will contain the
|
|||
|
PrimaryGroup of the output descriptor. This pointer will be
|
|||
|
referenced by, not copied into, the output descriptor.
|
|||
|
|
|||
|
PrimaryGroupSize - Supplies the size of the buffer pointed to by
|
|||
|
PrimaryGroup. In case of error, it will return the minimum size
|
|||
|
necessary to contain the PrimaryGroup.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS - Success
|
|||
|
|
|||
|
STATUS_BUFFER_TOO_SMALL - One of the buffers passed was too small.
|
|||
|
|
|||
|
STATUS_INVALID_OWNER - There was not a valid owner in the passed
|
|||
|
security descriptor.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG NewDaclSize;
|
|||
|
ULONG NewSaclSize;
|
|||
|
ULONG NewBodySize;
|
|||
|
ULONG NewOwnerSize;
|
|||
|
ULONG NewGroupSize;
|
|||
|
|
|||
|
PSID NewOwner;
|
|||
|
PSID NewGroup;
|
|||
|
PACL NewDacl;
|
|||
|
PACL NewSacl;
|
|||
|
|
|||
|
//
|
|||
|
// typecast security descriptors so we don't have to cast all over the place.
|
|||
|
//
|
|||
|
|
|||
|
PISECURITY_DESCRIPTOR OutSD =
|
|||
|
AbsoluteSecurityDescriptor;
|
|||
|
|
|||
|
PISECURITY_DESCRIPTOR InSD =
|
|||
|
(PISECURITY_DESCRIPTOR)SelfRelativeSecurityDescriptor;
|
|||
|
|
|||
|
|
|||
|
RTL_PAGED_CODE();
|
|||
|
|
|||
|
if ( !RtlpAreControlBitsSet( InSD, SE_SELF_RELATIVE) ) {
|
|||
|
return( STATUS_BAD_DESCRIPTOR_FORMAT );
|
|||
|
}
|
|||
|
|
|||
|
NewBodySize = sizeof(SECURITY_DESCRIPTOR);
|
|||
|
|
|||
|
RtlpQuerySecurityDescriptor(
|
|||
|
InSD,
|
|||
|
&NewOwner,
|
|||
|
&NewOwnerSize,
|
|||
|
&NewGroup,
|
|||
|
&NewGroupSize,
|
|||
|
&NewDacl,
|
|||
|
&NewDaclSize,
|
|||
|
&NewSacl,
|
|||
|
&NewSaclSize
|
|||
|
);
|
|||
|
|
|||
|
if ( (NewBodySize > *AbsoluteSecurityDescriptorSize) ||
|
|||
|
(NewOwnerSize > *OwnerSize ) ||
|
|||
|
(NewDaclSize > *DaclSize ) ||
|
|||
|
(NewSaclSize > *SaclSize ) ||
|
|||
|
(NewGroupSize > *PrimaryGroupSize ) ) {
|
|||
|
|
|||
|
*AbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
|
|||
|
*PrimaryGroupSize = NewGroupSize;
|
|||
|
*OwnerSize = NewOwnerSize;
|
|||
|
*SaclSize = NewSaclSize;
|
|||
|
*DaclSize = NewDaclSize;
|
|||
|
|
|||
|
return( STATUS_BUFFER_TOO_SMALL );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RtlMoveMemory( OutSD,
|
|||
|
InSD,
|
|||
|
sizeof(SECURITY_DESCRIPTOR) );
|
|||
|
|
|||
|
OutSD->Owner = NULL;
|
|||
|
OutSD->Group = NULL;
|
|||
|
OutSD->Sacl = NULL;
|
|||
|
OutSD->Dacl = NULL;
|
|||
|
|
|||
|
RtlpClearControlBits( OutSD, SE_SELF_RELATIVE );
|
|||
|
|
|||
|
if (NewOwner != NULL) {
|
|||
|
RtlMoveMemory( Owner, NewOwner, RtlLengthSid( NewOwner ));
|
|||
|
OutSD->Owner = Owner;
|
|||
|
}
|
|||
|
|
|||
|
if (NewGroup != NULL) {
|
|||
|
RtlMoveMemory( PrimaryGroup, NewGroup, RtlLengthSid( NewGroup ));
|
|||
|
OutSD->Group = PrimaryGroup;
|
|||
|
}
|
|||
|
|
|||
|
if (NewSacl != NULL) {
|
|||
|
RtlMoveMemory( Sacl, NewSacl, NewSacl->AclSize );
|
|||
|
OutSD->Sacl = Sacl;
|
|||
|
}
|
|||
|
|
|||
|
if (NewDacl != NULL) {
|
|||
|
RtlMoveMemory( Dacl, NewDacl, NewDacl->AclSize );
|
|||
|
OutSD->Dacl = Dacl;
|
|||
|
}
|
|||
|
|
|||
|
return( STATUS_SUCCESS );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
RtlMakeSelfRelativeSD(
|
|||
|
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
|
IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
|
|||
|
IN OUT PULONG BufferLength
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Makes a copy of a security descriptor. The produced copy will be in self-relative
|
|||
|
form.
|
|||
|
|
|||
|
The security descriptor to be copied may be in either absolute or self-relative
|
|||
|
form.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SecurityDescriptor - Pointer to a security descriptor. This descriptor will not
|
|||
|
be modified.
|
|||
|
|
|||
|
SelfRelativeSecurityDescriptor - Pointer to a buffer that will contain
|
|||
|
the returned self-relative security descriptor.
|
|||
|
|
|||
|
BufferLength - Supplies the length of the buffer. If the supplied
|
|||
|
buffer is not large enough to hold the self-relative security
|
|||
|
descriptor, an error will be returned, and this field will return
|
|||
|
the minimum size required.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_BUFFER_TOO_SMALL - The supplied buffer was too small to contain
|
|||
|
the resultant security descriptor.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG NewDaclSize;
|
|||
|
ULONG NewSaclSize;
|
|||
|
ULONG NewOwnerSize;
|
|||
|
ULONG NewGroupSize;
|
|||
|
|
|||
|
ULONG AllocationSize;
|
|||
|
|
|||
|
PSID NewOwner;
|
|||
|
PSID NewGroup;
|
|||
|
PACL NewDacl;
|
|||
|
PACL NewSacl;
|
|||
|
|
|||
|
PCHAR Field;
|
|||
|
PCHAR Base;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Convert security descriptors to new data type so we don't
|
|||
|
// have to cast all over the place.
|
|||
|
//
|
|||
|
|
|||
|
PISECURITY_DESCRIPTOR IResultantDescriptor =
|
|||
|
(PISECURITY_DESCRIPTOR)SelfRelativeSecurityDescriptor;
|
|||
|
|
|||
|
PISECURITY_DESCRIPTOR IPassedSecurityDescriptor =
|
|||
|
(PISECURITY_DESCRIPTOR)SecurityDescriptor;
|
|||
|
|
|||
|
|
|||
|
RtlpQuerySecurityDescriptor(
|
|||
|
IPassedSecurityDescriptor,
|
|||
|
&NewOwner,
|
|||
|
&NewOwnerSize,
|
|||
|
&NewGroup,
|
|||
|
&NewGroupSize,
|
|||
|
&NewDacl,
|
|||
|
&NewDaclSize,
|
|||
|
&NewSacl,
|
|||
|
&NewSaclSize
|
|||
|
);
|
|||
|
|
|||
|
RTL_PAGED_CODE();
|
|||
|
|
|||
|
AllocationSize = sizeof(SECURITY_DESCRIPTOR) +
|
|||
|
NewOwnerSize +
|
|||
|
NewGroupSize +
|
|||
|
NewDaclSize +
|
|||
|
NewSaclSize ;
|
|||
|
|
|||
|
if (AllocationSize > *BufferLength) {
|
|||
|
*BufferLength = AllocationSize;
|
|||
|
return( STATUS_BUFFER_TOO_SMALL );
|
|||
|
}
|
|||
|
|
|||
|
RtlZeroMemory( IResultantDescriptor, AllocationSize );
|
|||
|
|
|||
|
RtlMoveMemory( IResultantDescriptor,
|
|||
|
IPassedSecurityDescriptor,
|
|||
|
sizeof( SECURITY_DESCRIPTOR ));
|
|||
|
|
|||
|
|
|||
|
Base = (PCHAR)(IResultantDescriptor);
|
|||
|
Field = Base + (ULONG)sizeof(SECURITY_DESCRIPTOR);
|
|||
|
|
|||
|
if (NewSaclSize > 0) {
|
|||
|
RtlMoveMemory( Field, NewSacl, NewSaclSize );
|
|||
|
IResultantDescriptor->Sacl = (PACL)RtlPointerToOffset(Base,Field);
|
|||
|
Field += NewSaclSize;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (NewDaclSize > 0) {
|
|||
|
RtlMoveMemory( Field, NewDacl, NewDaclSize );
|
|||
|
IResultantDescriptor->Dacl = (PACL)RtlPointerToOffset(Base,Field);
|
|||
|
Field += NewDaclSize;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if (NewOwnerSize > 0) {
|
|||
|
RtlMoveMemory( Field, NewOwner, NewOwnerSize );
|
|||
|
IResultantDescriptor->Owner = (PSID)RtlPointerToOffset(Base,Field);
|
|||
|
Field += NewOwnerSize;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (NewGroupSize > 0) {
|
|||
|
RtlMoveMemory( Field, NewGroup, NewGroupSize );
|
|||
|
IResultantDescriptor->Group = (PSID)RtlPointerToOffset(Base,Field);
|
|||
|
}
|
|||
|
|
|||
|
RtlpSetControlBits( IResultantDescriptor, SE_SELF_RELATIVE );
|
|||
|
|
|||
|
return( STATUS_SUCCESS );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
RtlAbsoluteToSelfRelativeSD(
|
|||
|
IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
|
|||
|
IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
|
|||
|
IN OUT PULONG BufferLength
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Converts a security descriptor in absolute form to one in self-relative
|
|||
|
form.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
AbsoluteSecurityDescriptor - Pointer to an absolute format security
|
|||
|
descriptor. This descriptor will not be modified.
|
|||
|
|
|||
|
SelfRelativeSecurityDescriptor - Pointer to a buffer that will contain
|
|||
|
the returned self-relative security descriptor.
|
|||
|
|
|||
|
BufferLength - Supplies the length of the buffer. If the supplied
|
|||
|
buffer is not large enough to hold the self-relative security
|
|||
|
descriptor, an error will be returned, and this field will return
|
|||
|
the minimum size required.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_BUFFER_TOO_SMALL - The supplied buffer was too small to contain
|
|||
|
the resultant security descriptor.
|
|||
|
|
|||
|
STATUS_BAD_DESCRIPTOR_FORMAT - The supplied security descriptor was not
|
|||
|
in absolute form.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS NtStatus;
|
|||
|
|
|||
|
PISECURITY_DESCRIPTOR IAbsoluteSecurityDescriptor =
|
|||
|
(PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor;
|
|||
|
|
|||
|
|
|||
|
RTL_PAGED_CODE();
|
|||
|
|
|||
|
//
|
|||
|
// Make sure the passed SD is absolute format, and then call
|
|||
|
// RtlMakeSelfRelativeSD() to do all the work.
|
|||
|
//
|
|||
|
|
|||
|
if ( RtlpAreControlBitsSet( IAbsoluteSecurityDescriptor, SE_SELF_RELATIVE) ) {
|
|||
|
return( STATUS_BAD_DESCRIPTOR_FORMAT );
|
|||
|
}
|
|||
|
|
|||
|
NtStatus = RtlMakeSelfRelativeSD(
|
|||
|
AbsoluteSecurityDescriptor,
|
|||
|
SelfRelativeSecurityDescriptor,
|
|||
|
BufferLength
|
|||
|
);
|
|||
|
|
|||
|
return( NtStatus );
|
|||
|
|
|||
|
}
|
|||
|
VOID
|
|||
|
RtlpQuerySecurityDescriptor(
|
|||
|
IN PISECURITY_DESCRIPTOR SecurityDescriptor,
|
|||
|
OUT PSID *Owner,
|
|||
|
OUT PULONG OwnerSize,
|
|||
|
OUT PSID *PrimaryGroup,
|
|||
|
OUT PULONG PrimaryGroupSize,
|
|||
|
OUT PACL *Dacl,
|
|||
|
OUT PULONG DaclSize,
|
|||
|
OUT PACL *Sacl,
|
|||
|
OUT PULONG SaclSize
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Returns the pieces of a security descriptor structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
SecurityDescriptor - Provides the security descriptor of interest.
|
|||
|
|
|||
|
Owner - Returns a pointer to the owner information contained in the
|
|||
|
security descriptor.
|
|||
|
|
|||
|
OwnerSize - Returns the size of the owner information.
|
|||
|
|
|||
|
PrimaryGroup - Returns a pointer to the primary group information.
|
|||
|
|
|||
|
PrimaryGroupSize - Returns the size of the primary group information.
|
|||
|
|
|||
|
Dacl - Returns a pointer to the Dacl.
|
|||
|
|
|||
|
DaclSize - Returns the size of the Dacl.
|
|||
|
|
|||
|
Sacl - Returns a pointer to the Sacl.
|
|||
|
|
|||
|
SaclSize - Returns the size of the Sacl.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
RTL_PAGED_CODE();
|
|||
|
|
|||
|
*Owner = RtlpOwnerAddrSecurityDescriptor( SecurityDescriptor );
|
|||
|
|
|||
|
if (*Owner != NULL) {
|
|||
|
*OwnerSize = (ULONG)LongAlign(RtlLengthSid(*Owner));
|
|||
|
} else {
|
|||
|
*OwnerSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
*Dacl = RtlpDaclAddrSecurityDescriptor ( SecurityDescriptor );
|
|||
|
|
|||
|
if (*Dacl !=NULL) {
|
|||
|
*DaclSize = (ULONG)LongAlign((*Dacl)->AclSize);
|
|||
|
} else {
|
|||
|
*DaclSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
*PrimaryGroup = RtlpGroupAddrSecurityDescriptor( SecurityDescriptor );
|
|||
|
|
|||
|
if (*PrimaryGroup != NULL) {
|
|||
|
*PrimaryGroupSize = (ULONG)LongAlign(RtlLengthSid(*PrimaryGroup));
|
|||
|
} else {
|
|||
|
*PrimaryGroupSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
*Sacl = RtlpSaclAddrSecurityDescriptor( SecurityDescriptor );
|
|||
|
|
|||
|
if (*Sacl != NULL) {
|
|||
|
*SaclSize = (ULONG)LongAlign((*Sacl)->AclSize);
|
|||
|
} else {
|
|||
|
*SaclSize = 0;
|
|||
|
}
|
|||
|
|
|||
|
}
|