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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/port.h"
37 #include "wine/exception.h"
42 #include "ntdll_misc.h"
44 #include "wine/library.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
49 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
51 /* filter for page-fault exceptions */
52 static WINE_EXCEPTION_FILTER(page_fault
)
54 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
55 return EXCEPTION_EXECUTE_HANDLER
;
56 return EXCEPTION_CONTINUE_SEARCH
;
63 /******************************************************************************
64 * RtlAllocateAndInitializeSid [NTDLL.@]
67 BOOLEAN WINAPI
RtlAllocateAndInitializeSid (
68 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
69 BYTE nSubAuthorityCount
,
70 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
71 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
72 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
73 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
77 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
78 pIdentifierAuthority
,nSubAuthorityCount
,
79 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
80 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
82 if (!(*pSid
= RtlAllocateHeap( GetProcessHeap(), 0,
83 RtlLengthRequiredSid(nSubAuthorityCount
))))
86 ((SID
*)*pSid
)->Revision
= SID_REVISION
;
88 if (pIdentifierAuthority
)
89 memcpy(&((SID
*)*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
90 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
92 if (nSubAuthorityCount
> 0)
93 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
94 if (nSubAuthorityCount
> 1)
95 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
96 if (nSubAuthorityCount
> 2)
97 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
98 if (nSubAuthorityCount
> 3)
99 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
100 if (nSubAuthorityCount
> 4)
101 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
102 if (nSubAuthorityCount
> 5)
103 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
104 if (nSubAuthorityCount
> 6)
105 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
106 if (nSubAuthorityCount
> 7)
107 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
109 return STATUS_SUCCESS
;
111 /******************************************************************************
112 * RtlEqualSid [NTDLL.@]
114 * Determine if two SIDs are equal.
117 * pSid1 [I] Source SID
118 * pSid2 [I] SID to compare with
121 * TRUE, if pSid1 is equal to pSid2,
124 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
126 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
129 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
132 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
138 /******************************************************************************
139 * RtlEqualPrefixSid [NTDLL.@]
141 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
143 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
146 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
149 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
156 /******************************************************************************
157 * RtlFreeSid [NTDLL.@]
159 * Free the resources used by a SID.
162 * pSid [I] SID to Free.
167 DWORD WINAPI
RtlFreeSid(PSID pSid
)
169 TRACE("(%p)\n", pSid
);
170 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
171 return STATUS_SUCCESS
;
174 /**************************************************************************
175 * RtlLengthRequiredSid [NTDLL.@]
177 * Determine the amount of memory a SID will use
180 * nrofsubauths [I] Number of Sub Authorities in the SID.
183 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
185 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
187 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
190 /**************************************************************************
191 * RtlLengthSid [NTDLL.@]
193 * Determine the amount of memory a SID is using
196 * pSid [I] SID to ge the size of.
199 * The size, in bytes, of pSid.
201 DWORD WINAPI
RtlLengthSid(PSID pSid
)
203 TRACE("sid=%p\n",pSid
);
205 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
208 /**************************************************************************
209 * RtlInitializeSid [NTDLL.@]
214 * pSid [I] SID to initialise
215 * pIdentifierAuthority [I] Identifier Authority
216 * nSubAuthorityCount [I] Number of Sub Authorities
219 * Success: TRUE. pSid is initialised withe the details given.
220 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
222 BOOL WINAPI
RtlInitializeSid(
224 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
225 BYTE nSubAuthorityCount
)
230 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
233 pisid
->Revision
= SID_REVISION
;
234 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
235 if (pIdentifierAuthority
)
236 memcpy(&pisid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
238 for (i
= 0; i
< nSubAuthorityCount
; i
++)
239 *RtlSubAuthoritySid(pSid
, i
) = 0;
244 /**************************************************************************
245 * RtlSubAuthoritySid [NTDLL.@]
247 * Return the Sub Authority of a SID
250 * pSid [I] SID to get the Sub Authority from.
251 * nSubAuthority [I] Sub Authority number.
254 * A pointer to The Sub Authority value of pSid.
256 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
258 return &(((SID
*)pSid
)->SubAuthority
[nSubAuthority
]);
261 /**************************************************************************
262 * RtlIdentifierAuthoritySid [NTDLL.@]
264 * Return the Identifier Authority of a SID.
267 * pSid [I] SID to get the Identifier Authority from.
270 * A pointer to the Identifier Authority value of pSid.
272 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
274 return &(((SID
*)pSid
)->IdentifierAuthority
);
277 /**************************************************************************
278 * RtlSubAuthorityCountSid [NTDLL.@]
280 * Get the number of Sub Authorities in a SID.
283 * pSid [I] SID to get the count from.
286 * A pointer to the Sub Authority count of pSid.
288 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
290 return &(((SID
*)pSid
)->SubAuthorityCount
);
293 /**************************************************************************
294 * RtlCopySid [NTDLL.@]
296 DWORD WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
298 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
299 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
302 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
305 memmove(pDestinationSid
, pSourceSid
, ((SID
*)pSourceSid
)->SubAuthorityCount
*4+8);
308 /******************************************************************************
309 * RtlValidSid [NTDLL.@]
311 * Determine if a SID is valid.
314 * pSid [I] SID to check
317 * TRUE if pSid is valid,
320 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
326 if (!pSid
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
327 ((SID
*)pSid
)->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
334 WARN("(%p): invalid pointer!\n", pSid
);
343 * security descriptor functions
346 /**************************************************************************
347 * RtlCreateSecurityDescriptor [NTDLL.@]
349 * Initialise a SECURITY_DESCRIPTOR.
352 * lpsd [O] Descriptor to initialise.
353 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
356 * Success: STATUS_SUCCESS.
357 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
359 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
360 PSECURITY_DESCRIPTOR lpsd
,
363 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
364 return STATUS_UNKNOWN_REVISION
;
365 memset(lpsd
,'\0',sizeof(SECURITY_DESCRIPTOR
));
366 ((SECURITY_DESCRIPTOR
*)lpsd
)->Revision
= SECURITY_DESCRIPTOR_REVISION
;
367 return STATUS_SUCCESS
;
369 /**************************************************************************
370 * RtlValidSecurityDescriptor [NTDLL.@]
372 * Determine if a SECURITY_DESCRIPTOR is valid.
375 * SecurityDescriptor [I] Descriptor to check.
378 * Success: STATUS_SUCCESS.
379 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
381 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
382 PSECURITY_DESCRIPTOR SecurityDescriptor
)
384 if ( ! SecurityDescriptor
)
385 return STATUS_INVALID_SECURITY_DESCR
;
386 if ( ((SECURITY_DESCRIPTOR
*)SecurityDescriptor
)->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
387 return STATUS_UNKNOWN_REVISION
;
389 return STATUS_SUCCESS
;
392 /**************************************************************************
393 * RtlLengthSecurityDescriptor [NTDLL.@]
395 ULONG WINAPI
RtlLengthSecurityDescriptor(
396 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
398 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
400 ULONG Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
405 if ( lpsd
->Control
& SE_SELF_RELATIVE
)
406 offset
= (ULONG
) lpsd
;
408 if ( lpsd
->Owner
!= NULL
)
409 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Owner
+ offset
));
411 if ( lpsd
->Group
!= NULL
)
412 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Group
+ offset
));
414 if ( lpsd
->Sacl
!= NULL
)
415 Size
+= ((PACL
)((LPBYTE
)lpsd
->Sacl
+ offset
))->AclSize
;
417 if ( lpsd
->Dacl
!= NULL
)
418 Size
+= ((PACL
)((LPBYTE
)lpsd
->Dacl
+ offset
))->AclSize
;
423 /******************************************************************************
424 * RtlGetDaclSecurityDescriptor [NTDLL.@]
427 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
428 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
429 OUT PBOOLEAN lpbDaclPresent
,
431 OUT PBOOLEAN lpbDaclDefaulted
)
433 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
435 TRACE("(%p,%p,%p,%p)\n",
436 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
438 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
439 return STATUS_UNKNOWN_REVISION
;
441 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
443 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
444 { *pDacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Dacl
);
447 { *pDacl
= lpsd
->Dacl
;
451 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
453 return STATUS_SUCCESS
;
456 /**************************************************************************
457 * RtlSetDaclSecurityDescriptor [NTDLL.@]
459 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
460 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
463 BOOLEAN dacldefaulted
)
465 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
467 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
468 return STATUS_UNKNOWN_REVISION
;
469 if (lpsd
->Control
& SE_SELF_RELATIVE
)
470 return STATUS_INVALID_SECURITY_DESCR
;
473 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
477 lpsd
->Control
|= SE_DACL_PRESENT
;
481 lpsd
->Control
|= SE_DACL_DEFAULTED
;
483 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
485 return STATUS_SUCCESS
;
488 /******************************************************************************
489 * RtlGetSaclSecurityDescriptor [NTDLL.@]
492 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
493 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
494 OUT PBOOLEAN lpbSaclPresent
,
496 OUT PBOOLEAN lpbSaclDefaulted
)
498 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
500 TRACE("(%p,%p,%p,%p)\n",
501 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
503 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
504 return STATUS_UNKNOWN_REVISION
;
506 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
508 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
509 { *pSacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Sacl
);
512 { *pSacl
= lpsd
->Sacl
;
516 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
518 return STATUS_SUCCESS
;
521 /**************************************************************************
522 * RtlSetSaclSecurityDescriptor [NTDLL.@]
524 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
525 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
528 BOOLEAN sacldefaulted
)
530 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
532 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
533 return STATUS_UNKNOWN_REVISION
;
534 if (lpsd
->Control
& SE_SELF_RELATIVE
)
535 return STATUS_INVALID_SECURITY_DESCR
;
537 lpsd
->Control
&= ~SE_SACL_PRESENT
;
540 lpsd
->Control
|= SE_SACL_PRESENT
;
543 lpsd
->Control
|= SE_SACL_DEFAULTED
;
545 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
546 return STATUS_SUCCESS
;
549 /**************************************************************************
550 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
552 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
553 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
555 PBOOLEAN OwnerDefaulted
)
557 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
559 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
560 return STATUS_INVALID_PARAMETER
;
562 if (lpsd
->Owner
!= NULL
)
564 if (lpsd
->Control
& SE_SELF_RELATIVE
)
565 *Owner
= (PSID
)((LPBYTE
)lpsd
+
568 *Owner
= lpsd
->Owner
;
570 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
571 *OwnerDefaulted
= TRUE
;
573 *OwnerDefaulted
= FALSE
;
578 return STATUS_SUCCESS
;
581 /**************************************************************************
582 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
584 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
585 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
587 BOOLEAN ownerdefaulted
)
589 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
591 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
592 return STATUS_UNKNOWN_REVISION
;
593 if (lpsd
->Control
& SE_SELF_RELATIVE
)
594 return STATUS_INVALID_SECURITY_DESCR
;
598 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
600 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
601 return STATUS_SUCCESS
;
604 /**************************************************************************
605 * RtlSetGroupSecurityDescriptor [NTDLL.@]
607 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
608 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
610 BOOLEAN groupdefaulted
)
612 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
614 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
615 return STATUS_UNKNOWN_REVISION
;
616 if (lpsd
->Control
& SE_SELF_RELATIVE
)
617 return STATUS_INVALID_SECURITY_DESCR
;
621 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
623 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
624 return STATUS_SUCCESS
;
626 /**************************************************************************
627 * RtlGetGroupSecurityDescriptor [NTDLL.@]
629 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
630 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
632 PBOOLEAN GroupDefaulted
)
634 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
636 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
637 return STATUS_INVALID_PARAMETER
;
639 if (lpsd
->Group
!= NULL
)
641 if (lpsd
->Control
& SE_SELF_RELATIVE
)
642 *Group
= (PSID
)((LPBYTE
)lpsd
+
645 *Group
= lpsd
->Group
;
647 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
648 *GroupDefaulted
= TRUE
;
650 *GroupDefaulted
= FALSE
;
655 return STATUS_SUCCESS
;
658 /**************************************************************************
659 * RtlMakeSelfRelativeSD [NTDLL.@]
661 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
662 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
663 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
664 IN OUT LPDWORD lpdwBufferLength
)
668 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
669 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
671 TRACE(" %p %p %p(%ld)\n", pAbs
, pRel
, lpdwBufferLength
,
672 lpdwBufferLength
? *lpdwBufferLength
: -1);
674 if (!lpdwBufferLength
|| !pAbs
)
675 return STATUS_INVALID_PARAMETER
;
677 length
= RtlLengthSecurityDescriptor(pAbs
);
678 if (*lpdwBufferLength
< length
)
680 *lpdwBufferLength
= length
;
681 return STATUS_BUFFER_TOO_SMALL
;
685 return STATUS_INVALID_PARAMETER
;
687 if (pAbs
->Control
& SE_SELF_RELATIVE
)
689 memcpy(pRel
, pAbs
, length
);
690 return STATUS_SUCCESS
;
693 pRel
->Revision
= pAbs
->Revision
;
694 pRel
->Sbz1
= pAbs
->Sbz1
;
695 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
697 offsetRel
= sizeof(SECURITY_DESCRIPTOR
);
698 pRel
->Owner
= (PSID
) offsetRel
;
699 length
= RtlLengthSid(pAbs
->Owner
);
700 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
703 pRel
->Group
= (PSID
) offsetRel
;
704 length
= RtlLengthSid(pAbs
->Group
);
705 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
707 if (pRel
->Control
& SE_SACL_PRESENT
)
710 pRel
->Sacl
= (PACL
) offsetRel
;
711 length
= pAbs
->Sacl
->AclSize
;
712 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
719 if (pRel
->Control
& SE_DACL_PRESENT
)
722 pRel
->Dacl
= (PACL
) offsetRel
;
723 length
= pAbs
->Dacl
->AclSize
;
724 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
731 return STATUS_SUCCESS
;
735 /**************************************************************************
736 + * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
738 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
739 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
740 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
741 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
743 OUT LPDWORD lpdwDaclSize
,
745 OUT LPDWORD lpdwSaclSize
,
747 OUT LPDWORD lpdwOwnerSize
,
748 OUT PSID pPrimaryGroup
,
749 OUT LPDWORD lpdwPrimaryGroupSize
)
751 NTSTATUS status
= STATUS_SUCCESS
;
752 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
753 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
756 !lpdwAbsoluteSecurityDescriptorSize
||
760 !lpdwPrimaryGroupSize
||
761 ~pRel
->Control
& SE_SELF_RELATIVE
)
762 return STATUS_INVALID_PARAMETER
;
764 /* Confirm buffers are sufficiently large */
765 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
767 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
768 status
= STATUS_BUFFER_TOO_SMALL
;
771 if (pRel
->Control
& SE_DACL_PRESENT
&&
772 *lpdwDaclSize
< ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
)
774 *lpdwDaclSize
= ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
;
775 status
= STATUS_BUFFER_TOO_SMALL
;
778 if (pRel
->Control
& SE_SACL_PRESENT
&&
779 *lpdwSaclSize
< ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
)
781 *lpdwSaclSize
= ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
;
782 status
= STATUS_BUFFER_TOO_SMALL
;
786 *lpdwOwnerSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
)))
788 *lpdwOwnerSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
));
789 status
= STATUS_BUFFER_TOO_SMALL
;
793 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
)))
795 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
));
796 status
= STATUS_BUFFER_TOO_SMALL
;
799 if (status
!= STATUS_SUCCESS
)
802 /* Copy structures */
803 pAbs
->Revision
= pRel
->Revision
;
804 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
806 if (pRel
->Control
& SE_SACL_PRESENT
)
808 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
);
810 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
814 if (pRel
->Control
& SE_DACL_PRESENT
)
816 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
);
817 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
823 PSID psid
= (PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
);
824 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
825 pAbs
->Owner
= pOwner
;
830 PSID psid
= (PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
);
831 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
832 pAbs
->Group
= pPrimaryGroup
;
839 * access control list's
842 /**************************************************************************
843 * RtlCreateAcl [NTDLL.@]
846 * This should return NTSTATUS
848 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
850 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
852 if (rev
!=ACL_REVISION
)
853 return STATUS_INVALID_PARAMETER
;
854 if (size
<sizeof(ACL
))
855 return STATUS_BUFFER_TOO_SMALL
;
857 return STATUS_INVALID_PARAMETER
;
859 memset(acl
,'\0',sizeof(ACL
));
860 acl
->AclRevision
= rev
;
863 return STATUS_SUCCESS
;
866 /**************************************************************************
867 * RtlFirstFreeAce [NTDLL.@]
868 * looks for the AceCount+1 ACE, and if it is still within the alloced
869 * ACL, return a pointer to it
871 BOOLEAN WINAPI
RtlFirstFreeAce(
879 ace
= (PACE_HEADER
)(acl
+1);
880 for (i
=0;i
<acl
->AceCount
;i
++) {
881 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
883 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
885 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
891 /**************************************************************************
892 * RtlAddAce [NTDLL.@]
894 NTSTATUS WINAPI
RtlAddAce(
898 PACE_HEADER acestart
,
901 PACE_HEADER ace
,targetace
;
904 if (acl
->AclRevision
!= ACL_REVISION
)
905 return STATUS_INVALID_PARAMETER
;
906 if (!RtlFirstFreeAce(acl
,&targetace
))
907 return STATUS_INVALID_PARAMETER
;
908 nrofaces
=0;ace
=acestart
;
909 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
911 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
913 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
914 return STATUS_INVALID_PARAMETER
;
915 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
916 acl
->AceCount
+=nrofaces
;
917 return STATUS_SUCCESS
;
920 /**************************************************************************
921 * RtlDeleteAce [NTDLL.@]
923 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
928 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
930 if (STATUS_SUCCESS
== status
)
935 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
936 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
938 len
+= pcAce
->AceSize
;
939 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
942 memcpy(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
949 /******************************************************************************
950 * RtlAddAccessAllowedAce [NTDLL.@]
952 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
954 IN DWORD dwAceRevision
,
958 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
961 /******************************************************************************
962 * RtlAddAccessAllowedAceEx [NTDLL.@]
964 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
966 IN DWORD dwAceRevision
,
972 ACCESS_ALLOWED_ACE
* pAaAce
;
975 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
976 pAcl
, dwAceRevision
, AccessMask
, pSid
);
978 if (!RtlValidSid(pSid
))
979 return STATUS_INVALID_SID
;
980 if (!RtlValidAcl(pAcl
))
981 return STATUS_INVALID_ACL
;
983 dwLengthSid
= RtlLengthSid(pSid
);
984 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAaAce
))
985 return STATUS_INVALID_ACL
;
988 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
990 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAaAce
;
991 if (dwSpaceLeft
< sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
)
992 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
994 pAaAce
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
995 pAaAce
->Header
.AceFlags
= AceFlags
;
996 pAaAce
->Header
.AceSize
= sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
;
997 pAaAce
->Mask
= AccessMask
;
999 RtlCopySid(dwLengthSid
, (PSID
)&pAaAce
->SidStart
, pSid
);
1000 return STATUS_SUCCESS
;
1003 /******************************************************************************
1004 * RtlAddAccessDeniedAce [NTDLL.@]
1006 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1008 IN DWORD dwAceRevision
,
1009 IN DWORD AccessMask
,
1012 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1015 /******************************************************************************
1016 * RtlAddAccessDeniedAceEx [NTDLL.@]
1018 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1020 IN DWORD dwAceRevision
,
1022 IN DWORD AccessMask
,
1027 ACCESS_DENIED_ACE
* pAdAce
;
1029 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1030 pAcl
, dwAceRevision
, AccessMask
, pSid
);
1032 if (!RtlValidSid(pSid
))
1033 return STATUS_INVALID_SID
;
1034 if (!RtlValidAcl(pAcl
))
1035 return STATUS_INVALID_ACL
;
1037 dwLengthSid
= RtlLengthSid(pSid
);
1038 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAdAce
))
1039 return STATUS_INVALID_ACL
;
1042 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1044 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAdAce
;
1045 if (dwSpaceLeft
< sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
)
1046 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1048 pAdAce
->Header
.AceType
= ACCESS_DENIED_ACE_TYPE
;
1049 pAdAce
->Header
.AceFlags
= AceFlags
;
1050 pAdAce
->Header
.AceSize
= sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
;
1051 pAdAce
->Mask
= AccessMask
;
1053 RtlCopySid(dwLengthSid
, (PSID
)&pAdAce
->SidStart
, pSid
);
1054 return STATUS_SUCCESS
;
1057 /******************************************************************************
1058 * RtlValidAcl [NTDLL.@]
1060 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1063 TRACE("(%p)\n", pAcl
);
1070 if (pAcl
->AclRevision
!= ACL_REVISION
)
1074 ace
= (PACE_HEADER
)(pAcl
+1);
1076 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1078 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1083 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1087 __EXCEPT(page_fault
)
1089 WARN("(%p): invalid pointer!\n", pAcl
);
1096 /******************************************************************************
1097 * RtlGetAce [NTDLL.@]
1099 DWORD WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1103 TRACE("(%p,%ld,%p)\n",pAcl
,dwAceIndex
,pAce
);
1105 if ((dwAceIndex
< 0) || (dwAceIndex
> pAcl
->AceCount
))
1106 return STATUS_INVALID_PARAMETER
;
1108 ace
= (PACE_HEADER
)(pAcl
+ 1);
1109 for (;dwAceIndex
;dwAceIndex
--)
1110 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1112 *pAce
= (LPVOID
) ace
;
1114 return STATUS_SUCCESS
;
1121 /******************************************************************************
1122 * RtlAdjustPrivilege [NTDLL.@]
1124 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
1126 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
1130 /******************************************************************************
1131 * RtlImpersonateSelf [NTDLL.@]
1134 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1136 FIXME("(%08x), stub\n", ImpersonationLevel
);
1140 /******************************************************************************
1141 * NtAccessCheck [NTDLL.@]
1142 * ZwAccessCheck [NTDLL.@]
1146 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1147 IN HANDLE ClientToken
,
1148 IN ACCESS_MASK DesiredAccess
,
1149 IN PGENERIC_MAPPING GenericMapping
,
1150 OUT PPRIVILEGE_SET PrivilegeSet
,
1151 OUT PULONG ReturnLength
,
1152 OUT PULONG GrantedAccess
,
1153 OUT PBOOLEAN AccessStatus
)
1155 FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1156 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
1157 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
1158 *AccessStatus
= TRUE
;
1159 return STATUS_SUCCESS
;
1162 /******************************************************************************
1163 * NtSetSecurityObject [NTDLL.@]
1166 NtSetSecurityObject(
1168 IN SECURITY_INFORMATION SecurityInformation
,
1169 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
1171 FIXME("%p 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
1172 return STATUS_SUCCESS
;
1175 /******************************************************************************
1176 * RtlGetControlSecurityDescriptor (NTDLL.@)
1179 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1180 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1181 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1182 LPDWORD lpdwRevision
)
1184 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1185 return STATUS_SUCCESS
;
1188 /******************************************************************************
1189 * RtlConvertSidToUnicodeString (NTDLL.@)
1191 * The returned SID is used to access the USER registry hive usually
1193 * the native function returns something like
1194 * "S-1-5-21-0000000000-000000000-0000000000-500";
1196 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1197 PUNICODE_STRING String
,
1199 BOOLEAN AllocateString
)
1201 const char *user
= wine_get_user_name();
1202 int len
= ntdll_umbstowcs( 0, user
, strlen(user
)+1, NULL
, 0 ) * sizeof(WCHAR
);
1204 FIXME("(%p %p %u)\n", String
, Sid
, AllocateString
);
1206 String
->Length
= len
- sizeof(WCHAR
);
1209 String
->MaximumLength
= len
;
1210 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1211 return STATUS_NO_MEMORY
;
1213 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1215 ntdll_umbstowcs( 0, user
, strlen(user
)+1, String
->Buffer
, len
/sizeof(WCHAR
) );
1216 return STATUS_SUCCESS
;
1219 /******************************************************************************
1220 * RtlQueryInformationAcl (NTDLL.@)
1222 NTSTATUS WINAPI
RtlQueryInformationAcl(
1224 LPVOID pAclInformation
,
1225 DWORD nAclInformationLength
,
1226 ACL_INFORMATION_CLASS dwAclInformationClass
)
1228 NTSTATUS status
= STATUS_SUCCESS
;
1230 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1231 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1233 switch (dwAclInformationClass
)
1235 case AclRevisionInformation
:
1237 PACL_REVISION_INFORMATION paclrev
= (PACL_REVISION_INFORMATION
) pAclInformation
;
1239 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1240 status
= STATUS_INVALID_PARAMETER
;
1242 paclrev
->AclRevision
= pAcl
->AclRevision
;
1247 case AclSizeInformation
:
1249 PACL_SIZE_INFORMATION paclsize
= (PACL_SIZE_INFORMATION
) pAclInformation
;
1251 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1252 status
= STATUS_INVALID_PARAMETER
;
1258 paclsize
->AceCount
= pAcl
->AceCount
;
1260 paclsize
->AclBytesInUse
= 0;
1261 ace
= (PACE_HEADER
) (pAcl
+ 1);
1263 for (i
= 0; i
< pAcl
->AceCount
; i
++)
1265 paclsize
->AclBytesInUse
+= ace
->AceSize
;
1266 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1269 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1271 WARN("Acl has %ld bytes free\n", pAcl
->AclSize
- paclsize
->AclBytesInUse
);
1272 paclsize
->AclBytesFree
= 0;
1273 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1276 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1283 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1284 status
= STATUS_INVALID_PARAMETER
;