Fixed definition of the RtlMemory functions. Use macros internally and
[wine.git] / dlls / ntdll / sec.c
blobfc1dba8b9d4885a7ee361231b5589024a1efc6cf
1 /*
2 * Security functions
4 * Copyright 1996-1998 Marcus Meissner
5 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #include <ctype.h>
11 #include <math.h>
12 #include "windef.h"
13 #include "winbase.h"
14 #include "wingdi.h"
15 #include "winuser.h"
16 #include "wine/winestring.h"
17 #include "file.h"
18 #include "heap.h"
19 #include "winnls.h"
20 #include "debugtools.h"
21 #include "winerror.h"
22 #include "stackframe.h"
24 #include "ntddk.h"
25 #include "winreg.h"
27 DEFAULT_DEBUG_CHANNEL(ntdll);
29 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
32 * SID FUNCTIONS
35 /******************************************************************************
36 * RtlAllocateAndInitializeSid [NTDLL.265]
39 BOOLEAN WINAPI RtlAllocateAndInitializeSid (
40 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
41 BYTE nSubAuthorityCount,
42 DWORD nSubAuthority0, DWORD nSubAuthority1,
43 DWORD nSubAuthority2, DWORD nSubAuthority3,
44 DWORD nSubAuthority4, DWORD nSubAuthority5,
45 DWORD nSubAuthority6, DWORD nSubAuthority7,
46 PSID *pSid )
48 TRACE("(%p, 0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p)\n",
49 pIdentifierAuthority,nSubAuthorityCount,
50 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
51 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, pSid);
53 if (!(*pSid = HeapAlloc( GetProcessHeap(), 0, RtlLengthRequiredSid(nSubAuthorityCount))))
54 return FALSE;
56 (*pSid)->Revision = SID_REVISION;
58 if (pIdentifierAuthority)
59 memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
60 *GetSidSubAuthorityCount(*pSid) = nSubAuthorityCount;
62 if (nSubAuthorityCount > 0)
63 *GetSidSubAuthority(*pSid, 0) = nSubAuthority0;
64 if (nSubAuthorityCount > 1)
65 *GetSidSubAuthority(*pSid, 1) = nSubAuthority1;
66 if (nSubAuthorityCount > 2)
67 *GetSidSubAuthority(*pSid, 2) = nSubAuthority2;
68 if (nSubAuthorityCount > 3)
69 *GetSidSubAuthority(*pSid, 3) = nSubAuthority3;
70 if (nSubAuthorityCount > 4)
71 *GetSidSubAuthority(*pSid, 4) = nSubAuthority4;
72 if (nSubAuthorityCount > 5)
73 *GetSidSubAuthority(*pSid, 5) = nSubAuthority5;
74 if (nSubAuthorityCount > 6)
75 *GetSidSubAuthority(*pSid, 6) = nSubAuthority6;
76 if (nSubAuthorityCount > 7)
77 *GetSidSubAuthority(*pSid, 7) = nSubAuthority7;
79 return STATUS_SUCCESS;
81 /******************************************************************************
82 * RtlEqualSid [NTDLL.352]
85 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
87 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
88 return FALSE;
90 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
91 return FALSE;
93 if (memcmp(pSid1, pSid2, GetLengthSid(pSid1)) != 0)
94 return FALSE;
96 return TRUE;
99 /******************************************************************************
100 * RtlEqualPrefixSid [ntdll.]
102 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
104 if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
105 return FALSE;
107 if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
108 return FALSE;
110 if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
111 return FALSE;
113 return TRUE;
117 /******************************************************************************
118 * RtlFreeSid [NTDLL.376]
120 DWORD WINAPI RtlFreeSid(PSID pSid)
122 TRACE("(%p)\n", pSid);
123 HeapFree( GetProcessHeap(), 0, pSid );
124 return STATUS_SUCCESS;
127 /**************************************************************************
128 * RtlLengthRequiredSid [NTDLL.427]
130 * PARAMS
131 * nSubAuthorityCount []
133 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
135 return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
138 /**************************************************************************
139 * RtlLengthSid [NTDLL.429]
141 DWORD WINAPI RtlLengthSid(PSID pSid)
143 TRACE("sid=%p\n",pSid);
144 if (!pSid) return 0;
145 return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
148 /**************************************************************************
149 * RtlInitializeSid [NTDLL.410]
151 BOOL WINAPI RtlInitializeSid(
152 PSID pSid,
153 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
154 BYTE nSubAuthorityCount)
156 int i;
157 if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
158 return FALSE;
160 pSid->Revision = SID_REVISION;
161 pSid->SubAuthorityCount = nSubAuthorityCount;
162 if (pIdentifierAuthority)
163 memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
165 for (i = 0; i < nSubAuthorityCount; i++)
166 *GetSidSubAuthority(pSid, i) = 0;
168 return TRUE;
171 /**************************************************************************
172 * RtlSubAuthoritySid [NTDLL.497]
174 * PARAMS
175 * pSid []
176 * nSubAuthority []
178 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
180 return &(pSid->SubAuthority[nSubAuthority]);
183 /**************************************************************************
184 * RtlIdentifierAuthoritySid [NTDLL.395]
186 * PARAMS
187 * pSid []
189 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
191 return &(pSid->IdentifierAuthority);
194 /**************************************************************************
195 * RtlSubAuthorityCountSid [NTDLL.496]
197 * PARAMS
198 * pSid []
199 * nSubAuthority []
201 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
203 return &(pSid->SubAuthorityCount);
206 /**************************************************************************
207 * RtlCopySid [NTDLL.302]
209 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
211 if (!pSourceSid || !RtlValidSid(pSourceSid) ||
212 (nDestinationSidLength < RtlLengthSid(pSourceSid)))
213 return FALSE;
215 if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
216 return FALSE;
218 memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
219 return TRUE;
221 /******************************************************************************
222 * RtlValidSid [NTDLL.532]
224 * PARAMS
225 * pSid []
227 BOOL WINAPI
228 RtlValidSid( PSID pSid )
230 if (IsBadReadPtr(pSid, 4))
232 WARN("(%p): invalid pointer!\n", pSid);
233 return FALSE;
236 if (pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
237 return FALSE;
239 if (!pSid || pSid->Revision != SID_REVISION)
240 return FALSE;
242 return TRUE;
247 * security descriptor functions
250 /**************************************************************************
251 * RtlCreateSecurityDescriptor [NTDLL.313]
253 * RETURNS:
254 * 0 success,
255 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
256 * STATUS_NO_MEMORY
258 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
259 PSECURITY_DESCRIPTOR lpsd,
260 DWORD rev)
262 if (rev!=SECURITY_DESCRIPTOR_REVISION)
263 return STATUS_UNKNOWN_REVISION;
264 memset(lpsd,'\0',sizeof(*lpsd));
265 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
266 return STATUS_SUCCESS;
268 /**************************************************************************
269 * RtlValidSecurityDescriptor [NTDLL.313]
272 NTSTATUS WINAPI RtlValidSecurityDescriptor(
273 PSECURITY_DESCRIPTOR SecurityDescriptor)
275 if ( ! SecurityDescriptor )
276 return STATUS_INVALID_SECURITY_DESCR;
277 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
278 return STATUS_UNKNOWN_REVISION;
280 return STATUS_SUCCESS;
283 /**************************************************************************
284 * RtlLengthSecurityDescriptor [NTDLL]
286 ULONG WINAPI RtlLengthSecurityDescriptor(
287 PSECURITY_DESCRIPTOR SecurityDescriptor)
289 ULONG Size;
290 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
291 if ( SecurityDescriptor == NULL )
292 return 0;
294 if ( SecurityDescriptor->Owner != NULL )
295 Size += SecurityDescriptor->Owner->SubAuthorityCount;
296 if ( SecurityDescriptor->Group != NULL )
297 Size += SecurityDescriptor->Group->SubAuthorityCount;
300 if ( SecurityDescriptor->Sacl != NULL )
301 Size += SecurityDescriptor->Sacl->AclSize;
302 if ( SecurityDescriptor->Dacl != NULL )
303 Size += SecurityDescriptor->Dacl->AclSize;
305 return Size;
308 /******************************************************************************
309 * RtlGetDaclSecurityDescriptor [NTDLL]
312 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
313 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
314 OUT PBOOLEAN lpbDaclPresent,
315 OUT PACL *pDacl,
316 OUT PBOOLEAN lpbDaclDefaulted)
318 TRACE("(%p,%p,%p,%p)\n",
319 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
321 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
322 return STATUS_UNKNOWN_REVISION ;
324 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
326 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
327 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
329 else
330 { *pDacl = pSecurityDescriptor->Dacl;
334 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
336 return STATUS_SUCCESS;
339 /**************************************************************************
340 * RtlSetDaclSecurityDescriptor [NTDLL.483]
342 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
343 PSECURITY_DESCRIPTOR lpsd,
344 BOOLEAN daclpresent,
345 PACL dacl,
346 BOOLEAN dacldefaulted )
348 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
349 return STATUS_UNKNOWN_REVISION;
350 if (lpsd->Control & SE_SELF_RELATIVE)
351 return STATUS_INVALID_SECURITY_DESCR;
353 if (!daclpresent)
354 { lpsd->Control &= ~SE_DACL_PRESENT;
355 return TRUE;
358 lpsd->Control |= SE_DACL_PRESENT;
359 lpsd->Dacl = dacl;
361 if (dacldefaulted)
362 lpsd->Control |= SE_DACL_DEFAULTED;
363 else
364 lpsd->Control &= ~SE_DACL_DEFAULTED;
366 return STATUS_SUCCESS;
369 /******************************************************************************
370 * RtlGetSaclSecurityDescriptor [NTDLL]
373 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
374 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
375 OUT PBOOLEAN lpbSaclPresent,
376 OUT PACL *pSacl,
377 OUT PBOOLEAN lpbSaclDefaulted)
379 TRACE("(%p,%p,%p,%p)\n",
380 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
382 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
383 return STATUS_UNKNOWN_REVISION ;
385 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
387 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
388 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
390 else
391 { *pSacl = pSecurityDescriptor->Sacl;
395 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
397 return STATUS_SUCCESS;
400 /**************************************************************************
401 * RtlSetSaclSecurityDescriptor [NTDLL.488]
403 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
404 PSECURITY_DESCRIPTOR lpsd,
405 BOOLEAN saclpresent,
406 PACL sacl,
407 BOOLEAN sacldefaulted)
409 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
410 return STATUS_UNKNOWN_REVISION;
411 if (lpsd->Control & SE_SELF_RELATIVE)
412 return STATUS_INVALID_SECURITY_DESCR;
413 if (!saclpresent) {
414 lpsd->Control &= ~SE_SACL_PRESENT;
415 return 0;
417 lpsd->Control |= SE_SACL_PRESENT;
418 lpsd->Sacl = sacl;
419 if (sacldefaulted)
420 lpsd->Control |= SE_SACL_DEFAULTED;
421 else
422 lpsd->Control &= ~SE_SACL_DEFAULTED;
423 return STATUS_SUCCESS;
426 /**************************************************************************
427 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
429 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
430 PSECURITY_DESCRIPTOR SecurityDescriptor,
431 PSID *Owner,
432 PBOOLEAN OwnerDefaulted)
434 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
435 return STATUS_INVALID_PARAMETER;
437 *Owner = SecurityDescriptor->Owner;
438 if ( *Owner != NULL ) {
439 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
440 *OwnerDefaulted = TRUE;
441 else
442 *OwnerDefaulted = FALSE;
444 return STATUS_SUCCESS;
447 /**************************************************************************
448 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
450 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
451 PSECURITY_DESCRIPTOR lpsd,
452 PSID owner,
453 BOOLEAN ownerdefaulted)
455 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
456 return STATUS_UNKNOWN_REVISION;
457 if (lpsd->Control & SE_SELF_RELATIVE)
458 return STATUS_INVALID_SECURITY_DESCR;
460 lpsd->Owner = owner;
461 if (ownerdefaulted)
462 lpsd->Control |= SE_OWNER_DEFAULTED;
463 else
464 lpsd->Control &= ~SE_OWNER_DEFAULTED;
465 return STATUS_SUCCESS;
468 /**************************************************************************
469 * RtlSetGroupSecurityDescriptor [NTDLL.485]
471 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
472 PSECURITY_DESCRIPTOR lpsd,
473 PSID group,
474 BOOLEAN groupdefaulted)
476 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
477 return STATUS_UNKNOWN_REVISION;
478 if (lpsd->Control & SE_SELF_RELATIVE)
479 return STATUS_INVALID_SECURITY_DESCR;
481 lpsd->Group = group;
482 if (groupdefaulted)
483 lpsd->Control |= SE_GROUP_DEFAULTED;
484 else
485 lpsd->Control &= ~SE_GROUP_DEFAULTED;
486 return STATUS_SUCCESS;
488 /**************************************************************************
489 * RtlGetGroupSecurityDescriptor [NTDLL]
491 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
492 PSECURITY_DESCRIPTOR SecurityDescriptor,
493 PSID *Group,
494 PBOOLEAN GroupDefaulted)
496 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
497 return STATUS_INVALID_PARAMETER;
499 *Group = SecurityDescriptor->Group;
500 if ( *Group != NULL ) {
501 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
502 *GroupDefaulted = TRUE;
503 else
504 *GroupDefaulted = FALSE;
506 return STATUS_SUCCESS;
509 /**************************************************************************
510 * RtlMakeSelfRelativeSD [NTDLL]
512 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
513 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
514 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
515 IN OUT LPDWORD lpdwBufferLength)
517 FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
518 pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
519 return STATUS_SUCCESS;
523 * access control list's
526 /**************************************************************************
527 * RtlCreateAcl [NTDLL.306]
529 * NOTES
530 * This should return NTSTATUS
532 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
534 TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
536 if (rev!=ACL_REVISION)
537 return STATUS_INVALID_PARAMETER;
538 if (size<sizeof(ACL))
539 return STATUS_BUFFER_TOO_SMALL;
540 if (size>0xFFFF)
541 return STATUS_INVALID_PARAMETER;
543 memset(acl,'\0',sizeof(ACL));
544 acl->AclRevision = rev;
545 acl->AclSize = size;
546 acl->AceCount = 0;
547 return 0;
550 /**************************************************************************
551 * RtlFirstFreeAce [NTDLL.370]
552 * looks for the AceCount+1 ACE, and if it is still within the alloced
553 * ACL, return a pointer to it
555 BOOLEAN WINAPI RtlFirstFreeAce(
556 PACL acl,
557 PACE_HEADER *x)
559 PACE_HEADER ace;
560 int i;
562 *x = 0;
563 ace = (PACE_HEADER)(acl+1);
564 for (i=0;i<acl->AceCount;i++) {
565 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
566 return 0;
567 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
569 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
570 return 0;
571 *x = ace;
572 return 1;
575 /**************************************************************************
576 * RtlAddAce [NTDLL.260]
578 NTSTATUS WINAPI RtlAddAce(
579 PACL acl,
580 DWORD rev,
581 DWORD xnrofaces,
582 PACE_HEADER acestart,
583 DWORD acelen)
585 PACE_HEADER ace,targetace;
586 int nrofaces;
588 if (acl->AclRevision != ACL_REVISION)
589 return STATUS_INVALID_PARAMETER;
590 if (!RtlFirstFreeAce(acl,&targetace))
591 return STATUS_INVALID_PARAMETER;
592 nrofaces=0;ace=acestart;
593 while (((DWORD)ace-(DWORD)acestart)<acelen) {
594 nrofaces++;
595 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
597 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
598 return STATUS_INVALID_PARAMETER;
599 memcpy((LPBYTE)targetace,acestart,acelen);
600 acl->AceCount+=nrofaces;
601 return STATUS_SUCCESS;
604 /******************************************************************************
605 * RtlAddAccessAllowedAce [NTDLL]
607 BOOL WINAPI RtlAddAccessAllowedAce(
608 IN OUT PACL pAcl,
609 IN DWORD dwAceRevision,
610 IN DWORD AccessMask,
611 IN PSID pSid)
613 FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
614 pAcl, dwAceRevision, AccessMask, pSid);
615 return 0;
618 /******************************************************************************
619 * RtlGetAce [NTDLL]
621 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
623 FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
624 return 0;
628 * misc
631 /******************************************************************************
632 * RtlAdjustPrivilege [NTDLL]
634 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
636 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
637 return 0;
640 /******************************************************************************
641 * RtlImpersonateSelf [NTDLL]
643 BOOL WINAPI
644 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
646 FIXME("(%08x), stub\n", ImpersonationLevel);
647 return TRUE;
650 NTSTATUS WINAPI
651 NtAccessCheck(
652 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
653 IN HANDLE ClientToken,
654 IN ACCESS_MASK DesiredAccess,
655 IN PGENERIC_MAPPING GenericMapping,
656 OUT PPRIVILEGE_SET PrivilegeSet,
657 OUT PULONG ReturnLength,
658 OUT PULONG GrantedAccess,
659 OUT PBOOLEAN AccessStatus)
661 FIXME("(%p, %04x, %08lx, %p, %p, %p, %p, %p), stub\n",
662 SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
663 PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
664 *AccessStatus = TRUE;
665 return STATUS_SUCCESS;
668 NTSTATUS WINAPI
669 NtSetSecurityObject(
670 IN HANDLE Handle,
671 IN SECURITY_INFORMATION SecurityInformation,
672 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
674 FIXME("0x%08x 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
675 return STATUS_SUCCESS;
678 /******************************************************************************
679 * RtlGetControlSecurityDescriptor
682 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
683 PSECURITY_DESCRIPTOR pSecurityDescriptor,
684 PSECURITY_DESCRIPTOR_CONTROL pControl,
685 LPDWORD lpdwRevision)
687 FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
688 return STATUS_SUCCESS;