4 * Copyright 1996-1998 Marcus Meissner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include "wine/exception.h"
38 #include "wine/debug.h"
40 #include "stackframe.h"
44 #include "ntdll_misc.h"
45 #include "msvcrt/excpt.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
49 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
51 /* filter for page-fault exceptions */
52 static WINE_EXCEPTION_FILTER(page_fault)
54 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
55 return EXCEPTION_EXECUTE_HANDLER;
56 return EXCEPTION_CONTINUE_SEARCH;
63 /******************************************************************************
64 * RtlAllocateAndInitializeSid [NTDLL.@]
67 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
68 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
69 BYTE nSubAuthorityCount,
70 DWORD nSubAuthority0, DWORD nSubAuthority1,
71 DWORD nSubAuthority2, DWORD nSubAuthority3,
72 DWORD nSubAuthority4, DWORD nSubAuthority5,
73 DWORD nSubAuthority6, DWORD nSubAuthority7,
76 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
77 pIdentifierAuthority,nSubAuthorityCount,
78 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
79 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
81 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
84 (*pSid)->Revision = SID_REVISION;
86 if (pIdentifierAuthority)
87 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
88 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
90 if (nSubAuthorityCount > 0)
91 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
92 if (nSubAuthorityCount > 1)
93 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
94 if (nSubAuthorityCount > 2)
95 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
96 if (nSubAuthorityCount > 3)
97 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
98 if (nSubAuthorityCount > 4)
99 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
100 if (nSubAuthorityCount > 5)
101 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
102 if (nSubAuthorityCount > 6)
103 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
104 if (nSubAuthorityCount > 7)
105 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
107 return STATUS_SUCCESS;
109 /******************************************************************************
110 * RtlEqualSid [NTDLL.@]
113 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
115 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
118 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
121 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
127 /******************************************************************************
128 * RtlEqualPrefixSid [NTDLL.@]
130 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
132 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
135 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
138 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
145 /******************************************************************************
146 * RtlFreeSid [NTDLL.@]
148 DWORD WINAPI RtlFreeSid(PSID pSid)
150 TRACE("(%p)\n", pSid);
151 RtlFreeHeap( GetProcessHeap(), 0, pSid );
152 return STATUS_SUCCESS;
155 /**************************************************************************
156 * RtlLengthRequiredSid [NTDLL.@]
159 * nSubAuthorityCount []
161 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
163 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
166 /**************************************************************************
167 * RtlLengthSid [NTDLL.@]
169 DWORD WINAPI RtlLengthSid(PSID pSid)
171 TRACE("sid=%p\n",pSid);
173 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
176 /**************************************************************************
177 * RtlInitializeSid [NTDLL.@]
179 BOOL WINAPI RtlInitializeSid(
181 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
182 BYTE nSubAuthorityCount)
185 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
188 pSid->Revision = SID_REVISION;
189 pSid->SubAuthorityCount = nSubAuthorityCount;
190 if (pIdentifierAuthority)
191 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
193 for (i = 0; i < nSubAuthorityCount; i++)
194 *RtlSubAuthoritySid(pSid, i) = 0;
199 /**************************************************************************
200 * RtlSubAuthoritySid [NTDLL.@]
206 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
208 return &(pSid->SubAuthority[nSubAuthority]);
211 /**************************************************************************
212 * RtlIdentifierAuthoritySid [NTDLL.@]
217 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
219 return &(pSid->IdentifierAuthority);
222 /**************************************************************************
223 * RtlSubAuthorityCountSid [NTDLL.@]
229 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
231 return &(pSid->SubAuthorityCount);
234 /**************************************************************************
235 * RtlCopySid [NTDLL.@]
237 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
239 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
240 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
243 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
246 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
249 /******************************************************************************
250 * RtlValidSid [NTDLL.@]
256 RtlValidSid( PSID pSid )
262 if (!pSid || pSid->Revision != SID_REVISION ||
263 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
270 WARN("(%p): invalid pointer!\n", pSid);
279 * security descriptor functions
282 /**************************************************************************
283 * RtlCreateSecurityDescriptor [NTDLL.@]
287 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
290 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
291 PSECURITY_DESCRIPTOR lpsd,
294 if (rev!=SECURITY_DESCRIPTOR_REVISION)
295 return STATUS_UNKNOWN_REVISION;
296 memset(lpsd,'\0',sizeof(*lpsd));
297 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
298 return STATUS_SUCCESS;
300 /**************************************************************************
301 * RtlValidSecurityDescriptor [NTDLL.@]
304 NTSTATUS WINAPI RtlValidSecurityDescriptor(
305 PSECURITY_DESCRIPTOR SecurityDescriptor)
307 if ( ! SecurityDescriptor )
308 return STATUS_INVALID_SECURITY_DESCR;
309 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
310 return STATUS_UNKNOWN_REVISION;
312 return STATUS_SUCCESS;
315 /**************************************************************************
316 * RtlLengthSecurityDescriptor [NTDLL.@]
318 ULONG WINAPI RtlLengthSecurityDescriptor(
319 PSECURITY_DESCRIPTOR SecurityDescriptor)
322 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
323 if ( SecurityDescriptor == NULL )
326 if ( SecurityDescriptor->Owner != NULL )
327 Size += SecurityDescriptor->Owner->SubAuthorityCount;
328 if ( SecurityDescriptor->Group != NULL )
329 Size += SecurityDescriptor->Group->SubAuthorityCount;
332 if ( SecurityDescriptor->Sacl != NULL )
333 Size += SecurityDescriptor->Sacl->AclSize;
334 if ( SecurityDescriptor->Dacl != NULL )
335 Size += SecurityDescriptor->Dacl->AclSize;
340 /******************************************************************************
341 * RtlGetDaclSecurityDescriptor [NTDLL.@]
344 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
345 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
346 OUT PBOOLEAN lpbDaclPresent,
348 OUT PBOOLEAN lpbDaclDefaulted)
350 TRACE("(%p,%p,%p,%p)\n",
351 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
353 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
354 return STATUS_UNKNOWN_REVISION ;
356 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
358 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
359 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
362 { *pDacl = pSecurityDescriptor->Dacl;
366 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
368 return STATUS_SUCCESS;
371 /**************************************************************************
372 * RtlSetDaclSecurityDescriptor [NTDLL.@]
374 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
375 PSECURITY_DESCRIPTOR lpsd,
378 BOOLEAN dacldefaulted )
380 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
381 return STATUS_UNKNOWN_REVISION;
382 if (lpsd->Control & SE_SELF_RELATIVE)
383 return STATUS_INVALID_SECURITY_DESCR;
386 { lpsd->Control &= ~SE_DACL_PRESENT;
390 lpsd->Control |= SE_DACL_PRESENT;
394 lpsd->Control |= SE_DACL_DEFAULTED;
396 lpsd->Control &= ~SE_DACL_DEFAULTED;
398 return STATUS_SUCCESS;
401 /******************************************************************************
402 * RtlGetSaclSecurityDescriptor [NTDLL.@]
405 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
406 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
407 OUT PBOOLEAN lpbSaclPresent,
409 OUT PBOOLEAN lpbSaclDefaulted)
411 TRACE("(%p,%p,%p,%p)\n",
412 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
414 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
415 return STATUS_UNKNOWN_REVISION ;
417 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
419 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
420 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
423 { *pSacl = pSecurityDescriptor->Sacl;
427 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
429 return STATUS_SUCCESS;
432 /**************************************************************************
433 * RtlSetSaclSecurityDescriptor [NTDLL.@]
435 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
436 PSECURITY_DESCRIPTOR lpsd,
439 BOOLEAN sacldefaulted)
441 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
442 return STATUS_UNKNOWN_REVISION;
443 if (lpsd->Control & SE_SELF_RELATIVE)
444 return STATUS_INVALID_SECURITY_DESCR;
446 lpsd->Control &= ~SE_SACL_PRESENT;
449 lpsd->Control |= SE_SACL_PRESENT;
452 lpsd->Control |= SE_SACL_DEFAULTED;
454 lpsd->Control &= ~SE_SACL_DEFAULTED;
455 return STATUS_SUCCESS;
458 /**************************************************************************
459 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
461 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
462 PSECURITY_DESCRIPTOR SecurityDescriptor,
464 PBOOLEAN OwnerDefaulted)
466 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
467 return STATUS_INVALID_PARAMETER;
469 *Owner = SecurityDescriptor->Owner;
470 if ( *Owner != NULL ) {
471 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
472 *OwnerDefaulted = TRUE;
474 *OwnerDefaulted = FALSE;
476 return STATUS_SUCCESS;
479 /**************************************************************************
480 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
482 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
483 PSECURITY_DESCRIPTOR lpsd,
485 BOOLEAN ownerdefaulted)
487 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
488 return STATUS_UNKNOWN_REVISION;
489 if (lpsd->Control & SE_SELF_RELATIVE)
490 return STATUS_INVALID_SECURITY_DESCR;
494 lpsd->Control |= SE_OWNER_DEFAULTED;
496 lpsd->Control &= ~SE_OWNER_DEFAULTED;
497 return STATUS_SUCCESS;
500 /**************************************************************************
501 * RtlSetGroupSecurityDescriptor [NTDLL.@]
503 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
504 PSECURITY_DESCRIPTOR lpsd,
506 BOOLEAN groupdefaulted)
508 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
509 return STATUS_UNKNOWN_REVISION;
510 if (lpsd->Control & SE_SELF_RELATIVE)
511 return STATUS_INVALID_SECURITY_DESCR;
515 lpsd->Control |= SE_GROUP_DEFAULTED;
517 lpsd->Control &= ~SE_GROUP_DEFAULTED;
518 return STATUS_SUCCESS;
520 /**************************************************************************
521 * RtlGetGroupSecurityDescriptor [NTDLL.@]
523 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
524 PSECURITY_DESCRIPTOR SecurityDescriptor,
526 PBOOLEAN GroupDefaulted)
528 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
529 return STATUS_INVALID_PARAMETER;
531 *Group = SecurityDescriptor->Group;
532 if ( *Group != NULL ) {
533 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
534 *GroupDefaulted = TRUE;
536 *GroupDefaulted = FALSE;
538 return STATUS_SUCCESS;
541 /**************************************************************************
542 * RtlMakeSelfRelativeSD [NTDLL.@]
544 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
545 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
546 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
547 IN OUT LPDWORD lpdwBufferLength)
549 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
550 pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
551 return STATUS_SUCCESS;
555 * access control list's
558 /**************************************************************************
559 * RtlCreateAcl [NTDLL.@]
562 * This should return NTSTATUS
564 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
566 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
568 if (rev!=ACL_REVISION)
569 return STATUS_INVALID_PARAMETER;
570 if (size<sizeof(ACL))
571 return STATUS_BUFFER_TOO_SMALL;
573 return STATUS_INVALID_PARAMETER;
575 memset(acl,'\0',sizeof(ACL));
576 acl->AclRevision = rev;
582 /**************************************************************************
583 * RtlFirstFreeAce [NTDLL.@]
584 * looks for the AceCount+1 ACE, and if it is still within the alloced
585 * ACL, return a pointer to it
587 BOOLEAN WINAPI RtlFirstFreeAce(
595 ace = (PACE_HEADER)(acl+1);
596 for (i=0;i<acl->AceCount;i++) {
597 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
599 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
601 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
607 /**************************************************************************
608 * RtlAddAce [NTDLL.@]
610 NTSTATUS WINAPI RtlAddAce(
614 PACE_HEADER acestart,
617 PACE_HEADER ace,targetace;
620 if (acl->AclRevision != ACL_REVISION)
621 return STATUS_INVALID_PARAMETER;
622 if (!RtlFirstFreeAce(acl,&targetace))
623 return STATUS_INVALID_PARAMETER;
624 nrofaces=0;ace=acestart;
625 while (((DWORD)ace-(DWORD)acestart)<acelen) {
627 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
629 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
630 return STATUS_INVALID_PARAMETER;
631 memcpy((LPBYTE)targetace,acestart,acelen);
632 acl->AceCount+=nrofaces;
633 return STATUS_SUCCESS;
636 /******************************************************************************
637 * RtlAddAccessAllowedAce [NTDLL.@]
639 BOOL WINAPI RtlAddAccessAllowedAce(
641 IN DWORD dwAceRevision,
645 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
646 pAcl, dwAceRevision, AccessMask, pSid);
650 /******************************************************************************
651 * RtlGetAce [NTDLL.@]
653 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
655 FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
663 /******************************************************************************
664 * RtlAdjustPrivilege [NTDLL.@]
666 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
668 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
672 /******************************************************************************
673 * RtlImpersonateSelf [NTDLL.@]
676 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
678 FIXME("(%08x), stub\n", ImpersonationLevel);
682 /******************************************************************************
683 * NtAccessCheck [NTDLL.@]
687 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
688 IN HANDLE ClientToken,
689 IN ACCESS_MASK DesiredAccess,
690 IN PGENERIC_MAPPING GenericMapping,
691 OUT PPRIVILEGE_SET PrivilegeSet,
692 OUT PULONG ReturnLength,
693 OUT PULONG GrantedAccess,
694 OUT PBOOLEAN AccessStatus)
696 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
697 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
698 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
699 *AccessStatus = TRUE;
700 return STATUS_SUCCESS;
703 /******************************************************************************
704 * NtSetSecurityObject [NTDLL.@]
709 IN SECURITY_INFORMATION SecurityInformation,
710 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
712 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
713 return STATUS_SUCCESS;
716 /******************************************************************************
717 * RtlGetControlSecurityDescriptor (NTDLL.@)
720 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
721 PSECURITY_DESCRIPTOR pSecurityDescriptor,
722 PSECURITY_DESCRIPTOR_CONTROL pControl,
723 LPDWORD lpdwRevision)
725 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
726 return STATUS_SUCCESS;
729 /******************************************************************************
730 * RtlConvertSidToUnicodeString (NTDLL.@)
732 * The returned SID is used to access the USER registry hive usually
734 * the native function returns something like
735 * "S-1-5-21-0000000000-000000000-0000000000-500";
737 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
738 PUNICODE_STRING String,
740 BOOLEAN AllocateString)
746 struct passwd *pwd = getpwuid( getuid() );
747 p = (pwd) ? pwd->pw_name : ".Default";
749 FIXME("(%p %p %u)\n", String, Sid, AllocateString);
751 RtlInitAnsiString(&AnsiStr, p);
752 status = RtlAnsiStringToUnicodeString(String, &AnsiStr, AllocateString);
754 TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);