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