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
30 #define WIN32_NO_STATUS
32 #include "ntdll_misc.h"
33 #include "wine/exception.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
38 #define SELF_RELATIVE_FIELD(sd,field) ((BYTE *)(sd) + ((SECURITY_DESCRIPTOR_RELATIVE *)(sd))->field)
40 static const SID world_sid
= { SID_REVISION
, 1, { SECURITY_WORLD_SID_AUTHORITY
} , { SECURITY_WORLD_RID
} };
41 static const DWORD world_access_acl_size
= sizeof(ACL
) + sizeof(ACCESS_ALLOWED_ACE
) + sizeof(world_sid
) - sizeof(DWORD
);
43 static void get_world_access_acl( PACL acl
)
45 PACCESS_ALLOWED_ACE ace
= (PACCESS_ALLOWED_ACE
)(acl
+ 1);
47 acl
->AclRevision
= ACL_REVISION
;
49 acl
->AclSize
= world_access_acl_size
;
52 ace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
53 ace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
;
54 ace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
) + sizeof(world_sid
) - sizeof(DWORD
);
55 ace
->Mask
= 0xf3ffffff; /* Everything except reserved bits */
56 memcpy( &ace
->SidStart
, &world_sid
, sizeof(world_sid
) );
59 /* helper function to retrieve active length of an ACL */
60 static size_t acl_bytesInUse(PACL pAcl
)
63 size_t bytesInUse
= sizeof(ACL
);
64 PACE_HEADER ace
= (PACE_HEADER
) (pAcl
+ 1);
65 for (i
= 0; i
< pAcl
->AceCount
; i
++)
67 bytesInUse
+= ace
->AceSize
;
68 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
73 /* helper function to copy an ACL */
74 static BOOLEAN
copy_acl(DWORD nDestinationAclLength
, PACL pDestinationAcl
, PACL pSourceAcl
)
78 if (!pSourceAcl
|| !RtlValidAcl(pSourceAcl
))
81 size
= pSourceAcl
->AclSize
;
82 if (nDestinationAclLength
< size
)
85 memmove(pDestinationAcl
, pSourceAcl
, size
);
89 /* generically adds an ACE to an ACL */
90 static NTSTATUS
add_access_ace(PACL pAcl
, DWORD dwAceRevision
, DWORD dwAceFlags
,
91 DWORD dwAccessMask
, PSID pSid
, DWORD dwAceType
)
93 ACE_HEADER
*pAceHeader
;
99 if (!RtlValidSid(pSid
))
100 return STATUS_INVALID_SID
;
102 if (pAcl
->AclRevision
> MAX_ACL_REVISION
|| dwAceRevision
> MAX_ACL_REVISION
)
103 return STATUS_REVISION_MISMATCH
;
105 if (!RtlValidAcl(pAcl
))
106 return STATUS_INVALID_ACL
;
108 if (!RtlFirstFreeAce(pAcl
, &pAceHeader
))
109 return STATUS_INVALID_ACL
;
112 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
114 /* calculate generic size of the ACE */
115 dwLengthSid
= RtlLengthSid(pSid
);
116 dwAceSize
= sizeof(ACE_HEADER
) + sizeof(DWORD
) + dwLengthSid
;
117 if ((char *)pAceHeader
+ dwAceSize
> (char *)pAcl
+ pAcl
->AclSize
)
118 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
120 /* fill the new ACE */
121 pAceHeader
->AceType
= dwAceType
;
122 pAceHeader
->AceFlags
= dwAceFlags
;
123 pAceHeader
->AceSize
= dwAceSize
;
125 /* skip past the ACE_HEADER of the ACE */
126 pAccessMask
= (DWORD
*)(pAceHeader
+ 1);
127 *pAccessMask
= dwAccessMask
;
129 /* skip past ACE->Mask */
130 pSidStart
= pAccessMask
+ 1;
131 RtlCopySid(dwLengthSid
, pSidStart
, pSid
);
133 pAcl
->AclRevision
= max(pAcl
->AclRevision
, dwAceRevision
);
136 return STATUS_SUCCESS
;
143 /******************************************************************************
144 * RtlAllocateAndInitializeSid [NTDLL.@]
147 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
148 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
149 BYTE nSubAuthorityCount
,
150 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
151 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
152 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
153 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
158 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
159 pIdentifierAuthority
,nSubAuthorityCount
,
160 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
161 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
163 if (nSubAuthorityCount
> 8) return STATUS_INVALID_SID
;
165 if (!(tmp_sid
= RtlAllocateHeap( GetProcessHeap(), 0,
166 RtlLengthRequiredSid(nSubAuthorityCount
))))
167 return STATUS_NO_MEMORY
;
169 tmp_sid
->Revision
= SID_REVISION
;
171 if (pIdentifierAuthority
)
172 tmp_sid
->IdentifierAuthority
= *pIdentifierAuthority
;
173 tmp_sid
->SubAuthorityCount
= nSubAuthorityCount
;
175 switch( nSubAuthorityCount
)
177 case 8: tmp_sid
->SubAuthority
[7]= nSubAuthority7
;
179 case 7: tmp_sid
->SubAuthority
[6]= nSubAuthority6
;
181 case 6: tmp_sid
->SubAuthority
[5]= nSubAuthority5
;
183 case 5: tmp_sid
->SubAuthority
[4]= nSubAuthority4
;
185 case 4: tmp_sid
->SubAuthority
[3]= nSubAuthority3
;
187 case 3: tmp_sid
->SubAuthority
[2]= nSubAuthority2
;
189 case 2: tmp_sid
->SubAuthority
[1]= nSubAuthority1
;
191 case 1: tmp_sid
->SubAuthority
[0]= nSubAuthority0
;
195 return STATUS_SUCCESS
;
198 /******************************************************************************
199 * RtlEqualSid [NTDLL.@]
201 * Determine if two SIDs are equal.
204 * pSid1 [I] Source SID
205 * pSid2 [I] SID to compare with
208 * TRUE, if pSid1 is equal to pSid2,
211 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
213 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
216 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
219 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
225 /******************************************************************************
226 * RtlEqualPrefixSid [NTDLL.@]
228 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
230 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
233 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
236 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
243 /******************************************************************************
244 * RtlFreeSid [NTDLL.@]
246 * Free the resources used by a SID.
249 * pSid [I] SID to Free.
254 DWORD WINAPI
RtlFreeSid(PSID pSid
)
256 TRACE("(%p)\n", pSid
);
257 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
258 return STATUS_SUCCESS
;
261 /**************************************************************************
262 * RtlLengthRequiredSid [NTDLL.@]
264 * Determine the amount of memory a SID will use
267 * nrofsubauths [I] Number of Sub Authorities in the SID.
270 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
272 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
274 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
277 /**************************************************************************
278 * RtlLengthSid [NTDLL.@]
280 * Determine the amount of memory a SID is using
283 * pSid [I] SID to get the size of.
286 * The size, in bytes, of pSid.
288 DWORD WINAPI
RtlLengthSid(PSID pSid
)
290 TRACE("sid=%p\n",pSid
);
292 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
295 /**************************************************************************
296 * RtlInitializeSid [NTDLL.@]
298 NTSTATUS WINAPI
RtlInitializeSid(
300 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
301 BYTE nSubAuthorityCount
)
306 if (nSubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
307 return STATUS_INVALID_PARAMETER
;
309 pisid
->Revision
= SID_REVISION
;
310 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
311 if (pIdentifierAuthority
)
312 pisid
->IdentifierAuthority
= *pIdentifierAuthority
;
314 for (i
= 0; i
< nSubAuthorityCount
; i
++)
315 *RtlSubAuthoritySid(pSid
, i
) = 0;
317 return STATUS_SUCCESS
;
320 /**************************************************************************
321 * RtlSubAuthoritySid [NTDLL.@]
323 * Return the Sub Authority of a SID
326 * pSid [I] SID to get the Sub Authority from.
327 * nSubAuthority [I] Sub Authority number.
330 * A pointer to The Sub Authority value of pSid.
332 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
334 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
337 /**************************************************************************
338 * RtlIdentifierAuthoritySid [NTDLL.@]
340 * Return the Identifier Authority of a SID.
343 * pSid [I] SID to get the Identifier Authority from.
346 * A pointer to the Identifier Authority value of pSid.
348 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
350 return &(((SID
*)pSid
)->IdentifierAuthority
);
353 /**************************************************************************
354 * RtlSubAuthorityCountSid [NTDLL.@]
356 * Get the number of Sub Authorities in a SID.
359 * pSid [I] SID to get the count from.
362 * A pointer to the Sub Authority count of pSid.
364 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
366 return &(((SID
*)pSid
)->SubAuthorityCount
);
369 /**************************************************************************
370 * RtlCopySid [NTDLL.@]
372 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
374 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
375 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
378 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
381 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
384 /******************************************************************************
385 * RtlValidSid [NTDLL.@]
387 * Determine if a SID is valid.
390 * pSid [I] SID to check
393 * TRUE if pSid is valid,
396 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
402 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
403 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
410 WARN("(%p): invalid pointer!\n", pSid
);
419 * security descriptor functions
422 /**************************************************************************
423 * RtlCreateSecurityDescriptor [NTDLL.@]
425 * Initialise a SECURITY_DESCRIPTOR.
428 * lpsd [O] Descriptor to initialise.
429 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
432 * Success: STATUS_SUCCESS.
433 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
435 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
436 PSECURITY_DESCRIPTOR lpsd
,
439 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
440 return STATUS_UNKNOWN_REVISION
;
441 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
442 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
443 return STATUS_SUCCESS
;
446 /**************************************************************************
447 * RtlCopySecurityDescriptor [NTDLL.@]
449 * Copies an absolute or self-relative SECURITY_DESCRIPTOR.
452 * pSourceSD [O] SD to copy from.
453 * pDestinationSD [I] Destination SD.
456 * Success: STATUS_SUCCESS.
457 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
459 NTSTATUS WINAPI
RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD
, PSECURITY_DESCRIPTOR pDestinationSD
)
465 if (((SECURITY_DESCRIPTOR
*)pSourceSD
)->Control
& SE_SELF_RELATIVE
)
467 SECURITY_DESCRIPTOR_RELATIVE
*src
= pSourceSD
;
468 SECURITY_DESCRIPTOR_RELATIVE
*dst
= pDestinationSD
;
470 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
471 return STATUS_UNKNOWN_REVISION
;
476 Owner
= (PSID
)SELF_RELATIVE_FIELD( src
, Owner
);
477 length
= RtlLengthSid( Owner
);
478 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Owner
), Owner
);
482 Group
= (PSID
)SELF_RELATIVE_FIELD( src
, Group
);
483 length
= RtlLengthSid( Group
);
484 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Group
), Group
);
486 if ((src
->Control
& SE_SACL_PRESENT
) && src
->Sacl
)
488 Sacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Sacl
);
489 copy_acl(Sacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Sacl
), Sacl
);
491 if ((src
->Control
& SE_DACL_PRESENT
) && src
->Dacl
)
493 Dacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Dacl
);
494 copy_acl(Dacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Dacl
), Dacl
);
499 SECURITY_DESCRIPTOR
*src
= pSourceSD
;
500 SECURITY_DESCRIPTOR
*dst
= pDestinationSD
;
502 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
503 return STATUS_UNKNOWN_REVISION
;
508 length
= RtlLengthSid( src
->Owner
);
509 dst
->Owner
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
510 RtlCopySid(length
, dst
->Owner
, src
->Owner
);
514 length
= RtlLengthSid( src
->Group
);
515 dst
->Group
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
516 RtlCopySid(length
, dst
->Group
, src
->Group
);
518 if (src
->Control
& SE_SACL_PRESENT
)
520 length
= src
->Sacl
->AclSize
;
521 dst
->Sacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
522 copy_acl(length
, dst
->Sacl
, src
->Sacl
);
524 if (src
->Control
& SE_DACL_PRESENT
)
526 length
= src
->Dacl
->AclSize
;
527 dst
->Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
528 copy_acl(length
, dst
->Dacl
, src
->Dacl
);
532 return STATUS_SUCCESS
;
535 /**************************************************************************
536 * RtlValidSecurityDescriptor [NTDLL.@]
538 BOOLEAN WINAPI
RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR descriptor
)
540 SECURITY_DESCRIPTOR
*sd
= descriptor
;
541 return sd
&& sd
->Revision
== SECURITY_DESCRIPTOR_REVISION
;
544 /**************************************************************************
545 * RtlValidRelativeSecurityDescriptor [NTDLL.@]
547 BOOLEAN WINAPI
RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR descriptor
,
548 ULONG length
, SECURITY_INFORMATION info
)
550 FIXME("%p,%lu,%ld: semi-stub\n", descriptor
, length
, info
);
551 return RtlValidSecurityDescriptor(descriptor
) == STATUS_SUCCESS
;
554 /**************************************************************************
555 * RtlLengthSecurityDescriptor [NTDLL.@]
557 ULONG WINAPI
RtlLengthSecurityDescriptor(
558 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
562 if ( pSecurityDescriptor
== NULL
)
565 if (((SECURITY_DESCRIPTOR
*)pSecurityDescriptor
)->Control
& SE_SELF_RELATIVE
)
567 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
569 if (sd
->Owner
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Owner
));
570 if (sd
->Group
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Group
));
571 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
)
572 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Sacl
))->AclSize
;
573 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
)
574 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Dacl
))->AclSize
;
578 SECURITY_DESCRIPTOR
*sd
= pSecurityDescriptor
;
580 if (sd
->Owner
) size
+= RtlLengthSid( sd
->Owner
);
581 if (sd
->Group
) size
+= RtlLengthSid( sd
->Group
);
582 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
) size
+= sd
->Sacl
->AclSize
;
583 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
) size
+= sd
->Dacl
->AclSize
;
588 /******************************************************************************
589 * RtlGetDaclSecurityDescriptor [NTDLL.@]
592 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
593 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
594 OUT PBOOLEAN lpbDaclPresent
,
596 OUT PBOOLEAN lpbDaclDefaulted
)
598 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
600 TRACE("(%p,%p,%p,%p)\n",
601 pSecurityDescriptor
, lpbDaclPresent
, pDacl
, lpbDaclDefaulted
);
603 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
604 return STATUS_UNKNOWN_REVISION
;
606 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
608 if (lpsd
->Control
& SE_SELF_RELATIVE
)
610 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
611 if (sdr
->Dacl
) *pDacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Dacl
);
614 else *pDacl
= lpsd
->Dacl
;
616 *lpbDaclDefaulted
= (lpsd
->Control
& SE_DACL_DEFAULTED
) != 0;
621 *lpbDaclDefaulted
= 0;
624 return STATUS_SUCCESS
;
627 /**************************************************************************
628 * RtlSetDaclSecurityDescriptor [NTDLL.@]
630 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
631 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
634 BOOLEAN dacldefaulted
)
636 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
638 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
639 return STATUS_UNKNOWN_REVISION
;
640 if (lpsd
->Control
& SE_SELF_RELATIVE
)
641 return STATUS_INVALID_SECURITY_DESCR
;
645 lpsd
->Control
&= ~SE_DACL_PRESENT
;
646 return STATUS_SUCCESS
;
649 lpsd
->Control
|= SE_DACL_PRESENT
;
653 lpsd
->Control
|= SE_DACL_DEFAULTED
;
655 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
657 return STATUS_SUCCESS
;
660 /******************************************************************************
661 * RtlGetSaclSecurityDescriptor [NTDLL.@]
664 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
665 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
666 OUT PBOOLEAN lpbSaclPresent
,
668 OUT PBOOLEAN lpbSaclDefaulted
)
670 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
672 TRACE("(%p,%p,%p,%p)\n",
673 pSecurityDescriptor
, lpbSaclPresent
, pSacl
, lpbSaclDefaulted
);
675 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
676 return STATUS_UNKNOWN_REVISION
;
678 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
680 if (lpsd
->Control
& SE_SELF_RELATIVE
)
682 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
683 if (sdr
->Sacl
) *pSacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Sacl
);
686 else *pSacl
= lpsd
->Sacl
;
688 *lpbSaclDefaulted
= (lpsd
->Control
& SE_SACL_DEFAULTED
) != 0;
690 return STATUS_SUCCESS
;
693 /**************************************************************************
694 * RtlSetSaclSecurityDescriptor [NTDLL.@]
696 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
697 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
700 BOOLEAN sacldefaulted
)
702 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
704 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
705 return STATUS_UNKNOWN_REVISION
;
706 if (lpsd
->Control
& SE_SELF_RELATIVE
)
707 return STATUS_INVALID_SECURITY_DESCR
;
709 lpsd
->Control
&= ~SE_SACL_PRESENT
;
712 lpsd
->Control
|= SE_SACL_PRESENT
;
715 lpsd
->Control
|= SE_SACL_DEFAULTED
;
717 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
718 return STATUS_SUCCESS
;
721 /**************************************************************************
722 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
724 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
725 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
727 PBOOLEAN OwnerDefaulted
)
729 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
731 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
732 return STATUS_INVALID_PARAMETER
;
734 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
735 *OwnerDefaulted
= TRUE
;
737 *OwnerDefaulted
= FALSE
;
739 if (lpsd
->Control
& SE_SELF_RELATIVE
)
741 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
742 if (sd
->Owner
) *Owner
= (PSID
)SELF_RELATIVE_FIELD( sd
, Owner
);
746 *Owner
= lpsd
->Owner
;
748 return STATUS_SUCCESS
;
751 /**************************************************************************
752 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
754 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
755 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
757 BOOLEAN ownerdefaulted
)
759 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
761 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
762 return STATUS_UNKNOWN_REVISION
;
763 if (lpsd
->Control
& SE_SELF_RELATIVE
)
764 return STATUS_INVALID_SECURITY_DESCR
;
768 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
770 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
771 return STATUS_SUCCESS
;
774 /**************************************************************************
775 * RtlSetGroupSecurityDescriptor [NTDLL.@]
777 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
778 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
780 BOOLEAN groupdefaulted
)
782 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
784 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
785 return STATUS_UNKNOWN_REVISION
;
786 if (lpsd
->Control
& SE_SELF_RELATIVE
)
787 return STATUS_INVALID_SECURITY_DESCR
;
791 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
793 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
794 return STATUS_SUCCESS
;
797 /**************************************************************************
798 * RtlGetGroupSecurityDescriptor [NTDLL.@]
800 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
801 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
803 PBOOLEAN GroupDefaulted
)
805 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
807 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
808 return STATUS_INVALID_PARAMETER
;
810 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
811 *GroupDefaulted
= TRUE
;
813 *GroupDefaulted
= FALSE
;
815 if (lpsd
->Control
& SE_SELF_RELATIVE
)
817 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
818 if (sd
->Group
) *Group
= (PSID
)SELF_RELATIVE_FIELD( sd
, Group
);
822 *Group
= lpsd
->Group
;
824 return STATUS_SUCCESS
;
827 /**************************************************************************
828 * RtlMakeSelfRelativeSD [NTDLL.@]
830 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
831 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
832 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
833 IN OUT LPDWORD lpdwBufferLength
)
837 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
838 SECURITY_DESCRIPTOR_RELATIVE
*pRel
= pSelfRelativeSecurityDescriptor
;
840 TRACE(" %p %p %p(%ld)\n", pAbs
, pRel
, lpdwBufferLength
,
841 lpdwBufferLength
? *lpdwBufferLength
: -1);
843 if (!lpdwBufferLength
|| !pAbs
)
844 return STATUS_INVALID_PARAMETER
;
846 length
= RtlLengthSecurityDescriptor(pAbs
);
847 if (!(pAbs
->Control
& SE_SELF_RELATIVE
)) length
-= (sizeof(*pAbs
) - sizeof(*pRel
));
848 if (*lpdwBufferLength
< length
)
850 *lpdwBufferLength
= length
;
851 return STATUS_BUFFER_TOO_SMALL
;
855 return STATUS_INVALID_PARAMETER
;
857 if (pAbs
->Control
& SE_SELF_RELATIVE
)
859 memcpy(pRel
, pAbs
, length
);
860 return STATUS_SUCCESS
;
863 pRel
->Revision
= pAbs
->Revision
;
864 pRel
->Sbz1
= pAbs
->Sbz1
;
865 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
867 offsetRel
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
870 pRel
->Owner
= offsetRel
;
871 length
= RtlLengthSid(pAbs
->Owner
);
872 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
882 pRel
->Group
= offsetRel
;
883 length
= RtlLengthSid(pAbs
->Group
);
884 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
894 pRel
->Sacl
= offsetRel
;
895 length
= pAbs
->Sacl
->AclSize
;
896 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
906 pRel
->Dacl
= offsetRel
;
907 length
= pAbs
->Dacl
->AclSize
;
908 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
915 return STATUS_SUCCESS
;
919 /**************************************************************************
920 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
922 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
923 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
924 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
925 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
927 OUT LPDWORD lpdwDaclSize
,
929 OUT LPDWORD lpdwSaclSize
,
931 OUT LPDWORD lpdwOwnerSize
,
932 OUT PSID pPrimaryGroup
,
933 OUT LPDWORD lpdwPrimaryGroupSize
)
935 NTSTATUS status
= STATUS_SUCCESS
;
936 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
937 SECURITY_DESCRIPTOR_RELATIVE
* pRel
= pSelfRelativeSecurityDescriptor
;
940 !lpdwAbsoluteSecurityDescriptorSize
||
944 !lpdwPrimaryGroupSize
||
945 ~pRel
->Control
& SE_SELF_RELATIVE
)
946 return STATUS_INVALID_PARAMETER
;
948 /* Confirm buffers are sufficiently large */
949 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
951 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
952 status
= STATUS_BUFFER_TOO_SMALL
;
955 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
&&
956 *lpdwDaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
)
958 *lpdwDaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
;
959 status
= STATUS_BUFFER_TOO_SMALL
;
962 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
&&
963 *lpdwSaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
)
965 *lpdwSaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
;
966 status
= STATUS_BUFFER_TOO_SMALL
;
970 *lpdwOwnerSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
)))
972 *lpdwOwnerSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
));
973 status
= STATUS_BUFFER_TOO_SMALL
;
977 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
)))
979 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
));
980 status
= STATUS_BUFFER_TOO_SMALL
;
983 if (status
!= STATUS_SUCCESS
)
986 /* Copy structures, and clear the ones we don't set */
987 pAbs
->Revision
= pRel
->Revision
;
988 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
994 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
)
996 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Sacl
);
998 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
1002 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
)
1004 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Dacl
);
1005 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
1011 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Owner
);
1012 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
1013 pAbs
->Owner
= pOwner
;
1018 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Group
);
1019 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
1020 pAbs
->Group
= pPrimaryGroup
;
1026 /******************************************************************************
1027 * RtlGetControlSecurityDescriptor (NTDLL.@)
1029 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1030 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1031 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1032 LPDWORD lpdwRevision
)
1034 SECURITY_DESCRIPTOR
*lpsd
= pSecurityDescriptor
;
1036 TRACE("(%p,%p,%p)\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1038 *lpdwRevision
= lpsd
->Revision
;
1040 if (*lpdwRevision
!= SECURITY_DESCRIPTOR_REVISION
)
1041 return STATUS_UNKNOWN_REVISION
;
1043 *pControl
= lpsd
->Control
;
1045 return STATUS_SUCCESS
;
1048 /******************************************************************************
1049 * RtlSetControlSecurityDescriptor (NTDLL.@)
1051 NTSTATUS WINAPI
RtlSetControlSecurityDescriptor(
1052 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1053 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
1054 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
1056 SECURITY_DESCRIPTOR_CONTROL
const immutable
1057 = SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
1058 | SE_DACL_PRESENT
| SE_DACL_DEFAULTED
1059 | SE_SACL_PRESENT
| SE_SACL_DEFAULTED
1060 | SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
1063 SECURITY_DESCRIPTOR
*lpsd
= SecurityDescriptor
;
1065 TRACE("(%p 0x%04x 0x%04x)\n", SecurityDescriptor
,
1066 ControlBitsOfInterest
, ControlBitsToSet
);
1068 if ((ControlBitsOfInterest
| ControlBitsToSet
) & immutable
)
1069 return STATUS_INVALID_PARAMETER
;
1071 lpsd
->Control
|= (ControlBitsOfInterest
& ControlBitsToSet
);
1072 lpsd
->Control
&= ~(ControlBitsOfInterest
& ~ControlBitsToSet
);
1074 return STATUS_SUCCESS
;
1078 /**************************************************************************
1079 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1081 NTSTATUS WINAPI
RtlAbsoluteToSelfRelativeSD(
1082 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
1083 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
1084 PULONG BufferLength
)
1086 SECURITY_DESCRIPTOR
*abs
= AbsoluteSecurityDescriptor
;
1088 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor
,
1089 SelfRelativeSecurityDescriptor
, BufferLength
);
1091 if (abs
->Control
& SE_SELF_RELATIVE
)
1092 return STATUS_BAD_DESCRIPTOR_FORMAT
;
1094 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
1095 SelfRelativeSecurityDescriptor
, BufferLength
);
1098 /******************************************************************************
1099 * RtlNewSecurityObject [NTDLL.@]
1101 NTSTATUS WINAPI
RtlNewSecurityObject(PSECURITY_DESCRIPTOR parent
, PSECURITY_DESCRIPTOR creator
,
1102 PSECURITY_DESCRIPTOR
*descr
, BOOLEAN is_container
, HANDLE token
, PGENERIC_MAPPING mapping
)
1104 return RtlNewSecurityObjectEx(parent
, creator
, descr
, NULL
, is_container
, 0, token
, mapping
);
1107 /******************************************************************************
1108 * RtlNewSecurityObjectEx [NTDLL.@]
1110 NTSTATUS WINAPI
RtlNewSecurityObjectEx(PSECURITY_DESCRIPTOR parent
, PSECURITY_DESCRIPTOR creator
,
1111 PSECURITY_DESCRIPTOR
*descr
, GUID
*type
, BOOLEAN is_container
, ULONG flags
, HANDLE token
, PGENERIC_MAPPING mapping
)
1113 SECURITY_DESCRIPTOR_RELATIVE
*relative
;
1114 DWORD needed
, offset
;
1118 FIXME("%p, %p, %p, %p, %d, %#lx, %p %p - semi-stub\n", parent
, creator
, descr
, type
, is_container
, flags
, token
, mapping
);
1120 needed
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
1121 needed
+= sizeof(world_sid
);
1122 needed
+= sizeof(world_sid
);
1123 needed
+= world_access_acl_size
;
1124 needed
+= world_access_acl_size
;
1126 if (!(buffer
= RtlAllocateHeap( GetProcessHeap(), 0, needed
))) return STATUS_NO_MEMORY
;
1127 relative
= (SECURITY_DESCRIPTOR_RELATIVE
*)buffer
;
1128 if ((status
= RtlCreateSecurityDescriptor( relative
, SECURITY_DESCRIPTOR_REVISION
)))
1130 RtlFreeHeap( GetProcessHeap(), 0, buffer
);
1133 relative
->Control
|= SE_SELF_RELATIVE
;
1134 offset
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
1136 memcpy( buffer
+ offset
, &world_sid
, sizeof(world_sid
) );
1137 relative
->Owner
= offset
;
1138 offset
+= sizeof(world_sid
);
1140 memcpy( buffer
+ offset
, &world_sid
, sizeof(world_sid
) );
1141 relative
->Group
= offset
;
1142 offset
+= sizeof(world_sid
);
1144 get_world_access_acl( (ACL
*)(buffer
+ offset
) );
1145 relative
->Dacl
= offset
;
1146 offset
+= world_access_acl_size
;
1148 get_world_access_acl( (ACL
*)(buffer
+ offset
) );
1149 relative
->Sacl
= offset
;
1152 return STATUS_SUCCESS
;
1155 /******************************************************************************
1156 * RtlNewSecurityObjectWithMultipleInheritance [NTDLL.@]
1158 NTSTATUS WINAPI
RtlNewSecurityObjectWithMultipleInheritance(PSECURITY_DESCRIPTOR parent
, PSECURITY_DESCRIPTOR creator
,
1159 PSECURITY_DESCRIPTOR
*descr
, GUID
**types
, ULONG count
, BOOLEAN is_container
, ULONG flags
,
1160 HANDLE token
, PGENERIC_MAPPING mapping
)
1162 FIXME("semi-stub\n");
1163 return RtlNewSecurityObjectEx(parent
, creator
, descr
, NULL
, is_container
, flags
, token
, mapping
);
1166 /******************************************************************************
1167 * RtlDeleteSecurityObject [NTDLL.@]
1169 NTSTATUS WINAPI
RtlDeleteSecurityObject( PSECURITY_DESCRIPTOR
*descr
)
1171 FIXME("%p stub.\n", descr
);
1172 RtlFreeHeap( GetProcessHeap(), 0, *descr
);
1173 return STATUS_SUCCESS
;
1177 * access control list's
1180 /**************************************************************************
1181 * RtlCreateAcl [NTDLL.@]
1184 * This should return NTSTATUS
1186 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
1188 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
1190 if (rev
< MIN_ACL_REVISION
|| rev
> MAX_ACL_REVISION
)
1191 return STATUS_INVALID_PARAMETER
;
1192 if (size
<sizeof(ACL
))
1193 return STATUS_BUFFER_TOO_SMALL
;
1195 return STATUS_INVALID_PARAMETER
;
1197 memset(acl
,'\0',sizeof(ACL
));
1198 acl
->AclRevision
= rev
;
1199 acl
->AclSize
= size
;
1201 return STATUS_SUCCESS
;
1204 /**************************************************************************
1205 * RtlFirstFreeAce [NTDLL.@]
1206 * looks for the AceCount+1 ACE, and if it is still within the alloced
1207 * ACL, return a pointer to it
1209 BOOLEAN WINAPI
RtlFirstFreeAce(
1217 ace
= (PACE_HEADER
)(acl
+1);
1218 for (i
=0;i
<acl
->AceCount
;i
++) {
1219 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1221 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1223 if ((BYTE
*)ace
<= (BYTE
*)acl
+ acl
->AclSize
)
1228 /**************************************************************************
1229 * RtlAddAce [NTDLL.@]
1231 NTSTATUS WINAPI
RtlAddAce(
1235 PACE_HEADER acestart
,
1238 PACE_HEADER ace
,targetace
;
1241 if (!RtlValidAcl(acl
))
1242 return STATUS_INVALID_PARAMETER
;
1243 if (!RtlFirstFreeAce(acl
,&targetace
))
1244 return STATUS_INVALID_PARAMETER
;
1246 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1247 nrofaces
=0;ace
=acestart
;
1248 while (((BYTE
*)ace
- (BYTE
*)acestart
) < acelen
) {
1250 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1252 if ((BYTE
*)targetace
+ acelen
> (BYTE
*)acl
+ acl
->AclSize
) /* too much aces */
1253 return STATUS_INVALID_PARAMETER
;
1254 memcpy(targetace
,acestart
,acelen
);
1255 acl
->AceCount
+=nrofaces
;
1256 if (rev
> acl
->AclRevision
)
1257 acl
->AclRevision
= rev
;
1258 return STATUS_SUCCESS
;
1261 /**************************************************************************
1262 * RtlDeleteAce [NTDLL.@]
1264 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1269 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
1271 if (STATUS_SUCCESS
== status
)
1276 /* skip over the ACE we are deleting */
1277 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
1280 /* calculate the length of the rest */
1281 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
1283 len
+= pcAce
->AceSize
;
1284 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
1287 /* slide them all backwards */
1288 memmove(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
1292 TRACE("pAcl=%p dwAceIndex=%ld status=0x%08lx\n", pAcl
, dwAceIndex
, status
);
1297 /******************************************************************************
1298 * RtlAddAccessAllowedAce [NTDLL.@]
1300 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
1302 IN DWORD dwAceRevision
,
1303 IN DWORD AccessMask
,
1306 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1309 /******************************************************************************
1310 * RtlAddAccessAllowedAceEx [NTDLL.@]
1312 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
1314 IN DWORD dwAceRevision
,
1316 IN DWORD AccessMask
,
1319 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1321 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1322 AccessMask
, pSid
, ACCESS_ALLOWED_ACE_TYPE
);
1325 /******************************************************************************
1326 * RtlAddAccessAllowedObjectAce [NTDLL.@]
1328 NTSTATUS WINAPI
RtlAddAccessAllowedObjectAce(
1330 IN DWORD dwAceRevision
,
1331 IN DWORD dwAceFlags
,
1332 IN DWORD dwAccessMask
,
1333 IN GUID
* pObjectTypeGuid
,
1334 IN GUID
* pInheritedObjectTypeGuid
,
1337 FIXME("%p %lx %lx %lx %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1338 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1339 return STATUS_NOT_IMPLEMENTED
;
1342 /******************************************************************************
1343 * RtlAddAccessDeniedAce [NTDLL.@]
1345 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1347 IN DWORD dwAceRevision
,
1348 IN DWORD AccessMask
,
1351 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1354 /******************************************************************************
1355 * RtlAddAccessDeniedAceEx [NTDLL.@]
1357 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1359 IN DWORD dwAceRevision
,
1361 IN DWORD AccessMask
,
1364 TRACE("(%p,0x%08lx,0x%08lx,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1366 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1367 AccessMask
, pSid
, ACCESS_DENIED_ACE_TYPE
);
1370 /******************************************************************************
1371 * RtlAddAccessDeniedObjectAce [NTDLL.@]
1373 NTSTATUS WINAPI
RtlAddAccessDeniedObjectAce(
1375 IN DWORD dwAceRevision
,
1376 IN DWORD dwAceFlags
,
1377 IN DWORD dwAccessMask
,
1378 IN GUID
* pObjectTypeGuid
,
1379 IN GUID
* pInheritedObjectTypeGuid
,
1382 FIXME("%p %lx %lx %lx %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1383 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1384 return STATUS_NOT_IMPLEMENTED
;
1387 /**************************************************************************
1388 * RtlAddAuditAccessAce [NTDLL.@]
1390 NTSTATUS WINAPI
RtlAddAuditAccessAceEx(
1392 IN DWORD dwAceRevision
,
1393 IN DWORD dwAceFlags
,
1394 IN DWORD dwAccessMask
,
1396 IN BOOL bAuditSuccess
,
1397 IN BOOL bAuditFailure
)
1399 TRACE("(%p,%ld,0x%08lx,0x%08lx,%p,%u,%u)\n",pAcl
,dwAceRevision
,dwAceFlags
,dwAccessMask
,
1400 pSid
,bAuditSuccess
,bAuditFailure
);
1403 dwAceFlags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
1406 dwAceFlags
|= FAILED_ACCESS_ACE_FLAG
;
1408 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
,
1409 dwAccessMask
, pSid
, SYSTEM_AUDIT_ACE_TYPE
);
1412 /**************************************************************************
1413 * RtlAddAuditAccessAce [NTDLL.@]
1415 NTSTATUS WINAPI
RtlAddAuditAccessAce(
1417 IN DWORD dwAceRevision
,
1418 IN DWORD dwAccessMask
,
1420 IN BOOL bAuditSuccess
,
1421 IN BOOL bAuditFailure
)
1423 return RtlAddAuditAccessAceEx(pAcl
, dwAceRevision
, 0, dwAccessMask
, pSid
, bAuditSuccess
, bAuditFailure
);
1426 /******************************************************************************
1427 * RtlAddAuditAccessObjectAce [NTDLL.@]
1429 NTSTATUS WINAPI
RtlAddAuditAccessObjectAce(
1431 IN DWORD dwAceRevision
,
1432 IN DWORD dwAceFlags
,
1433 IN DWORD dwAccessMask
,
1434 IN GUID
* pObjectTypeGuid
,
1435 IN GUID
* pInheritedObjectTypeGuid
,
1437 IN BOOL bAuditSuccess
,
1438 IN BOOL bAuditFailure
)
1440 FIXME("%p %lx %lx %lx %p %p %p %d %d - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1441 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
, bAuditSuccess
, bAuditFailure
);
1442 return STATUS_NOT_IMPLEMENTED
;
1445 /**************************************************************************
1446 * RtlAddMandatoryAce [NTDLL.@]
1448 NTSTATUS WINAPI
RtlAddMandatoryAce(
1450 IN DWORD dwAceRevision
,
1451 IN DWORD dwAceFlags
,
1452 IN DWORD dwMandatoryFlags
,
1456 TRACE("(%p, %lu, 0x%08lx, 0x%08lx, %lu, %p)\n",
1457 pAcl
, dwAceRevision
, dwAceFlags
, dwMandatoryFlags
, dwAceType
, pSid
);
1459 if (dwAceType
!= SYSTEM_MANDATORY_LABEL_ACE_TYPE
)
1460 return STATUS_INVALID_PARAMETER
;
1461 if (dwMandatoryFlags
& ~SYSTEM_MANDATORY_LABEL_VALID_MASK
)
1462 return STATUS_INVALID_PARAMETER
;
1464 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
, dwMandatoryFlags
, pSid
, dwAceType
);
1467 /**************************************************************************
1468 * RtlAddProcessTrustLabelAce [NTDLL.@]
1470 NTSTATUS WINAPI
RtlAddProcessTrustLabelAce( ACL
*acl
, DWORD revision
, DWORD flags
,
1471 PSID sid
, DWORD type
, DWORD mask
)
1473 TRACE( "%p %lx %lx %p %lx %lx\n", acl
, revision
, flags
, sid
, type
, mask
);
1475 if (type
!= SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE
) return STATUS_INVALID_PARAMETER
;
1476 if (mask
& ~SYSTEM_PROCESS_TRUST_LABEL_VALID_MASK
) return STATUS_INVALID_PARAMETER
;
1478 return add_access_ace( acl
, revision
, flags
, mask
, sid
, type
);
1481 /******************************************************************************
1482 * RtlValidAcl [NTDLL.@]
1484 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1487 TRACE("(%p)\n", pAcl
);
1494 if (pAcl
->AclRevision
< MIN_ACL_REVISION
||
1495 pAcl
->AclRevision
> MAX_ACL_REVISION
)
1499 ace
= (PACE_HEADER
)(pAcl
+1);
1501 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1503 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1508 if (i
!= pAcl
->AceCount
)
1509 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1515 WARN("(%p): invalid pointer!\n", pAcl
);
1522 /******************************************************************************
1523 * RtlGetAce [NTDLL.@]
1525 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1529 TRACE("(%p,%ld,%p)\n",pAcl
,dwAceIndex
,pAce
);
1531 if (dwAceIndex
>= pAcl
->AceCount
)
1532 return STATUS_INVALID_PARAMETER
;
1534 ace
= (PACE_HEADER
)(pAcl
+ 1);
1535 for (;dwAceIndex
;dwAceIndex
--)
1536 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1540 return STATUS_SUCCESS
;
1547 /******************************************************************************
1548 * RtlAdjustPrivilege [NTDLL.@]
1550 * Enables or disables a privilege from the calling thread or process.
1553 * Privilege [I] Privilege index to change.
1554 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1555 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1556 * Enabled [O] Whether privilege was previously enabled or disabled.
1559 * Success: STATUS_SUCCESS.
1560 * Failure: NTSTATUS code.
1563 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1567 RtlAdjustPrivilege(ULONG Privilege
,
1569 BOOLEAN CurrentThread
,
1572 TOKEN_PRIVILEGES NewState
;
1573 TOKEN_PRIVILEGES OldState
;
1578 TRACE("(%ld, %s, %s, %p)\n", Privilege
, Enable
? "TRUE" : "FALSE",
1579 CurrentThread
? "TRUE" : "FALSE", Enabled
);
1583 Status
= NtOpenThreadToken(GetCurrentThread(),
1584 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1590 Status
= NtOpenProcessToken(GetCurrentProcess(),
1591 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1597 WARN("Retrieving token handle failed (Status %lx)\n", Status
);
1601 OldState
.PrivilegeCount
= 1;
1603 NewState
.PrivilegeCount
= 1;
1604 NewState
.Privileges
[0].Luid
.LowPart
= Privilege
;
1605 NewState
.Privileges
[0].Luid
.HighPart
= 0;
1606 NewState
.Privileges
[0].Attributes
= (Enable
) ? SE_PRIVILEGE_ENABLED
: 0;
1608 Status
= NtAdjustPrivilegesToken(TokenHandle
,
1611 sizeof(TOKEN_PRIVILEGES
),
1614 NtClose (TokenHandle
);
1615 if (Status
== STATUS_NOT_ALL_ASSIGNED
)
1617 TRACE("Failed to assign all privileges\n");
1618 return STATUS_PRIVILEGE_NOT_HELD
;
1622 WARN("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status
);
1626 if (OldState
.PrivilegeCount
== 0)
1629 *Enabled
= (OldState
.Privileges
[0].Attributes
& SE_PRIVILEGE_ENABLED
);
1631 return STATUS_SUCCESS
;
1634 /******************************************************************************
1635 * RtlImpersonateSelf [NTDLL.@]
1637 * Makes an impersonation token that represents the process user and assigns
1638 * to the current thread.
1641 * ImpersonationLevel [I] Level at which to impersonate.
1644 * Success: STATUS_SUCCESS.
1645 * Failure: NTSTATUS code.
1648 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1650 SECURITY_QUALITY_OF_SERVICE qos
;
1652 OBJECT_ATTRIBUTES attr
;
1653 HANDLE ProcessToken
;
1654 HANDLE ImpersonationToken
;
1656 TRACE("(%08x)\n", ImpersonationLevel
);
1658 Status
= NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE
,
1660 if (Status
!= STATUS_SUCCESS
)
1663 qos
.Length
= sizeof(qos
);
1664 qos
.ImpersonationLevel
= ImpersonationLevel
;
1665 qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
1666 qos
.EffectiveOnly
= FALSE
;
1667 InitializeObjectAttributes( &attr
, NULL
, 0, NULL
, NULL
);
1668 attr
.SecurityQualityOfService
= &qos
;
1670 Status
= NtDuplicateToken( ProcessToken
, TOKEN_IMPERSONATE
, &attr
, FALSE
,
1671 TokenImpersonation
, &ImpersonationToken
);
1672 if (Status
!= STATUS_SUCCESS
)
1674 NtClose( ProcessToken
);
1678 Status
= NtSetInformationThread( GetCurrentThread(),
1679 ThreadImpersonationToken
,
1680 &ImpersonationToken
,
1681 sizeof(ImpersonationToken
) );
1683 NtClose( ImpersonationToken
);
1684 NtClose( ProcessToken
);
1690 /******************************************************************************
1691 * RtlConvertSidToUnicodeString (NTDLL.@)
1693 * The returned SID is used to access the USER registry hive usually
1695 * the native function returns something like
1696 * "S-1-5-21-0000000000-000000000-0000000000-500";
1698 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1699 PUNICODE_STRING String
,
1701 BOOLEAN AllocateString
)
1703 WCHAR buffer
[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES
];
1705 const SID
*sid
= pSid
;
1709 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), L
"-%u", sid
->Revision
);
1710 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), L
"-%u",
1711 MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
1712 sid
->IdentifierAuthority
.Value
[4] ),
1713 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
1714 sid
->IdentifierAuthority
.Value
[2] )));
1715 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
1716 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), L
"-%u", sid
->SubAuthority
[i
] );
1718 len
= (p
+ 1 - buffer
) * sizeof(WCHAR
);
1720 String
->Length
= len
- sizeof(WCHAR
);
1723 String
->MaximumLength
= len
;
1724 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1725 return STATUS_NO_MEMORY
;
1727 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1729 memcpy( String
->Buffer
, buffer
, len
);
1730 return STATUS_SUCCESS
;
1733 /******************************************************************************
1734 * RtlQueryInformationAcl (NTDLL.@)
1736 NTSTATUS WINAPI
RtlQueryInformationAcl(
1738 LPVOID pAclInformation
,
1739 DWORD nAclInformationLength
,
1740 ACL_INFORMATION_CLASS dwAclInformationClass
)
1742 NTSTATUS status
= STATUS_SUCCESS
;
1744 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1745 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1747 switch (dwAclInformationClass
)
1749 case AclRevisionInformation
:
1751 PACL_REVISION_INFORMATION paclrev
= pAclInformation
;
1753 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1754 status
= STATUS_INVALID_PARAMETER
;
1756 paclrev
->AclRevision
= pAcl
->AclRevision
;
1761 case AclSizeInformation
:
1763 PACL_SIZE_INFORMATION paclsize
= pAclInformation
;
1765 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1766 status
= STATUS_INVALID_PARAMETER
;
1769 paclsize
->AceCount
= pAcl
->AceCount
;
1770 paclsize
->AclBytesInUse
= acl_bytesInUse(pAcl
);
1771 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1773 WARN("Acl uses %d bytes, but only has %ld allocated! Returning smaller of the two values.\n", pAcl
->AclSize
, paclsize
->AclBytesInUse
);
1774 paclsize
->AclBytesFree
= 0;
1775 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1778 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1785 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1786 status
= STATUS_INVALID_PARAMETER
;
1792 NTSTATUS WINAPI
RtlConvertToAutoInheritSecurityObject(
1793 PSECURITY_DESCRIPTOR pdesc
,
1794 PSECURITY_DESCRIPTOR cdesc
,
1795 PSECURITY_DESCRIPTOR
* ndesc
,
1798 PGENERIC_MAPPING genmap
)
1800 FIXME("%p %p %p %p %d %p - stub\n", pdesc
, cdesc
, ndesc
, objtype
, isdir
, genmap
);
1802 return STATUS_NOT_IMPLEMENTED
;
1805 /******************************************************************************
1806 * RtlDefaultNpAcl (NTDLL.@)
1808 NTSTATUS WINAPI
RtlDefaultNpAcl(PACL
*pAcl
)
1810 FIXME("%p - stub\n", pAcl
);
1813 return STATUS_SUCCESS
;