Take advantage of new winebuild syntax to remove redundant function
[wine] / dlls / ntdll / sec.c
1 /*
2  *      Security functions
3  *
4  *      Copyright 1996-1998 Marcus Meissner
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <ctype.h>
28 #include <math.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wine/exception.h"
36 #include "file.h"
37 #include "winnls.h"
38 #include "wine/debug.h"
39 #include "winerror.h"
40 #include "stackframe.h"
41
42 #include "winternl.h"
43 #include "winreg.h"
44 #include "ntdll_misc.h"
45 #include "excpt.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
48
49 #define NT_SUCCESS(status) (status == STATUS_SUCCESS)
50
51 /* filter for page-fault exceptions */
52 static WINE_EXCEPTION_FILTER(page_fault)
53 {
54     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
55         return EXCEPTION_EXECUTE_HANDLER;
56     return EXCEPTION_CONTINUE_SEARCH;
57 }
58
59 /*
60  *      SID FUNCTIONS
61  */
62
63 /******************************************************************************
64  *  RtlAllocateAndInitializeSid         [NTDLL.@]
65  *
66  */
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 )
75 {
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);
80
81         if (!(*pSid = RtlAllocateHeap( ntdll_get_process_heap(), 0,
82                                        RtlLengthRequiredSid(nSubAuthorityCount))))
83           return FALSE;
84
85         (*pSid)->Revision = SID_REVISION;
86
87         if (pIdentifierAuthority)
88           memcpy(&(*pSid)->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
89         *RtlSubAuthorityCountSid(*pSid) = nSubAuthorityCount;
90
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;
107
108         return STATUS_SUCCESS;
109 }
110 /******************************************************************************
111  *  RtlEqualSid         [NTDLL.@]
112  *
113  * Determine if two SIDs are equal.
114  *
115  * PARAMS
116  *  pSid1 [I] Source SID
117  *  pSid2 [I] SID to compare with
118  *
119  * RETURNS
120  *  TRUE, if pSid1 is equal to pSid2,
121  *  FALSE otherwise.
122  */
123 BOOL WINAPI RtlEqualSid( PSID pSid1, PSID pSid2 )
124 {
125     if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
126         return FALSE;
127
128     if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
129         return FALSE;
130
131     if (memcmp(pSid1, pSid2, RtlLengthSid(pSid1)) != 0)
132         return FALSE;
133
134     return TRUE;
135 }
136
137 /******************************************************************************
138  * RtlEqualPrefixSid    [NTDLL.@]
139  */
140 BOOL WINAPI RtlEqualPrefixSid (PSID pSid1, PSID pSid2)
141 {
142     if (!RtlValidSid(pSid1) || !RtlValidSid(pSid2))
143         return FALSE;
144
145     if (*RtlSubAuthorityCountSid(pSid1) != *RtlSubAuthorityCountSid(pSid2))
146         return FALSE;
147
148     if (memcmp(pSid1, pSid2, RtlLengthRequiredSid(pSid1->SubAuthorityCount - 1)) != 0)
149         return FALSE;
150
151     return TRUE;
152 }
153
154
155 /******************************************************************************
156  *  RtlFreeSid          [NTDLL.@]
157  *
158  * Free the resources used by a SID.
159  *
160  * PARAMS
161  *  pSid [I] SID to Free.
162  *
163  * RETURNS
164  *  STATUS_SUCCESS.
165  */
166 DWORD WINAPI RtlFreeSid(PSID pSid)
167 {
168         TRACE("(%p)\n", pSid);
169         RtlFreeHeap( ntdll_get_process_heap(), 0, pSid );
170         return STATUS_SUCCESS;
171 }
172
173 /**************************************************************************
174  * RtlLengthRequiredSid [NTDLL.@]
175  *
176  * Determine the amount of memory a SID will use
177  *
178  * PARAMS
179  *   nrofsubauths [I] Number of Sub Authorities in the SID.
180  *
181  * RETURNS
182  *   The size, in bytes, of a SID with nrofsubauths Sub Authorities.
183  */
184 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
185 {
186         return (nrofsubauths-1)*sizeof(DWORD) + sizeof(SID);
187 }
188
189 /**************************************************************************
190  *                 RtlLengthSid                         [NTDLL.@]
191  *
192  * Determine the amount of memory a SID is using
193  *
194  * PARAMS
195  *  pSid [I] SID to ge the size of.
196  *
197  * RETURNS
198  *  The size, in bytes, of pSid.
199  */
200 DWORD WINAPI RtlLengthSid(PSID pSid)
201 {
202         TRACE("sid=%p\n",pSid);
203         if (!pSid) return 0;
204         return RtlLengthRequiredSid(*RtlSubAuthorityCountSid(pSid));
205 }
206
207 /**************************************************************************
208  *                 RtlInitializeSid                     [NTDLL.@]
209  *
210  * Initialise a SID.
211  *
212  * PARAMS
213  *  pSid                 [I] SID to initialise
214  *  pIdentifierAuthority [I] Identifier Authority
215  *  nSubAuthorityCount   [I] Number of Sub Authorities
216  *
217  * RETURNS
218  *  Success: TRUE. pSid is initialised withe the details given.
219  *  Failure: FALSE, if nSubAuthorityCount is >= SID_MAX_SUB_AUTHORITIES.
220  */
221 BOOL WINAPI RtlInitializeSid(
222         PSID pSid,
223         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
224         BYTE nSubAuthorityCount)
225 {
226         int i;
227         if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
228           return FALSE;
229
230         pSid->Revision = SID_REVISION;
231         pSid->SubAuthorityCount = nSubAuthorityCount;
232         if (pIdentifierAuthority)
233           memcpy(&pSid->IdentifierAuthority, pIdentifierAuthority, sizeof (SID_IDENTIFIER_AUTHORITY));
234
235         for (i = 0; i < nSubAuthorityCount; i++)
236           *RtlSubAuthoritySid(pSid, i) = 0;
237
238         return TRUE;
239 }
240
241 /**************************************************************************
242  *                 RtlSubAuthoritySid                   [NTDLL.@]
243  *
244  * Return the Sub Authority of a SID
245  *
246  * PARAMS
247  *   pSid          [I] SID to get the Sub Authority from.
248  *   nSubAuthority [I] Sub Authority number.
249  *
250  * RETURNS
251  *   A pointer to The Sub Authority value of pSid.
252  */
253 LPDWORD WINAPI RtlSubAuthoritySid( PSID pSid, DWORD nSubAuthority )
254 {
255         return &(pSid->SubAuthority[nSubAuthority]);
256 }
257
258 /**************************************************************************
259  * RtlIdentifierAuthoritySid    [NTDLL.@]
260  *
261  * Return the Identifier Authority of a SID.
262  *
263  * PARAMS
264  *   pSid [I] SID to get the Identifier Authority from.
265  *
266  * RETURNS
267  *   A pointer to the Identifier Authority value of pSid.
268  */
269 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid( PSID pSid )
270 {
271         return &(pSid->IdentifierAuthority);
272 }
273
274 /**************************************************************************
275  *                 RtlSubAuthorityCountSid              [NTDLL.@]
276  *
277  * Get the number of Sub Authorities in a SID.
278  *
279  * PARAMS
280  *   pSid [I] SID to get the count from.
281  *
282  * RETURNS
283  *  A pointer to the Sub Authority count of pSid.
284  */
285 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID pSid)
286 {
287         return &(pSid->SubAuthorityCount);
288 }
289
290 /**************************************************************************
291  *                 RtlCopySid                           [NTDLL.@]
292  */
293 DWORD WINAPI RtlCopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
294 {
295         if (!pSourceSid || !RtlValidSid(pSourceSid) ||
296             (nDestinationSidLength < RtlLengthSid(pSourceSid)))
297           return FALSE;
298
299         if (nDestinationSidLength < (pSourceSid->SubAuthorityCount*4+8))
300           return FALSE;
301
302         memmove(pDestinationSid, pSourceSid, pSourceSid->SubAuthorityCount*4+8);
303         return TRUE;
304 }
305 /******************************************************************************
306  * RtlValidSid [NTDLL.@]
307  *
308  * Determine if a SID is valid.
309  *
310  * PARAMS
311  *   pSid [I] SID to check
312  *
313  * RETURNS
314  *   TRUE if pSid is valid,
315  *   FALSE otherwise.
316  */
317 BOOL WINAPI
318 RtlValidSid( PSID pSid )
319 {
320     BOOL ret;
321     __TRY
322     {
323         ret = TRUE;
324         if (!pSid || pSid->Revision != SID_REVISION ||
325             pSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
326         {
327             ret = FALSE;
328         }
329     }
330     __EXCEPT(page_fault)
331     {
332         WARN("(%p): invalid pointer!\n", pSid);
333         return FALSE;
334     }
335     __ENDTRY
336     return ret;
337 }
338
339
340 /*
341  *      security descriptor functions
342  */
343
344 /**************************************************************************
345  * RtlCreateSecurityDescriptor                  [NTDLL.@]
346  *
347  * Initialise a SECURITY_DESCRIPTOR.
348  *
349  * PARAMS
350  *  lpsd [O] Descriptor to initialise.
351  *  rev  [I] Revision, must be set to SECURITY_DESCRIPTOR_REVISION.
352  *
353  * RETURNS:
354  *  Success: STATUS_SUCCESS.
355  *  Failure: STATUS_UNKNOWN_REVISION if rev is incorrect.
356  */
357 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
358         PSECURITY_DESCRIPTOR lpsd,
359         DWORD rev)
360 {
361         if (rev!=SECURITY_DESCRIPTOR_REVISION)
362                 return STATUS_UNKNOWN_REVISION;
363         memset(lpsd,'\0',sizeof(*lpsd));
364         lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
365         return STATUS_SUCCESS;
366 }
367 /**************************************************************************
368  * RtlValidSecurityDescriptor                   [NTDLL.@]
369  *
370  * Determine if a SECURITY_DESCRIPTOR is valid.
371  *
372  * PARAMS
373  *  SecurityDescriptor [I] Descriptor to check.
374  *
375  * RETURNS
376  *   Success: STATUS_SUCCESS.
377  *   Failure: STATUS_INVALID_SECURITY_DESCR or STATUS_UNKNOWN_REVISION.
378  */
379 NTSTATUS WINAPI RtlValidSecurityDescriptor(
380         PSECURITY_DESCRIPTOR SecurityDescriptor)
381 {
382         if ( ! SecurityDescriptor )
383                 return STATUS_INVALID_SECURITY_DESCR;
384         if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
385                 return STATUS_UNKNOWN_REVISION;
386
387         return STATUS_SUCCESS;
388 }
389
390 /**************************************************************************
391  *  RtlLengthSecurityDescriptor                 [NTDLL.@]
392  */
393 ULONG WINAPI RtlLengthSecurityDescriptor(
394         PSECURITY_DESCRIPTOR SecurityDescriptor)
395 {
396         ULONG Size;
397         Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
398         if ( SecurityDescriptor == NULL )
399                 return 0;
400
401         if ( SecurityDescriptor->Owner != NULL )
402                 Size += SecurityDescriptor->Owner->SubAuthorityCount;
403         if ( SecurityDescriptor->Group != NULL )
404                 Size += SecurityDescriptor->Group->SubAuthorityCount;
405
406
407         if ( SecurityDescriptor->Sacl != NULL )
408                 Size += SecurityDescriptor->Sacl->AclSize;
409         if ( SecurityDescriptor->Dacl != NULL )
410                 Size += SecurityDescriptor->Dacl->AclSize;
411
412         return Size;
413 }
414
415 /******************************************************************************
416  *  RtlGetDaclSecurityDescriptor                [NTDLL.@]
417  *
418  */
419 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
420         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
421         OUT PBOOLEAN lpbDaclPresent,
422         OUT PACL *pDacl,
423         OUT PBOOLEAN lpbDaclDefaulted)
424 {
425         TRACE("(%p,%p,%p,%p)\n",
426         pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
427
428         if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
429           return STATUS_UNKNOWN_REVISION ;
430
431         if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
432         {
433           if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
434           { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
435           }
436           else
437           { *pDacl = pSecurityDescriptor->Dacl;
438           }
439         }
440
441         *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
442
443         return STATUS_SUCCESS;
444 }
445
446 /**************************************************************************
447  *  RtlSetDaclSecurityDescriptor                [NTDLL.@]
448  */
449 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
450         PSECURITY_DESCRIPTOR lpsd,
451         BOOLEAN daclpresent,
452         PACL dacl,
453         BOOLEAN dacldefaulted )
454 {
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;
459
460         if (!daclpresent)
461         {       lpsd->Control &= ~SE_DACL_PRESENT;
462                 return TRUE;
463         }
464
465         lpsd->Control |= SE_DACL_PRESENT;
466         lpsd->Dacl = dacl;
467
468         if (dacldefaulted)
469                 lpsd->Control |= SE_DACL_DEFAULTED;
470         else
471                 lpsd->Control &= ~SE_DACL_DEFAULTED;
472
473         return STATUS_SUCCESS;
474 }
475
476 /******************************************************************************
477  *  RtlGetSaclSecurityDescriptor                [NTDLL.@]
478  *
479  */
480 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
481         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
482         OUT PBOOLEAN lpbSaclPresent,
483         OUT PACL *pSacl,
484         OUT PBOOLEAN lpbSaclDefaulted)
485 {
486         TRACE("(%p,%p,%p,%p)\n",
487         pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
488
489         if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
490           return STATUS_UNKNOWN_REVISION ;
491
492         if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
493         {
494           if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
495           { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
496           }
497           else
498           { *pSacl = pSecurityDescriptor->Sacl;
499           }
500         }
501
502         *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
503
504         return STATUS_SUCCESS;
505 }
506
507 /**************************************************************************
508  * RtlSetSaclSecurityDescriptor                 [NTDLL.@]
509  */
510 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
511         PSECURITY_DESCRIPTOR lpsd,
512         BOOLEAN saclpresent,
513         PACL sacl,
514         BOOLEAN sacldefaulted)
515 {
516         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
517                 return STATUS_UNKNOWN_REVISION;
518         if (lpsd->Control & SE_SELF_RELATIVE)
519                 return STATUS_INVALID_SECURITY_DESCR;
520         if (!saclpresent) {
521                 lpsd->Control &= ~SE_SACL_PRESENT;
522                 return 0;
523         }
524         lpsd->Control |= SE_SACL_PRESENT;
525         lpsd->Sacl = sacl;
526         if (sacldefaulted)
527                 lpsd->Control |= SE_SACL_DEFAULTED;
528         else
529                 lpsd->Control &= ~SE_SACL_DEFAULTED;
530         return STATUS_SUCCESS;
531 }
532
533 /**************************************************************************
534  * RtlGetOwnerSecurityDescriptor                [NTDLL.@]
535  */
536 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
537         PSECURITY_DESCRIPTOR SecurityDescriptor,
538         PSID *Owner,
539         PBOOLEAN OwnerDefaulted)
540 {
541         if ( !SecurityDescriptor  || !Owner || !OwnerDefaulted )
542                 return STATUS_INVALID_PARAMETER;
543
544         *Owner = SecurityDescriptor->Owner;
545         if ( *Owner != NULL )  {
546                 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
547                         *OwnerDefaulted = TRUE;
548                 else
549                         *OwnerDefaulted = FALSE;
550         }
551         return STATUS_SUCCESS;
552 }
553
554 /**************************************************************************
555  *                 RtlSetOwnerSecurityDescriptor                [NTDLL.@]
556  */
557 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
558         PSECURITY_DESCRIPTOR lpsd,
559         PSID owner,
560         BOOLEAN ownerdefaulted)
561 {
562         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
563                 return STATUS_UNKNOWN_REVISION;
564         if (lpsd->Control & SE_SELF_RELATIVE)
565                 return STATUS_INVALID_SECURITY_DESCR;
566
567         lpsd->Owner = owner;
568         if (ownerdefaulted)
569                 lpsd->Control |= SE_OWNER_DEFAULTED;
570         else
571                 lpsd->Control &= ~SE_OWNER_DEFAULTED;
572         return STATUS_SUCCESS;
573 }
574
575 /**************************************************************************
576  *                 RtlSetGroupSecurityDescriptor                [NTDLL.@]
577  */
578 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
579         PSECURITY_DESCRIPTOR lpsd,
580         PSID group,
581         BOOLEAN groupdefaulted)
582 {
583         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
584                 return STATUS_UNKNOWN_REVISION;
585         if (lpsd->Control & SE_SELF_RELATIVE)
586                 return STATUS_INVALID_SECURITY_DESCR;
587
588         lpsd->Group = group;
589         if (groupdefaulted)
590                 lpsd->Control |= SE_GROUP_DEFAULTED;
591         else
592                 lpsd->Control &= ~SE_GROUP_DEFAULTED;
593         return STATUS_SUCCESS;
594 }
595 /**************************************************************************
596  *                 RtlGetGroupSecurityDescriptor                [NTDLL.@]
597  */
598 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
599         PSECURITY_DESCRIPTOR SecurityDescriptor,
600         PSID *Group,
601         PBOOLEAN GroupDefaulted)
602 {
603         if ( !SecurityDescriptor || !Group || !GroupDefaulted )
604                 return STATUS_INVALID_PARAMETER;
605
606         *Group = SecurityDescriptor->Group;
607         if ( *Group != NULL )  {
608                 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
609                         *GroupDefaulted = TRUE;
610                 else
611                         *GroupDefaulted = FALSE;
612         }
613         return STATUS_SUCCESS;
614 }
615
616 /**************************************************************************
617  *                 RtlMakeSelfRelativeSD                [NTDLL.@]
618  */
619 NTSTATUS WINAPI RtlMakeSelfRelativeSD(
620         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
621         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
622         IN OUT LPDWORD lpdwBufferLength)
623 {
624         FIXME("(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
625         pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
626         return STATUS_SUCCESS;
627 }
628
629 /*
630  *      access control list's
631  */
632
633 /**************************************************************************
634  *                 RtlCreateAcl                         [NTDLL.@]
635  *
636  * NOTES
637  *    This should return NTSTATUS
638  */
639 NTSTATUS WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
640 {
641         TRACE("%p 0x%08lx 0x%08lx\n", acl, size, rev);
642
643         if (rev!=ACL_REVISION)
644                 return STATUS_INVALID_PARAMETER;
645         if (size<sizeof(ACL))
646                 return STATUS_BUFFER_TOO_SMALL;
647         if (size>0xFFFF)
648                 return STATUS_INVALID_PARAMETER;
649
650         memset(acl,'\0',sizeof(ACL));
651         acl->AclRevision        = rev;
652         acl->AclSize            = size;
653         acl->AceCount           = 0;
654         return STATUS_SUCCESS;
655 }
656
657 /**************************************************************************
658  *                 RtlFirstFreeAce                      [NTDLL.@]
659  * looks for the AceCount+1 ACE, and if it is still within the alloced
660  * ACL, return a pointer to it
661  */
662 BOOLEAN WINAPI RtlFirstFreeAce(
663         PACL acl,
664         PACE_HEADER *x)
665 {
666         PACE_HEADER     ace;
667         int             i;
668
669         *x = 0;
670         ace = (PACE_HEADER)(acl+1);
671         for (i=0;i<acl->AceCount;i++) {
672                 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
673                         return 0;
674                 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
675         }
676         if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
677                 return 0;
678         *x = ace;
679         return 1;
680 }
681
682 /**************************************************************************
683  *                 RtlAddAce                            [NTDLL.@]
684  */
685 NTSTATUS WINAPI RtlAddAce(
686         PACL acl,
687         DWORD rev,
688         DWORD xnrofaces,
689         PACE_HEADER acestart,
690         DWORD acelen)
691 {
692         PACE_HEADER     ace,targetace;
693         int             nrofaces;
694
695         if (acl->AclRevision != ACL_REVISION)
696                 return STATUS_INVALID_PARAMETER;
697         if (!RtlFirstFreeAce(acl,&targetace))
698                 return STATUS_INVALID_PARAMETER;
699         nrofaces=0;ace=acestart;
700         while (((DWORD)ace-(DWORD)acestart)<acelen) {
701                 nrofaces++;
702                 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
703         }
704         if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
705                 return STATUS_INVALID_PARAMETER;
706         memcpy((LPBYTE)targetace,acestart,acelen);
707         acl->AceCount+=nrofaces;
708         return STATUS_SUCCESS;
709 }
710
711 /******************************************************************************
712  *  RtlAddAccessAllowedAce              [NTDLL.@]
713  */
714 BOOL WINAPI RtlAddAccessAllowedAce(
715         IN OUT PACL pAcl,
716         IN DWORD dwAceRevision,
717         IN DWORD AccessMask,
718         IN PSID pSid)
719 {
720         FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
721         pAcl, dwAceRevision, AccessMask, pSid);
722         return TRUE;
723 }
724
725 /******************************************************************************
726  *  RtlGetAce           [NTDLL.@]
727  */
728 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
729 {
730         FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
731         return 0;
732 }
733
734 /*
735  *      misc
736  */
737
738 /******************************************************************************
739  *  RtlAdjustPrivilege          [NTDLL.@]
740  */
741 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
742 {
743         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
744         return 0;
745 }
746
747 /******************************************************************************
748  *  RtlImpersonateSelf          [NTDLL.@]
749  */
750 BOOL WINAPI
751 RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
752 {
753         FIXME("(%08x), stub\n", ImpersonationLevel);
754         return TRUE;
755 }
756
757 /******************************************************************************
758  *  NtAccessCheck               [NTDLL.@]
759  *  ZwAccessCheck               [NTDLL.@]
760  */
761 NTSTATUS WINAPI
762 NtAccessCheck(
763         IN PSECURITY_DESCRIPTOR SecurityDescriptor,
764         IN HANDLE ClientToken,
765         IN ACCESS_MASK DesiredAccess,
766         IN PGENERIC_MAPPING GenericMapping,
767         OUT PPRIVILEGE_SET PrivilegeSet,
768         OUT PULONG ReturnLength,
769         OUT PULONG GrantedAccess,
770         OUT PBOOLEAN AccessStatus)
771 {
772         FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
773           SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
774           PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
775         *AccessStatus = TRUE;
776         return STATUS_SUCCESS;
777 }
778
779 /******************************************************************************
780  *  NtSetSecurityObject         [NTDLL.@]
781  */
782 NTSTATUS WINAPI
783 NtSetSecurityObject(
784         IN HANDLE Handle,
785         IN SECURITY_INFORMATION SecurityInformation,
786         IN PSECURITY_DESCRIPTOR SecurityDescriptor)
787 {
788         FIXME("%p 0x%08lx %p\n", Handle, SecurityInformation, SecurityDescriptor);
789         return STATUS_SUCCESS;
790 }
791
792 /******************************************************************************
793  * RtlGetControlSecurityDescriptor (NTDLL.@)
794  */
795
796 NTSTATUS WINAPI RtlGetControlSecurityDescriptor(
797         PSECURITY_DESCRIPTOR  pSecurityDescriptor,
798         PSECURITY_DESCRIPTOR_CONTROL pControl,
799         LPDWORD lpdwRevision)
800 {
801         FIXME("(%p,%p,%p),stub!\n",pSecurityDescriptor,pControl,lpdwRevision);
802         return STATUS_SUCCESS;
803 }
804
805 /******************************************************************************
806  * RtlConvertSidToUnicodeString (NTDLL.@)
807  *
808  * The returned SID is used to access the USER registry hive usually
809  *
810  * the native function returns something like
811  * "S-1-5-21-0000000000-000000000-0000000000-500";
812  */
813 NTSTATUS WINAPI RtlConvertSidToUnicodeString(
814        PUNICODE_STRING String,
815        PSID Sid,
816        BOOLEAN AllocateString)
817 {
818         const char *p = wine_get_user_name();
819         NTSTATUS status;
820         ANSI_STRING AnsiStr;
821
822         FIXME("(%p %p %u)\n", String, Sid, AllocateString);
823
824         RtlInitAnsiString(&AnsiStr, p);
825         status = RtlAnsiStringToUnicodeString(String, &AnsiStr, AllocateString);
826
827         TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);
828         return status;
829 }