4 * Copyright 1996-1998 Marcus Meissner
14 #include "wine/exception.h"
18 #include "debugtools.h"
20 #include "stackframe.h"
24 #include "ntdll_misc.h"
26 DEFAULT_DEBUG_CHANNEL(ntdll
);
28 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
30 /* filter for page-fault exceptions */
31 static WINE_EXCEPTION_FILTER(page_fault
)
33 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
34 return EXCEPTION_EXECUTE_HANDLER
;
35 return EXCEPTION_CONTINUE_SEARCH
;
42 /******************************************************************************
43 * RtlAllocateAndInitializeSid [NTDLL.265]
46 BOOLEAN WINAPI
RtlAllocateAndInitializeSid (
47 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
48 BYTE nSubAuthorityCount
,
49 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
50 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
51 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
52 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
55 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
56 pIdentifierAuthority
,nSubAuthorityCount
,
57 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
58 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
60 if (!(*pSid
= HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount
))))
63 (*pSid
)->Revision
= SID_REVISION
;
65 if (pIdentifierAuthority
)
66 memcpy(&(*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
67 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
69 if (nSubAuthorityCount
> 0)
70 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
71 if (nSubAuthorityCount
> 1)
72 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
73 if (nSubAuthorityCount
> 2)
74 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
75 if (nSubAuthorityCount
> 3)
76 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
77 if (nSubAuthorityCount
> 4)
78 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
79 if (nSubAuthorityCount
> 5)
80 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
81 if (nSubAuthorityCount
> 6)
82 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
83 if (nSubAuthorityCount
> 7)
84 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
86 return STATUS_SUCCESS
;
88 /******************************************************************************
89 * RtlEqualSid [NTDLL.352]
92 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
94 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
97 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
100 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
106 /******************************************************************************
107 * RtlEqualPrefixSid [ntdll.]
109 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
111 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
114 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
117 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(pSid1
->SubAuthorityCount
- 1)) != 0)
124 /******************************************************************************
125 * RtlFreeSid [NTDLL.376]
127 DWORD WINAPI
RtlFreeSid(PSID pSid
)
129 TRACE("(%p)\n", pSid
);
130 HeapFree( GetProcessHeap(), 0, pSid
);
131 return STATUS_SUCCESS
;
134 /**************************************************************************
135 * RtlLengthRequiredSid [NTDLL.427]
138 * nSubAuthorityCount []
140 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
142 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
145 /**************************************************************************
146 * RtlLengthSid [NTDLL.429]
148 DWORD WINAPI
RtlLengthSid(PSID pSid
)
150 TRACE("sid=%p\n",pSid
);
152 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
155 /**************************************************************************
156 * RtlInitializeSid [NTDLL.410]
158 BOOL WINAPI
RtlInitializeSid(
160 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
161 BYTE nSubAuthorityCount
)
164 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
167 pSid
->Revision
= SID_REVISION
;
168 pSid
->SubAuthorityCount
= nSubAuthorityCount
;
169 if (pIdentifierAuthority
)
170 memcpy(&pSid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
172 for (i
= 0; i
< nSubAuthorityCount
; i
++)
173 *RtlSubAuthoritySid(pSid
, i
) = 0;
178 /**************************************************************************
179 * RtlSubAuthoritySid [NTDLL.497]
185 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
187 return &(pSid
->SubAuthority
[nSubAuthority
]);
190 /**************************************************************************
191 * RtlIdentifierAuthoritySid [NTDLL.395]
196 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
198 return &(pSid
->IdentifierAuthority
);
201 /**************************************************************************
202 * RtlSubAuthorityCountSid [NTDLL.496]
208 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
210 return &(pSid
->SubAuthorityCount
);
213 /**************************************************************************
214 * RtlCopySid [NTDLL.302]
216 DWORD WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
218 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
219 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
222 if (nDestinationSidLength
< (pSourceSid
->SubAuthorityCount
*4+8))
225 memmove(pDestinationSid
, pSourceSid
, pSourceSid
->SubAuthorityCount
*4+8);
228 /******************************************************************************
229 * RtlValidSid [NTDLL.532]
235 RtlValidSid( PSID pSid
)
241 if (!pSid
|| pSid
->Revision
!= SID_REVISION
||
242 pSid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
249 WARN("(%p): invalid pointer!\n", pSid
);
258 * security descriptor functions
261 /**************************************************************************
262 * RtlCreateSecurityDescriptor [NTDLL.313]
266 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
269 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
270 PSECURITY_DESCRIPTOR lpsd
,
273 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
274 return STATUS_UNKNOWN_REVISION
;
275 memset(lpsd
,'\0',sizeof(*lpsd
));
276 lpsd
->Revision
= SECURITY_DESCRIPTOR_REVISION
;
277 return STATUS_SUCCESS
;
279 /**************************************************************************
280 * RtlValidSecurityDescriptor [NTDLL.313]
283 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
284 PSECURITY_DESCRIPTOR SecurityDescriptor
)
286 if ( ! SecurityDescriptor
)
287 return STATUS_INVALID_SECURITY_DESCR
;
288 if ( SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
289 return STATUS_UNKNOWN_REVISION
;
291 return STATUS_SUCCESS
;
294 /**************************************************************************
295 * RtlLengthSecurityDescriptor [NTDLL]
297 ULONG WINAPI
RtlLengthSecurityDescriptor(
298 PSECURITY_DESCRIPTOR SecurityDescriptor
)
301 Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
302 if ( SecurityDescriptor
== NULL
)
305 if ( SecurityDescriptor
->Owner
!= NULL
)
306 Size
+= SecurityDescriptor
->Owner
->SubAuthorityCount
;
307 if ( SecurityDescriptor
->Group
!= NULL
)
308 Size
+= SecurityDescriptor
->Group
->SubAuthorityCount
;
311 if ( SecurityDescriptor
->Sacl
!= NULL
)
312 Size
+= SecurityDescriptor
->Sacl
->AclSize
;
313 if ( SecurityDescriptor
->Dacl
!= NULL
)
314 Size
+= SecurityDescriptor
->Dacl
->AclSize
;
319 /******************************************************************************
320 * RtlGetDaclSecurityDescriptor [NTDLL]
323 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
324 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
325 OUT PBOOLEAN lpbDaclPresent
,
327 OUT PBOOLEAN lpbDaclDefaulted
)
329 TRACE("(%p,%p,%p,%p)\n",
330 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
332 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
333 return STATUS_UNKNOWN_REVISION
;
335 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
337 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
338 { *pDacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Dacl
);
341 { *pDacl
= pSecurityDescriptor
->Dacl
;
345 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
347 return STATUS_SUCCESS
;
350 /**************************************************************************
351 * RtlSetDaclSecurityDescriptor [NTDLL.483]
353 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
354 PSECURITY_DESCRIPTOR lpsd
,
357 BOOLEAN dacldefaulted
)
359 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
360 return STATUS_UNKNOWN_REVISION
;
361 if (lpsd
->Control
& SE_SELF_RELATIVE
)
362 return STATUS_INVALID_SECURITY_DESCR
;
365 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
369 lpsd
->Control
|= SE_DACL_PRESENT
;
373 lpsd
->Control
|= SE_DACL_DEFAULTED
;
375 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
377 return STATUS_SUCCESS
;
380 /******************************************************************************
381 * RtlGetSaclSecurityDescriptor [NTDLL]
384 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
385 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
386 OUT PBOOLEAN lpbSaclPresent
,
388 OUT PBOOLEAN lpbSaclDefaulted
)
390 TRACE("(%p,%p,%p,%p)\n",
391 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
393 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
394 return STATUS_UNKNOWN_REVISION
;
396 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
398 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
399 { *pSacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Sacl
);
402 { *pSacl
= pSecurityDescriptor
->Sacl
;
406 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
408 return STATUS_SUCCESS
;
411 /**************************************************************************
412 * RtlSetSaclSecurityDescriptor [NTDLL.488]
414 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
415 PSECURITY_DESCRIPTOR lpsd
,
418 BOOLEAN sacldefaulted
)
420 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
421 return STATUS_UNKNOWN_REVISION
;
422 if (lpsd
->Control
& SE_SELF_RELATIVE
)
423 return STATUS_INVALID_SECURITY_DESCR
;
425 lpsd
->Control
&= ~SE_SACL_PRESENT
;
428 lpsd
->Control
|= SE_SACL_PRESENT
;
431 lpsd
->Control
|= SE_SACL_DEFAULTED
;
433 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
434 return STATUS_SUCCESS
;
437 /**************************************************************************
438 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
440 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
441 PSECURITY_DESCRIPTOR SecurityDescriptor
,
443 PBOOLEAN OwnerDefaulted
)
445 if ( !SecurityDescriptor
|| !Owner
|| !OwnerDefaulted
)
446 return STATUS_INVALID_PARAMETER
;
448 *Owner
= SecurityDescriptor
->Owner
;
449 if ( *Owner
!= NULL
) {
450 if ( SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
)
451 *OwnerDefaulted
= TRUE
;
453 *OwnerDefaulted
= FALSE
;
455 return STATUS_SUCCESS
;
458 /**************************************************************************
459 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
461 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
462 PSECURITY_DESCRIPTOR lpsd
,
464 BOOLEAN ownerdefaulted
)
466 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
467 return STATUS_UNKNOWN_REVISION
;
468 if (lpsd
->Control
& SE_SELF_RELATIVE
)
469 return STATUS_INVALID_SECURITY_DESCR
;
473 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
475 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
476 return STATUS_SUCCESS
;
479 /**************************************************************************
480 * RtlSetGroupSecurityDescriptor [NTDLL.485]
482 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
483 PSECURITY_DESCRIPTOR lpsd
,
485 BOOLEAN groupdefaulted
)
487 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
488 return STATUS_UNKNOWN_REVISION
;
489 if (lpsd
->Control
& SE_SELF_RELATIVE
)
490 return STATUS_INVALID_SECURITY_DESCR
;
494 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
496 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
497 return STATUS_SUCCESS
;
499 /**************************************************************************
500 * RtlGetGroupSecurityDescriptor [NTDLL]
502 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
503 PSECURITY_DESCRIPTOR SecurityDescriptor
,
505 PBOOLEAN GroupDefaulted
)
507 if ( !SecurityDescriptor
|| !Group
|| !GroupDefaulted
)
508 return STATUS_INVALID_PARAMETER
;
510 *Group
= SecurityDescriptor
->Group
;
511 if ( *Group
!= NULL
) {
512 if ( SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
)
513 *GroupDefaulted
= TRUE
;
515 *GroupDefaulted
= FALSE
;
517 return STATUS_SUCCESS
;
520 /**************************************************************************
521 * RtlMakeSelfRelativeSD [NTDLL]
523 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
524 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
525 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
526 IN OUT LPDWORD lpdwBufferLength
)
528 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor
,
529 pSelfRelativeSecurityDescriptor
, lpdwBufferLength
,*lpdwBufferLength
);
530 return STATUS_SUCCESS
;
534 * access control list's
537 /**************************************************************************
538 * RtlCreateAcl [NTDLL.306]
541 * This should return NTSTATUS
543 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
545 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
547 if (rev
!=ACL_REVISION
)
548 return STATUS_INVALID_PARAMETER
;
549 if (size
<sizeof(ACL
))
550 return STATUS_BUFFER_TOO_SMALL
;
552 return STATUS_INVALID_PARAMETER
;
554 memset(acl
,'\0',sizeof(ACL
));
555 acl
->AclRevision
= rev
;
561 /**************************************************************************
562 * RtlFirstFreeAce [NTDLL.370]
563 * looks for the AceCount+1 ACE, and if it is still within the alloced
564 * ACL, return a pointer to it
566 BOOLEAN WINAPI
RtlFirstFreeAce(
574 ace
= (PACE_HEADER
)(acl
+1);
575 for (i
=0;i
<acl
->AceCount
;i
++) {
576 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
578 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
580 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
586 /**************************************************************************
587 * RtlAddAce [NTDLL.260]
589 NTSTATUS WINAPI
RtlAddAce(
593 PACE_HEADER acestart
,
596 PACE_HEADER ace
,targetace
;
599 if (acl
->AclRevision
!= ACL_REVISION
)
600 return STATUS_INVALID_PARAMETER
;
601 if (!RtlFirstFreeAce(acl
,&targetace
))
602 return STATUS_INVALID_PARAMETER
;
603 nrofaces
=0;ace
=acestart
;
604 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
606 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
608 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
609 return STATUS_INVALID_PARAMETER
;
610 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
611 acl
->AceCount
+=nrofaces
;
612 return STATUS_SUCCESS
;
615 /******************************************************************************
616 * RtlAddAccessAllowedAce [NTDLL]
618 BOOL WINAPI
RtlAddAccessAllowedAce(
620 IN DWORD dwAceRevision
,
624 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
625 pAcl
, dwAceRevision
, AccessMask
, pSid
);
629 /******************************************************************************
632 DWORD WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
634 FIXME("(%p,%ld,%p),stub!\n",pAcl
,dwAceIndex
,pAce
);
642 /******************************************************************************
643 * RtlAdjustPrivilege [NTDLL]
645 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
647 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
651 /******************************************************************************
652 * RtlImpersonateSelf [NTDLL]
655 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
657 FIXME("(%08x), stub\n", ImpersonationLevel
);
661 /******************************************************************************
662 * NtAccessCheck [NTDLL]
666 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
667 IN HANDLE ClientToken
,
668 IN ACCESS_MASK DesiredAccess
,
669 IN PGENERIC_MAPPING GenericMapping
,
670 OUT PPRIVILEGE_SET PrivilegeSet
,
671 OUT PULONG ReturnLength
,
672 OUT PULONG GrantedAccess
,
673 OUT PBOOLEAN AccessStatus
)
675 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
676 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
677 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
678 *AccessStatus
= TRUE
;
679 return STATUS_SUCCESS
;
682 /******************************************************************************
683 * NtSetSecurityObject [NTDLL]
688 IN SECURITY_INFORMATION SecurityInformation
,
689 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
691 FIXME("0x%08x 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
692 return STATUS_SUCCESS
;
695 /******************************************************************************
696 * RtlGetControlSecurityDescriptor
699 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
700 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
701 PSECURITY_DESCRIPTOR_CONTROL pControl
,
702 LPDWORD lpdwRevision
)
704 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
705 return STATUS_SUCCESS
;
708 /******************************************************************************
709 * RtlConvertSidToUnicodeString
711 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
712 PUNICODE_STRING UnicodeSID
,
715 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
717 LPSTR GenSID
= ".Default"; /* usually the returned SID is used to */
718 /* access "\\REGISTRY\\USER\\.DEFAULT" */
722 FIXME("(%p %p)\n", UnicodeSID
, pSid
);
723 dump_UnicodeString(UnicodeSID
, FALSE
);
725 RtlInitAnsiString(&AnsiStr
, GenSID
);
726 return RtlAnsiStringToUnicodeString(UnicodeSID
, &AnsiStr
, TRUE
);