- Be more accurate on Darwin stack size.
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  FIXME: for all functions thunking down to Rtl* functions:  implement SetLastError()
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "rpcnterr.h"
29 #include "winreg.h"
30 #include "winternl.h"
31 #include "ntstatus.h"
32 #include "ntsecapi.h"
33 #include "accctrl.h"
34 #include "sddl.h"
35
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
40
41 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
42 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
43     PACL pAcl, LPDWORD cBytes);
44 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
45 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
46 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
47 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
48     LPCWSTR StringSecurityDescriptor,
49     PSECURITY_DESCRIPTOR SecurityDescriptor, 
50     LPDWORD cBytes);
51 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
52
53 typedef struct _ACEFLAG
54 {
55    LPCWSTR wstr;
56    DWORD value;
57 } ACEFLAG, *LPACEFLAG;
58
59 /*
60  * ACE access rights
61  */
62 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
63 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
64 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
65 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
66 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
67 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
68 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
69 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
70
71 /*
72  * ACE types
73  */
74 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
75 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
76 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
77 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
78 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
79 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
80 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
81 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
82
83 /*
84  * ACE flags
85  */
86 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
87 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
88 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
89 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
90 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
91 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
92 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
93
94 #define CallWin32ToNt(func) \
95         { NTSTATUS ret; \
96           ret = (func); \
97           if (ret !=STATUS_SUCCESS) \
98           { SetLastError (RtlNtStatusToDosError(ret)); return FALSE; } \
99           return TRUE; \
100         }
101
102 static void dumpLsaAttributes( PLSA_OBJECT_ATTRIBUTES oa )
103 {
104         if (oa)
105         {
106           TRACE("\n\tlength=%lu, rootdir=%p, objectname=%s\n\tattr=0x%08lx, sid=%p qos=%p\n",
107                 oa->Length, oa->RootDirectory,
108                 oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
109                 oa->Attributes, oa->SecurityDescriptor, oa->SecurityQualityOfService);
110         }
111 }
112
113 /************************************************************
114  *                ADVAPI_IsLocalComputer
115  *
116  * Checks whether the server name indicates local machine.
117  */
118 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
119 {
120     if (!ServerName)
121     {
122         return TRUE;
123     }
124     else
125     {
126         DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
127         BOOL Result;
128         LPWSTR buf;
129
130         buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
131         Result = GetComputerNameW(buf,  &dwSize);
132         if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
133             ServerName += 2;
134         Result = Result && !lstrcmpW(ServerName, buf);
135         HeapFree(GetProcessHeap(), 0, buf);
136
137         return Result;
138     }
139 }
140
141 #define ADVAPI_ForceLocalComputer(ServerName, FailureCode) \
142     if (!ADVAPI_IsLocalComputer(ServerName)) \
143     { \
144         FIXME("Action Implemented for local computer only. " \
145               "Requested for server %s\n", debugstr_w(ServerName)); \
146         return FailureCode; \
147     }
148
149 /*      ##############################
150         ######  TOKEN FUNCTIONS ######
151         ##############################
152 */
153
154 /******************************************************************************
155  * OpenProcessToken                     [ADVAPI32.@]
156  * Opens the access token associated with a process handle.
157  *
158  * PARAMS
159  *   ProcessHandle [I] Handle to process
160  *   DesiredAccess [I] Desired access to process
161  *   TokenHandle   [O] Pointer to handle of open access token
162  *
163  * RETURNS
164  *  Success: TRUE. TokenHandle contains the access token.
165  *  Failure: FALSE.
166  *
167  * NOTES
168  *  See NtOpenProcessToken.
169  */
170 BOOL WINAPI
171 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
172                   HANDLE *TokenHandle )
173 {
174         CallWin32ToNt(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
175 }
176
177 /******************************************************************************
178  * OpenThreadToken [ADVAPI32.@]
179  *
180  * Opens the access token associated with a thread handle.
181  *
182  * PARAMS
183  *   ThreadHandle  [I] Handle to process
184  *   DesiredAccess [I] Desired access to the thread
185  *   OpenAsSelf    [I] ???
186  *   TokenHandle   [O] Destination for the token handle
187  *
188  * RETURNS
189  *  Success: TRUE. TokenHandle contains the access token.
190  *  Failure: FALSE.
191  *
192  * NOTES
193  *  See NtOpenThreadToken.
194  */
195 BOOL WINAPI
196 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
197                  BOOL OpenAsSelf, HANDLE *TokenHandle)
198 {
199         CallWin32ToNt (NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
200 }
201
202 /******************************************************************************
203  * AdjustTokenPrivileges [ADVAPI32.@]
204  *
205  * Adjust the privileges of an open token handle.
206  * 
207  * PARAMS
208  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
209  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
210  *  NewState             [I]   Desired new privileges of the token
211  *  BufferLength         [I]   Length of NewState
212  *  PreviousState        [O]   Destination for the previous state
213  *  ReturnLength         [I/O] Size of PreviousState
214  *
215  *
216  * RETURNS
217  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
218  *  Failure: FALSE.
219  *
220  * NOTES
221  *  See NtAdjustPrivilegesToken.
222  */
223 BOOL WINAPI
224 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
225                        LPVOID NewState, DWORD BufferLength,
226                        LPVOID PreviousState, LPDWORD ReturnLength )
227 {
228         CallWin32ToNt(NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength));
229 }
230
231 /******************************************************************************
232  * CheckTokenMembership [ADVAPI32.@]
233  *
234  * Determine if an access token is a member of a SID.
235  * 
236  * PARAMS
237  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
238  *   SidToCheck  [I] SID that possibly contains the token
239  *   IsMember    [O] Destination for result.
240  *
241  * RETURNS
242  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
243  *  Failure: FALSE.
244  */
245 BOOL WINAPI
246 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
247                       PBOOL IsMember )
248 {
249   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
250
251   *IsMember = TRUE;
252   return(TRUE);
253 }
254
255 /******************************************************************************
256  * GetTokenInformation [ADVAPI32.@]
257  *
258  * PARAMS
259  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
260  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
261  *   tokeninfo       [O] Destination for token information
262  *   tokeninfolength [I] Length of tokeninfo
263  *   retlen          [O] Destination for returned token information length
264  *
265  * RETURNS
266  *  Success: TRUE. tokeninfo contains retlen bytes of token information
267  *  Failure: FALSE.
268  *
269  * NOTES
270  *  See NtQueryInformationToken.
271  */
272 BOOL WINAPI
273 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
274                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
275 {
276     TRACE("(%p, %s, %p, %ld, %p): \n",
277           token,
278           (tokeninfoclass == TokenUser) ? "TokenUser" :
279           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
280           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
281           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
282           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
283           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
284           (tokeninfoclass == TokenSource) ? "TokenSource" :
285           (tokeninfoclass == TokenType) ? "TokenType" :
286           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
287           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
288           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
289           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
290           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
291           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
292           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
293           "Unknown",
294           tokeninfo, tokeninfolength, retlen);
295     CallWin32ToNt (NtQueryInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength, retlen));
296 }
297
298 /******************************************************************************
299  * SetTokenInformation [ADVAPI32.@]
300  *
301  * Set information for an access token.
302  *
303  * PARAMS
304  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
305  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
306  *   tokeninfo       [I] Token information to set
307  *   tokeninfolength [I] Length of tokeninfo
308  *
309  * RETURNS
310  *  Success: TRUE. The information for the token is set to tokeninfo.
311  *  Failure: FALSE.
312  */
313 BOOL WINAPI
314 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
315                      LPVOID tokeninfo, DWORD tokeninfolength )
316 {
317     FIXME("(%p, %s, %p, %ld): stub\n",
318           token,
319           (tokeninfoclass == TokenUser) ? "TokenUser" :
320           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
321           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
322           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
323           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
324           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
325           (tokeninfoclass == TokenSource) ? "TokenSource" :
326           (tokeninfoclass == TokenType) ? "TokenType" :
327           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
328           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
329           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
330           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
331           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
332           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
333           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
334           "Unknown",
335           tokeninfo, tokeninfolength);
336
337     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
338
339     return FALSE;
340 }
341
342 /*************************************************************************
343  * SetThreadToken [ADVAPI32.@]
344  *
345  * Assigns an 'impersonation token' to a thread so it can assume the
346  * security privileges of another thread or process.  Can also remove
347  * a previously assigned token. 
348  *
349  * PARAMS
350  *   thread          [O] Handle to thread to set the token for
351  *   token           [I] Token to set
352  *
353  * RETURNS
354  *  Success: TRUE. The threads access token is set to token
355  *  Failure: FALSE.
356  *
357  * NOTES
358  *  Only supported on NT or higher. On Win9X this function does nothing.
359  *  See SetTokenInformation.
360  */
361 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
362 {
363     FIXME("(%p, %p): stub (NT impl. only)\n", thread, token);
364
365     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
366
367     return FALSE;
368 }
369
370 /*      ##############################
371         ######  SID FUNCTIONS   ######
372         ##############################
373 */
374
375 /******************************************************************************
376  * AllocateAndInitializeSid [ADVAPI32.@]
377  *
378  * PARAMS
379  *   pIdentifierAuthority []
380  *   nSubAuthorityCount   []
381  *   nSubAuthority0       []
382  *   nSubAuthority1       []
383  *   nSubAuthority2       []
384  *   nSubAuthority3       []
385  *   nSubAuthority4       []
386  *   nSubAuthority5       []
387  *   nSubAuthority6       []
388  *   nSubAuthority7       []
389  *   pSid                 []
390  */
391 BOOL WINAPI
392 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
393                           BYTE nSubAuthorityCount,
394                           DWORD nSubAuthority0, DWORD nSubAuthority1,
395                           DWORD nSubAuthority2, DWORD nSubAuthority3,
396                           DWORD nSubAuthority4, DWORD nSubAuthority5,
397                           DWORD nSubAuthority6, DWORD nSubAuthority7,
398                           PSID *pSid )
399 {
400         CallWin32ToNt (RtlAllocateAndInitializeSid(
401                 pIdentifierAuthority, nSubAuthorityCount,
402                 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
403                 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
404                 pSid ));
405 }
406
407 /******************************************************************************
408  * FreeSid [ADVAPI32.@]
409  *
410  * PARAMS
411  *   pSid []
412  */
413 PVOID WINAPI
414 FreeSid( PSID pSid )
415 {
416         RtlFreeSid(pSid);
417         return NULL; /* is documented like this */
418 }
419
420 /******************************************************************************
421  * CopySid [ADVAPI32.@]
422  *
423  * PARAMS
424  *   nDestinationSidLength []
425  *   pDestinationSid       []
426  *   pSourceSid            []
427  */
428 BOOL WINAPI
429 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
430 {
431         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
432 }
433
434 /******************************************************************************
435  * IsValidSid [ADVAPI32.@]
436  *
437  * PARAMS
438  *   pSid []
439  */
440 BOOL WINAPI
441 IsValidSid( PSID pSid )
442 {
443         return RtlValidSid( pSid );
444 }
445
446 /******************************************************************************
447  * EqualSid [ADVAPI32.@]
448  *
449  * PARAMS
450  *   pSid1 []
451  *   pSid2 []
452  */
453 BOOL WINAPI
454 EqualSid( PSID pSid1, PSID pSid2 )
455 {
456         return RtlEqualSid( pSid1, pSid2 );
457 }
458
459 /******************************************************************************
460  * EqualPrefixSid [ADVAPI32.@]
461  */
462 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
463 {
464         return RtlEqualPrefixSid(pSid1, pSid2);
465 }
466
467 /******************************************************************************
468  * GetSidLengthRequired [ADVAPI32.@]
469  *
470  * PARAMS
471  *   nSubAuthorityCount []
472  */
473 DWORD WINAPI
474 GetSidLengthRequired( BYTE nSubAuthorityCount )
475 {
476         return RtlLengthRequiredSid(nSubAuthorityCount);
477 }
478
479 /******************************************************************************
480  * InitializeSid [ADVAPI32.@]
481  *
482  * PARAMS
483  *   pIdentifierAuthority []
484  */
485 BOOL WINAPI
486 InitializeSid (
487         PSID pSid,
488         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
489         BYTE nSubAuthorityCount)
490 {
491         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
492 }
493
494 /******************************************************************************
495  * GetSidIdentifierAuthority [ADVAPI32.@]
496  *
497  * PARAMS
498  *   pSid []
499  */
500 PSID_IDENTIFIER_AUTHORITY WINAPI
501 GetSidIdentifierAuthority( PSID pSid )
502 {
503         return RtlIdentifierAuthoritySid(pSid);
504 }
505
506 /******************************************************************************
507  * GetSidSubAuthority [ADVAPI32.@]
508  *
509  * PARAMS
510  *   pSid          []
511  *   nSubAuthority []
512  */
513 PDWORD WINAPI
514 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
515 {
516         return RtlSubAuthoritySid(pSid, nSubAuthority);
517 }
518
519 /******************************************************************************
520  * GetSidSubAuthorityCount [ADVAPI32.@]
521  *
522  * PARAMS
523  *   pSid []
524  */
525 PUCHAR WINAPI
526 GetSidSubAuthorityCount (PSID pSid)
527 {
528         return RtlSubAuthorityCountSid(pSid);
529 }
530
531 /******************************************************************************
532  * GetLengthSid [ADVAPI32.@]
533  *
534  * PARAMS
535  *   pSid []
536  */
537 DWORD WINAPI
538 GetLengthSid (PSID pSid)
539 {
540         return RtlLengthSid(pSid);
541 }
542
543 /*      ##############################################
544         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
545         ##############################################
546 */
547
548 /******************************************************************************
549  * InitializeSecurityDescriptor [ADVAPI32.@]
550  *
551  * PARAMS
552  *   pDescr   []
553  *   revision []
554  */
555 BOOL WINAPI
556 InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr, DWORD revision )
557 {
558         CallWin32ToNt (RtlCreateSecurityDescriptor(pDescr, revision ));
559 }
560
561
562 /******************************************************************************
563  * MakeAbsoluteSD [ADVAPI32.@]
564  */
565 BOOL WINAPI MakeAbsoluteSD (
566         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
567         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
568         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
569         OUT PACL pDacl,
570         OUT LPDWORD lpdwDaclSize,
571         OUT PACL pSacl,
572         OUT LPDWORD lpdwSaclSize,
573         OUT PSID pOwner,
574         OUT LPDWORD lpdwOwnerSize,
575         OUT PSID pPrimaryGroup,
576         OUT LPDWORD lpdwPrimaryGroupSize)
577 {
578         CallWin32ToNt (RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
579             pAbsoluteSecurityDescriptor, lpdwAbsoluteSecurityDescriptorSize,
580             pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize,
581             pPrimaryGroup, lpdwPrimaryGroupSize));
582 }
583
584
585 /******************************************************************************
586  * GetSecurityDescriptorLength [ADVAPI32.@]
587  */
588 DWORD WINAPI GetSecurityDescriptorLength( SECURITY_DESCRIPTOR *pDescr)
589 {
590         return (RtlLengthSecurityDescriptor(pDescr));
591 }
592
593 /******************************************************************************
594  * GetSecurityDescriptorOwner [ADVAPI32.@]
595  *
596  * PARAMS
597  *   pOwner            []
598  *   lpbOwnerDefaulted []
599  */
600 BOOL WINAPI
601 GetSecurityDescriptorOwner( SECURITY_DESCRIPTOR *pDescr, PSID *pOwner,
602                             LPBOOL lpbOwnerDefaulted )
603 {
604         CallWin32ToNt (RtlGetOwnerSecurityDescriptor( pDescr, pOwner, (PBOOLEAN)lpbOwnerDefaulted ));
605 }
606
607 /******************************************************************************
608  * SetSecurityDescriptorOwner [ADVAPI32.@]
609  *
610  * PARAMS
611  */
612 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
613                                    PSID pOwner, BOOL bOwnerDefaulted)
614 {
615         CallWin32ToNt (RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
616 }
617 /******************************************************************************
618  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
619  */
620 BOOL WINAPI GetSecurityDescriptorGroup(
621         PSECURITY_DESCRIPTOR SecurityDescriptor,
622         PSID *Group,
623         LPBOOL GroupDefaulted)
624 {
625         CallWin32ToNt (RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, (PBOOLEAN)GroupDefaulted));
626 }
627 /******************************************************************************
628  * SetSecurityDescriptorGroup [ADVAPI32.@]
629  */
630 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
631                                            PSID Group, BOOL GroupDefaulted)
632 {
633         CallWin32ToNt (RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
634 }
635
636 /******************************************************************************
637  * IsValidSecurityDescriptor [ADVAPI32.@]
638  *
639  * PARAMS
640  *   lpsecdesc []
641  */
642 BOOL WINAPI
643 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
644 {
645         CallWin32ToNt (RtlValidSecurityDescriptor(SecurityDescriptor));
646 }
647
648 /******************************************************************************
649  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
650  */
651 BOOL WINAPI GetSecurityDescriptorDacl(
652         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
653         OUT LPBOOL lpbDaclPresent,
654         OUT PACL *pDacl,
655         OUT LPBOOL lpbDaclDefaulted)
656 {
657         CallWin32ToNt (RtlGetDaclSecurityDescriptor(pSecurityDescriptor, (PBOOLEAN)lpbDaclPresent,
658                                                pDacl, (PBOOLEAN)lpbDaclDefaulted));
659 }
660
661 /******************************************************************************
662  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
663  */
664 BOOL WINAPI
665 SetSecurityDescriptorDacl (
666         PSECURITY_DESCRIPTOR lpsd,
667         BOOL daclpresent,
668         PACL dacl,
669         BOOL dacldefaulted )
670 {
671         CallWin32ToNt (RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ));
672 }
673 /******************************************************************************
674  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
675  */
676 BOOL WINAPI GetSecurityDescriptorSacl(
677         IN PSECURITY_DESCRIPTOR lpsd,
678         OUT LPBOOL lpbSaclPresent,
679         OUT PACL *pSacl,
680         OUT LPBOOL lpbSaclDefaulted)
681 {
682         CallWin32ToNt (RtlGetSaclSecurityDescriptor(lpsd,
683            (PBOOLEAN)lpbSaclPresent, pSacl, (PBOOLEAN)lpbSaclDefaulted));
684 }
685
686 /**************************************************************************
687  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
688  */
689 BOOL WINAPI SetSecurityDescriptorSacl (
690         PSECURITY_DESCRIPTOR lpsd,
691         BOOL saclpresent,
692         PACL lpsacl,
693         BOOL sacldefaulted)
694 {
695         CallWin32ToNt (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
696 }
697 /******************************************************************************
698  * MakeSelfRelativeSD [ADVAPI32.@]
699  *
700  * PARAMS
701  *   lpabssecdesc  []
702  *   lpselfsecdesc []
703  *   lpbuflen      []
704  */
705 BOOL WINAPI
706 MakeSelfRelativeSD(
707         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
708         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
709         IN OUT LPDWORD lpdwBufferLength)
710 {
711         CallWin32ToNt (RtlMakeSelfRelativeSD(pAbsoluteSecurityDescriptor,pSelfRelativeSecurityDescriptor, lpdwBufferLength));
712 }
713
714 /******************************************************************************
715  * GetSecurityDescriptorControl                 [ADVAPI32.@]
716  */
717
718 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
719                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
720 {
721         CallWin32ToNt (RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
722 }
723
724 /*      ##############################
725         ######  ACL FUNCTIONS   ######
726         ##############################
727 */
728
729 /*************************************************************************
730  * InitializeAcl [ADVAPI32.@]
731  */
732 DWORD WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
733 {
734         CallWin32ToNt (RtlCreateAcl(acl, size, rev));
735 }
736
737 /******************************************************************************
738  *  AddAccessAllowedAce [ADVAPI32.@]
739  */
740 BOOL WINAPI AddAccessAllowedAce(
741         IN OUT PACL pAcl,
742         IN DWORD dwAceRevision,
743         IN DWORD AccessMask,
744         IN PSID pSid)
745 {
746         CallWin32ToNt(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
747 }
748
749 /******************************************************************************
750  *  AddAccessAllowedAceEx [ADVAPI32.@]
751  */
752 BOOL WINAPI AddAccessAllowedAceEx(
753         IN OUT PACL pAcl,
754         IN DWORD dwAceRevision,
755         IN DWORD AceFlags,
756         IN DWORD AccessMask,
757         IN PSID pSid)
758 {
759         CallWin32ToNt(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
760 }
761
762 /******************************************************************************
763  *  AddAccessDeniedAce [ADVAPI32.@]
764  */
765 BOOL WINAPI AddAccessDeniedAce(
766         IN OUT PACL pAcl,
767         IN DWORD dwAceRevision,
768         IN DWORD AccessMask,
769         IN PSID pSid)
770 {
771         CallWin32ToNt(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
772 }
773
774 /******************************************************************************
775  *  AddAccessDeniedAceEx [ADVAPI32.@]
776  */
777 BOOL WINAPI AddAccessDeniedAceEx(
778         IN OUT PACL pAcl,
779         IN DWORD dwAceRevision,
780         IN DWORD AceFlags,
781         IN DWORD AccessMask,
782         IN PSID pSid)
783 {
784         CallWin32ToNt(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
785 }
786
787 /******************************************************************************
788  *  AddAce [ADVAPI32.@]
789  */
790 BOOL WINAPI AddAce(
791         IN OUT PACL pAcl,
792         IN DWORD dwAceRevision,
793         IN DWORD dwStartingAceIndex,
794         LPVOID pAceList,
795         DWORD nAceListLength)
796 {
797         CallWin32ToNt(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
798 }
799
800 /******************************************************************************
801  * DeleteAce [ADVAPI32.@]
802  */
803 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
804 {
805     CallWin32ToNt(RtlDeleteAce(pAcl, dwAceIndex));
806 }
807
808 /******************************************************************************
809  *  FindFirstFreeAce [ADVAPI32.@]
810  */
811 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
812 {
813         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
814 }
815
816 /******************************************************************************
817  * GetAce [ADVAPI32.@]
818  */
819 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
820 {
821     CallWin32ToNt(RtlGetAce(pAcl, dwAceIndex, pAce));
822 }
823
824 /******************************************************************************
825  * GetAclInformation [ADVAPI32.@]
826  */
827 BOOL WINAPI GetAclInformation(
828   PACL pAcl,
829   LPVOID pAclInformation,
830   DWORD nAclInformationLength,
831   ACL_INFORMATION_CLASS dwAclInformationClass)
832 {
833         CallWin32ToNt(RtlQueryInformationAcl(pAcl, pAclInformation,
834                 nAclInformationLength, dwAclInformationClass));
835 }
836
837 /******************************************************************************
838  *  IsValidAcl [ADVAPI32.@]
839  */
840 BOOL WINAPI IsValidAcl(IN PACL pAcl)
841 {
842         return RtlValidAcl(pAcl);
843 }
844
845 /*      ##############################
846         ######  MISC FUNCTIONS  ######
847         ##############################
848 */
849
850 static const char * const DefaultPrivNames[] =
851 {
852     NULL, NULL,
853     "SeCreateTokenPrivilege", "SeAssignPrimaryTokenPrivilege",
854     "SeLockMemoryPrivilege", "SeIncreaseQuotaPrivilege",
855     "SeUnsolicitedInputPrivilege", "SeMachineAccountPrivilege",
856     "SeTcbPrivilege", "SeSecurityPrivilege",
857     "SeTakeOwnershipPrivilege", "SeLoadDriverPrivilege",
858     "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
859     "SeProfileSingleProcessPrivilege", "SeIncreaseBasePriorityPrivilege",
860     "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege",
861     "SeBackupPrivilege", "SeRestorePrivilege",
862     "SeShutdownPrivilege", "SeDebugPrivilege",
863     "SeAuditPrivilege", "SeSystemEnvironmentPrivilege",
864     "SeChangeNotifyPrivilege", "SeRemoteShutdownPrivilege",
865     "SeUndockPrivilege", "SeSyncAgentPrivilege",
866     "SeEnableDelegationPrivilege", "SeManageVolumePrivilege",
867     "SeImpersonatePrivilege", "SeCreateGlobalPrivilege",
868 };
869 #define NUMPRIVS (sizeof DefaultPrivNames/sizeof DefaultPrivNames[0])
870
871 /******************************************************************************
872  * LookupPrivilegeValueW                        [ADVAPI32.@]
873  *
874  * See LookupPrivilegeValueA.
875  */
876 BOOL WINAPI
877 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
878 {
879     UINT i;
880     WCHAR priv[0x28];
881
882     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
883
884     for( i=0; i<NUMPRIVS; i++ )
885     {
886         if( !DefaultPrivNames[i] )
887             continue;
888         MultiByteToWideChar( CP_ACP, 0, DefaultPrivNames[i], -1,
889                              priv, sizeof priv );
890         if( strcmpW( priv, lpName) )
891             continue;
892         lpLuid->LowPart = i;
893         lpLuid->HighPart = 0;
894         TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
895                lpLuid->HighPart, lpLuid->LowPart );
896         return TRUE;
897     }
898     return FALSE;
899 }
900
901 /******************************************************************************
902  * LookupPrivilegeValueA                        [ADVAPI32.@]
903  *
904  * Retrieves LUID used on a system to represent the privilege name.
905  *
906  * PARAMS
907  *  lpSystemName [I] Name of the system
908  *  lpName       [I] Name of the privilege
909  *  lpLuid       [O] Destination for the resulting LUID
910  *
911  * RETURNS
912  *  Success: TRUE. lpLuid contains the requested LUID.
913  *  Failure: FALSE.
914  */
915 BOOL WINAPI
916 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
917 {
918     UNICODE_STRING lpSystemNameW;
919     UNICODE_STRING lpNameW;
920     BOOL ret;
921
922     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
923     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
924     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
925     RtlFreeUnicodeString(&lpNameW);
926     RtlFreeUnicodeString(&lpSystemNameW);
927     return ret;
928 }
929
930
931 /******************************************************************************
932  * LookupPrivilegeNameA                 [ADVAPI32.@]
933  */
934 BOOL WINAPI
935 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName)
936 {
937     FIXME("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
938     return FALSE;
939 }
940
941 /******************************************************************************
942  * LookupPrivilegeNameW                 [ADVAPI32.@]
943  */
944 BOOL WINAPI
945 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName)
946 {
947     FIXME("%s %p %p %p\n", debugstr_w(lpSystemName), lpLuid, lpName, cchName);
948     return FALSE;
949 }
950
951 /******************************************************************************
952  * GetFileSecurityA [ADVAPI32.@]
953  *
954  * Obtains Specified information about the security of a file or directory.
955  *
956  * PARAMS
957  *  lpFileName           [I] Name of the file to get info for
958  *  RequestedInformation [I] SE_ flags from "winnt.h"
959  *  pSecurityDescriptor  [O] Destination for security information
960  *  nLength              [I] Length of pSecurityDescriptor
961  *  lpnLengthNeeded      [O] Destination for length of returned security information
962  *
963  * RETURNS
964  *  Success: TRUE. pSecurityDescriptor contains the requested information.
965  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
966  *
967  * NOTES
968  *  The information returned is constrained by the callers access rights and
969  *  privileges.
970  */
971 BOOL WINAPI
972 GetFileSecurityA( LPCSTR lpFileName,
973                     SECURITY_INFORMATION RequestedInformation,
974                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
975                     DWORD nLength, LPDWORD lpnLengthNeeded )
976 {
977   FIXME("(%s) : stub\n", debugstr_a(lpFileName));
978   return TRUE;
979 }
980
981 /******************************************************************************
982  * GetFileSecurityW [ADVAPI32.@]
983  *
984  * See GetFileSecurityA.
985  */
986 BOOL WINAPI
987 GetFileSecurityW( LPCWSTR lpFileName,
988                     SECURITY_INFORMATION RequestedInformation,
989                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
990                     DWORD nLength, LPDWORD lpnLengthNeeded )
991 {
992   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
993   return TRUE;
994 }
995
996
997 /******************************************************************************
998  * LookupAccountSidA [ADVAPI32.@]
999  */
1000 BOOL WINAPI
1001 LookupAccountSidA(
1002         IN LPCSTR system,
1003         IN PSID sid,
1004         OUT LPSTR account,
1005         IN OUT LPDWORD accountSize,
1006         OUT LPSTR domain,
1007         IN OUT LPDWORD domainSize,
1008         OUT PSID_NAME_USE name_use )
1009 {
1010         static const char ac[] = "Administrator";
1011         static const char dm[] = "DOMAIN";
1012         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1013               debugstr_a(system),sid,
1014               account,accountSize,accountSize?*accountSize:0,
1015               domain,domainSize,domainSize?*domainSize:0,
1016               name_use);
1017
1018         if (accountSize) *accountSize = strlen(ac)+1;
1019         if (account && (*accountSize > strlen(ac)))
1020           strcpy(account, ac);
1021
1022         if (domainSize) *domainSize = strlen(dm)+1;
1023         if (domain && (*domainSize > strlen(dm)))
1024           strcpy(domain,dm);
1025
1026         if (name_use) *name_use = SidTypeUser;
1027         return TRUE;
1028 }
1029
1030 /******************************************************************************
1031  * LookupAccountSidW [ADVAPI32.@]
1032  *
1033  * PARAMS
1034  *   system      []
1035  *   sid         []
1036  *   account     []
1037  *   accountSize []
1038  *   domain      []
1039  *   domainSize  []
1040  *   name_use    []
1041  */
1042 BOOL WINAPI
1043 LookupAccountSidW(
1044         IN LPCWSTR system,
1045         IN PSID sid,
1046         OUT LPWSTR account,
1047         IN OUT LPDWORD accountSize,
1048         OUT LPWSTR domain,
1049         IN OUT LPDWORD domainSize,
1050         OUT PSID_NAME_USE name_use )
1051 {
1052     static const WCHAR ac[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
1053     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1054         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1055               debugstr_w(system),sid,
1056               account,accountSize,accountSize?*accountSize:0,
1057               domain,domainSize,domainSize?*domainSize:0,
1058               name_use);
1059
1060         if (accountSize) *accountSize = strlenW(ac)+1;
1061         if (account && (*accountSize > strlenW(ac)))
1062             strcpyW(account, ac);
1063
1064         if (domainSize) *domainSize = strlenW(dm)+1;
1065         if (domain && (*domainSize > strlenW(dm)))
1066             strcpyW(domain,dm);
1067
1068         if (name_use) *name_use = SidTypeUser;
1069         return TRUE;
1070 }
1071
1072 /******************************************************************************
1073  * SetFileSecurityA [ADVAPI32.@]
1074  * Sets the security of a file or directory
1075  */
1076 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1077                                 SECURITY_INFORMATION RequestedInformation,
1078                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1079 {
1080   FIXME("(%s) : stub\n", debugstr_a(lpFileName));
1081   return TRUE;
1082 }
1083
1084 /******************************************************************************
1085  * SetFileSecurityW [ADVAPI32.@]
1086  * Sets the security of a file or directory
1087  *
1088  * PARAMS
1089  *   lpFileName           []
1090  *   RequestedInformation []
1091  *   pSecurityDescriptor  []
1092  */
1093 BOOL WINAPI
1094 SetFileSecurityW( LPCWSTR lpFileName,
1095                     SECURITY_INFORMATION RequestedInformation,
1096                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
1097 {
1098   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1099   return TRUE;
1100 }
1101
1102 /******************************************************************************
1103  * QueryWindows31FilesMigration [ADVAPI32.@]
1104  *
1105  * PARAMS
1106  *   x1 []
1107  */
1108 BOOL WINAPI
1109 QueryWindows31FilesMigration( DWORD x1 )
1110 {
1111         FIXME("(%ld):stub\n",x1);
1112         return TRUE;
1113 }
1114
1115 /******************************************************************************
1116  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1117  *
1118  * PARAMS
1119  *   x1 []
1120  *   x2 []
1121  *   x3 []
1122  *   x4 []
1123  */
1124 BOOL WINAPI
1125 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1126                                                DWORD x4 )
1127 {
1128         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1129         return TRUE;
1130 }
1131
1132 /******************************************************************************
1133  * LsaOpenPolicy [ADVAPI32.@]
1134  *
1135  * PARAMS
1136  *   x1 []
1137  *   x2 []
1138  *   x3 []
1139  *   x4 []
1140  */
1141 NTSTATUS WINAPI
1142 LsaOpenPolicy(
1143         IN PLSA_UNICODE_STRING SystemName,
1144         IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
1145         IN ACCESS_MASK DesiredAccess,
1146         IN OUT PLSA_HANDLE PolicyHandle)
1147 {
1148         FIXME("(%s,%p,0x%08lx,%p):stub\n",
1149               SystemName?debugstr_w(SystemName->Buffer):"null",
1150               ObjectAttributes, DesiredAccess, PolicyHandle);
1151         ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
1152                                   STATUS_ACCESS_VIOLATION);
1153         dumpLsaAttributes(ObjectAttributes);
1154         if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
1155         return STATUS_SUCCESS;
1156 }
1157
1158 /******************************************************************************
1159  * LsaQueryInformationPolicy [ADVAPI32.@]
1160  */
1161 NTSTATUS WINAPI
1162 LsaQueryInformationPolicy(
1163         IN LSA_HANDLE PolicyHandle,
1164         IN POLICY_INFORMATION_CLASS InformationClass,
1165         OUT PVOID *Buffer)
1166 {
1167         FIXME("(%p,0x%08x,%p):stub\n",
1168               PolicyHandle, InformationClass, Buffer);
1169
1170         if(!Buffer) return FALSE;
1171         switch (InformationClass)
1172         {
1173           case PolicyAuditEventsInformation: /* 2 */
1174             {
1175               PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POLICY_AUDIT_EVENTS_INFO));
1176               p->AuditingMode = FALSE; /* no auditing */
1177               *Buffer = p;
1178             }
1179             break;
1180           case PolicyPrimaryDomainInformation: /* 3 */
1181           case PolicyAccountDomainInformation: /* 5 */
1182             {
1183               struct di
1184               { POLICY_PRIMARY_DOMAIN_INFO ppdi;
1185                 SID sid;
1186               };
1187               SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
1188
1189               struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(xdi));
1190               HKEY key;
1191               BOOL useDefault = TRUE;
1192               LONG ret;
1193
1194               if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1195                "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
1196                KEY_READ, &key)) == ERROR_SUCCESS)
1197               {
1198                   DWORD size = 0;
1199                   static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
1200
1201                   ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
1202                   if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
1203                   {
1204                       xdi->ppdi.Name.Buffer = HeapAlloc(GetProcessHeap(),
1205                        HEAP_ZERO_MEMORY, size);
1206                       if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
1207                        (LPBYTE)xdi->ppdi.Name.Buffer, &size)) == ERROR_SUCCESS)
1208                       {
1209                           xdi->ppdi.Name.Length = (USHORT)size;
1210                           useDefault = FALSE;
1211                       }
1212                       else
1213                       {
1214                           HeapFree(GetProcessHeap(), 0, xdi->ppdi.Name.Buffer);
1215                           xdi->ppdi.Name.Buffer = NULL;
1216                       }
1217                   }
1218                   RegCloseKey(key);
1219               }
1220               if (useDefault)
1221                   RtlCreateUnicodeStringFromAsciiz(&(xdi->ppdi.Name), "DOMAIN");
1222               TRACE("setting domain to %s\n", debugstr_w(xdi->ppdi.Name.Buffer));
1223
1224               xdi->ppdi.Sid = &(xdi->sid);
1225               xdi->sid.Revision = SID_REVISION;
1226               xdi->sid.SubAuthorityCount = 1;
1227               xdi->sid.IdentifierAuthority = localSidAuthority;
1228               xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
1229               *Buffer = xdi;
1230             }
1231             break;
1232           case  PolicyAuditLogInformation:
1233           case  PolicyPdAccountInformation:
1234           case  PolicyLsaServerRoleInformation:
1235           case  PolicyReplicaSourceInformation:
1236           case  PolicyDefaultQuotaInformation:
1237           case  PolicyModificationInformation:
1238           case  PolicyAuditFullSetInformation:
1239           case  PolicyAuditFullQueryInformation:
1240           case  PolicyDnsDomainInformation:
1241             {
1242               FIXME("category not implemented\n");
1243               return FALSE;
1244             }
1245         }
1246         return TRUE;
1247 }
1248
1249 /******************************************************************************
1250  * LsaLookupSids [ADVAPI32.@]
1251  */
1252 typedef struct
1253 {
1254         SID_NAME_USE Use;
1255         LSA_UNICODE_STRING Name;
1256         LONG DomainIndex;
1257 } LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME;
1258
1259 typedef struct
1260 {
1261         LSA_UNICODE_STRING Name;
1262         PSID Sid;
1263 } LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;
1264
1265 typedef struct
1266 {
1267         ULONG Entries;
1268         PLSA_TRUST_INFORMATION Domains;
1269 } LSA_REFERENCED_DOMAIN_LIST, *PLSA_REFERENCED_DOMAIN_LIST;
1270
1271 NTSTATUS WINAPI
1272 LsaLookupSids(
1273         IN LSA_HANDLE PolicyHandle,
1274         IN ULONG Count,
1275         IN PSID *Sids,
1276         OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1277         OUT PLSA_TRANSLATED_NAME *Names )
1278 {
1279         FIXME("%p %lu %p %p %p\n",
1280           PolicyHandle, Count, Sids, ReferencedDomains, Names);
1281         return FALSE;
1282 }
1283
1284 /******************************************************************************
1285  * LsaFreeMemory [ADVAPI32.@]
1286  */
1287 NTSTATUS WINAPI
1288 LsaFreeMemory(IN PVOID Buffer)
1289 {
1290         TRACE("(%p)\n",Buffer);
1291         return HeapFree(GetProcessHeap(), 0, Buffer);
1292 }
1293 /******************************************************************************
1294  * LsaClose [ADVAPI32.@]
1295  */
1296 NTSTATUS WINAPI
1297 LsaClose(IN LSA_HANDLE ObjectHandle)
1298 {
1299         FIXME("(%p):stub\n",ObjectHandle);
1300         return 0xc0000000;
1301 }
1302
1303 /******************************************************************************
1304  * LsaNtStatusToWinError [ADVAPI32.@]
1305  *
1306  * PARAMS
1307  *   Status [I]
1308  */
1309 ULONG WINAPI
1310 LsaNtStatusToWinError(NTSTATUS Status)
1311 {
1312     return RtlNtStatusToDosError(Status);
1313 }
1314
1315 /******************************************************************************
1316  * NotifyBootConfigStatus [ADVAPI32.@]
1317  *
1318  * PARAMS
1319  *   x1 []
1320  */
1321 BOOL WINAPI
1322 NotifyBootConfigStatus( DWORD x1 )
1323 {
1324         FIXME("(0x%08lx):stub\n",x1);
1325         return 1;
1326 }
1327
1328 /******************************************************************************
1329  * RevertToSelf [ADVAPI32.@]
1330  *
1331  * PARAMS
1332  *   void []
1333  */
1334 BOOL WINAPI
1335 RevertToSelf( void )
1336 {
1337         FIXME("(), stub\n");
1338         return TRUE;
1339 }
1340
1341 /******************************************************************************
1342  * ImpersonateSelf [ADVAPI32.@]
1343  */
1344 BOOL WINAPI
1345 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1346 {
1347         return RtlImpersonateSelf(ImpersonationLevel);
1348 }
1349
1350 /******************************************************************************
1351  * ImpersonateLoggedOnUser [ADVAPI32.@]
1352  */
1353 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1354 {
1355     FIXME("(%p):stub returning FALSE\n", hToken);
1356     return FALSE;
1357 }
1358
1359 /******************************************************************************
1360  * AccessCheck [ADVAPI32.@]
1361  *
1362  * FIXME check cast LPBOOL to PBOOLEAN
1363  */
1364 BOOL WINAPI
1365 AccessCheck(
1366         PSECURITY_DESCRIPTOR SecurityDescriptor,
1367         HANDLE ClientToken,
1368         DWORD DesiredAccess,
1369         PGENERIC_MAPPING GenericMapping,
1370         PPRIVILEGE_SET PrivilegeSet,
1371         LPDWORD PrivilegeSetLength,
1372         LPDWORD GrantedAccess,
1373         LPBOOL AccessStatus)
1374 {
1375         CallWin32ToNt (NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1376           GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
1377 }
1378
1379
1380 /******************************************************************************
1381  * AccessCheckByType [ADVAPI32.@]
1382  */
1383 BOOL WINAPI AccessCheckByType(
1384     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1385     PSID PrincipalSelfSid,
1386     HANDLE ClientToken, 
1387     DWORD DesiredAccess, 
1388     POBJECT_TYPE_LIST ObjectTypeList,
1389     DWORD ObjectTypeListLength,
1390     PGENERIC_MAPPING GenericMapping,
1391     PPRIVILEGE_SET PrivilegeSet,
1392     LPDWORD PrivilegeSetLength, 
1393     LPDWORD GrantedAccess,
1394     LPBOOL AccessStatus)
1395 {
1396         FIXME("stub\n");
1397
1398         *AccessStatus = TRUE;
1399
1400         return !*AccessStatus;
1401 }
1402
1403
1404 /*************************************************************************
1405  * SetKernelObjectSecurity [ADVAPI32.@]
1406  */
1407 BOOL WINAPI SetKernelObjectSecurity (
1408         IN HANDLE Handle,
1409         IN SECURITY_INFORMATION SecurityInformation,
1410         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1411 {
1412         CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1413 }
1414
1415
1416 /******************************************************************************
1417  *  AddAuditAccessAce [ADVAPI32.@]
1418  */
1419 BOOL WINAPI AddAuditAccessAce(
1420         IN OUT PACL pAcl,
1421         IN DWORD dwAceRevision,
1422         IN DWORD dwAccessMask,
1423         IN PSID pSid,
1424         IN BOOL bAuditSuccess,
1425         IN BOOL bAuditFailure)
1426 {
1427         FIXME("Stub\n");
1428         return TRUE;
1429 }
1430
1431 /******************************************************************************
1432  * LookupAccountNameA [ADVAPI32.@]
1433  */
1434 BOOL WINAPI
1435 LookupAccountNameA(
1436         IN LPCSTR system,
1437         IN LPCSTR account,
1438         OUT PSID sid,
1439         OUT LPDWORD cbSid,
1440         LPSTR ReferencedDomainName,
1441         IN OUT LPDWORD cbReferencedDomainName,
1442         OUT PSID_NAME_USE name_use )
1443 {
1444     FIXME("(%s,%s,%p,%p,%p,%p,%p), stub.\n",system,account,sid,cbSid,ReferencedDomainName,cbReferencedDomainName,name_use);
1445     return FALSE;
1446 }
1447
1448 /******************************************************************************
1449  * PrivilegeCheck [ADVAPI32.@]
1450  */
1451 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1452 {
1453         FIXME("stub %p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1454         if (pfResult)
1455                 *pfResult=TRUE;
1456         return TRUE;
1457 }
1458
1459 /******************************************************************************
1460  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1461  */
1462 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1463   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1464   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1465   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1466 {
1467         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1468                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1469                 SecurityDescriptor, DesiredAccess, GenericMapping,
1470                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1471         return TRUE;
1472 }
1473
1474 /******************************************************************************
1475  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1476  */
1477 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1478   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1479   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1480   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1481 {
1482         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1483                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1484                 SecurityDescriptor, DesiredAccess, GenericMapping,
1485                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1486         return TRUE;
1487 }
1488
1489
1490 /******************************************************************************
1491  * GetSecurityInfoExW [ADVAPI32.@]
1492  */
1493 DWORD WINAPI GetSecurityInfoExW(
1494         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
1495         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
1496         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
1497         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
1498 )
1499 {
1500   FIXME("stub!\n");
1501   return ERROR_BAD_PROVIDER; 
1502 }
1503
1504 /******************************************************************************
1505  * BuildTrusteeWithSidA [ADVAPI32.@]
1506  */
1507 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
1508 {
1509     FIXME("%p %p\n", pTrustee, pSid);
1510 }
1511
1512 /******************************************************************************
1513  * BuildTrusteeWithSidW [ADVAPI32.@]
1514  */
1515 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
1516 {
1517     FIXME("%p %p\n", pTrustee, pSid);
1518 }
1519
1520 /******************************************************************************
1521  * SetEntriesInAclA [ADVAPI32.@]
1522  */
1523 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
1524                                PACL OldAcl, PACL* NewAcl )
1525 {
1526     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1527     return ERROR_CALL_NOT_IMPLEMENTED;
1528 }
1529
1530 /******************************************************************************
1531  * SetEntriesInAclW [ADVAPI32.@]
1532  */
1533 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
1534                                PACL OldAcl, PACL* NewAcl )
1535 {
1536     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1537     return ERROR_CALL_NOT_IMPLEMENTED;
1538 }
1539
1540 /******************************************************************************
1541  * SetNamedSecurityInfoA [ADVAPI32.@]
1542  */
1543 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
1544         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1545         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1546 {
1547     FIXME("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
1548            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1549     return ERROR_CALL_NOT_IMPLEMENTED;
1550 }
1551
1552 /******************************************************************************
1553  * AreAnyAccessesGranted [ADVAPI32.@]
1554  *
1555  * Determines whether or not any of a set of specified access permissions have
1556  * been granted or not.
1557  *
1558  * PARAMS
1559  *   GrantedAccess [I] The permissions that have been granted.
1560  *   DesiredAccess [I] The permissions that you want to have.
1561  *
1562  * RETURNS
1563  *   Nonzero if any of the permissions have been granted, zero if none of the
1564  *   permissions have been granted.
1565  */
1566
1567 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
1568 {
1569     return (GrantedAccess & DesiredAccess) != 0;
1570 }
1571
1572 /******************************************************************************
1573  * SetNamedSecurityInfoW [ADVAPI32.@]
1574  */
1575 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
1576         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1577         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1578 {
1579     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
1580            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1581     return ERROR_CALL_NOT_IMPLEMENTED;
1582 }
1583
1584 /******************************************************************************
1585  * GetExplicitEntriesFromAclA [ADVAPI32.@]
1586  */
1587 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
1588         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
1589 {
1590     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1591     return ERROR_CALL_NOT_IMPLEMENTED;
1592 }
1593
1594 /******************************************************************************
1595  * GetExplicitEntriesFromAclW [ADVAPI32.@]
1596  */
1597 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
1598         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
1599 {
1600     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1601     return ERROR_CALL_NOT_IMPLEMENTED;
1602 }
1603
1604
1605 /******************************************************************************
1606  * ParseAclStringFlags
1607  */
1608 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
1609 {
1610     DWORD flags = 0;
1611     LPCWSTR szAcl = *StringAcl;
1612
1613     while (*szAcl != '(')
1614     {
1615         if (*szAcl == 'P')
1616         {
1617             flags |= SE_DACL_PROTECTED;
1618         }
1619         else if (*szAcl == 'A')
1620         {
1621             szAcl++;
1622             if (*szAcl == 'R')
1623                 flags |= SE_DACL_AUTO_INHERIT_REQ;
1624             else if (*szAcl == 'I')
1625                 flags |= SE_DACL_AUTO_INHERITED;
1626         }
1627         szAcl++;
1628     }
1629
1630     *StringAcl = szAcl;
1631     return flags;
1632 }
1633
1634 /******************************************************************************
1635  * ParseAceStringType
1636  */
1637 ACEFLAG AceType[] =
1638 {
1639     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
1640     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
1641     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
1642     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
1643     /*
1644     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
1645     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
1646     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
1647     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
1648     */
1649     { NULL, 0 },
1650 };
1651
1652 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
1653 {
1654     UINT len = 0;
1655     LPCWSTR szAcl = *StringAcl;
1656     LPACEFLAG lpaf = AceType;
1657
1658     while (lpaf->wstr &&
1659         (len = strlenW(lpaf->wstr)) &&
1660         strncmpW(lpaf->wstr, szAcl, len))
1661         lpaf++;
1662
1663     if (!lpaf->wstr)
1664         return 0;
1665
1666     *StringAcl += len;
1667     return lpaf->value;
1668 }
1669
1670
1671 /******************************************************************************
1672  * ParseAceStringFlags
1673  */
1674 ACEFLAG AceFlags[] =
1675 {
1676     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
1677     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
1678     { SDDL_INHERITED,         INHERITED_ACE },
1679     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
1680     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
1681     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
1682     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
1683     { NULL, 0 },
1684 };
1685
1686 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
1687 {
1688     UINT len = 0;
1689     BYTE flags = 0;
1690     LPCWSTR szAcl = *StringAcl;
1691
1692     while (*szAcl != ';')
1693     {
1694         LPACEFLAG lpaf = AceFlags;
1695
1696         while (lpaf->wstr &&
1697                (len = strlenW(lpaf->wstr)) &&
1698                strncmpW(lpaf->wstr, szAcl, len))
1699             lpaf++;
1700
1701         if (!lpaf->wstr)
1702             return 0;
1703
1704         flags |= lpaf->value;
1705         szAcl += len;
1706     }
1707
1708     *StringAcl = szAcl;
1709     return flags;
1710 }
1711
1712
1713 /******************************************************************************
1714  * ParseAceStringRights
1715  */
1716 ACEFLAG AceRights[] =
1717 {
1718     { SDDL_GENERIC_ALL,     GENERIC_ALL },
1719     { SDDL_GENERIC_READ,    GENERIC_READ },
1720     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
1721     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
1722     { SDDL_READ_CONTROL,    READ_CONTROL },
1723     { SDDL_STANDARD_DELETE, DELETE },
1724     { SDDL_WRITE_DAC,       WRITE_DAC },
1725     { SDDL_WRITE_OWNER,     WRITE_OWNER },
1726     { NULL, 0 },
1727 };
1728
1729 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
1730 {
1731     UINT len = 0;
1732     DWORD rights = 0;
1733     LPCWSTR szAcl = *StringAcl;
1734
1735     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
1736     {
1737         LPCWSTR p = szAcl;
1738
1739         while (*p && *p != ';')
1740             p++;
1741
1742         if (p - szAcl <= 8)
1743         {
1744             rights = strtoulW(szAcl, NULL, 16);
1745             *StringAcl = p;
1746         }
1747         else
1748             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
1749     }
1750     else
1751     {
1752         while (*szAcl != ';')
1753         {
1754             LPACEFLAG lpaf = AceRights;
1755
1756             while (lpaf->wstr &&
1757                (len = strlenW(lpaf->wstr)) &&
1758                strncmpW(lpaf->wstr, szAcl, len))
1759             {
1760                lpaf++;
1761             }
1762
1763             if (!lpaf->wstr)
1764                 return 0;
1765
1766             rights |= lpaf->value;
1767             szAcl += len;
1768         }
1769     }
1770
1771     *StringAcl = szAcl;
1772     return rights;
1773 }
1774
1775
1776 /******************************************************************************
1777  * ParseStringAclToAcl
1778  * 
1779  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
1780  */
1781 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
1782     PACL pAcl, LPDWORD cBytes)
1783 {
1784     DWORD val;
1785     DWORD sidlen;
1786     DWORD length = sizeof(ACL);
1787     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
1788
1789     TRACE("%s\n", debugstr_w(StringAcl));
1790
1791     if (!StringAcl)
1792         return FALSE;
1793
1794     if (pAcl) /* pAce is only useful if we're setting values */
1795         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
1796
1797     /* Parse ACL flags */
1798     *lpdwFlags = ParseAclStringFlags(&StringAcl);
1799
1800     /* Parse ACE */
1801     while (*StringAcl == '(')
1802     {
1803         StringAcl++;
1804
1805         /* Parse ACE type */
1806         val = ParseAceStringType(&StringAcl);
1807         if (pAce)
1808             pAce->Header.AceType = (BYTE) val;
1809         if (*StringAcl != ';')
1810             goto lerr;
1811         StringAcl++;
1812
1813         /* Parse ACE flags */
1814         val = ParseAceStringFlags(&StringAcl);
1815         if (pAce)
1816             pAce->Header.AceFlags = (BYTE) val;
1817         if (*StringAcl != ';')
1818             goto lerr;
1819         StringAcl++;
1820
1821         /* Parse ACE rights */
1822         val = ParseAceStringRights(&StringAcl);
1823         if (pAce)
1824             pAce->Mask = val;
1825         if (*StringAcl != ';')
1826             goto lerr;
1827         StringAcl++;
1828
1829         /* Parse ACE object guid */
1830         if (*StringAcl != ';')
1831         {
1832             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1833             goto lerr;
1834         }
1835         StringAcl++;
1836
1837         /* Parse ACE inherit object guid */
1838         if (*StringAcl != ';')
1839         {
1840             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1841             goto lerr;
1842         }
1843         StringAcl++;
1844
1845         /* Parse ACE account sid */
1846         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
1847         {
1848             while (*StringAcl && *StringAcl != ')')
1849                 StringAcl++;
1850         }
1851
1852         if (*StringAcl != ')')
1853             goto lerr;
1854         StringAcl++;
1855
1856         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
1857     }
1858
1859     *cBytes = length;
1860     return TRUE;
1861
1862 lerr:
1863     WARN("Invalid ACE string format\n");
1864     return FALSE;
1865 }
1866
1867
1868 /******************************************************************************
1869  * ParseStringSecurityDescriptorToSecurityDescriptor
1870  */
1871 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
1872     LPCWSTR StringSecurityDescriptor,
1873     PSECURITY_DESCRIPTOR SecurityDescriptor,
1874     LPDWORD cBytes)
1875 {
1876     BOOL bret = FALSE;
1877     WCHAR toktype;
1878     WCHAR tok[MAX_PATH];
1879     LPCWSTR lptoken;
1880     LPBYTE lpNext = NULL;
1881
1882     *cBytes = 0;
1883
1884     if (SecurityDescriptor)
1885         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
1886
1887     while (*StringSecurityDescriptor)
1888     {
1889         toktype = *StringSecurityDescriptor;
1890
1891         /* Expect char identifier followed by ':' */
1892         StringSecurityDescriptor++;
1893         if (*StringSecurityDescriptor != ':')
1894         {
1895             SetLastError(ERROR_INVALID_PARAMETER);
1896             goto lend;
1897         }
1898         StringSecurityDescriptor++;
1899
1900         /* Extract token */
1901         lptoken = StringSecurityDescriptor;
1902         while (*lptoken && *lptoken != ':')
1903             lptoken++;
1904
1905         if (*lptoken)
1906             lptoken--;
1907
1908         strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
1909
1910         switch (toktype)
1911         {
1912             case 'O':
1913             {
1914                 DWORD bytes;
1915
1916                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
1917                     goto lend;
1918
1919                 if (SecurityDescriptor)
1920                 {
1921                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
1922                         (DWORD) SecurityDescriptor);
1923                     lpNext += bytes; /* Advance to next token */
1924                 }
1925
1926                 *cBytes += bytes;
1927
1928                 break;
1929             }
1930
1931             case 'G':
1932             {
1933                 DWORD bytes;
1934
1935                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
1936                     goto lend;
1937
1938                 if (SecurityDescriptor)
1939                 {
1940                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
1941                         (DWORD) SecurityDescriptor);
1942                     lpNext += bytes; /* Advance to next token */
1943                 }
1944
1945                 *cBytes += bytes;
1946
1947                 break;
1948             }
1949
1950             case 'D':
1951             {
1952                 DWORD flags;
1953                 DWORD bytes;
1954
1955                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
1956                     goto lend;
1957
1958                 if (SecurityDescriptor)
1959                 {
1960                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
1961                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
1962                         (DWORD) SecurityDescriptor);
1963                     lpNext += bytes; /* Advance to next token */
1964                 }
1965
1966                 *cBytes += bytes;
1967
1968                 break;
1969             }
1970
1971             case 'S':
1972             {
1973                 DWORD flags;
1974                 DWORD bytes;
1975
1976                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
1977                     goto lend;
1978
1979                 if (SecurityDescriptor)
1980                 {
1981                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
1982                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
1983                         (DWORD) SecurityDescriptor);
1984                     lpNext += bytes; /* Advance to next token */
1985                 }
1986
1987                 *cBytes += bytes;
1988
1989                 break;
1990             }
1991
1992             default:
1993                 FIXME("Unknown token\n");
1994                 SetLastError(ERROR_INVALID_PARAMETER);
1995                 goto lend;
1996         }
1997
1998         StringSecurityDescriptor = lptoken;
1999     }
2000
2001     bret = TRUE;
2002
2003 lend:
2004     return bret;
2005 }
2006
2007 /******************************************************************************
2008  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2009  */
2010 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2011         LPCWSTR StringSecurityDescriptor,
2012         DWORD StringSDRevision,
2013         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2014         PULONG SecurityDescriptorSize)
2015 {
2016     DWORD cBytes;
2017     PSECURITY_DESCRIPTOR psd;
2018     BOOL bret = FALSE;
2019
2020     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2021
2022     if (GetVersion() & 0x80000000)
2023     {
2024         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2025         goto lend;
2026     }
2027     else if (StringSDRevision != SID_REVISION)
2028     {
2029         SetLastError(ERROR_UNKNOWN_REVISION);
2030         goto lend;
2031     }
2032
2033     /* Compute security descriptor length */
2034     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2035         NULL, &cBytes))
2036         goto lend;
2037
2038     psd = *SecurityDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(
2039         GMEM_ZEROINIT, cBytes);
2040
2041     psd->Revision = SID_REVISION;
2042     psd->Control |= SE_SELF_RELATIVE;
2043
2044     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2045         psd, &cBytes))
2046     {
2047         LocalFree(psd);
2048         goto lend;
2049     }
2050
2051     if (SecurityDescriptorSize)
2052         *SecurityDescriptorSize = cBytes;
2053
2054     bret = TRUE;
2055  
2056 lend:
2057     TRACE(" ret=%d\n", bret);
2058     return bret;
2059 }
2060
2061 /******************************************************************************
2062  * ConvertStringSidToSidW [ADVAPI32.@]
2063  */
2064 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
2065 {
2066     BOOL bret = FALSE;
2067     DWORD cBytes;
2068
2069     if (GetVersion() & 0x80000000)
2070         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2071     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
2072     {
2073         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
2074
2075         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
2076         if (!bret)
2077             LocalFree(*Sid); 
2078     }
2079
2080     return bret;
2081 }
2082
2083 /******************************************************************************
2084  * ComputeStringSidSize
2085  */
2086 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
2087 {
2088     int ctok = 0;
2089     DWORD size = sizeof(SID);
2090
2091     while (*StringSid)
2092     {
2093         if (*StringSid == '-')
2094             ctok++;
2095         StringSid++;
2096     }
2097
2098     if (ctok > 3)
2099         size += (ctok - 3) * sizeof(DWORD);
2100
2101     return size;
2102 }
2103
2104 /******************************************************************************
2105  * ParseStringSidToSid
2106  */
2107 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
2108 {
2109     BOOL bret = FALSE;
2110
2111     if (!StringSid)
2112     {
2113         SetLastError(ERROR_INVALID_PARAMETER);
2114         return FALSE;
2115     }
2116
2117     *cBytes = ComputeStringSidSize(StringSid);
2118     if (!pSid) /* Simply compute the size */
2119         return TRUE;
2120
2121     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
2122     {
2123         int i = 0;
2124         int csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
2125
2126         StringSid += 2; /* Advance to Revision */
2127         pSid->Revision = atoiW(StringSid);
2128
2129         if (pSid->Revision != SDDL_REVISION)
2130            goto lend; /* ERROR_INVALID_SID */
2131
2132         pSid->SubAuthorityCount = csubauth;
2133
2134         while (*StringSid && *StringSid != '-')
2135             StringSid++; /* Advance to identifier authority */
2136
2137         pSid->IdentifierAuthority.Value[5] = atoiW(StringSid);
2138
2139         if (pSid->IdentifierAuthority.Value[5] > 5)
2140             goto lend; /* ERROR_INVALID_SID */
2141     
2142         while (*StringSid)
2143         {       
2144             while (*StringSid && *StringSid != '-')
2145                 StringSid++;
2146
2147             pSid->SubAuthority[i++] = atoiW(StringSid);
2148         }
2149
2150         if (i != pSid->SubAuthorityCount)
2151             goto lend; /* ERROR_INVALID_SID */
2152
2153         bret = TRUE;
2154     }
2155     else /* String constant format  - Only available in winxp and above */
2156     {
2157         pSid->Revision = SDDL_REVISION;
2158         pSid->SubAuthorityCount = 1;
2159
2160         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
2161
2162         /* TODO: Lookup string of well-known SIDs in table */
2163         pSid->IdentifierAuthority.Value[5] = 0;
2164         pSid->SubAuthority[0] = 0;
2165
2166         bret = TRUE;
2167     }
2168
2169 lend:
2170     if (!bret)
2171         SetLastError(ERROR_INVALID_SID);
2172
2173     return bret;
2174 }
2175
2176 /******************************************************************************
2177  * GetNamedSecurityInfoA [ADVAPI32.@]
2178  */
2179 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
2180         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2181         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2182         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2183 {
2184     FIXME("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
2185         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2186     return ERROR_CALL_NOT_IMPLEMENTED;
2187 }
2188
2189 /******************************************************************************
2190  * GetNamedSecurityInfoW [ADVAPI32.@]
2191  */
2192 DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
2193         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2194         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2195         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2196 {
2197     FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
2198         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2199     return ERROR_CALL_NOT_IMPLEMENTED;
2200 }