4 * Copyright 1996-1998 Marcus Meissner
16 #include "wine/winestring.h"
20 #include "debugtools.h"
22 #include "stackframe.h"
26 #include "ntdll_misc.h"
28 DEFAULT_DEBUG_CHANNEL(ntdll
);
30 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
36 /******************************************************************************
37 * RtlAllocateAndInitializeSid [NTDLL.265]
40 BOOLEAN WINAPI
RtlAllocateAndInitializeSid (
41 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
42 BYTE nSubAuthorityCount
,
43 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
44 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
45 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
46 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
49 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
50 pIdentifierAuthority
,nSubAuthorityCount
,
51 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
52 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
54 if (!(*pSid
= HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount
))))
57 (*pSid
)->Revision
= SID_REVISION
;
59 if (pIdentifierAuthority
)
60 memcpy(&(*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
61 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
63 if (nSubAuthorityCount
> 0)
64 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
65 if (nSubAuthorityCount
> 1)
66 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
67 if (nSubAuthorityCount
> 2)
68 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
69 if (nSubAuthorityCount
> 3)
70 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
71 if (nSubAuthorityCount
> 4)
72 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
73 if (nSubAuthorityCount
> 5)
74 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
75 if (nSubAuthorityCount
> 6)
76 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
77 if (nSubAuthorityCount
> 7)
78 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
80 return STATUS_SUCCESS
;
82 /******************************************************************************
83 * RtlEqualSid [NTDLL.352]
86 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
88 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
91 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
94 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
100 /******************************************************************************
101 * RtlEqualPrefixSid [ntdll.]
103 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
105 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
108 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
111 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(pSid1
->SubAuthorityCount
- 1)) != 0)
118 /******************************************************************************
119 * RtlFreeSid [NTDLL.376]
121 DWORD WINAPI
RtlFreeSid(PSID pSid
)
123 TRACE("(%p)\n", pSid
);
124 HeapFree( GetProcessHeap(), 0, pSid
);
125 return STATUS_SUCCESS
;
128 /**************************************************************************
129 * RtlLengthRequiredSid [NTDLL.427]
132 * nSubAuthorityCount []
134 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
136 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
139 /**************************************************************************
140 * RtlLengthSid [NTDLL.429]
142 DWORD WINAPI
RtlLengthSid(PSID pSid
)
144 TRACE("sid=%p\n",pSid
);
146 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
149 /**************************************************************************
150 * RtlInitializeSid [NTDLL.410]
152 BOOL WINAPI
RtlInitializeSid(
154 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
155 BYTE nSubAuthorityCount
)
158 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
161 pSid
->Revision
= SID_REVISION
;
162 pSid
->SubAuthorityCount
= nSubAuthorityCount
;
163 if (pIdentifierAuthority
)
164 memcpy(&pSid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
166 for (i
= 0; i
< nSubAuthorityCount
; i
++)
167 *RtlSubAuthoritySid(pSid
, i
) = 0;
172 /**************************************************************************
173 * RtlSubAuthoritySid [NTDLL.497]
179 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
181 return &(pSid
->SubAuthority
[nSubAuthority
]);
184 /**************************************************************************
185 * RtlIdentifierAuthoritySid [NTDLL.395]
190 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
192 return &(pSid
->IdentifierAuthority
);
195 /**************************************************************************
196 * RtlSubAuthorityCountSid [NTDLL.496]
202 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
204 return &(pSid
->SubAuthorityCount
);
207 /**************************************************************************
208 * RtlCopySid [NTDLL.302]
210 DWORD WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
212 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
213 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
216 if (nDestinationSidLength
< (pSourceSid
->SubAuthorityCount
*4+8))
219 memmove(pDestinationSid
, pSourceSid
, pSourceSid
->SubAuthorityCount
*4+8);
222 /******************************************************************************
223 * RtlValidSid [NTDLL.532]
229 RtlValidSid( PSID pSid
)
231 if (IsBadReadPtr(pSid
, 4))
233 WARN("(%p): invalid pointer!\n", pSid
);
237 if (pSid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
240 if (!pSid
|| pSid
->Revision
!= SID_REVISION
)
248 * security descriptor functions
251 /**************************************************************************
252 * RtlCreateSecurityDescriptor [NTDLL.313]
256 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
259 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
260 PSECURITY_DESCRIPTOR lpsd
,
263 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
264 return STATUS_UNKNOWN_REVISION
;
265 memset(lpsd
,'\0',sizeof(*lpsd
));
266 lpsd
->Revision
= SECURITY_DESCRIPTOR_REVISION
;
267 return STATUS_SUCCESS
;
269 /**************************************************************************
270 * RtlValidSecurityDescriptor [NTDLL.313]
273 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
274 PSECURITY_DESCRIPTOR SecurityDescriptor
)
276 if ( ! SecurityDescriptor
)
277 return STATUS_INVALID_SECURITY_DESCR
;
278 if ( SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
279 return STATUS_UNKNOWN_REVISION
;
281 return STATUS_SUCCESS
;
284 /**************************************************************************
285 * RtlLengthSecurityDescriptor [NTDLL]
287 ULONG WINAPI
RtlLengthSecurityDescriptor(
288 PSECURITY_DESCRIPTOR SecurityDescriptor
)
291 Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
292 if ( SecurityDescriptor
== NULL
)
295 if ( SecurityDescriptor
->Owner
!= NULL
)
296 Size
+= SecurityDescriptor
->Owner
->SubAuthorityCount
;
297 if ( SecurityDescriptor
->Group
!= NULL
)
298 Size
+= SecurityDescriptor
->Group
->SubAuthorityCount
;
301 if ( SecurityDescriptor
->Sacl
!= NULL
)
302 Size
+= SecurityDescriptor
->Sacl
->AclSize
;
303 if ( SecurityDescriptor
->Dacl
!= NULL
)
304 Size
+= SecurityDescriptor
->Dacl
->AclSize
;
309 /******************************************************************************
310 * RtlGetDaclSecurityDescriptor [NTDLL]
313 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
314 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
315 OUT PBOOLEAN lpbDaclPresent
,
317 OUT PBOOLEAN lpbDaclDefaulted
)
319 TRACE("(%p,%p,%p,%p)\n",
320 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
322 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
323 return STATUS_UNKNOWN_REVISION
;
325 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
327 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
328 { *pDacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Dacl
);
331 { *pDacl
= pSecurityDescriptor
->Dacl
;
335 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
337 return STATUS_SUCCESS
;
340 /**************************************************************************
341 * RtlSetDaclSecurityDescriptor [NTDLL.483]
343 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
344 PSECURITY_DESCRIPTOR lpsd
,
347 BOOLEAN dacldefaulted
)
349 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
350 return STATUS_UNKNOWN_REVISION
;
351 if (lpsd
->Control
& SE_SELF_RELATIVE
)
352 return STATUS_INVALID_SECURITY_DESCR
;
355 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
359 lpsd
->Control
|= SE_DACL_PRESENT
;
363 lpsd
->Control
|= SE_DACL_DEFAULTED
;
365 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
367 return STATUS_SUCCESS
;
370 /******************************************************************************
371 * RtlGetSaclSecurityDescriptor [NTDLL]
374 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
375 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
376 OUT PBOOLEAN lpbSaclPresent
,
378 OUT PBOOLEAN lpbSaclDefaulted
)
380 TRACE("(%p,%p,%p,%p)\n",
381 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
383 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
384 return STATUS_UNKNOWN_REVISION
;
386 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
388 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
389 { *pSacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Sacl
);
392 { *pSacl
= pSecurityDescriptor
->Sacl
;
396 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
398 return STATUS_SUCCESS
;
401 /**************************************************************************
402 * RtlSetSaclSecurityDescriptor [NTDLL.488]
404 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
405 PSECURITY_DESCRIPTOR lpsd
,
408 BOOLEAN sacldefaulted
)
410 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
411 return STATUS_UNKNOWN_REVISION
;
412 if (lpsd
->Control
& SE_SELF_RELATIVE
)
413 return STATUS_INVALID_SECURITY_DESCR
;
415 lpsd
->Control
&= ~SE_SACL_PRESENT
;
418 lpsd
->Control
|= SE_SACL_PRESENT
;
421 lpsd
->Control
|= SE_SACL_DEFAULTED
;
423 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
424 return STATUS_SUCCESS
;
427 /**************************************************************************
428 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
430 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
431 PSECURITY_DESCRIPTOR SecurityDescriptor
,
433 PBOOLEAN OwnerDefaulted
)
435 if ( !SecurityDescriptor
|| !Owner
|| !OwnerDefaulted
)
436 return STATUS_INVALID_PARAMETER
;
438 *Owner
= SecurityDescriptor
->Owner
;
439 if ( *Owner
!= NULL
) {
440 if ( SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
)
441 *OwnerDefaulted
= TRUE
;
443 *OwnerDefaulted
= FALSE
;
445 return STATUS_SUCCESS
;
448 /**************************************************************************
449 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
451 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
452 PSECURITY_DESCRIPTOR lpsd
,
454 BOOLEAN ownerdefaulted
)
456 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
457 return STATUS_UNKNOWN_REVISION
;
458 if (lpsd
->Control
& SE_SELF_RELATIVE
)
459 return STATUS_INVALID_SECURITY_DESCR
;
463 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
465 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
466 return STATUS_SUCCESS
;
469 /**************************************************************************
470 * RtlSetGroupSecurityDescriptor [NTDLL.485]
472 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
473 PSECURITY_DESCRIPTOR lpsd
,
475 BOOLEAN groupdefaulted
)
477 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
478 return STATUS_UNKNOWN_REVISION
;
479 if (lpsd
->Control
& SE_SELF_RELATIVE
)
480 return STATUS_INVALID_SECURITY_DESCR
;
484 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
486 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
487 return STATUS_SUCCESS
;
489 /**************************************************************************
490 * RtlGetGroupSecurityDescriptor [NTDLL]
492 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
493 PSECURITY_DESCRIPTOR SecurityDescriptor
,
495 PBOOLEAN GroupDefaulted
)
497 if ( !SecurityDescriptor
|| !Group
|| !GroupDefaulted
)
498 return STATUS_INVALID_PARAMETER
;
500 *Group
= SecurityDescriptor
->Group
;
501 if ( *Group
!= NULL
) {
502 if ( SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
)
503 *GroupDefaulted
= TRUE
;
505 *GroupDefaulted
= FALSE
;
507 return STATUS_SUCCESS
;
510 /**************************************************************************
511 * RtlMakeSelfRelativeSD [NTDLL]
513 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
514 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
515 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
516 IN OUT LPDWORD lpdwBufferLength
)
518 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor
,
519 pSelfRelativeSecurityDescriptor
, lpdwBufferLength
,*lpdwBufferLength
);
520 return STATUS_SUCCESS
;
524 * access control list's
527 /**************************************************************************
528 * RtlCreateAcl [NTDLL.306]
531 * This should return NTSTATUS
533 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
535 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
537 if (rev
!=ACL_REVISION
)
538 return STATUS_INVALID_PARAMETER
;
539 if (size
<sizeof(ACL
))
540 return STATUS_BUFFER_TOO_SMALL
;
542 return STATUS_INVALID_PARAMETER
;
544 memset(acl
,'\0',sizeof(ACL
));
545 acl
->AclRevision
= rev
;
551 /**************************************************************************
552 * RtlFirstFreeAce [NTDLL.370]
553 * looks for the AceCount+1 ACE, and if it is still within the alloced
554 * ACL, return a pointer to it
556 BOOLEAN WINAPI
RtlFirstFreeAce(
564 ace
= (PACE_HEADER
)(acl
+1);
565 for (i
=0;i
<acl
->AceCount
;i
++) {
566 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
568 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
570 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
576 /**************************************************************************
577 * RtlAddAce [NTDLL.260]
579 NTSTATUS WINAPI
RtlAddAce(
583 PACE_HEADER acestart
,
586 PACE_HEADER ace
,targetace
;
589 if (acl
->AclRevision
!= ACL_REVISION
)
590 return STATUS_INVALID_PARAMETER
;
591 if (!RtlFirstFreeAce(acl
,&targetace
))
592 return STATUS_INVALID_PARAMETER
;
593 nrofaces
=0;ace
=acestart
;
594 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
596 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
598 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
599 return STATUS_INVALID_PARAMETER
;
600 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
601 acl
->AceCount
+=nrofaces
;
602 return STATUS_SUCCESS
;
605 /******************************************************************************
606 * RtlAddAccessAllowedAce [NTDLL]
608 BOOL WINAPI
RtlAddAccessAllowedAce(
610 IN DWORD dwAceRevision
,
614 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
615 pAcl
, dwAceRevision
, AccessMask
, pSid
);
619 /******************************************************************************
622 DWORD WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
624 FIXME("(%p,%ld,%p),stub!\n",pAcl
,dwAceIndex
,pAce
);
632 /******************************************************************************
633 * RtlAdjustPrivilege [NTDLL]
635 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
637 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
641 /******************************************************************************
642 * RtlImpersonateSelf [NTDLL]
645 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
647 FIXME("(%08x), stub\n", ImpersonationLevel
);
651 /******************************************************************************
652 * NtAccessCheck [NTDLL]
656 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
657 IN HANDLE ClientToken
,
658 IN ACCESS_MASK DesiredAccess
,
659 IN PGENERIC_MAPPING GenericMapping
,
660 OUT PPRIVILEGE_SET PrivilegeSet
,
661 OUT PULONG ReturnLength
,
662 OUT PULONG GrantedAccess
,
663 OUT PBOOLEAN AccessStatus
)
665 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
666 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
667 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
668 *AccessStatus
= TRUE
;
669 return STATUS_SUCCESS
;
672 /******************************************************************************
673 * NtSetSecurityObject [NTDLL]
678 IN SECURITY_INFORMATION SecurityInformation
,
679 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
681 FIXME("0x%08x 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
682 return STATUS_SUCCESS
;
685 /******************************************************************************
686 * RtlGetControlSecurityDescriptor
689 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
690 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
691 PSECURITY_DESCRIPTOR_CONTROL pControl
,
692 LPDWORD lpdwRevision
)
694 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
695 return STATUS_SUCCESS
;
698 /******************************************************************************
699 * RtlConvertSidToUnicodeString
701 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
702 PUNICODE_STRING UnicodeSID
,
705 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
707 LPSTR GenSID
= ".Default"; /* usually the returned SID is used to */
708 /* access "\\REGISTRY\\USER\\.DEFAULT" */
712 FIXME("(%p %p)\n", UnicodeSID
, pSid
);
713 dump_UnicodeString(UnicodeSID
, FALSE
);
715 RtlInitAnsiString(&AnsiStr
, GenSID
);
716 return RtlAnsiStringToUnicodeString(UnicodeSID
, &AnsiStr
, TRUE
);