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