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
28 #include "wine/exception.h"
31 #include "wine/debug.h"
33 #include "stackframe.h"
37 #include "ntdll_misc.h"
38 #include "msvcrt/excpt.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
42 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
44 /* filter for page-fault exceptions */
45 static WINE_EXCEPTION_FILTER(page_fault)
47 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
48 return EXCEPTION_EXECUTE_HANDLER;
49 return EXCEPTION_CONTINUE_SEARCH;
56 /******************************************************************************
57 * RtlAllocateAndInitializeSid [NTDLL.@]
60 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
61 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
62 BYTE nSubAuthorityCount,
63 DWORD nSubAuthority0, DWORD nSubAuthority1,
64 DWORD nSubAuthority2, DWORD nSubAuthority3,
65 DWORD nSubAuthority4, DWORD nSubAuthority5,
66 DWORD nSubAuthority6, DWORD nSubAuthority7,
69 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
70 pIdentifierAuthority,nSubAuthorityCount,
71 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
72 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
74 if (!(*pSid = RtlAllocateHeap( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
77 (*pSid)->Revision = SID_REVISION;
79 if (pIdentifierAuthority)
80 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
81 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
83 if (nSubAuthorityCount > 0)
84 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
85 if (nSubAuthorityCount > 1)
86 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
87 if (nSubAuthorityCount > 2)
88 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
89 if (nSubAuthorityCount > 3)
90 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
91 if (nSubAuthorityCount > 4)
92 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
93 if (nSubAuthorityCount > 5)
94 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
95 if (nSubAuthorityCount > 6)
96 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
97 if (nSubAuthorityCount > 7)
98 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
100 return STATUS_SUCCESS;
102 /******************************************************************************
103 * RtlEqualSid [NTDLL.@]
106 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
108 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
111 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
114 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
120 /******************************************************************************
121 * RtlEqualPrefixSid [NTDLL.@]
123 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
125 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
128 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
131 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
138 /******************************************************************************
139 * RtlFreeSid [NTDLL.@]
141 DWORD WINAPI RtlFreeSid(PSID pSid)
143 TRACE("(%p)\n", pSid);
144 RtlFreeHeap( GetProcessHeap(), 0, pSid );
145 return STATUS_SUCCESS;
148 /**************************************************************************
149 * RtlLengthRequiredSid [NTDLL.@]
152 * nSubAuthorityCount []
154 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
156 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
159 /**************************************************************************
160 * RtlLengthSid [NTDLL.@]
162 DWORD WINAPI RtlLengthSid(PSID pSid)
164 TRACE("sid=%p\n",pSid);
166 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
169 /**************************************************************************
170 * RtlInitializeSid [NTDLL.@]
172 BOOL WINAPI RtlInitializeSid(
174 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
175 BYTE nSubAuthorityCount)
178 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
181 pSid->Revision = SID_REVISION;
182 pSid->SubAuthorityCount = nSubAuthorityCount;
183 if (pIdentifierAuthority)
184 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
186 for (i = 0; i < nSubAuthorityCount; i++)
187 *RtlSubAuthoritySid(pSid, i) = 0;
192 /**************************************************************************
193 * RtlSubAuthoritySid [NTDLL.@]
199 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
201 return &(pSid->SubAuthority[nSubAuthority]);
204 /**************************************************************************
205 * RtlIdentifierAuthoritySid [NTDLL.@]
210 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
212 return &(pSid->IdentifierAuthority);
215 /**************************************************************************
216 * RtlSubAuthorityCountSid [NTDLL.@]
222 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
224 return &(pSid->SubAuthorityCount);
227 /**************************************************************************
228 * RtlCopySid [NTDLL.@]
230 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
232 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
233 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
236 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
239 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
242 /******************************************************************************
243 * RtlValidSid [NTDLL.@]
249 RtlValidSid( PSID pSid )
255 if (!pSid || pSid->Revision != SID_REVISION ||
256 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
263 WARN("(%p): invalid pointer!\n", pSid);
272 * security descriptor functions
275 /**************************************************************************
276 * RtlCreateSecurityDescriptor [NTDLL.@]
280 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
283 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
284 PSECURITY_DESCRIPTOR lpsd,
287 if (rev!=SECURITY_DESCRIPTOR_REVISION)
288 return STATUS_UNKNOWN_REVISION;
289 memset(lpsd,'\0',sizeof(*lpsd));
290 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
291 return STATUS_SUCCESS;
293 /**************************************************************************
294 * RtlValidSecurityDescriptor [NTDLL.@]
297 NTSTATUS WINAPI RtlValidSecurityDescriptor(
298 PSECURITY_DESCRIPTOR SecurityDescriptor)
300 if ( ! SecurityDescriptor )
301 return STATUS_INVALID_SECURITY_DESCR;
302 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
303 return STATUS_UNKNOWN_REVISION;
305 return STATUS_SUCCESS;
308 /**************************************************************************
309 * RtlLengthSecurityDescriptor [NTDLL.@]
311 ULONG WINAPI RtlLengthSecurityDescriptor(
312 PSECURITY_DESCRIPTOR SecurityDescriptor)
315 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
316 if ( SecurityDescriptor == NULL )
319 if ( SecurityDescriptor->Owner != NULL )
320 Size += SecurityDescriptor->Owner->SubAuthorityCount;
321 if ( SecurityDescriptor->Group != NULL )
322 Size += SecurityDescriptor->Group->SubAuthorityCount;
325 if ( SecurityDescriptor->Sacl != NULL )
326 Size += SecurityDescriptor->Sacl->AclSize;
327 if ( SecurityDescriptor->Dacl != NULL )
328 Size += SecurityDescriptor->Dacl->AclSize;
333 /******************************************************************************
334 * RtlGetDaclSecurityDescriptor [NTDLL.@]
337 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
338 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
339 OUT PBOOLEAN lpbDaclPresent,
341 OUT PBOOLEAN lpbDaclDefaulted)
343 TRACE("(%p,%p,%p,%p)\n",
344 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
346 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
347 return STATUS_UNKNOWN_REVISION ;
349 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
351 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
352 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
355 { *pDacl = pSecurityDescriptor->Dacl;
359 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
361 return STATUS_SUCCESS;
364 /**************************************************************************
365 * RtlSetDaclSecurityDescriptor [NTDLL.@]
367 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
368 PSECURITY_DESCRIPTOR lpsd,
371 BOOLEAN dacldefaulted )
373 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
374 return STATUS_UNKNOWN_REVISION;
375 if (lpsd->Control & SE_SELF_RELATIVE)
376 return STATUS_INVALID_SECURITY_DESCR;
379 { lpsd->Control &= ~SE_DACL_PRESENT;
383 lpsd->Control |= SE_DACL_PRESENT;
387 lpsd->Control |= SE_DACL_DEFAULTED;
389 lpsd->Control &= ~SE_DACL_DEFAULTED;
391 return STATUS_SUCCESS;
394 /******************************************************************************
395 * RtlGetSaclSecurityDescriptor [NTDLL.@]
398 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
399 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
400 OUT PBOOLEAN lpbSaclPresent,
402 OUT PBOOLEAN lpbSaclDefaulted)
404 TRACE("(%p,%p,%p,%p)\n",
405 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
407 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
408 return STATUS_UNKNOWN_REVISION ;
410 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
412 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
413 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
416 { *pSacl = pSecurityDescriptor->Sacl;
420 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
422 return STATUS_SUCCESS;
425 /**************************************************************************
426 * RtlSetSaclSecurityDescriptor [NTDLL.@]
428 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
429 PSECURITY_DESCRIPTOR lpsd,
432 BOOLEAN sacldefaulted)
434 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
435 return STATUS_UNKNOWN_REVISION;
436 if (lpsd->Control & SE_SELF_RELATIVE)
437 return STATUS_INVALID_SECURITY_DESCR;
439 lpsd->Control &= ~SE_SACL_PRESENT;
442 lpsd->Control |= SE_SACL_PRESENT;
445 lpsd->Control |= SE_SACL_DEFAULTED;
447 lpsd->Control &= ~SE_SACL_DEFAULTED;
448 return STATUS_SUCCESS;
451 /**************************************************************************
452 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
454 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
455 PSECURITY_DESCRIPTOR SecurityDescriptor,
457 PBOOLEAN OwnerDefaulted)
459 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
460 return STATUS_INVALID_PARAMETER;
462 *Owner = SecurityDescriptor->Owner;
463 if ( *Owner != NULL ) {
464 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
465 *OwnerDefaulted = TRUE;
467 *OwnerDefaulted = FALSE;
469 return STATUS_SUCCESS;
472 /**************************************************************************
473 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
475 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
476 PSECURITY_DESCRIPTOR lpsd,
478 BOOLEAN ownerdefaulted)
480 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
481 return STATUS_UNKNOWN_REVISION;
482 if (lpsd->Control & SE_SELF_RELATIVE)
483 return STATUS_INVALID_SECURITY_DESCR;
487 lpsd->Control |= SE_OWNER_DEFAULTED;
489 lpsd->Control &= ~SE_OWNER_DEFAULTED;
490 return STATUS_SUCCESS;
493 /**************************************************************************
494 * RtlSetGroupSecurityDescriptor [NTDLL.@]
496 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
497 PSECURITY_DESCRIPTOR lpsd,
499 BOOLEAN groupdefaulted)
501 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
502 return STATUS_UNKNOWN_REVISION;
503 if (lpsd->Control & SE_SELF_RELATIVE)
504 return STATUS_INVALID_SECURITY_DESCR;
508 lpsd->Control |= SE_GROUP_DEFAULTED;
510 lpsd->Control &= ~SE_GROUP_DEFAULTED;
511 return STATUS_SUCCESS;
513 /**************************************************************************
514 * RtlGetGroupSecurityDescriptor [NTDLL.@]
516 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
517 PSECURITY_DESCRIPTOR SecurityDescriptor,
519 PBOOLEAN GroupDefaulted)
521 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
522 return STATUS_INVALID_PARAMETER;
524 *Group = SecurityDescriptor->Group;
525 if ( *Group != NULL ) {
526 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
527 *GroupDefaulted = TRUE;
529 *GroupDefaulted = FALSE;
531 return STATUS_SUCCESS;
534 /**************************************************************************
535 * RtlMakeSelfRelativeSD [NTDLL.@]
537 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
538 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
539 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
540 IN OUT LPDWORD lpdwBufferLength)
542 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
543 pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
544 return STATUS_SUCCESS;
548 * access control list's
551 /**************************************************************************
552 * RtlCreateAcl [NTDLL.@]
555 * This should return NTSTATUS
557 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
559 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
561 if (rev!=ACL_REVISION)
562 return STATUS_INVALID_PARAMETER;
563 if (size<sizeof(ACL))
564 return STATUS_BUFFER_TOO_SMALL;
566 return STATUS_INVALID_PARAMETER;
568 memset(acl,'\0',sizeof(ACL));
569 acl->AclRevision = rev;
575 /**************************************************************************
576 * RtlFirstFreeAce [NTDLL.@]
577 * looks for the AceCount+1 ACE, and if it is still within the alloced
578 * ACL, return a pointer to it
580 BOOLEAN WINAPI RtlFirstFreeAce(
588 ace = (PACE_HEADER)(acl+1);
589 for (i=0;i<acl->AceCount;i++) {
590 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
592 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
594 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
600 /**************************************************************************
601 * RtlAddAce [NTDLL.@]
603 NTSTATUS WINAPI RtlAddAce(
607 PACE_HEADER acestart,
610 PACE_HEADER ace,targetace;
613 if (acl->AclRevision != ACL_REVISION)
614 return STATUS_INVALID_PARAMETER;
615 if (!RtlFirstFreeAce(acl,&targetace))
616 return STATUS_INVALID_PARAMETER;
617 nrofaces=0;ace=acestart;
618 while (((DWORD)ace-(DWORD)acestart)<acelen) {
620 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
622 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
623 return STATUS_INVALID_PARAMETER;
624 memcpy((LPBYTE)targetace,acestart,acelen);
625 acl->AceCount+=nrofaces;
626 return STATUS_SUCCESS;
629 /******************************************************************************
630 * RtlAddAccessAllowedAce [NTDLL.@]
632 BOOL WINAPI RtlAddAccessAllowedAce(
634 IN DWORD dwAceRevision,
638 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
639 pAcl, dwAceRevision, AccessMask, pSid);
643 /******************************************************************************
644 * RtlGetAce [NTDLL.@]
646 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
648 FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
656 /******************************************************************************
657 * RtlAdjustPrivilege [NTDLL.@]
659 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
661 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
665 /******************************************************************************
666 * RtlImpersonateSelf [NTDLL.@]
669 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
671 FIXME("(%08x), stub\n", ImpersonationLevel);
675 /******************************************************************************
676 * NtAccessCheck [NTDLL.@]
680 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
681 IN HANDLE ClientToken,
682 IN ACCESS_MASK DesiredAccess,
683 IN PGENERIC_MAPPING GenericMapping,
684 OUT PPRIVILEGE_SET PrivilegeSet,
685 OUT PULONG ReturnLength,
686 OUT PULONG GrantedAccess,
687 OUT PBOOLEAN AccessStatus)
689 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
690 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
691 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
692 *AccessStatus = TRUE;
693 return STATUS_SUCCESS;
696 /******************************************************************************
697 * NtSetSecurityObject [NTDLL.@]
702 IN SECURITY_INFORMATION SecurityInformation,
703 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
705 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
706 return STATUS_SUCCESS;
709 /******************************************************************************
710 * RtlGetControlSecurityDescriptor (NTDLL.@)
713 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
714 PSECURITY_DESCRIPTOR pSecurityDescriptor,
715 PSECURITY_DESCRIPTOR_CONTROL pControl,
716 LPDWORD lpdwRevision)
718 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
719 return STATUS_SUCCESS;
722 /******************************************************************************
723 * RtlConvertSidToUnicodeString (NTDLL.@)
725 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
726 PUNICODE_STRING UnicodeSID,
729 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
731 LPSTR GenSID = ".Default"; /* usually the returned SID is used to */
732 /* access "\\REGISTRY\\USER\\.DEFAULT" */
736 FIXME("(%p %p)\n", UnicodeSID, pSid);
738 TRACE("%p(<OUT>) (%u %u)\n",
739 UnicodeSID->Buffer, UnicodeSID->Length, UnicodeSID->MaximumLength);
741 RtlInitAnsiString(&AnsiStr, GenSID);
742 return RtlAnsiStringToUnicodeString(UnicodeSID, &AnsiStr, TRUE);