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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
36 #define WIN32_NO_STATUS
38 #include "wine/exception.h"
39 #include "ntdll_misc.h"
41 #include "wine/library.h"
42 #include "wine/unicode.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
47 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
49 /* helper function to copy an ACL */
50 static BOOLEAN
copy_acl(DWORD nDestinationAclLength
, PACL pDestinationAcl
, PACL pSourceAcl
)
54 if (!pSourceAcl
|| !RtlValidAcl(pSourceAcl
))
57 size
= ((ACL
*)pSourceAcl
)->AclSize
;
58 if (nDestinationAclLength
< size
)
61 memmove(pDestinationAcl
, pSourceAcl
, size
);
65 /* generically adds an ACE to an ACL */
66 static NTSTATUS
add_access_ace(PACL pAcl
, DWORD dwAceRevision
, DWORD dwAceFlags
,
67 DWORD dwAccessMask
, PSID pSid
, DWORD dwAceType
)
69 ACE_HEADER
*pAceHeader
;
75 if (!RtlValidSid(pSid
))
76 return STATUS_INVALID_SID
;
78 if (pAcl
->AclRevision
> MAX_ACL_REVISION
|| dwAceRevision
> MAX_ACL_REVISION
)
79 return STATUS_REVISION_MISMATCH
;
81 if (!RtlValidAcl(pAcl
))
82 return STATUS_INVALID_ACL
;
84 if (!RtlFirstFreeAce(pAcl
, &pAceHeader
))
85 return STATUS_INVALID_ACL
;
88 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
90 /* calculate generic size of the ACE */
91 dwLengthSid
= RtlLengthSid(pSid
);
92 dwAceSize
= sizeof(ACE_HEADER
) + sizeof(DWORD
) + dwLengthSid
;
93 if ((char *)pAceHeader
+ dwAceSize
> (char *)pAcl
+ pAcl
->AclSize
)
94 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
96 /* fill the new ACE */
97 pAceHeader
->AceType
= dwAceType
;
98 pAceHeader
->AceFlags
= dwAceFlags
;
99 pAceHeader
->AceSize
= dwAceSize
;
101 /* skip past the ACE_HEADER of the ACE */
102 pAccessMask
= (DWORD
*)(pAceHeader
+ 1);
103 *pAccessMask
= dwAccessMask
;
105 /* skip past ACE->Mask */
106 pSidStart
= pAccessMask
+ 1;
107 RtlCopySid(dwLengthSid
, (PSID
)pSidStart
, pSid
);
109 pAcl
->AclRevision
= max(pAcl
->AclRevision
, dwAceRevision
);
112 return STATUS_SUCCESS
;
119 /******************************************************************************
120 * RtlAllocateAndInitializeSid [NTDLL.@]
123 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
124 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
125 BYTE nSubAuthorityCount
,
126 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
127 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
128 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
129 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
134 TRACE("(%p, 0x%04x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,%p)\n",
135 pIdentifierAuthority
,nSubAuthorityCount
,
136 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
137 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
139 if (nSubAuthorityCount
> 8) return STATUS_INVALID_SID
;
141 if (!(tmp_sid
= RtlAllocateHeap( GetProcessHeap(), 0,
142 RtlLengthRequiredSid(nSubAuthorityCount
))))
143 return STATUS_NO_MEMORY
;
145 tmp_sid
->Revision
= SID_REVISION
;
147 if (pIdentifierAuthority
)
148 memcpy(&tmp_sid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof(SID_IDENTIFIER_AUTHORITY
));
149 tmp_sid
->SubAuthorityCount
= nSubAuthorityCount
;
151 switch( nSubAuthorityCount
)
153 case 8: tmp_sid
->SubAuthority
[7]= nSubAuthority7
;
154 case 7: tmp_sid
->SubAuthority
[6]= nSubAuthority6
;
155 case 6: tmp_sid
->SubAuthority
[5]= nSubAuthority5
;
156 case 5: tmp_sid
->SubAuthority
[4]= nSubAuthority4
;
157 case 4: tmp_sid
->SubAuthority
[3]= nSubAuthority3
;
158 case 3: tmp_sid
->SubAuthority
[2]= nSubAuthority2
;
159 case 2: tmp_sid
->SubAuthority
[1]= nSubAuthority1
;
160 case 1: tmp_sid
->SubAuthority
[0]= nSubAuthority0
;
164 return STATUS_SUCCESS
;
167 /******************************************************************************
168 * RtlEqualSid [NTDLL.@]
170 * Determine if two SIDs are equal.
173 * pSid1 [I] Source SID
174 * pSid2 [I] SID to compare with
177 * TRUE, if pSid1 is equal to pSid2,
180 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
182 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
185 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
188 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
194 /******************************************************************************
195 * RtlEqualPrefixSid [NTDLL.@]
197 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
199 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
202 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
205 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
212 /******************************************************************************
213 * RtlFreeSid [NTDLL.@]
215 * Free the resources used by a SID.
218 * pSid [I] SID to Free.
223 DWORD WINAPI
RtlFreeSid(PSID pSid
)
225 TRACE("(%p)\n", pSid
);
226 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
227 return STATUS_SUCCESS
;
230 /**************************************************************************
231 * RtlLengthRequiredSid [NTDLL.@]
233 * Determine the amount of memory a SID will use
236 * nrofsubauths [I] Number of Sub Authorities in the SID.
239 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
241 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
243 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
246 /**************************************************************************
247 * RtlLengthSid [NTDLL.@]
249 * Determine the amount of memory a SID is using
252 * pSid [I] SID to get the size of.
255 * The size, in bytes, of pSid.
257 DWORD WINAPI
RtlLengthSid(PSID pSid
)
259 TRACE("sid=%p\n",pSid
);
261 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
264 /**************************************************************************
265 * RtlInitializeSid [NTDLL.@]
270 * pSid [I] SID to initialise
271 * pIdentifierAuthority [I] Identifier Authority
272 * nSubAuthorityCount [I] Number of Sub Authorities
275 * Success: TRUE. pSid is initialised with the details given.
276 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
278 BOOL WINAPI
RtlInitializeSid(
280 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
281 BYTE nSubAuthorityCount
)
286 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
289 pisid
->Revision
= SID_REVISION
;
290 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
291 if (pIdentifierAuthority
)
292 memcpy(&pisid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
294 for (i
= 0; i
< nSubAuthorityCount
; i
++)
295 *RtlSubAuthoritySid(pSid
, i
) = 0;
300 /**************************************************************************
301 * RtlSubAuthoritySid [NTDLL.@]
303 * Return the Sub Authority of a SID
306 * pSid [I] SID to get the Sub Authority from.
307 * nSubAuthority [I] Sub Authority number.
310 * A pointer to The Sub Authority value of pSid.
312 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
314 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
317 /**************************************************************************
318 * RtlIdentifierAuthoritySid [NTDLL.@]
320 * Return the Identifier Authority of a SID.
323 * pSid [I] SID to get the Identifier Authority from.
326 * A pointer to the Identifier Authority value of pSid.
328 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
330 return &(((SID
*)pSid
)->IdentifierAuthority
);
333 /**************************************************************************
334 * RtlSubAuthorityCountSid [NTDLL.@]
336 * Get the number of Sub Authorities in a SID.
339 * pSid [I] SID to get the count from.
342 * A pointer to the Sub Authority count of pSid.
344 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
346 return &(((SID
*)pSid
)->SubAuthorityCount
);
349 /**************************************************************************
350 * RtlCopySid [NTDLL.@]
352 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
354 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
355 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
358 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
361 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
364 /******************************************************************************
365 * RtlValidSid [NTDLL.@]
367 * Determine if a SID is valid.
370 * pSid [I] SID to check
373 * TRUE if pSid is valid,
376 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
382 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
383 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
390 WARN("(%p): invalid pointer!\n", pSid
);
399 * security descriptor functions
402 /**************************************************************************
403 * RtlCreateSecurityDescriptor [NTDLL.@]
405 * Initialise a SECURITY_DESCRIPTOR.
408 * lpsd [O] Descriptor to initialise.
409 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
412 * Success: STATUS_SUCCESS.
413 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
415 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
416 PSECURITY_DESCRIPTOR lpsd
,
419 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
420 return STATUS_UNKNOWN_REVISION
;
421 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
422 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
423 return STATUS_SUCCESS
;
426 /**************************************************************************
427 * RtlCopySecurityDescriptor [NTDLL.@]
429 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
432 * pSourceSD [O] SD to copy from.
433 * pDestinationSD [I] Destination SD.
436 * Success: STATUS_SUCCESS.
437 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
439 NTSTATUS WINAPI
RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD
, PSECURITY_DESCRIPTOR pDestinationSD
)
441 SECURITY_DESCRIPTOR
*srcSD
= (SECURITY_DESCRIPTOR
*)pSourceSD
;
442 SECURITY_DESCRIPTOR
*destSD
= (SECURITY_DESCRIPTOR
*)pDestinationSD
;
445 BOOLEAN defaulted
, present
;
447 BOOL isSelfRelative
= srcSD
->Control
& SE_SELF_RELATIVE
;
449 if (srcSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
450 return STATUS_UNKNOWN_REVISION
;
452 /* copy initial data */
453 destSD
->Revision
= srcSD
->Revision
;
454 destSD
->Sbz1
= srcSD
->Sbz1
;
455 destSD
->Control
= srcSD
->Control
;
458 RtlGetOwnerSecurityDescriptor(pSourceSD
, &Owner
, &defaulted
);
459 length
= RtlLengthSid(Owner
);
463 destSD
->Owner
= srcSD
->Owner
;
464 RtlCopySid(length
, (LPBYTE
)destSD
+ (DWORD
)destSD
->Owner
, Owner
);
468 destSD
->Owner
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
469 RtlCopySid(length
, destSD
->Owner
, Owner
);
473 RtlGetGroupSecurityDescriptor(pSourceSD
, &Group
, &defaulted
);
474 length
= RtlLengthSid(Group
);
478 destSD
->Group
= srcSD
->Group
;
479 RtlCopySid(length
, (LPBYTE
)destSD
+ (DWORD
)destSD
->Group
, Group
);
483 destSD
->Group
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
484 RtlCopySid(length
, destSD
->Group
, Group
);
488 if (srcSD
->Control
& SE_DACL_PRESENT
)
490 RtlGetDaclSecurityDescriptor(pSourceSD
, &present
, &Dacl
, &defaulted
);
491 length
= Dacl
->AclSize
;
495 destSD
->Dacl
= srcSD
->Dacl
;
496 copy_acl(length
, (PACL
)((LPBYTE
)destSD
+ (DWORD
)destSD
->Dacl
), Dacl
);
500 destSD
->Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
501 copy_acl(length
, destSD
->Dacl
, Dacl
);
506 if (srcSD
->Control
& SE_SACL_PRESENT
)
508 RtlGetSaclSecurityDescriptor(pSourceSD
, &present
, &Sacl
, &defaulted
);
509 length
= Sacl
->AclSize
;
513 destSD
->Sacl
= srcSD
->Sacl
;
514 copy_acl(length
, (PACL
)((LPBYTE
)destSD
+ (DWORD
)destSD
->Sacl
), Sacl
);
518 destSD
->Sacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
519 copy_acl(length
, destSD
->Sacl
, Sacl
);
523 return STATUS_SUCCESS
;
526 /**************************************************************************
527 * RtlValidSecurityDescriptor [NTDLL.@]
529 * Determine if a SECURITY_DESCRIPTOR is valid.
532 * SecurityDescriptor [I] Descriptor to check.
535 * Success: STATUS_SUCCESS.
536 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
538 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
539 PSECURITY_DESCRIPTOR SecurityDescriptor
)
541 if ( ! SecurityDescriptor
)
542 return STATUS_INVALID_SECURITY_DESCR
;
543 if ( ((SECURITY_DESCRIPTOR
*)SecurityDescriptor
)->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
544 return STATUS_UNKNOWN_REVISION
;
546 return STATUS_SUCCESS
;
549 /**************************************************************************
550 * RtlLengthSecurityDescriptor [NTDLL.@]
552 ULONG WINAPI
RtlLengthSecurityDescriptor(
553 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
555 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
557 ULONG Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
562 if ( lpsd
->Control
& SE_SELF_RELATIVE
)
563 offset
= (ULONG
) lpsd
;
565 if ( lpsd
->Owner
!= NULL
)
566 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Owner
+ offset
));
568 if ( lpsd
->Group
!= NULL
)
569 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Group
+ offset
));
571 if ( (lpsd
->Control
& SE_SACL_PRESENT
) &&
573 Size
+= ((PACL
)((LPBYTE
)lpsd
->Sacl
+ offset
))->AclSize
;
575 if ( (lpsd
->Control
& SE_DACL_PRESENT
) &&
577 Size
+= ((PACL
)((LPBYTE
)lpsd
->Dacl
+ offset
))->AclSize
;
582 /******************************************************************************
583 * RtlGetDaclSecurityDescriptor [NTDLL.@]
586 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
587 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
588 OUT PBOOLEAN lpbDaclPresent
,
590 OUT PBOOLEAN lpbDaclDefaulted
)
592 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
594 TRACE("(%p,%p,%p,%p)\n",
595 pSecurityDescriptor
, lpbDaclPresent
, pDacl
, lpbDaclDefaulted
);
597 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
598 return STATUS_UNKNOWN_REVISION
;
600 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
602 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
603 *pDacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Dacl
);
607 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
610 return STATUS_SUCCESS
;
613 /**************************************************************************
614 * RtlSetDaclSecurityDescriptor [NTDLL.@]
616 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
617 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
620 BOOLEAN dacldefaulted
)
622 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
624 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
625 return STATUS_UNKNOWN_REVISION
;
626 if (lpsd
->Control
& SE_SELF_RELATIVE
)
627 return STATUS_INVALID_SECURITY_DESCR
;
630 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
634 lpsd
->Control
|= SE_DACL_PRESENT
;
638 lpsd
->Control
|= SE_DACL_DEFAULTED
;
640 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
642 return STATUS_SUCCESS
;
645 /******************************************************************************
646 * RtlGetSaclSecurityDescriptor [NTDLL.@]
649 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
650 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
651 OUT PBOOLEAN lpbSaclPresent
,
653 OUT PBOOLEAN lpbSaclDefaulted
)
655 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
657 TRACE("(%p,%p,%p,%p)\n",
658 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
660 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
661 return STATUS_UNKNOWN_REVISION
;
663 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
665 if (SE_SELF_RELATIVE
& lpsd
->Control
)
666 *pSacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Sacl
);
670 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
673 return STATUS_SUCCESS
;
676 /**************************************************************************
677 * RtlSetSaclSecurityDescriptor [NTDLL.@]
679 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
680 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
683 BOOLEAN sacldefaulted
)
685 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
687 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
688 return STATUS_UNKNOWN_REVISION
;
689 if (lpsd
->Control
& SE_SELF_RELATIVE
)
690 return STATUS_INVALID_SECURITY_DESCR
;
692 lpsd
->Control
&= ~SE_SACL_PRESENT
;
695 lpsd
->Control
|= SE_SACL_PRESENT
;
698 lpsd
->Control
|= SE_SACL_DEFAULTED
;
700 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
701 return STATUS_SUCCESS
;
704 /**************************************************************************
705 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
707 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
708 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
710 PBOOLEAN OwnerDefaulted
)
712 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
714 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
715 return STATUS_INVALID_PARAMETER
;
717 if (lpsd
->Owner
!= NULL
)
719 if (lpsd
->Control
& SE_SELF_RELATIVE
)
720 *Owner
= (PSID
)((LPBYTE
)lpsd
+
723 *Owner
= lpsd
->Owner
;
725 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
726 *OwnerDefaulted
= TRUE
;
728 *OwnerDefaulted
= FALSE
;
733 return STATUS_SUCCESS
;
736 /**************************************************************************
737 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
739 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
740 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
742 BOOLEAN ownerdefaulted
)
744 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
746 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
747 return STATUS_UNKNOWN_REVISION
;
748 if (lpsd
->Control
& SE_SELF_RELATIVE
)
749 return STATUS_INVALID_SECURITY_DESCR
;
753 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
755 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
756 return STATUS_SUCCESS
;
759 /**************************************************************************
760 * RtlSetGroupSecurityDescriptor [NTDLL.@]
762 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
763 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
765 BOOLEAN groupdefaulted
)
767 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
769 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
770 return STATUS_UNKNOWN_REVISION
;
771 if (lpsd
->Control
& SE_SELF_RELATIVE
)
772 return STATUS_INVALID_SECURITY_DESCR
;
776 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
778 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
779 return STATUS_SUCCESS
;
782 /**************************************************************************
783 * RtlGetGroupSecurityDescriptor [NTDLL.@]
785 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
786 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
788 PBOOLEAN GroupDefaulted
)
790 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
792 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
793 return STATUS_INVALID_PARAMETER
;
795 if (lpsd
->Group
!= NULL
)
797 if (lpsd
->Control
& SE_SELF_RELATIVE
)
798 *Group
= (PSID
)((LPBYTE
)lpsd
+
801 *Group
= lpsd
->Group
;
803 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
804 *GroupDefaulted
= TRUE
;
806 *GroupDefaulted
= FALSE
;
811 return STATUS_SUCCESS
;
814 /**************************************************************************
815 * RtlMakeSelfRelativeSD [NTDLL.@]
817 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
818 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
819 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
820 IN OUT LPDWORD lpdwBufferLength
)
824 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
825 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
827 TRACE(" %p %p %p(%d)\n", pAbs
, pRel
, lpdwBufferLength
,
828 lpdwBufferLength
? *lpdwBufferLength
: -1);
830 if (!lpdwBufferLength
|| !pAbs
)
831 return STATUS_INVALID_PARAMETER
;
833 length
= RtlLengthSecurityDescriptor(pAbs
);
834 if (*lpdwBufferLength
< length
)
836 *lpdwBufferLength
= length
;
837 return STATUS_BUFFER_TOO_SMALL
;
841 return STATUS_INVALID_PARAMETER
;
843 if (pAbs
->Control
& SE_SELF_RELATIVE
)
845 memcpy(pRel
, pAbs
, length
);
846 return STATUS_SUCCESS
;
849 pRel
->Revision
= pAbs
->Revision
;
850 pRel
->Sbz1
= pAbs
->Sbz1
;
851 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
853 offsetRel
= sizeof(SECURITY_DESCRIPTOR
);
854 pRel
->Owner
= (PSID
) offsetRel
;
855 length
= RtlLengthSid(pAbs
->Owner
);
856 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
859 pRel
->Group
= (PSID
) offsetRel
;
860 length
= RtlLengthSid(pAbs
->Group
);
861 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
863 if (pRel
->Control
& SE_SACL_PRESENT
)
866 pRel
->Sacl
= (PACL
) offsetRel
;
867 length
= pAbs
->Sacl
->AclSize
;
868 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
875 if (pRel
->Control
& SE_DACL_PRESENT
)
878 pRel
->Dacl
= (PACL
) offsetRel
;
879 length
= pAbs
->Dacl
->AclSize
;
880 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
887 return STATUS_SUCCESS
;
891 /**************************************************************************
892 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
894 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
895 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
896 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
897 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
899 OUT LPDWORD lpdwDaclSize
,
901 OUT LPDWORD lpdwSaclSize
,
903 OUT LPDWORD lpdwOwnerSize
,
904 OUT PSID pPrimaryGroup
,
905 OUT LPDWORD lpdwPrimaryGroupSize
)
907 NTSTATUS status
= STATUS_SUCCESS
;
908 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
909 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
912 !lpdwAbsoluteSecurityDescriptorSize
||
916 !lpdwPrimaryGroupSize
||
917 ~pRel
->Control
& SE_SELF_RELATIVE
)
918 return STATUS_INVALID_PARAMETER
;
920 /* Confirm buffers are sufficiently large */
921 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
923 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
924 status
= STATUS_BUFFER_TOO_SMALL
;
927 if (pRel
->Control
& SE_DACL_PRESENT
&&
928 *lpdwDaclSize
< ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
)
930 *lpdwDaclSize
= ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
;
931 status
= STATUS_BUFFER_TOO_SMALL
;
934 if (pRel
->Control
& SE_SACL_PRESENT
&&
935 *lpdwSaclSize
< ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
)
937 *lpdwSaclSize
= ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
;
938 status
= STATUS_BUFFER_TOO_SMALL
;
942 *lpdwOwnerSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
)))
944 *lpdwOwnerSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
));
945 status
= STATUS_BUFFER_TOO_SMALL
;
949 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
)))
951 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
));
952 status
= STATUS_BUFFER_TOO_SMALL
;
955 if (status
!= STATUS_SUCCESS
)
958 /* Copy structures */
959 pAbs
->Revision
= pRel
->Revision
;
960 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
962 if (pRel
->Control
& SE_SACL_PRESENT
)
964 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
);
966 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
970 if (pRel
->Control
& SE_DACL_PRESENT
)
972 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
);
973 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
979 PSID psid
= (PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
);
980 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
981 pAbs
->Owner
= pOwner
;
986 PSID psid
= (PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
);
987 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
988 pAbs
->Group
= pPrimaryGroup
;
994 /******************************************************************************
995 * RtlGetControlSecurityDescriptor (NTDLL.@)
997 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
998 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
999 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1000 LPDWORD lpdwRevision
)
1002 SECURITY_DESCRIPTOR
*lpsd
= pSecurityDescriptor
;
1004 TRACE("(%p,%p,%p)\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1006 *lpdwRevision
= lpsd
->Revision
;
1008 if (*lpdwRevision
!= SECURITY_DESCRIPTOR_REVISION
)
1009 return STATUS_UNKNOWN_REVISION
;
1011 *pControl
= lpsd
->Control
;
1013 return STATUS_SUCCESS
;
1017 /**************************************************************************
1018 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1020 NTSTATUS WINAPI
RtlAbsoluteToSelfRelativeSD(
1021 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
1022 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
1023 PULONG BufferLength
)
1025 SECURITY_DESCRIPTOR
*abs
= AbsoluteSecurityDescriptor
;
1027 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor
,
1028 SelfRelativeSecurityDescriptor
, BufferLength
);
1030 if (abs
->Control
& SE_SELF_RELATIVE
)
1031 return STATUS_BAD_DESCRIPTOR_FORMAT
;
1033 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
1034 SelfRelativeSecurityDescriptor
, BufferLength
);
1039 * access control list's
1042 /**************************************************************************
1043 * RtlCreateAcl [NTDLL.@]
1046 * This should return NTSTATUS
1048 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
1050 TRACE("%p 0x%08x 0x%08x\n", acl
, size
, rev
);
1052 if (rev
!=ACL_REVISION
)
1053 return STATUS_INVALID_PARAMETER
;
1054 if (size
<sizeof(ACL
))
1055 return STATUS_BUFFER_TOO_SMALL
;
1057 return STATUS_INVALID_PARAMETER
;
1059 memset(acl
,'\0',sizeof(ACL
));
1060 acl
->AclRevision
= rev
;
1061 acl
->AclSize
= size
;
1063 return STATUS_SUCCESS
;
1066 /**************************************************************************
1067 * RtlFirstFreeAce [NTDLL.@]
1068 * looks for the AceCount+1 ACE, and if it is still within the alloced
1069 * ACL, return a pointer to it
1071 BOOLEAN WINAPI
RtlFirstFreeAce(
1079 ace
= (PACE_HEADER
)(acl
+1);
1080 for (i
=0;i
<acl
->AceCount
;i
++) {
1081 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1083 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1085 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1091 /**************************************************************************
1092 * RtlAddAce [NTDLL.@]
1094 NTSTATUS WINAPI
RtlAddAce(
1098 PACE_HEADER acestart
,
1101 PACE_HEADER ace
,targetace
;
1104 if (acl
->AclRevision
!= ACL_REVISION
)
1105 return STATUS_INVALID_PARAMETER
;
1106 if (!RtlFirstFreeAce(acl
,&targetace
))
1107 return STATUS_INVALID_PARAMETER
;
1108 nrofaces
=0;ace
=acestart
;
1109 while (((BYTE
*)ace
- (BYTE
*)acestart
) < acelen
) {
1111 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1113 if ((BYTE
*)targetace
+ acelen
> (BYTE
*)acl
+ acl
->AclSize
) /* too much aces */
1114 return STATUS_INVALID_PARAMETER
;
1115 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
1116 acl
->AceCount
+=nrofaces
;
1117 return STATUS_SUCCESS
;
1120 /**************************************************************************
1121 * RtlDeleteAce [NTDLL.@]
1123 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1128 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
1130 if (STATUS_SUCCESS
== status
)
1135 /* skip over the ACE we are deleting */
1136 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
1139 /* calculate the length of the rest */
1140 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
1142 len
+= pcAce
->AceSize
;
1143 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
1146 /* slide them all backwards */
1147 memmove(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
1151 TRACE("pAcl=%p dwAceIndex=%d status=0x%08x\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%08x,0x%08x,%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%08x,0x%08x,%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,%d,%d,%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
);
1270 WARN("(%p): invalid pointer!\n", pAcl
);
1277 /******************************************************************************
1278 * RtlGetAce [NTDLL.@]
1280 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1284 TRACE("(%p,%d,%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("(%d, %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 %x)\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 %x)\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, %08x, %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%08x %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 static const WCHAR formatW
[] = {'-','%','u',0};
1565 WCHAR buffer
[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES
];
1567 const SID
*sid
= (const SID
*)pSid
;
1571 p
+= sprintfW( p
, formatW
, sid
->Revision
);
1572 p
+= sprintfW( p
, formatW
, MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
1573 sid
->IdentifierAuthority
.Value
[4] ),
1574 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
1575 sid
->IdentifierAuthority
.Value
[2] )));
1576 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
1577 p
+= sprintfW( p
, formatW
, sid
->SubAuthority
[i
] );
1579 len
= (p
+ 1 - buffer
) * sizeof(WCHAR
);
1581 String
->Length
= len
- sizeof(WCHAR
);
1584 String
->MaximumLength
= len
;
1585 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1586 return STATUS_NO_MEMORY
;
1588 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1590 memcpy( String
->Buffer
, buffer
, len
);
1591 return STATUS_SUCCESS
;
1594 /******************************************************************************
1595 * RtlQueryInformationAcl (NTDLL.@)
1597 NTSTATUS WINAPI
RtlQueryInformationAcl(
1599 LPVOID pAclInformation
,
1600 DWORD nAclInformationLength
,
1601 ACL_INFORMATION_CLASS dwAclInformationClass
)
1603 NTSTATUS status
= STATUS_SUCCESS
;
1605 TRACE("pAcl=%p pAclInfo=%p len=%d, class=%d\n",
1606 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1608 switch (dwAclInformationClass
)
1610 case AclRevisionInformation
:
1612 PACL_REVISION_INFORMATION paclrev
= (PACL_REVISION_INFORMATION
) pAclInformation
;
1614 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1615 status
= STATUS_INVALID_PARAMETER
;
1617 paclrev
->AclRevision
= pAcl
->AclRevision
;
1622 case AclSizeInformation
:
1624 PACL_SIZE_INFORMATION paclsize
= (PACL_SIZE_INFORMATION
) pAclInformation
;
1626 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1627 status
= STATUS_INVALID_PARAMETER
;
1633 paclsize
->AceCount
= pAcl
->AceCount
;
1635 paclsize
->AclBytesInUse
= 0;
1636 ace
= (PACE_HEADER
) (pAcl
+ 1);
1638 for (i
= 0; i
< pAcl
->AceCount
; i
++)
1640 paclsize
->AclBytesInUse
+= ace
->AceSize
;
1641 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1644 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1646 WARN("Acl has %d bytes free\n", paclsize
->AclBytesFree
);
1647 paclsize
->AclBytesFree
= 0;
1648 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1651 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1658 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1659 status
= STATUS_INVALID_PARAMETER
;