4 * Copyright 1996-1998 Marcus Meissner
14 #include "wine/exception.h"
17 #include "debugtools.h"
19 #include "stackframe.h"
23 #include "ntdll_misc.h"
25 DEFAULT_DEBUG_CHANNEL(ntdll);
27 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
29 /* filter for page-fault exceptions */
30 static WINE_EXCEPTION_FILTER(page_fault)
32 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
33 return EXCEPTION_EXECUTE_HANDLER;
34 return EXCEPTION_CONTINUE_SEARCH;
41 /******************************************************************************
42 * RtlAllocateAndInitializeSid [NTDLL.@]
45 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
46 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
47 BYTE nSubAuthorityCount,
48 DWORD nSubAuthority0, DWORD nSubAuthority1,
49 DWORD nSubAuthority2, DWORD nSubAuthority3,
50 DWORD nSubAuthority4, DWORD nSubAuthority5,
51 DWORD nSubAuthority6, DWORD nSubAuthority7,
54 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
55 pIdentifierAuthority,nSubAuthorityCount,
56 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
57 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
59 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
62 (*pSid)->Revision = SID_REVISION;
64 if (pIdentifierAuthority)
65 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
66 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
68 if (nSubAuthorityCount > 0)
69 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
70 if (nSubAuthorityCount > 1)
71 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
72 if (nSubAuthorityCount > 2)
73 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
74 if (nSubAuthorityCount > 3)
75 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
76 if (nSubAuthorityCount > 4)
77 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
78 if (nSubAuthorityCount > 5)
79 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
80 if (nSubAuthorityCount > 6)
81 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
82 if (nSubAuthorityCount > 7)
83 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
85 return STATUS_SUCCESS;
87 /******************************************************************************
88 * RtlEqualSid [NTDLL.@]
91 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
93 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
96 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
99 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
105 /******************************************************************************
106 * RtlEqualPrefixSid [NTDLL.@]
108 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
110 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
113 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
116 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
123 /******************************************************************************
124 * RtlFreeSid [NTDLL.@]
126 DWORD WINAPI RtlFreeSid(PSID pSid)
128 TRACE("(%p)\n", pSid);
129 RtlFreeHeap( GetProcessHeap(), 0, pSid );
130 return STATUS_SUCCESS;
133 /**************************************************************************
134 * RtlLengthRequiredSid [NTDLL.@]
137 * nSubAuthorityCount []
139 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
141 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
144 /**************************************************************************
145 * RtlLengthSid [NTDLL.@]
147 DWORD WINAPI RtlLengthSid(PSID pSid)
149 TRACE("sid=%p\n",pSid);
151 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
154 /**************************************************************************
155 * RtlInitializeSid [NTDLL.@]
157 BOOL WINAPI RtlInitializeSid(
159 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
160 BYTE nSubAuthorityCount)
163 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
166 pSid->Revision = SID_REVISION;
167 pSid->SubAuthorityCount = nSubAuthorityCount;
168 if (pIdentifierAuthority)
169 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
171 for (i = 0; i < nSubAuthorityCount; i++)
172 *RtlSubAuthoritySid(pSid, i) = 0;
177 /**************************************************************************
178 * RtlSubAuthoritySid [NTDLL.@]
184 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
186 return &(pSid->SubAuthority[nSubAuthority]);
189 /**************************************************************************
190 * RtlIdentifierAuthoritySid [NTDLL.@]
195 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
197 return &(pSid->IdentifierAuthority);
200 /**************************************************************************
201 * RtlSubAuthorityCountSid [NTDLL.@]
207 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
209 return &(pSid->SubAuthorityCount);
212 /**************************************************************************
213 * RtlCopySid [NTDLL.@]
215 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
217 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
218 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
221 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
224 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
227 /******************************************************************************
228 * RtlValidSid [NTDLL.@]
234 RtlValidSid( PSID pSid )
240 if (!pSid || pSid->Revision != SID_REVISION ||
241 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
248 WARN("(%p): invalid pointer!\n", pSid);
257 * security descriptor functions
260 /**************************************************************************
261 * RtlCreateSecurityDescriptor [NTDLL.@]
265 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
268 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
269 PSECURITY_DESCRIPTOR lpsd,
272 if (rev!=SECURITY_DESCRIPTOR_REVISION)
273 return STATUS_UNKNOWN_REVISION;
274 memset(lpsd,'\0',sizeof(*lpsd));
275 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
276 return STATUS_SUCCESS;
278 /**************************************************************************
279 * RtlValidSecurityDescriptor [NTDLL.@]
282 NTSTATUS WINAPI RtlValidSecurityDescriptor(
283 PSECURITY_DESCRIPTOR SecurityDescriptor)
285 if ( ! SecurityDescriptor )
286 return STATUS_INVALID_SECURITY_DESCR;
287 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
288 return STATUS_UNKNOWN_REVISION;
290 return STATUS_SUCCESS;
293 /**************************************************************************
294 * RtlLengthSecurityDescriptor [NTDLL.@]
296 ULONG WINAPI RtlLengthSecurityDescriptor(
297 PSECURITY_DESCRIPTOR SecurityDescriptor)
300 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
301 if ( SecurityDescriptor == NULL )
304 if ( SecurityDescriptor->Owner != NULL )
305 Size += SecurityDescriptor->Owner->SubAuthorityCount;
306 if ( SecurityDescriptor->Group != NULL )
307 Size += SecurityDescriptor->Group->SubAuthorityCount;
310 if ( SecurityDescriptor->Sacl != NULL )
311 Size += SecurityDescriptor->Sacl->AclSize;
312 if ( SecurityDescriptor->Dacl != NULL )
313 Size += SecurityDescriptor->Dacl->AclSize;
318 /******************************************************************************
319 * RtlGetDaclSecurityDescriptor [NTDLL.@]
322 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
323 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
324 OUT PBOOLEAN lpbDaclPresent,
326 OUT PBOOLEAN lpbDaclDefaulted)
328 TRACE("(%p,%p,%p,%p)\n",
329 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
331 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
332 return STATUS_UNKNOWN_REVISION ;
334 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
336 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
337 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
340 { *pDacl = pSecurityDescriptor->Dacl;
344 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
346 return STATUS_SUCCESS;
349 /**************************************************************************
350 * RtlSetDaclSecurityDescriptor [NTDLL.@]
352 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
353 PSECURITY_DESCRIPTOR lpsd,
356 BOOLEAN dacldefaulted )
358 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
359 return STATUS_UNKNOWN_REVISION;
360 if (lpsd->Control & SE_SELF_RELATIVE)
361 return STATUS_INVALID_SECURITY_DESCR;
364 { lpsd->Control &= ~SE_DACL_PRESENT;
368 lpsd->Control |= SE_DACL_PRESENT;
372 lpsd->Control |= SE_DACL_DEFAULTED;
374 lpsd->Control &= ~SE_DACL_DEFAULTED;
376 return STATUS_SUCCESS;
379 /******************************************************************************
380 * RtlGetSaclSecurityDescriptor [NTDLL.@]
383 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
384 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
385 OUT PBOOLEAN lpbSaclPresent,
387 OUT PBOOLEAN lpbSaclDefaulted)
389 TRACE("(%p,%p,%p,%p)\n",
390 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
392 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
393 return STATUS_UNKNOWN_REVISION ;
395 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
397 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
398 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
401 { *pSacl = pSecurityDescriptor->Sacl;
405 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
407 return STATUS_SUCCESS;
410 /**************************************************************************
411 * RtlSetSaclSecurityDescriptor [NTDLL.@]
413 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
414 PSECURITY_DESCRIPTOR lpsd,
417 BOOLEAN sacldefaulted)
419 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
420 return STATUS_UNKNOWN_REVISION;
421 if (lpsd->Control & SE_SELF_RELATIVE)
422 return STATUS_INVALID_SECURITY_DESCR;
424 lpsd->Control &= ~SE_SACL_PRESENT;
427 lpsd->Control |= SE_SACL_PRESENT;
430 lpsd->Control |= SE_SACL_DEFAULTED;
432 lpsd->Control &= ~SE_SACL_DEFAULTED;
433 return STATUS_SUCCESS;
436 /**************************************************************************
437 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
439 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
440 PSECURITY_DESCRIPTOR SecurityDescriptor,
442 PBOOLEAN OwnerDefaulted)
444 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
445 return STATUS_INVALID_PARAMETER;
447 *Owner = SecurityDescriptor->Owner;
448 if ( *Owner != NULL ) {
449 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
450 *OwnerDefaulted = TRUE;
452 *OwnerDefaulted = FALSE;
454 return STATUS_SUCCESS;
457 /**************************************************************************
458 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
460 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
461 PSECURITY_DESCRIPTOR lpsd,
463 BOOLEAN ownerdefaulted)
465 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
466 return STATUS_UNKNOWN_REVISION;
467 if (lpsd->Control & SE_SELF_RELATIVE)
468 return STATUS_INVALID_SECURITY_DESCR;
472 lpsd->Control |= SE_OWNER_DEFAULTED;
474 lpsd->Control &= ~SE_OWNER_DEFAULTED;
475 return STATUS_SUCCESS;
478 /**************************************************************************
479 * RtlSetGroupSecurityDescriptor [NTDLL.@]
481 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
482 PSECURITY_DESCRIPTOR lpsd,
484 BOOLEAN groupdefaulted)
486 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
487 return STATUS_UNKNOWN_REVISION;
488 if (lpsd->Control & SE_SELF_RELATIVE)
489 return STATUS_INVALID_SECURITY_DESCR;
493 lpsd->Control |= SE_GROUP_DEFAULTED;
495 lpsd->Control &= ~SE_GROUP_DEFAULTED;
496 return STATUS_SUCCESS;
498 /**************************************************************************
499 * RtlGetGroupSecurityDescriptor [NTDLL.@]
501 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
502 PSECURITY_DESCRIPTOR SecurityDescriptor,
504 PBOOLEAN GroupDefaulted)
506 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
507 return STATUS_INVALID_PARAMETER;
509 *Group = SecurityDescriptor->Group;
510 if ( *Group != NULL ) {
511 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
512 *GroupDefaulted = TRUE;
514 *GroupDefaulted = FALSE;
516 return STATUS_SUCCESS;
519 /**************************************************************************
520 * RtlMakeSelfRelativeSD [NTDLL.@]
522 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
523 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
524 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
525 IN OUT LPDWORD lpdwBufferLength)
527 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
528 pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
529 return STATUS_SUCCESS;
533 * access control list's
536 /**************************************************************************
537 * RtlCreateAcl [NTDLL.@]
540 * This should return NTSTATUS
542 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
544 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
546 if (rev!=ACL_REVISION)
547 return STATUS_INVALID_PARAMETER;
548 if (size<sizeof(ACL))
549 return STATUS_BUFFER_TOO_SMALL;
551 return STATUS_INVALID_PARAMETER;
553 memset(acl,'\0',sizeof(ACL));
554 acl->AclRevision = rev;
560 /**************************************************************************
561 * RtlFirstFreeAce [NTDLL.@]
562 * looks for the AceCount+1 ACE, and if it is still within the alloced
563 * ACL, return a pointer to it
565 BOOLEAN WINAPI RtlFirstFreeAce(
573 ace = (PACE_HEADER)(acl+1);
574 for (i=0;i<acl->AceCount;i++) {
575 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
577 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
579 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
585 /**************************************************************************
586 * RtlAddAce [NTDLL.@]
588 NTSTATUS WINAPI RtlAddAce(
592 PACE_HEADER acestart,
595 PACE_HEADER ace,targetace;
598 if (acl->AclRevision != ACL_REVISION)
599 return STATUS_INVALID_PARAMETER;
600 if (!RtlFirstFreeAce(acl,&targetace))
601 return STATUS_INVALID_PARAMETER;
602 nrofaces=0;ace=acestart;
603 while (((DWORD)ace-(DWORD)acestart)<acelen) {
605 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
607 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
608 return STATUS_INVALID_PARAMETER;
609 memcpy((LPBYTE)targetace,acestart,acelen);
610 acl->AceCount+=nrofaces;
611 return STATUS_SUCCESS;
614 /******************************************************************************
615 * RtlAddAccessAllowedAce [NTDLL.@]
617 BOOL WINAPI RtlAddAccessAllowedAce(
619 IN DWORD dwAceRevision,
623 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
624 pAcl, dwAceRevision, AccessMask, pSid);
628 /******************************************************************************
629 * RtlGetAce [NTDLL.@]
631 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
633 FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
641 /******************************************************************************
642 * RtlAdjustPrivilege [NTDLL.@]
644 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
646 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
650 /******************************************************************************
651 * RtlImpersonateSelf [NTDLL.@]
654 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
656 FIXME("(%08x), stub\n", ImpersonationLevel);
660 /******************************************************************************
661 * NtAccessCheck [NTDLL.@]
665 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
666 IN HANDLE ClientToken,
667 IN ACCESS_MASK DesiredAccess,
668 IN PGENERIC_MAPPING GenericMapping,
669 OUT PPRIVILEGE_SET PrivilegeSet,
670 OUT PULONG ReturnLength,
671 OUT PULONG GrantedAccess,
672 OUT PBOOLEAN AccessStatus)
674 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
675 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
676 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
677 *AccessStatus = TRUE;
678 return STATUS_SUCCESS;
681 /******************************************************************************
682 * NtSetSecurityObject [NTDLL.@]
687 IN SECURITY_INFORMATION SecurityInformation,
688 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
690 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
691 return STATUS_SUCCESS;
694 /******************************************************************************
695 * RtlGetControlSecurityDescriptor (NTDLL.@)
698 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
699 PSECURITY_DESCRIPTOR pSecurityDescriptor,
700 PSECURITY_DESCRIPTOR_CONTROL pControl,
701 LPDWORD lpdwRevision)
703 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
704 return STATUS_SUCCESS;
707 /******************************************************************************
708 * RtlConvertSidToUnicodeString (NTDLL.@)
710 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
711 PUNICODE_STRING UnicodeSID,
714 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
716 LPSTR GenSID = ".Default"; /* usually the returned SID is used to */
717 /* access "\\REGISTRY\\USER\\.DEFAULT" */
721 FIXME("(%p %p)\n", UnicodeSID, pSid);
723 TRACE("%p(<OUT>) (%u %u)\n",
724 UnicodeSID->Buffer, UnicodeSID->Length, UnicodeSID->MaximumLength);
726 RtlInitAnsiString(&AnsiStr, GenSID);
727 return RtlAnsiStringToUnicodeString(UnicodeSID, &AnsiStr, TRUE);