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 #define SELF_RELATIVE_FIELD(sd,field) ((BYTE *)(sd) + ((SECURITY_DESCRIPTOR_RELATIVE *)(sd))->field)
50 /* helper function to retrieve active length of an ACL */
51 static size_t acl_bytesInUse(PACL pAcl
)
54 size_t bytesInUse
= sizeof(ACL
);
55 PACE_HEADER ace
= (PACE_HEADER
) (pAcl
+ 1);
56 for (i
= 0; i
< pAcl
->AceCount
; i
++)
58 bytesInUse
+= ace
->AceSize
;
59 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
64 /* helper function to copy an ACL */
65 static BOOLEAN
copy_acl(DWORD nDestinationAclLength
, PACL pDestinationAcl
, PACL pSourceAcl
)
69 if (!pSourceAcl
|| !RtlValidAcl(pSourceAcl
))
72 size
= pSourceAcl
->AclSize
;
73 if (nDestinationAclLength
< size
)
76 memmove(pDestinationAcl
, pSourceAcl
, size
);
80 /* generically adds an ACE to an ACL */
81 static NTSTATUS
add_access_ace(PACL pAcl
, DWORD dwAceRevision
, DWORD dwAceFlags
,
82 DWORD dwAccessMask
, PSID pSid
, DWORD dwAceType
)
84 ACE_HEADER
*pAceHeader
;
90 if (!RtlValidSid(pSid
))
91 return STATUS_INVALID_SID
;
93 if (pAcl
->AclRevision
> MAX_ACL_REVISION
|| dwAceRevision
> MAX_ACL_REVISION
)
94 return STATUS_REVISION_MISMATCH
;
96 if (!RtlValidAcl(pAcl
))
97 return STATUS_INVALID_ACL
;
99 if (!RtlFirstFreeAce(pAcl
, &pAceHeader
))
100 return STATUS_INVALID_ACL
;
103 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
105 /* calculate generic size of the ACE */
106 dwLengthSid
= RtlLengthSid(pSid
);
107 dwAceSize
= sizeof(ACE_HEADER
) + sizeof(DWORD
) + dwLengthSid
;
108 if ((char *)pAceHeader
+ dwAceSize
> (char *)pAcl
+ pAcl
->AclSize
)
109 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
111 /* fill the new ACE */
112 pAceHeader
->AceType
= dwAceType
;
113 pAceHeader
->AceFlags
= dwAceFlags
;
114 pAceHeader
->AceSize
= dwAceSize
;
116 /* skip past the ACE_HEADER of the ACE */
117 pAccessMask
= (DWORD
*)(pAceHeader
+ 1);
118 *pAccessMask
= dwAccessMask
;
120 /* skip past ACE->Mask */
121 pSidStart
= pAccessMask
+ 1;
122 RtlCopySid(dwLengthSid
, pSidStart
, pSid
);
124 pAcl
->AclRevision
= max(pAcl
->AclRevision
, dwAceRevision
);
127 return STATUS_SUCCESS
;
134 /******************************************************************************
135 * RtlAllocateAndInitializeSid [NTDLL.@]
138 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
139 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
140 BYTE nSubAuthorityCount
,
141 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
142 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
143 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
144 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
149 TRACE("(%p, 0x%04x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,%p)\n",
150 pIdentifierAuthority
,nSubAuthorityCount
,
151 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
152 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
154 if (nSubAuthorityCount
> 8) return STATUS_INVALID_SID
;
156 if (!(tmp_sid
= RtlAllocateHeap( GetProcessHeap(), 0,
157 RtlLengthRequiredSid(nSubAuthorityCount
))))
158 return STATUS_NO_MEMORY
;
160 tmp_sid
->Revision
= SID_REVISION
;
162 if (pIdentifierAuthority
)
163 tmp_sid
->IdentifierAuthority
= *pIdentifierAuthority
;
164 tmp_sid
->SubAuthorityCount
= nSubAuthorityCount
;
166 switch( nSubAuthorityCount
)
168 case 8: tmp_sid
->SubAuthority
[7]= nSubAuthority7
;
170 case 7: tmp_sid
->SubAuthority
[6]= nSubAuthority6
;
172 case 6: tmp_sid
->SubAuthority
[5]= nSubAuthority5
;
174 case 5: tmp_sid
->SubAuthority
[4]= nSubAuthority4
;
176 case 4: tmp_sid
->SubAuthority
[3]= nSubAuthority3
;
178 case 3: tmp_sid
->SubAuthority
[2]= nSubAuthority2
;
180 case 2: tmp_sid
->SubAuthority
[1]= nSubAuthority1
;
182 case 1: tmp_sid
->SubAuthority
[0]= nSubAuthority0
;
186 return STATUS_SUCCESS
;
189 /******************************************************************************
190 * RtlEqualSid [NTDLL.@]
192 * Determine if two SIDs are equal.
195 * pSid1 [I] Source SID
196 * pSid2 [I] SID to compare with
199 * TRUE, if pSid1 is equal to pSid2,
202 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
204 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
207 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
210 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
216 /******************************************************************************
217 * RtlEqualPrefixSid [NTDLL.@]
219 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
221 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
224 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
227 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
234 /******************************************************************************
235 * RtlFreeSid [NTDLL.@]
237 * Free the resources used by a SID.
240 * pSid [I] SID to Free.
245 DWORD WINAPI
RtlFreeSid(PSID pSid
)
247 TRACE("(%p)\n", pSid
);
248 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
249 return STATUS_SUCCESS
;
252 /**************************************************************************
253 * RtlLengthRequiredSid [NTDLL.@]
255 * Determine the amount of memory a SID will use
258 * nrofsubauths [I] Number of Sub Authorities in the SID.
261 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
263 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
265 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
268 /**************************************************************************
269 * RtlLengthSid [NTDLL.@]
271 * Determine the amount of memory a SID is using
274 * pSid [I] SID to get the size of.
277 * The size, in bytes, of pSid.
279 DWORD WINAPI
RtlLengthSid(PSID pSid
)
281 TRACE("sid=%p\n",pSid
);
283 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
286 /**************************************************************************
287 * RtlInitializeSid [NTDLL.@]
292 * pSid [I] SID to initialise
293 * pIdentifierAuthority [I] Identifier Authority
294 * nSubAuthorityCount [I] Number of Sub Authorities
297 * Success: TRUE. pSid is initialised with the details given.
298 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
300 BOOL WINAPI
RtlInitializeSid(
302 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
303 BYTE nSubAuthorityCount
)
308 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
311 pisid
->Revision
= SID_REVISION
;
312 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
313 if (pIdentifierAuthority
)
314 pisid
->IdentifierAuthority
= *pIdentifierAuthority
;
316 for (i
= 0; i
< nSubAuthorityCount
; i
++)
317 *RtlSubAuthoritySid(pSid
, i
) = 0;
322 /**************************************************************************
323 * RtlSubAuthoritySid [NTDLL.@]
325 * Return the Sub Authority of a SID
328 * pSid [I] SID to get the Sub Authority from.
329 * nSubAuthority [I] Sub Authority number.
332 * A pointer to The Sub Authority value of pSid.
334 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
336 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
339 /**************************************************************************
340 * RtlIdentifierAuthoritySid [NTDLL.@]
342 * Return the Identifier Authority of a SID.
345 * pSid [I] SID to get the Identifier Authority from.
348 * A pointer to the Identifier Authority value of pSid.
350 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
352 return &(((SID
*)pSid
)->IdentifierAuthority
);
355 /**************************************************************************
356 * RtlSubAuthorityCountSid [NTDLL.@]
358 * Get the number of Sub Authorities in a SID.
361 * pSid [I] SID to get the count from.
364 * A pointer to the Sub Authority count of pSid.
366 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
368 return &(((SID
*)pSid
)->SubAuthorityCount
);
371 /**************************************************************************
372 * RtlCopySid [NTDLL.@]
374 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
376 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
377 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
380 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
383 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
386 /******************************************************************************
387 * RtlValidSid [NTDLL.@]
389 * Determine if a SID is valid.
392 * pSid [I] SID to check
395 * TRUE if pSid is valid,
398 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
404 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
405 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
412 WARN("(%p): invalid pointer!\n", pSid
);
421 * security descriptor functions
424 /**************************************************************************
425 * RtlCreateSecurityDescriptor [NTDLL.@]
427 * Initialise a SECURITY_DESCRIPTOR.
430 * lpsd [O] Descriptor to initialise.
431 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
434 * Success: STATUS_SUCCESS.
435 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
437 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
438 PSECURITY_DESCRIPTOR lpsd
,
441 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
442 return STATUS_UNKNOWN_REVISION
;
443 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
444 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
445 return STATUS_SUCCESS
;
448 /**************************************************************************
449 * RtlCopySecurityDescriptor [NTDLL.@]
451 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
454 * pSourceSD [O] SD to copy from.
455 * pDestinationSD [I] Destination SD.
458 * Success: STATUS_SUCCESS.
459 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
461 NTSTATUS WINAPI
RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD
, PSECURITY_DESCRIPTOR pDestinationSD
)
467 if (((SECURITY_DESCRIPTOR
*)pSourceSD
)->Control
& SE_SELF_RELATIVE
)
469 SECURITY_DESCRIPTOR_RELATIVE
*src
= pSourceSD
;
470 SECURITY_DESCRIPTOR_RELATIVE
*dst
= pDestinationSD
;
472 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
473 return STATUS_UNKNOWN_REVISION
;
478 Owner
= (PSID
)SELF_RELATIVE_FIELD( src
, Owner
);
479 length
= RtlLengthSid( Owner
);
480 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Owner
), Owner
);
484 Group
= (PSID
)SELF_RELATIVE_FIELD( src
, Group
);
485 length
= RtlLengthSid( Group
);
486 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Group
), Group
);
488 if ((src
->Control
& SE_SACL_PRESENT
) && src
->Sacl
)
490 Sacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Sacl
);
491 copy_acl(Sacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Sacl
), Sacl
);
493 if ((src
->Control
& SE_DACL_PRESENT
) && src
->Dacl
)
495 Dacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Dacl
);
496 copy_acl(Dacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Dacl
), Dacl
);
501 SECURITY_DESCRIPTOR
*src
= pSourceSD
;
502 SECURITY_DESCRIPTOR
*dst
= pDestinationSD
;
504 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
505 return STATUS_UNKNOWN_REVISION
;
510 length
= RtlLengthSid( src
->Owner
);
511 dst
->Owner
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
512 RtlCopySid(length
, dst
->Owner
, src
->Owner
);
516 length
= RtlLengthSid( src
->Group
);
517 dst
->Group
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
518 RtlCopySid(length
, dst
->Group
, src
->Group
);
520 if (src
->Control
& SE_SACL_PRESENT
)
522 length
= src
->Sacl
->AclSize
;
523 dst
->Sacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
524 copy_acl(length
, dst
->Sacl
, src
->Sacl
);
526 if (src
->Control
& SE_DACL_PRESENT
)
528 length
= src
->Dacl
->AclSize
;
529 dst
->Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
530 copy_acl(length
, dst
->Dacl
, src
->Dacl
);
534 return STATUS_SUCCESS
;
537 /**************************************************************************
538 * RtlValidSecurityDescriptor [NTDLL.@]
540 * Determine if a SECURITY_DESCRIPTOR is valid.
543 * SecurityDescriptor [I] Descriptor to check.
546 * Success: STATUS_SUCCESS.
547 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
549 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
550 PSECURITY_DESCRIPTOR SecurityDescriptor
)
552 if ( ! SecurityDescriptor
)
553 return STATUS_INVALID_SECURITY_DESCR
;
554 if ( ((SECURITY_DESCRIPTOR
*)SecurityDescriptor
)->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
555 return STATUS_UNKNOWN_REVISION
;
557 return STATUS_SUCCESS
;
560 /**************************************************************************
561 * RtlValidRelativeSecurityDescriptor [NTDLL.@]
563 BOOLEAN WINAPI
RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR descriptor
,
564 ULONG length
, SECURITY_INFORMATION info
)
566 FIXME("%p,%u,%d: semi-stub\n", descriptor
, length
, info
);
567 return RtlValidSecurityDescriptor(descriptor
) == STATUS_SUCCESS
;
570 /**************************************************************************
571 * RtlLengthSecurityDescriptor [NTDLL.@]
573 ULONG WINAPI
RtlLengthSecurityDescriptor(
574 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
578 if ( pSecurityDescriptor
== NULL
)
581 if (((SECURITY_DESCRIPTOR
*)pSecurityDescriptor
)->Control
& SE_SELF_RELATIVE
)
583 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
585 if (sd
->Owner
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Owner
));
586 if (sd
->Group
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Group
));
587 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
)
588 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Sacl
))->AclSize
;
589 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
)
590 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Dacl
))->AclSize
;
594 SECURITY_DESCRIPTOR
*sd
= pSecurityDescriptor
;
596 if (sd
->Owner
) size
+= RtlLengthSid( sd
->Owner
);
597 if (sd
->Group
) size
+= RtlLengthSid( sd
->Group
);
598 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
) size
+= sd
->Sacl
->AclSize
;
599 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
) size
+= sd
->Dacl
->AclSize
;
604 /******************************************************************************
605 * RtlGetDaclSecurityDescriptor [NTDLL.@]
608 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
609 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
610 OUT PBOOLEAN lpbDaclPresent
,
612 OUT PBOOLEAN lpbDaclDefaulted
)
614 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
616 TRACE("(%p,%p,%p,%p)\n",
617 pSecurityDescriptor
, lpbDaclPresent
, pDacl
, lpbDaclDefaulted
);
619 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
620 return STATUS_UNKNOWN_REVISION
;
622 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
624 if (lpsd
->Control
& SE_SELF_RELATIVE
)
626 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
627 if (sdr
->Dacl
) *pDacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Dacl
);
630 else *pDacl
= lpsd
->Dacl
;
632 *lpbDaclDefaulted
= (lpsd
->Control
& SE_DACL_DEFAULTED
) != 0;
637 *lpbDaclDefaulted
= 0;
640 return STATUS_SUCCESS
;
643 /**************************************************************************
644 * RtlSetDaclSecurityDescriptor [NTDLL.@]
646 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
647 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
650 BOOLEAN dacldefaulted
)
652 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
654 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
655 return STATUS_UNKNOWN_REVISION
;
656 if (lpsd
->Control
& SE_SELF_RELATIVE
)
657 return STATUS_INVALID_SECURITY_DESCR
;
661 lpsd
->Control
&= ~SE_DACL_PRESENT
;
662 return STATUS_SUCCESS
;
665 lpsd
->Control
|= SE_DACL_PRESENT
;
669 lpsd
->Control
|= SE_DACL_DEFAULTED
;
671 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
673 return STATUS_SUCCESS
;
676 /******************************************************************************
677 * RtlGetSaclSecurityDescriptor [NTDLL.@]
680 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
681 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
682 OUT PBOOLEAN lpbSaclPresent
,
684 OUT PBOOLEAN lpbSaclDefaulted
)
686 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
688 TRACE("(%p,%p,%p,%p)\n",
689 pSecurityDescriptor
, lpbSaclPresent
, pSacl
, lpbSaclDefaulted
);
691 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
692 return STATUS_UNKNOWN_REVISION
;
694 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
696 if (lpsd
->Control
& SE_SELF_RELATIVE
)
698 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
699 if (sdr
->Sacl
) *pSacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Sacl
);
702 else *pSacl
= lpsd
->Sacl
;
704 *lpbSaclDefaulted
= (lpsd
->Control
& SE_SACL_DEFAULTED
) != 0;
706 return STATUS_SUCCESS
;
709 /**************************************************************************
710 * RtlSetSaclSecurityDescriptor [NTDLL.@]
712 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
713 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
716 BOOLEAN sacldefaulted
)
718 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
720 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
721 return STATUS_UNKNOWN_REVISION
;
722 if (lpsd
->Control
& SE_SELF_RELATIVE
)
723 return STATUS_INVALID_SECURITY_DESCR
;
725 lpsd
->Control
&= ~SE_SACL_PRESENT
;
728 lpsd
->Control
|= SE_SACL_PRESENT
;
731 lpsd
->Control
|= SE_SACL_DEFAULTED
;
733 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
734 return STATUS_SUCCESS
;
737 /**************************************************************************
738 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
740 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
741 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
743 PBOOLEAN OwnerDefaulted
)
745 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
747 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
748 return STATUS_INVALID_PARAMETER
;
750 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
751 *OwnerDefaulted
= TRUE
;
753 *OwnerDefaulted
= FALSE
;
755 if (lpsd
->Control
& SE_SELF_RELATIVE
)
757 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
758 if (sd
->Owner
) *Owner
= (PSID
)SELF_RELATIVE_FIELD( sd
, Owner
);
762 *Owner
= lpsd
->Owner
;
764 return STATUS_SUCCESS
;
767 /**************************************************************************
768 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
770 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
771 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
773 BOOLEAN ownerdefaulted
)
775 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
777 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
778 return STATUS_UNKNOWN_REVISION
;
779 if (lpsd
->Control
& SE_SELF_RELATIVE
)
780 return STATUS_INVALID_SECURITY_DESCR
;
784 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
786 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
787 return STATUS_SUCCESS
;
790 /**************************************************************************
791 * RtlSetGroupSecurityDescriptor [NTDLL.@]
793 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
794 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
796 BOOLEAN groupdefaulted
)
798 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
800 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
801 return STATUS_UNKNOWN_REVISION
;
802 if (lpsd
->Control
& SE_SELF_RELATIVE
)
803 return STATUS_INVALID_SECURITY_DESCR
;
807 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
809 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
810 return STATUS_SUCCESS
;
813 /**************************************************************************
814 * RtlGetGroupSecurityDescriptor [NTDLL.@]
816 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
817 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
819 PBOOLEAN GroupDefaulted
)
821 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
823 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
824 return STATUS_INVALID_PARAMETER
;
826 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
827 *GroupDefaulted
= TRUE
;
829 *GroupDefaulted
= FALSE
;
831 if (lpsd
->Control
& SE_SELF_RELATIVE
)
833 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
834 if (sd
->Group
) *Group
= (PSID
)SELF_RELATIVE_FIELD( sd
, Group
);
838 *Group
= lpsd
->Group
;
840 return STATUS_SUCCESS
;
843 /**************************************************************************
844 * RtlMakeSelfRelativeSD [NTDLL.@]
846 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
847 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
848 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
849 IN OUT LPDWORD lpdwBufferLength
)
853 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
854 SECURITY_DESCRIPTOR_RELATIVE
*pRel
= pSelfRelativeSecurityDescriptor
;
856 TRACE(" %p %p %p(%d)\n", pAbs
, pRel
, lpdwBufferLength
,
857 lpdwBufferLength
? *lpdwBufferLength
: -1);
859 if (!lpdwBufferLength
|| !pAbs
)
860 return STATUS_INVALID_PARAMETER
;
862 length
= RtlLengthSecurityDescriptor(pAbs
);
863 if (!(pAbs
->Control
& SE_SELF_RELATIVE
)) length
-= (sizeof(*pAbs
) - sizeof(*pRel
));
864 if (*lpdwBufferLength
< length
)
866 *lpdwBufferLength
= length
;
867 return STATUS_BUFFER_TOO_SMALL
;
871 return STATUS_INVALID_PARAMETER
;
873 if (pAbs
->Control
& SE_SELF_RELATIVE
)
875 memcpy(pRel
, pAbs
, length
);
876 return STATUS_SUCCESS
;
879 pRel
->Revision
= pAbs
->Revision
;
880 pRel
->Sbz1
= pAbs
->Sbz1
;
881 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
883 offsetRel
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
886 pRel
->Owner
= offsetRel
;
887 length
= RtlLengthSid(pAbs
->Owner
);
888 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
898 pRel
->Group
= offsetRel
;
899 length
= RtlLengthSid(pAbs
->Group
);
900 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
910 pRel
->Sacl
= offsetRel
;
911 length
= pAbs
->Sacl
->AclSize
;
912 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
922 pRel
->Dacl
= offsetRel
;
923 length
= pAbs
->Dacl
->AclSize
;
924 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
931 return STATUS_SUCCESS
;
935 /**************************************************************************
936 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
938 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
939 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
940 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
941 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
943 OUT LPDWORD lpdwDaclSize
,
945 OUT LPDWORD lpdwSaclSize
,
947 OUT LPDWORD lpdwOwnerSize
,
948 OUT PSID pPrimaryGroup
,
949 OUT LPDWORD lpdwPrimaryGroupSize
)
951 NTSTATUS status
= STATUS_SUCCESS
;
952 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
953 SECURITY_DESCRIPTOR_RELATIVE
* pRel
= pSelfRelativeSecurityDescriptor
;
956 !lpdwAbsoluteSecurityDescriptorSize
||
960 !lpdwPrimaryGroupSize
||
961 ~pRel
->Control
& SE_SELF_RELATIVE
)
962 return STATUS_INVALID_PARAMETER
;
964 /* Confirm buffers are sufficiently large */
965 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
967 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
968 status
= STATUS_BUFFER_TOO_SMALL
;
971 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
&&
972 *lpdwDaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
)
974 *lpdwDaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
;
975 status
= STATUS_BUFFER_TOO_SMALL
;
978 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
&&
979 *lpdwSaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
)
981 *lpdwSaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
;
982 status
= STATUS_BUFFER_TOO_SMALL
;
986 *lpdwOwnerSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
)))
988 *lpdwOwnerSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
));
989 status
= STATUS_BUFFER_TOO_SMALL
;
993 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
)))
995 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
));
996 status
= STATUS_BUFFER_TOO_SMALL
;
999 if (status
!= STATUS_SUCCESS
)
1002 /* Copy structures, and clear the ones we don't set */
1003 pAbs
->Revision
= pRel
->Revision
;
1004 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
1010 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
)
1012 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Sacl
);
1014 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
1018 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
)
1020 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Dacl
);
1021 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
1027 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Owner
);
1028 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
1029 pAbs
->Owner
= pOwner
;
1034 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Group
);
1035 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
1036 pAbs
->Group
= pPrimaryGroup
;
1042 /******************************************************************************
1043 * RtlGetControlSecurityDescriptor (NTDLL.@)
1045 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1046 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1047 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1048 LPDWORD lpdwRevision
)
1050 SECURITY_DESCRIPTOR
*lpsd
= pSecurityDescriptor
;
1052 TRACE("(%p,%p,%p)\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1054 *lpdwRevision
= lpsd
->Revision
;
1056 if (*lpdwRevision
!= SECURITY_DESCRIPTOR_REVISION
)
1057 return STATUS_UNKNOWN_REVISION
;
1059 *pControl
= lpsd
->Control
;
1061 return STATUS_SUCCESS
;
1064 /******************************************************************************
1065 * RtlSetControlSecurityDescriptor (NTDLL.@)
1067 NTSTATUS WINAPI
RtlSetControlSecurityDescriptor(
1068 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1069 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
1070 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
1072 SECURITY_DESCRIPTOR_CONTROL
const immutable
1073 = SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
1074 | SE_DACL_PRESENT
| SE_DACL_DEFAULTED
1075 | SE_SACL_PRESENT
| SE_SACL_DEFAULTED
1076 | SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
1079 SECURITY_DESCRIPTOR
*lpsd
= SecurityDescriptor
;
1081 TRACE("(%p 0x%04x 0x%04x)\n", SecurityDescriptor
,
1082 ControlBitsOfInterest
, ControlBitsToSet
);
1084 if ((ControlBitsOfInterest
| ControlBitsToSet
) & immutable
)
1085 return STATUS_INVALID_PARAMETER
;
1087 lpsd
->Control
|= (ControlBitsOfInterest
& ControlBitsToSet
);
1088 lpsd
->Control
&= ~(ControlBitsOfInterest
& ~ControlBitsToSet
);
1090 return STATUS_SUCCESS
;
1094 /**************************************************************************
1095 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1097 NTSTATUS WINAPI
RtlAbsoluteToSelfRelativeSD(
1098 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
1099 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
1100 PULONG BufferLength
)
1102 SECURITY_DESCRIPTOR
*abs
= AbsoluteSecurityDescriptor
;
1104 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor
,
1105 SelfRelativeSecurityDescriptor
, BufferLength
);
1107 if (abs
->Control
& SE_SELF_RELATIVE
)
1108 return STATUS_BAD_DESCRIPTOR_FORMAT
;
1110 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
1111 SelfRelativeSecurityDescriptor
, BufferLength
);
1116 * access control list's
1119 /**************************************************************************
1120 * RtlCreateAcl [NTDLL.@]
1123 * This should return NTSTATUS
1125 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
1127 TRACE("%p 0x%08x 0x%08x\n", acl
, size
, rev
);
1129 if (rev
< MIN_ACL_REVISION
|| rev
> MAX_ACL_REVISION
)
1130 return STATUS_INVALID_PARAMETER
;
1131 if (size
<sizeof(ACL
))
1132 return STATUS_BUFFER_TOO_SMALL
;
1134 return STATUS_INVALID_PARAMETER
;
1136 memset(acl
,'\0',sizeof(ACL
));
1137 acl
->AclRevision
= rev
;
1138 acl
->AclSize
= size
;
1140 return STATUS_SUCCESS
;
1143 /**************************************************************************
1144 * RtlFirstFreeAce [NTDLL.@]
1145 * looks for the AceCount+1 ACE, and if it is still within the alloced
1146 * ACL, return a pointer to it
1148 BOOLEAN WINAPI
RtlFirstFreeAce(
1156 ace
= (PACE_HEADER
)(acl
+1);
1157 for (i
=0;i
<acl
->AceCount
;i
++) {
1158 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1160 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1162 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1168 /**************************************************************************
1169 * RtlAddAce [NTDLL.@]
1171 NTSTATUS WINAPI
RtlAddAce(
1175 PACE_HEADER acestart
,
1178 PACE_HEADER ace
,targetace
;
1181 if (!RtlValidAcl(acl
))
1182 return STATUS_INVALID_PARAMETER
;
1183 if (!RtlFirstFreeAce(acl
,&targetace
))
1184 return STATUS_INVALID_PARAMETER
;
1185 nrofaces
=0;ace
=acestart
;
1186 while (((BYTE
*)ace
- (BYTE
*)acestart
) < acelen
) {
1188 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1190 if ((BYTE
*)targetace
+ acelen
> (BYTE
*)acl
+ acl
->AclSize
) /* too much aces */
1191 return STATUS_INVALID_PARAMETER
;
1192 memcpy(targetace
,acestart
,acelen
);
1193 acl
->AceCount
+=nrofaces
;
1194 if (rev
> acl
->AclRevision
)
1195 acl
->AclRevision
= rev
;
1196 return STATUS_SUCCESS
;
1199 /**************************************************************************
1200 * RtlDeleteAce [NTDLL.@]
1202 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1207 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
1209 if (STATUS_SUCCESS
== status
)
1214 /* skip over the ACE we are deleting */
1215 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
1218 /* calculate the length of the rest */
1219 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
1221 len
+= pcAce
->AceSize
;
1222 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
1225 /* slide them all backwards */
1226 memmove(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
1230 TRACE("pAcl=%p dwAceIndex=%d status=0x%08x\n", pAcl
, dwAceIndex
, status
);
1235 /******************************************************************************
1236 * RtlAddAccessAllowedAce [NTDLL.@]
1238 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
1240 IN DWORD dwAceRevision
,
1241 IN DWORD AccessMask
,
1244 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1247 /******************************************************************************
1248 * RtlAddAccessAllowedAceEx [NTDLL.@]
1250 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
1252 IN DWORD dwAceRevision
,
1254 IN DWORD AccessMask
,
1257 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1259 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1260 AccessMask
, pSid
, ACCESS_ALLOWED_ACE_TYPE
);
1263 /******************************************************************************
1264 * RtlAddAccessAllowedObjectAce [NTDLL.@]
1266 NTSTATUS WINAPI
RtlAddAccessAllowedObjectAce(
1268 IN DWORD dwAceRevision
,
1269 IN DWORD dwAceFlags
,
1270 IN DWORD dwAccessMask
,
1271 IN GUID
* pObjectTypeGuid
,
1272 IN GUID
* pInheritedObjectTypeGuid
,
1275 FIXME("%p %x %x %x %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1276 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1277 return STATUS_NOT_IMPLEMENTED
;
1280 /******************************************************************************
1281 * RtlAddAccessDeniedAce [NTDLL.@]
1283 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1285 IN DWORD dwAceRevision
,
1286 IN DWORD AccessMask
,
1289 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1292 /******************************************************************************
1293 * RtlAddAccessDeniedAceEx [NTDLL.@]
1295 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1297 IN DWORD dwAceRevision
,
1299 IN DWORD AccessMask
,
1302 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1304 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1305 AccessMask
, pSid
, ACCESS_DENIED_ACE_TYPE
);
1308 /******************************************************************************
1309 * RtlAddAccessDeniedObjectAce [NTDLL.@]
1311 NTSTATUS WINAPI
RtlAddAccessDeniedObjectAce(
1313 IN DWORD dwAceRevision
,
1314 IN DWORD dwAceFlags
,
1315 IN DWORD dwAccessMask
,
1316 IN GUID
* pObjectTypeGuid
,
1317 IN GUID
* pInheritedObjectTypeGuid
,
1320 FIXME("%p %x %x %x %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1321 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1322 return STATUS_NOT_IMPLEMENTED
;
1325 /**************************************************************************
1326 * RtlAddAuditAccessAce [NTDLL.@]
1328 NTSTATUS WINAPI
RtlAddAuditAccessAceEx(
1330 IN DWORD dwAceRevision
,
1331 IN DWORD dwAceFlags
,
1332 IN DWORD dwAccessMask
,
1334 IN BOOL bAuditSuccess
,
1335 IN BOOL bAuditFailure
)
1337 TRACE("(%p,%d,0x%08x,0x%08x,%p,%u,%u)\n",pAcl
,dwAceRevision
,dwAceFlags
,dwAccessMask
,
1338 pSid
,bAuditSuccess
,bAuditFailure
);
1341 dwAceFlags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
1344 dwAceFlags
|= FAILED_ACCESS_ACE_FLAG
;
1346 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
,
1347 dwAccessMask
, pSid
, SYSTEM_AUDIT_ACE_TYPE
);
1350 /**************************************************************************
1351 * RtlAddAuditAccessAce [NTDLL.@]
1353 NTSTATUS WINAPI
RtlAddAuditAccessAce(
1355 IN DWORD dwAceRevision
,
1356 IN DWORD dwAccessMask
,
1358 IN BOOL bAuditSuccess
,
1359 IN BOOL bAuditFailure
)
1361 return RtlAddAuditAccessAceEx(pAcl
, dwAceRevision
, 0, dwAccessMask
, pSid
, bAuditSuccess
, bAuditFailure
);
1364 /******************************************************************************
1365 * RtlAddAuditAccessObjectAce [NTDLL.@]
1367 NTSTATUS WINAPI
RtlAddAuditAccessObjectAce(
1369 IN DWORD dwAceRevision
,
1370 IN DWORD dwAceFlags
,
1371 IN DWORD dwAccessMask
,
1372 IN GUID
* pObjectTypeGuid
,
1373 IN GUID
* pInheritedObjectTypeGuid
,
1375 IN BOOL bAuditSuccess
,
1376 IN BOOL bAuditFailure
)
1378 FIXME("%p %x %x %x %p %p %p %d %d - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1379 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
, bAuditSuccess
, bAuditFailure
);
1380 return STATUS_NOT_IMPLEMENTED
;
1383 /**************************************************************************
1384 * RtlAddMandatoryAce [NTDLL.@]
1386 NTSTATUS WINAPI
RtlAddMandatoryAce(
1388 IN DWORD dwAceRevision
,
1389 IN DWORD dwAceFlags
,
1390 IN DWORD dwMandatoryFlags
,
1394 static const DWORD valid_flags
= SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
|
1395 SYSTEM_MANDATORY_LABEL_NO_READ_UP
|
1396 SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP
;
1398 TRACE("(%p, %u, 0x%08x, 0x%08x, %u, %p)\n", pAcl
, dwAceRevision
, dwAceFlags
,
1399 dwMandatoryFlags
, dwAceType
, pSid
);
1401 if (dwAceType
!= SYSTEM_MANDATORY_LABEL_ACE_TYPE
)
1402 return STATUS_INVALID_PARAMETER
;
1404 if (dwMandatoryFlags
& ~valid_flags
)
1405 return STATUS_INVALID_PARAMETER
;
1407 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
, dwMandatoryFlags
, pSid
, dwAceType
);
1410 /******************************************************************************
1411 * RtlValidAcl [NTDLL.@]
1413 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1416 TRACE("(%p)\n", pAcl
);
1423 if (pAcl
->AclRevision
< MIN_ACL_REVISION
||
1424 pAcl
->AclRevision
> MAX_ACL_REVISION
)
1428 ace
= (PACE_HEADER
)(pAcl
+1);
1430 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1432 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1437 if (i
!= pAcl
->AceCount
)
1438 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1444 WARN("(%p): invalid pointer!\n", pAcl
);
1451 /******************************************************************************
1452 * RtlGetAce [NTDLL.@]
1454 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1458 TRACE("(%p,%d,%p)\n",pAcl
,dwAceIndex
,pAce
);
1460 if (dwAceIndex
>= pAcl
->AceCount
)
1461 return STATUS_INVALID_PARAMETER
;
1463 ace
= (PACE_HEADER
)(pAcl
+ 1);
1464 for (;dwAceIndex
;dwAceIndex
--)
1465 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1469 return STATUS_SUCCESS
;
1476 /******************************************************************************
1477 * RtlAdjustPrivilege [NTDLL.@]
1479 * Enables or disables a privilege from the calling thread or process.
1482 * Privilege [I] Privilege index to change.
1483 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1484 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1485 * Enabled [O] Whether privilege was previously enabled or disabled.
1488 * Success: STATUS_SUCCESS.
1489 * Failure: NTSTATUS code.
1492 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1496 RtlAdjustPrivilege(ULONG Privilege
,
1498 BOOLEAN CurrentThread
,
1501 TOKEN_PRIVILEGES NewState
;
1502 TOKEN_PRIVILEGES OldState
;
1507 TRACE("(%d, %s, %s, %p)\n", Privilege
, Enable
? "TRUE" : "FALSE",
1508 CurrentThread
? "TRUE" : "FALSE", Enabled
);
1512 Status
= NtOpenThreadToken(GetCurrentThread(),
1513 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1519 Status
= NtOpenProcessToken(GetCurrentProcess(),
1520 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1524 if (!NT_SUCCESS(Status
))
1526 WARN("Retrieving token handle failed (Status %x)\n", Status
);
1530 OldState
.PrivilegeCount
= 1;
1532 NewState
.PrivilegeCount
= 1;
1533 NewState
.Privileges
[0].Luid
.LowPart
= Privilege
;
1534 NewState
.Privileges
[0].Luid
.HighPart
= 0;
1535 NewState
.Privileges
[0].Attributes
= (Enable
) ? SE_PRIVILEGE_ENABLED
: 0;
1537 Status
= NtAdjustPrivilegesToken(TokenHandle
,
1540 sizeof(TOKEN_PRIVILEGES
),
1543 NtClose (TokenHandle
);
1544 if (Status
== STATUS_NOT_ALL_ASSIGNED
)
1546 TRACE("Failed to assign all privileges\n");
1547 return STATUS_PRIVILEGE_NOT_HELD
;
1549 if (!NT_SUCCESS(Status
))
1551 WARN("NtAdjustPrivilegesToken() failed (Status %x)\n", Status
);
1555 if (OldState
.PrivilegeCount
== 0)
1558 *Enabled
= (OldState
.Privileges
[0].Attributes
& SE_PRIVILEGE_ENABLED
);
1560 return STATUS_SUCCESS
;
1563 /******************************************************************************
1564 * RtlImpersonateSelf [NTDLL.@]
1566 * Makes an impersonation token that represents the process user and assigns
1567 * to the current thread.
1570 * ImpersonationLevel [I] Level at which to impersonate.
1573 * Success: STATUS_SUCCESS.
1574 * Failure: NTSTATUS code.
1577 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1580 OBJECT_ATTRIBUTES ObjectAttributes
;
1581 HANDLE ProcessToken
;
1582 HANDLE ImpersonationToken
;
1584 TRACE("(%08x)\n", ImpersonationLevel
);
1586 Status
= NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE
,
1588 if (Status
!= STATUS_SUCCESS
)
1591 InitializeObjectAttributes( &ObjectAttributes
, NULL
, 0, NULL
, NULL
);
1593 Status
= NtDuplicateToken( ProcessToken
,
1598 &ImpersonationToken
);
1599 if (Status
!= STATUS_SUCCESS
)
1601 NtClose( ProcessToken
);
1605 Status
= NtSetInformationThread( GetCurrentThread(),
1606 ThreadImpersonationToken
,
1607 &ImpersonationToken
,
1608 sizeof(ImpersonationToken
) );
1610 NtClose( ImpersonationToken
);
1611 NtClose( ProcessToken
);
1616 /******************************************************************************
1617 * NtImpersonateAnonymousToken [NTDLL.@]
1620 NtImpersonateAnonymousToken(HANDLE thread
)
1622 FIXME("(%p): stub\n", thread
);
1623 return STATUS_NOT_IMPLEMENTED
;
1626 /******************************************************************************
1627 * NtAccessCheck [NTDLL.@]
1628 * ZwAccessCheck [NTDLL.@]
1630 * Checks that a user represented by a token is allowed to access an object
1631 * represented by a security descriptor.
1634 * SecurityDescriptor [I] The security descriptor of the object to check.
1635 * ClientToken [I] Token of the user accessing the object.
1636 * DesiredAccess [I] The desired access to the object.
1637 * GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
1638 * PrivilegeSet [I/O] Privileges used during the access check.
1639 * ReturnLength [O] Number of bytes stored into PrivilegeSet.
1640 * GrantedAccess [O] The actual access rights granted.
1641 * AccessStatus [O] The status of the access check.
1647 * DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
1648 * the maximum access rights allowed by the SD and returns them in
1650 * The SecurityDescriptor must have a valid owner and groups present,
1651 * otherwise the function will fail.
1655 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1657 ACCESS_MASK DesiredAccess
,
1658 PGENERIC_MAPPING GenericMapping
,
1659 PPRIVILEGE_SET PrivilegeSet
,
1660 PULONG ReturnLength
,
1661 PULONG GrantedAccess
,
1662 NTSTATUS
*AccessStatus
)
1666 TRACE("(%p, %p, %08x, %p, %p, %p, %p, %p)\n",
1667 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
1668 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
1670 if (!PrivilegeSet
|| !ReturnLength
)
1671 return STATUS_ACCESS_VIOLATION
;
1673 SERVER_START_REQ( access_check
)
1675 struct security_descriptor sd
;
1680 BOOLEAN defaulted
, present
;
1682 SECURITY_DESCRIPTOR_CONTROL control
;
1684 req
->handle
= wine_server_obj_handle( ClientToken
);
1685 req
->desired_access
= DesiredAccess
;
1686 req
->mapping_read
= GenericMapping
->GenericRead
;
1687 req
->mapping_write
= GenericMapping
->GenericWrite
;
1688 req
->mapping_execute
= GenericMapping
->GenericExecute
;
1689 req
->mapping_all
= GenericMapping
->GenericAll
;
1691 /* marshal security descriptor */
1692 RtlGetControlSecurityDescriptor( SecurityDescriptor
, &control
, &revision
);
1693 sd
.control
= control
& ~SE_SELF_RELATIVE
;
1694 RtlGetOwnerSecurityDescriptor( SecurityDescriptor
, &owner
, &defaulted
);
1695 sd
.owner_len
= RtlLengthSid( owner
);
1696 RtlGetGroupSecurityDescriptor( SecurityDescriptor
, &group
, &defaulted
);
1697 sd
.group_len
= RtlLengthSid( group
);
1698 RtlGetSaclSecurityDescriptor( SecurityDescriptor
, &present
, &sacl
, &defaulted
);
1699 sd
.sacl_len
= ((present
&& sacl
) ? acl_bytesInUse(sacl
) : 0);
1700 RtlGetDaclSecurityDescriptor( SecurityDescriptor
, &present
, &dacl
, &defaulted
);
1701 sd
.dacl_len
= ((present
&& dacl
) ? acl_bytesInUse(dacl
) : 0);
1703 wine_server_add_data( req
, &sd
, sizeof(sd
) );
1704 wine_server_add_data( req
, owner
, sd
.owner_len
);
1705 wine_server_add_data( req
, group
, sd
.group_len
);
1706 wine_server_add_data( req
, sacl
, sd
.sacl_len
);
1707 wine_server_add_data( req
, dacl
, sd
.dacl_len
);
1709 wine_server_set_reply( req
, PrivilegeSet
->Privilege
, *ReturnLength
- FIELD_OFFSET( PRIVILEGE_SET
, Privilege
) );
1711 status
= wine_server_call( req
);
1713 *ReturnLength
= FIELD_OFFSET( PRIVILEGE_SET
, Privilege
) + reply
->privileges_len
;
1714 PrivilegeSet
->PrivilegeCount
= reply
->privileges_len
/ sizeof(LUID_AND_ATTRIBUTES
);
1716 if (status
== STATUS_SUCCESS
)
1718 *AccessStatus
= reply
->access_status
;
1719 *GrantedAccess
= reply
->access_granted
;
1727 /******************************************************************************
1728 * NtSetSecurityObject [NTDLL.@]
1729 * ZwSetSecurityObject [NTDLL.@]
1731 * Sets specified parts of the object's security descriptor.
1734 * Handle [I] Handle to the object to change security descriptor of.
1735 * SecurityInformation [I] Specifies which parts of the security descriptor to set.
1736 * SecurityDescriptor [I] New parts of a security descriptor for the object.
1742 NTSTATUS WINAPI
NtSetSecurityObject(HANDLE Handle
,
1743 SECURITY_INFORMATION SecurityInformation
,
1744 PSECURITY_DESCRIPTOR SecurityDescriptor
)
1747 struct security_descriptor sd
;
1748 PACL dacl
= NULL
, sacl
= NULL
;
1749 PSID owner
= NULL
, group
= NULL
;
1750 BOOLEAN defaulted
, present
;
1752 SECURITY_DESCRIPTOR_CONTROL control
;
1754 TRACE("%p 0x%08x %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
1756 if (!SecurityDescriptor
) return STATUS_ACCESS_VIOLATION
;
1758 memset( &sd
, 0, sizeof(sd
) );
1759 status
= RtlGetControlSecurityDescriptor( SecurityDescriptor
, &control
, &revision
);
1760 if (status
!= STATUS_SUCCESS
) return status
;
1761 sd
.control
= control
& ~SE_SELF_RELATIVE
;
1763 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
1765 status
= RtlGetOwnerSecurityDescriptor( SecurityDescriptor
, &owner
, &defaulted
);
1766 if (status
!= STATUS_SUCCESS
) return status
;
1767 if (!(sd
.owner_len
= RtlLengthSid( owner
)))
1768 return STATUS_INVALID_SECURITY_DESCR
;
1771 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
1773 status
= RtlGetGroupSecurityDescriptor( SecurityDescriptor
, &group
, &defaulted
);
1774 if (status
!= STATUS_SUCCESS
) return status
;
1775 if (!(sd
.group_len
= RtlLengthSid( group
)))
1776 return STATUS_INVALID_SECURITY_DESCR
;
1779 if (SecurityInformation
& SACL_SECURITY_INFORMATION
||
1780 SecurityInformation
& LABEL_SECURITY_INFORMATION
)
1782 status
= RtlGetSaclSecurityDescriptor( SecurityDescriptor
, &present
, &sacl
, &defaulted
);
1783 if (status
!= STATUS_SUCCESS
) return status
;
1784 sd
.sacl_len
= (sacl
&& present
) ? acl_bytesInUse(sacl
) : 0;
1785 sd
.control
|= SE_SACL_PRESENT
;
1788 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
1790 status
= RtlGetDaclSecurityDescriptor( SecurityDescriptor
, &present
, &dacl
, &defaulted
);
1791 if (status
!= STATUS_SUCCESS
) return status
;
1792 sd
.dacl_len
= (dacl
&& present
) ? acl_bytesInUse(dacl
) : 0;
1793 sd
.control
|= SE_DACL_PRESENT
;
1796 SERVER_START_REQ( set_security_object
)
1798 req
->handle
= wine_server_obj_handle( Handle
);
1799 req
->security_info
= SecurityInformation
;
1801 wine_server_add_data( req
, &sd
, sizeof(sd
) );
1802 wine_server_add_data( req
, owner
, sd
.owner_len
);
1803 wine_server_add_data( req
, group
, sd
.group_len
);
1804 wine_server_add_data( req
, sacl
, sd
.sacl_len
);
1805 wine_server_add_data( req
, dacl
, sd
.dacl_len
);
1806 status
= wine_server_call( req
);
1813 /******************************************************************************
1814 * RtlConvertSidToUnicodeString (NTDLL.@)
1816 * The returned SID is used to access the USER registry hive usually
1818 * the native function returns something like
1819 * "S-1-5-21-0000000000-000000000-0000000000-500";
1821 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1822 PUNICODE_STRING String
,
1824 BOOLEAN AllocateString
)
1826 static const WCHAR formatW
[] = {'-','%','u',0};
1827 WCHAR buffer
[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES
];
1829 const SID
*sid
= pSid
;
1833 p
+= sprintfW( p
, formatW
, sid
->Revision
);
1834 p
+= sprintfW( p
, formatW
, MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
1835 sid
->IdentifierAuthority
.Value
[4] ),
1836 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
1837 sid
->IdentifierAuthority
.Value
[2] )));
1838 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
1839 p
+= sprintfW( p
, formatW
, sid
->SubAuthority
[i
] );
1841 len
= (p
+ 1 - buffer
) * sizeof(WCHAR
);
1843 String
->Length
= len
- sizeof(WCHAR
);
1846 String
->MaximumLength
= len
;
1847 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1848 return STATUS_NO_MEMORY
;
1850 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1852 memcpy( String
->Buffer
, buffer
, len
);
1853 return STATUS_SUCCESS
;
1856 /******************************************************************************
1857 * RtlQueryInformationAcl (NTDLL.@)
1859 NTSTATUS WINAPI
RtlQueryInformationAcl(
1861 LPVOID pAclInformation
,
1862 DWORD nAclInformationLength
,
1863 ACL_INFORMATION_CLASS dwAclInformationClass
)
1865 NTSTATUS status
= STATUS_SUCCESS
;
1867 TRACE("pAcl=%p pAclInfo=%p len=%d, class=%d\n",
1868 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1870 switch (dwAclInformationClass
)
1872 case AclRevisionInformation
:
1874 PACL_REVISION_INFORMATION paclrev
= pAclInformation
;
1876 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1877 status
= STATUS_INVALID_PARAMETER
;
1879 paclrev
->AclRevision
= pAcl
->AclRevision
;
1884 case AclSizeInformation
:
1886 PACL_SIZE_INFORMATION paclsize
= pAclInformation
;
1888 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1889 status
= STATUS_INVALID_PARAMETER
;
1892 paclsize
->AceCount
= pAcl
->AceCount
;
1893 paclsize
->AclBytesInUse
= acl_bytesInUse(pAcl
);
1894 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1896 WARN("Acl uses %d bytes, but only has %d allocated! Returning smaller of the two values.\n", pAcl
->AclSize
, paclsize
->AclBytesInUse
);
1897 paclsize
->AclBytesFree
= 0;
1898 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1901 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1908 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1909 status
= STATUS_INVALID_PARAMETER
;
1915 BOOL WINAPI
RtlConvertToAutoInheritSecurityObject(
1916 PSECURITY_DESCRIPTOR pdesc
,
1917 PSECURITY_DESCRIPTOR cdesc
,
1918 PSECURITY_DESCRIPTOR
* ndesc
,
1921 PGENERIC_MAPPING genmap
)
1923 FIXME("%p %p %p %p %d %p - stub\n", pdesc
, cdesc
, ndesc
, objtype
, isdir
, genmap
);