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 *GetSidSubAuthorityCount(*pSid) = nSubAuthorityCount;
63 if (nSubAuthorityCount > 0)
64 *GetSidSubAuthority(*pSid, 0) = nSubAuthority0;
65 if (nSubAuthorityCount > 1)
66 *GetSidSubAuthority(*pSid, 1) = nSubAuthority1;
67 if (nSubAuthorityCount > 2)
68 *GetSidSubAuthority(*pSid, 2) = nSubAuthority2;
69 if (nSubAuthorityCount > 3)
70 *GetSidSubAuthority(*pSid, 3) = nSubAuthority3;
71 if (nSubAuthorityCount > 4)
72 *GetSidSubAuthority(*pSid, 4) = nSubAuthority4;
73 if (nSubAuthorityCount > 5)
74 *GetSidSubAuthority(*pSid, 5) = nSubAuthority5;
75 if (nSubAuthorityCount > 6)
76 *GetSidSubAuthority(*pSid, 6) = nSubAuthority6;
77 if (nSubAuthorityCount > 7)
78 *GetSidSubAuthority(*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, GetLengthSid(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 *GetSidSubAuthority(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);