Define COBJMACROS. Fixes compilation on Windows.
[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 = TRUSTEE_IS_SID;
1523     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1524     pTrustee->ptstrName = (LPSTR) pSid;
1525 }
1526
1527 /******************************************************************************
1528  * BuildTrusteeWithSidW [ADVAPI32.@]
1529  */
1530 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
1531 {
1532     TRACE("%p %p\n", pTrustee, pSid);
1533
1534     pTrustee->pMultipleTrustee = NULL;
1535     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1536     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
1537     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1538     pTrustee->ptstrName = (LPWSTR) pSid;
1539 }
1540
1541 /******************************************************************************
1542  * BuildTrusteeWithNameA [ADVAPI32.@]
1543  */
1544 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
1545 {
1546     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
1547
1548     pTrustee->pMultipleTrustee = NULL;
1549     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1550     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1551     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1552     pTrustee->ptstrName = name;
1553 }
1554
1555 /******************************************************************************
1556  * BuildTrusteeWithNameW [ADVAPI32.@]
1557  */
1558 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
1559 {
1560     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
1561
1562     pTrustee->pMultipleTrustee = NULL;
1563     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1564     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1565     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1566     pTrustee->ptstrName = name;
1567 }
1568
1569 /******************************************************************************
1570  * SetEntriesInAclA [ADVAPI32.@]
1571  */
1572 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
1573                                PACL OldAcl, PACL* NewAcl )
1574 {
1575     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1576     return ERROR_CALL_NOT_IMPLEMENTED;
1577 }
1578
1579 /******************************************************************************
1580  * SetEntriesInAclW [ADVAPI32.@]
1581  */
1582 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
1583                                PACL OldAcl, PACL* NewAcl )
1584 {
1585     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1586     return ERROR_CALL_NOT_IMPLEMENTED;
1587 }
1588
1589 /******************************************************************************
1590  * SetNamedSecurityInfoA [ADVAPI32.@]
1591  */
1592 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
1593         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1594         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1595 {
1596     DWORD len;
1597     LPWSTR wstr = NULL;
1598     DWORD r;
1599
1600     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
1601            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1602
1603     if( pObjectName )
1604     {
1605         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
1606         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
1607         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
1608     }
1609
1610     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
1611                            psidGroup, pDacl, pSacl );
1612
1613     if( wstr )
1614         HeapFree( GetProcessHeap(), 0, wstr );
1615
1616     return r;
1617 }
1618
1619 /******************************************************************************
1620  * AreAnyAccessesGranted [ADVAPI32.@]
1621  *
1622  * Determines whether or not any of a set of specified access permissions have
1623  * been granted or not.
1624  *
1625  * PARAMS
1626  *   GrantedAccess [I] The permissions that have been granted.
1627  *   DesiredAccess [I] The permissions that you want to have.
1628  *
1629  * RETURNS
1630  *   Nonzero if any of the permissions have been granted, zero if none of the
1631  *   permissions have been granted.
1632  */
1633
1634 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
1635 {
1636     return (GrantedAccess & DesiredAccess) != 0;
1637 }
1638
1639 /******************************************************************************
1640  * SetNamedSecurityInfoW [ADVAPI32.@]
1641  */
1642 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
1643         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1644         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1645 {
1646     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
1647            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1648     return ERROR_CALL_NOT_IMPLEMENTED;
1649 }
1650
1651 /******************************************************************************
1652  * GetExplicitEntriesFromAclA [ADVAPI32.@]
1653  */
1654 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
1655         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
1656 {
1657     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1658     return ERROR_CALL_NOT_IMPLEMENTED;
1659 }
1660
1661 /******************************************************************************
1662  * GetExplicitEntriesFromAclW [ADVAPI32.@]
1663  */
1664 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
1665         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
1666 {
1667     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1668     return ERROR_CALL_NOT_IMPLEMENTED;
1669 }
1670
1671
1672 /******************************************************************************
1673  * ParseAclStringFlags
1674  */
1675 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
1676 {
1677     DWORD flags = 0;
1678     LPCWSTR szAcl = *StringAcl;
1679
1680     while (*szAcl != '(')
1681     {
1682         if (*szAcl == 'P')
1683         {
1684             flags |= SE_DACL_PROTECTED;
1685         }
1686         else if (*szAcl == 'A')
1687         {
1688             szAcl++;
1689             if (*szAcl == 'R')
1690                 flags |= SE_DACL_AUTO_INHERIT_REQ;
1691             else if (*szAcl == 'I')
1692                 flags |= SE_DACL_AUTO_INHERITED;
1693         }
1694         szAcl++;
1695     }
1696
1697     *StringAcl = szAcl;
1698     return flags;
1699 }
1700
1701 /******************************************************************************
1702  * ParseAceStringType
1703  */
1704 ACEFLAG AceType[] =
1705 {
1706     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
1707     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
1708     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
1709     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
1710     /*
1711     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
1712     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
1713     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
1714     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
1715     */
1716     { NULL, 0 },
1717 };
1718
1719 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
1720 {
1721     UINT len = 0;
1722     LPCWSTR szAcl = *StringAcl;
1723     LPACEFLAG lpaf = AceType;
1724
1725     while (lpaf->wstr &&
1726         (len = strlenW(lpaf->wstr)) &&
1727         strncmpW(lpaf->wstr, szAcl, len))
1728         lpaf++;
1729
1730     if (!lpaf->wstr)
1731         return 0;
1732
1733     *StringAcl += len;
1734     return lpaf->value;
1735 }
1736
1737
1738 /******************************************************************************
1739  * ParseAceStringFlags
1740  */
1741 ACEFLAG AceFlags[] =
1742 {
1743     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
1744     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
1745     { SDDL_INHERITED,         INHERITED_ACE },
1746     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
1747     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
1748     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
1749     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
1750     { NULL, 0 },
1751 };
1752
1753 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
1754 {
1755     UINT len = 0;
1756     BYTE flags = 0;
1757     LPCWSTR szAcl = *StringAcl;
1758
1759     while (*szAcl != ';')
1760     {
1761         LPACEFLAG lpaf = AceFlags;
1762
1763         while (lpaf->wstr &&
1764                (len = strlenW(lpaf->wstr)) &&
1765                strncmpW(lpaf->wstr, szAcl, len))
1766             lpaf++;
1767
1768         if (!lpaf->wstr)
1769             return 0;
1770
1771         flags |= lpaf->value;
1772         szAcl += len;
1773     }
1774
1775     *StringAcl = szAcl;
1776     return flags;
1777 }
1778
1779
1780 /******************************************************************************
1781  * ParseAceStringRights
1782  */
1783 ACEFLAG AceRights[] =
1784 {
1785     { SDDL_GENERIC_ALL,     GENERIC_ALL },
1786     { SDDL_GENERIC_READ,    GENERIC_READ },
1787     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
1788     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
1789     { SDDL_READ_CONTROL,    READ_CONTROL },
1790     { SDDL_STANDARD_DELETE, DELETE },
1791     { SDDL_WRITE_DAC,       WRITE_DAC },
1792     { SDDL_WRITE_OWNER,     WRITE_OWNER },
1793     { NULL, 0 },
1794 };
1795
1796 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
1797 {
1798     UINT len = 0;
1799     DWORD rights = 0;
1800     LPCWSTR szAcl = *StringAcl;
1801
1802     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
1803     {
1804         LPCWSTR p = szAcl;
1805
1806         while (*p && *p != ';')
1807             p++;
1808
1809         if (p - szAcl <= 8)
1810         {
1811             rights = strtoulW(szAcl, NULL, 16);
1812             *StringAcl = p;
1813         }
1814         else
1815             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
1816     }
1817     else
1818     {
1819         while (*szAcl != ';')
1820         {
1821             LPACEFLAG lpaf = AceRights;
1822
1823             while (lpaf->wstr &&
1824                (len = strlenW(lpaf->wstr)) &&
1825                strncmpW(lpaf->wstr, szAcl, len))
1826             {
1827                lpaf++;
1828             }
1829
1830             if (!lpaf->wstr)
1831                 return 0;
1832
1833             rights |= lpaf->value;
1834             szAcl += len;
1835         }
1836     }
1837
1838     *StringAcl = szAcl;
1839     return rights;
1840 }
1841
1842
1843 /******************************************************************************
1844  * ParseStringAclToAcl
1845  * 
1846  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
1847  */
1848 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
1849     PACL pAcl, LPDWORD cBytes)
1850 {
1851     DWORD val;
1852     DWORD sidlen;
1853     DWORD length = sizeof(ACL);
1854     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
1855
1856     TRACE("%s\n", debugstr_w(StringAcl));
1857
1858     if (!StringAcl)
1859         return FALSE;
1860
1861     if (pAcl) /* pAce is only useful if we're setting values */
1862         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
1863
1864     /* Parse ACL flags */
1865     *lpdwFlags = ParseAclStringFlags(&StringAcl);
1866
1867     /* Parse ACE */
1868     while (*StringAcl == '(')
1869     {
1870         StringAcl++;
1871
1872         /* Parse ACE type */
1873         val = ParseAceStringType(&StringAcl);
1874         if (pAce)
1875             pAce->Header.AceType = (BYTE) val;
1876         if (*StringAcl != ';')
1877             goto lerr;
1878         StringAcl++;
1879
1880         /* Parse ACE flags */
1881         val = ParseAceStringFlags(&StringAcl);
1882         if (pAce)
1883             pAce->Header.AceFlags = (BYTE) val;
1884         if (*StringAcl != ';')
1885             goto lerr;
1886         StringAcl++;
1887
1888         /* Parse ACE rights */
1889         val = ParseAceStringRights(&StringAcl);
1890         if (pAce)
1891             pAce->Mask = val;
1892         if (*StringAcl != ';')
1893             goto lerr;
1894         StringAcl++;
1895
1896         /* Parse ACE object guid */
1897         if (*StringAcl != ';')
1898         {
1899             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1900             goto lerr;
1901         }
1902         StringAcl++;
1903
1904         /* Parse ACE inherit object guid */
1905         if (*StringAcl != ';')
1906         {
1907             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1908             goto lerr;
1909         }
1910         StringAcl++;
1911
1912         /* Parse ACE account sid */
1913         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
1914         {
1915             while (*StringAcl && *StringAcl != ')')
1916                 StringAcl++;
1917         }
1918
1919         if (*StringAcl != ')')
1920             goto lerr;
1921         StringAcl++;
1922
1923         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
1924     }
1925
1926     *cBytes = length;
1927     return TRUE;
1928
1929 lerr:
1930     WARN("Invalid ACE string format\n");
1931     return FALSE;
1932 }
1933
1934
1935 /******************************************************************************
1936  * ParseStringSecurityDescriptorToSecurityDescriptor
1937  */
1938 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
1939     LPCWSTR StringSecurityDescriptor,
1940     SECURITY_DESCRIPTOR* SecurityDescriptor,
1941     LPDWORD cBytes)
1942 {
1943     BOOL bret = FALSE;
1944     WCHAR toktype;
1945     WCHAR tok[MAX_PATH];
1946     LPCWSTR lptoken;
1947     LPBYTE lpNext = NULL;
1948
1949     *cBytes = 0;
1950
1951     if (SecurityDescriptor)
1952         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
1953
1954     while (*StringSecurityDescriptor)
1955     {
1956         toktype = *StringSecurityDescriptor;
1957
1958         /* Expect char identifier followed by ':' */
1959         StringSecurityDescriptor++;
1960         if (*StringSecurityDescriptor != ':')
1961         {
1962             SetLastError(ERROR_INVALID_PARAMETER);
1963             goto lend;
1964         }
1965         StringSecurityDescriptor++;
1966
1967         /* Extract token */
1968         lptoken = StringSecurityDescriptor;
1969         while (*lptoken && *lptoken != ':')
1970             lptoken++;
1971
1972         if (*lptoken)
1973             lptoken--;
1974
1975         strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
1976
1977         switch (toktype)
1978         {
1979             case 'O':
1980             {
1981                 DWORD bytes;
1982
1983                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
1984                     goto lend;
1985
1986                 if (SecurityDescriptor)
1987                 {
1988                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
1989                         (DWORD) SecurityDescriptor);
1990                     lpNext += bytes; /* Advance to next token */
1991                 }
1992
1993                 *cBytes += bytes;
1994
1995                 break;
1996             }
1997
1998             case 'G':
1999             {
2000                 DWORD bytes;
2001
2002                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2003                     goto lend;
2004
2005                 if (SecurityDescriptor)
2006                 {
2007                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
2008                         (DWORD) SecurityDescriptor);
2009                     lpNext += bytes; /* Advance to next token */
2010                 }
2011
2012                 *cBytes += bytes;
2013
2014                 break;
2015             }
2016
2017             case 'D':
2018             {
2019                 DWORD flags;
2020                 DWORD bytes;
2021
2022                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2023                     goto lend;
2024
2025                 if (SecurityDescriptor)
2026                 {
2027                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2028                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
2029                         (DWORD) SecurityDescriptor);
2030                     lpNext += bytes; /* Advance to next token */
2031                 }
2032
2033                 *cBytes += bytes;
2034
2035                 break;
2036             }
2037
2038             case 'S':
2039             {
2040                 DWORD flags;
2041                 DWORD bytes;
2042
2043                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2044                     goto lend;
2045
2046                 if (SecurityDescriptor)
2047                 {
2048                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2049                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
2050                         (DWORD) SecurityDescriptor);
2051                     lpNext += bytes; /* Advance to next token */
2052                 }
2053
2054                 *cBytes += bytes;
2055
2056                 break;
2057             }
2058
2059             default:
2060                 FIXME("Unknown token\n");
2061                 SetLastError(ERROR_INVALID_PARAMETER);
2062                 goto lend;
2063         }
2064
2065         StringSecurityDescriptor = lptoken;
2066     }
2067
2068     bret = TRUE;
2069
2070 lend:
2071     return bret;
2072 }
2073
2074 /******************************************************************************
2075  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2076  */
2077 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2078         LPCWSTR StringSecurityDescriptor,
2079         DWORD StringSDRevision,
2080         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2081         PULONG SecurityDescriptorSize)
2082 {
2083     DWORD cBytes;
2084     SECURITY_DESCRIPTOR* psd;
2085     BOOL bret = FALSE;
2086
2087     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2088
2089     if (GetVersion() & 0x80000000)
2090     {
2091         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2092         goto lend;
2093     }
2094     else if (StringSDRevision != SID_REVISION)
2095     {
2096         SetLastError(ERROR_UNKNOWN_REVISION);
2097         goto lend;
2098     }
2099
2100     /* Compute security descriptor length */
2101     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2102         NULL, &cBytes))
2103         goto lend;
2104
2105     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
2106         GMEM_ZEROINIT, cBytes);
2107
2108     psd->Revision = SID_REVISION;
2109     psd->Control |= SE_SELF_RELATIVE;
2110
2111     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2112         psd, &cBytes))
2113     {
2114         LocalFree(psd);
2115         goto lend;
2116     }
2117
2118     if (SecurityDescriptorSize)
2119         *SecurityDescriptorSize = cBytes;
2120
2121     bret = TRUE;
2122  
2123 lend:
2124     TRACE(" ret=%d\n", bret);
2125     return bret;
2126 }
2127
2128 /******************************************************************************
2129  * ConvertStringSidToSidW [ADVAPI32.@]
2130  */
2131 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
2132 {
2133     BOOL bret = FALSE;
2134     DWORD cBytes;
2135
2136     if (GetVersion() & 0x80000000)
2137         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2138     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
2139     {
2140         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
2141
2142         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
2143         if (!bret)
2144             LocalFree(*Sid); 
2145     }
2146
2147     return bret;
2148 }
2149
2150 /******************************************************************************
2151  * ConvertSidToStringSidW [ADVAPI32.@]
2152  *
2153  *  format of SID string is:
2154  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
2155  *  where
2156  *    <rev> is the revision of the SID encoded as decimal
2157  *    <auth> is the identifier authority encoded as hex
2158  *    <subauthN> is the subauthority id encoded as decimal
2159  */
2160 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
2161 {
2162     DWORD sz, i;
2163     LPWSTR str;
2164     WCHAR fmt[] = { 
2165         'S','-','%','u','-','%','2','X','%','2','X','%','X','%','X','%','X','%','X',0 };
2166     WCHAR subauthfmt[] = { '-','%','u',0 };
2167     SID* pisid=pSid;
2168
2169     TRACE("%p %p\n", pSid, pstr );
2170
2171     if( !IsValidSid( pSid ) )
2172         return FALSE;
2173
2174     if (pisid->Revision != SDDL_REVISION)
2175         return FALSE;
2176
2177     sz = 14 + pisid->SubAuthorityCount * 11;
2178     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
2179     sprintfW( str, fmt, pisid->Revision,
2180          pisid->IdentifierAuthority.Value[2],
2181          pisid->IdentifierAuthority.Value[3],
2182          pisid->IdentifierAuthority.Value[0]&0x0f,
2183          pisid->IdentifierAuthority.Value[4]&0x0f,
2184          pisid->IdentifierAuthority.Value[1]&0x0f,
2185          pisid->IdentifierAuthority.Value[5]&0x0f);
2186     for( i=0; i<pisid->SubAuthorityCount; i++ )
2187         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
2188     *pstr = str;
2189
2190     return TRUE;
2191 }
2192
2193 /******************************************************************************
2194  * ConvertSidToStringSidA [ADVAPI32.@]
2195  */
2196 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
2197 {
2198     LPWSTR wstr = NULL;
2199     LPSTR str;
2200     UINT len;
2201
2202     TRACE("%p %p\n", pSid, pstr );
2203
2204     if( !ConvertSidToStringSidW( pSid, &wstr ) )
2205         return FALSE;
2206
2207     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
2208     str = LocalAlloc( 0, len );
2209     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
2210     LocalFree( wstr );
2211
2212     *pstr = str;
2213
2214     return TRUE;
2215 }
2216
2217 /******************************************************************************
2218  * ComputeStringSidSize
2219  */
2220 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
2221 {
2222     int ctok = 0;
2223     DWORD size = sizeof(SID);
2224
2225     while (*StringSid)
2226     {
2227         if (*StringSid == '-')
2228             ctok++;
2229         StringSid++;
2230     }
2231
2232     if (ctok > 3)
2233         size += (ctok - 3) * sizeof(DWORD);
2234
2235     return size;
2236 }
2237
2238 /******************************************************************************
2239  * ParseStringSidToSid
2240  */
2241 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
2242 {
2243     BOOL bret = FALSE;
2244     SID* pisid=pSid;
2245
2246     if (!StringSid)
2247     {
2248         SetLastError(ERROR_INVALID_PARAMETER);
2249         return FALSE;
2250     }
2251
2252     *cBytes = ComputeStringSidSize(StringSid);
2253     if (!pisid) /* Simply compute the size */
2254         return TRUE;
2255
2256     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
2257     {
2258         int i = 0;
2259         int csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
2260
2261         StringSid += 2; /* Advance to Revision */
2262         pisid->Revision = atoiW(StringSid);
2263
2264         if (pisid->Revision != SDDL_REVISION)
2265            goto lend; /* ERROR_INVALID_SID */
2266
2267         pisid->SubAuthorityCount = csubauth;
2268
2269         while (*StringSid && *StringSid != '-')
2270             StringSid++; /* Advance to identifier authority */
2271
2272         pisid->IdentifierAuthority.Value[5] = atoiW(StringSid);
2273
2274         if (pisid->IdentifierAuthority.Value[5] > 5)
2275             goto lend; /* ERROR_INVALID_SID */
2276     
2277         while (*StringSid)
2278         {       
2279             while (*StringSid && *StringSid != '-')
2280                 StringSid++;
2281
2282             pisid->SubAuthority[i++] = atoiW(StringSid);
2283         }
2284
2285         if (i != pisid->SubAuthorityCount)
2286             goto lend; /* ERROR_INVALID_SID */
2287
2288         bret = TRUE;
2289     }
2290     else /* String constant format  - Only available in winxp and above */
2291     {
2292         pisid->Revision = SDDL_REVISION;
2293         pisid->SubAuthorityCount = 1;
2294
2295         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
2296
2297         /* TODO: Lookup string of well-known SIDs in table */
2298         pisid->IdentifierAuthority.Value[5] = 0;
2299         pisid->SubAuthority[0] = 0;
2300
2301         bret = TRUE;
2302     }
2303
2304 lend:
2305     if (!bret)
2306         SetLastError(ERROR_INVALID_SID);
2307
2308     return bret;
2309 }
2310
2311 /******************************************************************************
2312  * GetNamedSecurityInfoA [ADVAPI32.@]
2313  */
2314 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
2315         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2316         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2317         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2318 {
2319     DWORD len;
2320     LPWSTR wstr = NULL;
2321     DWORD r;
2322
2323     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
2324         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2325
2326     if( pObjectName )
2327     {
2328         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2329         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2330         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2331     }
2332
2333     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
2334                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
2335
2336     if( wstr )
2337         HeapFree( GetProcessHeap(), 0, wstr );
2338
2339     return r;
2340 }
2341
2342 /******************************************************************************
2343  * GetNamedSecurityInfoW [ADVAPI32.@]
2344  */
2345 DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
2346         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2347         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2348         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2349 {
2350     FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
2351         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2352     return ERROR_CALL_NOT_IMPLEMENTED;
2353 }