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