Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

498 lines
12 KiB

/*++
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;
}
}