4 * Copyright 1996-1998 Marcus Meissner
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
37 #include "wine/exception.h"
42 #include "ntdll_misc.h"
44 #include "wine/library.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
49 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
51 /* filter for page-fault exceptions */
52 static WINE_EXCEPTION_FILTER(page_fault)
54 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
55 return EXCEPTION_EXECUTE_HANDLER;
56 return EXCEPTION_CONTINUE_SEARCH;
63 /******************************************************************************
64 * RtlAllocateAndInitializeSid [NTDLL.@]
67 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
68 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
69 BYTE nSubAuthorityCount,
70 DWORD nSubAuthority0, DWORD nSubAuthority1,
71 DWORD nSubAuthority2, DWORD nSubAuthority3,
72 DWORD nSubAuthority4, DWORD nSubAuthority5,
73 DWORD nSubAuthority6, DWORD nSubAuthority7,
76 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
77 pIdentifierAuthority,nSubAuthorityCount,
78 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
79 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
81 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0,
82 RtlLengthRequiredSid(nSubAuthorityCount))))
85 (*pSid)->Revision = SID_REVISION;
87 if (pIdentifierAuthority)
88 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
89 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
91 if (nSubAuthorityCount > 0)
92 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
93 if (nSubAuthorityCount > 1)
94 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
95 if (nSubAuthorityCount > 2)
96 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
97 if (nSubAuthorityCount > 3)
98 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
99 if (nSubAuthorityCount > 4)
100 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
101 if (nSubAuthorityCount > 5)
102 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
103 if (nSubAuthorityCount > 6)
104 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
105 if (nSubAuthorityCount > 7)
106 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
108 return STATUS_SUCCESS;
110 /******************************************************************************
111 * RtlEqualSid [NTDLL.@]
113 * Determine if two SIDs are equal.
116 * pSid1 [I] Source SID
117 * pSid2 [I] SID to compare with
120 * TRUE, if pSid1 is equal to pSid2,
123 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
125 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
128 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
131 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
137 /******************************************************************************
138 * RtlEqualPrefixSid [NTDLL.@]
140 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
142 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
145 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
148 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
155 /******************************************************************************
156 * RtlFreeSid [NTDLL.@]
158 * Free the resources used by a SID.
161 * pSid [I] SID to Free.
166 DWORD WINAPI RtlFreeSid(PSID pSid)
168 TRACE("(%p)\n", pSid);
169 RtlFreeHeap( GetProcessHeap(), 0, pSid );
170 return STATUS_SUCCESS;
173 /**************************************************************************
174 * RtlLengthRequiredSid [NTDLL.@]
176 * Determine the amount of memory a SID will use
179 * nrofsubauths [I] Number of Sub Authorities in the SID.
182 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
184 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
186 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
189 /**************************************************************************
190 * RtlLengthSid [NTDLL.@]
192 * Determine the amount of memory a SID is using
195 * pSid [I] SID to ge the size of.
198 * The size, in bytes, of pSid.
200 DWORD WINAPI RtlLengthSid(PSID pSid)
202 TRACE("sid=%p\n",pSid);
204 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
207 /**************************************************************************
208 * RtlInitializeSid [NTDLL.@]
213 * pSid [I] SID to initialise
214 * pIdentifierAuthority [I] Identifier Authority
215 * nSubAuthorityCount [I] Number of Sub Authorities
218 * Success: TRUE. pSid is initialised withe the details given.
219 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
221 BOOL WINAPI RtlInitializeSid(
223 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
224 BYTE nSubAuthorityCount)
227 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
230 pSid->Revision = SID_REVISION;
231 pSid->SubAuthorityCount = nSubAuthorityCount;
232 if (pIdentifierAuthority)
233 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
235 for (i = 0; i < nSubAuthorityCount; i++)
236 *RtlSubAuthoritySid(pSid, i) = 0;
241 /**************************************************************************
242 * RtlSubAuthoritySid [NTDLL.@]
244 * Return the Sub Authority of a SID
247 * pSid [I] SID to get the Sub Authority from.
248 * nSubAuthority [I] Sub Authority number.
251 * A pointer to The Sub Authority value of pSid.
253 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
255 return &(pSid->SubAuthority[nSubAuthority]);
258 /**************************************************************************
259 * RtlIdentifierAuthoritySid [NTDLL.@]
261 * Return the Identifier Authority of a SID.
264 * pSid [I] SID to get the Identifier Authority from.
267 * A pointer to the Identifier Authority value of pSid.
269 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
271 return &(pSid->IdentifierAuthority);
274 /**************************************************************************
275 * RtlSubAuthorityCountSid [NTDLL.@]
277 * Get the number of Sub Authorities in a SID.
280 * pSid [I] SID to get the count from.
283 * A pointer to the Sub Authority count of pSid.
285 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
287 return &(pSid->SubAuthorityCount);
290 /**************************************************************************
291 * RtlCopySid [NTDLL.@]
293 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
295 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
296 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
299 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
302 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
305 /******************************************************************************
306 * RtlValidSid [NTDLL.@]
308 * Determine if a SID is valid.
311 * pSid [I] SID to check
314 * TRUE if pSid is valid,
317 BOOLEAN WINAPI RtlValidSid( PSID pSid )
323 if (!pSid || pSid->Revision != SID_REVISION ||
324 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
331 WARN("(%p): invalid pointer!\n", pSid);
340 * security descriptor functions
343 /**************************************************************************
344 * RtlCreateSecurityDescriptor [NTDLL.@]
346 * Initialise a SECURITY_DESCRIPTOR.
349 * lpsd [O] Descriptor to initialise.
350 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
353 * Success: STATUS_SUCCESS.
354 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
356 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
357 PSECURITY_DESCRIPTOR lpsd,
360 if (rev!=SECURITY_DESCRIPTOR_REVISION)
361 return STATUS_UNKNOWN_REVISION;
362 memset(lpsd,'\0',sizeof(*lpsd));
363 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
364 return STATUS_SUCCESS;
366 /**************************************************************************
367 * RtlValidSecurityDescriptor [NTDLL.@]
369 * Determine if a SECURITY_DESCRIPTOR is valid.
372 * SecurityDescriptor [I] Descriptor to check.
375 * Success: STATUS_SUCCESS.
376 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
378 NTSTATUS WINAPI RtlValidSecurityDescriptor(
379 PSECURITY_DESCRIPTOR SecurityDescriptor)
381 if ( ! SecurityDescriptor )
382 return STATUS_INVALID_SECURITY_DESCR;
383 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
384 return STATUS_UNKNOWN_REVISION;
386 return STATUS_SUCCESS;
389 /**************************************************************************
390 * RtlLengthSecurityDescriptor [NTDLL.@]
392 ULONG WINAPI RtlLengthSecurityDescriptor(
393 PSECURITY_DESCRIPTOR SecurityDescriptor)
396 ULONG Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
398 if ( SecurityDescriptor == NULL )
401 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
402 offset = (ULONG) SecurityDescriptor;
404 if ( SecurityDescriptor->Owner != NULL )
405 Size += RtlLengthSid((PSID)((LPBYTE)SecurityDescriptor->Owner + offset));
407 if ( SecurityDescriptor->Group != NULL )
408 Size += RtlLengthSid((PSID)((LPBYTE)SecurityDescriptor->Group + offset));
410 if ( SecurityDescriptor->Sacl != NULL )
411 Size += ((PACL)((LPBYTE)SecurityDescriptor->Sacl + offset))->AclSize;
413 if ( SecurityDescriptor->Dacl != NULL )
414 Size += ((PACL)((LPBYTE)SecurityDescriptor->Dacl + offset))->AclSize;
419 /******************************************************************************
420 * RtlGetDaclSecurityDescriptor [NTDLL.@]
423 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
424 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
425 OUT PBOOLEAN lpbDaclPresent,
427 OUT PBOOLEAN lpbDaclDefaulted)
429 TRACE("(%p,%p,%p,%p)\n",
430 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
432 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
433 return STATUS_UNKNOWN_REVISION ;
435 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
437 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
438 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
441 { *pDacl = pSecurityDescriptor->Dacl;
445 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
447 return STATUS_SUCCESS;
450 /**************************************************************************
451 * RtlSetDaclSecurityDescriptor [NTDLL.@]
453 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
454 PSECURITY_DESCRIPTOR lpsd,
457 BOOLEAN dacldefaulted )
459 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
460 return STATUS_UNKNOWN_REVISION;
461 if (lpsd->Control & SE_SELF_RELATIVE)
462 return STATUS_INVALID_SECURITY_DESCR;
465 { lpsd->Control &= ~SE_DACL_PRESENT;
469 lpsd->Control |= SE_DACL_PRESENT;
473 lpsd->Control |= SE_DACL_DEFAULTED;
475 lpsd->Control &= ~SE_DACL_DEFAULTED;
477 return STATUS_SUCCESS;
480 /******************************************************************************
481 * RtlGetSaclSecurityDescriptor [NTDLL.@]
484 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
485 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
486 OUT PBOOLEAN lpbSaclPresent,
488 OUT PBOOLEAN lpbSaclDefaulted)
490 TRACE("(%p,%p,%p,%p)\n",
491 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
493 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
494 return STATUS_UNKNOWN_REVISION ;
496 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
498 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
499 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
502 { *pSacl = pSecurityDescriptor->Sacl;
506 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
508 return STATUS_SUCCESS;
511 /**************************************************************************
512 * RtlSetSaclSecurityDescriptor [NTDLL.@]
514 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
515 PSECURITY_DESCRIPTOR lpsd,
518 BOOLEAN sacldefaulted)
520 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
521 return STATUS_UNKNOWN_REVISION;
522 if (lpsd->Control & SE_SELF_RELATIVE)
523 return STATUS_INVALID_SECURITY_DESCR;
525 lpsd->Control &= ~SE_SACL_PRESENT;
528 lpsd->Control |= SE_SACL_PRESENT;
531 lpsd->Control |= SE_SACL_DEFAULTED;
533 lpsd->Control &= ~SE_SACL_DEFAULTED;
534 return STATUS_SUCCESS;
537 /**************************************************************************
538 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
540 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
541 PSECURITY_DESCRIPTOR SecurityDescriptor,
543 PBOOLEAN OwnerDefaulted)
545 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
546 return STATUS_INVALID_PARAMETER;
548 if (SecurityDescriptor->Owner != NULL)
550 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
551 *Owner = (PSID)((LPBYTE)SecurityDescriptor +
552 (ULONG)SecurityDescriptor->Owner);
554 *Owner = SecurityDescriptor->Owner;
556 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
557 *OwnerDefaulted = TRUE;
559 *OwnerDefaulted = FALSE;
564 return STATUS_SUCCESS;
567 /**************************************************************************
568 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
570 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
571 PSECURITY_DESCRIPTOR lpsd,
573 BOOLEAN ownerdefaulted)
575 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
576 return STATUS_UNKNOWN_REVISION;
577 if (lpsd->Control & SE_SELF_RELATIVE)
578 return STATUS_INVALID_SECURITY_DESCR;
582 lpsd->Control |= SE_OWNER_DEFAULTED;
584 lpsd->Control &= ~SE_OWNER_DEFAULTED;
585 return STATUS_SUCCESS;
588 /**************************************************************************
589 * RtlSetGroupSecurityDescriptor [NTDLL.@]
591 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
592 PSECURITY_DESCRIPTOR lpsd,
594 BOOLEAN groupdefaulted)
596 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
597 return STATUS_UNKNOWN_REVISION;
598 if (lpsd->Control & SE_SELF_RELATIVE)
599 return STATUS_INVALID_SECURITY_DESCR;
603 lpsd->Control |= SE_GROUP_DEFAULTED;
605 lpsd->Control &= ~SE_GROUP_DEFAULTED;
606 return STATUS_SUCCESS;
608 /**************************************************************************
609 * RtlGetGroupSecurityDescriptor [NTDLL.@]
611 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
612 PSECURITY_DESCRIPTOR SecurityDescriptor,
614 PBOOLEAN GroupDefaulted)
616 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
617 return STATUS_INVALID_PARAMETER;
619 if (SecurityDescriptor->Group != NULL)
621 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
622 *Group = (PSID)((LPBYTE)SecurityDescriptor +
623 (ULONG)SecurityDescriptor->Group);
625 *Group = SecurityDescriptor->Group;
627 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
628 *GroupDefaulted = TRUE;
630 *GroupDefaulted = FALSE;
635 return STATUS_SUCCESS;
638 /**************************************************************************
639 * RtlMakeSelfRelativeSD [NTDLL.@]
641 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
642 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
643 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
644 IN OUT LPDWORD lpdwBufferLength)
648 PSECURITY_DESCRIPTOR pAbs = pAbsoluteSecurityDescriptor;
649 PSECURITY_DESCRIPTOR pRel = pSelfRelativeSecurityDescriptor;
651 TRACE(" %p %p %p(%ld)\n", pAbs, pRel, lpdwBufferLength,
652 lpdwBufferLength ? *lpdwBufferLength: -1);
654 if (!lpdwBufferLength || !pAbs)
655 return STATUS_INVALID_PARAMETER;
657 length = RtlLengthSecurityDescriptor(pAbs);
658 if (*lpdwBufferLength < length)
660 *lpdwBufferLength = length;
661 return STATUS_BUFFER_TOO_SMALL;
665 return STATUS_INVALID_PARAMETER;
667 if (pAbs->Control & SE_SELF_RELATIVE)
669 memcpy(pRel, pAbs, length);
670 return STATUS_SUCCESS;
673 pRel->Revision = pAbs->Revision;
674 pRel->Sbz1 = pAbs->Sbz1;
675 pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
677 offsetRel = sizeof(SECURITY_DESCRIPTOR);
678 pRel->Owner = (PSID) offsetRel;
679 length = RtlLengthSid(pAbs->Owner);
680 memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
683 pRel->Group = (PSID) offsetRel;
684 length = RtlLengthSid(pAbs->Group);
685 memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
687 if (pRel->Control & SE_SACL_PRESENT)
690 pRel->Sacl = (PACL) offsetRel;
691 length = pAbs->Sacl->AclSize;
692 memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
699 if (pRel->Control & SE_DACL_PRESENT)
702 pRel->Dacl = (PACL) offsetRel;
703 length = pAbs->Dacl->AclSize;
704 memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
711 return STATUS_SUCCESS;
715 /**************************************************************************
716 + * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
718 NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
719 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
720 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
721 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
723 OUT LPDWORD lpdwDaclSize,
725 OUT LPDWORD lpdwSaclSize,
727 OUT LPDWORD lpdwOwnerSize,
728 OUT PSID pPrimaryGroup,
729 OUT LPDWORD lpdwPrimaryGroupSize)
731 NTSTATUS status = STATUS_SUCCESS;
732 PSECURITY_DESCRIPTOR pAbs = pAbsoluteSecurityDescriptor;
733 PSECURITY_DESCRIPTOR pRel = pSelfRelativeSecurityDescriptor;
736 !lpdwAbsoluteSecurityDescriptorSize ||
740 !lpdwPrimaryGroupSize ||
741 ~pRel->Control & SE_SELF_RELATIVE)
742 return STATUS_INVALID_PARAMETER;
744 /* Confirm buffers are sufficiently large */
745 if (*lpdwAbsoluteSecurityDescriptorSize < sizeof(SECURITY_DESCRIPTOR))
747 *lpdwAbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
748 status = STATUS_BUFFER_TOO_SMALL;
751 if (pRel->Control & SE_DACL_PRESENT &&
752 *lpdwDaclSize < ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize)
754 *lpdwDaclSize = ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize;
755 status = STATUS_BUFFER_TOO_SMALL;
758 if (pRel->Control & SE_SACL_PRESENT &&
759 *lpdwSaclSize < ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize)
761 *lpdwSaclSize = ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize;
762 status = STATUS_BUFFER_TOO_SMALL;
766 *lpdwOwnerSize < RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel)))
768 *lpdwOwnerSize = RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel));
769 status = STATUS_BUFFER_TOO_SMALL;
773 *lpdwPrimaryGroupSize < RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel)))
775 *lpdwPrimaryGroupSize = RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel));
776 status = STATUS_BUFFER_TOO_SMALL;
779 if (status != STATUS_SUCCESS)
782 /* Copy structures */
783 pAbs->Revision = pRel->Revision;
784 pAbs->Control = pRel->Control & ~SE_SELF_RELATIVE;
786 if (pRel->Control & SE_SACL_PRESENT)
788 PACL pAcl = (PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel);
790 memcpy(pSacl, pAcl, pAcl->AclSize);
794 if (pRel->Control & SE_DACL_PRESENT)
796 PACL pAcl = (PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel);
797 memcpy(pDacl, pAcl, pAcl->AclSize);
803 PSID psid = (PSID)((LPBYTE)pRel->Owner + (ULONG)pRel);
804 memcpy(pOwner, psid, RtlLengthSid(psid));
805 pAbs->Owner = pOwner;
810 PSID psid = (PSID)((LPBYTE)pRel->Group + (ULONG)pRel);
811 memcpy(pPrimaryGroup, psid, RtlLengthSid(psid));
812 pAbs->Group = pPrimaryGroup;
819 * access control list's
822 /**************************************************************************
823 * RtlCreateAcl [NTDLL.@]
826 * This should return NTSTATUS
828 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
830 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
832 if (rev!=ACL_REVISION)
833 return STATUS_INVALID_PARAMETER;
834 if (size<sizeof(ACL))
835 return STATUS_BUFFER_TOO_SMALL;
837 return STATUS_INVALID_PARAMETER;
839 memset(acl,'\0',sizeof(ACL));
840 acl->AclRevision = rev;
843 return STATUS_SUCCESS;
846 /**************************************************************************
847 * RtlFirstFreeAce [NTDLL.@]
848 * looks for the AceCount+1 ACE, and if it is still within the alloced
849 * ACL, return a pointer to it
851 BOOLEAN WINAPI RtlFirstFreeAce(
859 ace = (PACE_HEADER)(acl+1);
860 for (i=0;i<acl->AceCount;i++) {
861 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
863 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
865 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
871 /**************************************************************************
872 * RtlAddAce [NTDLL.@]
874 NTSTATUS WINAPI RtlAddAce(
878 PACE_HEADER acestart,
881 PACE_HEADER ace,targetace;
884 if (acl->AclRevision != ACL_REVISION)
885 return STATUS_INVALID_PARAMETER;
886 if (!RtlFirstFreeAce(acl,&targetace))
887 return STATUS_INVALID_PARAMETER;
888 nrofaces=0;ace=acestart;
889 while (((DWORD)ace-(DWORD)acestart)<acelen) {
891 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
893 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
894 return STATUS_INVALID_PARAMETER;
895 memcpy((LPBYTE)targetace,acestart,acelen);
896 acl->AceCount+=nrofaces;
897 return STATUS_SUCCESS;
900 /**************************************************************************
901 * RtlDeleteAce [NTDLL.@]
903 NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
908 status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
910 if (STATUS_SUCCESS == status)
915 pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
916 for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
918 len += pcAce->AceSize;
919 pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
922 memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
929 /******************************************************************************
930 * RtlAddAccessAllowedAce [NTDLL.@]
932 NTSTATUS WINAPI RtlAddAccessAllowedAce(
934 IN DWORD dwAceRevision,
938 return RtlAddAccessAllowedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
941 /******************************************************************************
942 * RtlAddAccessAllowedAceEx [NTDLL.@]
944 NTSTATUS WINAPI RtlAddAccessAllowedAceEx(
946 IN DWORD dwAceRevision,
952 ACCESS_ALLOWED_ACE * pAaAce;
955 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
956 pAcl, dwAceRevision, AccessMask, pSid);
958 if (!RtlValidSid(pSid))
959 return STATUS_INVALID_SID;
960 if (!RtlValidAcl(pAcl))
961 return STATUS_INVALID_ACL;
963 dwLengthSid = RtlLengthSid(pSid);
964 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAaAce))
965 return STATUS_INVALID_ACL;
968 return STATUS_ALLOTTED_SPACE_EXCEEDED;
970 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAaAce;
971 if (dwSpaceLeft < sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid)
972 return STATUS_ALLOTTED_SPACE_EXCEEDED;
974 pAaAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
975 pAaAce->Header.AceFlags = AceFlags;
976 pAaAce->Header.AceSize = sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid;
977 pAaAce->Mask = AccessMask;
979 RtlCopySid(dwLengthSid, (PSID)&pAaAce->SidStart, pSid);
980 return STATUS_SUCCESS;
983 /******************************************************************************
984 * RtlAddAccessDeniedAce [NTDLL.@]
986 NTSTATUS WINAPI RtlAddAccessDeniedAce(
988 IN DWORD dwAceRevision,
992 return RtlAddAccessDeniedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
995 /******************************************************************************
996 * RtlAddAccessDeniedAceEx [NTDLL.@]
998 NTSTATUS WINAPI RtlAddAccessDeniedAceEx(
1000 IN DWORD dwAceRevision,
1002 IN DWORD AccessMask,
1007 ACCESS_DENIED_ACE * pAdAce;
1009 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1010 pAcl, dwAceRevision, AccessMask, pSid);
1012 if (!RtlValidSid(pSid))
1013 return STATUS_INVALID_SID;
1014 if (!RtlValidAcl(pAcl))
1015 return STATUS_INVALID_ACL;
1017 dwLengthSid = RtlLengthSid(pSid);
1018 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAdAce))
1019 return STATUS_INVALID_ACL;
1022 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1024 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAdAce;
1025 if (dwSpaceLeft < sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid)
1026 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1028 pAdAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
1029 pAdAce->Header.AceFlags = AceFlags;
1030 pAdAce->Header.AceSize = sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid;
1031 pAdAce->Mask = AccessMask;
1033 RtlCopySid(dwLengthSid, (PSID)&pAdAce->SidStart, pSid);
1034 return STATUS_SUCCESS;
1037 /******************************************************************************
1038 * RtlValidAcl [NTDLL.@]
1040 BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
1043 TRACE("(%p)\n", pAcl);
1050 if (pAcl->AclRevision != ACL_REVISION)
1054 ace = (PACE_HEADER)(pAcl+1);
1056 for (i=0;i<=pAcl->AceCount;i++)
1058 if ((char *)ace > (char *)pAcl + pAcl->AclSize)
1063 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1067 __EXCEPT(page_fault)
1069 WARN("(%p): invalid pointer!\n", pAcl);
1076 /******************************************************************************
1077 * RtlGetAce [NTDLL.@]
1079 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1083 TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
1085 if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
1086 return STATUS_INVALID_PARAMETER;
1088 ace = (PACE_HEADER)(pAcl + 1);
1089 for (;dwAceIndex;dwAceIndex--)
1090 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1092 *pAce = (LPVOID) ace;
1094 return STATUS_SUCCESS;
1101 /******************************************************************************
1102 * RtlAdjustPrivilege [NTDLL.@]
1104 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
1106 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
1110 /******************************************************************************
1111 * RtlImpersonateSelf [NTDLL.@]
1114 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1116 FIXME("(%08x), stub\n", ImpersonationLevel);
1120 /******************************************************************************
1121 * NtAccessCheck [NTDLL.@]
1122 * ZwAccessCheck [NTDLL.@]
1126 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1127 IN HANDLE ClientToken,
1128 IN ACCESS_MASK DesiredAccess,
1129 IN PGENERIC_MAPPING GenericMapping,
1130 OUT PPRIVILEGE_SET PrivilegeSet,
1131 OUT PULONG ReturnLength,
1132 OUT PULONG GrantedAccess,
1133 OUT PBOOLEAN AccessStatus)
1135 FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1136 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
1137 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
1138 *AccessStatus = TRUE;
1139 return STATUS_SUCCESS;
1142 /******************************************************************************
1143 * NtSetSecurityObject [NTDLL.@]
1146 NtSetSecurityObject(
1148 IN SECURITY_INFORMATION SecurityInformation,
1149 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
1151 FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
1152 return STATUS_SUCCESS;
1155 /******************************************************************************
1156 * RtlGetControlSecurityDescriptor (NTDLL.@)
1159 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
1160 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1161 PSECURITY_DESCRIPTOR_CONTROL pControl,
1162 LPDWORD lpdwRevision)
1164 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
1165 return STATUS_SUCCESS;
1168 /******************************************************************************
1169 * RtlConvertSidToUnicodeString (NTDLL.@)
1171 * The returned SID is used to access the USER registry hive usually
1173 * the native function returns something like
1174 * "S-1-5-21-0000000000-000000000-0000000000-500";
1176 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
1177 PUNICODE_STRING String,
1179 BOOLEAN AllocateString)
1181 const char *p = wine_get_user_name();
1183 ANSI_STRING AnsiStr;
1185 FIXME("(%p %p %u)\n", String, Sid, AllocateString);
1187 RtlInitAnsiString(&AnsiStr, p);
1188 status = RtlAnsiStringToUnicodeString(String, &AnsiStr, AllocateString);
1190 TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);
1194 /******************************************************************************
1195 * RtlQueryInformationAcl (NTDLL.@)
1197 NTSTATUS WINAPI RtlQueryInformationAcl(
1199 LPVOID pAclInformation,
1200 DWORD nAclInformationLength,
1201 ACL_INFORMATION_CLASS dwAclInformationClass)
1203 NTSTATUS status = STATUS_SUCCESS;
1205 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1206 pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
1208 switch (dwAclInformationClass)
1210 case AclRevisionInformation:
1212 PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
1214 if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
1215 status = STATUS_INVALID_PARAMETER;
1217 paclrev->AclRevision = pAcl->AclRevision;
1222 case AclSizeInformation:
1224 PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
1226 if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
1227 status = STATUS_INVALID_PARAMETER;
1233 paclsize->AceCount = pAcl->AceCount;
1235 paclsize->AclBytesInUse = 0;
1236 ace = (PACE_HEADER) (pAcl + 1);
1238 for (i = 0; i < pAcl->AceCount; i++)
1240 paclsize->AclBytesInUse += ace->AceSize;
1241 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1244 if (pAcl->AclSize < paclsize->AclBytesInUse)
1246 WARN("Acl has %ld bytes free\n", pAcl->AclSize - paclsize->AclBytesInUse);
1247 paclsize->AclBytesFree = 0;
1248 paclsize->AclBytesInUse = pAcl->AclSize;
1251 paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
1258 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
1259 status = STATUS_INVALID_PARAMETER;