Get rid of ntdll_get_process_heap and ntdll_get_process_pmts by using
[wine/wine64.git] / dlls / ntdll / sec.c
blob57bcaf3db522e9b088dd7bdf313a862c6afe1f60
1 /*
2 * Security functions
4 * Copyright 1996-1998 Marcus Meissner
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <ctype.h>
30 #include <math.h>
31 #ifdef HAVE_UNISTD_H
32 # include <unistd.h>
33 #endif
35 #include "windef.h"
36 #include "winbase.h"
37 #include "wine/exception.h"
38 #include "winnls.h"
39 #include "winerror.h"
40 #include "winreg.h"
41 #include "winternl.h"
42 #include "ntdll_misc.h"
43 #include "excpt.h"
44 #include "wine/library.h"
45 #include "wine/debug.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;
60 * SID FUNCTIONS
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,
74 PSID *pSid )
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,
82 RtlLengthRequiredSid(nSubAuthorityCount))))
83 return FALSE;
85 (*pSid)->Revision = SID_REVISION;
87 if (pIdentifierAuthority)
88 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
89 *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
91 if (nSubAuthorityCount > 0)
92 *RtlSubAuthoritySid(*pSid, 0) = nSubAuthority0;
93 if (nSubAuthorityCount > 1)
94 *RtlSubAuthoritySid(*pSid, 1) = nSubAuthority1;
95 if (nSubAuthorityCount > 2)
96 *RtlSubAuthoritySid(*pSid, 2) = nSubAuthority2;
97 if (nSubAuthorityCount > 3)
98 *RtlSubAuthoritySid(*pSid, 3) = nSubAuthority3;
99 if (nSubAuthorityCount > 4)
100 *RtlSubAuthoritySid(*pSid, 4) = nSubAuthority4;
101 if (nSubAuthorityCount > 5)
102 *RtlSubAuthoritySid(*pSid, 5) = nSubAuthority5;
103 if (nSubAuthorityCount > 6)
104 *RtlSubAuthoritySid(*pSid, 6) = nSubAuthority6;
105 if (nSubAuthorityCount > 7)
106 *RtlSubAuthoritySid(*pSid, 7) = nSubAuthority7;
108 return STATUS_SUCCESS;
110 /******************************************************************************
111 * RtlEqualSid [NTDLL.@]
113 * Determine if two SIDs are equal.
115 * PARAMS
116 * pSid1 [I] Source SID
117 * pSid2 [I] SID to compare with
119 * RETURNS
120 * TRUE, if pSid1 is equal to pSid2,
121 * FALSE otherwise.
123 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
125 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
126 return FALSE;
128 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
129 return FALSE;
131 if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
132 return FALSE;
134 return TRUE;
137 /******************************************************************************
138 * RtlEqualPrefixSid [NTDLL.@]
140 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
142 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
143 return FALSE;
145 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
146 return FALSE;
148 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
149 return FALSE;
151 return TRUE;
155 /******************************************************************************
156 * RtlFreeSid [NTDLL.@]
158 * Free the resources used by a SID.
160 * PARAMS
161 * pSid [I] SID to Free.
163 * RETURNS
164 * STATUS_SUCCESS.
166 DWORD WINAPI RtlFreeSid(PSID pSid)
168 TRACE("(%p)\n", pSid);
169 RtlFreeHeap( GetProcessHeap(), 0, pSid );
170 return STATUS_SUCCESS;
173 /**************************************************************************
174 * RtlLengthRequiredSid [NTDLL.@]
176 * Determine the amount of memory a SID will use
178 * PARAMS
179 * nrofsubauths [I] Number of Sub Authorities in the SID.
181 * RETURNS
182 * The size, in bytes, of a SID with nrofsubauths Sub Authorities.
184 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
186 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
189 /**************************************************************************
190 * RtlLengthSid [NTDLL.@]
192 * Determine the amount of memory a SID is using
194 * PARAMS
195 * pSid [I] SID to ge the size of.
197 * RETURNS
198 * The size, in bytes, of pSid.
200 DWORD WINAPI RtlLengthSid(PSID pSid)
202 TRACE("sid=%p\n",pSid);
203 if (!pSid) return 0;
204 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
207 /**************************************************************************
208 * RtlInitializeSid [NTDLL.@]
210 * Initialise a SID.
212 * PARAMS
213 * pSid [I] SID to initialise
214 * pIdentifierAuthority [I] Identifier Authority
215 * nSubAuthorityCount [I] Number of Sub Authorities
217 * RETURNS
218 * Success: TRUE. pSid is initialised withe the details given.
219 * Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
221 BOOL WINAPI RtlInitializeSid(
222 PSID pSid,
223 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
224 BYTE nSubAuthorityCount)
226 int i;
227 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
228 return FALSE;
230 pSid->Revision = SID_REVISION;
231 pSid->SubAuthorityCount = nSubAuthorityCount;
232 if (pIdentifierAuthority)
233 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
235 for (i = 0; i < nSubAuthorityCount; i++)
236 *RtlSubAuthoritySid(pSid, i) = 0;
238 return TRUE;
241 /**************************************************************************
242 * RtlSubAuthoritySid [NTDLL.@]
244 * Return the Sub Authority of a SID
246 * PARAMS
247 * pSid [I] SID to get the Sub Authority from.
248 * nSubAuthority [I] Sub Authority number.
250 * RETURNS
251 * A pointer to The Sub Authority value of pSid.
253 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
255 return &(pSid->SubAuthority[nSubAuthority]);
258 /**************************************************************************
259 * RtlIdentifierAuthoritySid [NTDLL.@]
261 * Return the Identifier Authority of a SID.
263 * PARAMS
264 * pSid [I] SID to get the Identifier Authority from.
266 * RETURNS
267 * A pointer to the Identifier Authority value of pSid.
269 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
271 return &(pSid->IdentifierAuthority);
274 /**************************************************************************
275 * RtlSubAuthorityCountSid [NTDLL.@]
277 * Get the number of Sub Authorities in a SID.
279 * PARAMS
280 * pSid [I] SID to get the count from.
282 * RETURNS
283 * A pointer to the Sub Authority count of pSid.
285 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
287 return &(pSid->SubAuthorityCount);
290 /**************************************************************************
291 * RtlCopySid [NTDLL.@]
293 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
295 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
296 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
297 return FALSE;
299 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
300 return FALSE;
302 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
303 return TRUE;
305 /******************************************************************************
306 * RtlValidSid [NTDLL.@]
308 * Determine if a SID is valid.
310 * PARAMS
311 * pSid [I] SID to check
313 * RETURNS
314 * TRUE if pSid is valid,
315 * FALSE otherwise.
317 BOOLEAN WINAPI RtlValidSid( PSID pSid )
319 BOOL ret;
320 __TRY
322 ret = TRUE;
323 if (!pSid || pSid->Revision != SID_REVISION ||
324 pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
326 ret = FALSE;
329 __EXCEPT(page_fault)
331 WARN("(%p): invalid pointer!\n", pSid);
332 return FALSE;
334 __ENDTRY
335 return ret;
340 * security descriptor functions
343 /**************************************************************************
344 * RtlCreateSecurityDescriptor [NTDLL.@]
346 * Initialise a SECURITY_DESCRIPTOR.
348 * PARAMS
349 * lpsd [O] Descriptor to initialise.
350 * rev [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
352 * RETURNS:
353 * Success: STATUS_SUCCESS.
354 * Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
356 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
357 PSECURITY_DESCRIPTOR lpsd,
358 DWORD rev)
360 if (rev!=SECURITY_DESCRIPTOR_REVISION)
361 return STATUS_UNKNOWN_REVISION;
362 memset(lpsd,'\0',sizeof(*lpsd));
363 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
364 return STATUS_SUCCESS;
366 /**************************************************************************
367 * RtlValidSecurityDescriptor [NTDLL.@]
369 * Determine if a SECURITY_DESCRIPTOR is valid.
371 * PARAMS
372 * SecurityDescriptor [I] Descriptor to check.
374 * RETURNS
375 * Success: STATUS_SUCCESS.
376 * Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
378 NTSTATUS WINAPI RtlValidSecurityDescriptor(
379 PSECURITY_DESCRIPTOR SecurityDescriptor)
381 if ( ! SecurityDescriptor )
382 return STATUS_INVALID_SECURITY_DESCR;
383 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
384 return STATUS_UNKNOWN_REVISION;
386 return STATUS_SUCCESS;
389 /**************************************************************************
390 * RtlLengthSecurityDescriptor [NTDLL.@]
392 ULONG WINAPI RtlLengthSecurityDescriptor(
393 PSECURITY_DESCRIPTOR SecurityDescriptor)
395 ULONG offset = 0;
396 ULONG Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
398 if ( SecurityDescriptor == NULL )
399 return 0;
401 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
402 offset = (ULONG) SecurityDescriptor;
404 if ( SecurityDescriptor->Owner != NULL )
405 Size += RtlLengthSid((PSID)((LPBYTE)SecurityDescriptor->Owner + offset));
407 if ( SecurityDescriptor->Group != NULL )
408 Size += RtlLengthSid((PSID)((LPBYTE)SecurityDescriptor->Group + offset));
410 if ( SecurityDescriptor->Sacl != NULL )
411 Size += ((PACL)((LPBYTE)SecurityDescriptor->Sacl + offset))->AclSize;
413 if ( SecurityDescriptor->Dacl != NULL )
414 Size += ((PACL)((LPBYTE)SecurityDescriptor->Dacl + offset))->AclSize;
416 return Size;
419 /******************************************************************************
420 * RtlGetDaclSecurityDescriptor [NTDLL.@]
423 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
424 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
425 OUT PBOOLEAN lpbDaclPresent,
426 OUT PACL *pDacl,
427 OUT PBOOLEAN lpbDaclDefaulted)
429 TRACE("(%p,%p,%p,%p)\n",
430 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
432 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
433 return STATUS_UNKNOWN_REVISION ;
435 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
437 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
438 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
440 else
441 { *pDacl = pSecurityDescriptor->Dacl;
445 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
447 return STATUS_SUCCESS;
450 /**************************************************************************
451 * RtlSetDaclSecurityDescriptor [NTDLL.@]
453 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
454 PSECURITY_DESCRIPTOR lpsd,
455 BOOLEAN daclpresent,
456 PACL dacl,
457 BOOLEAN dacldefaulted )
459 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
460 return STATUS_UNKNOWN_REVISION;
461 if (lpsd->Control & SE_SELF_RELATIVE)
462 return STATUS_INVALID_SECURITY_DESCR;
464 if (!daclpresent)
465 { lpsd->Control &= ~SE_DACL_PRESENT;
466 return TRUE;
469 lpsd->Control |= SE_DACL_PRESENT;
470 lpsd->Dacl = dacl;
472 if (dacldefaulted)
473 lpsd->Control |= SE_DACL_DEFAULTED;
474 else
475 lpsd->Control &= ~SE_DACL_DEFAULTED;
477 return STATUS_SUCCESS;
480 /******************************************************************************
481 * RtlGetSaclSecurityDescriptor [NTDLL.@]
484 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
485 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
486 OUT PBOOLEAN lpbSaclPresent,
487 OUT PACL *pSacl,
488 OUT PBOOLEAN lpbSaclDefaulted)
490 TRACE("(%p,%p,%p,%p)\n",
491 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
493 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
494 return STATUS_UNKNOWN_REVISION ;
496 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
498 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
499 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
501 else
502 { *pSacl = pSecurityDescriptor->Sacl;
506 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
508 return STATUS_SUCCESS;
511 /**************************************************************************
512 * RtlSetSaclSecurityDescriptor [NTDLL.@]
514 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
515 PSECURITY_DESCRIPTOR lpsd,
516 BOOLEAN saclpresent,
517 PACL sacl,
518 BOOLEAN sacldefaulted)
520 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
521 return STATUS_UNKNOWN_REVISION;
522 if (lpsd->Control & SE_SELF_RELATIVE)
523 return STATUS_INVALID_SECURITY_DESCR;
524 if (!saclpresent) {
525 lpsd->Control &= ~SE_SACL_PRESENT;
526 return 0;
528 lpsd->Control |= SE_SACL_PRESENT;
529 lpsd->Sacl = sacl;
530 if (sacldefaulted)
531 lpsd->Control |= SE_SACL_DEFAULTED;
532 else
533 lpsd->Control &= ~SE_SACL_DEFAULTED;
534 return STATUS_SUCCESS;
537 /**************************************************************************
538 * RtlGetOwnerSecurityDescriptor [NTDLL.@]
540 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
541 PSECURITY_DESCRIPTOR SecurityDescriptor,
542 PSID *Owner,
543 PBOOLEAN OwnerDefaulted)
545 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
546 return STATUS_INVALID_PARAMETER;
548 if (SecurityDescriptor->Owner != NULL)
550 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
551 *Owner = (PSID)((LPBYTE)SecurityDescriptor +
552 (ULONG)SecurityDescriptor->Owner);
553 else
554 *Owner = SecurityDescriptor->Owner;
556 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
557 *OwnerDefaulted = TRUE;
558 else
559 *OwnerDefaulted = FALSE;
561 else
562 *Owner = NULL;
564 return STATUS_SUCCESS;
567 /**************************************************************************
568 * RtlSetOwnerSecurityDescriptor [NTDLL.@]
570 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
571 PSECURITY_DESCRIPTOR lpsd,
572 PSID owner,
573 BOOLEAN ownerdefaulted)
575 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
576 return STATUS_UNKNOWN_REVISION;
577 if (lpsd->Control & SE_SELF_RELATIVE)
578 return STATUS_INVALID_SECURITY_DESCR;
580 lpsd->Owner = owner;
581 if (ownerdefaulted)
582 lpsd->Control |= SE_OWNER_DEFAULTED;
583 else
584 lpsd->Control &= ~SE_OWNER_DEFAULTED;
585 return STATUS_SUCCESS;
588 /**************************************************************************
589 * RtlSetGroupSecurityDescriptor [NTDLL.@]
591 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
592 PSECURITY_DESCRIPTOR lpsd,
593 PSID group,
594 BOOLEAN groupdefaulted)
596 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
597 return STATUS_UNKNOWN_REVISION;
598 if (lpsd->Control & SE_SELF_RELATIVE)
599 return STATUS_INVALID_SECURITY_DESCR;
601 lpsd->Group = group;
602 if (groupdefaulted)
603 lpsd->Control |= SE_GROUP_DEFAULTED;
604 else
605 lpsd->Control &= ~SE_GROUP_DEFAULTED;
606 return STATUS_SUCCESS;
608 /**************************************************************************
609 * RtlGetGroupSecurityDescriptor [NTDLL.@]
611 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
612 PSECURITY_DESCRIPTOR SecurityDescriptor,
613 PSID *Group,
614 PBOOLEAN GroupDefaulted)
616 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
617 return STATUS_INVALID_PARAMETER;
619 if (SecurityDescriptor->Group != NULL)
621 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
622 *Group = (PSID)((LPBYTE)SecurityDescriptor +
623 (ULONG)SecurityDescriptor->Group);
624 else
625 *Group = SecurityDescriptor->Group;
627 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
628 *GroupDefaulted = TRUE;
629 else
630 *GroupDefaulted = FALSE;
632 else
633 *Group = NULL;
635 return STATUS_SUCCESS;
638 /**************************************************************************
639 * RtlMakeSelfRelativeSD [NTDLL.@]
641 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
642 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
643 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
644 IN OUT LPDWORD lpdwBufferLength)
646 ULONG offsetRel;
647 ULONG length;
648 PSECURITY_DESCRIPTOR pAbs = pAbsoluteSecurityDescriptor;
649 PSECURITY_DESCRIPTOR pRel = pSelfRelativeSecurityDescriptor;
651 TRACE(" %p %p %p(%ld)\n", pAbs, pRel, lpdwBufferLength,
652 lpdwBufferLength ? *lpdwBufferLength: -1);
654 if (!lpdwBufferLength || !pAbs)
655 return STATUS_INVALID_PARAMETER;
657 length = RtlLengthSecurityDescriptor(pAbs);
658 if (*lpdwBufferLength < length)
660 *lpdwBufferLength = length;
661 return STATUS_BUFFER_TOO_SMALL;
664 if (!pRel)
665 return STATUS_INVALID_PARAMETER;
667 if (pAbs->Control & SE_SELF_RELATIVE)
669 memcpy(pRel, pAbs, length);
670 return STATUS_SUCCESS;
673 pRel->Revision = pAbs->Revision;
674 pRel->Sbz1 = pAbs->Sbz1;
675 pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
677 offsetRel = sizeof(SECURITY_DESCRIPTOR);
678 pRel->Owner = (PSID) offsetRel;
679 length = RtlLengthSid(pAbs->Owner);
680 memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
682 offsetRel += length;
683 pRel->Group = (PSID) offsetRel;
684 length = RtlLengthSid(pAbs->Group);
685 memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
687 if (pRel->Control & SE_SACL_PRESENT)
689 offsetRel += length;
690 pRel->Sacl = (PACL) offsetRel;
691 length = pAbs->Sacl->AclSize;
692 memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
694 else
696 pRel->Sacl = NULL;
699 if (pRel->Control & SE_DACL_PRESENT)
701 offsetRel += length;
702 pRel->Dacl = (PACL) offsetRel;
703 length = pAbs->Dacl->AclSize;
704 memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
706 else
708 pRel->Dacl = NULL;
711 return STATUS_SUCCESS;
715 /**************************************************************************
716 + * RtlSelfRelativeToAbsoluteSD [NTDLL.@]
717 + */
718 NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(
719 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
720 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
721 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
722 OUT PACL pDacl,
723 OUT LPDWORD lpdwDaclSize,
724 OUT PACL pSacl,
725 OUT LPDWORD lpdwSaclSize,
726 OUT PSID pOwner,
727 OUT LPDWORD lpdwOwnerSize,
728 OUT PSID pPrimaryGroup,
729 OUT LPDWORD lpdwPrimaryGroupSize)
731 NTSTATUS status = STATUS_SUCCESS;
732 PSECURITY_DESCRIPTOR pAbs = pAbsoluteSecurityDescriptor;
733 PSECURITY_DESCRIPTOR pRel = pSelfRelativeSecurityDescriptor;
735 if (!pRel ||
736 !lpdwAbsoluteSecurityDescriptorSize ||
737 !lpdwDaclSize ||
738 !lpdwSaclSize ||
739 !lpdwOwnerSize ||
740 !lpdwPrimaryGroupSize ||
741 ~pRel->Control & SE_SELF_RELATIVE)
742 return STATUS_INVALID_PARAMETER;
744 /* Confirm buffers are sufficiently large */
745 if (*lpdwAbsoluteSecurityDescriptorSize < sizeof(SECURITY_DESCRIPTOR))
747 *lpdwAbsoluteSecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR);
748 status = STATUS_BUFFER_TOO_SMALL;
751 if (pRel->Control & SE_DACL_PRESENT &&
752 *lpdwDaclSize < ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize)
754 *lpdwDaclSize = ((PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel))->AclSize;
755 status = STATUS_BUFFER_TOO_SMALL;
758 if (pRel->Control & SE_SACL_PRESENT &&
759 *lpdwSaclSize < ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize)
761 *lpdwSaclSize = ((PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel))->AclSize;
762 status = STATUS_BUFFER_TOO_SMALL;
765 if (pRel->Owner &&
766 *lpdwOwnerSize < RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel)))
768 *lpdwOwnerSize = RtlLengthSid((PSID)((LPBYTE)pRel->Owner + (ULONG)pRel));
769 status = STATUS_BUFFER_TOO_SMALL;
772 if (pRel->Group &&
773 *lpdwPrimaryGroupSize < RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel)))
775 *lpdwPrimaryGroupSize = RtlLengthSid((PSID)((LPBYTE)pRel->Group + (ULONG)pRel));
776 status = STATUS_BUFFER_TOO_SMALL;
779 if (status != STATUS_SUCCESS)
780 return status;
782 /* Copy structures */
783 pAbs->Revision = pRel->Revision;
784 pAbs->Control = pRel->Control & ~SE_SELF_RELATIVE;
786 if (pRel->Control & SE_SACL_PRESENT)
788 PACL pAcl = (PACL)((LPBYTE)pRel->Sacl + (ULONG)pRel);
790 memcpy(pSacl, pAcl, pAcl->AclSize);
791 pAbs->Sacl = pSacl;
794 if (pRel->Control & SE_DACL_PRESENT)
796 PACL pAcl = (PACL)((LPBYTE)pRel->Dacl + (ULONG)pRel);
797 memcpy(pDacl, pAcl, pAcl->AclSize);
798 pAbs->Dacl = pDacl;
801 if (pRel->Owner)
803 PSID psid = (PSID)((LPBYTE)pRel->Owner + (ULONG)pRel);
804 memcpy(pOwner, psid, RtlLengthSid(psid));
805 pAbs->Owner = pOwner;
808 if (pRel->Group)
810 PSID psid = (PSID)((LPBYTE)pRel->Group + (ULONG)pRel);
811 memcpy(pPrimaryGroup, psid, RtlLengthSid(psid));
812 pAbs->Group = pPrimaryGroup;
815 return status;
819 * access control list's
822 /**************************************************************************
823 * RtlCreateAcl [NTDLL.@]
825 * NOTES
826 * This should return NTSTATUS
828 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
830 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
832 if (rev!=ACL_REVISION)
833 return STATUS_INVALID_PARAMETER;
834 if (size<sizeof(ACL))
835 return STATUS_BUFFER_TOO_SMALL;
836 if (size>0xFFFF)
837 return STATUS_INVALID_PARAMETER;
839 memset(acl,'\0',sizeof(ACL));
840 acl->AclRevision = rev;
841 acl->AclSize = size;
842 acl->AceCount = 0;
843 return STATUS_SUCCESS;
846 /**************************************************************************
847 * RtlFirstFreeAce [NTDLL.@]
848 * looks for the AceCount+1 ACE, and if it is still within the alloced
849 * ACL, return a pointer to it
851 BOOLEAN WINAPI RtlFirstFreeAce(
852 PACL acl,
853 PACE_HEADER *x)
855 PACE_HEADER ace;
856 int i;
858 *x = 0;
859 ace = (PACE_HEADER)(acl+1);
860 for (i=0;i<acl->AceCount;i++) {
861 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
862 return 0;
863 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
865 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
866 return 0;
867 *x = ace;
868 return 1;
871 /**************************************************************************
872 * RtlAddAce [NTDLL.@]
874 NTSTATUS WINAPI RtlAddAce(
875 PACL acl,
876 DWORD rev,
877 DWORD xnrofaces,
878 PACE_HEADER acestart,
879 DWORD acelen)
881 PACE_HEADER ace,targetace;
882 int nrofaces;
884 if (acl->AclRevision != ACL_REVISION)
885 return STATUS_INVALID_PARAMETER;
886 if (!RtlFirstFreeAce(acl,&targetace))
887 return STATUS_INVALID_PARAMETER;
888 nrofaces=0;ace=acestart;
889 while (((DWORD)ace-(DWORD)acestart)<acelen) {
890 nrofaces++;
891 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
893 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
894 return STATUS_INVALID_PARAMETER;
895 memcpy((LPBYTE)targetace,acestart,acelen);
896 acl->AceCount+=nrofaces;
897 return STATUS_SUCCESS;
900 /**************************************************************************
901 * RtlDeleteAce [NTDLL.@]
903 NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
905 NTSTATUS status;
906 PACE_HEADER pAce;
908 status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
910 if (STATUS_SUCCESS == status)
912 PACE_HEADER pcAce;
913 DWORD len = 0;
915 pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
916 for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
918 len += pcAce->AceSize;
919 pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
922 memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
923 pAcl->AceCount--;
926 return status;
929 /******************************************************************************
930 * RtlAddAccessAllowedAce [NTDLL.@]
932 NTSTATUS WINAPI RtlAddAccessAllowedAce(
933 IN OUT PACL pAcl,
934 IN DWORD dwAceRevision,
935 IN DWORD AccessMask,
936 IN PSID pSid)
938 return RtlAddAccessAllowedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
941 /******************************************************************************
942 * RtlAddAccessAllowedAceEx [NTDLL.@]
944 NTSTATUS WINAPI RtlAddAccessAllowedAceEx(
945 IN OUT PACL pAcl,
946 IN DWORD dwAceRevision,
947 IN DWORD AceFlags,
948 IN DWORD AccessMask,
949 IN PSID pSid)
951 DWORD dwLengthSid;
952 ACCESS_ALLOWED_ACE * pAaAce;
953 DWORD dwSpaceLeft;
955 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
956 pAcl, dwAceRevision, AccessMask, pSid);
958 if (!RtlValidSid(pSid))
959 return STATUS_INVALID_SID;
960 if (!RtlValidAcl(pAcl))
961 return STATUS_INVALID_ACL;
963 dwLengthSid = RtlLengthSid(pSid);
964 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAaAce))
965 return STATUS_INVALID_ACL;
967 if (!pAaAce)
968 return STATUS_ALLOTTED_SPACE_EXCEEDED;
970 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAaAce;
971 if (dwSpaceLeft < sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid)
972 return STATUS_ALLOTTED_SPACE_EXCEEDED;
974 pAaAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
975 pAaAce->Header.AceFlags = AceFlags;
976 pAaAce->Header.AceSize = sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid;
977 pAaAce->Mask = AccessMask;
978 pAcl->AceCount++;
979 RtlCopySid(dwLengthSid, (PSID)&pAaAce->SidStart, pSid);
980 return STATUS_SUCCESS;
983 /******************************************************************************
984 * RtlAddAccessDeniedAce [NTDLL.@]
986 NTSTATUS WINAPI RtlAddAccessDeniedAce(
987 IN OUT PACL pAcl,
988 IN DWORD dwAceRevision,
989 IN DWORD AccessMask,
990 IN PSID pSid)
992 return RtlAddAccessDeniedAceEx( pAcl, dwAceRevision, 0, AccessMask, pSid);
995 /******************************************************************************
996 * RtlAddAccessDeniedAceEx [NTDLL.@]
998 NTSTATUS WINAPI RtlAddAccessDeniedAceEx(
999 IN OUT PACL pAcl,
1000 IN DWORD dwAceRevision,
1001 IN DWORD AceFlags,
1002 IN DWORD AccessMask,
1003 IN PSID pSid)
1005 DWORD dwLengthSid;
1006 DWORD dwSpaceLeft;
1007 ACCESS_DENIED_ACE * pAdAce;
1009 TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
1010 pAcl, dwAceRevision, AccessMask, pSid);
1012 if (!RtlValidSid(pSid))
1013 return STATUS_INVALID_SID;
1014 if (!RtlValidAcl(pAcl))
1015 return STATUS_INVALID_ACL;
1017 dwLengthSid = RtlLengthSid(pSid);
1018 if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAdAce))
1019 return STATUS_INVALID_ACL;
1021 if (!pAdAce)
1022 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1024 dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAdAce;
1025 if (dwSpaceLeft < sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid)
1026 return STATUS_ALLOTTED_SPACE_EXCEEDED;
1028 pAdAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
1029 pAdAce->Header.AceFlags = AceFlags;
1030 pAdAce->Header.AceSize = sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid;
1031 pAdAce->Mask = AccessMask;
1032 pAcl->AceCount++;
1033 RtlCopySid(dwLengthSid, (PSID)&pAdAce->SidStart, pSid);
1034 return STATUS_SUCCESS;
1037 /******************************************************************************
1038 * RtlValidAcl [NTDLL.@]
1040 BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
1042 BOOLEAN ret;
1043 TRACE("(%p)\n", pAcl);
1045 __TRY
1047 PACE_HEADER ace;
1048 int i;
1050 if (pAcl->AclRevision != ACL_REVISION)
1051 ret = FALSE;
1052 else
1054 ace = (PACE_HEADER)(pAcl+1);
1055 ret = TRUE;
1056 for (i=0;i<=pAcl->AceCount;i++)
1058 if ((char *)ace > (char *)pAcl + pAcl->AclSize)
1060 ret = FALSE;
1061 break;
1063 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1067 __EXCEPT(page_fault)
1069 WARN("(%p): invalid pointer!\n", pAcl);
1070 return 0;
1072 __ENDTRY
1073 return ret;
1076 /******************************************************************************
1077 * RtlGetAce [NTDLL.@]
1079 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1081 PACE_HEADER ace;
1083 TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
1085 if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
1086 return STATUS_INVALID_PARAMETER;
1088 ace = (PACE_HEADER)(pAcl + 1);
1089 for (;dwAceIndex;dwAceIndex--)
1090 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1092 *pAce = (LPVOID) ace;
1094 return STATUS_SUCCESS;
1098 * misc
1101 /******************************************************************************
1102 * RtlAdjustPrivilege [NTDLL.@]
1104 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
1106 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
1107 return 0;
1110 /******************************************************************************
1111 * RtlImpersonateSelf [NTDLL.@]
1113 BOOL WINAPI
1114 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1116 FIXME("(%08x), stub\n", ImpersonationLevel);
1117 return TRUE;
1120 /******************************************************************************
1121 * NtAccessCheck [NTDLL.@]
1122 * ZwAccessCheck [NTDLL.@]
1124 NTSTATUS WINAPI
1125 NtAccessCheck(
1126 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
1127 IN HANDLE ClientToken,
1128 IN ACCESS_MASK DesiredAccess,
1129 IN PGENERIC_MAPPING GenericMapping,
1130 OUT PPRIVILEGE_SET PrivilegeSet,
1131 OUT PULONG ReturnLength,
1132 OUT PULONG GrantedAccess,
1133 OUT PBOOLEAN AccessStatus)
1135 FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
1136 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
1137 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
1138 *AccessStatus = TRUE;
1139 return STATUS_SUCCESS;
1142 /******************************************************************************
1143 * NtSetSecurityObject [NTDLL.@]
1145 NTSTATUS WINAPI
1146 NtSetSecurityObject(
1147 IN HANDLE Handle,
1148 IN SECURITY_INFORMATION SecurityInformation,
1149 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
1151 FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
1152 return STATUS_SUCCESS;
1155 /******************************************************************************
1156 * RtlGetControlSecurityDescriptor (NTDLL.@)
1159 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
1160 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1161 PSECURITY_DESCRIPTOR_CONTROL pControl,
1162 LPDWORD lpdwRevision)
1164 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
1165 return STATUS_SUCCESS;
1168 /******************************************************************************
1169 * RtlConvertSidToUnicodeString (NTDLL.@)
1171 * The returned SID is used to access the USER registry hive usually
1173 * the native function returns something like
1174 * "S-1-5-21-0000000000-000000000-0000000000-500";
1176 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
1177 PUNICODE_STRING String,
1178 PSID Sid,
1179 BOOLEAN AllocateString)
1181 const char *p = wine_get_user_name();
1182 NTSTATUS status;
1183 ANSI_STRING AnsiStr;
1185 FIXME("(%p %p %u)\n", String, Sid, AllocateString);
1187 RtlInitAnsiString(&AnsiStr, p);
1188 status = RtlAnsiStringToUnicodeString(String, &AnsiStr, AllocateString);
1190 TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);
1191 return status;
1194 /******************************************************************************
1195 * RtlQueryInformationAcl (NTDLL.@)
1197 NTSTATUS WINAPI RtlQueryInformationAcl(
1198 PACL pAcl,
1199 LPVOID pAclInformation,
1200 DWORD nAclInformationLength,
1201 ACL_INFORMATION_CLASS dwAclInformationClass)
1203 NTSTATUS status = STATUS_SUCCESS;
1205 TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
1206 pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
1208 switch (dwAclInformationClass)
1210 case AclRevisionInformation:
1212 PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
1214 if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
1215 status = STATUS_INVALID_PARAMETER;
1216 else
1217 paclrev->AclRevision = pAcl->AclRevision;
1219 break;
1222 case AclSizeInformation:
1224 PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
1226 if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
1227 status = STATUS_INVALID_PARAMETER;
1228 else
1230 INT i;
1231 PACE_HEADER ace;
1233 paclsize->AceCount = pAcl->AceCount;
1235 paclsize->AclBytesInUse = 0;
1236 ace = (PACE_HEADER) (pAcl + 1);
1238 for (i = 0; i < pAcl->AceCount; i++)
1240 paclsize->AclBytesInUse += ace->AceSize;
1241 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
1244 if (pAcl->AclSize < paclsize->AclBytesInUse)
1246 WARN("Acl has %ld bytes free\n", pAcl->AclSize - paclsize->AclBytesInUse);
1247 paclsize->AclBytesFree = 0;
1248 paclsize->AclBytesInUse = pAcl->AclSize;
1250 else
1251 paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
1254 break;
1257 default:
1258 WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
1259 status = STATUS_INVALID_PARAMETER;
1262 return status;