4 * Copyright 1996-1998 Marcus Meissner
14 #include "wine/exception.h"
18 #include "debugtools.h"
20 #include "stackframe.h"
24 #include "ntdll_misc.h"
26 DEFAULT_DEBUG_CHANNEL(ntdll);
28 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
30 /* filter for page-fault exceptions */
31 static WINE_EXCEPTION_FILTER(page_fault)
33 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
34 return EXCEPTION_EXECUTE_HANDLER;
35 return EXCEPTION_CONTINUE_SEARCH;
42 /******************************************************************************
43 * RtlAllocateAndInitializeSid [NTDLL.265]
46 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
47 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
48 BYTE nSubAuthorityCount,
49 DWORD nSubAuthority0, DWORD nSubAuthority1,
50 DWORD nSubAuthority2, DWORD nSubAuthority3,
51 DWORD nSubAuthority4, DWORD nSubAuthority5,
52 DWORD nSubAuthority6, DWORD nSubAuthority7,
55 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
56 pIdentifierAuthority,nSubAuthorityCount,
57 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
58 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
60 if (!(*pSid = HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
63 (*pSid)->Revision = SID_REVISION;
65 if (pIdentifierAuthority)
66 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
67 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
69 if (nSubAuthorityCount > 0)
70 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
71 if (nSubAuthorityCount > 1)
72 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
73 if (nSubAuthorityCount > 2)
74 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
75 if (nSubAuthorityCount > 3)
76 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
77 if (nSubAuthorityCount > 4)
78 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
79 if (nSubAuthorityCount > 5)
80 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
81 if (nSubAuthorityCount > 6)
82 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
83 if (nSubAuthorityCount > 7)
84 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
86 return STATUS_SUCCESS;
88 /******************************************************************************
89 * RtlEqualSid [NTDLL.352]
92 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
94 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
97 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
100 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
106 /******************************************************************************
107 * RtlEqualPrefixSid [ntdll.]
109 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
111 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
114 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
117 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
124 /******************************************************************************
125 * RtlFreeSid [NTDLL.376]
127 DWORD WINAPI RtlFreeSid(PSID pSid)
129 TRACE("(%p)\n", pSid);
130 HeapFree( GetProcessHeap(), 0, pSid );
131 return STATUS_SUCCESS;
134 /**************************************************************************
135 * RtlLengthRequiredSid [NTDLL.427]
138 * nSubAuthorityCount []
140 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
142 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
145 /**************************************************************************
146 * RtlLengthSid [NTDLL.429]
148 DWORD WINAPI RtlLengthSid(PSID pSid)
150 TRACE("sid=%p\n",pSid);
152 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
155 /**************************************************************************
156 * RtlInitializeSid [NTDLL.410]
158 BOOL WINAPI RtlInitializeSid(
160 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
161 BYTE nSubAuthorityCount)
164 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
167 pSid->Revision = SID_REVISION;
168 pSid->SubAuthorityCount = nSubAuthorityCount;
169 if (pIdentifierAuthority)
170 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
172 for (i = 0; i < nSubAuthorityCount; i++)
173 *RtlSubAuthoritySid(pSid, i) = 0;
178 /**************************************************************************
179 * RtlSubAuthoritySid [NTDLL.497]
185 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
187 return &(pSid->SubAuthority[nSubAuthority]);
190 /**************************************************************************
191 * RtlIdentifierAuthoritySid [NTDLL.395]
196 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
198 return &(pSid->IdentifierAuthority);
201 /**************************************************************************
202 * RtlSubAuthorityCountSid [NTDLL.496]
208 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
210 return &(pSid->SubAuthorityCount);
213 /**************************************************************************
214 * RtlCopySid [NTDLL.302]
216 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
218 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
219 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
222 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
225 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
228 /******************************************************************************
229 * RtlValidSid [NTDLL.532]
235 RtlValidSid( PSID pSid )
241 if (!pSid || pSid->Revision != SID_REVISION ||
242 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
249 WARN("(%p): invalid pointer!\n", pSid);
258 * security descriptor functions
261 /**************************************************************************
262 * RtlCreateSecurityDescriptor [NTDLL.313]
266 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
269 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
270 PSECURITY_DESCRIPTOR lpsd,
273 if (rev!=SECURITY_DESCRIPTOR_REVISION)
274 return STATUS_UNKNOWN_REVISION;
275 memset(lpsd,'\0',sizeof(*lpsd));
276 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
277 return STATUS_SUCCESS;
279 /**************************************************************************
280 * RtlValidSecurityDescriptor [NTDLL.313]
283 NTSTATUS WINAPI RtlValidSecurityDescriptor(
284 PSECURITY_DESCRIPTOR SecurityDescriptor)
286 if ( ! SecurityDescriptor )
287 return STATUS_INVALID_SECURITY_DESCR;
288 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
289 return STATUS_UNKNOWN_REVISION;
291 return STATUS_SUCCESS;
294 /**************************************************************************
295 * RtlLengthSecurityDescriptor [NTDLL]
297 ULONG WINAPI RtlLengthSecurityDescriptor(
298 PSECURITY_DESCRIPTOR SecurityDescriptor)
301 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
302 if ( SecurityDescriptor == NULL )
305 if ( SecurityDescriptor->Owner != NULL )
306 Size += SecurityDescriptor->Owner->SubAuthorityCount;
307 if ( SecurityDescriptor->Group != NULL )
308 Size += SecurityDescriptor->Group->SubAuthorityCount;
311 if ( SecurityDescriptor->Sacl != NULL )
312 Size += SecurityDescriptor->Sacl->AclSize;
313 if ( SecurityDescriptor->Dacl != NULL )
314 Size += SecurityDescriptor->Dacl->AclSize;
319 /******************************************************************************
320 * RtlGetDaclSecurityDescriptor [NTDLL]
323 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
324 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
325 OUT PBOOLEAN lpbDaclPresent,
327 OUT PBOOLEAN lpbDaclDefaulted)
329 TRACE("(%p,%p,%p,%p)\n",
330 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
332 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
333 return STATUS_UNKNOWN_REVISION ;
335 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
337 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
338 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
341 { *pDacl = pSecurityDescriptor->Dacl;
345 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
347 return STATUS_SUCCESS;
350 /**************************************************************************
351 * RtlSetDaclSecurityDescriptor [NTDLL.483]
353 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
354 PSECURITY_DESCRIPTOR lpsd,
357 BOOLEAN dacldefaulted )
359 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
360 return STATUS_UNKNOWN_REVISION;
361 if (lpsd->Control & SE_SELF_RELATIVE)
362 return STATUS_INVALID_SECURITY_DESCR;
365 { lpsd->Control &= ~SE_DACL_PRESENT;
369 lpsd->Control |= SE_DACL_PRESENT;
373 lpsd->Control |= SE_DACL_DEFAULTED;
375 lpsd->Control &= ~SE_DACL_DEFAULTED;
377 return STATUS_SUCCESS;
380 /******************************************************************************
381 * RtlGetSaclSecurityDescriptor [NTDLL]
384 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
385 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
386 OUT PBOOLEAN lpbSaclPresent,
388 OUT PBOOLEAN lpbSaclDefaulted)
390 TRACE("(%p,%p,%p,%p)\n",
391 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
393 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
394 return STATUS_UNKNOWN_REVISION ;
396 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
398 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
399 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
402 { *pSacl = pSecurityDescriptor->Sacl;
406 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
408 return STATUS_SUCCESS;
411 /**************************************************************************
412 * RtlSetSaclSecurityDescriptor [NTDLL.488]
414 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
415 PSECURITY_DESCRIPTOR lpsd,
418 BOOLEAN sacldefaulted)
420 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
421 return STATUS_UNKNOWN_REVISION;
422 if (lpsd->Control & SE_SELF_RELATIVE)
423 return STATUS_INVALID_SECURITY_DESCR;
425 lpsd->Control &= ~SE_SACL_PRESENT;
428 lpsd->Control |= SE_SACL_PRESENT;
431 lpsd->Control |= SE_SACL_DEFAULTED;
433 lpsd->Control &= ~SE_SACL_DEFAULTED;
434 return STATUS_SUCCESS;
437 /**************************************************************************
438 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
440 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
441 PSECURITY_DESCRIPTOR SecurityDescriptor,
443 PBOOLEAN OwnerDefaulted)
445 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
446 return STATUS_INVALID_PARAMETER;
448 *Owner = SecurityDescriptor->Owner;
449 if ( *Owner != NULL ) {
450 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
451 *OwnerDefaulted = TRUE;
453 *OwnerDefaulted = FALSE;
455 return STATUS_SUCCESS;
458 /**************************************************************************
459 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
461 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
462 PSECURITY_DESCRIPTOR lpsd,
464 BOOLEAN ownerdefaulted)
466 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
467 return STATUS_UNKNOWN_REVISION;
468 if (lpsd->Control & SE_SELF_RELATIVE)
469 return STATUS_INVALID_SECURITY_DESCR;
473 lpsd->Control |= SE_OWNER_DEFAULTED;
475 lpsd->Control &= ~SE_OWNER_DEFAULTED;
476 return STATUS_SUCCESS;
479 /**************************************************************************
480 * RtlSetGroupSecurityDescriptor [NTDLL.485]
482 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
483 PSECURITY_DESCRIPTOR lpsd,
485 BOOLEAN groupdefaulted)
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_GROUP_DEFAULTED;
496 lpsd->Control &= ~SE_GROUP_DEFAULTED;
497 return STATUS_SUCCESS;
499 /**************************************************************************
500 * RtlGetGroupSecurityDescriptor [NTDLL]
502 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
503 PSECURITY_DESCRIPTOR SecurityDescriptor,
505 PBOOLEAN GroupDefaulted)
507 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
508 return STATUS_INVALID_PARAMETER;
510 *Group = SecurityDescriptor->Group;
511 if ( *Group != NULL ) {
512 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
513 *GroupDefaulted = TRUE;
515 *GroupDefaulted = FALSE;
517 return STATUS_SUCCESS;
520 /**************************************************************************
521 * RtlMakeSelfRelativeSD [NTDLL]
523 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
524 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
525 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
526 IN OUT LPDWORD lpdwBufferLength)
528 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
529 pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
530 return STATUS_SUCCESS;
534 * access control list's
537 /**************************************************************************
538 * RtlCreateAcl [NTDLL.306]
541 * This should return NTSTATUS
543 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
545 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
547 if (rev!=ACL_REVISION)
548 return STATUS_INVALID_PARAMETER;
549 if (size<sizeof(ACL))
550 return STATUS_BUFFER_TOO_SMALL;
552 return STATUS_INVALID_PARAMETER;
554 memset(acl,'\0',sizeof(ACL));
555 acl->AclRevision = rev;
561 /**************************************************************************
562 * RtlFirstFreeAce [NTDLL.370]
563 * looks for the AceCount+1 ACE, and if it is still within the alloced
564 * ACL, return a pointer to it
566 BOOLEAN WINAPI RtlFirstFreeAce(
574 ace = (PACE_HEADER)(acl+1);
575 for (i=0;i<acl->AceCount;i++) {
576 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
578 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
580 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
586 /**************************************************************************
587 * RtlAddAce [NTDLL.260]
589 NTSTATUS WINAPI RtlAddAce(
593 PACE_HEADER acestart,
596 PACE_HEADER ace,targetace;
599 if (acl->AclRevision != ACL_REVISION)
600 return STATUS_INVALID_PARAMETER;
601 if (!RtlFirstFreeAce(acl,&targetace))
602 return STATUS_INVALID_PARAMETER;
603 nrofaces=0;ace=acestart;
604 while (((DWORD)ace-(DWORD)acestart)<acelen) {
606 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
608 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
609 return STATUS_INVALID_PARAMETER;
610 memcpy((LPBYTE)targetace,acestart,acelen);
611 acl->AceCount+=nrofaces;
612 return STATUS_SUCCESS;
615 /******************************************************************************
616 * RtlAddAccessAllowedAce [NTDLL]
618 BOOL WINAPI RtlAddAccessAllowedAce(
620 IN DWORD dwAceRevision,
624 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
625 pAcl, dwAceRevision, AccessMask, pSid);
629 /******************************************************************************
632 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
634 FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
642 /******************************************************************************
643 * RtlAdjustPrivilege [NTDLL]
645 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
647 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
651 /******************************************************************************
652 * RtlImpersonateSelf [NTDLL]
655 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
657 FIXME("(%08x), stub\n", ImpersonationLevel);
661 /******************************************************************************
662 * NtAccessCheck [NTDLL]
666 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
667 IN HANDLE ClientToken,
668 IN ACCESS_MASK DesiredAccess,
669 IN PGENERIC_MAPPING GenericMapping,
670 OUT PPRIVILEGE_SET PrivilegeSet,
671 OUT PULONG ReturnLength,
672 OUT PULONG GrantedAccess,
673 OUT PBOOLEAN AccessStatus)
675 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
676 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
677 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
678 *AccessStatus = TRUE;
679 return STATUS_SUCCESS;
682 /******************************************************************************
683 * NtSetSecurityObject [NTDLL]
688 IN SECURITY_INFORMATION SecurityInformation,
689 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
691 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
692 return STATUS_SUCCESS;
695 /******************************************************************************
696 * RtlGetControlSecurityDescriptor
699 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
700 PSECURITY_DESCRIPTOR pSecurityDescriptor,
701 PSECURITY_DESCRIPTOR_CONTROL pControl,
702 LPDWORD lpdwRevision)
704 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
705 return STATUS_SUCCESS;
708 /******************************************************************************
709 * RtlConvertSidToUnicodeString
711 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
712 PUNICODE_STRING UnicodeSID,
715 /* LPSTR GenSID = "S-1-5-21-0000000000-000000000-0000000000-500"; */
717 LPSTR GenSID = ".Default"; /* usually the returned SID is used to */
718 /* access "\\REGISTRY\\USER\\.DEFAULT" */
722 FIXME("(%p %p)\n", UnicodeSID, pSid);
723 dump_UnicodeString(UnicodeSID, FALSE);
725 RtlInitAnsiString(&AnsiStr, GenSID);
726 return RtlAnsiStringToUnicodeString(UnicodeSID, &AnsiStr, TRUE);