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