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 "ntdll_misc.h"
39 #include "wine/exception.h"
40 #include "wine/library.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
46 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
48 /* helper function to retrieve active length of an ACL */
49 static size_t acl_bytesInUse(PACL pAcl
)
52 size_t bytesInUse
= sizeof(ACL
);
53 PACE_HEADER ace
= (PACE_HEADER
) (pAcl
+ 1);
54 for (i
= 0; i
< pAcl
->AceCount
; i
++)
56 bytesInUse
+= ace
->AceSize
;
57 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
62 /* helper function to copy an ACL */
63 static BOOLEAN
copy_acl(DWORD nDestinationAclLength
, PACL pDestinationAcl
, PACL pSourceAcl
)
67 if (!pSourceAcl
|| !RtlValidAcl(pSourceAcl
))
70 size
= pSourceAcl
->AclSize
;
71 if (nDestinationAclLength
< size
)
74 memmove(pDestinationAcl
, pSourceAcl
, size
);
78 /* generically adds an ACE to an ACL */
79 static NTSTATUS
add_access_ace(PACL pAcl
, DWORD dwAceRevision
, DWORD dwAceFlags
,
80 DWORD dwAccessMask
, PSID pSid
, DWORD dwAceType
)
82 ACE_HEADER
*pAceHeader
;
88 if (!RtlValidSid(pSid
))
89 return STATUS_INVALID_SID
;
91 if (pAcl
->AclRevision
> MAX_ACL_REVISION
|| dwAceRevision
> MAX_ACL_REVISION
)
92 return STATUS_REVISION_MISMATCH
;
94 if (!RtlValidAcl(pAcl
))
95 return STATUS_INVALID_ACL
;
97 if (!RtlFirstFreeAce(pAcl
, &pAceHeader
))
98 return STATUS_INVALID_ACL
;
101 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
103 /* calculate generic size of the ACE */
104 dwLengthSid
= RtlLengthSid(pSid
);
105 dwAceSize
= sizeof(ACE_HEADER
) + sizeof(DWORD
) + dwLengthSid
;
106 if ((char *)pAceHeader
+ dwAceSize
> (char *)pAcl
+ pAcl
->AclSize
)
107 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
109 /* fill the new ACE */
110 pAceHeader
->AceType
= dwAceType
;
111 pAceHeader
->AceFlags
= dwAceFlags
;
112 pAceHeader
->AceSize
= dwAceSize
;
114 /* skip past the ACE_HEADER of the ACE */
115 pAccessMask
= (DWORD
*)(pAceHeader
+ 1);
116 *pAccessMask
= dwAccessMask
;
118 /* skip past ACE->Mask */
119 pSidStart
= pAccessMask
+ 1;
120 RtlCopySid(dwLengthSid
, pSidStart
, pSid
);
122 pAcl
->AclRevision
= max(pAcl
->AclRevision
, dwAceRevision
);
125 return STATUS_SUCCESS
;
132 /******************************************************************************
133 * RtlAllocateAndInitializeSid [NTDLL.@]
136 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
137 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
138 BYTE nSubAuthorityCount
,
139 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
140 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
141 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
142 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
147 TRACE("(%p, 0x%04x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,%p)\n",
148 pIdentifierAuthority
,nSubAuthorityCount
,
149 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
150 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
152 if (nSubAuthorityCount
> 8) return STATUS_INVALID_SID
;
154 if (!(tmp_sid
= RtlAllocateHeap( GetProcessHeap(), 0,
155 RtlLengthRequiredSid(nSubAuthorityCount
))))
156 return STATUS_NO_MEMORY
;
158 tmp_sid
->Revision
= SID_REVISION
;
160 if (pIdentifierAuthority
)
161 tmp_sid
->IdentifierAuthority
= *pIdentifierAuthority
;
162 tmp_sid
->SubAuthorityCount
= nSubAuthorityCount
;
164 switch( nSubAuthorityCount
)
166 case 8: tmp_sid
->SubAuthority
[7]= nSubAuthority7
;
167 case 7: tmp_sid
->SubAuthority
[6]= nSubAuthority6
;
168 case 6: tmp_sid
->SubAuthority
[5]= nSubAuthority5
;
169 case 5: tmp_sid
->SubAuthority
[4]= nSubAuthority4
;
170 case 4: tmp_sid
->SubAuthority
[3]= nSubAuthority3
;
171 case 3: tmp_sid
->SubAuthority
[2]= nSubAuthority2
;
172 case 2: tmp_sid
->SubAuthority
[1]= nSubAuthority1
;
173 case 1: tmp_sid
->SubAuthority
[0]= nSubAuthority0
;
177 return STATUS_SUCCESS
;
180 /******************************************************************************
181 * RtlEqualSid [NTDLL.@]
183 * Determine if two SIDs are equal.
186 * pSid1 [I] Source SID
187 * pSid2 [I] SID to compare with
190 * TRUE, if pSid1 is equal to pSid2,
193 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
195 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
198 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
201 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
207 /******************************************************************************
208 * RtlEqualPrefixSid [NTDLL.@]
210 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
212 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
215 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
218 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
225 /******************************************************************************
226 * RtlFreeSid [NTDLL.@]
228 * Free the resources used by a SID.
231 * pSid [I] SID to Free.
236 DWORD WINAPI
RtlFreeSid(PSID pSid
)
238 TRACE("(%p)\n", pSid
);
239 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
240 return STATUS_SUCCESS
;
243 /**************************************************************************
244 * RtlLengthRequiredSid [NTDLL.@]
246 * Determine the amount of memory a SID will use
249 * nrofsubauths [I] Number of Sub Authorities in the SID.
252 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
254 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
256 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
259 /**************************************************************************
260 * RtlLengthSid [NTDLL.@]
262 * Determine the amount of memory a SID is using
265 * pSid [I] SID to get the size of.
268 * The size, in bytes, of pSid.
270 DWORD WINAPI
RtlLengthSid(PSID pSid
)
272 TRACE("sid=%p\n",pSid
);
274 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
277 /**************************************************************************
278 * RtlInitializeSid [NTDLL.@]
283 * pSid [I] SID to initialise
284 * pIdentifierAuthority [I] Identifier Authority
285 * nSubAuthorityCount [I] Number of Sub Authorities
288 * Success: TRUE. pSid is initialised with the details given.
289 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
291 BOOL WINAPI
RtlInitializeSid(
293 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
294 BYTE nSubAuthorityCount
)
299 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
302 pisid
->Revision
= SID_REVISION
;
303 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
304 if (pIdentifierAuthority
)
305 pisid
->IdentifierAuthority
= *pIdentifierAuthority
;
307 for (i
= 0; i
< nSubAuthorityCount
; i
++)
308 *RtlSubAuthoritySid(pSid
, i
) = 0;
313 /**************************************************************************
314 * RtlSubAuthoritySid [NTDLL.@]
316 * Return the Sub Authority of a SID
319 * pSid [I] SID to get the Sub Authority from.
320 * nSubAuthority [I] Sub Authority number.
323 * A pointer to The Sub Authority value of pSid.
325 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
327 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
330 /**************************************************************************
331 * RtlIdentifierAuthoritySid [NTDLL.@]
333 * Return the Identifier Authority of a SID.
336 * pSid [I] SID to get the Identifier Authority from.
339 * A pointer to the Identifier Authority value of pSid.
341 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
343 return &(((SID
*)pSid
)->IdentifierAuthority
);
346 /**************************************************************************
347 * RtlSubAuthorityCountSid [NTDLL.@]
349 * Get the number of Sub Authorities in a SID.
352 * pSid [I] SID to get the count from.
355 * A pointer to the Sub Authority count of pSid.
357 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
359 return &(((SID
*)pSid
)->SubAuthorityCount
);
362 /**************************************************************************
363 * RtlCopySid [NTDLL.@]
365 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
367 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
368 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
371 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
374 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
377 /******************************************************************************
378 * RtlValidSid [NTDLL.@]
380 * Determine if a SID is valid.
383 * pSid [I] SID to check
386 * TRUE if pSid is valid,
389 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
395 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
396 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
403 WARN("(%p): invalid pointer!\n", pSid
);
412 * security descriptor functions
415 /**************************************************************************
416 * RtlCreateSecurityDescriptor [NTDLL.@]
418 * Initialise a SECURITY_DESCRIPTOR.
421 * lpsd [O] Descriptor to initialise.
422 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
425 * Success: STATUS_SUCCESS.
426 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
428 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
429 PSECURITY_DESCRIPTOR lpsd
,
432 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
433 return STATUS_UNKNOWN_REVISION
;
434 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
435 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
436 return STATUS_SUCCESS
;
439 /**************************************************************************
440 * RtlCopySecurityDescriptor [NTDLL.@]
442 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
445 * pSourceSD [O] SD to copy from.
446 * pDestinationSD [I] Destination SD.
449 * Success: STATUS_SUCCESS.
450 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
452 NTSTATUS WINAPI
RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD
, PSECURITY_DESCRIPTOR pDestinationSD
)
454 SECURITY_DESCRIPTOR
*srcSD
= pSourceSD
;
455 SECURITY_DESCRIPTOR
*destSD
= pDestinationSD
;
458 BOOLEAN defaulted
, present
;
460 BOOL isSelfRelative
= srcSD
->Control
& SE_SELF_RELATIVE
;
462 if (srcSD
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
463 return STATUS_UNKNOWN_REVISION
;
465 /* copy initial data */
466 destSD
->Revision
= srcSD
->Revision
;
467 destSD
->Sbz1
= srcSD
->Sbz1
;
468 destSD
->Control
= srcSD
->Control
;
471 RtlGetOwnerSecurityDescriptor(pSourceSD
, &Owner
, &defaulted
);
472 length
= RtlLengthSid(Owner
);
476 destSD
->Owner
= srcSD
->Owner
;
477 RtlCopySid(length
, (LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Owner
, Owner
);
481 destSD
->Owner
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
482 RtlCopySid(length
, destSD
->Owner
, Owner
);
486 RtlGetGroupSecurityDescriptor(pSourceSD
, &Group
, &defaulted
);
487 length
= RtlLengthSid(Group
);
491 destSD
->Group
= srcSD
->Group
;
492 RtlCopySid(length
, (LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Group
, Group
);
496 destSD
->Group
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
497 RtlCopySid(length
, destSD
->Group
, Group
);
501 if (srcSD
->Control
& SE_DACL_PRESENT
)
503 RtlGetDaclSecurityDescriptor(pSourceSD
, &present
, &Dacl
, &defaulted
);
504 length
= Dacl
->AclSize
;
508 destSD
->Dacl
= srcSD
->Dacl
;
509 copy_acl(length
, (PACL
)((LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Dacl
), Dacl
);
513 destSD
->Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
514 copy_acl(length
, destSD
->Dacl
, Dacl
);
519 if (srcSD
->Control
& SE_SACL_PRESENT
)
521 RtlGetSaclSecurityDescriptor(pSourceSD
, &present
, &Sacl
, &defaulted
);
522 length
= Sacl
->AclSize
;
526 destSD
->Sacl
= srcSD
->Sacl
;
527 copy_acl(length
, (PACL
)((LPBYTE
)destSD
+ (DWORD_PTR
)destSD
->Sacl
), Sacl
);
531 destSD
->Sacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
532 copy_acl(length
, destSD
->Sacl
, Sacl
);
536 return STATUS_SUCCESS
;
539 /**************************************************************************
540 * RtlValidSecurityDescriptor [NTDLL.@]
542 * Determine if a SECURITY_DESCRIPTOR is valid.
545 * SecurityDescriptor [I] Descriptor to check.
548 * Success: STATUS_SUCCESS.
549 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
551 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
552 PSECURITY_DESCRIPTOR SecurityDescriptor
)
554 if ( ! SecurityDescriptor
)
555 return STATUS_INVALID_SECURITY_DESCR
;
556 if ( ((SECURITY_DESCRIPTOR
*)SecurityDescriptor
)->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
557 return STATUS_UNKNOWN_REVISION
;
559 return STATUS_SUCCESS
;
562 /**************************************************************************
563 * RtlLengthSecurityDescriptor [NTDLL.@]
565 ULONG WINAPI
RtlLengthSecurityDescriptor(
566 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
568 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
569 ULONG_PTR offset
= 0;
570 ULONG Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
575 if ( lpsd
->Control
& SE_SELF_RELATIVE
)
576 offset
= (ULONG_PTR
) lpsd
;
578 if ( lpsd
->Owner
!= NULL
)
579 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Owner
+ offset
));
581 if ( lpsd
->Group
!= NULL
)
582 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Group
+ offset
));
584 if ( (lpsd
->Control
& SE_SACL_PRESENT
) &&
586 Size
+= ((PACL
)((LPBYTE
)lpsd
->Sacl
+ offset
))->AclSize
;
588 if ( (lpsd
->Control
& SE_DACL_PRESENT
) &&
590 Size
+= ((PACL
)((LPBYTE
)lpsd
->Dacl
+ offset
))->AclSize
;
595 /******************************************************************************
596 * RtlGetDaclSecurityDescriptor [NTDLL.@]
599 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
600 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
601 OUT PBOOLEAN lpbDaclPresent
,
603 OUT PBOOLEAN lpbDaclDefaulted
)
605 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
607 TRACE("(%p,%p,%p,%p)\n",
608 pSecurityDescriptor
, lpbDaclPresent
, pDacl
, lpbDaclDefaulted
);
610 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
611 return STATUS_UNKNOWN_REVISION
;
613 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
615 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
616 *pDacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD_PTR
)lpsd
->Dacl
);
620 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
625 *lpbDaclDefaulted
= 0;
628 return STATUS_SUCCESS
;
631 /**************************************************************************
632 * RtlSetDaclSecurityDescriptor [NTDLL.@]
634 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
635 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
638 BOOLEAN dacldefaulted
)
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
;
649 lpsd
->Control
&= ~SE_DACL_PRESENT
;
650 return STATUS_SUCCESS
;
653 lpsd
->Control
|= SE_DACL_PRESENT
;
657 lpsd
->Control
|= SE_DACL_DEFAULTED
;
659 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
661 return STATUS_SUCCESS
;
664 /******************************************************************************
665 * RtlGetSaclSecurityDescriptor [NTDLL.@]
668 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
669 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
670 OUT PBOOLEAN lpbSaclPresent
,
672 OUT PBOOLEAN lpbSaclDefaulted
)
674 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
676 TRACE("(%p,%p,%p,%p)\n",
677 pSecurityDescriptor
, lpbSaclPresent
, pSacl
, lpbSaclDefaulted
);
679 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
680 return STATUS_UNKNOWN_REVISION
;
682 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
684 if (SE_SELF_RELATIVE
& lpsd
->Control
)
685 *pSacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD_PTR
)lpsd
->Sacl
);
689 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
692 return STATUS_SUCCESS
;
695 /**************************************************************************
696 * RtlSetSaclSecurityDescriptor [NTDLL.@]
698 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
699 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
702 BOOLEAN sacldefaulted
)
704 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
706 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
707 return STATUS_UNKNOWN_REVISION
;
708 if (lpsd
->Control
& SE_SELF_RELATIVE
)
709 return STATUS_INVALID_SECURITY_DESCR
;
711 lpsd
->Control
&= ~SE_SACL_PRESENT
;
714 lpsd
->Control
|= SE_SACL_PRESENT
;
717 lpsd
->Control
|= SE_SACL_DEFAULTED
;
719 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
720 return STATUS_SUCCESS
;
723 /**************************************************************************
724 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
726 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
727 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
729 PBOOLEAN OwnerDefaulted
)
731 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
733 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
734 return STATUS_INVALID_PARAMETER
;
736 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
737 *OwnerDefaulted
= TRUE
;
739 *OwnerDefaulted
= FALSE
;
741 if (lpsd
->Owner
!= NULL
)
743 if (lpsd
->Control
& SE_SELF_RELATIVE
)
744 *Owner
= (PSID
)((LPBYTE
)lpsd
+ (ULONG_PTR
)lpsd
->Owner
);
746 *Owner
= lpsd
->Owner
;
752 return STATUS_SUCCESS
;
755 /**************************************************************************
756 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
758 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
759 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
761 BOOLEAN ownerdefaulted
)
763 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
765 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
766 return STATUS_UNKNOWN_REVISION
;
767 if (lpsd
->Control
& SE_SELF_RELATIVE
)
768 return STATUS_INVALID_SECURITY_DESCR
;
772 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
774 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
775 return STATUS_SUCCESS
;
778 /**************************************************************************
779 * RtlSetGroupSecurityDescriptor [NTDLL.@]
781 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
782 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
784 BOOLEAN groupdefaulted
)
786 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
788 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
789 return STATUS_UNKNOWN_REVISION
;
790 if (lpsd
->Control
& SE_SELF_RELATIVE
)
791 return STATUS_INVALID_SECURITY_DESCR
;
795 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
797 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
798 return STATUS_SUCCESS
;
801 /**************************************************************************
802 * RtlGetGroupSecurityDescriptor [NTDLL.@]
804 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
805 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
807 PBOOLEAN GroupDefaulted
)
809 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
811 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
812 return STATUS_INVALID_PARAMETER
;
814 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
815 *GroupDefaulted
= TRUE
;
817 *GroupDefaulted
= FALSE
;
819 if (lpsd
->Group
!= NULL
)
821 if (lpsd
->Control
& SE_SELF_RELATIVE
)
822 *Group
= (PSID
)((LPBYTE
)lpsd
+ (ULONG_PTR
)lpsd
->Group
);
824 *Group
= lpsd
->Group
;
829 return STATUS_SUCCESS
;
832 /**************************************************************************
833 * RtlMakeSelfRelativeSD [NTDLL.@]
835 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
836 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
837 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
838 IN OUT LPDWORD lpdwBufferLength
)
842 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
843 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
845 TRACE(" %p %p %p(%d)\n", pAbs
, pRel
, lpdwBufferLength
,
846 lpdwBufferLength
? *lpdwBufferLength
: -1);
848 if (!lpdwBufferLength
|| !pAbs
)
849 return STATUS_INVALID_PARAMETER
;
851 length
= RtlLengthSecurityDescriptor(pAbs
);
852 if (*lpdwBufferLength
< length
)
854 *lpdwBufferLength
= length
;
855 return STATUS_BUFFER_TOO_SMALL
;
859 return STATUS_INVALID_PARAMETER
;
861 if (pAbs
->Control
& SE_SELF_RELATIVE
)
863 memcpy(pRel
, pAbs
, length
);
864 return STATUS_SUCCESS
;
867 pRel
->Revision
= pAbs
->Revision
;
868 pRel
->Sbz1
= pAbs
->Sbz1
;
869 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
871 offsetRel
= sizeof(SECURITY_DESCRIPTOR
);
874 pRel
->Owner
= (PSID
) offsetRel
;
875 length
= RtlLengthSid(pAbs
->Owner
);
876 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
886 pRel
->Group
= (PSID
) offsetRel
;
887 length
= RtlLengthSid(pAbs
->Group
);
888 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
898 pRel
->Sacl
= (PACL
) offsetRel
;
899 length
= pAbs
->Sacl
->AclSize
;
900 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
910 pRel
->Dacl
= (PACL
) offsetRel
;
911 length
= pAbs
->Dacl
->AclSize
;
912 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
919 return STATUS_SUCCESS
;
923 /**************************************************************************
924 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
926 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
927 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
928 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
929 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
931 OUT LPDWORD lpdwDaclSize
,
933 OUT LPDWORD lpdwSaclSize
,
935 OUT LPDWORD lpdwOwnerSize
,
936 OUT PSID pPrimaryGroup
,
937 OUT LPDWORD lpdwPrimaryGroupSize
)
939 NTSTATUS status
= STATUS_SUCCESS
;
940 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
941 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
944 !lpdwAbsoluteSecurityDescriptorSize
||
948 !lpdwPrimaryGroupSize
||
949 ~pRel
->Control
& SE_SELF_RELATIVE
)
950 return STATUS_INVALID_PARAMETER
;
952 /* Confirm buffers are sufficiently large */
953 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
955 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
956 status
= STATUS_BUFFER_TOO_SMALL
;
959 if (pRel
->Control
& SE_DACL_PRESENT
&&
960 *lpdwDaclSize
< ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG_PTR
)pRel
))->AclSize
)
962 *lpdwDaclSize
= ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG_PTR
)pRel
))->AclSize
;
963 status
= STATUS_BUFFER_TOO_SMALL
;
966 if (pRel
->Control
& SE_SACL_PRESENT
&&
967 *lpdwSaclSize
< ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG_PTR
)pRel
))->AclSize
)
969 *lpdwSaclSize
= ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG_PTR
)pRel
))->AclSize
;
970 status
= STATUS_BUFFER_TOO_SMALL
;
974 *lpdwOwnerSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG_PTR
)pRel
)))
976 *lpdwOwnerSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG_PTR
)pRel
));
977 status
= STATUS_BUFFER_TOO_SMALL
;
981 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG_PTR
)pRel
)))
983 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG_PTR
)pRel
));
984 status
= STATUS_BUFFER_TOO_SMALL
;
987 if (status
!= STATUS_SUCCESS
)
990 /* Copy structures, and clear the ones we don't set */
991 pAbs
->Revision
= pRel
->Revision
;
992 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
998 if (pRel
->Control
& SE_SACL_PRESENT
)
1000 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG_PTR
)pRel
);
1002 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
1006 if (pRel
->Control
& SE_DACL_PRESENT
)
1008 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG_PTR
)pRel
);
1009 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
1015 PSID psid
= (PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG_PTR
)pRel
);
1016 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
1017 pAbs
->Owner
= pOwner
;
1022 PSID psid
= (PSID
)((LPBYTE
)pRel
->Group
+ (ULONG_PTR
)pRel
);
1023 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
1024 pAbs
->Group
= pPrimaryGroup
;
1030 /******************************************************************************
1031 * RtlGetControlSecurityDescriptor (NTDLL.@)
1033 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1034 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1035 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1036 LPDWORD lpdwRevision
)
1038 SECURITY_DESCRIPTOR
*lpsd
= pSecurityDescriptor
;
1040 TRACE("(%p,%p,%p)\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1042 *lpdwRevision
= lpsd
->Revision
;
1044 if (*lpdwRevision
!= SECURITY_DESCRIPTOR_REVISION
)
1045 return STATUS_UNKNOWN_REVISION
;
1047 *pControl
= lpsd
->Control
;
1049 return STATUS_SUCCESS
;
1052 /******************************************************************************
1053 * RtlSetControlSecurityDescriptor (NTDLL.@)
1055 NTSTATUS WINAPI
RtlSetControlSecurityDescriptor(
1056 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1057 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
1058 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
1060 SECURITY_DESCRIPTOR_CONTROL
const immutable
1061 = SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
1062 | SE_DACL_PRESENT
| SE_DACL_DEFAULTED
1063 | SE_SACL_PRESENT
| SE_SACL_DEFAULTED
1064 | SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
1067 SECURITY_DESCRIPTOR
*lpsd
= SecurityDescriptor
;
1069 TRACE("(%p 0x%04x 0x%04x)\n", SecurityDescriptor
,
1070 ControlBitsOfInterest
, ControlBitsToSet
);
1072 if ((ControlBitsOfInterest
| ControlBitsToSet
) & immutable
)
1073 return STATUS_INVALID_PARAMETER
;
1075 lpsd
->Control
|= (ControlBitsOfInterest
& ControlBitsToSet
);
1076 lpsd
->Control
&= ~(ControlBitsOfInterest
& ~ControlBitsToSet
);
1078 return STATUS_SUCCESS
;
1082 /**************************************************************************
1083 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1085 NTSTATUS WINAPI
RtlAbsoluteToSelfRelativeSD(
1086 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
1087 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
1088 PULONG BufferLength
)
1090 SECURITY_DESCRIPTOR
*abs
= AbsoluteSecurityDescriptor
;
1092 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor
,
1093 SelfRelativeSecurityDescriptor
, BufferLength
);
1095 if (abs
->Control
& SE_SELF_RELATIVE
)
1096 return STATUS_BAD_DESCRIPTOR_FORMAT
;
1098 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
1099 SelfRelativeSecurityDescriptor
, BufferLength
);
1104 * access control list's
1107 /**************************************************************************
1108 * RtlCreateAcl [NTDLL.@]
1111 * This should return NTSTATUS
1113 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
1115 TRACE("%p 0x%08x 0x%08x\n", acl
, size
, rev
);
1117 if (rev
< MIN_ACL_REVISION
|| rev
> MAX_ACL_REVISION
)
1118 return STATUS_INVALID_PARAMETER
;
1119 if (size
<sizeof(ACL
))
1120 return STATUS_BUFFER_TOO_SMALL
;
1122 return STATUS_INVALID_PARAMETER
;
1124 memset(acl
,'\0',sizeof(ACL
));
1125 acl
->AclRevision
= rev
;
1126 acl
->AclSize
= size
;
1128 return STATUS_SUCCESS
;
1131 /**************************************************************************
1132 * RtlFirstFreeAce [NTDLL.@]
1133 * looks for the AceCount+1 ACE, and if it is still within the alloced
1134 * ACL, return a pointer to it
1136 BOOLEAN WINAPI
RtlFirstFreeAce(
1144 ace
= (PACE_HEADER
)(acl
+1);
1145 for (i
=0;i
<acl
->AceCount
;i
++) {
1146 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1148 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1150 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1156 /**************************************************************************
1157 * RtlAddAce [NTDLL.@]
1159 NTSTATUS WINAPI
RtlAddAce(
1163 PACE_HEADER acestart
,
1166 PACE_HEADER ace
,targetace
;
1169 if (acl
->AclRevision
!= ACL_REVISION
)
1170 return STATUS_INVALID_PARAMETER
;
1171 if (!RtlFirstFreeAce(acl
,&targetace
))
1172 return STATUS_INVALID_PARAMETER
;
1173 nrofaces
=0;ace
=acestart
;
1174 while (((BYTE
*)ace
- (BYTE
*)acestart
) < acelen
) {
1176 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1178 if ((BYTE
*)targetace
+ acelen
> (BYTE
*)acl
+ acl
->AclSize
) /* too much aces */
1179 return STATUS_INVALID_PARAMETER
;
1180 memcpy(targetace
,acestart
,acelen
);
1181 acl
->AceCount
+=nrofaces
;
1182 return STATUS_SUCCESS
;
1185 /**************************************************************************
1186 * RtlDeleteAce [NTDLL.@]
1188 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1193 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
1195 if (STATUS_SUCCESS
== status
)
1200 /* skip over the ACE we are deleting */
1201 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
1204 /* calculate the length of the rest */
1205 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
1207 len
+= pcAce
->AceSize
;
1208 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
1211 /* slide them all backwards */
1212 memmove(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
1216 TRACE("pAcl=%p dwAceIndex=%d status=0x%08x\n", pAcl
, dwAceIndex
, status
);
1221 /******************************************************************************
1222 * RtlAddAccessAllowedAce [NTDLL.@]
1224 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
1226 IN DWORD dwAceRevision
,
1227 IN DWORD AccessMask
,
1230 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1233 /******************************************************************************
1234 * RtlAddAccessAllowedAceEx [NTDLL.@]
1236 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
1238 IN DWORD dwAceRevision
,
1240 IN DWORD AccessMask
,
1243 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1245 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1246 AccessMask
, pSid
, ACCESS_ALLOWED_ACE_TYPE
);
1249 /******************************************************************************
1250 * RtlAddAccessDeniedAce [NTDLL.@]
1252 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1254 IN DWORD dwAceRevision
,
1255 IN DWORD AccessMask
,
1258 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1261 /******************************************************************************
1262 * RtlAddAccessDeniedAceEx [NTDLL.@]
1264 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1266 IN DWORD dwAceRevision
,
1268 IN DWORD AccessMask
,
1271 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1273 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1274 AccessMask
, pSid
, ACCESS_DENIED_ACE_TYPE
);
1277 /**************************************************************************
1278 * RtlAddAuditAccessAce [NTDLL.@]
1280 NTSTATUS WINAPI
RtlAddAuditAccessAceEx(
1282 IN DWORD dwAceRevision
,
1283 IN DWORD dwAceFlags
,
1284 IN DWORD dwAccessMask
,
1286 IN BOOL bAuditSuccess
,
1287 IN BOOL bAuditFailure
)
1289 TRACE("(%p,%d,0x%08x,0x%08x,%p,%u,%u)\n",pAcl
,dwAceRevision
,dwAceFlags
,dwAccessMask
,
1290 pSid
,bAuditSuccess
,bAuditFailure
);
1293 dwAceFlags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
1296 dwAceFlags
|= FAILED_ACCESS_ACE_FLAG
;
1298 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
,
1299 dwAccessMask
, pSid
, SYSTEM_AUDIT_ACE_TYPE
);
1302 /**************************************************************************
1303 * RtlAddAuditAccessAce [NTDLL.@]
1305 NTSTATUS WINAPI
RtlAddAuditAccessAce(
1307 IN DWORD dwAceRevision
,
1308 IN DWORD dwAccessMask
,
1310 IN BOOL bAuditSuccess
,
1311 IN BOOL bAuditFailure
)
1313 return RtlAddAuditAccessAceEx(pAcl
, dwAceRevision
, 0, dwAccessMask
, pSid
, bAuditSuccess
, bAuditFailure
);
1316 /******************************************************************************
1317 * RtlValidAcl [NTDLL.@]
1319 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1322 TRACE("(%p)\n", pAcl
);
1329 if (pAcl
->AclRevision
< MIN_ACL_REVISION
||
1330 pAcl
->AclRevision
> MAX_ACL_REVISION
)
1334 ace
= (PACE_HEADER
)(pAcl
+1);
1336 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1338 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1343 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1349 WARN("(%p): invalid pointer!\n", pAcl
);
1356 /******************************************************************************
1357 * RtlGetAce [NTDLL.@]
1359 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1363 TRACE("(%p,%d,%p)\n",pAcl
,dwAceIndex
,pAce
);
1365 if (dwAceIndex
>= pAcl
->AceCount
)
1366 return STATUS_INVALID_PARAMETER
;
1368 ace
= (PACE_HEADER
)(pAcl
+ 1);
1369 for (;dwAceIndex
;dwAceIndex
--)
1370 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1374 return STATUS_SUCCESS
;
1381 /******************************************************************************
1382 * RtlAdjustPrivilege [NTDLL.@]
1384 * Enables or disables a privilege from the calling thread or process.
1387 * Privilege [I] Privilege index to change.
1388 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1389 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1390 * Enabled [O] Whether privilege was previously enabled or disabled.
1393 * Success: STATUS_SUCCESS.
1394 * Failure: NTSTATUS code.
1397 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1401 RtlAdjustPrivilege(ULONG Privilege
,
1403 BOOLEAN CurrentThread
,
1406 TOKEN_PRIVILEGES NewState
;
1407 TOKEN_PRIVILEGES OldState
;
1412 TRACE("(%d, %s, %s, %p)\n", Privilege
, Enable
? "TRUE" : "FALSE",
1413 CurrentThread
? "TRUE" : "FALSE", Enabled
);
1417 Status
= NtOpenThreadToken(GetCurrentThread(),
1418 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1424 Status
= NtOpenProcessToken(GetCurrentProcess(),
1425 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1429 if (!NT_SUCCESS(Status
))
1431 WARN("Retrieving token handle failed (Status %x)\n", Status
);
1435 OldState
.PrivilegeCount
= 1;
1437 NewState
.PrivilegeCount
= 1;
1438 NewState
.Privileges
[0].Luid
.LowPart
= Privilege
;
1439 NewState
.Privileges
[0].Luid
.HighPart
= 0;
1440 NewState
.Privileges
[0].Attributes
= (Enable
) ? SE_PRIVILEGE_ENABLED
: 0;
1442 Status
= NtAdjustPrivilegesToken(TokenHandle
,
1445 sizeof(TOKEN_PRIVILEGES
),
1448 NtClose (TokenHandle
);
1449 if (Status
== STATUS_NOT_ALL_ASSIGNED
)
1451 TRACE("Failed to assign all privileges\n");
1452 return STATUS_PRIVILEGE_NOT_HELD
;
1454 if (!NT_SUCCESS(Status
))
1456 WARN("NtAdjustPrivilegesToken() failed (Status %x)\n", Status
);
1460 if (OldState
.PrivilegeCount
== 0)
1463 *Enabled
= (OldState
.Privileges
[0].Attributes
& SE_PRIVILEGE_ENABLED
);
1465 return STATUS_SUCCESS
;
1468 /******************************************************************************
1469 * RtlImpersonateSelf [NTDLL.@]
1471 * Makes an impersonation token that represents the process user and assigns
1472 * to the current thread.
1475 * ImpersonationLevel [I] Level at which to impersonate.
1478 * Success: STATUS_SUCCESS.
1479 * Failure: NTSTATUS code.
1482 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1485 OBJECT_ATTRIBUTES ObjectAttributes
;
1486 HANDLE ProcessToken
;
1487 HANDLE ImpersonationToken
;
1489 TRACE("(%08x)\n", ImpersonationLevel
);
1491 Status
= NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE
,
1493 if (Status
!= STATUS_SUCCESS
)
1496 InitializeObjectAttributes( &ObjectAttributes
, NULL
, 0, NULL
, NULL
);
1498 Status
= NtDuplicateToken( ProcessToken
,
1503 &ImpersonationToken
);
1504 if (Status
!= STATUS_SUCCESS
)
1506 NtClose( ProcessToken
);
1510 Status
= NtSetInformationThread( GetCurrentThread(),
1511 ThreadImpersonationToken
,
1512 &ImpersonationToken
,
1513 sizeof(ImpersonationToken
) );
1515 NtClose( ImpersonationToken
);
1516 NtClose( ProcessToken
);
1521 /******************************************************************************
1522 * NtAccessCheck [NTDLL.@]
1523 * ZwAccessCheck [NTDLL.@]
1525 * Checks that a user represented by a token is allowed to access an object
1526 * represented by a security descriptor.
1529 * SecurityDescriptor [I] The security descriptor of the object to check.
1530 * ClientToken [I] Token of the user accessing the object.
1531 * DesiredAccess [I] The desired access to the object.
1532 * GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
1533 * PrivilegeSet [I/O] Privileges used during the access check.
1534 * ReturnLength [O] Number of bytes stored into PrivilegeSet.
1535 * GrantedAccess [O] The actual access rights granted.
1536 * AccessStatus [O] The status of the access check.
1542 * DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
1543 * the maximum access rights allowed by the SD and returns them in
1545 * The SecurityDescriptor must have a valid owner and groups present,
1546 * otherwise the function will fail.
1550 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1552 ACCESS_MASK DesiredAccess
,
1553 PGENERIC_MAPPING GenericMapping
,
1554 PPRIVILEGE_SET PrivilegeSet
,
1555 PULONG ReturnLength
,
1556 PULONG GrantedAccess
,
1557 NTSTATUS
*AccessStatus
)
1561 TRACE("(%p, %p, %08x, %p, %p, %p, %p, %p)\n",
1562 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
1563 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
1565 if (!PrivilegeSet
|| !ReturnLength
)
1566 return STATUS_ACCESS_VIOLATION
;
1568 SERVER_START_REQ( access_check
)
1570 struct security_descriptor sd
;
1575 BOOLEAN defaulted
, present
;
1577 SECURITY_DESCRIPTOR_CONTROL control
;
1579 req
->handle
= wine_server_obj_handle( ClientToken
);
1580 req
->desired_access
= DesiredAccess
;
1581 req
->mapping_read
= GenericMapping
->GenericRead
;
1582 req
->mapping_write
= GenericMapping
->GenericWrite
;
1583 req
->mapping_execute
= GenericMapping
->GenericExecute
;
1584 req
->mapping_all
= GenericMapping
->GenericAll
;
1586 /* marshal security descriptor */
1587 RtlGetControlSecurityDescriptor( SecurityDescriptor
, &control
, &revision
);
1588 sd
.control
= control
& ~SE_SELF_RELATIVE
;
1589 RtlGetOwnerSecurityDescriptor( SecurityDescriptor
, &owner
, &defaulted
);
1590 sd
.owner_len
= RtlLengthSid( owner
);
1591 RtlGetGroupSecurityDescriptor( SecurityDescriptor
, &group
, &defaulted
);
1592 sd
.group_len
= RtlLengthSid( group
);
1593 RtlGetSaclSecurityDescriptor( SecurityDescriptor
, &present
, &sacl
, &defaulted
);
1594 sd
.sacl_len
= ((present
&& sacl
) ? acl_bytesInUse(sacl
) : 0);
1595 RtlGetDaclSecurityDescriptor( SecurityDescriptor
, &present
, &dacl
, &defaulted
);
1596 sd
.dacl_len
= ((present
&& dacl
) ? acl_bytesInUse(dacl
) : 0);
1598 wine_server_add_data( req
, &sd
, sizeof(sd
) );
1599 wine_server_add_data( req
, owner
, sd
.owner_len
);
1600 wine_server_add_data( req
, group
, sd
.group_len
);
1601 wine_server_add_data( req
, sacl
, sd
.sacl_len
);
1602 wine_server_add_data( req
, dacl
, sd
.dacl_len
);
1604 wine_server_set_reply( req
, PrivilegeSet
->Privilege
, *ReturnLength
- FIELD_OFFSET( PRIVILEGE_SET
, Privilege
) );
1606 status
= wine_server_call( req
);
1608 *ReturnLength
= FIELD_OFFSET( PRIVILEGE_SET
, Privilege
) + reply
->privileges_len
;
1609 PrivilegeSet
->PrivilegeCount
= reply
->privileges_len
/ sizeof(LUID_AND_ATTRIBUTES
);
1611 if (status
== STATUS_SUCCESS
)
1613 *AccessStatus
= reply
->access_status
;
1614 *GrantedAccess
= reply
->access_granted
;
1622 /******************************************************************************
1623 * NtSetSecurityObject [NTDLL.@]
1624 * ZwSetSecurityObject [NTDLL.@]
1626 * Sets specified parts of the object's security descriptor.
1629 * Handle [I] Handle to the object to change security descriptor of.
1630 * SecurityInformation [I] Specifies which parts of the security descriptor to set.
1631 * SecurityDescriptor [I] New parts of a security descriptor for the object.
1637 NTSTATUS WINAPI
NtSetSecurityObject(HANDLE Handle
,
1638 SECURITY_INFORMATION SecurityInformation
,
1639 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1642 struct security_descriptor sd
;
1643 PACL dacl
= NULL
, sacl
= NULL
;
1644 PSID owner
= NULL
, group
= NULL
;
1645 BOOLEAN defaulted
, present
;
1647 SECURITY_DESCRIPTOR_CONTROL control
;
1649 TRACE("%p 0x%08x %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
1651 if (!SecurityDescriptor
) return STATUS_ACCESS_VIOLATION
;
1653 memset( &sd
, 0, sizeof(sd
) );
1654 status
= RtlGetControlSecurityDescriptor( SecurityDescriptor
, &control
, &revision
);
1655 if (status
!= STATUS_SUCCESS
) return status
;
1656 sd
.control
= control
& ~SE_SELF_RELATIVE
;
1658 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1660 status
= RtlGetOwnerSecurityDescriptor( SecurityDescriptor
, &owner
, &defaulted
);
1661 if (status
!= STATUS_SUCCESS
) return status
;
1662 if (!(sd
.owner_len
= RtlLengthSid( owner
)))
1663 return STATUS_INVALID_SECURITY_DESCR
;
1666 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1668 status
= RtlGetGroupSecurityDescriptor( SecurityDescriptor
, &group
, &defaulted
);
1669 if (status
!= STATUS_SUCCESS
) return status
;
1670 if (!(sd
.group_len
= RtlLengthSid( group
)))
1671 return STATUS_INVALID_SECURITY_DESCR
;
1674 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
1676 status
= RtlGetSaclSecurityDescriptor( SecurityDescriptor
, &present
, &sacl
, &defaulted
);
1677 if (status
!= STATUS_SUCCESS
) return status
;
1678 sd
.sacl_len
= (sacl
&& present
) ? acl_bytesInUse(sacl
) : 0;
1679 sd
.control
|= SE_SACL_PRESENT
;
1682 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1684 status
= RtlGetDaclSecurityDescriptor( SecurityDescriptor
, &present
, &dacl
, &defaulted
);
1685 if (status
!= STATUS_SUCCESS
) return status
;
1686 sd
.dacl_len
= (dacl
&& present
) ? acl_bytesInUse(dacl
) : 0;
1687 sd
.control
|= SE_DACL_PRESENT
;
1690 SERVER_START_REQ( set_security_object
)
1692 req
->handle
= wine_server_obj_handle( Handle
);
1693 req
->security_info
= SecurityInformation
;
1695 wine_server_add_data( req
, &sd
, sizeof(sd
) );
1696 wine_server_add_data( req
, owner
, sd
.owner_len
);
1697 wine_server_add_data( req
, group
, sd
.group_len
);
1698 wine_server_add_data( req
, sacl
, sd
.sacl_len
);
1699 wine_server_add_data( req
, dacl
, sd
.dacl_len
);
1700 status
= wine_server_call( req
);
1707 /******************************************************************************
1708 * RtlConvertSidToUnicodeString (NTDLL.@)
1710 * The returned SID is used to access the USER registry hive usually
1712 * the native function returns something like
1713 * "S-1-5-21-0000000000-000000000-0000000000-500";
1715 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1716 PUNICODE_STRING String
,
1718 BOOLEAN AllocateString
)
1720 static const WCHAR formatW
[] = {'-','%','u',0};
1721 WCHAR buffer
[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES
];
1723 const SID
*sid
= pSid
;
1727 p
+= sprintfW( p
, formatW
, sid
->Revision
);
1728 p
+= sprintfW( p
, formatW
, MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
1729 sid
->IdentifierAuthority
.Value
[4] ),
1730 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
1731 sid
->IdentifierAuthority
.Value
[2] )));
1732 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
1733 p
+= sprintfW( p
, formatW
, sid
->SubAuthority
[i
] );
1735 len
= (p
+ 1 - buffer
) * sizeof(WCHAR
);
1737 String
->Length
= len
- sizeof(WCHAR
);
1740 String
->MaximumLength
= len
;
1741 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1742 return STATUS_NO_MEMORY
;
1744 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1746 memcpy( String
->Buffer
, buffer
, len
);
1747 return STATUS_SUCCESS
;
1750 /******************************************************************************
1751 * RtlQueryInformationAcl (NTDLL.@)
1753 NTSTATUS WINAPI
RtlQueryInformationAcl(
1755 LPVOID pAclInformation
,
1756 DWORD nAclInformationLength
,
1757 ACL_INFORMATION_CLASS dwAclInformationClass
)
1759 NTSTATUS status
= STATUS_SUCCESS
;
1761 TRACE("pAcl=%p pAclInfo=%p len=%d, class=%d\n",
1762 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1764 switch (dwAclInformationClass
)
1766 case AclRevisionInformation
:
1768 PACL_REVISION_INFORMATION paclrev
= pAclInformation
;
1770 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1771 status
= STATUS_INVALID_PARAMETER
;
1773 paclrev
->AclRevision
= pAcl
->AclRevision
;
1778 case AclSizeInformation
:
1780 PACL_SIZE_INFORMATION paclsize
= pAclInformation
;
1782 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1783 status
= STATUS_INVALID_PARAMETER
;
1786 paclsize
->AceCount
= pAcl
->AceCount
;
1787 paclsize
->AclBytesInUse
= acl_bytesInUse(pAcl
);
1788 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1790 WARN("Acl uses %d bytes, but only has %d allocated! Returning smaller of the two values.\n", pAcl
->AclSize
, paclsize
->AclBytesInUse
);
1791 paclsize
->AclBytesFree
= 0;
1792 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1795 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1802 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1803 status
= STATUS_INVALID_PARAMETER
;