diff --git a/reactos/include/ntos/security.h b/reactos/include/ntos/security.h index 00af3160a5c..da67f46879e 100644 --- a/reactos/include/ntos/security.h +++ b/reactos/include/ntos/security.h @@ -206,6 +206,24 @@ typedef struct _ACL USHORT Sbz2; } ACL, *PACL; +typedef struct _ACL_REVISION_INFORMATION +{ + ULONG AclRevision; +} ACL_REVISION_INFORMATION, *PACL_REVISION_INFORMATION; + +typedef struct _ACL_SIZE_INFORMATION +{ + ULONG AceCount; + ULONG AclBytesInUse; + ULONG AclBytesFree; +} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION; + +typedef enum _ACL_INFORMATION_CLASS +{ + AclRevisionInformation = 1, + AclSizeInformation +} ACL_INFORMATION_CLASS; + typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; typedef struct _SECURITY_DESCRIPTOR_CONTEXT @@ -315,12 +333,6 @@ typedef struct _PRIVILEGE_SET LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; } PRIVILEGE_SET, *PPRIVILEGE_SET, *LPPRIVILEGE_SET; -typedef enum _ACL_INFORMATION_CLASS -{ - AclRevisionInformation = 1, - AclSizeInformation -} ACL_INFORMATION_CLASS; - typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; diff --git a/reactos/include/structs.h b/reactos/include/structs.h index aa3400c06bf..5cdcdc54bf9 100644 --- a/reactos/include/structs.h +++ b/reactos/include/structs.h @@ -83,16 +83,6 @@ typedef struct tagACCESSTIMEOUT { DWORD iTimeOutMSec; } ACCESSTIMEOUT; -typedef struct _ACL_REVISION_INFORMATION { - DWORD AclRevision; -} ACL_REVISION_INFORMATION; - -typedef struct _ACL_SIZE_INFORMATION { - DWORD AceCount; - DWORD AclBytesInUse; - DWORD AclBytesFree; -} ACL_SIZE_INFORMATION; - typedef struct _ACTION_HEADER { ULONG transport_id; USHORT action_code; diff --git a/reactos/lib/ntdll/rtl/acl.c b/reactos/lib/ntdll/rtl/acl.c index 0cf92445039..cbecef820a7 100644 --- a/reactos/lib/ntdll/rtl/acl.c +++ b/reactos/lib/ntdll/rtl/acl.c @@ -1,4 +1,4 @@ -/* $Id: acl.c,v 1.5 2002/06/15 10:08:46 ekohl Exp $ +/* $Id: acl.c,v 1.6 2002/08/13 20:41:22 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,7 +33,7 @@ RtlFirstFreeAce(PACL Acl, *Ace = Current; return(TRUE); } - AclEnd = Acl->AclSize + Acl; + AclEnd = Acl->AclSize + (PVOID)Acl; do { if ((PVOID)Current >= AclEnd) @@ -52,11 +52,10 @@ RtlFirstFreeAce(PACL Acl, } while (i < Acl->AceCount); - if ((PVOID)Current >= AclEnd) + if ((PVOID)Current < AclEnd) { - return(FALSE); + *Ace = Current; } - *Ace = Current; return(TRUE); } @@ -68,14 +67,13 @@ RtlGetAce(PACL Acl, PACE *Ace) { ULONG i; - PACE p = (PACE)(Acl + 1); - *Ace = NULL; + *Ace = (PACE)(Acl + 1); if (Acl->AclRevision != 2 && Acl->AclRevision != 3) { - return(STATUS_UNKNOWN_REVISION); + return(STATUS_INVALID_PARAMETER); } if (AceIndex >= Acl->AceCount) @@ -85,16 +83,23 @@ RtlGetAce(PACL Acl, for (i = 0; i < AceIndex; i++) { - p = (PACE)((PVOID)p + (ULONG)p->Header.AceSize); + if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize) + { + return(STATUS_INVALID_PARAMETER); + } + *Ace = (PACE)((PVOID)(*Ace) + (ULONG)(*Ace)->Header.AceSize); } - *Ace = p; + if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize) + { + return(STATUS_INVALID_PARAMETER); + } return(STATUS_SUCCESS); } -NTSTATUS +static NTSTATUS RtlpAddKnownAce(PACL Acl, ULONG Revision, ACCESS_MASK AccessMask, @@ -118,16 +123,16 @@ RtlpAddKnownAce(PACL Acl, } if (!RtlFirstFreeAce(Acl, &Ace)) { - return(STATUS_BUFFER_TOO_SMALL); + return(STATUS_INVALID_ACL); } if (Ace == NULL) { - return(STATUS_UNSUCCESSFUL); + return(STATUS_ALLOTTED_SPACE_EXCEEDED); } if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= ((PVOID)Acl + Acl->AclSize)) { - return(STATUS_BUFFER_TOO_SMALL); + return(STATUS_ALLOTTED_SPACE_EXCEEDED); } Ace->Header.AceFlags = 0; Ace->Header.AceType = Type; @@ -160,6 +165,28 @@ RtlAddAccessDeniedAce(PACL Acl, } +static VOID +RtlpAddData(PVOID AceList, + ULONG AceListLength, + PVOID Ace, + ULONG Offset) +{ + if (Offset > 0) + { + memcpy((PUCHAR)Ace + AceListLength, + Ace, + Offset); + } + + if (AceListLength != 0) + { + memcpy(Ace, + AceList, + AceListLength); + } +} + + NTSTATUS STDCALL RtlAddAce(PACL Acl, ULONG AclRevision, @@ -167,63 +194,74 @@ RtlAddAce(PACL Acl, PACE AceList, ULONG AceListLength) { - PACE Ace; - ULONG i; - PACE Current; - ULONG j; - - if (Acl->AclRevision != 2 && - Acl->AclRevision != 3) - { - return(STATUS_UNSUCCESSFUL); - } - if (!RtlFirstFreeAce(Acl,&Ace)) - { - return(STATUS_UNSUCCESSFUL); - } - if (Acl->AclRevision <= AclRevision) - { - AclRevision = Acl->AclRevision; - } - if (((PVOID)AceList + AceListLength) <= (PVOID)AceList) - { - return(STATUS_UNSUCCESSFUL); - } - i = 0; - Current = (PACE)(Acl + 1); - while ((PVOID)Current < ((PVOID)AceList + AceListLength)) - { - if (AceList->Header.AceType == 4 && - AclRevision < 3) - { - return(STATUS_UNSUCCESSFUL); - } - Current = (PACE)((PVOID)Current + Current->Header.AceSize); - } - if (Ace == NULL) - { - return(STATUS_UNSUCCESSFUL); - } - if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize)) - { - return(STATUS_UNSUCCESSFUL); - } - if (StartingIndex != 0) - { - if (Acl->AceCount > 0) - { - Current = (PACE)(Acl + 1); - for (j = 0; j < StartingIndex; j++) - { - Current = (PACE)((PVOID)Current + Current->Header.AceSize); - } - } - } - /* RtlpAddData(AceList, AceListLength, Current, (PVOID)Ace - Current)); */ - memcpy(Current, AceList, AceListLength); - Acl->AceCount = Acl->AceCount + i; - Acl->AclRevision = AclRevision; - return(TRUE); + PACE Ace; + ULONG i; + PACE Current; + ULONG j; + + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(STATUS_INVALID_PARAMETER); + } + + if (!RtlFirstFreeAce(Acl,&Ace)) + { + return(STATUS_INVALID_PARAMETER); + } + + if (Acl->AclRevision <= AclRevision) + { + AclRevision = Acl->AclRevision; + } + + if (((PVOID)AceList + AceListLength) <= (PVOID)AceList) + { + return(STATUS_INVALID_PARAMETER); + } + + i = 0; + Current = (PACE)(Acl + 1); + while ((PVOID)Current < ((PVOID)AceList + AceListLength)) + { + if (AceList->Header.AceType == 4 && + AclRevision < 3) + { + return(STATUS_INVALID_PARAMETER); + } + Current = (PACE)((PVOID)Current + Current->Header.AceSize); + } + + if (Ace == NULL) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize)) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + if (StartingIndex != 0) + { + if (Acl->AceCount > 0) + { + Current = (PACE)(Acl + 1); + for (j = 0; j < StartingIndex; j++) + { + Current = (PACE)((PVOID)Current + Current->Header.AceSize); + } + } + } + + RtlpAddData(AceList, + AceListLength, + Current, + (ULONG)Ace - (ULONG)Current); + Acl->AceCount = Acl->AceCount + i; + Acl->AclRevision = AclRevision; + + return(STATUS_SUCCESS); } @@ -235,8 +273,82 @@ RtlAddAuditAccessAce(PACL Acl, BOOLEAN Success, BOOLEAN Failure) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PACE Ace; + ULONG Flags = 0; + + if (Success != FALSE) + { + Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; + } + + if (Failure != FALSE) + { + Flags |= FAILED_ACCESS_ACE_FLAG; + } + + if (!RtlValidSid(Sid)) + { + return(STATUS_INVALID_SID); + } + + if (Acl->AclRevision > 3 || + Revision > 3) + { + return(STATUS_REVISION_MISMATCH); + } + + if (Revision < Acl->AclRevision) + { + Revision = Acl->AclRevision; + } + + if (!RtlFirstFreeAce(Acl, &Ace)) + { + return(STATUS_INVALID_ACL); + } + + if (Ace == NULL) + { + return(STATUS_ALLOTTED_SPACE_EXCEEDED); + } + + if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= ((PVOID)Acl + Acl->AclSize)) + { + return(STATUS_ALLOTTED_SPACE_EXCEEDED); + } + + Ace->Header.AceFlags = Flags; + Ace->Header.AceType = 2; + Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE); + Ace->Header.AccessMask = AccessMask; + RtlCopySid(RtlLengthSid(Sid), + (PSID)(Ace + 1), + Sid); + Acl->AceCount++; + Acl->AclRevision = Revision; + + return(STATUS_SUCCESS); +} + + +static VOID +RtlpDeleteData(PVOID Ace, + ULONG AceSize, + ULONG Offset) +{ + if (AceSize < Offset) + { + memcpy(Ace, + (PUCHAR)Ace + AceSize, + Offset - AceSize); + } + + if (Offset - AceSize < Offset) + { + memset((PUCHAR)Ace + Offset - AceSize, + 0, + AceSize); + } } @@ -244,8 +356,38 @@ NTSTATUS STDCALL RtlDeleteAce(PACL Acl, ULONG AceIndex) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PACE Ace; + PACE Current; + + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(STATUS_INVALID_PARAMETER); + } + + if (Acl->AceCount <= AceIndex) + { + return(STATUS_INVALID_PARAMETER); + } + + if (!RtlFirstFreeAce(Acl, &Ace)) + { + return(STATUS_INVALID_PARAMETER); + } + + Current = (PACE)(Acl + 1); + + while(AceIndex--) + { + Current = (PACE)((PVOID)Current + Current->Header.AceSize); + } + + RtlpDeleteData(Current, + Current->Header.AceSize, + Ace - Current); + Acl->AceCount++; + + return(STATUS_SUCCESS); } @@ -254,26 +396,30 @@ RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision) { - if (AclSize < 8) - { - return(STATUS_BUFFER_TOO_SMALL); - } - if (AclRevision != 2 && - AclRevision != 3) - { - return(STATUS_UNKNOWN_REVISION); - } - if (AclSize > 0xffff) - { - return(STATUS_UNSUCCESSFUL); - } - AclSize = AclSize & ~(0x3); - Acl->AclSize = AclSize; - Acl->AclRevision = AclRevision; - Acl->AceCount = 0; - Acl->Sbz1 = 0; - Acl->Sbz2 = 0; - return(STATUS_SUCCESS); + if (AclSize < 8) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + if (AclRevision != 2 && + AclRevision != 3) + { + return(STATUS_INVALID_PARAMETER); + } + + if (AclSize > 0xffff) + { + return(STATUS_INVALID_PARAMETER); + } + + AclSize = AclSize & ~(0x3); + Acl->AclSize = AclSize; + Acl->AclRevision = AclRevision; + Acl->AceCount = 0; + Acl->Sbz1 = 0; + Acl->Sbz2 = 0; + + return(STATUS_SUCCESS); } @@ -283,8 +429,61 @@ RtlQueryInformationAcl(PACL Acl, ULONG InformationLength, ACL_INFORMATION_CLASS InformationClass) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PACE Ace; + + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(STATUS_INVALID_PARAMETER); + } + + switch (InformationClass) + { + case AclRevisionInformation: + { + PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information; + + if (InformationLength < sizeof(ACL_REVISION_INFORMATION)) + { + return(STATUS_BUFFER_TOO_SMALL); + } + Info->AclRevision = Acl->AclRevision; + } + break; + + case AclSizeInformation: + { + PACL_SIZE_INFORMATION Info = (PACL_SIZE_INFORMATION)Information; + + if (InformationLength < sizeof(ACL_SIZE_INFORMATION)) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + if (!RtlFirstFreeAce(Acl, &Ace)) + { + return(STATUS_INVALID_PARAMETER); + } + + Info->AceCount = Acl->AceCount; + if (Ace != NULL) + { + Info->AclBytesInUse = (PVOID)Ace - (PVOID)Acl; + Info->AclBytesFree = Acl->AclSize - Info->AclBytesInUse; + } + else + { + Info->AclBytesInUse = Acl->AclSize; + Info->AclBytesFree = 0; + } + } + break; + + default: + return(STATUS_INVALID_INFO_CLASS); + } + + return(STATUS_SUCCESS); } @@ -294,16 +493,60 @@ RtlSetInformationAcl(PACL Acl, ULONG InformationLength, ACL_INFORMATION_CLASS InformationClass) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(STATUS_INVALID_PARAMETER); + } + + switch (InformationClass) + { + case AclRevisionInformation: + { + PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information; + + if (InformationLength < sizeof(ACL_REVISION_INFORMATION)) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + if (Acl->AclRevision >= Info->AclRevision) + { + return(STATUS_INVALID_PARAMETER); + } + + Acl->AclRevision = Info->AclRevision; + } + break; + + default: + return(STATUS_INVALID_INFO_CLASS); + } + + return(STATUS_SUCCESS); } BOOLEAN STDCALL RtlValidAcl(PACL Acl) { - UNIMPLEMENTED; - return FALSE; + PACE Ace; + USHORT Size; + + Size = (Acl->AclSize + 3) & ~3; + + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(FALSE); + } + + if (Size != Acl->AclSize) + { + return(FALSE); + } + + return(RtlFirstFreeAce(Acl, &Ace)); } /* EOF */ diff --git a/reactos/lib/ntdll/rtl/sd.c b/reactos/lib/ntdll/rtl/sd.c index 37a06130d59..354eb4364b7 100644 --- a/reactos/lib/ntdll/rtl/sd.c +++ b/reactos/lib/ntdll/rtl/sd.c @@ -1,4 +1,4 @@ -/* $Id: sd.c,v 1.6 2001/12/04 20:47:54 ekohl Exp $ +/* $Id: sd.c,v 1.7 2002/08/13 20:41:22 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -21,33 +21,35 @@ NTSTATUS STDCALL RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Revision) { - if (Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - SecurityDescriptor->Revision = 1; - SecurityDescriptor->Sbz1 = 0; - SecurityDescriptor->Control = 0; - SecurityDescriptor->Owner = NULL; - SecurityDescriptor->Group = NULL; - SecurityDescriptor->Sacl = NULL; - SecurityDescriptor->Dacl = NULL; - return(STATUS_SUCCESS); + if (Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + + SecurityDescriptor->Revision = 1; + SecurityDescriptor->Sbz1 = 0; + SecurityDescriptor->Control = 0; + SecurityDescriptor->Owner = NULL; + SecurityDescriptor->Group = NULL; + SecurityDescriptor->Sacl = NULL; + SecurityDescriptor->Dacl = NULL; + + return(STATUS_SUCCESS); } ULONG STDCALL -RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) +RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) { - PSID Owner; - PSID Group; - ULONG Length; - PACL Dacl; - PACL Sacl; + PSID Owner; + PSID Group; + ULONG Length; + PACL Dacl; + PACL Sacl; - Length = sizeof(SECURITY_DESCRIPTOR); + Length = sizeof(SECURITY_DESCRIPTOR); - if (SecurityDescriptor->Owner != NULL) - { + if (SecurityDescriptor->Owner != NULL) + { Owner = SecurityDescriptor->Owner; if (SecurityDescriptor->Control & SE_SELF_RELATIVE) { @@ -56,9 +58,10 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) } Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * sizeof(ULONG) + 3) & 0xfc); - } - if (SecurityDescriptor->Group != NULL) - { + } + + if (SecurityDescriptor->Group != NULL) + { Group = SecurityDescriptor->Group; if (SecurityDescriptor->Control & SE_SELF_RELATIVE) { @@ -66,30 +69,34 @@ RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) } Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) * sizeof(ULONG) + 3) & 0xfc); - } - if (SecurityDescriptor->Control & SE_DACL_PRESENT && - SecurityDescriptor->Dacl != NULL) - { + } + + if (SecurityDescriptor->Control & SE_DACL_PRESENT && + SecurityDescriptor->Dacl != NULL) + { Dacl = SecurityDescriptor->Dacl; if (SecurityDescriptor->Control & SE_SELF_RELATIVE) { Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor); } Length = Length + ((Dacl->AclSize + 3) & 0xfc); - } - if (SecurityDescriptor->Control & SE_SACL_PRESENT && - SecurityDescriptor->Sacl != NULL) - { + } + + if (SecurityDescriptor->Control & SE_SACL_PRESENT && + SecurityDescriptor->Sacl != NULL) + { Sacl = SecurityDescriptor->Sacl; if (SecurityDescriptor->Control & SE_SELF_RELATIVE) { Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor); } Length = Length + ((Sacl->AclSize + 3) & 0xfc); - } - return(Length); + } + + return(Length); } + NTSTATUS STDCALL RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PBOOLEAN DaclPresent, @@ -133,6 +140,7 @@ RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, return(STATUS_SUCCESS); } + NTSTATUS STDCALL RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, BOOLEAN DaclPresent, @@ -162,12 +170,76 @@ RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, return(STATUS_SUCCESS); } + BOOLEAN STDCALL RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; + + if (SecurityDescriptor->Revision != 1) + { + return(FALSE); + } + + Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor); + } + + if (!RtlValidSid(Owner)) + { + return(FALSE); + } + + Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor); + } + + if (!RtlValidSid(Group)) + { + return(FALSE); + } + + if (SecurityDescriptor->Control & SE_DACL_PRESENT && + SecurityDescriptor->Dacl != NULL) + { + Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor); + } + + if (!RtlValidAcl(Dacl)) + { + return(FALSE); + } + } + + if (SecurityDescriptor->Control & SE_SACL_PRESENT && + SecurityDescriptor->Sacl != NULL) + { + Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor); + } + + if (!RtlValidAcl(Sacl)) + { + return(FALSE); + } + } + + return(TRUE); } + NTSTATUS STDCALL RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID Owner, @@ -284,43 +356,219 @@ RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, return(STATUS_SUCCESS); } + +static VOID +RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID* Owner, + PULONG OwnerLength, + PSID* Group, + PULONG GroupLength, + PACL* Dacl, + PULONG DaclLength, + PACL* Sacl, + PULONG SaclLength) +{ + if (SecurityDescriptor->Owner == NULL) + { + *Owner = NULL; + } + else + { + *Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor); + } + } + + if (*Owner != NULL) + { + *OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3; + } + else + { + *OwnerLength = 0; + } + + if ((SecurityDescriptor->Control & SE_DACL_PRESENT) && + SecurityDescriptor->Dacl != NULL) + { + *Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor); + } + } + else + { + *Dacl = NULL; + } + + if (*Dacl != NULL) + { + *DaclLength = ((*Dacl)->AclSize + 3) & ~3; + } + else + { + *DaclLength = 0; + } + + if (SecurityDescriptor->Group != NULL) + { + *Group = NULL; + } + else + { + *Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor); + } + } + + if (*Group != NULL) + { + *GroupLength = (RtlLengthSid(*Group) + 3) & ~3; + } + else + { + *GroupLength = 0; + } + + if ((SecurityDescriptor->Control & SE_SACL_PRESENT) && + SecurityDescriptor->Sacl != NULL) + { + *Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor); + } + } + else + { + *Sacl = NULL; + } + + if (*Sacl != NULL) + { + *SaclLength = ((*Sacl)->AclSize + 3) & ~3; + } +} + + NTSTATUS STDCALL RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, PSECURITY_DESCRIPTOR RelSD, PULONG BufferLength) { - UNIMPLEMENTED; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; + ULONG OwnerLength; + ULONG GroupLength; + ULONG SaclLength; + ULONG DaclLength; + ULONG TotalLength; + ULONG Current; + + RtlpQuerySecurityDescriptor(AbsSD, + &Owner, + &OwnerLength, + &Group, + &GroupLength, + &Dacl, + &DaclLength, + &Sacl, + &SaclLength); + + TotalLength = OwnerLength + GroupLength + SaclLength + DaclLength + sizeof(SECURITY_DESCRIPTOR); + if (*BufferLength < TotalLength) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + RtlZeroMemory(RelSD, + TotalLength); + memmove(RelSD, + AbsSD, + sizeof(SECURITY_DESCRIPTOR)); + Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR); + + if (SaclLength != 0) + { + memmove((PVOID)Current, + Sacl, + SaclLength); + RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD); + Current += SaclLength; + } + + if (DaclLength != 0) + { + memmove((PVOID)Current, + Dacl, + DaclLength); + RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD); + Current += DaclLength; + } + + if (OwnerLength != 0) + { + memmove((PVOID)Current, + Owner, + OwnerLength); + RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD); + Current += OwnerLength; + } + + if (GroupLength != 0) + { + memmove((PVOID)Current, + Group, + GroupLength); + RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD); + } + + RelSD->Control |= SE_SELF_RELATIVE; + + return(STATUS_SUCCESS); } + NTSTATUS STDCALL RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, PSECURITY_DESCRIPTOR RelSD, PULONG BufferLength ) { - if (AbsSD->Control & SE_SELF_RELATIVE) - { - return(STATUS_BAD_DESCRIPTOR_FORMAT); - } + if (AbsSD->Control & SE_SELF_RELATIVE) + { + return(STATUS_BAD_DESCRIPTOR_FORMAT); + } - return(RtlMakeSelfRelativeSD (AbsSD, RelSD, BufferLength)); + return(RtlMakeSelfRelativeSD(AbsSD, RelSD, BufferLength)); } + NTSTATUS STDCALL RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR_CONTROL Control, PULONG Revision) { - *Revision = SecurityDescriptor->Revision; + *Revision = SecurityDescriptor->Revision; - if (SecurityDescriptor->Revision != 1) - return(STATUS_UNKNOWN_REVISION); + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNKNOWN_REVISION); + } - *Control = SecurityDescriptor->Control; + *Control = SecurityDescriptor->Control; - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } + NTSTATUS STDCALL RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PBOOLEAN SaclPresent,