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