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
,
76 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
77 pIdentifierAuthority
,nSubAuthorityCount
,
78 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
79 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
81 if (!(*pSid
= RtlAllocateHeap( GetProcessHeap(), 0,
82 RtlLengthRequiredSid(nSubAuthorityCount
))))
85 (*pSid
)->Revision
= SID_REVISION
;
87 if (pIdentifierAuthority
)
88 memcpy(&(*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
89 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
91 if (nSubAuthorityCount
> 0)
92 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
93 if (nSubAuthorityCount
> 1)
94 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
95 if (nSubAuthorityCount
> 2)
96 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
97 if (nSubAuthorityCount
> 3)
98 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
99 if (nSubAuthorityCount
> 4)
100 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
101 if (nSubAuthorityCount
> 5)
102 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
103 if (nSubAuthorityCount
> 6)
104 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
105 if (nSubAuthorityCount
> 7)
106 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
108 return STATUS_SUCCESS
;
110 /******************************************************************************
111 * RtlEqualSid [NTDLL.@]
113 * Determine if two SIDs are equal.
116 * pSid1 [I] Source SID
117 * pSid2 [I] SID to compare with
120 * TRUE, if pSid1 is equal to pSid2,
123 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
125 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
128 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
131 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
137 /******************************************************************************
138 * RtlEqualPrefixSid [NTDLL.@]
140 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
142 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
145 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
148 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(pSid1
->SubAuthorityCount
- 1)) != 0)
155 /******************************************************************************
156 * RtlFreeSid [NTDLL.@]
158 * Free the resources used by a SID.
161 * pSid [I] SID to Free.
166 DWORD WINAPI
RtlFreeSid(PSID pSid
)
168 TRACE("(%p)\n", pSid
);
169 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
170 return STATUS_SUCCESS
;
173 /**************************************************************************
174 * RtlLengthRequiredSid [NTDLL.@]
176 * Determine the amount of memory a SID will use
179 * nrofsubauths [I] Number of Sub Authorities in the SID.
182 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
184 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
186 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
189 /**************************************************************************
190 * RtlLengthSid [NTDLL.@]
192 * Determine the amount of memory a SID is using
195 * pSid [I] SID to ge the size of.
198 * The size, in bytes, of pSid.
200 DWORD WINAPI
RtlLengthSid(PSID pSid
)
202 TRACE("sid=%p\n",pSid
);
204 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
207 /**************************************************************************
208 * RtlInitializeSid [NTDLL.@]
213 * pSid [I] SID to initialise
214 * pIdentifierAuthority [I] Identifier Authority
215 * nSubAuthorityCount [I] Number of Sub Authorities
218 * Success: TRUE. pSid is initialised withe the details given.
219 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
221 BOOL WINAPI
RtlInitializeSid(
223 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
224 BYTE nSubAuthorityCount
)
227 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
230 pSid
->Revision
= SID_REVISION
;
231 pSid
->SubAuthorityCount
= nSubAuthorityCount
;
232 if (pIdentifierAuthority
)
233 memcpy(&pSid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
235 for (i
= 0; i
< nSubAuthorityCount
; i
++)
236 *RtlSubAuthoritySid(pSid
, i
) = 0;
241 /**************************************************************************
242 * RtlSubAuthoritySid [NTDLL.@]
244 * Return the Sub Authority of a SID
247 * pSid [I] SID to get the Sub Authority from.
248 * nSubAuthority [I] Sub Authority number.
251 * A pointer to The Sub Authority value of pSid.
253 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
255 return &(pSid
->SubAuthority
[nSubAuthority
]);
258 /**************************************************************************
259 * RtlIdentifierAuthoritySid [NTDLL.@]
261 * Return the Identifier Authority of a SID.
264 * pSid [I] SID to get the Identifier Authority from.
267 * A pointer to the Identifier Authority value of pSid.
269 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
271 return &(pSid
->IdentifierAuthority
);
274 /**************************************************************************
275 * RtlSubAuthorityCountSid [NTDLL.@]
277 * Get the number of Sub Authorities in a SID.
280 * pSid [I] SID to get the count from.
283 * A pointer to the Sub Authority count of pSid.
285 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
287 return &(pSid
->SubAuthorityCount
);
290 /**************************************************************************
291 * RtlCopySid [NTDLL.@]
293 DWORD WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
295 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
296 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
299 if (nDestinationSidLength
< (pSourceSid
->SubAuthorityCount
*4+8))
302 memmove(pDestinationSid
, pSourceSid
, pSourceSid
->SubAuthorityCount
*4+8);
305 /******************************************************************************
306 * RtlValidSid [NTDLL.@]
308 * Determine if a SID is valid.
311 * pSid [I] SID to check
314 * TRUE if pSid is valid,
317 BOOLEAN WINAPI
RtlValidSid( PSID pSid
)
323 if (!pSid
|| pSid
->Revision
!= SID_REVISION
||
324 pSid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
331 WARN("(%p): invalid pointer!\n", pSid
);
340 * security descriptor functions
343 /**************************************************************************
344 * RtlCreateSecurityDescriptor [NTDLL.@]
346 * Initialise a SECURITY_DESCRIPTOR.
349 * lpsd [O] Descriptor to initialise.
350 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
353 * Success: STATUS_SUCCESS.
354 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
356 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
357 PSECURITY_DESCRIPTOR lpsd
,
360 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
361 return STATUS_UNKNOWN_REVISION
;
362 memset(lpsd
,'\0',sizeof(*lpsd
));
363 lpsd
->Revision
= SECURITY_DESCRIPTOR_REVISION
;
364 return STATUS_SUCCESS
;
366 /**************************************************************************
367 * RtlValidSecurityDescriptor [NTDLL.@]
369 * Determine if a SECURITY_DESCRIPTOR is valid.
372 * SecurityDescriptor [I] Descriptor to check.
375 * Success: STATUS_SUCCESS.
376 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
378 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
379 PSECURITY_DESCRIPTOR SecurityDescriptor
)
381 if ( ! SecurityDescriptor
)
382 return STATUS_INVALID_SECURITY_DESCR
;
383 if ( SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
384 return STATUS_UNKNOWN_REVISION
;
386 return STATUS_SUCCESS
;
389 /**************************************************************************
390 * RtlLengthSecurityDescriptor [NTDLL.@]
392 ULONG WINAPI
RtlLengthSecurityDescriptor(
393 PSECURITY_DESCRIPTOR SecurityDescriptor
)
396 ULONG Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
398 if ( SecurityDescriptor
== NULL
)
401 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
402 offset
= (ULONG
) SecurityDescriptor
;
404 if ( SecurityDescriptor
->Owner
!= NULL
)
405 Size
+= RtlLengthSid((PSID
)((LPBYTE
)SecurityDescriptor
->Owner
+ offset
));
407 if ( SecurityDescriptor
->Group
!= NULL
)
408 Size
+= RtlLengthSid((PSID
)((LPBYTE
)SecurityDescriptor
->Group
+ offset
));
410 if ( SecurityDescriptor
->Sacl
!= NULL
)
411 Size
+= ((PACL
)((LPBYTE
)SecurityDescriptor
->Sacl
+ offset
))->AclSize
;
413 if ( SecurityDescriptor
->Dacl
!= NULL
)
414 Size
+= ((PACL
)((LPBYTE
)SecurityDescriptor
->Dacl
+ offset
))->AclSize
;
419 /******************************************************************************
420 * RtlGetDaclSecurityDescriptor [NTDLL.@]
423 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
424 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
425 OUT PBOOLEAN lpbDaclPresent
,
427 OUT PBOOLEAN lpbDaclDefaulted
)
429 TRACE("(%p,%p,%p,%p)\n",
430 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
432 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
433 return STATUS_UNKNOWN_REVISION
;
435 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
437 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
438 { *pDacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Dacl
);
441 { *pDacl
= pSecurityDescriptor
->Dacl
;
445 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
447 return STATUS_SUCCESS
;
450 /**************************************************************************
451 * RtlSetDaclSecurityDescriptor [NTDLL.@]
453 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
454 PSECURITY_DESCRIPTOR lpsd
,
457 BOOLEAN dacldefaulted
)
459 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
460 return STATUS_UNKNOWN_REVISION
;
461 if (lpsd
->Control
& SE_SELF_RELATIVE
)
462 return STATUS_INVALID_SECURITY_DESCR
;
465 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
469 lpsd
->Control
|= SE_DACL_PRESENT
;
473 lpsd
->Control
|= SE_DACL_DEFAULTED
;
475 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
477 return STATUS_SUCCESS
;
480 /******************************************************************************
481 * RtlGetSaclSecurityDescriptor [NTDLL.@]
484 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
485 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
486 OUT PBOOLEAN lpbSaclPresent
,
488 OUT PBOOLEAN lpbSaclDefaulted
)
490 TRACE("(%p,%p,%p,%p)\n",
491 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
493 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
494 return STATUS_UNKNOWN_REVISION
;
496 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
498 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
499 { *pSacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Sacl
);
502 { *pSacl
= pSecurityDescriptor
->Sacl
;
506 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
508 return STATUS_SUCCESS
;
511 /**************************************************************************
512 * RtlSetSaclSecurityDescriptor [NTDLL.@]
514 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
515 PSECURITY_DESCRIPTOR lpsd
,
518 BOOLEAN sacldefaulted
)
520 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
521 return STATUS_UNKNOWN_REVISION
;
522 if (lpsd
->Control
& SE_SELF_RELATIVE
)
523 return STATUS_INVALID_SECURITY_DESCR
;
525 lpsd
->Control
&= ~SE_SACL_PRESENT
;
528 lpsd
->Control
|= SE_SACL_PRESENT
;
531 lpsd
->Control
|= SE_SACL_DEFAULTED
;
533 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
534 return STATUS_SUCCESS
;
537 /**************************************************************************
538 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
540 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
541 PSECURITY_DESCRIPTOR SecurityDescriptor
,
543 PBOOLEAN OwnerDefaulted
)
545 if ( !SecurityDescriptor
|| !Owner
|| !OwnerDefaulted
)
546 return STATUS_INVALID_PARAMETER
;
548 if (SecurityDescriptor
->Owner
!= NULL
)
550 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
551 *Owner
= (PSID
)((LPBYTE
)SecurityDescriptor
+
552 (ULONG
)SecurityDescriptor
->Owner
);
554 *Owner
= SecurityDescriptor
->Owner
;
556 if ( SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
)
557 *OwnerDefaulted
= TRUE
;
559 *OwnerDefaulted
= FALSE
;
564 return STATUS_SUCCESS
;
567 /**************************************************************************
568 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
570 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
571 PSECURITY_DESCRIPTOR lpsd
,
573 BOOLEAN ownerdefaulted
)
575 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
576 return STATUS_UNKNOWN_REVISION
;
577 if (lpsd
->Control
& SE_SELF_RELATIVE
)
578 return STATUS_INVALID_SECURITY_DESCR
;
582 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
584 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
585 return STATUS_SUCCESS
;
588 /**************************************************************************
589 * RtlSetGroupSecurityDescriptor [NTDLL.@]
591 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
592 PSECURITY_DESCRIPTOR lpsd
,
594 BOOLEAN groupdefaulted
)
596 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
597 return STATUS_UNKNOWN_REVISION
;
598 if (lpsd
->Control
& SE_SELF_RELATIVE
)
599 return STATUS_INVALID_SECURITY_DESCR
;
603 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
605 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
606 return STATUS_SUCCESS
;
608 /**************************************************************************
609 * RtlGetGroupSecurityDescriptor [NTDLL.@]
611 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
612 PSECURITY_DESCRIPTOR SecurityDescriptor
,
614 PBOOLEAN GroupDefaulted
)
616 if ( !SecurityDescriptor
|| !Group
|| !GroupDefaulted
)
617 return STATUS_INVALID_PARAMETER
;
619 if (SecurityDescriptor
->Group
!= NULL
)
621 if (SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
622 *Group
= (PSID
)((LPBYTE
)SecurityDescriptor
+
623 (ULONG
)SecurityDescriptor
->Group
);
625 *Group
= SecurityDescriptor
->Group
;
627 if ( SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
)
628 *GroupDefaulted
= TRUE
;
630 *GroupDefaulted
= FALSE
;
635 return STATUS_SUCCESS
;
638 /**************************************************************************
639 * RtlMakeSelfRelativeSD [NTDLL.@]
641 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
642 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
643 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
644 IN OUT LPDWORD lpdwBufferLength
)
648 PSECURITY_DESCRIPTOR pAbs
= pAbsoluteSecurityDescriptor
;
649 PSECURITY_DESCRIPTOR pRel
= pSelfRelativeSecurityDescriptor
;
651 TRACE(" %p %p %p(%ld)\n", pAbs
, pRel
, lpdwBufferLength
,
652 lpdwBufferLength
? *lpdwBufferLength
: -1);
654 if (!lpdwBufferLength
|| !pAbs
)
655 return STATUS_INVALID_PARAMETER
;
657 length
= RtlLengthSecurityDescriptor(pAbs
);
658 if (*lpdwBufferLength
< length
)
660 *lpdwBufferLength
= length
;
661 return STATUS_BUFFER_TOO_SMALL
;
665 return STATUS_INVALID_PARAMETER
;
667 if (pAbs
->Control
& SE_SELF_RELATIVE
)
669 memcpy(pRel
, pAbs
, length
);
670 return STATUS_SUCCESS
;
673 pRel
->Revision
= pAbs
->Revision
;
674 pRel
->Sbz1
= pAbs
->Sbz1
;
675 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
677 offsetRel
= sizeof(SECURITY_DESCRIPTOR
);
678 pRel
->Owner
= (PSID
) offsetRel
;
679 length
= RtlLengthSid(pAbs
->Owner
);
680 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
683 pRel
->Group
= (PSID
) offsetRel
;
684 length
= RtlLengthSid(pAbs
->Group
);
685 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
687 if (pRel
->Control
& SE_SACL_PRESENT
)
690 pRel
->Sacl
= (PACL
) offsetRel
;
691 length
= pAbs
->Sacl
->AclSize
;
692 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
699 if (pRel
->Control
& SE_DACL_PRESENT
)
702 pRel
->Dacl
= (PACL
) offsetRel
;
703 length
= pAbs
->Dacl
->AclSize
;
704 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
711 return STATUS_SUCCESS
;
715 /**************************************************************************
716 + * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
718 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
719 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
720 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
721 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
723 OUT LPDWORD lpdwDaclSize
,
725 OUT LPDWORD lpdwSaclSize
,
727 OUT LPDWORD lpdwOwnerSize
,
728 OUT PSID pPrimaryGroup
,
729 OUT LPDWORD lpdwPrimaryGroupSize
)
731 NTSTATUS status
= STATUS_SUCCESS
;
732 PSECURITY_DESCRIPTOR pAbs
= pAbsoluteSecurityDescriptor
;
733 PSECURITY_DESCRIPTOR pRel
= pSelfRelativeSecurityDescriptor
;
736 !lpdwAbsoluteSecurityDescriptorSize
||
740 !lpdwPrimaryGroupSize
||
741 ~pRel
->Control
& SE_SELF_RELATIVE
)
742 return STATUS_INVALID_PARAMETER
;
744 /* Confirm buffers are sufficiently large */
745 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
747 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
748 status
= STATUS_BUFFER_TOO_SMALL
;
751 if (pRel
->Control
& SE_DACL_PRESENT
&&
752 *lpdwDaclSize
< ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
)
754 *lpdwDaclSize
= ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
;
755 status
= STATUS_BUFFER_TOO_SMALL
;
758 if (pRel
->Control
& SE_SACL_PRESENT
&&
759 *lpdwSaclSize
< ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
)
761 *lpdwSaclSize
= ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
;
762 status
= STATUS_BUFFER_TOO_SMALL
;
766 *lpdwOwnerSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
)))
768 *lpdwOwnerSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
));
769 status
= STATUS_BUFFER_TOO_SMALL
;
773 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
)))
775 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
));
776 status
= STATUS_BUFFER_TOO_SMALL
;
779 if (status
!= STATUS_SUCCESS
)
782 /* Copy structures */
783 pAbs
->Revision
= pRel
->Revision
;
784 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
786 if (pRel
->Control
& SE_SACL_PRESENT
)
788 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
);
790 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
794 if (pRel
->Control
& SE_DACL_PRESENT
)
796 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
);
797 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
803 PSID psid
= (PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
);
804 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
805 pAbs
->Owner
= pOwner
;
810 PSID psid
= (PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
);
811 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
812 pAbs
->Group
= pPrimaryGroup
;
819 * access control list's
822 /**************************************************************************
823 * RtlCreateAcl [NTDLL.@]
826 * This should return NTSTATUS
828 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
830 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
832 if (rev
!=ACL_REVISION
)
833 return STATUS_INVALID_PARAMETER
;
834 if (size
<sizeof(ACL
))
835 return STATUS_BUFFER_TOO_SMALL
;
837 return STATUS_INVALID_PARAMETER
;
839 memset(acl
,'\0',sizeof(ACL
));
840 acl
->AclRevision
= rev
;
843 return STATUS_SUCCESS
;
846 /**************************************************************************
847 * RtlFirstFreeAce [NTDLL.@]
848 * looks for the AceCount+1 ACE, and if it is still within the alloced
849 * ACL, return a pointer to it
851 BOOLEAN WINAPI
RtlFirstFreeAce(
859 ace
= (PACE_HEADER
)(acl
+1);
860 for (i
=0;i
<acl
->AceCount
;i
++) {
861 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
863 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
865 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
871 /**************************************************************************
872 * RtlAddAce [NTDLL.@]
874 NTSTATUS WINAPI
RtlAddAce(
878 PACE_HEADER acestart
,
881 PACE_HEADER ace
,targetace
;
884 if (acl
->AclRevision
!= ACL_REVISION
)
885 return STATUS_INVALID_PARAMETER
;
886 if (!RtlFirstFreeAce(acl
,&targetace
))
887 return STATUS_INVALID_PARAMETER
;
888 nrofaces
=0;ace
=acestart
;
889 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
891 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
893 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
894 return STATUS_INVALID_PARAMETER
;
895 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
896 acl
->AceCount
+=nrofaces
;
897 return STATUS_SUCCESS
;
900 /**************************************************************************
901 * RtlDeleteAce [NTDLL.@]
903 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
908 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
910 if (STATUS_SUCCESS
== status
)
915 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
916 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
918 len
+= pcAce
->AceSize
;
919 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
922 memcpy(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
929 /******************************************************************************
930 * RtlAddAccessAllowedAce [NTDLL.@]
932 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
934 IN DWORD dwAceRevision
,
938 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
941 /******************************************************************************
942 * RtlAddAccessAllowedAceEx [NTDLL.@]
944 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
946 IN DWORD dwAceRevision
,
952 ACCESS_ALLOWED_ACE
* pAaAce
;
955 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
956 pAcl
, dwAceRevision
, AccessMask
, pSid
);
958 if (!RtlValidSid(pSid
))
959 return STATUS_INVALID_SID
;
960 if (!RtlValidAcl(pAcl
))
961 return STATUS_INVALID_ACL
;
963 dwLengthSid
= RtlLengthSid(pSid
);
964 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAaAce
))
965 return STATUS_INVALID_ACL
;
968 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
970 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAaAce
;
971 if (dwSpaceLeft
< sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
)
972 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
974 pAaAce
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
975 pAaAce
->Header
.AceFlags
= AceFlags
;
976 pAaAce
->Header
.AceSize
= sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
;
977 pAaAce
->Mask
= AccessMask
;
979 RtlCopySid(dwLengthSid
, (PSID
)&pAaAce
->SidStart
, pSid
);
980 return STATUS_SUCCESS
;
983 /******************************************************************************
984 * RtlAddAccessDeniedAce [NTDLL.@]
986 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
988 IN DWORD dwAceRevision
,
992 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
995 /******************************************************************************
996 * RtlAddAccessDeniedAceEx [NTDLL.@]
998 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1000 IN DWORD dwAceRevision
,
1002 IN DWORD AccessMask
,
1007 ACCESS_DENIED_ACE
* pAdAce
;
1009 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1010 pAcl
, dwAceRevision
, AccessMask
, pSid
);
1012 if (!RtlValidSid(pSid
))
1013 return STATUS_INVALID_SID
;
1014 if (!RtlValidAcl(pAcl
))
1015 return STATUS_INVALID_ACL
;
1017 dwLengthSid
= RtlLengthSid(pSid
);
1018 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAdAce
))
1019 return STATUS_INVALID_ACL
;
1022 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1024 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAdAce
;
1025 if (dwSpaceLeft
< sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
)
1026 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1028 pAdAce
->Header
.AceType
= ACCESS_DENIED_ACE_TYPE
;
1029 pAdAce
->Header
.AceFlags
= AceFlags
;
1030 pAdAce
->Header
.AceSize
= sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
;
1031 pAdAce
->Mask
= AccessMask
;
1033 RtlCopySid(dwLengthSid
, (PSID
)&pAdAce
->SidStart
, pSid
);
1034 return STATUS_SUCCESS
;
1037 /******************************************************************************
1038 * RtlValidAcl [NTDLL.@]
1040 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1043 TRACE("(%p)\n", pAcl
);
1050 if (pAcl
->AclRevision
!= ACL_REVISION
)
1054 ace
= (PACE_HEADER
)(pAcl
+1);
1056 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1058 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1063 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1067 __EXCEPT(page_fault
)
1069 WARN("(%p): invalid pointer!\n", pAcl
);
1076 /******************************************************************************
1077 * RtlGetAce [NTDLL.@]
1079 DWORD WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1083 TRACE("(%p,%ld,%p)\n",pAcl
,dwAceIndex
,pAce
);
1085 if ((dwAceIndex
< 0) || (dwAceIndex
> pAcl
->AceCount
))
1086 return STATUS_INVALID_PARAMETER
;
1088 ace
= (PACE_HEADER
)(pAcl
+ 1);
1089 for (;dwAceIndex
;dwAceIndex
--)
1090 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1092 *pAce
= (LPVOID
) ace
;
1094 return STATUS_SUCCESS
;
1101 /******************************************************************************
1102 * RtlAdjustPrivilege [NTDLL.@]
1104 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
1106 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
1110 /******************************************************************************
1111 * RtlImpersonateSelf [NTDLL.@]
1114 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1116 FIXME("(%08x), stub\n", ImpersonationLevel
);
1120 /******************************************************************************
1121 * NtAccessCheck [NTDLL.@]
1122 * ZwAccessCheck [NTDLL.@]
1126 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1127 IN HANDLE ClientToken
,
1128 IN ACCESS_MASK DesiredAccess
,
1129 IN PGENERIC_MAPPING GenericMapping
,
1130 OUT PPRIVILEGE_SET PrivilegeSet
,
1131 OUT PULONG ReturnLength
,
1132 OUT PULONG GrantedAccess
,
1133 OUT PBOOLEAN AccessStatus
)
1135 FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1136 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
1137 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
1138 *AccessStatus
= TRUE
;
1139 return STATUS_SUCCESS
;
1142 /******************************************************************************
1143 * NtSetSecurityObject [NTDLL.@]
1146 NtSetSecurityObject(
1148 IN SECURITY_INFORMATION SecurityInformation
,
1149 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
1151 FIXME("%p 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
1152 return STATUS_SUCCESS
;
1155 /******************************************************************************
1156 * RtlGetControlSecurityDescriptor (NTDLL.@)
1159 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1160 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1161 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1162 LPDWORD lpdwRevision
)
1164 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1165 return STATUS_SUCCESS
;
1168 /******************************************************************************
1169 * RtlConvertSidToUnicodeString (NTDLL.@)
1171 * The returned SID is used to access the USER registry hive usually
1173 * the native function returns something like
1174 * "S-1-5-21-0000000000-000000000-0000000000-500";
1176 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1177 PUNICODE_STRING String
,
1179 BOOLEAN AllocateString
)
1181 const char *p
= wine_get_user_name();
1183 ANSI_STRING AnsiStr
;
1185 FIXME("(%p %p %u)\n", String
, Sid
, AllocateString
);
1187 RtlInitAnsiString(&AnsiStr
, p
);
1188 status
= RtlAnsiStringToUnicodeString(String
, &AnsiStr
, AllocateString
);
1190 TRACE("%s (%u %u)\n",debugstr_w(String
->Buffer
),String
->Length
,String
->MaximumLength
);
1194 /******************************************************************************
1195 * RtlQueryInformationAcl (NTDLL.@)
1197 NTSTATUS WINAPI
RtlQueryInformationAcl(
1199 LPVOID pAclInformation
,
1200 DWORD nAclInformationLength
,
1201 ACL_INFORMATION_CLASS dwAclInformationClass
)
1203 NTSTATUS status
= STATUS_SUCCESS
;
1205 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1206 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1208 switch (dwAclInformationClass
)
1210 case AclRevisionInformation
:
1212 PACL_REVISION_INFORMATION paclrev
= (PACL_REVISION_INFORMATION
) pAclInformation
;
1214 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1215 status
= STATUS_INVALID_PARAMETER
;
1217 paclrev
->AclRevision
= pAcl
->AclRevision
;
1222 case AclSizeInformation
:
1224 PACL_SIZE_INFORMATION paclsize
= (PACL_SIZE_INFORMATION
) pAclInformation
;
1226 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1227 status
= STATUS_INVALID_PARAMETER
;
1233 paclsize
->AceCount
= pAcl
->AceCount
;
1235 paclsize
->AclBytesInUse
= 0;
1236 ace
= (PACE_HEADER
) (pAcl
+ 1);
1238 for (i
= 0; i
< pAcl
->AceCount
; i
++)
1240 paclsize
->AclBytesInUse
+= ace
->AceSize
;
1241 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1244 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1246 WARN("Acl has %ld bytes free\n", pAcl
->AclSize
- paclsize
->AclBytesInUse
);
1247 paclsize
->AclBytesFree
= 0;
1248 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1251 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1258 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1259 status
= STATUS_INVALID_PARAMETER
;