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);
74 /******************************************************************************
75 * RtlAllocateAndInitializeSid [NTDLL.@]
78 NTSTATUS WINAPI RtlAllocateAndInitializeSid (
79 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
80 BYTE nSubAuthorityCount,
81 DWORD nSubAuthority0, DWORD nSubAuthority1,
82 DWORD nSubAuthority2, DWORD nSubAuthority3,
83 DWORD nSubAuthority4, DWORD nSubAuthority5,
84 DWORD nSubAuthority6, DWORD nSubAuthority7,
88 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
89 pIdentifierAuthority,nSubAuthorityCount,
90 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
91 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
93 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0,
94 RtlLengthRequiredSid(nSubAuthorityCount))))
95 return STATUS_NO_MEMORY;
97 ((SID*)*pSid)->Revision = SID_REVISION;
99 if (pIdentifierAuthority)
100 memcpy(&((SID*)*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
101 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
103 if (nSubAuthorityCount > 0)
104 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
105 if (nSubAuthorityCount > 1)
106 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
107 if (nSubAuthorityCount > 2)
108 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
109 if (nSubAuthorityCount > 3)
110 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
111 if (nSubAuthorityCount > 4)
112 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
113 if (nSubAuthorityCount > 5)
114 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
115 if (nSubAuthorityCount > 6)
116 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
117 if (nSubAuthorityCount > 7)
118 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
120 return STATUS_SUCCESS;
122 /******************************************************************************
123 * RtlEqualSid [NTDLL.@]
125 * Determine if two SIDs are equal.
128 * pSid1 [I] Source SID
129 * pSid2 [I] SID to compare with
132 * TRUE, if pSid1 is equal to pSid2,
135 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
137 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
140 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
143 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
149 /******************************************************************************
150 * RtlEqualPrefixSid [NTDLL.@]
152 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
154 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
157 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
160 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(((SID*)pSid1)->SubAuthorityCount - 1)) != 0)
167 /******************************************************************************
168 * RtlFreeSid [NTDLL.@]
170 * Free the resources used by a SID.
173 * pSid [I] SID to Free.
178 DWORD WINAPI RtlFreeSid(PSID pSid)
180 TRACE("(%p)\n", pSid);
181 RtlFreeHeap( GetProcessHeap(), 0, pSid );
182 return STATUS_SUCCESS;
185 /**************************************************************************
186 * RtlLengthRequiredSid [NTDLL.@]
188 * Determine the amount of memory a SID will use
191 * nrofsubauths [I] Number of Sub Authorities in the SID.
194 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
196 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
198 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
201 /**************************************************************************
202 * RtlLengthSid [NTDLL.@]
204 * Determine the amount of memory a SID is using
207 * pSid [I] SID to get the size of.
210 * The size, in bytes, of pSid.
212 DWORD WINAPI RtlLengthSid(PSID pSid)
214 TRACE("sid=%p\n",pSid);
216 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
219 /**************************************************************************
220 * RtlInitializeSid [NTDLL.@]
225 * pSid [I] SID to initialise
226 * pIdentifierAuthority [I] Identifier Authority
227 * nSubAuthorityCount [I] Number of Sub Authorities
230 * Success: TRUE. pSid is initialised with the details given.
231 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
233 BOOL WINAPI RtlInitializeSid(
235 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
236 BYTE nSubAuthorityCount)
241 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
244 pisid->Revision = SID_REVISION;
245 pisid->SubAuthorityCount = nSubAuthorityCount;
246 if (pIdentifierAuthority)
247 memcpy(&pisid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
249 for (i = 0; i < nSubAuthorityCount; i++)
250 *RtlSubAuthoritySid(pSid, i) = 0;
255 /**************************************************************************
256 * RtlSubAuthoritySid [NTDLL.@]
258 * Return the Sub Authority of a SID
261 * pSid [I] SID to get the Sub Authority from.
262 * nSubAuthority [I] Sub Authority number.
265 * A pointer to The Sub Authority value of pSid.
267 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
269 return &(((SID*)pSid)->SubAuthority[nSubAuthority]);
272 /**************************************************************************
273 * RtlIdentifierAuthoritySid [NTDLL.@]
275 * Return the Identifier Authority of a SID.
278 * pSid [I] SID to get the Identifier Authority from.
281 * A pointer to the Identifier Authority value of pSid.
283 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
285 return &(((SID*)pSid)->IdentifierAuthority);
288 /**************************************************************************
289 * RtlSubAuthorityCountSid [NTDLL.@]
291 * Get the number of Sub Authorities in a SID.
294 * pSid [I] SID to get the count from.
297 * A pointer to the Sub Authority count of pSid.
299 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
301 return &(((SID*)pSid)->SubAuthorityCount);
304 /**************************************************************************
305 * RtlCopySid [NTDLL.@]
307 BOOLEAN WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
309 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
310 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
313 if (nDestinationSidLength < (((SID*)pSourceSid)->SubAuthorityCount*4+8))
316 memmove(pDestinationSid, pSourceSid, ((SID*)pSourceSid)->SubAuthorityCount*4+8);
319 /******************************************************************************
320 * RtlValidSid [NTDLL.@]
322 * Determine if a SID is valid.
325 * pSid [I] SID to check
328 * TRUE if pSid is valid,
331 BOOLEAN WINAPI RtlValidSid( PSID pSid )
337 if (!pSid || ((SID*)pSid)->Revision != SID_REVISION ||
338 ((SID*)pSid)->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
345 WARN("(%p): invalid pointer!\n", pSid);
354 * security descriptor functions
357 /**************************************************************************
358 * RtlCreateSecurityDescriptor [NTDLL.@]
360 * Initialise a SECURITY_DESCRIPTOR.
363 * lpsd [O] Descriptor to initialise.
364 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
367 * Success: STATUS_SUCCESS.
368 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
370 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
371 PSECURITY_DESCRIPTOR lpsd,
374 if (rev!=SECURITY_DESCRIPTOR_REVISION)
375 return STATUS_UNKNOWN_REVISION;
376 memset(lpsd,'\0',sizeof(SECURITY_DESCRIPTOR));
377 ((SECURITY_DESCRIPTOR*)lpsd)->Revision = SECURITY_DESCRIPTOR_REVISION;
378 return STATUS_SUCCESS;
381 /**************************************************************************
382 * RtlCopySecurityDescriptor [NTDLL.@]
384 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
387 * pSourceSD [O] SD to copy from.
388 * pDestinationSD [I] Destination SD.
391 * Success: STATUS_SUCCESS.
392 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
394 NTSTATUS WINAPI RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD, PSECURITY_DESCRIPTOR pDestinationSD)
396 SECURITY_DESCRIPTOR *srcSD = (SECURITY_DESCRIPTOR *)pSourceSD;
397 SECURITY_DESCRIPTOR *destSD = (SECURITY_DESCRIPTOR *)pDestinationSD;
400 BOOLEAN defaulted, present;
402 BOOL isSelfRelative = srcSD->Control & SE_SELF_RELATIVE;
404 if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION)
405 return STATUS_UNKNOWN_REVISION;
407 /* copy initial data */
408 destSD->Revision = srcSD->Revision;
409 destSD->Sbz1 = srcSD->Sbz1;
410 destSD->Control = srcSD->Control;
413 RtlGetOwnerSecurityDescriptor(pSourceSD, &Owner, &defaulted);
414 length = RtlLengthSid(Owner);
418 destSD->Owner = srcSD->Owner;
419 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Owner, Owner);
423 destSD->Owner = RtlAllocateHeap(GetProcessHeap(), 0, length);
424 RtlCopySid(length, destSD->Owner, Owner);
428 RtlGetGroupSecurityDescriptor(pSourceSD, &Group, &defaulted);
429 length = RtlLengthSid(Group);
433 destSD->Group = srcSD->Group;
434 RtlCopySid(length, (LPBYTE)destSD + (DWORD)destSD->Group, Group);
438 destSD->Group = RtlAllocateHeap(GetProcessHeap(), 0, length);
439 RtlCopySid(length, destSD->Group, Group);
443 if (srcSD->Control & SE_DACL_PRESENT)
445 RtlGetDaclSecurityDescriptor(pSourceSD, &present, &Dacl, &defaulted);
446 length = Dacl->AclSize;
450 destSD->Dacl = srcSD->Dacl;
451 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Dacl), Dacl);
455 destSD->Dacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
456 copy_acl(length, destSD->Dacl, Dacl);
461 if (srcSD->Control & SE_SACL_PRESENT)
463 RtlGetSaclSecurityDescriptor(pSourceSD, &present, &Sacl, &defaulted);
464 length = Sacl->AclSize;
468 destSD->Sacl = srcSD->Sacl;
469 copy_acl(length, (PACL)((LPBYTE)destSD + (DWORD)destSD->Sacl), Sacl);
473 destSD->Sacl = RtlAllocateHeap(GetProcessHeap(), 0, length);
474 copy_acl(length, destSD->Sacl, Sacl);
478 return STATUS_SUCCESS;
481 /**************************************************************************
482 * RtlValidSecurityDescriptor [NTDLL.@]
484 * Determine if a SECURITY_DESCRIPTOR is valid.
487 * SecurityDescriptor [I] Descriptor to check.
490 * Success: STATUS_SUCCESS.
491 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
493 NTSTATUS WINAPI RtlValidSecurityDescriptor(
494 PSECURITY_DESCRIPTOR SecurityDescriptor)
496 if ( ! SecurityDescriptor )
497 return STATUS_INVALID_SECURITY_DESCR;
498 if ( ((SECURITY_DESCRIPTOR*)SecurityDescriptor)->Revision != SECURITY_DESCRIPTOR_REVISION )
499 return STATUS_UNKNOWN_REVISION;
501 return STATUS_SUCCESS;
504 /**************************************************************************
505 * RtlLengthSecurityDescriptor [NTDLL.@]
507 ULONG WINAPI RtlLengthSecurityDescriptor(
508 PSECURITY_DESCRIPTOR pSecurityDescriptor)
510 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
512 ULONG Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
517 if ( lpsd->Control & SE_SELF_RELATIVE)
518 offset = (ULONG) lpsd;
520 if ( lpsd->Owner != NULL )
521 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Owner + offset));
523 if ( lpsd->Group != NULL )
524 Size += RtlLengthSid((PSID)((LPBYTE)lpsd->Group + offset));
526 if ( (lpsd->Control & SE_SACL_PRESENT) &&
528 Size += ((PACL)((LPBYTE)lpsd->Sacl + offset))->AclSize;
530 if ( (lpsd->Control & SE_DACL_PRESENT) &&
532 Size += ((PACL)((LPBYTE)lpsd->Dacl + offset))->AclSize;
537 /******************************************************************************
538 * RtlGetDaclSecurityDescriptor [NTDLL.@]
541 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
542 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
543 OUT PBOOLEAN lpbDaclPresent,
545 OUT PBOOLEAN lpbDaclDefaulted)
547 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
549 TRACE("(%p,%p,%p,%p)\n",
550 pSecurityDescriptor, lpbDaclPresent, pDacl, lpbDaclDefaulted);
552 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
553 return STATUS_UNKNOWN_REVISION ;
555 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & lpsd->Control) ? 1 : 0) )
557 if ( SE_SELF_RELATIVE & lpsd->Control)
558 *pDacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Dacl);
562 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
565 return STATUS_SUCCESS;
568 /**************************************************************************
569 * RtlSetDaclSecurityDescriptor [NTDLL.@]
571 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
572 PSECURITY_DESCRIPTOR pSecurityDescriptor,
575 BOOLEAN dacldefaulted )
577 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
579 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
580 return STATUS_UNKNOWN_REVISION;
581 if (lpsd->Control & SE_SELF_RELATIVE)
582 return STATUS_INVALID_SECURITY_DESCR;
585 { lpsd->Control &= ~SE_DACL_PRESENT;
589 lpsd->Control |= SE_DACL_PRESENT;
593 lpsd->Control |= SE_DACL_DEFAULTED;
595 lpsd->Control &= ~SE_DACL_DEFAULTED;
597 return STATUS_SUCCESS;
600 /******************************************************************************
601 * RtlGetSaclSecurityDescriptor [NTDLL.@]
604 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
605 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
606 OUT PBOOLEAN lpbSaclPresent,
608 OUT PBOOLEAN lpbSaclDefaulted)
610 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
612 TRACE("(%p,%p,%p,%p)\n",
613 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
615 if (lpsd->Revision != SECURITY_DESCRIPTOR_REVISION)
616 return STATUS_UNKNOWN_REVISION;
618 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & lpsd->Control) ? 1 : 0) )
620 if (SE_SELF_RELATIVE & lpsd->Control)
621 *pSacl = (PACL) ((LPBYTE)lpsd + (DWORD)lpsd->Sacl);
625 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & lpsd->Control ) ? 1 : 0);
628 return STATUS_SUCCESS;
631 /**************************************************************************
632 * RtlSetSaclSecurityDescriptor [NTDLL.@]
634 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
635 PSECURITY_DESCRIPTOR pSecurityDescriptor,
638 BOOLEAN sacldefaulted)
640 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
642 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
643 return STATUS_UNKNOWN_REVISION;
644 if (lpsd->Control & SE_SELF_RELATIVE)
645 return STATUS_INVALID_SECURITY_DESCR;
647 lpsd->Control &= ~SE_SACL_PRESENT;
650 lpsd->Control |= SE_SACL_PRESENT;
653 lpsd->Control |= SE_SACL_DEFAULTED;
655 lpsd->Control &= ~SE_SACL_DEFAULTED;
656 return STATUS_SUCCESS;
659 /**************************************************************************
660 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
662 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
663 PSECURITY_DESCRIPTOR pSecurityDescriptor,
665 PBOOLEAN OwnerDefaulted)
667 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
669 if ( !lpsd || !Owner || !OwnerDefaulted )
670 return STATUS_INVALID_PARAMETER;
672 if (lpsd->Owner != NULL)
674 if (lpsd->Control & SE_SELF_RELATIVE)
675 *Owner = (PSID)((LPBYTE)lpsd +
678 *Owner = lpsd->Owner;
680 if ( lpsd->Control & SE_OWNER_DEFAULTED )
681 *OwnerDefaulted = TRUE;
683 *OwnerDefaulted = FALSE;
688 return STATUS_SUCCESS;
691 /**************************************************************************
692 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
694 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
695 PSECURITY_DESCRIPTOR pSecurityDescriptor,
697 BOOLEAN ownerdefaulted)
699 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
701 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
702 return STATUS_UNKNOWN_REVISION;
703 if (lpsd->Control & SE_SELF_RELATIVE)
704 return STATUS_INVALID_SECURITY_DESCR;
708 lpsd->Control |= SE_OWNER_DEFAULTED;
710 lpsd->Control &= ~SE_OWNER_DEFAULTED;
711 return STATUS_SUCCESS;
714 /**************************************************************************
715 * RtlSetGroupSecurityDescriptor [NTDLL.@]
717 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
718 PSECURITY_DESCRIPTOR pSecurityDescriptor,
720 BOOLEAN groupdefaulted)
722 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
724 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
725 return STATUS_UNKNOWN_REVISION;
726 if (lpsd->Control & SE_SELF_RELATIVE)
727 return STATUS_INVALID_SECURITY_DESCR;
731 lpsd->Control |= SE_GROUP_DEFAULTED;
733 lpsd->Control &= ~SE_GROUP_DEFAULTED;
734 return STATUS_SUCCESS;
737 /**************************************************************************
738 * RtlGetGroupSecurityDescriptor [NTDLL.@]
740 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
741 PSECURITY_DESCRIPTOR pSecurityDescriptor,
743 PBOOLEAN GroupDefaulted)
745 SECURITY_DESCRIPTOR* lpsd=pSecurityDescriptor;
747 if ( !lpsd || !Group || !GroupDefaulted )
748 return STATUS_INVALID_PARAMETER;
750 if (lpsd->Group != NULL)
752 if (lpsd->Control & SE_SELF_RELATIVE)
753 *Group = (PSID)((LPBYTE)lpsd +
756 *Group = lpsd->Group;
758 if ( lpsd->Control & SE_GROUP_DEFAULTED )
759 *GroupDefaulted = TRUE;
761 *GroupDefaulted = FALSE;
766 return STATUS_SUCCESS;
769 /**************************************************************************
770 * RtlMakeSelfRelativeSD [NTDLL.@]
772 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
773 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
774 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
775 IN OUT LPDWORD lpdwBufferLength)
779 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
780 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
782 TRACE(" %p %p %p(%ld)\n", pAbs, pRel, lpdwBufferLength,
783 lpdwBufferLength ? *lpdwBufferLength: -1);
785 if (!lpdwBufferLength || !pAbs)
786 return STATUS_INVALID_PARAMETER;
788 length = RtlLengthSecurityDescriptor(pAbs);
789 if (*lpdwBufferLength < length)
791 *lpdwBufferLength = length;
792 return STATUS_BUFFER_TOO_SMALL;
796 return STATUS_INVALID_PARAMETER;
798 if (pAbs->Control & SE_SELF_RELATIVE)
800 memcpy(pRel, pAbs, length);
801 return STATUS_SUCCESS;
804 pRel->Revision = pAbs->Revision;
805 pRel->Sbz1 = pAbs->Sbz1;
806 pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
808 offsetRel = sizeof(SECURITY_DESCRIPTOR);
809 pRel->Owner = (PSID) offsetRel;
810 length = RtlLengthSid(pAbs->Owner);
811 memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
814 pRel->Group = (PSID) offsetRel;
815 length = RtlLengthSid(pAbs->Group);
816 memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
818 if (pRel->Control & SE_SACL_PRESENT)
821 pRel->Sacl = (PACL) offsetRel;
822 length = pAbs->Sacl->AclSize;
823 memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
830 if (pRel->Control & SE_DACL_PRESENT)
833 pRel->Dacl = (PACL) offsetRel;
834 length = pAbs->Dacl->AclSize;
835 memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
842 return STATUS_SUCCESS;
846 /**************************************************************************
847 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
849 NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
850 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
851 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
852 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
854 OUT LPDWORD lpdwDaclSize,
856 OUT LPDWORD lpdwSaclSize,
858 OUT LPDWORD lpdwOwnerSize,
859 OUT PSID pPrimaryGroup,
860 OUT LPDWORD lpdwPrimaryGroupSize)
862 NTSTATUS status = STATUS_SUCCESS;
863 SECURITY_DESCRIPTOR* pAbs = pAbsoluteSecurityDescriptor;
864 SECURITY_DESCRIPTOR* pRel = pSelfRelativeSecurityDescriptor;
867 !lpdwAbsoluteSecurityDescriptorSize ||
871 !lpdwPrimaryGroupSize ||
872 ~pRel->Control & SE_SELF_RELATIVE)
873 return STATUS_INVALID_PARAMETER;
875 /* Confirm buffers are sufficiently large */
876 if (*lpdwAbsoluteSecurityDescriptorSize < sizeof(SECURITY_DESCRIPTOR))
878 *lpdwAbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
879 status = STATUS_BUFFER_TOO_SMALL;
882 if (pRel->Control & SE_DACL_PRESENT &&
883 *lpdwDaclSize < ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize)
885 *lpdwDaclSize = ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize;
886 status = STATUS_BUFFER_TOO_SMALL;
889 if (pRel->Control & SE_SACL_PRESENT &&
890 *lpdwSaclSize < ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize)
892 *lpdwSaclSize = ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize;
893 status = STATUS_BUFFER_TOO_SMALL;
897 *lpdwOwnerSize < RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel)))
899 *lpdwOwnerSize = RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel));
900 status = STATUS_BUFFER_TOO_SMALL;
904 *lpdwPrimaryGroupSize < RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel)))
906 *lpdwPrimaryGroupSize = RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel));
907 status = STATUS_BUFFER_TOO_SMALL;
910 if (status != STATUS_SUCCESS)
913 /* Copy structures */
914 pAbs->Revision = pRel->Revision;
915 pAbs->Control = pRel->Control & ~SE_SELF_RELATIVE;
917 if (pRel->Control & SE_SACL_PRESENT)
919 PACL pAcl = (PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel);
921 memcpy(pSacl, pAcl, pAcl->AclSize);
925 if (pRel->Control & SE_DACL_PRESENT)
927 PACL pAcl = (PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel);
928 memcpy(pDacl, pAcl, pAcl->AclSize);
934 PSID psid = (PSID)((LPBYTE)pRel->Owner + (ULONG)pRel);
935 memcpy(pOwner, psid, RtlLengthSid(psid));
936 pAbs->Owner = pOwner;
941 PSID psid = (PSID)((LPBYTE)pRel->Group + (ULONG)pRel);
942 memcpy(pPrimaryGroup, psid, RtlLengthSid(psid));
943 pAbs->Group = pPrimaryGroup;
949 /******************************************************************************
950 * RtlGetControlSecurityDescriptor (NTDLL.@)
952 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
953 PSECURITY_DESCRIPTOR pSecurityDescriptor,
954 PSECURITY_DESCRIPTOR_CONTROL pControl,
955 LPDWORD lpdwRevision)
957 SECURITY_DESCRIPTOR *lpsd = pSecurityDescriptor;
959 TRACE("(%p,%p,%p)\n",pSecurityDescriptor,pControl,lpdwRevision);
961 *lpdwRevision = lpsd->Revision;
963 if (*lpdwRevision != SECURITY_DESCRIPTOR_REVISION)
964 return STATUS_UNKNOWN_REVISION;
966 *pControl = lpsd->Control;
968 return STATUS_SUCCESS;
972 /**************************************************************************
973 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
975 NTSTATUS WINAPI RtlAbsoluteToSelfRelativeSD(
976 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
977 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
980 SECURITY_DESCRIPTOR *abs = AbsoluteSecurityDescriptor;
982 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor,
983 SelfRelativeSecurityDescriptor, BufferLength);
985 if (abs->Control & SE_SELF_RELATIVE)
986 return STATUS_BAD_DESCRIPTOR_FORMAT;
988 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor,
989 SelfRelativeSecurityDescriptor, BufferLength);
994 * access control list's
997 /**************************************************************************
998 * RtlCreateAcl [NTDLL.@]
1001 * This should return NTSTATUS
1003 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
1005 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
1007 if (rev!=ACL_REVISION)
1008 return STATUS_INVALID_PARAMETER;
1009 if (size<sizeof(ACL))
1010 return STATUS_BUFFER_TOO_SMALL;
1012 return STATUS_INVALID_PARAMETER;
1014 memset(acl,'\0',sizeof(ACL));
1015 acl->AclRevision = rev;
1016 acl->AclSize = size;
1018 return STATUS_SUCCESS;
1021 /**************************************************************************
1022 * RtlFirstFreeAce [NTDLL.@]
1023 * looks for the AceCount+1 ACE, and if it is still within the alloced
1024 * ACL, return a pointer to it
1026 BOOLEAN WINAPI RtlFirstFreeAce(
1034 ace = (PACE_HEADER)(acl+1);
1035 for (i=0;i<acl->AceCount;i++) {
1036 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1038 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1040 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
1046 /**************************************************************************
1047 * RtlAddAce [NTDLL.@]
1049 NTSTATUS WINAPI RtlAddAce(
1053 PACE_HEADER acestart,
1056 PACE_HEADER ace,targetace;
1059 if (acl->AclRevision != ACL_REVISION)
1060 return STATUS_INVALID_PARAMETER;
1061 if (!RtlFirstFreeAce(acl,&targetace))
1062 return STATUS_INVALID_PARAMETER;
1063 nrofaces=0;ace=acestart;
1064 while (((DWORD)ace-(DWORD)acestart)<acelen) {
1066 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1068 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
1069 return STATUS_INVALID_PARAMETER;
1070 memcpy((LPBYTE)targetace,acestart,acelen);
1071 acl->AceCount+=nrofaces;
1072 return STATUS_SUCCESS;
1075 /**************************************************************************
1076 * RtlDeleteAce [NTDLL.@]
1078 NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
1083 status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
1085 if (STATUS_SUCCESS == status)
1090 pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
1091 for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
1093 len += pcAce->AceSize;
1094 pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
1097 memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
1101 TRACE("pAcl=%p dwAceIndex=%ld status=0x%08lx\n", pAcl, dwAceIndex, status);
1106 /******************************************************************************
1107 * RtlAddAccessAllowedAce [NTDLL.@]
1109 NTSTATUS WINAPI RtlAddAccessAllowedAce(
1111 IN DWORD dwAceRevision,
1112 IN DWORD AccessMask,
1115 return RtlAddAccessAllowedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1118 /******************************************************************************
1119 * RtlAddAccessAllowedAceEx [NTDLL.@]
1121 NTSTATUS WINAPI RtlAddAccessAllowedAceEx(
1123 IN DWORD dwAceRevision,
1125 IN DWORD AccessMask,
1129 ACCESS_ALLOWED_ACE * pAaAce;
1132 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1133 pAcl, dwAceRevision, AccessMask, pSid);
1135 if (!RtlValidSid(pSid))
1136 return STATUS_INVALID_SID;
1137 if (!RtlValidAcl(pAcl))
1138 return STATUS_INVALID_ACL;
1140 dwLengthSid = RtlLengthSid(pSid);
1141 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAaAce))
1142 return STATUS_INVALID_ACL;
1145 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1147 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAaAce;
1148 if (dwSpaceLeft < sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid)
1149 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1151 pAaAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
1152 pAaAce->Header.AceFlags = AceFlags;
1153 pAaAce->Header.AceSize = sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid;
1154 pAaAce->Mask = AccessMask;
1156 RtlCopySid(dwLengthSid, (PSID)&pAaAce->SidStart, pSid);
1157 return STATUS_SUCCESS;
1160 /******************************************************************************
1161 * RtlAddAccessDeniedAce [NTDLL.@]
1163 NTSTATUS WINAPI RtlAddAccessDeniedAce(
1165 IN DWORD dwAceRevision,
1166 IN DWORD AccessMask,
1169 return RtlAddAccessDeniedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
1172 /******************************************************************************
1173 * RtlAddAccessDeniedAceEx [NTDLL.@]
1175 NTSTATUS WINAPI RtlAddAccessDeniedAceEx(
1177 IN DWORD dwAceRevision,
1179 IN DWORD AccessMask,
1184 ACCESS_DENIED_ACE * pAdAce;
1186 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1187 pAcl, dwAceRevision, AccessMask, pSid);
1189 if (!RtlValidSid(pSid))
1190 return STATUS_INVALID_SID;
1191 if (!RtlValidAcl(pAcl))
1192 return STATUS_INVALID_ACL;
1194 dwLengthSid = RtlLengthSid(pSid);
1195 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAdAce))
1196 return STATUS_INVALID_ACL;
1199 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1201 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAdAce;
1202 if (dwSpaceLeft < sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid)
1203 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1205 pAdAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
1206 pAdAce->Header.AceFlags = AceFlags;
1207 pAdAce->Header.AceSize = sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid;
1208 pAdAce->Mask = AccessMask;
1210 RtlCopySid(dwLengthSid, (PSID)&pAdAce->SidStart, pSid);
1211 return STATUS_SUCCESS;
1214 /******************************************************************************
1215 * RtlValidAcl [NTDLL.@]
1217 BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
1220 TRACE("(%p)\n", pAcl);
1227 if (pAcl->AclRevision != ACL_REVISION)
1231 ace = (PACE_HEADER)(pAcl+1);
1233 for (i=0;i<=pAcl->AceCount;i++)
1235 if ((char *)ace > (char *)pAcl + pAcl->AclSize)
1240 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1244 __EXCEPT(page_fault)
1246 WARN("(%p): invalid pointer!\n", pAcl);
1253 /******************************************************************************
1254 * RtlGetAce [NTDLL.@]
1256 NTSTATUS WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1260 TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
1262 if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
1263 return STATUS_INVALID_PARAMETER;
1265 ace = (PACE_HEADER)(pAcl + 1);
1266 for (;dwAceIndex;dwAceIndex--)
1267 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1269 *pAce = (LPVOID) ace;
1271 return STATUS_SUCCESS;
1278 /******************************************************************************
1279 * RtlAdjustPrivilege [NTDLL.@]
1281 * Enables or disables a privilege from the calling thread or process.
1284 * Privilege [I] Privilege index to change.
1285 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1286 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1287 * Enabled [O] Whether privilege was previously enabled or disabled.
1290 * Success: STATUS_SUCCESS.
1291 * Failure: NTSTATUS code.
1294 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1298 RtlAdjustPrivilege(ULONG Privilege,
1300 BOOLEAN CurrentThread,
1303 TOKEN_PRIVILEGES NewState;
1304 TOKEN_PRIVILEGES OldState;
1309 TRACE("(%ld, %s, %s, %p)\n", Privilege, Enable ? "TRUE" : "FALSE",
1310 CurrentThread ? "TRUE" : "FALSE", Enabled);
1314 Status = NtOpenThreadToken(GetCurrentThread(),
1315 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1321 Status = NtOpenProcessToken(GetCurrentProcess(),
1322 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1326 if (!NT_SUCCESS(Status))
1328 WARN("Retrieving token handle failed (Status %lx)\n", Status);
1332 OldState.PrivilegeCount = 1;
1334 NewState.PrivilegeCount = 1;
1335 NewState.Privileges[0].Luid.LowPart = Privilege;
1336 NewState.Privileges[0].Luid.HighPart = 0;
1337 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
1339 Status = NtAdjustPrivilegesToken(TokenHandle,
1342 sizeof(TOKEN_PRIVILEGES),
1345 NtClose (TokenHandle);
1346 if (Status == STATUS_NOT_ALL_ASSIGNED)
1348 TRACE("Failed to assign all privileges\n");
1349 return STATUS_PRIVILEGE_NOT_HELD;
1351 if (!NT_SUCCESS(Status))
1353 WARN("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
1357 if (OldState.PrivilegeCount == 0)
1360 *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
1362 return STATUS_SUCCESS;
1365 /******************************************************************************
1366 * RtlImpersonateSelf [NTDLL.@]
1368 * Makes an impersonation token that represents the process user and assigns
1369 * to the current thread.
1372 * ImpersonationLevel [I] Level at which to impersonate.
1375 * Success: STATUS_SUCCESS.
1376 * Failure: NTSTATUS code.
1379 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1382 OBJECT_ATTRIBUTES ObjectAttributes;
1383 HANDLE ProcessToken;
1384 HANDLE ImpersonationToken;
1386 TRACE("(%08x)\n", ImpersonationLevel);
1388 Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE,
1390 if (Status != STATUS_SUCCESS)
1393 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1395 Status = NtDuplicateToken( ProcessToken,
1400 &ImpersonationToken );
1401 if (Status != STATUS_SUCCESS)
1403 NtClose( ProcessToken );
1407 Status = NtSetInformationThread( GetCurrentThread(),
1408 ThreadImpersonationToken,
1409 &ImpersonationToken,
1410 sizeof(ImpersonationToken) );
1412 NtClose( ImpersonationToken );
1413 NtClose( ProcessToken );
1418 /******************************************************************************
1419 * NtAccessCheck [NTDLL.@]
1420 * ZwAccessCheck [NTDLL.@]
1422 * Checks that a user represented by a token is allowed to access an object
1423 * represented by a security descriptor.
1426 * SecurityDescriptor [I] The security descriptor of the object to check.
1427 * ClientToken [I] Token of the user accessing the object.
1428 * DesiredAccess [I] The desired access to the object.
1429 * GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
1430 * PrivilegeSet [I/O] Privileges used during the access check.
1431 * ReturnLength [O] Number of bytes stored into PrivilegeSet.
1432 * GrantedAccess [O] The actual access rights granted.
1433 * AccessStatus [O] The status of the access check.
1439 * DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
1440 * the maximum access rights allowed by the SD and returns them in
1442 * The SecurityDescriptor must have a valid owner and groups present,
1443 * otherwise the function will fail.
1447 PSECURITY_DESCRIPTOR SecurityDescriptor,
1449 ACCESS_MASK DesiredAccess,
1450 PGENERIC_MAPPING GenericMapping,
1451 PPRIVILEGE_SET PrivilegeSet,
1452 PULONG ReturnLength,
1453 PULONG GrantedAccess,
1454 NTSTATUS *AccessStatus)
1458 TRACE("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1459 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
1460 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
1462 SERVER_START_REQ( access_check )
1464 struct security_descriptor sd;
1469 BOOLEAN defaulted, present;
1471 SECURITY_DESCRIPTOR_CONTROL control;
1473 req->handle = ClientToken;
1474 req->desired_access = DesiredAccess;
1475 req->mapping_read = GenericMapping->GenericRead;
1476 req->mapping_write = GenericMapping->GenericWrite;
1477 req->mapping_execute = GenericMapping->GenericExecute;
1478 req->mapping_all = GenericMapping->GenericAll;
1480 /* marshal security descriptor */
1481 RtlGetControlSecurityDescriptor( SecurityDescriptor, &control, &revision );
1482 sd.control = control & ~SE_SELF_RELATIVE;
1483 RtlGetOwnerSecurityDescriptor( SecurityDescriptor, &owner, &defaulted );
1484 sd.owner_len = RtlLengthSid( owner );
1485 RtlGetGroupSecurityDescriptor( SecurityDescriptor, &group, &defaulted );
1486 sd.group_len = RtlLengthSid( group );
1487 RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
1488 sd.sacl_len = (present ? sacl->AclSize : 0);
1489 RtlGetDaclSecurityDescriptor( SecurityDescriptor, &present, &dacl, &defaulted );
1490 sd.dacl_len = (present ? dacl->AclSize : 0);
1492 wine_server_add_data( req, &sd, sizeof(sd) );
1493 wine_server_add_data( req, owner, sd.owner_len );
1494 wine_server_add_data( req, group, sd.group_len );
1495 wine_server_add_data( req, sacl, sd.sacl_len );
1496 wine_server_add_data( req, dacl, sd.dacl_len );
1498 wine_server_set_reply( req, &PrivilegeSet->Privilege, *ReturnLength - FIELD_OFFSET( PRIVILEGE_SET, Privilege ) );
1500 status = wine_server_call( req );
1502 *ReturnLength = FIELD_OFFSET( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
1503 PrivilegeSet->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
1505 if (status == STATUS_SUCCESS)
1506 *AccessStatus = reply->access_status;
1507 *GrantedAccess = reply->access_granted;
1514 /******************************************************************************
1515 * NtSetSecurityObject [NTDLL.@]
1518 NtSetSecurityObject(
1520 IN SECURITY_INFORMATION SecurityInformation,
1521 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
1523 FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
1524 return STATUS_SUCCESS;
1527 /******************************************************************************
1528 * RtlConvertSidToUnicodeString (NTDLL.@)
1530 * The returned SID is used to access the USER registry hive usually
1532 * the native function returns something like
1533 * "S-1-5-21-0000000000-000000000-0000000000-500";
1535 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
1536 PUNICODE_STRING String,
1538 BOOLEAN AllocateString)
1540 const char *user = wine_get_user_name();
1541 int len = ntdll_umbstowcs( 0, user, strlen(user)+1, NULL, 0 ) * sizeof(WCHAR);
1543 FIXME("(%p %p %u)\n", String, Sid, AllocateString);
1545 String->Length = len - sizeof(WCHAR);
1548 String->MaximumLength = len;
1549 if (!(String->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len )))
1550 return STATUS_NO_MEMORY;
1552 else if (len > String->MaximumLength) return STATUS_BUFFER_OVERFLOW;
1554 ntdll_umbstowcs( 0, user, strlen(user)+1, String->Buffer, len/sizeof(WCHAR) );
1555 return STATUS_SUCCESS;
1558 /******************************************************************************
1559 * RtlQueryInformationAcl (NTDLL.@)
1561 NTSTATUS WINAPI RtlQueryInformationAcl(
1563 LPVOID pAclInformation,
1564 DWORD nAclInformationLength,
1565 ACL_INFORMATION_CLASS dwAclInformationClass)
1567 NTSTATUS status = STATUS_SUCCESS;
1569 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1570 pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
1572 switch (dwAclInformationClass)
1574 case AclRevisionInformation:
1576 PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
1578 if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
1579 status = STATUS_INVALID_PARAMETER;
1581 paclrev->AclRevision = pAcl->AclRevision;
1586 case AclSizeInformation:
1588 PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
1590 if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
1591 status = STATUS_INVALID_PARAMETER;
1597 paclsize->AceCount = pAcl->AceCount;
1599 paclsize->AclBytesInUse = 0;
1600 ace = (PACE_HEADER) (pAcl + 1);
1602 for (i = 0; i < pAcl->AceCount; i++)
1604 paclsize->AclBytesInUse += ace->AceSize;
1605 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1608 if (pAcl->AclSize < paclsize->AclBytesInUse)
1610 WARN("Acl has %ld bytes free\n", paclsize->AclBytesFree);
1611 paclsize->AclBytesFree = 0;
1612 paclsize->AclBytesInUse = pAcl->AclSize;
1615 paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
1622 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
1623 status = STATUS_INVALID_PARAMETER;