4 * Copyright 1996-1998 Marcus Meissner
15 #include "wine/winestring.h"
19 #include "debugtools.h"
21 #include "stackframe.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 *GetSidSubAuthorityCount(*pSid) = nSubAuthorityCount;
61 if (nSubAuthorityCount > 0)
62 *GetSidSubAuthority(*pSid, 0) = nSubAuthority0;
63 if (nSubAuthorityCount > 1)
64 *GetSidSubAuthority(*pSid, 1) = nSubAuthority1;
65 if (nSubAuthorityCount > 2)
66 *GetSidSubAuthority(*pSid, 2) = nSubAuthority2;
67 if (nSubAuthorityCount > 3)
68 *GetSidSubAuthority(*pSid, 3) = nSubAuthority3;
69 if (nSubAuthorityCount > 4)
70 *GetSidSubAuthority(*pSid, 4) = nSubAuthority4;
71 if (nSubAuthorityCount > 5)
72 *GetSidSubAuthority(*pSid, 5) = nSubAuthority5;
73 if (nSubAuthorityCount > 6)
74 *GetSidSubAuthority(*pSid, 6) = nSubAuthority6;
75 if (nSubAuthorityCount > 7)
76 *GetSidSubAuthority(*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, GetLengthSid(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 *GetSidSubAuthority(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);
651 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
652 IN HANDLE ClientToken,
653 IN ACCESS_MASK DesiredAccess,
654 IN PGENERIC_MAPPING GenericMapping,
655 OUT PPRIVILEGE_SET PrivilegeSet,
656 OUT PULONG ReturnLength,
657 OUT PULONG GrantedAccess,
658 OUT PBOOLEAN AccessStatus)
660 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
661 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
662 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
663 *AccessStatus = TRUE;
664 return STATUS_SUCCESS;
670 IN SECURITY_INFORMATION SecurityInformation,
671 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
673 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
674 return STATUS_SUCCESS;
677 /******************************************************************************
678 * RtlGetControlSecurityDescriptor
681 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
682 PSECURITY_DESCRIPTOR pSecurityDescriptor,
683 PSECURITY_DESCRIPTOR_CONTROL pControl,
684 LPDWORD lpdwRevision)
686 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
687 return STATUS_SUCCESS;