4 * Copyright 1996-1998 Marcus Meissner
14 #include "wine/winestring.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)
34 /******************************************************************************
35 * RtlAllocateAndInitializeSid [NTDLL.265]
38 BOOLEAN WINAPI
RtlAllocateAndInitializeSid (
39 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
40 BYTE nSubAuthorityCount
,
41 DWORD nSubAuthority0
, DWORD nSubAuthority1
,
42 DWORD nSubAuthority2
, DWORD nSubAuthority3
,
43 DWORD nSubAuthority4
, DWORD nSubAuthority5
,
44 DWORD nSubAuthority6
, DWORD nSubAuthority7
,
47 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
48 pIdentifierAuthority
,nSubAuthorityCount
,
49 nSubAuthority0
, nSubAuthority1
, nSubAuthority2
, nSubAuthority3
,
50 nSubAuthority4
, nSubAuthority5
, nSubAuthority6
, nSubAuthority7
, pSid
);
52 if (!(*pSid
= HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount
))))
55 (*pSid
)->Revision
= SID_REVISION
;
57 if (pIdentifierAuthority
)
58 memcpy(&(*pSid
)->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
59 *RtlSubAuthorityCountSid(*pSid
) = nSubAuthorityCount
;
61 if (nSubAuthorityCount
> 0)
62 *RtlSubAuthoritySid(*pSid
, 0) = nSubAuthority0
;
63 if (nSubAuthorityCount
> 1)
64 *RtlSubAuthoritySid(*pSid
, 1) = nSubAuthority1
;
65 if (nSubAuthorityCount
> 2)
66 *RtlSubAuthoritySid(*pSid
, 2) = nSubAuthority2
;
67 if (nSubAuthorityCount
> 3)
68 *RtlSubAuthoritySid(*pSid
, 3) = nSubAuthority3
;
69 if (nSubAuthorityCount
> 4)
70 *RtlSubAuthoritySid(*pSid
, 4) = nSubAuthority4
;
71 if (nSubAuthorityCount
> 5)
72 *RtlSubAuthoritySid(*pSid
, 5) = nSubAuthority5
;
73 if (nSubAuthorityCount
> 6)
74 *RtlSubAuthoritySid(*pSid
, 6) = nSubAuthority6
;
75 if (nSubAuthorityCount
> 7)
76 *RtlSubAuthoritySid(*pSid
, 7) = nSubAuthority7
;
78 return STATUS_SUCCESS
;
80 /******************************************************************************
81 * RtlEqualSid [NTDLL.352]
84 BOOL WINAPI
RtlEqualSid( PSID pSid1
, PSID pSid2
)
86 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
89 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
92 if (memcmp(pSid1
, pSid2
, RtlLengthSid(pSid1
)) != 0)
98 /******************************************************************************
99 * RtlEqualPrefixSid [ntdll.]
101 BOOL WINAPI
RtlEqualPrefixSid (PSID pSid1
, PSID pSid2
)
103 if (!RtlValidSid(pSid1
) || !RtlValidSid(pSid2
))
106 if (*RtlSubAuthorityCountSid(pSid1
) != *RtlSubAuthorityCountSid(pSid2
))
109 if (memcmp(pSid1
, pSid2
, RtlLengthRequiredSid(pSid1
->SubAuthorityCount
- 1)) != 0)
116 /******************************************************************************
117 * RtlFreeSid [NTDLL.376]
119 DWORD WINAPI
RtlFreeSid(PSID pSid
)
121 TRACE("(%p)\n", pSid
);
122 HeapFree( GetProcessHeap(), 0, pSid
);
123 return STATUS_SUCCESS
;
126 /**************************************************************************
127 * RtlLengthRequiredSid [NTDLL.427]
130 * nSubAuthorityCount []
132 DWORD WINAPI
RtlLengthRequiredSid(DWORD nrofsubauths
)
134 return (nrofsubauths
-1)*sizeof(DWORD
) + sizeof(SID
);
137 /**************************************************************************
138 * RtlLengthSid [NTDLL.429]
140 DWORD WINAPI
RtlLengthSid(PSID pSid
)
142 TRACE("sid=%p\n",pSid
);
144 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid
));
147 /**************************************************************************
148 * RtlInitializeSid [NTDLL.410]
150 BOOL WINAPI
RtlInitializeSid(
152 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority
,
153 BYTE nSubAuthorityCount
)
156 if (nSubAuthorityCount
>= SID_MAX_SUB_AUTHORITIES
)
159 pSid
->Revision
= SID_REVISION
;
160 pSid
->SubAuthorityCount
= nSubAuthorityCount
;
161 if (pIdentifierAuthority
)
162 memcpy(&pSid
->IdentifierAuthority
, pIdentifierAuthority
, sizeof (SID_IDENTIFIER_AUTHORITY
));
164 for (i
= 0; i
< nSubAuthorityCount
; i
++)
165 *RtlSubAuthoritySid(pSid
, i
) = 0;
170 /**************************************************************************
171 * RtlSubAuthoritySid [NTDLL.497]
177 LPDWORD WINAPI
RtlSubAuthoritySid( PSID pSid
, DWORD nSubAuthority
)
179 return &(pSid
->SubAuthority
[nSubAuthority
]);
182 /**************************************************************************
183 * RtlIdentifierAuthoritySid [NTDLL.395]
188 PSID_IDENTIFIER_AUTHORITY WINAPI
RtlIdentifierAuthoritySid( PSID pSid
)
190 return &(pSid
->IdentifierAuthority
);
193 /**************************************************************************
194 * RtlSubAuthorityCountSid [NTDLL.496]
200 LPBYTE WINAPI
RtlSubAuthorityCountSid(PSID pSid
)
202 return &(pSid
->SubAuthorityCount
);
205 /**************************************************************************
206 * RtlCopySid [NTDLL.302]
208 DWORD WINAPI
RtlCopySid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PSID pSourceSid
)
210 if (!pSourceSid
|| !RtlValidSid(pSourceSid
) ||
211 (nDestinationSidLength
< RtlLengthSid(pSourceSid
)))
214 if (nDestinationSidLength
< (pSourceSid
->SubAuthorityCount
*4+8))
217 memmove(pDestinationSid
, pSourceSid
, pSourceSid
->SubAuthorityCount
*4+8);
220 /******************************************************************************
221 * RtlValidSid [NTDLL.532]
227 RtlValidSid( PSID pSid
)
229 if (IsBadReadPtr(pSid
, 4))
231 WARN("(%p): invalid pointer!\n", pSid
);
235 if (pSid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
)
238 if (!pSid
|| pSid
->Revision
!= SID_REVISION
)
246 * security descriptor functions
249 /**************************************************************************
250 * RtlCreateSecurityDescriptor [NTDLL.313]
254 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
257 NTSTATUS WINAPI
RtlCreateSecurityDescriptor(
258 PSECURITY_DESCRIPTOR lpsd
,
261 if (rev
!=SECURITY_DESCRIPTOR_REVISION
)
262 return STATUS_UNKNOWN_REVISION
;
263 memset(lpsd
,'\0',sizeof(*lpsd
));
264 lpsd
->Revision
= SECURITY_DESCRIPTOR_REVISION
;
265 return STATUS_SUCCESS
;
267 /**************************************************************************
268 * RtlValidSecurityDescriptor [NTDLL.313]
271 NTSTATUS WINAPI
RtlValidSecurityDescriptor(
272 PSECURITY_DESCRIPTOR SecurityDescriptor
)
274 if ( ! SecurityDescriptor
)
275 return STATUS_INVALID_SECURITY_DESCR
;
276 if ( SecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
277 return STATUS_UNKNOWN_REVISION
;
279 return STATUS_SUCCESS
;
282 /**************************************************************************
283 * RtlLengthSecurityDescriptor [NTDLL]
285 ULONG WINAPI
RtlLengthSecurityDescriptor(
286 PSECURITY_DESCRIPTOR SecurityDescriptor
)
289 Size
= SECURITY_DESCRIPTOR_MIN_LENGTH
;
290 if ( SecurityDescriptor
== NULL
)
293 if ( SecurityDescriptor
->Owner
!= NULL
)
294 Size
+= SecurityDescriptor
->Owner
->SubAuthorityCount
;
295 if ( SecurityDescriptor
->Group
!= NULL
)
296 Size
+= SecurityDescriptor
->Group
->SubAuthorityCount
;
299 if ( SecurityDescriptor
->Sacl
!= NULL
)
300 Size
+= SecurityDescriptor
->Sacl
->AclSize
;
301 if ( SecurityDescriptor
->Dacl
!= NULL
)
302 Size
+= SecurityDescriptor
->Dacl
->AclSize
;
307 /******************************************************************************
308 * RtlGetDaclSecurityDescriptor [NTDLL]
311 NTSTATUS WINAPI
RtlGetDaclSecurityDescriptor(
312 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
313 OUT PBOOLEAN lpbDaclPresent
,
315 OUT PBOOLEAN lpbDaclDefaulted
)
317 TRACE("(%p,%p,%p,%p)\n",
318 pSecurityDescriptor
, lpbDaclPresent
, *pDacl
, lpbDaclDefaulted
);
320 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
321 return STATUS_UNKNOWN_REVISION
;
323 if ( (*lpbDaclPresent
= (SE_DACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
325 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
326 { *pDacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Dacl
);
329 { *pDacl
= pSecurityDescriptor
->Dacl
;
333 *lpbDaclDefaulted
= (( SE_DACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
335 return STATUS_SUCCESS
;
338 /**************************************************************************
339 * RtlSetDaclSecurityDescriptor [NTDLL.483]
341 NTSTATUS WINAPI
RtlSetDaclSecurityDescriptor (
342 PSECURITY_DESCRIPTOR lpsd
,
345 BOOLEAN dacldefaulted
)
347 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
348 return STATUS_UNKNOWN_REVISION
;
349 if (lpsd
->Control
& SE_SELF_RELATIVE
)
350 return STATUS_INVALID_SECURITY_DESCR
;
353 { lpsd
->Control
&= ~SE_DACL_PRESENT
;
357 lpsd
->Control
|= SE_DACL_PRESENT
;
361 lpsd
->Control
|= SE_DACL_DEFAULTED
;
363 lpsd
->Control
&= ~SE_DACL_DEFAULTED
;
365 return STATUS_SUCCESS
;
368 /******************************************************************************
369 * RtlGetSaclSecurityDescriptor [NTDLL]
372 NTSTATUS WINAPI
RtlGetSaclSecurityDescriptor(
373 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
,
374 OUT PBOOLEAN lpbSaclPresent
,
376 OUT PBOOLEAN lpbSaclDefaulted
)
378 TRACE("(%p,%p,%p,%p)\n",
379 pSecurityDescriptor
, lpbSaclPresent
, *pSacl
, lpbSaclDefaulted
);
381 if (pSecurityDescriptor
->Revision
!= SECURITY_DESCRIPTOR_REVISION
)
382 return STATUS_UNKNOWN_REVISION
;
384 if ( (*lpbSaclPresent
= (SE_SACL_PRESENT
& pSecurityDescriptor
->Control
) ? 1 : 0) )
386 if ( SE_SELF_RELATIVE
& pSecurityDescriptor
->Control
)
387 { *pSacl
= (PACL
) ((LPBYTE
)pSecurityDescriptor
+ (DWORD
)pSecurityDescriptor
->Sacl
);
390 { *pSacl
= pSecurityDescriptor
->Sacl
;
394 *lpbSaclDefaulted
= (( SE_SACL_DEFAULTED
& pSecurityDescriptor
->Control
) ? 1 : 0);
396 return STATUS_SUCCESS
;
399 /**************************************************************************
400 * RtlSetSaclSecurityDescriptor [NTDLL.488]
402 NTSTATUS WINAPI
RtlSetSaclSecurityDescriptor (
403 PSECURITY_DESCRIPTOR lpsd
,
406 BOOLEAN sacldefaulted
)
408 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
409 return STATUS_UNKNOWN_REVISION
;
410 if (lpsd
->Control
& SE_SELF_RELATIVE
)
411 return STATUS_INVALID_SECURITY_DESCR
;
413 lpsd
->Control
&= ~SE_SACL_PRESENT
;
416 lpsd
->Control
|= SE_SACL_PRESENT
;
419 lpsd
->Control
|= SE_SACL_DEFAULTED
;
421 lpsd
->Control
&= ~SE_SACL_DEFAULTED
;
422 return STATUS_SUCCESS
;
425 /**************************************************************************
426 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
428 NTSTATUS WINAPI
RtlGetOwnerSecurityDescriptor(
429 PSECURITY_DESCRIPTOR SecurityDescriptor
,
431 PBOOLEAN OwnerDefaulted
)
433 if ( !SecurityDescriptor
|| !Owner
|| !OwnerDefaulted
)
434 return STATUS_INVALID_PARAMETER
;
436 *Owner
= SecurityDescriptor
->Owner
;
437 if ( *Owner
!= NULL
) {
438 if ( SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
)
439 *OwnerDefaulted
= TRUE
;
441 *OwnerDefaulted
= FALSE
;
443 return STATUS_SUCCESS
;
446 /**************************************************************************
447 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
449 NTSTATUS WINAPI
RtlSetOwnerSecurityDescriptor(
450 PSECURITY_DESCRIPTOR lpsd
,
452 BOOLEAN ownerdefaulted
)
454 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
455 return STATUS_UNKNOWN_REVISION
;
456 if (lpsd
->Control
& SE_SELF_RELATIVE
)
457 return STATUS_INVALID_SECURITY_DESCR
;
461 lpsd
->Control
|= SE_OWNER_DEFAULTED
;
463 lpsd
->Control
&= ~SE_OWNER_DEFAULTED
;
464 return STATUS_SUCCESS
;
467 /**************************************************************************
468 * RtlSetGroupSecurityDescriptor [NTDLL.485]
470 NTSTATUS WINAPI
RtlSetGroupSecurityDescriptor (
471 PSECURITY_DESCRIPTOR lpsd
,
473 BOOLEAN groupdefaulted
)
475 if (lpsd
->Revision
!=SECURITY_DESCRIPTOR_REVISION
)
476 return STATUS_UNKNOWN_REVISION
;
477 if (lpsd
->Control
& SE_SELF_RELATIVE
)
478 return STATUS_INVALID_SECURITY_DESCR
;
482 lpsd
->Control
|= SE_GROUP_DEFAULTED
;
484 lpsd
->Control
&= ~SE_GROUP_DEFAULTED
;
485 return STATUS_SUCCESS
;
487 /**************************************************************************
488 * RtlGetGroupSecurityDescriptor [NTDLL]
490 NTSTATUS WINAPI
RtlGetGroupSecurityDescriptor(
491 PSECURITY_DESCRIPTOR SecurityDescriptor
,
493 PBOOLEAN GroupDefaulted
)
495 if ( !SecurityDescriptor
|| !Group
|| !GroupDefaulted
)
496 return STATUS_INVALID_PARAMETER
;
498 *Group
= SecurityDescriptor
->Group
;
499 if ( *Group
!= NULL
) {
500 if ( SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
)
501 *GroupDefaulted
= TRUE
;
503 *GroupDefaulted
= FALSE
;
505 return STATUS_SUCCESS
;
508 /**************************************************************************
509 * RtlMakeSelfRelativeSD [NTDLL]
511 NTSTATUS WINAPI
RtlMakeSelfRelativeSD(
512 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor
,
513 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor
,
514 IN OUT LPDWORD lpdwBufferLength
)
516 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor
,
517 pSelfRelativeSecurityDescriptor
, lpdwBufferLength
,*lpdwBufferLength
);
518 return STATUS_SUCCESS
;
522 * access control list's
525 /**************************************************************************
526 * RtlCreateAcl [NTDLL.306]
529 * This should return NTSTATUS
531 NTSTATUS WINAPI
RtlCreateAcl(PACL acl
,DWORD size
,DWORD rev
)
533 TRACE("%p 0x%08lx 0x%08lx\n", acl
, size
, rev
);
535 if (rev
!=ACL_REVISION
)
536 return STATUS_INVALID_PARAMETER
;
537 if (size
<sizeof(ACL
))
538 return STATUS_BUFFER_TOO_SMALL
;
540 return STATUS_INVALID_PARAMETER
;
542 memset(acl
,'\0',sizeof(ACL
));
543 acl
->AclRevision
= rev
;
549 /**************************************************************************
550 * RtlFirstFreeAce [NTDLL.370]
551 * looks for the AceCount+1 ACE, and if it is still within the alloced
552 * ACL, return a pointer to it
554 BOOLEAN WINAPI
RtlFirstFreeAce(
562 ace
= (PACE_HEADER
)(acl
+1);
563 for (i
=0;i
<acl
->AceCount
;i
++) {
564 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
566 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
568 if ((DWORD
)ace
>=(((DWORD
)acl
)+acl
->AclSize
))
574 /**************************************************************************
575 * RtlAddAce [NTDLL.260]
577 NTSTATUS WINAPI
RtlAddAce(
581 PACE_HEADER acestart
,
584 PACE_HEADER ace
,targetace
;
587 if (acl
->AclRevision
!= ACL_REVISION
)
588 return STATUS_INVALID_PARAMETER
;
589 if (!RtlFirstFreeAce(acl
,&targetace
))
590 return STATUS_INVALID_PARAMETER
;
591 nrofaces
=0;ace
=acestart
;
592 while (((DWORD
)ace
-(DWORD
)acestart
)<acelen
) {
594 ace
= (PACE_HEADER
)(((BYTE
*)ace
)+ace
->AceSize
);
596 if ((DWORD
)targetace
+acelen
>(DWORD
)acl
+acl
->AclSize
) /* too much aces */
597 return STATUS_INVALID_PARAMETER
;
598 memcpy((LPBYTE
)targetace
,acestart
,acelen
);
599 acl
->AceCount
+=nrofaces
;
600 return STATUS_SUCCESS
;
603 /******************************************************************************
604 * RtlAddAccessAllowedAce [NTDLL]
606 BOOL WINAPI
RtlAddAccessAllowedAce(
608 IN DWORD dwAceRevision
,
612 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
613 pAcl
, dwAceRevision
, AccessMask
, pSid
);
617 /******************************************************************************
620 DWORD WINAPI
RtlGetAce(PACL pAcl
,DWORD dwAceIndex
,LPVOID
*pAce
)
622 FIXME("(%p,%ld,%p),stub!\n",pAcl
,dwAceIndex
,pAce
);
630 /******************************************************************************
631 * RtlAdjustPrivilege [NTDLL]
633 DWORD WINAPI
RtlAdjustPrivilege(DWORD x1
,DWORD x2
,DWORD x3
,DWORD x4
)
635 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1
,x2
,x3
,x4
);
639 /******************************************************************************
640 * RtlImpersonateSelf [NTDLL]
643 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
645 FIXME("(%08x), stub\n", ImpersonationLevel
);
649 /******************************************************************************
650 * NtAccessCheck [NTDLL]
654 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
655 IN HANDLE ClientToken
,
656 IN ACCESS_MASK DesiredAccess
,
657 IN PGENERIC_MAPPING GenericMapping
,
658 OUT PPRIVILEGE_SET PrivilegeSet
,
659 OUT PULONG ReturnLength
,
660 OUT PULONG GrantedAccess
,
661 OUT PBOOLEAN AccessStatus
)
663 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
664 SecurityDescriptor
, ClientToken
, DesiredAccess
, GenericMapping
,
665 PrivilegeSet
, ReturnLength
, GrantedAccess
, AccessStatus
);
666 *AccessStatus
= TRUE
;
667 return STATUS_SUCCESS
;
670 /******************************************************************************
671 * NtSetSecurityObject [NTDLL]
676 IN SECURITY_INFORMATION SecurityInformation
,
677 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
679 FIXME("0x%08x 0x%08lx %p\n", Handle
, SecurityInformation
, SecurityDescriptor
);
680 return STATUS_SUCCESS
;
683 /******************************************************************************
684 * RtlGetControlSecurityDescriptor
687 NTSTATUS WINAPI
RtlGetControlSecurityDescriptor(
688 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
689 PSECURITY_DESCRIPTOR_CONTROL pControl
,
690 LPDWORD lpdwRevision
)
692 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor
,pControl
,lpdwRevision
);
693 return STATUS_SUCCESS
;
696 /******************************************************************************
697 * RtlConvertSidToUnicodeString
699 NTSTATUS WINAPI
RtlConvertSidToUnicodeString(
700 PUNICODE_STRING UnicodeSID
,
703 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
705 LPSTR GenSID
= ".Default"; /* usually the returned SID is used to */
706 /* access "\\REGISTRY\\USER\\.DEFAULT" */
710 FIXME("(%p %p)\n", UnicodeSID
, pSid
);
711 dump_UnicodeString(UnicodeSID
, FALSE
);
713 RtlInitAnsiString(&AnsiStr
, GenSID
);
714 return RtlAnsiStringToUnicodeString(UnicodeSID
, &AnsiStr
, TRUE
);