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