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/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
44 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
46 /* filter for page-fault exceptions */
47 static WINE_EXCEPTION_FILTER(page_fault)
49 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
50 return EXCEPTION_EXECUTE_HANDLER;
51 return EXCEPTION_CONTINUE_SEARCH;
54 /* helper function to copy an ACL */
55 static BOOLEAN copy_acl(DWORD nDestinationAclLength, PACL pDestinationAcl, PACL pSourceAcl)
59 if (!pSourceAcl || !RtlValidAcl(pSourceAcl))
62 size = ((ACL *)pSourceAcl)->AclSize;
63 if (nDestinationAclLength < size)
66 memmove(pDestinationAcl, pSourceAcl, size);
70 /* generically adds an ACE to an ACL */
71 static NTSTATUS add_access_ace(PACL pAcl, DWORD dwAceRevision, DWORD dwAceFlags,
72 DWORD dwAccessMask, PSID pSid, DWORD dwAceType)
74 ACE_HEADER *pAceHeader;
80 if (!RtlValidSid(pSid))
81 return STATUS_INVALID_SID;
83 if (pAcl->AclRevision > MAX_ACL_REVISION || dwAceRevision > MAX_ACL_REVISION)
84 return STATUS_REVISION_MISMATCH;
86 if (!RtlValidAcl(pAcl))
87 return STATUS_INVALID_ACL;
89 if (!RtlFirstFreeAce(pAcl, &pAceHeader))
90 return STATUS_INVALID_ACL;
93 return STATUS_ALLOTTED_SPACE_EXCEEDED;
95 /* calculate generic size of the ACE */
96 dwLengthSid = RtlLengthSid(pSid);
97 dwAceSize = sizeof(ACE_HEADER) + sizeof(DWORD) + dwLengthSid;
98 if ((DWORD)(pAceHeader + dwAceSize) > (DWORD)(pAcl + pAcl->AclSize))
99 return STATUS_ALLOTTED_SPACE_EXCEEDED;
101 /* fill the new ACE */
102 pAceHeader->AceType = dwAceType;
103 pAceHeader->AceFlags = dwAceFlags;
104 pAceHeader->AceSize = dwAceSize;
106 /* skip past the ACE_HEADER of the ACE */
107 pAccessMask = (DWORD *)(pAceHeader + 1);
108 *pAccessMask = dwAccessMask;
110 /* skip past ACE->Mask */
111 pSidStart = pAccessMask + 1;
112 RtlCopySid(dwLengthSid, (PSID)pSidStart, pSid);
114 pAcl->AclRevision = max(pAcl->AclRevision, dwAceRevision);
117 return STATUS_SUCCESS;
124 /******************************************************************************
125 * RtlAllocateAndInitializeSid [NTDLL.@]
128 NTSTATUS WINAPI RtlAllocateAndInitializeSid (
129 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
130 BYTE nSubAuthorityCount,
131 DWORD nSubAuthority0, DWORD nSubAuthority1,
132 DWORD nSubAuthority2, DWORD nSubAuthority3,
133 DWORD nSubAuthority4, DWORD nSubAuthority5,
134 DWORD nSubAuthority6, DWORD nSubAuthority7,
138 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
139 pIdentifierAuthority,nSubAuthorityCount,
140 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
141 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
143 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0,
144 RtlLengthRequiredSid(nSubAuthorityCount))))
145 return STATUS_NO_MEMORY;
147 ((SID*)*pSid)->Revision = SID_REVISION;
149 if (pIdentifierAuthority)
150 memcpy(&((SID*)*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
151 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
153 if (nSubAuthorityCount > 0)
154 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
155 if (nSubAuthorityCount > 1)
156 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
157 if (nSubAuthorityCount > 2)
158 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
159 if (nSubAuthorityCount > 3)
160 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
161 if (nSubAuthorityCount > 4)
162 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
163 if (nSubAuthorityCount > 5)
164 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
165 if (nSubAuthorityCount > 6)
166 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
167 if (nSubAuthorityCount > 7)
168 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
170 return STATUS_SUCCESS;
172 /******************************************************************************
173 * RtlEqualSid [NTDLL.@]
175 * Determine if two SIDs are equal.
178 * pSid1 [I] Source SID
179 * pSid2 [I] SID to compare with
182 * TRUE, if pSid1 is equal to pSid2,
185 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
187 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
190 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
193 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
199 /******************************************************************************
200 * RtlEqualPrefixSid [NTDLL.@]
202 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
204 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
207 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
210 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(((SID*)pSid1)->SubAuthorityCount - 1)) != 0)
217 /******************************************************************************
218 * RtlFreeSid [NTDLL.@]
220 * Free the resources used by a SID.
223 * pSid [I] SID to Free.
228 DWORD WINAPI RtlFreeSid(PSID pSid)
230 TRACE("(%p)\n", pSid);
231 RtlFreeHeap( GetProcessHeap(), 0, pSid );
232 return STATUS_SUCCESS;
235 /**************************************************************************
236 * RtlLengthRequiredSid [NTDLL.@]
238 * Determine the amount of memory a SID will use
241 * nrofsubauths [I] Number of Sub Authorities in the SID.
244 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
246 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
248 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
251 /**************************************************************************
252 * RtlLengthSid [NTDLL.@]
254 * Determine the amount of memory a SID is using
257 * pSid [I] SID to get the size of.
260 * The size, in bytes, of pSid.
262 DWORD WINAPI RtlLengthSid(PSID pSid)
264 TRACE("sid=%p\n",pSid);
266 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
269 /**************************************************************************
270 * RtlInitializeSid [NTDLL.@]
275 * pSid [I] SID to initialise
276 * pIdentifierAuthority [I] Identifier Authority
277 * nSubAuthorityCount [I] Number of Sub Authorities
280 * Success: TRUE. pSid is initialised with the details given.
281 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
283 BOOL WINAPI RtlInitializeSid(
285 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
286 BYTE nSubAuthorityCount)
291 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
294 pisid->Revision = SID_REVISION;
295 pisid->SubAuthorityCount = nSubAuthorityCount;
296 if (pIdentifierAuthority)
297 memcpy(&pisid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
299 for (i = 0; i < nSubAuthorityCount; i++)
300 *RtlSubAuthoritySid(pSid, i) = 0;
305 /**************************************************************************
306 * RtlSubAuthoritySid [NTDLL.@]
308 * Return the Sub Authority of a SID
311 * pSid [I] SID to get the Sub Authority from.
312 * nSubAuthority [I] Sub Authority number.
315 * A pointer to The Sub Authority value of pSid.
317 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
319 return &(((SID*)pSid)->SubAuthority[nSubAuthority]);
322 /**************************************************************************
323 * RtlIdentifierAuthoritySid [NTDLL.@]
325 * Return the Identifier Authority of a SID.
328 * pSid [I] SID to get the Identifier Authority from.
331 * A pointer to the Identifier Authority value of pSid.
333 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
335 return &(((SID*)pSid)->IdentifierAuthority);
338 /**************************************************************************
339 * RtlSubAuthorityCountSid [NTDLL.@]
341 * Get the number of Sub Authorities in a SID.
344 * pSid [I] SID to get the count from.
347 * A pointer to the Sub Authority count of pSid.
349 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
351 return &(((SID*)pSid)->SubAuthorityCount);
354 /**************************************************************************
355 * RtlCopySid [NTDLL.@]
357 BOOLEAN WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
359 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
360 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
363 if (nDestinationSidLength < (((SID*)pSourceSid)->SubAuthorityCount*4+8))
366 memmove(pDestinationSid, pSourceSid, ((SID*)pSourceSid)->SubAuthorityCount*4+8);
369 /******************************************************************************
370 * RtlValidSid [NTDLL.@]
372 * Determine if a SID is valid.
375 * pSid [I] SID to check
378 * TRUE if pSid is valid,
381 BOOLEAN WINAPI RtlValidSid( PSID pSid )
387 if (!pSid || ((SID*)pSid)->Revision != SID_REVISION ||
388 ((SID*)pSid)->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
395 WARN("(%p): invalid pointer!\n", pSid);
404 * security descriptor functions
407 /**************************************************************************
408 * RtlCreateSecurityDescriptor [NTDLL.@]
410 * Initialise a SECURITY_DESCRIPTOR.
413 * lpsd [O] Descriptor to initialise.
414 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
417 * Success: STATUS_SUCCESS.
418 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
420 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
421 PSECURITY_DESCRIPTOR lpsd,
424 if (rev!=SECURITY_DESCRIPTOR_REVISION)
425 return STATUS_UNKNOWN_REVISION;
426 memset(lpsd,'\0',sizeof(SECURITY_DESCRIPTOR));
427 ((SECURITY_DESCRIPTOR*)lpsd)->Revision = SECURITY_DESCRIPTOR_REVISION;
428 return STATUS_SUCCESS;
431 /**************************************************************************
432 * RtlCopySecurityDescriptor [NTDLL.@]
434 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
437 * pSourceSD [O] SD to copy from.
438 * pDestinationSD [I] Destination SD.
441 * Success: STATUS_SUCCESS.
442 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
444 NTSTATUS WINAPI RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD, PSECURITY_DESCRIPTOR pDestinationSD)
446 SECURITY_DESCRIPTOR *srcSD = (SECURITY_DESCRIPTOR *)pSourceSD;
447 SECURITY_DESCRIPTOR *destSD = (SECURITY_DESCRIPTOR *)pDestinationSD;
450 BOOLEAN defaulted, present;
452 BOOL isSelfRelative = srcSD->Control & SE_SELF_RELATIVE;
454 if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION)
455 return STATUS_UNKNOWN_REVISION;
457 /* copy initial data */
458 destSD->Revision = srcSD->Revision;
459 destSD->Sbz1 = srcSD->Sbz1;
460 destSD->Control = srcSD->Control;
463 RtlGetOwnerSecurityDescriptor(pSourceSD, &Owner, &defaulted);
464 length = RtlLengthSid(Owner);
468 destSD->Owner = srcSD->Owner;
469 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Owner, Owner);
473 destSD->Owner = RtlAllocateHeap(GetProcessHeap(), 0, length);
474 RtlCopySid(length, destSD->Owner, Owner);
478 RtlGetGroupSecurityDescriptor(pSourceSD, &Group, &defaulted);
479 length = RtlLengthSid(Group);
483 destSD->Group = srcSD->Group;
484 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Group, Group);
488 destSD->Group = RtlAllocateHeap(GetProcessHeap(), 0, length);
489 RtlCopySid(length, destSD->Group, Group);
493 if (srcSD->Control & SE_DACL_PRESENT)
495 RtlGetDaclSecurityDescriptor(pSourceSD, &present, &Dacl, &defaulted);
496 length = Dacl->AclSize;
500 destSD->Dacl = srcSD->Dacl;
501 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Dacl), Dacl);
505 destSD->Dacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
506 copy_acl(length, destSD->Dacl, Dacl);
511 if (srcSD->Control & SE_SACL_PRESENT)
513 RtlGetSaclSecurityDescriptor(pSourceSD, &present, &Sacl, &defaulted);
514 length = Sacl->AclSize;
518 destSD->Sacl = srcSD->Sacl;
519 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Sacl), Sacl);
523 destSD->Sacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
524 copy_acl(length, destSD->Sacl, Sacl);
528 return STATUS_SUCCESS;
531 /**************************************************************************
532 * RtlValidSecurityDescriptor [NTDLL.@]
534 * Determine if a SECURITY_DESCRIPTOR is valid.
537 * SecurityDescriptor [I] Descriptor to check.
540 * Success: STATUS_SUCCESS.
541 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
543 NTSTATUS WINAPI RtlValidSecurityDescriptor(
544 PSECURITY_DESCRIPTOR SecurityDescriptor)
546 if ( ! SecurityDescriptor )
547 return STATUS_INVALID_SECURITY_DESCR;
548 if ( ((SECURITY_DESCRIPTOR*)SecurityDescriptor)->Revision != SECURITY_DESCRIPTOR_REVISION )
549 return STATUS_UNKNOWN_REVISION;
551 return STATUS_SUCCESS;
554 /**************************************************************************
555 * RtlLengthSecurityDescriptor [NTDLL.@]
557 ULONG WINAPI RtlLengthSecurityDescriptor(
558 PSECURITY_DESCRIPTOR pSecurityDescriptor)
560 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
562 ULONG Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
567 if ( lpsd->Control & SE_SELF_RELATIVE)
568 offset = (ULONG) lpsd;
570 if ( lpsd->Owner != NULL )
571 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Owner + offset));
573 if ( lpsd->Group != NULL )
574 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Group + offset));
576 if ( (lpsd->Control & SE_SACL_PRESENT) &&
578 Size += ((PACL)((LPBYTE)lpsd->Sacl + offset))->AclSize;
580 if ( (lpsd->Control & SE_DACL_PRESENT) &&
582 Size += ((PACL)((LPBYTE)lpsd->Dacl + offset))->AclSize;
587 /******************************************************************************
588 * RtlGetDaclSecurityDescriptor [NTDLL.@]
591 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
592 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
593 OUT PBOOLEAN lpbDaclPresent,
595 OUT PBOOLEAN lpbDaclDefaulted)
597 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
599 TRACE("(%p,%p,%p,%p)\n",
600 pSecurityDescriptor, lpbDaclPresent, pDacl, lpbDaclDefaulted);
602 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
603 return STATUS_UNKNOWN_REVISION ;
605 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & lpsd->Control) ? 1 : 0) )
607 if ( SE_SELF_RELATIVE & lpsd->Control)
608 *pDacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Dacl);
612 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
615 return STATUS_SUCCESS;
618 /**************************************************************************
619 * RtlSetDaclSecurityDescriptor [NTDLL.@]
621 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
622 PSECURITY_DESCRIPTOR pSecurityDescriptor,
625 BOOLEAN dacldefaulted )
627 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
629 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
630 return STATUS_UNKNOWN_REVISION;
631 if (lpsd->Control & SE_SELF_RELATIVE)
632 return STATUS_INVALID_SECURITY_DESCR;
635 { lpsd->Control &= ~SE_DACL_PRESENT;
639 lpsd->Control |= SE_DACL_PRESENT;
643 lpsd->Control |= SE_DACL_DEFAULTED;
645 lpsd->Control &= ~SE_DACL_DEFAULTED;
647 return STATUS_SUCCESS;
650 /******************************************************************************
651 * RtlGetSaclSecurityDescriptor [NTDLL.@]
654 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
655 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
656 OUT PBOOLEAN lpbSaclPresent,
658 OUT PBOOLEAN lpbSaclDefaulted)
660 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
662 TRACE("(%p,%p,%p,%p)\n",
663 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
665 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
666 return STATUS_UNKNOWN_REVISION;
668 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & lpsd->Control) ? 1 : 0) )
670 if (SE_SELF_RELATIVE & lpsd->Control)
671 *pSacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Sacl);
675 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
678 return STATUS_SUCCESS;
681 /**************************************************************************
682 * RtlSetSaclSecurityDescriptor [NTDLL.@]
684 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
685 PSECURITY_DESCRIPTOR pSecurityDescriptor,
688 BOOLEAN sacldefaulted)
690 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
692 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
693 return STATUS_UNKNOWN_REVISION;
694 if (lpsd->Control & SE_SELF_RELATIVE)
695 return STATUS_INVALID_SECURITY_DESCR;
697 lpsd->Control &= ~SE_SACL_PRESENT;
700 lpsd->Control |= SE_SACL_PRESENT;
703 lpsd->Control |= SE_SACL_DEFAULTED;
705 lpsd->Control &= ~SE_SACL_DEFAULTED;
706 return STATUS_SUCCESS;
709 /**************************************************************************
710 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
712 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
713 PSECURITY_DESCRIPTOR pSecurityDescriptor,
715 PBOOLEAN OwnerDefaulted)
717 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
719 if ( !lpsd || !Owner || !OwnerDefaulted )
720 return STATUS_INVALID_PARAMETER;
722 if (lpsd->Owner != NULL)
724 if (lpsd->Control & SE_SELF_RELATIVE)
725 *Owner = (PSID)((LPBYTE)lpsd +
728 *Owner = lpsd->Owner;
730 if ( lpsd->Control & SE_OWNER_DEFAULTED )
731 *OwnerDefaulted = TRUE;
733 *OwnerDefaulted = FALSE;
738 return STATUS_SUCCESS;
741 /**************************************************************************
742 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
744 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
745 PSECURITY_DESCRIPTOR pSecurityDescriptor,
747 BOOLEAN ownerdefaulted)
749 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
751 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
752 return STATUS_UNKNOWN_REVISION;
753 if (lpsd->Control & SE_SELF_RELATIVE)
754 return STATUS_INVALID_SECURITY_DESCR;
758 lpsd->Control |= SE_OWNER_DEFAULTED;
760 lpsd->Control &= ~SE_OWNER_DEFAULTED;
761 return STATUS_SUCCESS;
764 /**************************************************************************
765 * RtlSetGroupSecurityDescriptor [NTDLL.@]
767 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
768 PSECURITY_DESCRIPTOR pSecurityDescriptor,
770 BOOLEAN groupdefaulted)
772 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
774 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
775 return STATUS_UNKNOWN_REVISION;
776 if (lpsd->Control & SE_SELF_RELATIVE)
777 return STATUS_INVALID_SECURITY_DESCR;
781 lpsd->Control |= SE_GROUP_DEFAULTED;
783 lpsd->Control &= ~SE_GROUP_DEFAULTED;
784 return STATUS_SUCCESS;
787 /**************************************************************************
788 * RtlGetGroupSecurityDescriptor [NTDLL.@]
790 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
791 PSECURITY_DESCRIPTOR pSecurityDescriptor,
793 PBOOLEAN GroupDefaulted)
795 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
797 if ( !lpsd || !Group || !GroupDefaulted )
798 return STATUS_INVALID_PARAMETER;
800 if (lpsd->Group != NULL)
802 if (lpsd->Control & SE_SELF_RELATIVE)
803 *Group = (PSID)((LPBYTE)lpsd +
806 *Group = lpsd->Group;
808 if ( lpsd->Control & SE_GROUP_DEFAULTED )
809 *GroupDefaulted = TRUE;
811 *GroupDefaulted = FALSE;
816 return STATUS_SUCCESS;
819 /**************************************************************************
820 * RtlMakeSelfRelativeSD [NTDLL.@]
822 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
823 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
824 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
825 IN OUT LPDWORD lpdwBufferLength)
829 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
830 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
832 TRACE(" %p %p %p(%ld)\n", pAbs, pRel, lpdwBufferLength,
833 lpdwBufferLength ? *lpdwBufferLength: -1);
835 if (!lpdwBufferLength || !pAbs)
836 return STATUS_INVALID_PARAMETER;
838 length = RtlLengthSecurityDescriptor(pAbs);
839 if (*lpdwBufferLength < length)
841 *lpdwBufferLength = length;
842 return STATUS_BUFFER_TOO_SMALL;
846 return STATUS_INVALID_PARAMETER;
848 if (pAbs->Control & SE_SELF_RELATIVE)
850 memcpy(pRel, pAbs, length);
851 return STATUS_SUCCESS;
854 pRel->Revision = pAbs->Revision;
855 pRel->Sbz1 = pAbs->Sbz1;
856 pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
858 offsetRel = sizeof(SECURITY_DESCRIPTOR);
859 pRel->Owner = (PSID) offsetRel;
860 length = RtlLengthSid(pAbs->Owner);
861 memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
864 pRel->Group = (PSID) offsetRel;
865 length = RtlLengthSid(pAbs->Group);
866 memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
868 if (pRel->Control & SE_SACL_PRESENT)
871 pRel->Sacl = (PACL) offsetRel;
872 length = pAbs->Sacl->AclSize;
873 memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
880 if (pRel->Control & SE_DACL_PRESENT)
883 pRel->Dacl = (PACL) offsetRel;
884 length = pAbs->Dacl->AclSize;
885 memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
892 return STATUS_SUCCESS;
896 /**************************************************************************
897 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
899 NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
900 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
901 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
902 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
904 OUT LPDWORD lpdwDaclSize,
906 OUT LPDWORD lpdwSaclSize,
908 OUT LPDWORD lpdwOwnerSize,
909 OUT PSID pPrimaryGroup,
910 OUT LPDWORD lpdwPrimaryGroupSize)
912 NTSTATUS status = STATUS_SUCCESS;
913 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
914 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
917 !lpdwAbsoluteSecurityDescriptorSize ||
921 !lpdwPrimaryGroupSize ||
922 ~pRel->Control & SE_SELF_RELATIVE)
923 return STATUS_INVALID_PARAMETER;
925 /* Confirm buffers are sufficiently large */
926 if (*lpdwAbsoluteSecurityDescriptorSize < sizeof(SECURITY_DESCRIPTOR))
928 *lpdwAbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
929 status = STATUS_BUFFER_TOO_SMALL;
932 if (pRel->Control & SE_DACL_PRESENT &&
933 *lpdwDaclSize < ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize)
935 *lpdwDaclSize = ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize;
936 status = STATUS_BUFFER_TOO_SMALL;
939 if (pRel->Control & SE_SACL_PRESENT &&
940 *lpdwSaclSize < ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize)
942 *lpdwSaclSize = ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize;
943 status = STATUS_BUFFER_TOO_SMALL;
947 *lpdwOwnerSize < RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel)))
949 *lpdwOwnerSize = RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel));
950 status = STATUS_BUFFER_TOO_SMALL;
954 *lpdwPrimaryGroupSize < RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel)))
956 *lpdwPrimaryGroupSize = RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel));
957 status = STATUS_BUFFER_TOO_SMALL;
960 if (status != STATUS_SUCCESS)
963 /* Copy structures */
964 pAbs->Revision = pRel->Revision;
965 pAbs->Control = pRel->Control & ~SE_SELF_RELATIVE;
967 if (pRel->Control & SE_SACL_PRESENT)
969 PACL pAcl = (PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel);
971 memcpy(pSacl, pAcl, pAcl->AclSize);
975 if (pRel->Control & SE_DACL_PRESENT)
977 PACL pAcl = (PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel);
978 memcpy(pDacl, pAcl, pAcl->AclSize);
984 PSID psid = (PSID)((LPBYTE)pRel->Owner + (ULONG)pRel);
985 memcpy(pOwner, psid, RtlLengthSid(psid));
986 pAbs->Owner = pOwner;
991 PSID psid = (PSID)((LPBYTE)pRel->Group + (ULONG)pRel);
992 memcpy(pPrimaryGroup, psid, RtlLengthSid(psid));
993 pAbs->Group = pPrimaryGroup;
999 /******************************************************************************
1000 * RtlGetControlSecurityDescriptor (NTDLL.@)
1002 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
1003 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1004 PSECURITY_DESCRIPTOR_CONTROL pControl,
1005 LPDWORD lpdwRevision)
1007 SECURITY_DESCRIPTOR *lpsd = pSecurityDescriptor;
1009 TRACE("(%p,%p,%p)\n",pSecurityDescriptor,pControl,lpdwRevision);
1011 *lpdwRevision = lpsd->Revision;
1013 if (*lpdwRevision != SECURITY_DESCRIPTOR_REVISION)
1014 return STATUS_UNKNOWN_REVISION;
1016 *pControl = lpsd->Control;
1018 return STATUS_SUCCESS;
1022 /**************************************************************************
1023 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1025 NTSTATUS WINAPI RtlAbsoluteToSelfRelativeSD(
1026 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
1027 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
1028 PULONG BufferLength)
1030 SECURITY_DESCRIPTOR *abs = AbsoluteSecurityDescriptor;
1032 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor,
1033 SelfRelativeSecurityDescriptor, BufferLength);
1035 if (abs->Control & SE_SELF_RELATIVE)
1036 return STATUS_BAD_DESCRIPTOR_FORMAT;
1038 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
1039 SelfRelativeSecurityDescriptor, BufferLength);
1044 * access control list's
1047 /**************************************************************************
1048 * RtlCreateAcl [NTDLL.@]
1051 * This should return NTSTATUS
1053 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
1055 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
1057 if (rev!=ACL_REVISION)
1058 return STATUS_INVALID_PARAMETER;
1059 if (size<sizeof(ACL))
1060 return STATUS_BUFFER_TOO_SMALL;
1062 return STATUS_INVALID_PARAMETER;
1064 memset(acl,'\0',sizeof(ACL));
1065 acl->AclRevision = rev;
1066 acl->AclSize = size;
1068 return STATUS_SUCCESS;
1071 /**************************************************************************
1072 * RtlFirstFreeAce [NTDLL.@]
1073 * looks for the AceCount+1 ACE, and if it is still within the alloced
1074 * ACL, return a pointer to it
1076 BOOLEAN WINAPI RtlFirstFreeAce(
1084 ace = (PACE_HEADER)(acl+1);
1085 for (i=0;i<acl->AceCount;i++) {
1086 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1088 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1090 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1096 /**************************************************************************
1097 * RtlAddAce [NTDLL.@]
1099 NTSTATUS WINAPI RtlAddAce(
1103 PACE_HEADER acestart,
1106 PACE_HEADER ace,targetace;
1109 if (acl->AclRevision != ACL_REVISION)
1110 return STATUS_INVALID_PARAMETER;
1111 if (!RtlFirstFreeAce(acl,&targetace))
1112 return STATUS_INVALID_PARAMETER;
1113 nrofaces=0;ace=acestart;
1114 while (((DWORD)ace-(DWORD)acestart)<acelen) {
1116 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1118 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
1119 return STATUS_INVALID_PARAMETER;
1120 memcpy((LPBYTE)targetace,acestart,acelen);
1121 acl->AceCount+=nrofaces;
1122 return STATUS_SUCCESS;
1125 /**************************************************************************
1126 * RtlDeleteAce [NTDLL.@]
1128 NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
1133 status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
1135 if (STATUS_SUCCESS == status)
1140 pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
1141 for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
1143 len += pcAce->AceSize;
1144 pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
1147 memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
1151 TRACE("pAcl=%p dwAceIndex=%ld status=0x%08lx\n", pAcl, dwAceIndex, status);
1156 /******************************************************************************
1157 * RtlAddAccessAllowedAce [NTDLL.@]
1159 NTSTATUS WINAPI RtlAddAccessAllowedAce(
1161 IN DWORD dwAceRevision,
1162 IN DWORD AccessMask,
1165 return RtlAddAccessAllowedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1168 /******************************************************************************
1169 * RtlAddAccessAllowedAceEx [NTDLL.@]
1171 NTSTATUS WINAPI RtlAddAccessAllowedAceEx(
1173 IN DWORD dwAceRevision,
1175 IN DWORD AccessMask,
1178 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl, dwAceRevision, AccessMask, pSid);
1180 return add_access_ace(pAcl, dwAceRevision, AceFlags,
1181 AccessMask, pSid, ACCESS_ALLOWED_ACE_TYPE);
1184 /******************************************************************************
1185 * RtlAddAccessDeniedAce [NTDLL.@]
1187 NTSTATUS WINAPI RtlAddAccessDeniedAce(
1189 IN DWORD dwAceRevision,
1190 IN DWORD AccessMask,
1193 return RtlAddAccessDeniedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1196 /******************************************************************************
1197 * RtlAddAccessDeniedAceEx [NTDLL.@]
1199 NTSTATUS WINAPI RtlAddAccessDeniedAceEx(
1201 IN DWORD dwAceRevision,
1203 IN DWORD AccessMask,
1206 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl, dwAceRevision, AccessMask, pSid);
1208 return add_access_ace(pAcl, dwAceRevision, AceFlags,
1209 AccessMask, pSid, ACCESS_DENIED_ACE_TYPE);
1212 /**************************************************************************
1213 * RtlAddAuditAccessAce [NTDLL.@]
1215 NTSTATUS WINAPI RtlAddAuditAccessAce(
1217 IN DWORD dwAceRevision,
1218 IN DWORD dwAccessMask,
1220 IN BOOL bAuditSuccess,
1221 IN BOOL bAuditFailure)
1223 DWORD dwAceFlags = 0;
1225 TRACE("(%p,%ld,%ld,%p,%u,%u)\n",pAcl,dwAceRevision,dwAccessMask,
1226 pSid,bAuditSuccess,bAuditFailure);
1229 dwAceFlags |= SUCCESSFUL_ACCESS_ACE_FLAG;
1232 dwAceFlags |= FAILED_ACCESS_ACE_FLAG;
1234 return add_access_ace(pAcl, dwAceRevision, dwAceFlags,
1235 dwAccessMask, pSid, SYSTEM_AUDIT_ACE_TYPE);
1238 /******************************************************************************
1239 * RtlValidAcl [NTDLL.@]
1241 BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
1244 TRACE("(%p)\n", pAcl);
1251 if (pAcl->AclRevision != ACL_REVISION)
1255 ace = (PACE_HEADER)(pAcl+1);
1257 for (i=0;i<=pAcl->AceCount;i++)
1259 if ((char *)ace > (char *)pAcl + pAcl->AclSize)
1264 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1268 __EXCEPT(page_fault)
1270 WARN("(%p): invalid pointer!\n", pAcl);
1277 /******************************************************************************
1278 * RtlGetAce [NTDLL.@]
1280 NTSTATUS WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1284 TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
1286 if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
1287 return STATUS_INVALID_PARAMETER;
1289 ace = (PACE_HEADER)(pAcl + 1);
1290 for (;dwAceIndex;dwAceIndex--)
1291 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1293 *pAce = (LPVOID) ace;
1295 return STATUS_SUCCESS;
1302 /******************************************************************************
1303 * RtlAdjustPrivilege [NTDLL.@]
1305 * Enables or disables a privilege from the calling thread or process.
1308 * Privilege [I] Privilege index to change.
1309 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1310 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1311 * Enabled [O] Whether privilege was previously enabled or disabled.
1314 * Success: STATUS_SUCCESS.
1315 * Failure: NTSTATUS code.
1318 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1322 RtlAdjustPrivilege(ULONG Privilege,
1324 BOOLEAN CurrentThread,
1327 TOKEN_PRIVILEGES NewState;
1328 TOKEN_PRIVILEGES OldState;
1333 TRACE("(%ld, %s, %s, %p)\n", Privilege, Enable ? "TRUE" : "FALSE",
1334 CurrentThread ? "TRUE" : "FALSE", Enabled);
1338 Status = NtOpenThreadToken(GetCurrentThread(),
1339 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1345 Status = NtOpenProcessToken(GetCurrentProcess(),
1346 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1350 if (!NT_SUCCESS(Status))
1352 WARN("Retrieving token handle failed (Status %lx)\n", Status);
1356 OldState.PrivilegeCount = 1;
1358 NewState.PrivilegeCount = 1;
1359 NewState.Privileges[0].Luid.LowPart = Privilege;
1360 NewState.Privileges[0].Luid.HighPart = 0;
1361 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
1363 Status = NtAdjustPrivilegesToken(TokenHandle,
1366 sizeof(TOKEN_PRIVILEGES),
1369 NtClose (TokenHandle);
1370 if (Status == STATUS_NOT_ALL_ASSIGNED)
1372 TRACE("Failed to assign all privileges\n");
1373 return STATUS_PRIVILEGE_NOT_HELD;
1375 if (!NT_SUCCESS(Status))
1377 WARN("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
1381 if (OldState.PrivilegeCount == 0)
1384 *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
1386 return STATUS_SUCCESS;
1389 /******************************************************************************
1390 * RtlImpersonateSelf [NTDLL.@]
1392 * Makes an impersonation token that represents the process user and assigns
1393 * to the current thread.
1396 * ImpersonationLevel [I] Level at which to impersonate.
1399 * Success: STATUS_SUCCESS.
1400 * Failure: NTSTATUS code.
1403 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1406 OBJECT_ATTRIBUTES ObjectAttributes;
1407 HANDLE ProcessToken;
1408 HANDLE ImpersonationToken;
1410 TRACE("(%08x)\n", ImpersonationLevel);
1412 Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE,
1414 if (Status != STATUS_SUCCESS)
1417 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1419 Status = NtDuplicateToken( ProcessToken,
1424 &ImpersonationToken );
1425 if (Status != STATUS_SUCCESS)
1427 NtClose( ProcessToken );
1431 Status = NtSetInformationThread( GetCurrentThread(),
1432 ThreadImpersonationToken,
1433 &ImpersonationToken,
1434 sizeof(ImpersonationToken) );
1436 NtClose( ImpersonationToken );
1437 NtClose( ProcessToken );
1442 /******************************************************************************
1443 * NtAccessCheck [NTDLL.@]
1444 * ZwAccessCheck [NTDLL.@]
1446 * Checks that a user represented by a token is allowed to access an object
1447 * represented by a security descriptor.
1450 * SecurityDescriptor [I] The security descriptor of the object to check.
1451 * ClientToken [I] Token of the user accessing the object.
1452 * DesiredAccess [I] The desired access to the object.
1453 * GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
1454 * PrivilegeSet [I/O] Privileges used during the access check.
1455 * ReturnLength [O] Number of bytes stored into PrivilegeSet.
1456 * GrantedAccess [O] The actual access rights granted.
1457 * AccessStatus [O] The status of the access check.
1463 * DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
1464 * the maximum access rights allowed by the SD and returns them in
1466 * The SecurityDescriptor must have a valid owner and groups present,
1467 * otherwise the function will fail.
1471 PSECURITY_DESCRIPTOR SecurityDescriptor,
1473 ACCESS_MASK DesiredAccess,
1474 PGENERIC_MAPPING GenericMapping,
1475 PPRIVILEGE_SET PrivilegeSet,
1476 PULONG ReturnLength,
1477 PULONG GrantedAccess,
1478 NTSTATUS *AccessStatus)
1482 TRACE("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1483 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
1484 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
1486 SERVER_START_REQ( access_check )
1488 struct security_descriptor sd;
1493 BOOLEAN defaulted, present;
1495 SECURITY_DESCRIPTOR_CONTROL control;
1497 req->handle = ClientToken;
1498 req->desired_access = DesiredAccess;
1499 req->mapping_read = GenericMapping->GenericRead;
1500 req->mapping_write = GenericMapping->GenericWrite;
1501 req->mapping_execute = GenericMapping->GenericExecute;
1502 req->mapping_all = GenericMapping->GenericAll;
1504 /* marshal security descriptor */
1505 RtlGetControlSecurityDescriptor( SecurityDescriptor, &control, &revision );
1506 sd.control = control & ~SE_SELF_RELATIVE;
1507 RtlGetOwnerSecurityDescriptor( SecurityDescriptor, &owner, &defaulted );
1508 sd.owner_len = RtlLengthSid( owner );
1509 RtlGetGroupSecurityDescriptor( SecurityDescriptor, &group, &defaulted );
1510 sd.group_len = RtlLengthSid( group );
1511 RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
1512 sd.sacl_len = (present ? sacl->AclSize : 0);
1513 RtlGetDaclSecurityDescriptor( SecurityDescriptor, &present, &dacl, &defaulted );
1514 sd.dacl_len = (present ? dacl->AclSize : 0);
1516 wine_server_add_data( req, &sd, sizeof(sd) );
1517 wine_server_add_data( req, owner, sd.owner_len );
1518 wine_server_add_data( req, group, sd.group_len );
1519 wine_server_add_data( req, sacl, sd.sacl_len );
1520 wine_server_add_data( req, dacl, sd.dacl_len );
1522 wine_server_set_reply( req, &PrivilegeSet->Privilege, *ReturnLength - FIELD_OFFSET( PRIVILEGE_SET, Privilege ) );
1524 status = wine_server_call( req );
1526 *ReturnLength = FIELD_OFFSET( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
1527 PrivilegeSet->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
1529 if (status == STATUS_SUCCESS)
1530 *AccessStatus = reply->access_status;
1531 *GrantedAccess = reply->access_granted;
1538 /******************************************************************************
1539 * NtSetSecurityObject [NTDLL.@]
1542 NtSetSecurityObject(
1544 IN SECURITY_INFORMATION SecurityInformation,
1545 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
1547 FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
1548 return STATUS_SUCCESS;
1551 /******************************************************************************
1552 * RtlConvertSidToUnicodeString (NTDLL.@)
1554 * The returned SID is used to access the USER registry hive usually
1556 * the native function returns something like
1557 * "S-1-5-21-0000000000-000000000-0000000000-500";
1559 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
1560 PUNICODE_STRING String,
1562 BOOLEAN AllocateString)
1564 const char *user = wine_get_user_name();
1565 int len = ntdll_umbstowcs( 0, user, strlen(user)+1, NULL, 0 ) * sizeof(WCHAR);
1567 FIXME("(%p %p %u)\n", String, Sid, AllocateString);
1569 String->Length = len - sizeof(WCHAR);
1572 String->MaximumLength = len;
1573 if (!(String->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
1574 return STATUS_NO_MEMORY;
1576 else if (len > String->MaximumLength) return STATUS_BUFFER_OVERFLOW;
1578 ntdll_umbstowcs( 0, user, strlen(user)+1, String->Buffer, len/sizeof(WCHAR) );
1579 return STATUS_SUCCESS;
1582 /******************************************************************************
1583 * RtlQueryInformationAcl (NTDLL.@)
1585 NTSTATUS WINAPI RtlQueryInformationAcl(
1587 LPVOID pAclInformation,
1588 DWORD nAclInformationLength,
1589 ACL_INFORMATION_CLASS dwAclInformationClass)
1591 NTSTATUS status = STATUS_SUCCESS;
1593 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1594 pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
1596 switch (dwAclInformationClass)
1598 case AclRevisionInformation:
1600 PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
1602 if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
1603 status = STATUS_INVALID_PARAMETER;
1605 paclrev->AclRevision = pAcl->AclRevision;
1610 case AclSizeInformation:
1612 PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
1614 if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
1615 status = STATUS_INVALID_PARAMETER;
1621 paclsize->AceCount = pAcl->AceCount;
1623 paclsize->AclBytesInUse = 0;
1624 ace = (PACE_HEADER) (pAcl + 1);
1626 for (i = 0; i < pAcl->AceCount; i++)
1628 paclsize->AclBytesInUse += ace->AceSize;
1629 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1632 if (pAcl->AclSize < paclsize->AclBytesInUse)
1634 WARN("Acl has %ld bytes free\n", paclsize->AclBytesFree);
1635 paclsize->AclBytesFree = 0;
1636 paclsize->AclBytesInUse = pAcl->AclSize;
1639 paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
1646 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
1647 status = STATUS_INVALID_PARAMETER;