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"
36 #include "wine/exception.h"
37 #include "ntdll_misc.h"
39 #include "wine/library.h"
40 #include "wine/unicode.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
45 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
47 /* filter for page-fault exceptions */
48 static WINE_EXCEPTION_FILTER(page_fault)
50 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
51 return EXCEPTION_EXECUTE_HANDLER;
52 return EXCEPTION_CONTINUE_SEARCH;
55 /* helper function to copy an ACL */
56 static BOOLEAN copy_acl(DWORD nDestinationAclLength, PACL pDestinationAcl, PACL pSourceAcl)
60 if (!pSourceAcl || !RtlValidAcl(pSourceAcl))
63 size = ((ACL *)pSourceAcl)->AclSize;
64 if (nDestinationAclLength < size)
67 memmove(pDestinationAcl, pSourceAcl, size);
71 /* generically adds an ACE to an ACL */
72 static NTSTATUS add_access_ace(PACL pAcl, DWORD dwAceRevision, DWORD dwAceFlags,
73 DWORD dwAccessMask, PSID pSid, DWORD dwAceType)
75 ACE_HEADER *pAceHeader;
81 if (!RtlValidSid(pSid))
82 return STATUS_INVALID_SID;
84 if (pAcl->AclRevision > MAX_ACL_REVISION || dwAceRevision > MAX_ACL_REVISION)
85 return STATUS_REVISION_MISMATCH;
87 if (!RtlValidAcl(pAcl))
88 return STATUS_INVALID_ACL;
90 if (!RtlFirstFreeAce(pAcl, &pAceHeader))
91 return STATUS_INVALID_ACL;
94 return STATUS_ALLOTTED_SPACE_EXCEEDED;
96 /* calculate generic size of the ACE */
97 dwLengthSid = RtlLengthSid(pSid);
98 dwAceSize = sizeof(ACE_HEADER) + sizeof(DWORD) + dwLengthSid;
99 if ((DWORD)(pAceHeader + dwAceSize) > (DWORD)(pAcl + pAcl->AclSize))
100 return STATUS_ALLOTTED_SPACE_EXCEEDED;
102 /* fill the new ACE */
103 pAceHeader->AceType = dwAceType;
104 pAceHeader->AceFlags = dwAceFlags;
105 pAceHeader->AceSize = dwAceSize;
107 /* skip past the ACE_HEADER of the ACE */
108 pAccessMask = (DWORD *)(pAceHeader + 1);
109 *pAccessMask = dwAccessMask;
111 /* skip past ACE->Mask */
112 pSidStart = pAccessMask + 1;
113 RtlCopySid(dwLengthSid, (PSID)pSidStart, pSid);
115 pAcl->AclRevision = max(pAcl->AclRevision, dwAceRevision);
118 return STATUS_SUCCESS;
125 /******************************************************************************
126 * RtlAllocateAndInitializeSid [NTDLL.@]
129 NTSTATUS WINAPI RtlAllocateAndInitializeSid (
130 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
131 BYTE nSubAuthorityCount,
132 DWORD nSubAuthority0, DWORD nSubAuthority1,
133 DWORD nSubAuthority2, DWORD nSubAuthority3,
134 DWORD nSubAuthority4, DWORD nSubAuthority5,
135 DWORD nSubAuthority6, DWORD nSubAuthority7,
139 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
140 pIdentifierAuthority,nSubAuthorityCount,
141 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
142 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
144 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0,
145 RtlLengthRequiredSid(nSubAuthorityCount))))
146 return STATUS_NO_MEMORY;
148 ((SID*)*pSid)->Revision = SID_REVISION;
150 if (pIdentifierAuthority)
151 memcpy(&((SID*)*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
152 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
154 if (nSubAuthorityCount > 0)
155 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
156 if (nSubAuthorityCount > 1)
157 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
158 if (nSubAuthorityCount > 2)
159 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
160 if (nSubAuthorityCount > 3)
161 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
162 if (nSubAuthorityCount > 4)
163 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
164 if (nSubAuthorityCount > 5)
165 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
166 if (nSubAuthorityCount > 6)
167 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
168 if (nSubAuthorityCount > 7)
169 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
171 return STATUS_SUCCESS;
173 /******************************************************************************
174 * RtlEqualSid [NTDLL.@]
176 * Determine if two SIDs are equal.
179 * pSid1 [I] Source SID
180 * pSid2 [I] SID to compare with
183 * TRUE, if pSid1 is equal to pSid2,
186 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
188 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
191 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
194 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
200 /******************************************************************************
201 * RtlEqualPrefixSid [NTDLL.@]
203 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
205 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
208 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
211 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(((SID*)pSid1)->SubAuthorityCount - 1)) != 0)
218 /******************************************************************************
219 * RtlFreeSid [NTDLL.@]
221 * Free the resources used by a SID.
224 * pSid [I] SID to Free.
229 DWORD WINAPI RtlFreeSid(PSID pSid)
231 TRACE("(%p)\n", pSid);
232 RtlFreeHeap( GetProcessHeap(), 0, pSid );
233 return STATUS_SUCCESS;
236 /**************************************************************************
237 * RtlLengthRequiredSid [NTDLL.@]
239 * Determine the amount of memory a SID will use
242 * nrofsubauths [I] Number of Sub Authorities in the SID.
245 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
247 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
249 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
252 /**************************************************************************
253 * RtlLengthSid [NTDLL.@]
255 * Determine the amount of memory a SID is using
258 * pSid [I] SID to get the size of.
261 * The size, in bytes, of pSid.
263 DWORD WINAPI RtlLengthSid(PSID pSid)
265 TRACE("sid=%p\n",pSid);
267 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
270 /**************************************************************************
271 * RtlInitializeSid [NTDLL.@]
276 * pSid [I] SID to initialise
277 * pIdentifierAuthority [I] Identifier Authority
278 * nSubAuthorityCount [I] Number of Sub Authorities
281 * Success: TRUE. pSid is initialised with the details given.
282 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
284 BOOL WINAPI RtlInitializeSid(
286 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
287 BYTE nSubAuthorityCount)
292 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
295 pisid->Revision = SID_REVISION;
296 pisid->SubAuthorityCount = nSubAuthorityCount;
297 if (pIdentifierAuthority)
298 memcpy(&pisid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
300 for (i = 0; i < nSubAuthorityCount; i++)
301 *RtlSubAuthoritySid(pSid, i) = 0;
306 /**************************************************************************
307 * RtlSubAuthoritySid [NTDLL.@]
309 * Return the Sub Authority of a SID
312 * pSid [I] SID to get the Sub Authority from.
313 * nSubAuthority [I] Sub Authority number.
316 * A pointer to The Sub Authority value of pSid.
318 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
320 return &(((SID*)pSid)->SubAuthority[nSubAuthority]);
323 /**************************************************************************
324 * RtlIdentifierAuthoritySid [NTDLL.@]
326 * Return the Identifier Authority of a SID.
329 * pSid [I] SID to get the Identifier Authority from.
332 * A pointer to the Identifier Authority value of pSid.
334 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
336 return &(((SID*)pSid)->IdentifierAuthority);
339 /**************************************************************************
340 * RtlSubAuthorityCountSid [NTDLL.@]
342 * Get the number of Sub Authorities in a SID.
345 * pSid [I] SID to get the count from.
348 * A pointer to the Sub Authority count of pSid.
350 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
352 return &(((SID*)pSid)->SubAuthorityCount);
355 /**************************************************************************
356 * RtlCopySid [NTDLL.@]
358 BOOLEAN WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
360 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
361 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
364 if (nDestinationSidLength < (((SID*)pSourceSid)->SubAuthorityCount*4+8))
367 memmove(pDestinationSid, pSourceSid, ((SID*)pSourceSid)->SubAuthorityCount*4+8);
370 /******************************************************************************
371 * RtlValidSid [NTDLL.@]
373 * Determine if a SID is valid.
376 * pSid [I] SID to check
379 * TRUE if pSid is valid,
382 BOOLEAN WINAPI RtlValidSid( PSID pSid )
388 if (!pSid || ((SID*)pSid)->Revision != SID_REVISION ||
389 ((SID*)pSid)->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
396 WARN("(%p): invalid pointer!\n", pSid);
405 * security descriptor functions
408 /**************************************************************************
409 * RtlCreateSecurityDescriptor [NTDLL.@]
411 * Initialise a SECURITY_DESCRIPTOR.
414 * lpsd [O] Descriptor to initialise.
415 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
418 * Success: STATUS_SUCCESS.
419 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
421 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
422 PSECURITY_DESCRIPTOR lpsd,
425 if (rev!=SECURITY_DESCRIPTOR_REVISION)
426 return STATUS_UNKNOWN_REVISION;
427 memset(lpsd,'\0',sizeof(SECURITY_DESCRIPTOR));
428 ((SECURITY_DESCRIPTOR*)lpsd)->Revision = SECURITY_DESCRIPTOR_REVISION;
429 return STATUS_SUCCESS;
432 /**************************************************************************
433 * RtlCopySecurityDescriptor [NTDLL.@]
435 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
438 * pSourceSD [O] SD to copy from.
439 * pDestinationSD [I] Destination SD.
442 * Success: STATUS_SUCCESS.
443 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
445 NTSTATUS WINAPI RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD, PSECURITY_DESCRIPTOR pDestinationSD)
447 SECURITY_DESCRIPTOR *srcSD = (SECURITY_DESCRIPTOR *)pSourceSD;
448 SECURITY_DESCRIPTOR *destSD = (SECURITY_DESCRIPTOR *)pDestinationSD;
451 BOOLEAN defaulted, present;
453 BOOL isSelfRelative = srcSD->Control & SE_SELF_RELATIVE;
455 if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION)
456 return STATUS_UNKNOWN_REVISION;
458 /* copy initial data */
459 destSD->Revision = srcSD->Revision;
460 destSD->Sbz1 = srcSD->Sbz1;
461 destSD->Control = srcSD->Control;
464 RtlGetOwnerSecurityDescriptor(pSourceSD, &Owner, &defaulted);
465 length = RtlLengthSid(Owner);
469 destSD->Owner = srcSD->Owner;
470 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Owner, Owner);
474 destSD->Owner = RtlAllocateHeap(GetProcessHeap(), 0, length);
475 RtlCopySid(length, destSD->Owner, Owner);
479 RtlGetGroupSecurityDescriptor(pSourceSD, &Group, &defaulted);
480 length = RtlLengthSid(Group);
484 destSD->Group = srcSD->Group;
485 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Group, Group);
489 destSD->Group = RtlAllocateHeap(GetProcessHeap(), 0, length);
490 RtlCopySid(length, destSD->Group, Group);
494 if (srcSD->Control & SE_DACL_PRESENT)
496 RtlGetDaclSecurityDescriptor(pSourceSD, &present, &Dacl, &defaulted);
497 length = Dacl->AclSize;
501 destSD->Dacl = srcSD->Dacl;
502 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Dacl), Dacl);
506 destSD->Dacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
507 copy_acl(length, destSD->Dacl, Dacl);
512 if (srcSD->Control & SE_SACL_PRESENT)
514 RtlGetSaclSecurityDescriptor(pSourceSD, &present, &Sacl, &defaulted);
515 length = Sacl->AclSize;
519 destSD->Sacl = srcSD->Sacl;
520 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Sacl), Sacl);
524 destSD->Sacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
525 copy_acl(length, destSD->Sacl, Sacl);
529 return STATUS_SUCCESS;
532 /**************************************************************************
533 * RtlValidSecurityDescriptor [NTDLL.@]
535 * Determine if a SECURITY_DESCRIPTOR is valid.
538 * SecurityDescriptor [I] Descriptor to check.
541 * Success: STATUS_SUCCESS.
542 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
544 NTSTATUS WINAPI RtlValidSecurityDescriptor(
545 PSECURITY_DESCRIPTOR SecurityDescriptor)
547 if ( ! SecurityDescriptor )
548 return STATUS_INVALID_SECURITY_DESCR;
549 if ( ((SECURITY_DESCRIPTOR*)SecurityDescriptor)->Revision != SECURITY_DESCRIPTOR_REVISION )
550 return STATUS_UNKNOWN_REVISION;
552 return STATUS_SUCCESS;
555 /**************************************************************************
556 * RtlLengthSecurityDescriptor [NTDLL.@]
558 ULONG WINAPI RtlLengthSecurityDescriptor(
559 PSECURITY_DESCRIPTOR pSecurityDescriptor)
561 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
563 ULONG Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
568 if ( lpsd->Control & SE_SELF_RELATIVE)
569 offset = (ULONG) lpsd;
571 if ( lpsd->Owner != NULL )
572 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Owner + offset));
574 if ( lpsd->Group != NULL )
575 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Group + offset));
577 if ( (lpsd->Control & SE_SACL_PRESENT) &&
579 Size += ((PACL)((LPBYTE)lpsd->Sacl + offset))->AclSize;
581 if ( (lpsd->Control & SE_DACL_PRESENT) &&
583 Size += ((PACL)((LPBYTE)lpsd->Dacl + offset))->AclSize;
588 /******************************************************************************
589 * RtlGetDaclSecurityDescriptor [NTDLL.@]
592 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
593 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
594 OUT PBOOLEAN lpbDaclPresent,
596 OUT PBOOLEAN lpbDaclDefaulted)
598 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
600 TRACE("(%p,%p,%p,%p)\n",
601 pSecurityDescriptor, lpbDaclPresent, pDacl, lpbDaclDefaulted);
603 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
604 return STATUS_UNKNOWN_REVISION ;
606 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & lpsd->Control) ? 1 : 0) )
608 if ( SE_SELF_RELATIVE & lpsd->Control)
609 *pDacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Dacl);
613 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
616 return STATUS_SUCCESS;
619 /**************************************************************************
620 * RtlSetDaclSecurityDescriptor [NTDLL.@]
622 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
623 PSECURITY_DESCRIPTOR pSecurityDescriptor,
626 BOOLEAN dacldefaulted )
628 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
630 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
631 return STATUS_UNKNOWN_REVISION;
632 if (lpsd->Control & SE_SELF_RELATIVE)
633 return STATUS_INVALID_SECURITY_DESCR;
636 { lpsd->Control &= ~SE_DACL_PRESENT;
640 lpsd->Control |= SE_DACL_PRESENT;
644 lpsd->Control |= SE_DACL_DEFAULTED;
646 lpsd->Control &= ~SE_DACL_DEFAULTED;
648 return STATUS_SUCCESS;
651 /******************************************************************************
652 * RtlGetSaclSecurityDescriptor [NTDLL.@]
655 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
656 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
657 OUT PBOOLEAN lpbSaclPresent,
659 OUT PBOOLEAN lpbSaclDefaulted)
661 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
663 TRACE("(%p,%p,%p,%p)\n",
664 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
666 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
667 return STATUS_UNKNOWN_REVISION;
669 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & lpsd->Control) ? 1 : 0) )
671 if (SE_SELF_RELATIVE & lpsd->Control)
672 *pSacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Sacl);
676 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
679 return STATUS_SUCCESS;
682 /**************************************************************************
683 * RtlSetSaclSecurityDescriptor [NTDLL.@]
685 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
686 PSECURITY_DESCRIPTOR pSecurityDescriptor,
689 BOOLEAN sacldefaulted)
691 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
693 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
694 return STATUS_UNKNOWN_REVISION;
695 if (lpsd->Control & SE_SELF_RELATIVE)
696 return STATUS_INVALID_SECURITY_DESCR;
698 lpsd->Control &= ~SE_SACL_PRESENT;
701 lpsd->Control |= SE_SACL_PRESENT;
704 lpsd->Control |= SE_SACL_DEFAULTED;
706 lpsd->Control &= ~SE_SACL_DEFAULTED;
707 return STATUS_SUCCESS;
710 /**************************************************************************
711 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
713 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
714 PSECURITY_DESCRIPTOR pSecurityDescriptor,
716 PBOOLEAN OwnerDefaulted)
718 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
720 if ( !lpsd || !Owner || !OwnerDefaulted )
721 return STATUS_INVALID_PARAMETER;
723 if (lpsd->Owner != NULL)
725 if (lpsd->Control & SE_SELF_RELATIVE)
726 *Owner = (PSID)((LPBYTE)lpsd +
729 *Owner = lpsd->Owner;
731 if ( lpsd->Control & SE_OWNER_DEFAULTED )
732 *OwnerDefaulted = TRUE;
734 *OwnerDefaulted = FALSE;
739 return STATUS_SUCCESS;
742 /**************************************************************************
743 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
745 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
746 PSECURITY_DESCRIPTOR pSecurityDescriptor,
748 BOOLEAN ownerdefaulted)
750 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
752 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
753 return STATUS_UNKNOWN_REVISION;
754 if (lpsd->Control & SE_SELF_RELATIVE)
755 return STATUS_INVALID_SECURITY_DESCR;
759 lpsd->Control |= SE_OWNER_DEFAULTED;
761 lpsd->Control &= ~SE_OWNER_DEFAULTED;
762 return STATUS_SUCCESS;
765 /**************************************************************************
766 * RtlSetGroupSecurityDescriptor [NTDLL.@]
768 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
769 PSECURITY_DESCRIPTOR pSecurityDescriptor,
771 BOOLEAN groupdefaulted)
773 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
775 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
776 return STATUS_UNKNOWN_REVISION;
777 if (lpsd->Control & SE_SELF_RELATIVE)
778 return STATUS_INVALID_SECURITY_DESCR;
782 lpsd->Control |= SE_GROUP_DEFAULTED;
784 lpsd->Control &= ~SE_GROUP_DEFAULTED;
785 return STATUS_SUCCESS;
788 /**************************************************************************
789 * RtlGetGroupSecurityDescriptor [NTDLL.@]
791 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
792 PSECURITY_DESCRIPTOR pSecurityDescriptor,
794 PBOOLEAN GroupDefaulted)
796 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
798 if ( !lpsd || !Group || !GroupDefaulted )
799 return STATUS_INVALID_PARAMETER;
801 if (lpsd->Group != NULL)
803 if (lpsd->Control & SE_SELF_RELATIVE)
804 *Group = (PSID)((LPBYTE)lpsd +
807 *Group = lpsd->Group;
809 if ( lpsd->Control & SE_GROUP_DEFAULTED )
810 *GroupDefaulted = TRUE;
812 *GroupDefaulted = FALSE;
817 return STATUS_SUCCESS;
820 /**************************************************************************
821 * RtlMakeSelfRelativeSD [NTDLL.@]
823 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
824 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
825 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
826 IN OUT LPDWORD lpdwBufferLength)
830 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
831 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
833 TRACE(" %p %p %p(%ld)\n", pAbs, pRel, lpdwBufferLength,
834 lpdwBufferLength ? *lpdwBufferLength: -1);
836 if (!lpdwBufferLength || !pAbs)
837 return STATUS_INVALID_PARAMETER;
839 length = RtlLengthSecurityDescriptor(pAbs);
840 if (*lpdwBufferLength < length)
842 *lpdwBufferLength = length;
843 return STATUS_BUFFER_TOO_SMALL;
847 return STATUS_INVALID_PARAMETER;
849 if (pAbs->Control & SE_SELF_RELATIVE)
851 memcpy(pRel, pAbs, length);
852 return STATUS_SUCCESS;
855 pRel->Revision = pAbs->Revision;
856 pRel->Sbz1 = pAbs->Sbz1;
857 pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
859 offsetRel = sizeof(SECURITY_DESCRIPTOR);
860 pRel->Owner = (PSID) offsetRel;
861 length = RtlLengthSid(pAbs->Owner);
862 memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
865 pRel->Group = (PSID) offsetRel;
866 length = RtlLengthSid(pAbs->Group);
867 memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
869 if (pRel->Control & SE_SACL_PRESENT)
872 pRel->Sacl = (PACL) offsetRel;
873 length = pAbs->Sacl->AclSize;
874 memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
881 if (pRel->Control & SE_DACL_PRESENT)
884 pRel->Dacl = (PACL) offsetRel;
885 length = pAbs->Dacl->AclSize;
886 memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
893 return STATUS_SUCCESS;
897 /**************************************************************************
898 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
900 NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
901 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
902 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
903 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
905 OUT LPDWORD lpdwDaclSize,
907 OUT LPDWORD lpdwSaclSize,
909 OUT LPDWORD lpdwOwnerSize,
910 OUT PSID pPrimaryGroup,
911 OUT LPDWORD lpdwPrimaryGroupSize)
913 NTSTATUS status = STATUS_SUCCESS;
914 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
915 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
918 !lpdwAbsoluteSecurityDescriptorSize ||
922 !lpdwPrimaryGroupSize ||
923 ~pRel->Control & SE_SELF_RELATIVE)
924 return STATUS_INVALID_PARAMETER;
926 /* Confirm buffers are sufficiently large */
927 if (*lpdwAbsoluteSecurityDescriptorSize < sizeof(SECURITY_DESCRIPTOR))
929 *lpdwAbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
930 status = STATUS_BUFFER_TOO_SMALL;
933 if (pRel->Control & SE_DACL_PRESENT &&
934 *lpdwDaclSize < ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize)
936 *lpdwDaclSize = ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize;
937 status = STATUS_BUFFER_TOO_SMALL;
940 if (pRel->Control & SE_SACL_PRESENT &&
941 *lpdwSaclSize < ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize)
943 *lpdwSaclSize = ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize;
944 status = STATUS_BUFFER_TOO_SMALL;
948 *lpdwOwnerSize < RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel)))
950 *lpdwOwnerSize = RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel));
951 status = STATUS_BUFFER_TOO_SMALL;
955 *lpdwPrimaryGroupSize < RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel)))
957 *lpdwPrimaryGroupSize = RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel));
958 status = STATUS_BUFFER_TOO_SMALL;
961 if (status != STATUS_SUCCESS)
964 /* Copy structures */
965 pAbs->Revision = pRel->Revision;
966 pAbs->Control = pRel->Control & ~SE_SELF_RELATIVE;
968 if (pRel->Control & SE_SACL_PRESENT)
970 PACL pAcl = (PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel);
972 memcpy(pSacl, pAcl, pAcl->AclSize);
976 if (pRel->Control & SE_DACL_PRESENT)
978 PACL pAcl = (PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel);
979 memcpy(pDacl, pAcl, pAcl->AclSize);
985 PSID psid = (PSID)((LPBYTE)pRel->Owner + (ULONG)pRel);
986 memcpy(pOwner, psid, RtlLengthSid(psid));
987 pAbs->Owner = pOwner;
992 PSID psid = (PSID)((LPBYTE)pRel->Group + (ULONG)pRel);
993 memcpy(pPrimaryGroup, psid, RtlLengthSid(psid));
994 pAbs->Group = pPrimaryGroup;
1000 /******************************************************************************
1001 * RtlGetControlSecurityDescriptor (NTDLL.@)
1003 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
1004 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1005 PSECURITY_DESCRIPTOR_CONTROL pControl,
1006 LPDWORD lpdwRevision)
1008 SECURITY_DESCRIPTOR *lpsd = pSecurityDescriptor;
1010 TRACE("(%p,%p,%p)\n",pSecurityDescriptor,pControl,lpdwRevision);
1012 *lpdwRevision = lpsd->Revision;
1014 if (*lpdwRevision != SECURITY_DESCRIPTOR_REVISION)
1015 return STATUS_UNKNOWN_REVISION;
1017 *pControl = lpsd->Control;
1019 return STATUS_SUCCESS;
1023 /**************************************************************************
1024 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1026 NTSTATUS WINAPI RtlAbsoluteToSelfRelativeSD(
1027 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
1028 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
1029 PULONG BufferLength)
1031 SECURITY_DESCRIPTOR *abs = AbsoluteSecurityDescriptor;
1033 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor,
1034 SelfRelativeSecurityDescriptor, BufferLength);
1036 if (abs->Control & SE_SELF_RELATIVE)
1037 return STATUS_BAD_DESCRIPTOR_FORMAT;
1039 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
1040 SelfRelativeSecurityDescriptor, BufferLength);
1045 * access control list's
1048 /**************************************************************************
1049 * RtlCreateAcl [NTDLL.@]
1052 * This should return NTSTATUS
1054 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
1056 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
1058 if (rev!=ACL_REVISION)
1059 return STATUS_INVALID_PARAMETER;
1060 if (size<sizeof(ACL))
1061 return STATUS_BUFFER_TOO_SMALL;
1063 return STATUS_INVALID_PARAMETER;
1065 memset(acl,'\0',sizeof(ACL));
1066 acl->AclRevision = rev;
1067 acl->AclSize = size;
1069 return STATUS_SUCCESS;
1072 /**************************************************************************
1073 * RtlFirstFreeAce [NTDLL.@]
1074 * looks for the AceCount+1 ACE, and if it is still within the alloced
1075 * ACL, return a pointer to it
1077 BOOLEAN WINAPI RtlFirstFreeAce(
1085 ace = (PACE_HEADER)(acl+1);
1086 for (i=0;i<acl->AceCount;i++) {
1087 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1089 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1091 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1097 /**************************************************************************
1098 * RtlAddAce [NTDLL.@]
1100 NTSTATUS WINAPI RtlAddAce(
1104 PACE_HEADER acestart,
1107 PACE_HEADER ace,targetace;
1110 if (acl->AclRevision != ACL_REVISION)
1111 return STATUS_INVALID_PARAMETER;
1112 if (!RtlFirstFreeAce(acl,&targetace))
1113 return STATUS_INVALID_PARAMETER;
1114 nrofaces=0;ace=acestart;
1115 while (((DWORD)ace-(DWORD)acestart)<acelen) {
1117 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1119 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
1120 return STATUS_INVALID_PARAMETER;
1121 memcpy((LPBYTE)targetace,acestart,acelen);
1122 acl->AceCount+=nrofaces;
1123 return STATUS_SUCCESS;
1126 /**************************************************************************
1127 * RtlDeleteAce [NTDLL.@]
1129 NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
1134 status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
1136 if (STATUS_SUCCESS == status)
1141 pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
1142 for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
1144 len += pcAce->AceSize;
1145 pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
1148 memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
1152 TRACE("pAcl=%p dwAceIndex=%ld status=0x%08lx\n", pAcl, dwAceIndex, status);
1157 /******************************************************************************
1158 * RtlAddAccessAllowedAce [NTDLL.@]
1160 NTSTATUS WINAPI RtlAddAccessAllowedAce(
1162 IN DWORD dwAceRevision,
1163 IN DWORD AccessMask,
1166 return RtlAddAccessAllowedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1169 /******************************************************************************
1170 * RtlAddAccessAllowedAceEx [NTDLL.@]
1172 NTSTATUS WINAPI RtlAddAccessAllowedAceEx(
1174 IN DWORD dwAceRevision,
1176 IN DWORD AccessMask,
1179 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl, dwAceRevision, AccessMask, pSid);
1181 return add_access_ace(pAcl, dwAceRevision, AceFlags,
1182 AccessMask, pSid, ACCESS_ALLOWED_ACE_TYPE);
1185 /******************************************************************************
1186 * RtlAddAccessDeniedAce [NTDLL.@]
1188 NTSTATUS WINAPI RtlAddAccessDeniedAce(
1190 IN DWORD dwAceRevision,
1191 IN DWORD AccessMask,
1194 return RtlAddAccessDeniedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1197 /******************************************************************************
1198 * RtlAddAccessDeniedAceEx [NTDLL.@]
1200 NTSTATUS WINAPI RtlAddAccessDeniedAceEx(
1202 IN DWORD dwAceRevision,
1204 IN DWORD AccessMask,
1207 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl, dwAceRevision, AccessMask, pSid);
1209 return add_access_ace(pAcl, dwAceRevision, AceFlags,
1210 AccessMask, pSid, ACCESS_DENIED_ACE_TYPE);
1213 /**************************************************************************
1214 * RtlAddAuditAccessAce [NTDLL.@]
1216 NTSTATUS WINAPI RtlAddAuditAccessAce(
1218 IN DWORD dwAceRevision,
1219 IN DWORD dwAccessMask,
1221 IN BOOL bAuditSuccess,
1222 IN BOOL bAuditFailure)
1224 DWORD dwAceFlags = 0;
1226 TRACE("(%p,%ld,%ld,%p,%u,%u)\n",pAcl,dwAceRevision,dwAccessMask,
1227 pSid,bAuditSuccess,bAuditFailure);
1230 dwAceFlags |= SUCCESSFUL_ACCESS_ACE_FLAG;
1233 dwAceFlags |= FAILED_ACCESS_ACE_FLAG;
1235 return add_access_ace(pAcl, dwAceRevision, dwAceFlags,
1236 dwAccessMask, pSid, SYSTEM_AUDIT_ACE_TYPE);
1239 /******************************************************************************
1240 * RtlValidAcl [NTDLL.@]
1242 BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
1245 TRACE("(%p)\n", pAcl);
1252 if (pAcl->AclRevision != ACL_REVISION)
1256 ace = (PACE_HEADER)(pAcl+1);
1258 for (i=0;i<=pAcl->AceCount;i++)
1260 if ((char *)ace > (char *)pAcl + pAcl->AclSize)
1265 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1269 __EXCEPT(page_fault)
1271 WARN("(%p): invalid pointer!\n", pAcl);
1278 /******************************************************************************
1279 * RtlGetAce [NTDLL.@]
1281 NTSTATUS WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1285 TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
1287 if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
1288 return STATUS_INVALID_PARAMETER;
1290 ace = (PACE_HEADER)(pAcl + 1);
1291 for (;dwAceIndex;dwAceIndex--)
1292 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1294 *pAce = (LPVOID) ace;
1296 return STATUS_SUCCESS;
1303 /******************************************************************************
1304 * RtlAdjustPrivilege [NTDLL.@]
1306 * Enables or disables a privilege from the calling thread or process.
1309 * Privilege [I] Privilege index to change.
1310 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1311 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1312 * Enabled [O] Whether privilege was previously enabled or disabled.
1315 * Success: STATUS_SUCCESS.
1316 * Failure: NTSTATUS code.
1319 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1323 RtlAdjustPrivilege(ULONG Privilege,
1325 BOOLEAN CurrentThread,
1328 TOKEN_PRIVILEGES NewState;
1329 TOKEN_PRIVILEGES OldState;
1334 TRACE("(%ld, %s, %s, %p)\n", Privilege, Enable ? "TRUE" : "FALSE",
1335 CurrentThread ? "TRUE" : "FALSE", Enabled);
1339 Status = NtOpenThreadToken(GetCurrentThread(),
1340 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1346 Status = NtOpenProcessToken(GetCurrentProcess(),
1347 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1351 if (!NT_SUCCESS(Status))
1353 WARN("Retrieving token handle failed (Status %lx)\n", Status);
1357 OldState.PrivilegeCount = 1;
1359 NewState.PrivilegeCount = 1;
1360 NewState.Privileges[0].Luid.LowPart = Privilege;
1361 NewState.Privileges[0].Luid.HighPart = 0;
1362 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
1364 Status = NtAdjustPrivilegesToken(TokenHandle,
1367 sizeof(TOKEN_PRIVILEGES),
1370 NtClose (TokenHandle);
1371 if (Status == STATUS_NOT_ALL_ASSIGNED)
1373 TRACE("Failed to assign all privileges\n");
1374 return STATUS_PRIVILEGE_NOT_HELD;
1376 if (!NT_SUCCESS(Status))
1378 WARN("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
1382 if (OldState.PrivilegeCount == 0)
1385 *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
1387 return STATUS_SUCCESS;
1390 /******************************************************************************
1391 * RtlImpersonateSelf [NTDLL.@]
1393 * Makes an impersonation token that represents the process user and assigns
1394 * to the current thread.
1397 * ImpersonationLevel [I] Level at which to impersonate.
1400 * Success: STATUS_SUCCESS.
1401 * Failure: NTSTATUS code.
1404 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1407 OBJECT_ATTRIBUTES ObjectAttributes;
1408 HANDLE ProcessToken;
1409 HANDLE ImpersonationToken;
1411 TRACE("(%08x)\n", ImpersonationLevel);
1413 Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE,
1415 if (Status != STATUS_SUCCESS)
1418 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1420 Status = NtDuplicateToken( ProcessToken,
1425 &ImpersonationToken );
1426 if (Status != STATUS_SUCCESS)
1428 NtClose( ProcessToken );
1432 Status = NtSetInformationThread( GetCurrentThread(),
1433 ThreadImpersonationToken,
1434 &ImpersonationToken,
1435 sizeof(ImpersonationToken) );
1437 NtClose( ImpersonationToken );
1438 NtClose( ProcessToken );
1443 /******************************************************************************
1444 * NtAccessCheck [NTDLL.@]
1445 * ZwAccessCheck [NTDLL.@]
1447 * Checks that a user represented by a token is allowed to access an object
1448 * represented by a security descriptor.
1451 * SecurityDescriptor [I] The security descriptor of the object to check.
1452 * ClientToken [I] Token of the user accessing the object.
1453 * DesiredAccess [I] The desired access to the object.
1454 * GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
1455 * PrivilegeSet [I/O] Privileges used during the access check.
1456 * ReturnLength [O] Number of bytes stored into PrivilegeSet.
1457 * GrantedAccess [O] The actual access rights granted.
1458 * AccessStatus [O] The status of the access check.
1464 * DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
1465 * the maximum access rights allowed by the SD and returns them in
1467 * The SecurityDescriptor must have a valid owner and groups present,
1468 * otherwise the function will fail.
1472 PSECURITY_DESCRIPTOR SecurityDescriptor,
1474 ACCESS_MASK DesiredAccess,
1475 PGENERIC_MAPPING GenericMapping,
1476 PPRIVILEGE_SET PrivilegeSet,
1477 PULONG ReturnLength,
1478 PULONG GrantedAccess,
1479 NTSTATUS *AccessStatus)
1483 TRACE("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1484 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
1485 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
1487 SERVER_START_REQ( access_check )
1489 struct security_descriptor sd;
1494 BOOLEAN defaulted, present;
1496 SECURITY_DESCRIPTOR_CONTROL control;
1498 req->handle = ClientToken;
1499 req->desired_access = DesiredAccess;
1500 req->mapping_read = GenericMapping->GenericRead;
1501 req->mapping_write = GenericMapping->GenericWrite;
1502 req->mapping_execute = GenericMapping->GenericExecute;
1503 req->mapping_all = GenericMapping->GenericAll;
1505 /* marshal security descriptor */
1506 RtlGetControlSecurityDescriptor( SecurityDescriptor, &control, &revision );
1507 sd.control = control & ~SE_SELF_RELATIVE;
1508 RtlGetOwnerSecurityDescriptor( SecurityDescriptor, &owner, &defaulted );
1509 sd.owner_len = RtlLengthSid( owner );
1510 RtlGetGroupSecurityDescriptor( SecurityDescriptor, &group, &defaulted );
1511 sd.group_len = RtlLengthSid( group );
1512 RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
1513 sd.sacl_len = (present ? sacl->AclSize : 0);
1514 RtlGetDaclSecurityDescriptor( SecurityDescriptor, &present, &dacl, &defaulted );
1515 sd.dacl_len = (present ? dacl->AclSize : 0);
1517 wine_server_add_data( req, &sd, sizeof(sd) );
1518 wine_server_add_data( req, owner, sd.owner_len );
1519 wine_server_add_data( req, group, sd.group_len );
1520 wine_server_add_data( req, sacl, sd.sacl_len );
1521 wine_server_add_data( req, dacl, sd.dacl_len );
1523 wine_server_set_reply( req, &PrivilegeSet->Privilege, *ReturnLength - FIELD_OFFSET( PRIVILEGE_SET, Privilege ) );
1525 status = wine_server_call( req );
1527 *ReturnLength = FIELD_OFFSET( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
1528 PrivilegeSet->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
1530 if (status == STATUS_SUCCESS)
1531 *AccessStatus = reply->access_status;
1532 *GrantedAccess = reply->access_granted;
1539 /******************************************************************************
1540 * NtSetSecurityObject [NTDLL.@]
1543 NtSetSecurityObject(
1545 IN SECURITY_INFORMATION SecurityInformation,
1546 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
1548 FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
1549 return STATUS_SUCCESS;
1552 /******************************************************************************
1553 * RtlConvertSidToUnicodeString (NTDLL.@)
1555 * The returned SID is used to access the USER registry hive usually
1557 * the native function returns something like
1558 * "S-1-5-21-0000000000-000000000-0000000000-500";
1560 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
1561 PUNICODE_STRING String,
1563 BOOLEAN AllocateString)
1565 static const WCHAR formatW[] = {'-','%','u',0};
1566 WCHAR buffer[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES];
1568 const SID *sid = (const SID *)pSid;
1572 p += sprintfW( p, formatW, sid->Revision );
1573 p += sprintfW( p, formatW, MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5],
1574 sid->IdentifierAuthority.Value[4] ),
1575 MAKEWORD( sid->IdentifierAuthority.Value[3],
1576 sid->IdentifierAuthority.Value[2] )));
1577 for (i = 0; i < sid->SubAuthorityCount; i++)
1578 p += sprintfW( p, formatW, sid->SubAuthority[i] );
1580 len = (p + 1 - buffer) * sizeof(WCHAR);
1582 String->Length = len - sizeof(WCHAR);
1585 String->MaximumLength = len;
1586 if (!(String->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
1587 return STATUS_NO_MEMORY;
1589 else if (len > String->MaximumLength) return STATUS_BUFFER_OVERFLOW;
1591 memcpy( String->Buffer, buffer, len );
1592 return STATUS_SUCCESS;
1595 /******************************************************************************
1596 * RtlQueryInformationAcl (NTDLL.@)
1598 NTSTATUS WINAPI RtlQueryInformationAcl(
1600 LPVOID pAclInformation,
1601 DWORD nAclInformationLength,
1602 ACL_INFORMATION_CLASS dwAclInformationClass)
1604 NTSTATUS status = STATUS_SUCCESS;
1606 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1607 pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
1609 switch (dwAclInformationClass)
1611 case AclRevisionInformation:
1613 PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
1615 if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
1616 status = STATUS_INVALID_PARAMETER;
1618 paclrev->AclRevision = pAcl->AclRevision;
1623 case AclSizeInformation:
1625 PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
1627 if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
1628 status = STATUS_INVALID_PARAMETER;
1634 paclsize->AceCount = pAcl->AceCount;
1636 paclsize->AclBytesInUse = 0;
1637 ace = (PACE_HEADER) (pAcl + 1);
1639 for (i = 0; i < pAcl->AceCount; i++)
1641 paclsize->AclBytesInUse += ace->AceSize;
1642 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1645 if (pAcl->AclSize < paclsize->AclBytesInUse)
1647 WARN("Acl has %ld bytes free\n", paclsize->AclBytesFree);
1648 paclsize->AclBytesFree = 0;
1649 paclsize->AclBytesInUse = pAcl->AclSize;
1652 paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
1659 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
1660 status = STATUS_INVALID_PARAMETER;