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"
39 #include "ntdll_misc.h"
41 #include "wine/library.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
46 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
48 /* filter for page-fault exceptions */
49 static WINE_EXCEPTION_FILTER(page_fault
)
51 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
52 return EXCEPTION_EXECUTE_HANDLER
;
53 return EXCEPTION_CONTINUE_SEARCH
;
60 /******************************************************************************
61 * RtlAllocateAndInitializeSid [NTDLL.@]
64 NTSTATUS WINAPI
RtlAllocateAndInitializeSid (
65 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
66 BYTE nSubAuthorityCount
,
67 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
68 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
69 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
70 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
74 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
75 pIdentifierAuthority
,nSubAuthorityCount
,
76 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
77 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
79 if (!(*pSid
= RtlAllocateHeap( GetProcessHeap(), 0,
80 RtlLengthRequiredSid(nSubAuthorityCount
))))
81 return STATUS_NO_MEMORY
;
83 ((SID
*)*pSid
)->Revision
= SID_REVISION
;
85 if (pIdentifierAuthority
)
86 memcpy(&((SID
*)*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
87 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
89 if (nSubAuthorityCount
> 0)
90 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
91 if (nSubAuthorityCount
> 1)
92 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
93 if (nSubAuthorityCount
> 2)
94 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
95 if (nSubAuthorityCount
> 3)
96 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
97 if (nSubAuthorityCount
> 4)
98 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
99 if (nSubAuthorityCount
> 5)
100 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
101 if (nSubAuthorityCount
> 6)
102 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
103 if (nSubAuthorityCount
> 7)
104 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
106 return STATUS_SUCCESS
;
108 /******************************************************************************
109 * RtlEqualSid [NTDLL.@]
111 * Determine if two SIDs are equal.
114 * pSid1 [I] Source SID
115 * pSid2 [I] SID to compare with
118 * TRUE, if pSid1 is equal to pSid2,
121 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
123 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
126 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
129 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
135 /******************************************************************************
136 * RtlEqualPrefixSid [NTDLL.@]
138 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
140 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
143 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
146 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(((SID
*)pSid1
)->SubAuthorityCount
- 1)) != 0)
153 /******************************************************************************
154 * RtlFreeSid [NTDLL.@]
156 * Free the resources used by a SID.
159 * pSid [I] SID to Free.
164 DWORD WINAPI
RtlFreeSid(PSID pSid
)
166 TRACE("(%p)\n", pSid
);
167 RtlFreeHeap( GetProcessHeap(), 0, pSid
);
168 return STATUS_SUCCESS
;
171 /**************************************************************************
172 * RtlLengthRequiredSid [NTDLL.@]
174 * Determine the amount of memory a SID will use
177 * nrofsubauths [I] Number of Sub Authorities in the SID.
180 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
182 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
184 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
187 /**************************************************************************
188 * RtlLengthSid [NTDLL.@]
190 * Determine the amount of memory a SID is using
193 * pSid [I] SID to ge the size of.
196 * The size, in bytes, of pSid.
198 DWORD WINAPI
RtlLengthSid(PSID pSid
)
200 TRACE("sid=%p\n",pSid
);
202 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
205 /**************************************************************************
206 * RtlInitializeSid [NTDLL.@]
211 * pSid [I] SID to initialise
212 * pIdentifierAuthority [I] Identifier Authority
213 * nSubAuthorityCount [I] Number of Sub Authorities
216 * Success: TRUE. pSid is initialised withe the details given.
217 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
219 BOOL WINAPI
RtlInitializeSid(
221 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
222 BYTE nSubAuthorityCount
)
227 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
230 pisid
->Revision
= SID_REVISION
;
231 pisid
->SubAuthorityCount
= nSubAuthorityCount
;
232 if (pIdentifierAuthority
)
233 memcpy(&pisid
->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 &(((SID
*)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 &(((SID
*)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 &(((SID
*)pSid
)->SubAuthorityCount
);
290 /**************************************************************************
291 * RtlCopySid [NTDLL.@]
293 BOOLEAN WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
295 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
296 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
299 if (nDestinationSidLength
< (((SID
*)pSourceSid
)->SubAuthorityCount
*4+8))
302 memmove(pDestinationSid
, pSourceSid
, ((SID
*)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
|| ((SID
*)pSid
)->Revision
!= SID_REVISION
||
324 ((SID
*)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(SECURITY_DESCRIPTOR
));
363 ((SECURITY_DESCRIPTOR
*)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 ( ((SECURITY_DESCRIPTOR
*)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 pSecurityDescriptor
)
395 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
397 ULONG Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
402 if ( lpsd
->Control
& SE_SELF_RELATIVE
)
403 offset
= (ULONG
) lpsd
;
405 if ( lpsd
->Owner
!= NULL
)
406 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Owner
+ offset
));
408 if ( lpsd
->Group
!= NULL
)
409 Size
+= RtlLengthSid((PSID
)((LPBYTE
)lpsd
->Group
+ offset
));
411 if ( lpsd
->Sacl
!= NULL
)
412 Size
+= ((PACL
)((LPBYTE
)lpsd
->Sacl
+ offset
))->AclSize
;
414 if ( lpsd
->Dacl
!= NULL
)
415 Size
+= ((PACL
)((LPBYTE
)lpsd
->Dacl
+ offset
))->AclSize
;
420 /******************************************************************************
421 * RtlGetDaclSecurityDescriptor [NTDLL.@]
424 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
425 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
426 OUT PBOOLEAN lpbDaclPresent
,
428 OUT PBOOLEAN lpbDaclDefaulted
)
430 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
432 TRACE("(%p,%p,%p,%p)\n",
433 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
435 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
436 return STATUS_UNKNOWN_REVISION
;
438 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
440 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
441 { *pDacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Dacl
);
444 { *pDacl
= lpsd
->Dacl
;
448 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
450 return STATUS_SUCCESS
;
453 /**************************************************************************
454 * RtlSetDaclSecurityDescriptor [NTDLL.@]
456 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
457 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
460 BOOLEAN dacldefaulted
)
462 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
464 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
465 return STATUS_UNKNOWN_REVISION
;
466 if (lpsd
->Control
& SE_SELF_RELATIVE
)
467 return STATUS_INVALID_SECURITY_DESCR
;
470 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
474 lpsd
->Control
|= SE_DACL_PRESENT
;
478 lpsd
->Control
|= SE_DACL_DEFAULTED
;
480 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
482 return STATUS_SUCCESS
;
485 /******************************************************************************
486 * RtlGetSaclSecurityDescriptor [NTDLL.@]
489 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
490 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
491 OUT PBOOLEAN lpbSaclPresent
,
493 OUT PBOOLEAN lpbSaclDefaulted
)
495 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
497 TRACE("(%p,%p,%p,%p)\n",
498 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
500 if (lpsd
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
501 return STATUS_UNKNOWN_REVISION
;
503 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& lpsd
->Control
) ? 1 : 0) )
505 if ( SE_SELF_RELATIVE
& lpsd
->Control
)
506 { *pSacl
= (PACL
) ((LPBYTE
)lpsd
+ (DWORD
)lpsd
->Sacl
);
509 { *pSacl
= lpsd
->Sacl
;
513 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& lpsd
->Control
) ? 1 : 0);
515 return STATUS_SUCCESS
;
518 /**************************************************************************
519 * RtlSetSaclSecurityDescriptor [NTDLL.@]
521 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
522 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
525 BOOLEAN sacldefaulted
)
527 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
529 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
530 return STATUS_UNKNOWN_REVISION
;
531 if (lpsd
->Control
& SE_SELF_RELATIVE
)
532 return STATUS_INVALID_SECURITY_DESCR
;
534 lpsd
->Control
&= ~SE_SACL_PRESENT
;
537 lpsd
->Control
|= SE_SACL_PRESENT
;
540 lpsd
->Control
|= SE_SACL_DEFAULTED
;
542 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
543 return STATUS_SUCCESS
;
546 /**************************************************************************
547 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
549 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
550 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
552 PBOOLEAN OwnerDefaulted
)
554 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
556 if ( !lpsd
|| !Owner
|| !OwnerDefaulted
)
557 return STATUS_INVALID_PARAMETER
;
559 if (lpsd
->Owner
!= NULL
)
561 if (lpsd
->Control
& SE_SELF_RELATIVE
)
562 *Owner
= (PSID
)((LPBYTE
)lpsd
+
565 *Owner
= lpsd
->Owner
;
567 if ( lpsd
->Control
& SE_OWNER_DEFAULTED
)
568 *OwnerDefaulted
= TRUE
;
570 *OwnerDefaulted
= FALSE
;
575 return STATUS_SUCCESS
;
578 /**************************************************************************
579 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
581 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
582 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
584 BOOLEAN ownerdefaulted
)
586 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
588 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
589 return STATUS_UNKNOWN_REVISION
;
590 if (lpsd
->Control
& SE_SELF_RELATIVE
)
591 return STATUS_INVALID_SECURITY_DESCR
;
595 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
597 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
598 return STATUS_SUCCESS
;
601 /**************************************************************************
602 * RtlSetGroupSecurityDescriptor [NTDLL.@]
604 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
605 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
607 BOOLEAN groupdefaulted
)
609 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
611 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
612 return STATUS_UNKNOWN_REVISION
;
613 if (lpsd
->Control
& SE_SELF_RELATIVE
)
614 return STATUS_INVALID_SECURITY_DESCR
;
618 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
620 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
621 return STATUS_SUCCESS
;
623 /**************************************************************************
624 * RtlGetGroupSecurityDescriptor [NTDLL.@]
626 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
627 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
629 PBOOLEAN GroupDefaulted
)
631 SECURITY_DESCRIPTOR
* lpsd
=pSecurityDescriptor
;
633 if ( !lpsd
|| !Group
|| !GroupDefaulted
)
634 return STATUS_INVALID_PARAMETER
;
636 if (lpsd
->Group
!= NULL
)
638 if (lpsd
->Control
& SE_SELF_RELATIVE
)
639 *Group
= (PSID
)((LPBYTE
)lpsd
+
642 *Group
= lpsd
->Group
;
644 if ( lpsd
->Control
& SE_GROUP_DEFAULTED
)
645 *GroupDefaulted
= TRUE
;
647 *GroupDefaulted
= FALSE
;
652 return STATUS_SUCCESS
;
655 /**************************************************************************
656 * RtlMakeSelfRelativeSD [NTDLL.@]
658 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
659 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
660 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
661 IN OUT LPDWORD lpdwBufferLength
)
665 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
666 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
668 TRACE(" %p %p %p(%ld)\n", pAbs
, pRel
, lpdwBufferLength
,
669 lpdwBufferLength
? *lpdwBufferLength
: -1);
671 if (!lpdwBufferLength
|| !pAbs
)
672 return STATUS_INVALID_PARAMETER
;
674 length
= RtlLengthSecurityDescriptor(pAbs
);
675 if (*lpdwBufferLength
< length
)
677 *lpdwBufferLength
= length
;
678 return STATUS_BUFFER_TOO_SMALL
;
682 return STATUS_INVALID_PARAMETER
;
684 if (pAbs
->Control
& SE_SELF_RELATIVE
)
686 memcpy(pRel
, pAbs
, length
);
687 return STATUS_SUCCESS
;
690 pRel
->Revision
= pAbs
->Revision
;
691 pRel
->Sbz1
= pAbs
->Sbz1
;
692 pRel
->Control
= pAbs
->Control
| SE_SELF_RELATIVE
;
694 offsetRel
= sizeof(SECURITY_DESCRIPTOR
);
695 pRel
->Owner
= (PSID
) offsetRel
;
696 length
= RtlLengthSid(pAbs
->Owner
);
697 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Owner
, length
);
700 pRel
->Group
= (PSID
) offsetRel
;
701 length
= RtlLengthSid(pAbs
->Group
);
702 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Group
, length
);
704 if (pRel
->Control
& SE_SACL_PRESENT
)
707 pRel
->Sacl
= (PACL
) offsetRel
;
708 length
= pAbs
->Sacl
->AclSize
;
709 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Sacl
, length
);
716 if (pRel
->Control
& SE_DACL_PRESENT
)
719 pRel
->Dacl
= (PACL
) offsetRel
;
720 length
= pAbs
->Dacl
->AclSize
;
721 memcpy((LPBYTE
)pRel
+ offsetRel
, pAbs
->Dacl
, length
);
728 return STATUS_SUCCESS
;
732 /**************************************************************************
733 + * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
735 NTSTATUS WINAPI
RtlSelfRelativeToAbsoluteSD(
736 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
737 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
738 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize
,
740 OUT LPDWORD lpdwDaclSize
,
742 OUT LPDWORD lpdwSaclSize
,
744 OUT LPDWORD lpdwOwnerSize
,
745 OUT PSID pPrimaryGroup
,
746 OUT LPDWORD lpdwPrimaryGroupSize
)
748 NTSTATUS status
= STATUS_SUCCESS
;
749 SECURITY_DESCRIPTOR
* pAbs
= pAbsoluteSecurityDescriptor
;
750 SECURITY_DESCRIPTOR
* pRel
= pSelfRelativeSecurityDescriptor
;
753 !lpdwAbsoluteSecurityDescriptorSize
||
757 !lpdwPrimaryGroupSize
||
758 ~pRel
->Control
& SE_SELF_RELATIVE
)
759 return STATUS_INVALID_PARAMETER
;
761 /* Confirm buffers are sufficiently large */
762 if (*lpdwAbsoluteSecurityDescriptorSize
< sizeof(SECURITY_DESCRIPTOR
))
764 *lpdwAbsoluteSecurityDescriptorSize
= sizeof(SECURITY_DESCRIPTOR
);
765 status
= STATUS_BUFFER_TOO_SMALL
;
768 if (pRel
->Control
& SE_DACL_PRESENT
&&
769 *lpdwDaclSize
< ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
)
771 *lpdwDaclSize
= ((PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
))->AclSize
;
772 status
= STATUS_BUFFER_TOO_SMALL
;
775 if (pRel
->Control
& SE_SACL_PRESENT
&&
776 *lpdwSaclSize
< ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
)
778 *lpdwSaclSize
= ((PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
))->AclSize
;
779 status
= STATUS_BUFFER_TOO_SMALL
;
783 *lpdwOwnerSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
)))
785 *lpdwOwnerSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
));
786 status
= STATUS_BUFFER_TOO_SMALL
;
790 *lpdwPrimaryGroupSize
< RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
)))
792 *lpdwPrimaryGroupSize
= RtlLengthSid((PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
));
793 status
= STATUS_BUFFER_TOO_SMALL
;
796 if (status
!= STATUS_SUCCESS
)
799 /* Copy structures */
800 pAbs
->Revision
= pRel
->Revision
;
801 pAbs
->Control
= pRel
->Control
& ~SE_SELF_RELATIVE
;
803 if (pRel
->Control
& SE_SACL_PRESENT
)
805 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Sacl
+ (ULONG
)pRel
);
807 memcpy(pSacl
, pAcl
, pAcl
->AclSize
);
811 if (pRel
->Control
& SE_DACL_PRESENT
)
813 PACL pAcl
= (PACL
)((LPBYTE
)pRel
->Dacl
+ (ULONG
)pRel
);
814 memcpy(pDacl
, pAcl
, pAcl
->AclSize
);
820 PSID psid
= (PSID
)((LPBYTE
)pRel
->Owner
+ (ULONG
)pRel
);
821 memcpy(pOwner
, psid
, RtlLengthSid(psid
));
822 pAbs
->Owner
= pOwner
;
827 PSID psid
= (PSID
)((LPBYTE
)pRel
->Group
+ (ULONG
)pRel
);
828 memcpy(pPrimaryGroup
, psid
, RtlLengthSid(psid
));
829 pAbs
->Group
= pPrimaryGroup
;
836 * access control list's
839 /**************************************************************************
840 * RtlCreateAcl [NTDLL.@]
843 * This should return NTSTATUS
845 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
847 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
849 if (rev
!=ACL_REVISION
)
850 return STATUS_INVALID_PARAMETER
;
851 if (size
<sizeof(ACL
))
852 return STATUS_BUFFER_TOO_SMALL
;
854 return STATUS_INVALID_PARAMETER
;
856 memset(acl
,'\0',sizeof(ACL
));
857 acl
->AclRevision
= rev
;
860 return STATUS_SUCCESS
;
863 /**************************************************************************
864 * RtlFirstFreeAce [NTDLL.@]
865 * looks for the AceCount+1 ACE, and if it is still within the alloced
866 * ACL, return a pointer to it
868 BOOLEAN WINAPI
RtlFirstFreeAce(
876 ace
= (PACE_HEADER
)(acl
+1);
877 for (i
=0;i
<acl
->AceCount
;i
++) {
878 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
880 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
882 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
888 /**************************************************************************
889 * RtlAddAce [NTDLL.@]
891 NTSTATUS WINAPI
RtlAddAce(
895 PACE_HEADER acestart
,
898 PACE_HEADER ace
,targetace
;
901 if (acl
->AclRevision
!= ACL_REVISION
)
902 return STATUS_INVALID_PARAMETER
;
903 if (!RtlFirstFreeAce(acl
,&targetace
))
904 return STATUS_INVALID_PARAMETER
;
905 nrofaces
=0;ace
=acestart
;
906 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
908 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
910 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
911 return STATUS_INVALID_PARAMETER
;
912 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
913 acl
->AceCount
+=nrofaces
;
914 return STATUS_SUCCESS
;
917 /**************************************************************************
918 * RtlDeleteAce [NTDLL.@]
920 NTSTATUS WINAPI
RtlDeleteAce(PACL pAcl
, DWORD dwAceIndex
)
925 status
= RtlGetAce(pAcl
,dwAceIndex
,(LPVOID
*)&pAce
);
927 if (STATUS_SUCCESS
== status
)
932 pcAce
= (PACE_HEADER
)(((BYTE
*)pAce
)+pAce
->AceSize
);
933 for (; dwAceIndex
< pAcl
->AceCount
; dwAceIndex
++)
935 len
+= pcAce
->AceSize
;
936 pcAce
= (PACE_HEADER
)(((BYTE
*)pcAce
) + pcAce
->AceSize
);
939 memcpy(pAce
, ((BYTE
*)pAce
)+pAce
->AceSize
, len
);
946 /******************************************************************************
947 * RtlAddAccessAllowedAce [NTDLL.@]
949 NTSTATUS WINAPI
RtlAddAccessAllowedAce(
951 IN DWORD dwAceRevision
,
955 return RtlAddAccessAllowedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
958 /******************************************************************************
959 * RtlAddAccessAllowedAceEx [NTDLL.@]
961 NTSTATUS WINAPI
RtlAddAccessAllowedAceEx(
963 IN DWORD dwAceRevision
,
969 ACCESS_ALLOWED_ACE
* pAaAce
;
972 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
973 pAcl
, dwAceRevision
, AccessMask
, pSid
);
975 if (!RtlValidSid(pSid
))
976 return STATUS_INVALID_SID
;
977 if (!RtlValidAcl(pAcl
))
978 return STATUS_INVALID_ACL
;
980 dwLengthSid
= RtlLengthSid(pSid
);
981 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAaAce
))
982 return STATUS_INVALID_ACL
;
985 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
987 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAaAce
;
988 if (dwSpaceLeft
< sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
)
989 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
991 pAaAce
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
992 pAaAce
->Header
.AceFlags
= AceFlags
;
993 pAaAce
->Header
.AceSize
= sizeof(*pAaAce
) - sizeof(pAaAce
->SidStart
) + dwLengthSid
;
994 pAaAce
->Mask
= AccessMask
;
996 RtlCopySid(dwLengthSid
, (PSID
)&pAaAce
->SidStart
, pSid
);
997 return STATUS_SUCCESS
;
1000 /******************************************************************************
1001 * RtlAddAccessDeniedAce [NTDLL.@]
1003 NTSTATUS WINAPI
RtlAddAccessDeniedAce(
1005 IN DWORD dwAceRevision
,
1006 IN DWORD AccessMask
,
1009 return RtlAddAccessDeniedAceEx( pAcl
, dwAceRevision
, 0, AccessMask
, pSid
);
1012 /******************************************************************************
1013 * RtlAddAccessDeniedAceEx [NTDLL.@]
1015 NTSTATUS WINAPI
RtlAddAccessDeniedAceEx(
1017 IN DWORD dwAceRevision
,
1019 IN DWORD AccessMask
,
1024 ACCESS_DENIED_ACE
* pAdAce
;
1026 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1027 pAcl
, dwAceRevision
, AccessMask
, pSid
);
1029 if (!RtlValidSid(pSid
))
1030 return STATUS_INVALID_SID
;
1031 if (!RtlValidAcl(pAcl
))
1032 return STATUS_INVALID_ACL
;
1034 dwLengthSid
= RtlLengthSid(pSid
);
1035 if (!RtlFirstFreeAce(pAcl
, (PACE_HEADER
*) &pAdAce
))
1036 return STATUS_INVALID_ACL
;
1039 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1041 dwSpaceLeft
= (DWORD
)pAcl
+ pAcl
->AclSize
- (DWORD
)pAdAce
;
1042 if (dwSpaceLeft
< sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
)
1043 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
1045 pAdAce
->Header
.AceType
= ACCESS_DENIED_ACE_TYPE
;
1046 pAdAce
->Header
.AceFlags
= AceFlags
;
1047 pAdAce
->Header
.AceSize
= sizeof(*pAdAce
) - sizeof(pAdAce
->SidStart
) + dwLengthSid
;
1048 pAdAce
->Mask
= AccessMask
;
1050 RtlCopySid(dwLengthSid
, (PSID
)&pAdAce
->SidStart
, pSid
);
1051 return STATUS_SUCCESS
;
1054 /******************************************************************************
1055 * RtlValidAcl [NTDLL.@]
1057 BOOLEAN WINAPI
RtlValidAcl(PACL pAcl
)
1060 TRACE("(%p)\n", pAcl
);
1067 if (pAcl
->AclRevision
!= ACL_REVISION
)
1071 ace
= (PACE_HEADER
)(pAcl
+1);
1073 for (i
=0;i
<=pAcl
->AceCount
;i
++)
1075 if ((char *)ace
> (char *)pAcl
+ pAcl
->AclSize
)
1080 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1084 __EXCEPT(page_fault
)
1086 WARN("(%p): invalid pointer!\n", pAcl
);
1093 /******************************************************************************
1094 * RtlGetAce [NTDLL.@]
1096 NTSTATUS WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
1100 TRACE("(%p,%ld,%p)\n",pAcl
,dwAceIndex
,pAce
);
1102 if ((dwAceIndex
< 0) || (dwAceIndex
> pAcl
->AceCount
))
1103 return STATUS_INVALID_PARAMETER
;
1105 ace
= (PACE_HEADER
)(pAcl
+ 1);
1106 for (;dwAceIndex
;dwAceIndex
--)
1107 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1109 *pAce
= (LPVOID
) ace
;
1111 return STATUS_SUCCESS
;
1118 /******************************************************************************
1119 * RtlAdjustPrivilege [NTDLL.@]
1121 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
1123 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
1127 /******************************************************************************
1128 * RtlImpersonateSelf [NTDLL.@]
1131 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1133 FIXME("(%08x), stub\n", ImpersonationLevel
);
1137 /******************************************************************************
1138 * NtAccessCheck [NTDLL.@]
1139 * ZwAccessCheck [NTDLL.@]
1143 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
1144 IN HANDLE ClientToken
,
1145 IN ACCESS_MASK DesiredAccess
,
1146 IN PGENERIC_MAPPING GenericMapping
,
1147 OUT PPRIVILEGE_SET PrivilegeSet
,
1148 OUT PULONG ReturnLength
,
1149 OUT PULONG GrantedAccess
,
1150 OUT NTSTATUS
*AccessStatus
)
1152 FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1153 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
1154 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
1155 *AccessStatus
= STATUS_SUCCESS
;
1156 return STATUS_SUCCESS
;
1159 /******************************************************************************
1160 * NtSetSecurityObject [NTDLL.@]
1163 NtSetSecurityObject(
1165 IN SECURITY_INFORMATION SecurityInformation
,
1166 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
1168 FIXME("%p 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
1169 return STATUS_SUCCESS
;
1172 /******************************************************************************
1173 * RtlGetControlSecurityDescriptor (NTDLL.@)
1176 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
1177 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1178 PSECURITY_DESCRIPTOR_CONTROL pControl
,
1179 LPDWORD lpdwRevision
)
1181 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
1182 return STATUS_SUCCESS
;
1185 /******************************************************************************
1186 * RtlConvertSidToUnicodeString (NTDLL.@)
1188 * The returned SID is used to access the USER registry hive usually
1190 * the native function returns something like
1191 * "S-1-5-21-0000000000-000000000-0000000000-500";
1193 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
1194 PUNICODE_STRING String
,
1196 BOOLEAN AllocateString
)
1198 const char *user
= wine_get_user_name();
1199 int len
= ntdll_umbstowcs( 0, user
, strlen(user
)+1, NULL
, 0 ) * sizeof(WCHAR
);
1201 FIXME("(%p %p %u)\n", String
, Sid
, AllocateString
);
1203 String
->Length
= len
- sizeof(WCHAR
);
1206 String
->MaximumLength
= len
;
1207 if (!(String
->Buffer
= RtlAllocateHeap( GetProcessHeap(), 0, len
)))
1208 return STATUS_NO_MEMORY
;
1210 else if (len
> String
->MaximumLength
) return STATUS_BUFFER_OVERFLOW
;
1212 ntdll_umbstowcs( 0, user
, strlen(user
)+1, String
->Buffer
, len
/sizeof(WCHAR
) );
1213 return STATUS_SUCCESS
;
1216 /******************************************************************************
1217 * RtlQueryInformationAcl (NTDLL.@)
1219 NTSTATUS WINAPI
RtlQueryInformationAcl(
1221 LPVOID pAclInformation
,
1222 DWORD nAclInformationLength
,
1223 ACL_INFORMATION_CLASS dwAclInformationClass
)
1225 NTSTATUS status
= STATUS_SUCCESS
;
1227 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1228 pAcl
, pAclInformation
, nAclInformationLength
, dwAclInformationClass
);
1230 switch (dwAclInformationClass
)
1232 case AclRevisionInformation
:
1234 PACL_REVISION_INFORMATION paclrev
= (PACL_REVISION_INFORMATION
) pAclInformation
;
1236 if (nAclInformationLength
< sizeof(ACL_REVISION_INFORMATION
))
1237 status
= STATUS_INVALID_PARAMETER
;
1239 paclrev
->AclRevision
= pAcl
->AclRevision
;
1244 case AclSizeInformation
:
1246 PACL_SIZE_INFORMATION paclsize
= (PACL_SIZE_INFORMATION
) pAclInformation
;
1248 if (nAclInformationLength
< sizeof(ACL_SIZE_INFORMATION
))
1249 status
= STATUS_INVALID_PARAMETER
;
1255 paclsize
->AceCount
= pAcl
->AceCount
;
1257 paclsize
->AclBytesInUse
= 0;
1258 ace
= (PACE_HEADER
) (pAcl
+ 1);
1260 for (i
= 0; i
< pAcl
->AceCount
; i
++)
1262 paclsize
->AclBytesInUse
+= ace
->AceSize
;
1263 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
1266 if (pAcl
->AclSize
< paclsize
->AclBytesInUse
)
1268 WARN("Acl has %ld bytes free\n", pAcl
->AclSize
- paclsize
->AclBytesInUse
);
1269 paclsize
->AclBytesFree
= 0;
1270 paclsize
->AclBytesInUse
= pAcl
->AclSize
;
1273 paclsize
->AclBytesFree
= pAcl
->AclSize
- paclsize
->AclBytesInUse
;
1280 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass
);
1281 status
= STATUS_INVALID_PARAMETER
;