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 /* helper function to retrieve active length of an ACL */
41 static size_t acl_bytesInUse(PACL pAcl
)
44 size_t bytesInUse
= sizeof(ACL
);
45 PACE_HEADER ace
= (PACE_HEADER
) (pAcl
+ 1);
46 for (i
= 0; i
< pAcl
->AceCount
; i
++)
48 bytesInUse
+= ace
->AceSize
;
49 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
54 /* helper function to copy an ACL */
55 static BOOLEAN
copy_acl(DWORD nDestinationAclLength
, PACL pDestinationAcl
, PACL pSourceAcl
)
59 if (!pSourceAcl
|| !RtlValidAcl(pSourceAcl
))
62 size
= pSourceAcl
->AclSize
;
63 if (nDestinationAclLength
< size
)
66 memmove(pDestinationAcl
, pSourceAcl
, size
);
70 /* generically adds an ACE to an ACL */
71 static NTSTATUS
add_access_ace(PACL pAcl
, DWORD dwAceRevision
, DWORD dwAceFlags
,
72 DWORD dwAccessMask
, PSID pSid
, DWORD dwAceType
)
74 ACE_HEADER
*pAceHeader
;
80 if (!RtlValidSid(pSid
))
81 return STATUS_INVALID_SID
;
83 if (pAcl
->AclRevision
> MAX_ACL_REVISION
|| dwAceRevision
> MAX_ACL_REVISION
)
84 return STATUS_REVISION_MISMATCH
;
86 if (!RtlValidAcl(pAcl
))
87 return STATUS_INVALID_ACL
;
89 if (!RtlFirstFreeAce(pAcl
, &pAceHeader
))
90 return STATUS_INVALID_ACL
;
93 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
95 /* calculate generic size of the ACE */
96 dwLengthSid
= RtlLengthSid(pSid
);
97 dwAceSize
= sizeof(ACE_HEADER
) + sizeof(DWORD
) + dwLengthSid
;
98 if ((char *)pAceHeader
+ dwAceSize
> (char *)pAcl
+ pAcl
->AclSize
)
99 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
101 /* fill the new ACE */
102 pAceHeader
->AceType
= dwAceType
;
103 pAceHeader
->AceFlags
= dwAceFlags
;
104 pAceHeader
->AceSize
= dwAceSize
;
106 /* skip past the ACE_HEADER of the ACE */
107 pAccessMask
= (DWORD
*)(pAceHeader
+ 1);
108 *pAccessMask
= dwAccessMask
;
110 /* skip past ACE->Mask */
111 pSidStart
= pAccessMask
+ 1;
112 RtlCopySid(dwLengthSid
, pSidStart
, pSid
);
114 pAcl
->AclRevision
= max(pAcl
->AclRevision
, dwAceRevision
);
117 return STATUS_SUCCESS
;
124 /******************************************************************************
125 * RtlAllocateAndInitializeSid [NTDLL.@]
128 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
129 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
130 BYTE nSubAuthorityCount
,
131 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
132 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
133 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
134 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
139 TRACE("(%p, 0x%04x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,%p)\n",
140 pIdentifierAuthority
,nSubAuthorityCount
,
141 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
142 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
144 if (nSubAuthorityCount
> 8) return STATUS_INVALID_SID
;
146 if (!(tmp_sid
= RtlAllocateHeap( GetProcessHeap(), 0,
147 RtlLengthRequiredSid(nSubAuthorityCount
))))
148 return STATUS_NO_MEMORY
;
150 tmp_sid
->Revision
= SID_REVISION
;
152 if (pIdentifierAuthority
)
153 tmp_sid
->IdentifierAuthority
= *pIdentifierAuthority
;
154 tmp_sid
->SubAuthorityCount
= nSubAuthorityCount
;
156 switch( nSubAuthorityCount
)
158 case 8: tmp_sid
->SubAuthority
[7]= nSubAuthority7
;
160 case 7: tmp_sid
->SubAuthority
[6]= nSubAuthority6
;
162 case 6: tmp_sid
->SubAuthority
[5]= nSubAuthority5
;
164 case 5: tmp_sid
->SubAuthority
[4]= nSubAuthority4
;
166 case 4: tmp_sid
->SubAuthority
[3]= nSubAuthority3
;
168 case 3: tmp_sid
->SubAuthority
[2]= nSubAuthority2
;
170 case 2: tmp_sid
->SubAuthority
[1]= nSubAuthority1
;
172 case 1: tmp_sid
->SubAuthority
[0]= nSubAuthority0
;
176 return STATUS_SUCCESS
;
179 /******************************************************************************
180 * RtlEqualSid [NTDLL.@]
182 * Determine if two SIDs are equal.
185 * pSid1 [I] Source SID
186 * pSid2 [I] SID to compare with
189 * TRUE, if pSid1 is equal to pSid2,
192 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
194 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
197 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
200 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
206 /******************************************************************************
207 * RtlEqualPrefixSid [NTDLL.@]
209 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
211 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
214 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
217 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
224 /******************************************************************************
225 * RtlFreeSid [NTDLL.@]
227 * Free the resources used by a SID.
230 * pSid [I] SID to Free.
235 DWORD WINAPI
RtlFreeSid(PSID pSid
)
237 TRACE("(%p)\n", pSid
);
238 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
239 return STATUS_SUCCESS
;
242 /**************************************************************************
243 * RtlLengthRequiredSid [NTDLL.@]
245 * Determine the amount of memory a SID will use
248 * nrofsubauths [I] Number of Sub Authorities in the SID.
251 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
253 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
255 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
258 /**************************************************************************
259 * RtlLengthSid [NTDLL.@]
261 * Determine the amount of memory a SID is using
264 * pSid [I] SID to get the size of.
267 * The size, in bytes, of pSid.
269 DWORD WINAPI
RtlLengthSid(PSID pSid
)
271 TRACE("sid=%p\n",pSid
);
273 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
276 /**************************************************************************
277 * RtlInitializeSid [NTDLL.@]
282 * pSid [I] SID to initialise
283 * pIdentifierAuthority [I] Identifier Authority
284 * nSubAuthorityCount [I] Number of Sub Authorities
287 * Success: TRUE. pSid is initialised with the details given.
288 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
290 BOOL WINAPI
RtlInitializeSid(
292 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
293 BYTE nSubAuthorityCount
)
298 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
301 pisid
->Revision
= SID_REVISION
;
302 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
303 if (pIdentifierAuthority
)
304 pisid
->IdentifierAuthority
= *pIdentifierAuthority
;
306 for (i
= 0; i
< nSubAuthorityCount
; i
++)
307 *RtlSubAuthoritySid(pSid
, i
) = 0;
312 /**************************************************************************
313 * RtlSubAuthoritySid [NTDLL.@]
315 * Return the Sub Authority of a SID
318 * pSid [I] SID to get the Sub Authority from.
319 * nSubAuthority [I] Sub Authority number.
322 * A pointer to The Sub Authority value of pSid.
324 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
326 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
329 /**************************************************************************
330 * RtlIdentifierAuthoritySid [NTDLL.@]
332 * Return the Identifier Authority of a SID.
335 * pSid [I] SID to get the Identifier Authority from.
338 * A pointer to the Identifier Authority value of pSid.
340 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
342 return &(((SID
*)pSid
)->IdentifierAuthority
);
345 /**************************************************************************
346 * RtlSubAuthorityCountSid [NTDLL.@]
348 * Get the number of Sub Authorities in a SID.
351 * pSid [I] SID to get the count from.
354 * A pointer to the Sub Authority count of pSid.
356 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
358 return &(((SID
*)pSid
)->SubAuthorityCount
);
361 /**************************************************************************
362 * RtlCopySid [NTDLL.@]
364 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
366 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
367 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
370 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
373 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
376 /******************************************************************************
377 * RtlValidSid [NTDLL.@]
379 * Determine if a SID is valid.
382 * pSid [I] SID to check
385 * TRUE if pSid is valid,
388 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
394 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
395 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
402 WARN("(%p): invalid pointer!\n", pSid
);
411 * security descriptor functions
414 /**************************************************************************
415 * RtlCreateSecurityDescriptor [NTDLL.@]
417 * Initialise a SECURITY_DESCRIPTOR.
420 * lpsd [O] Descriptor to initialise.
421 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
424 * Success: STATUS_SUCCESS.
425 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
427 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
428 PSECURITY_DESCRIPTOR lpsd
,
431 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
432 return STATUS_UNKNOWN_REVISION
;
433 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
434 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
435 return STATUS_SUCCESS
;
438 /**************************************************************************
439 * RtlCopySecurityDescriptor [NTDLL.@]
441 * Copies an absolute or sefl-relative SECURITY_DESCRIPTOR.
444 * pSourceSD [O] SD to copy from.
445 * pDestinationSD [I] Destination SD.
448 * Success: STATUS_SUCCESS.
449 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
451 NTSTATUS WINAPI
RtlCopySecurityDescriptor(PSECURITY_DESCRIPTOR pSourceSD
, PSECURITY_DESCRIPTOR pDestinationSD
)
457 if (((SECURITY_DESCRIPTOR
*)pSourceSD
)->Control
& SE_SELF_RELATIVE
)
459 SECURITY_DESCRIPTOR_RELATIVE
*src
= pSourceSD
;
460 SECURITY_DESCRIPTOR_RELATIVE
*dst
= pDestinationSD
;
462 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
463 return STATUS_UNKNOWN_REVISION
;
468 Owner
= (PSID
)SELF_RELATIVE_FIELD( src
, Owner
);
469 length
= RtlLengthSid( Owner
);
470 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Owner
), Owner
);
474 Group
= (PSID
)SELF_RELATIVE_FIELD( src
, Group
);
475 length
= RtlLengthSid( Group
);
476 RtlCopySid(length
, SELF_RELATIVE_FIELD( dst
, Group
), Group
);
478 if ((src
->Control
& SE_SACL_PRESENT
) && src
->Sacl
)
480 Sacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Sacl
);
481 copy_acl(Sacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Sacl
), Sacl
);
483 if ((src
->Control
& SE_DACL_PRESENT
) && src
->Dacl
)
485 Dacl
= (PACL
)SELF_RELATIVE_FIELD( src
, Dacl
);
486 copy_acl(Dacl
->AclSize
, (PACL
)SELF_RELATIVE_FIELD( dst
, Dacl
), Dacl
);
491 SECURITY_DESCRIPTOR
*src
= pSourceSD
;
492 SECURITY_DESCRIPTOR
*dst
= pDestinationSD
;
494 if (src
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
495 return STATUS_UNKNOWN_REVISION
;
500 length
= RtlLengthSid( src
->Owner
);
501 dst
->Owner
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
502 RtlCopySid(length
, dst
->Owner
, src
->Owner
);
506 length
= RtlLengthSid( src
->Group
);
507 dst
->Group
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
508 RtlCopySid(length
, dst
->Group
, src
->Group
);
510 if (src
->Control
& SE_SACL_PRESENT
)
512 length
= src
->Sacl
->AclSize
;
513 dst
->Sacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
514 copy_acl(length
, dst
->Sacl
, src
->Sacl
);
516 if (src
->Control
& SE_DACL_PRESENT
)
518 length
= src
->Dacl
->AclSize
;
519 dst
->Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, length
);
520 copy_acl(length
, dst
->Dacl
, src
->Dacl
);
524 return STATUS_SUCCESS
;
527 /**************************************************************************
528 * RtlValidSecurityDescriptor [NTDLL.@]
530 * Determine if a SECURITY_DESCRIPTOR is valid.
533 * SecurityDescriptor [I] Descriptor to check.
536 * Success: STATUS_SUCCESS.
537 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
539 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
540 PSECURITY_DESCRIPTOR SecurityDescriptor
)
542 if ( ! SecurityDescriptor
)
543 return STATUS_INVALID_SECURITY_DESCR
;
544 if ( ((SECURITY_DESCRIPTOR
*)SecurityDescriptor
)->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
545 return STATUS_UNKNOWN_REVISION
;
547 return STATUS_SUCCESS
;
550 /**************************************************************************
551 * RtlValidRelativeSecurityDescriptor [NTDLL.@]
553 BOOLEAN WINAPI
RtlValidRelativeSecurityDescriptor(PSECURITY_DESCRIPTOR descriptor
,
554 ULONG length
, SECURITY_INFORMATION info
)
556 FIXME("%p,%u,%d: semi-stub\n", descriptor
, length
, info
);
557 return RtlValidSecurityDescriptor(descriptor
) == STATUS_SUCCESS
;
560 /**************************************************************************
561 * RtlLengthSecurityDescriptor [NTDLL.@]
563 ULONG WINAPI
RtlLengthSecurityDescriptor(
564 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
568 if ( pSecurityDescriptor
== NULL
)
571 if (((SECURITY_DESCRIPTOR
*)pSecurityDescriptor
)->Control
& SE_SELF_RELATIVE
)
573 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
575 if (sd
->Owner
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Owner
));
576 if (sd
->Group
) size
+= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(sd
,Group
));
577 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
)
578 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Sacl
))->AclSize
;
579 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
)
580 size
+= ((PACL
)SELF_RELATIVE_FIELD(sd
,Dacl
))->AclSize
;
584 SECURITY_DESCRIPTOR
*sd
= pSecurityDescriptor
;
586 if (sd
->Owner
) size
+= RtlLengthSid( sd
->Owner
);
587 if (sd
->Group
) size
+= RtlLengthSid( sd
->Group
);
588 if ((sd
->Control
& SE_SACL_PRESENT
) && sd
->Sacl
) size
+= sd
->Sacl
->AclSize
;
589 if ((sd
->Control
& SE_DACL_PRESENT
) && sd
->Dacl
) size
+= sd
->Dacl
->AclSize
;
594 /******************************************************************************
595 * RtlGetDaclSecurityDescriptor [NTDLL.@]
598 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
599 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
600 OUT PBOOLEAN lpbDaclPresent
,
602 OUT PBOOLEAN lpbDaclDefaulted
)
604 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
606 TRACE("(%p,%p,%p,%p)\n",
607 pSecurityDescriptor
, lpbDaclPresent
, pDacl
, lpbDaclDefaulted
);
609 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
610 return STATUS_UNKNOWN_REVISION
;
612 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
614 if (lpsd
->Control
& SE_SELF_RELATIVE
)
616 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
617 if (sdr
->Dacl
) *pDacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Dacl
);
620 else *pDacl
= lpsd
->Dacl
;
622 *lpbDaclDefaulted
= (lpsd
->Control
& SE_DACL_DEFAULTED
) != 0;
627 *lpbDaclDefaulted
= 0;
630 return STATUS_SUCCESS
;
633 /**************************************************************************
634 * RtlSetDaclSecurityDescriptor [NTDLL.@]
636 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
637 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
640 BOOLEAN dacldefaulted
)
642 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
644 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
645 return STATUS_UNKNOWN_REVISION
;
646 if (lpsd
->Control
& SE_SELF_RELATIVE
)
647 return STATUS_INVALID_SECURITY_DESCR
;
651 lpsd
->Control
&= ~SE_DACL_PRESENT
;
652 return STATUS_SUCCESS
;
655 lpsd
->Control
|= SE_DACL_PRESENT
;
659 lpsd
->Control
|= SE_DACL_DEFAULTED
;
661 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
663 return STATUS_SUCCESS
;
666 /******************************************************************************
667 * RtlGetSaclSecurityDescriptor [NTDLL.@]
670 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
671 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
672 OUT PBOOLEAN lpbSaclPresent
,
674 OUT PBOOLEAN lpbSaclDefaulted
)
676 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
678 TRACE("(%p,%p,%p,%p)\n",
679 pSecurityDescriptor
, lpbSaclPresent
, pSacl
, lpbSaclDefaulted
);
681 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
682 return STATUS_UNKNOWN_REVISION
;
684 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
686 if (lpsd
->Control
& SE_SELF_RELATIVE
)
688 SECURITY_DESCRIPTOR_RELATIVE
*sdr
= pSecurityDescriptor
;
689 if (sdr
->Sacl
) *pSacl
= (PACL
)SELF_RELATIVE_FIELD( sdr
, Sacl
);
692 else *pSacl
= lpsd
->Sacl
;
694 *lpbSaclDefaulted
= (lpsd
->Control
& SE_SACL_DEFAULTED
) != 0;
696 return STATUS_SUCCESS
;
699 /**************************************************************************
700 * RtlSetSaclSecurityDescriptor [NTDLL.@]
702 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
703 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
706 BOOLEAN sacldefaulted
)
708 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
710 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
711 return STATUS_UNKNOWN_REVISION
;
712 if (lpsd
->Control
& SE_SELF_RELATIVE
)
713 return STATUS_INVALID_SECURITY_DESCR
;
715 lpsd
->Control
&= ~SE_SACL_PRESENT
;
718 lpsd
->Control
|= SE_SACL_PRESENT
;
721 lpsd
->Control
|= SE_SACL_DEFAULTED
;
723 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
724 return STATUS_SUCCESS
;
727 /**************************************************************************
728 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
730 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
731 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
733 PBOOLEAN OwnerDefaulted
)
735 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
737 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
738 return STATUS_INVALID_PARAMETER
;
740 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
741 *OwnerDefaulted
= TRUE
;
743 *OwnerDefaulted
= FALSE
;
745 if (lpsd
->Control
& SE_SELF_RELATIVE
)
747 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
748 if (sd
->Owner
) *Owner
= (PSID
)SELF_RELATIVE_FIELD( sd
, Owner
);
752 *Owner
= lpsd
->Owner
;
754 return STATUS_SUCCESS
;
757 /**************************************************************************
758 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
760 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
761 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
763 BOOLEAN ownerdefaulted
)
765 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
767 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
768 return STATUS_UNKNOWN_REVISION
;
769 if (lpsd
->Control
& SE_SELF_RELATIVE
)
770 return STATUS_INVALID_SECURITY_DESCR
;
774 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
776 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
777 return STATUS_SUCCESS
;
780 /**************************************************************************
781 * RtlSetGroupSecurityDescriptor [NTDLL.@]
783 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
784 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
786 BOOLEAN groupdefaulted
)
788 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
790 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
791 return STATUS_UNKNOWN_REVISION
;
792 if (lpsd
->Control
& SE_SELF_RELATIVE
)
793 return STATUS_INVALID_SECURITY_DESCR
;
797 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
799 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
800 return STATUS_SUCCESS
;
803 /**************************************************************************
804 * RtlGetGroupSecurityDescriptor [NTDLL.@]
806 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
807 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
809 PBOOLEAN GroupDefaulted
)
811 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
813 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
814 return STATUS_INVALID_PARAMETER
;
816 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
817 *GroupDefaulted
= TRUE
;
819 *GroupDefaulted
= FALSE
;
821 if (lpsd
->Control
& SE_SELF_RELATIVE
)
823 SECURITY_DESCRIPTOR_RELATIVE
*sd
= pSecurityDescriptor
;
824 if (sd
->Group
) *Group
= (PSID
)SELF_RELATIVE_FIELD( sd
, Group
);
828 *Group
= lpsd
->Group
;
830 return STATUS_SUCCESS
;
833 /**************************************************************************
834 * RtlMakeSelfRelativeSD [NTDLL.@]
836 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
837 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
838 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
839 IN OUT LPDWORD lpdwBufferLength
)
843 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
844 SECURITY_DESCRIPTOR_RELATIVE
*pRel
= pSelfRelativeSecurityDescriptor
;
846 TRACE(" %p %p %p(%d)\n", pAbs
, pRel
, lpdwBufferLength
,
847 lpdwBufferLength
? *lpdwBufferLength
: -1);
849 if (!lpdwBufferLength
|| !pAbs
)
850 return STATUS_INVALID_PARAMETER
;
852 length
= RtlLengthSecurityDescriptor(pAbs
);
853 if (!(pAbs
->Control
& SE_SELF_RELATIVE
)) length
-= (sizeof(*pAbs
) - sizeof(*pRel
));
854 if (*lpdwBufferLength
< length
)
856 *lpdwBufferLength
= length
;
857 return STATUS_BUFFER_TOO_SMALL
;
861 return STATUS_INVALID_PARAMETER
;
863 if (pAbs
->Control
& SE_SELF_RELATIVE
)
865 memcpy(pRel
, pAbs
, length
);
866 return STATUS_SUCCESS
;
869 pRel
->Revision
= pAbs
->Revision
;
870 pRel
->Sbz1
= pAbs
->Sbz1
;
871 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
873 offsetRel
= sizeof(SECURITY_DESCRIPTOR_RELATIVE
);
876 pRel
->Owner
= offsetRel
;
877 length
= RtlLengthSid(pAbs
->Owner
);
878 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
888 pRel
->Group
= offsetRel
;
889 length
= RtlLengthSid(pAbs
->Group
);
890 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
900 pRel
->Sacl
= offsetRel
;
901 length
= pAbs
->Sacl
->AclSize
;
902 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
912 pRel
->Dacl
= offsetRel
;
913 length
= pAbs
->Dacl
->AclSize
;
914 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
921 return STATUS_SUCCESS
;
925 /**************************************************************************
926 * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
928 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
929 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
930 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
931 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
933 OUT LPDWORD lpdwDaclSize
,
935 OUT LPDWORD lpdwSaclSize
,
937 OUT LPDWORD lpdwOwnerSize
,
938 OUT PSID pPrimaryGroup
,
939 OUT LPDWORD lpdwPrimaryGroupSize
)
941 NTSTATUS status
= STATUS_SUCCESS
;
942 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
943 SECURITY_DESCRIPTOR_RELATIVE
* pRel
= pSelfRelativeSecurityDescriptor
;
946 !lpdwAbsoluteSecurityDescriptorSize
||
950 !lpdwPrimaryGroupSize
||
951 ~pRel
->Control
& SE_SELF_RELATIVE
)
952 return STATUS_INVALID_PARAMETER
;
954 /* Confirm buffers are sufficiently large */
955 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
957 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
958 status
= STATUS_BUFFER_TOO_SMALL
;
961 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
&&
962 *lpdwDaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
)
964 *lpdwDaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Dacl
))->AclSize
;
965 status
= STATUS_BUFFER_TOO_SMALL
;
968 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
&&
969 *lpdwSaclSize
< ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
)
971 *lpdwSaclSize
= ((PACL
)SELF_RELATIVE_FIELD(pRel
,Sacl
))->AclSize
;
972 status
= STATUS_BUFFER_TOO_SMALL
;
976 *lpdwOwnerSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
)))
978 *lpdwOwnerSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Owner
));
979 status
= STATUS_BUFFER_TOO_SMALL
;
983 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
)))
985 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)SELF_RELATIVE_FIELD(pRel
,Group
));
986 status
= STATUS_BUFFER_TOO_SMALL
;
989 if (status
!= STATUS_SUCCESS
)
992 /* Copy structures, and clear the ones we don't set */
993 pAbs
->Revision
= pRel
->Revision
;
994 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
1000 if ((pRel
->Control
& SE_SACL_PRESENT
) && pRel
->Sacl
)
1002 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Sacl
);
1004 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
1008 if ((pRel
->Control
& SE_DACL_PRESENT
) && pRel
->Dacl
)
1010 PACL pAcl
= (PACL
)SELF_RELATIVE_FIELD( pRel
, Dacl
);
1011 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
1017 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Owner
);
1018 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
1019 pAbs
->Owner
= pOwner
;
1024 PSID psid
= (PSID
)SELF_RELATIVE_FIELD( pRel
, Group
);
1025 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
1026 pAbs
->Group
= pPrimaryGroup
;
1032 /******************************************************************************
1033 * RtlGetControlSecurityDescriptor (NTDLL.@)
1035 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1036 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1037 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1038 LPDWORD lpdwRevision
)
1040 SECURITY_DESCRIPTOR
*lpsd
= pSecurityDescriptor
;
1042 TRACE("(%p,%p,%p)\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1044 *lpdwRevision
= lpsd
->Revision
;
1046 if (*lpdwRevision
!= SECURITY_DESCRIPTOR_REVISION
)
1047 return STATUS_UNKNOWN_REVISION
;
1049 *pControl
= lpsd
->Control
;
1051 return STATUS_SUCCESS
;
1054 /******************************************************************************
1055 * RtlSetControlSecurityDescriptor (NTDLL.@)
1057 NTSTATUS WINAPI
RtlSetControlSecurityDescriptor(
1058 PSECURITY_DESCRIPTOR SecurityDescriptor
,
1059 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest
,
1060 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
)
1062 SECURITY_DESCRIPTOR_CONTROL
const immutable
1063 = SE_OWNER_DEFAULTED
| SE_GROUP_DEFAULTED
1064 | SE_DACL_PRESENT
| SE_DACL_DEFAULTED
1065 | SE_SACL_PRESENT
| SE_SACL_DEFAULTED
1066 | SE_RM_CONTROL_VALID
| SE_SELF_RELATIVE
1069 SECURITY_DESCRIPTOR
*lpsd
= SecurityDescriptor
;
1071 TRACE("(%p 0x%04x 0x%04x)\n", SecurityDescriptor
,
1072 ControlBitsOfInterest
, ControlBitsToSet
);
1074 if ((ControlBitsOfInterest
| ControlBitsToSet
) & immutable
)
1075 return STATUS_INVALID_PARAMETER
;
1077 lpsd
->Control
|= (ControlBitsOfInterest
& ControlBitsToSet
);
1078 lpsd
->Control
&= ~(ControlBitsOfInterest
& ~ControlBitsToSet
);
1080 return STATUS_SUCCESS
;
1084 /**************************************************************************
1085 * RtlAbsoluteToSelfRelativeSD [NTDLL.@]
1087 NTSTATUS WINAPI
RtlAbsoluteToSelfRelativeSD(
1088 PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
,
1089 PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
,
1090 PULONG BufferLength
)
1092 SECURITY_DESCRIPTOR
*abs
= AbsoluteSecurityDescriptor
;
1094 TRACE("%p %p %p\n", AbsoluteSecurityDescriptor
,
1095 SelfRelativeSecurityDescriptor
, BufferLength
);
1097 if (abs
->Control
& SE_SELF_RELATIVE
)
1098 return STATUS_BAD_DESCRIPTOR_FORMAT
;
1100 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor
,
1101 SelfRelativeSecurityDescriptor
, BufferLength
);
1106 * access control list's
1109 /**************************************************************************
1110 * RtlCreateAcl [NTDLL.@]
1113 * This should return NTSTATUS
1115 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
1117 TRACE("%p 0x%08x 0x%08x\n", acl
, size
, rev
);
1119 if (rev
< MIN_ACL_REVISION
|| rev
> MAX_ACL_REVISION
)
1120 return STATUS_INVALID_PARAMETER
;
1121 if (size
<sizeof(ACL
))
1122 return STATUS_BUFFER_TOO_SMALL
;
1124 return STATUS_INVALID_PARAMETER
;
1126 memset(acl
,'\0',sizeof(ACL
));
1127 acl
->AclRevision
= rev
;
1128 acl
->AclSize
= size
;
1130 return STATUS_SUCCESS
;
1133 /**************************************************************************
1134 * RtlFirstFreeAce [NTDLL.@]
1135 * looks for the AceCount+1 ACE, and if it is still within the alloced
1136 * ACL, return a pointer to it
1138 BOOLEAN WINAPI
RtlFirstFreeAce(
1146 ace
= (PACE_HEADER
)(acl
+1);
1147 for (i
=0;i
<acl
->AceCount
;i
++) {
1148 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1150 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1152 if ((BYTE
*)ace
>= (BYTE
*)acl
+ acl
->AclSize
)
1158 /**************************************************************************
1159 * RtlAddAce [NTDLL.@]
1161 NTSTATUS WINAPI
RtlAddAce(
1165 PACE_HEADER acestart
,
1168 PACE_HEADER ace
,targetace
;
1171 if (!RtlValidAcl(acl
))
1172 return STATUS_INVALID_PARAMETER
;
1173 if (!RtlFirstFreeAce(acl
,&targetace
))
1174 return STATUS_INVALID_PARAMETER
;
1175 nrofaces
=0;ace
=acestart
;
1176 while (((BYTE
*)ace
- (BYTE
*)acestart
) < acelen
) {
1178 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1180 if ((BYTE
*)targetace
+ acelen
> (BYTE
*)acl
+ acl
->AclSize
) /* too much aces */
1181 return STATUS_INVALID_PARAMETER
;
1182 memcpy(targetace
,acestart
,acelen
);
1183 acl
->AceCount
+=nrofaces
;
1184 if (rev
> acl
->AclRevision
)
1185 acl
->AclRevision
= rev
;
1186 return STATUS_SUCCESS
;
1189 /**************************************************************************
1190 * RtlDeleteAce [NTDLL.@]
1192 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
1197 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
1199 if (STATUS_SUCCESS
== status
)
1204 /* skip over the ACE we are deleting */
1205 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
1208 /* calculate the length of the rest */
1209 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
1211 len
+= pcAce
->AceSize
;
1212 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
1215 /* slide them all backwards */
1216 memmove(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
1220 TRACE("pAcl=%p dwAceIndex=%d status=0x%08x\n", pAcl
, dwAceIndex
, status
);
1225 /******************************************************************************
1226 * RtlAddAccessAllowedAce [NTDLL.@]
1228 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
1230 IN DWORD dwAceRevision
,
1231 IN DWORD AccessMask
,
1234 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1237 /******************************************************************************
1238 * RtlAddAccessAllowedAceEx [NTDLL.@]
1240 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
1242 IN DWORD dwAceRevision
,
1244 IN DWORD AccessMask
,
1247 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1249 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1250 AccessMask
, pSid
, ACCESS_ALLOWED_ACE_TYPE
);
1253 /******************************************************************************
1254 * RtlAddAccessAllowedObjectAce [NTDLL.@]
1256 NTSTATUS WINAPI
RtlAddAccessAllowedObjectAce(
1258 IN DWORD dwAceRevision
,
1259 IN DWORD dwAceFlags
,
1260 IN DWORD dwAccessMask
,
1261 IN GUID
* pObjectTypeGuid
,
1262 IN GUID
* pInheritedObjectTypeGuid
,
1265 FIXME("%p %x %x %x %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1266 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1267 return STATUS_NOT_IMPLEMENTED
;
1270 /******************************************************************************
1271 * RtlAddAccessDeniedAce [NTDLL.@]
1273 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1275 IN DWORD dwAceRevision
,
1276 IN DWORD AccessMask
,
1279 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1282 /******************************************************************************
1283 * RtlAddAccessDeniedAceEx [NTDLL.@]
1285 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1287 IN DWORD dwAceRevision
,
1289 IN DWORD AccessMask
,
1292 TRACE("(%p,0x%08x,0x%08x,%p)\n", pAcl
, dwAceRevision
, AccessMask
, pSid
);
1294 return add_access_ace(pAcl
, dwAceRevision
, AceFlags
,
1295 AccessMask
, pSid
, ACCESS_DENIED_ACE_TYPE
);
1298 /******************************************************************************
1299 * RtlAddAccessDeniedObjectAce [NTDLL.@]
1301 NTSTATUS WINAPI
RtlAddAccessDeniedObjectAce(
1303 IN DWORD dwAceRevision
,
1304 IN DWORD dwAceFlags
,
1305 IN DWORD dwAccessMask
,
1306 IN GUID
* pObjectTypeGuid
,
1307 IN GUID
* pInheritedObjectTypeGuid
,
1310 FIXME("%p %x %x %x %p %p %p - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1311 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
);
1312 return STATUS_NOT_IMPLEMENTED
;
1315 /**************************************************************************
1316 * RtlAddAuditAccessAce [NTDLL.@]
1318 NTSTATUS WINAPI
RtlAddAuditAccessAceEx(
1320 IN DWORD dwAceRevision
,
1321 IN DWORD dwAceFlags
,
1322 IN DWORD dwAccessMask
,
1324 IN BOOL bAuditSuccess
,
1325 IN BOOL bAuditFailure
)
1327 TRACE("(%p,%d,0x%08x,0x%08x,%p,%u,%u)\n",pAcl
,dwAceRevision
,dwAceFlags
,dwAccessMask
,
1328 pSid
,bAuditSuccess
,bAuditFailure
);
1331 dwAceFlags
|= SUCCESSFUL_ACCESS_ACE_FLAG
;
1334 dwAceFlags
|= FAILED_ACCESS_ACE_FLAG
;
1336 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
,
1337 dwAccessMask
, pSid
, SYSTEM_AUDIT_ACE_TYPE
);
1340 /**************************************************************************
1341 * RtlAddAuditAccessAce [NTDLL.@]
1343 NTSTATUS WINAPI
RtlAddAuditAccessAce(
1345 IN DWORD dwAceRevision
,
1346 IN DWORD dwAccessMask
,
1348 IN BOOL bAuditSuccess
,
1349 IN BOOL bAuditFailure
)
1351 return RtlAddAuditAccessAceEx(pAcl
, dwAceRevision
, 0, dwAccessMask
, pSid
, bAuditSuccess
, bAuditFailure
);
1354 /******************************************************************************
1355 * RtlAddAuditAccessObjectAce [NTDLL.@]
1357 NTSTATUS WINAPI
RtlAddAuditAccessObjectAce(
1359 IN DWORD dwAceRevision
,
1360 IN DWORD dwAceFlags
,
1361 IN DWORD dwAccessMask
,
1362 IN GUID
* pObjectTypeGuid
,
1363 IN GUID
* pInheritedObjectTypeGuid
,
1365 IN BOOL bAuditSuccess
,
1366 IN BOOL bAuditFailure
)
1368 FIXME("%p %x %x %x %p %p %p %d %d - stub\n", pAcl
, dwAceRevision
, dwAceFlags
, dwAccessMask
,
1369 pObjectTypeGuid
, pInheritedObjectTypeGuid
, pSid
, bAuditSuccess
, bAuditFailure
);
1370 return STATUS_NOT_IMPLEMENTED
;
1373 /**************************************************************************
1374 * RtlAddMandatoryAce [NTDLL.@]
1376 NTSTATUS WINAPI
RtlAddMandatoryAce(
1378 IN DWORD dwAceRevision
,
1379 IN DWORD dwAceFlags
,
1380 IN DWORD dwMandatoryFlags
,
1384 static const DWORD valid_flags
= SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
|
1385 SYSTEM_MANDATORY_LABEL_NO_READ_UP
|
1386 SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP
;
1388 TRACE("(%p, %u, 0x%08x, 0x%08x, %u, %p)\n", pAcl
, dwAceRevision
, dwAceFlags
,
1389 dwMandatoryFlags
, dwAceType
, pSid
);
1391 if (dwAceType
!= SYSTEM_MANDATORY_LABEL_ACE_TYPE
)
1392 return STATUS_INVALID_PARAMETER
;
1394 if (dwMandatoryFlags
& ~valid_flags
)
1395 return STATUS_INVALID_PARAMETER
;
1397 return add_access_ace(pAcl
, dwAceRevision
, dwAceFlags
, dwMandatoryFlags
, pSid
, dwAceType
);
1400 /******************************************************************************
1401 * RtlValidAcl [NTDLL.@]
1403 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1406 TRACE("(%p)\n", pAcl
);
1413 if (pAcl
->AclRevision
< MIN_ACL_REVISION
||
1414 pAcl
->AclRevision
> MAX_ACL_REVISION
)
1418 ace
= (PACE_HEADER
)(pAcl
+1);
1420 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1422 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1427 if (i
!= pAcl
->AceCount
)
1428 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1434 WARN("(%p): invalid pointer!\n", pAcl
);
1441 /******************************************************************************
1442 * RtlGetAce [NTDLL.@]
1444 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1448 TRACE("(%p,%d,%p)\n",pAcl
,dwAceIndex
,pAce
);
1450 if (dwAceIndex
>= pAcl
->AceCount
)
1451 return STATUS_INVALID_PARAMETER
;
1453 ace
= (PACE_HEADER
)(pAcl
+ 1);
1454 for (;dwAceIndex
;dwAceIndex
--)
1455 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1459 return STATUS_SUCCESS
;
1466 /******************************************************************************
1467 * RtlAdjustPrivilege [NTDLL.@]
1469 * Enables or disables a privilege from the calling thread or process.
1472 * Privilege [I] Privilege index to change.
1473 * Enable [I] If TRUE, then enable the privilege otherwise disable.
1474 * CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
1475 * Enabled [O] Whether privilege was previously enabled or disabled.
1478 * Success: STATUS_SUCCESS.
1479 * Failure: NTSTATUS code.
1482 * NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
1486 RtlAdjustPrivilege(ULONG Privilege
,
1488 BOOLEAN CurrentThread
,
1491 TOKEN_PRIVILEGES NewState
;
1492 TOKEN_PRIVILEGES OldState
;
1497 TRACE("(%d, %s, %s, %p)\n", Privilege
, Enable
? "TRUE" : "FALSE",
1498 CurrentThread
? "TRUE" : "FALSE", Enabled
);
1502 Status
= NtOpenThreadToken(GetCurrentThread(),
1503 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1509 Status
= NtOpenProcessToken(GetCurrentProcess(),
1510 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1516 WARN("Retrieving token handle failed (Status %x)\n", Status
);
1520 OldState
.PrivilegeCount
= 1;
1522 NewState
.PrivilegeCount
= 1;
1523 NewState
.Privileges
[0].Luid
.LowPart
= Privilege
;
1524 NewState
.Privileges
[0].Luid
.HighPart
= 0;
1525 NewState
.Privileges
[0].Attributes
= (Enable
) ? SE_PRIVILEGE_ENABLED
: 0;
1527 Status
= NtAdjustPrivilegesToken(TokenHandle
,
1530 sizeof(TOKEN_PRIVILEGES
),
1533 NtClose (TokenHandle
);
1534 if (Status
== STATUS_NOT_ALL_ASSIGNED
)
1536 TRACE("Failed to assign all privileges\n");
1537 return STATUS_PRIVILEGE_NOT_HELD
;
1541 WARN("NtAdjustPrivilegesToken() failed (Status %x)\n", Status
);
1545 if (OldState
.PrivilegeCount
== 0)
1548 *Enabled
= (OldState
.Privileges
[0].Attributes
& SE_PRIVILEGE_ENABLED
);
1550 return STATUS_SUCCESS
;
1553 /******************************************************************************
1554 * RtlImpersonateSelf [NTDLL.@]
1556 * Makes an impersonation token that represents the process user and assigns
1557 * to the current thread.
1560 * ImpersonationLevel [I] Level at which to impersonate.
1563 * Success: STATUS_SUCCESS.
1564 * Failure: NTSTATUS code.
1567 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1570 OBJECT_ATTRIBUTES ObjectAttributes
;
1571 HANDLE ProcessToken
;
1572 HANDLE ImpersonationToken
;
1574 TRACE("(%08x)\n", ImpersonationLevel
);
1576 Status
= NtOpenProcessToken( NtCurrentProcess(), TOKEN_DUPLICATE
,
1578 if (Status
!= STATUS_SUCCESS
)
1581 InitializeObjectAttributes( &ObjectAttributes
, NULL
, 0, NULL
, NULL
);
1583 Status
= NtDuplicateToken( ProcessToken
,
1588 &ImpersonationToken
);
1589 if (Status
!= STATUS_SUCCESS
)
1591 NtClose( ProcessToken
);
1595 Status
= NtSetInformationThread( GetCurrentThread(),
1596 ThreadImpersonationToken
,
1597 &ImpersonationToken
,
1598 sizeof(ImpersonationToken
) );
1600 NtClose( ImpersonationToken
);
1601 NtClose( ProcessToken
);
1607 /******************************************************************************
1608 * RtlConvertSidToUnicodeString (NTDLL.@)
1610 * The returned SID is used to access the USER registry hive usually
1612 * the native function returns something like
1613 * "S-1-5-21-0000000000-000000000-0000000000-500";
1615 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1616 PUNICODE_STRING String
,
1618 BOOLEAN AllocateString
)
1620 static const WCHAR formatW
[] = {'-','%','u',0};
1621 WCHAR buffer
[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES
];
1623 const SID
*sid
= pSid
;
1627 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), formatW
, sid
->Revision
);
1628 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), formatW
,
1629 MAKELONG( MAKEWORD( sid
->IdentifierAuthority
.Value
[5],
1630 sid
->IdentifierAuthority
.Value
[4] ),
1631 MAKEWORD( sid
->IdentifierAuthority
.Value
[3],
1632 sid
->IdentifierAuthority
.Value
[2] )));
1633 for (i
= 0; i
< sid
->SubAuthorityCount
; i
++)
1634 p
+= swprintf( p
, ARRAY_SIZE(buffer
) - (p
- buffer
), formatW
, sid
->SubAuthority
[i
] );
1636 len
= (p
+ 1 - buffer
) * sizeof(WCHAR
);
1638 String
->Length
= len
- sizeof(WCHAR
);
1641 String
->MaximumLength
= len
;
1642 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1643 return STATUS_NO_MEMORY
;
1645 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1647 memcpy( String
->Buffer
, buffer
, len
);
1648 return STATUS_SUCCESS
;
1651 /******************************************************************************
1652 * RtlQueryInformationAcl (NTDLL.@)
1654 NTSTATUS WINAPI
RtlQueryInformationAcl(
1656 LPVOID pAclInformation
,
1657 DWORD nAclInformationLength
,
1658 ACL_INFORMATION_CLASS dwAclInformationClass
)
1660 NTSTATUS status
= STATUS_SUCCESS
;
1662 TRACE("pAcl=%p pAclInfo=%p len=%d, class=%d\n",
1663 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1665 switch (dwAclInformationClass
)
1667 case AclRevisionInformation
:
1669 PACL_REVISION_INFORMATION paclrev
= pAclInformation
;
1671 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1672 status
= STATUS_INVALID_PARAMETER
;
1674 paclrev
->AclRevision
= pAcl
->AclRevision
;
1679 case AclSizeInformation
:
1681 PACL_SIZE_INFORMATION paclsize
= pAclInformation
;
1683 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1684 status
= STATUS_INVALID_PARAMETER
;
1687 paclsize
->AceCount
= pAcl
->AceCount
;
1688 paclsize
->AclBytesInUse
= acl_bytesInUse(pAcl
);
1689 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1691 WARN("Acl uses %d bytes, but only has %d allocated! Returning smaller of the two values.\n", pAcl
->AclSize
, paclsize
->AclBytesInUse
);
1692 paclsize
->AclBytesFree
= 0;
1693 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1696 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1703 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1704 status
= STATUS_INVALID_PARAMETER
;
1710 BOOL WINAPI
RtlConvertToAutoInheritSecurityObject(
1711 PSECURITY_DESCRIPTOR pdesc
,
1712 PSECURITY_DESCRIPTOR cdesc
,
1713 PSECURITY_DESCRIPTOR
* ndesc
,
1716 PGENERIC_MAPPING genmap
)
1718 FIXME("%p %p %p %p %d %p - stub\n", pdesc
, cdesc
, ndesc
, objtype
, isdir
, genmap
);