quartz: Give video renderer's Inner_QueryInterface a less generic name.
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  * Copyright 2006 Robert Reif
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
41
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
44
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
46
47 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
48 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
49     PACL pAcl, LPDWORD cBytes);
50 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
51 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
52 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
53 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
54     LPCWSTR StringSecurityDescriptor,
55     SECURITY_DESCRIPTOR* SecurityDescriptor,
56     LPDWORD cBytes);
57 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
58
59 typedef struct _ACEFLAG
60 {
61    LPCWSTR wstr;
62    DWORD value;
63 } ACEFLAG, *LPACEFLAG;
64
65 typedef struct _MAX_SID
66 {
67     /* same fields as struct _SID */
68     BYTE Revision;
69     BYTE SubAuthorityCount;
70     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } MAX_SID;
73
74 typedef struct WELLKNOWNSID
75 {
76     WCHAR wstr[2];
77     WELL_KNOWN_SID_TYPE Type;
78     MAX_SID Sid;
79 } WELLKNOWNSID;
80
81 static const WELLKNOWNSID WellKnownSids[] =
82 {
83     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
84     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
85     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
86     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
87     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
88     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
89     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
90     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
91     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
92     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
93     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
94     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
95     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
96     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
97     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
98     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
99     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
100     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
101     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
102     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
103     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
104     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
105     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
106     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
107     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
108     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
109     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
110     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
111     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
112     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
113     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
114     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
115     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
116     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
117     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
118     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
119     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
121     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
122     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
123     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
124     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
125     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
126     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
127     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
128     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
129     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
130     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
131 };
132
133 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
134 typedef struct WELLKNOWNRID
135 {
136     WELL_KNOWN_SID_TYPE Type;
137     DWORD Rid;
138 } WELLKNOWNRID;
139
140 static const WELLKNOWNRID WellKnownRids[] = {
141     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
142     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
143     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
144     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
145     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
146     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
147     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
148     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
149     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
150     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
151     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
152     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
153     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
154 };
155
156
157 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
158
159 typedef struct _AccountSid {
160     WELL_KNOWN_SID_TYPE type;
161     LPCWSTR account;
162     LPCWSTR domain;
163     SID_NAME_USE name_use;
164 } AccountSid;
165
166 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
167 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
168 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
169 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
170 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
171 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
172 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
173 static const WCHAR Blank[] = { 0 };
174 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
175 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
176 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
177 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
178 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
179 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
180 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
181 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
182 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
183 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
184 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
185 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
186 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
187 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
188 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
189 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
190 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
191 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
192 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
193 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
194 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
195 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
196 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
197 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
198 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
199 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
201 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
202 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
203 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
204 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
205 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
206 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
207 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
208 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
209 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
210 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
211 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
212 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
213 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
214 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
215 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
216 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
217 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
218 static const WCHAR SELF[] = { 'S','E','L','F',0 };
219 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
221 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
222 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
223 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
224 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
225
226 static const AccountSid ACCOUNT_SIDS[] = {
227     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
228     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
229     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
230     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
231     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
232     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
233     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
234     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
235     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
236     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
237     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
238     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
239     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
240     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
241     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
242     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
243     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
244     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
245     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
246     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
247     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
248     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
249     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
252     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
253     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
254     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
255     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
256     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
257     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
258     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
259     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
260     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
261     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
262     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
263     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
264     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
265     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
268     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
270     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
271 };
272 /*
273  * ACE access rights
274  */
275 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
276 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
277 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
278 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
279
280 static const WCHAR SDDL_READ_PROPERTY[]    = {'R','P',0};
281 static const WCHAR SDDL_WRITE_PROPERTY[]   = {'W','P',0};
282 static const WCHAR SDDL_CREATE_CHILD[]     = {'C','C',0};
283 static const WCHAR SDDL_DELETE_CHILD[]     = {'D','C',0};
284 static const WCHAR SDDL_LIST_CHILDREN[]    = {'L','C',0};
285 static const WCHAR SDDL_SELF_WRITE[]       = {'S','W',0};
286 static const WCHAR SDDL_LIST_OBJECT[]      = {'L','O',0};
287 static const WCHAR SDDL_DELETE_TREE[]      = {'D','T',0};
288 static const WCHAR SDDL_CONTROL_ACCESS[]   = {'C','R',0};
289
290 static const WCHAR SDDL_FILE_ALL[]         = {'F','A',0};
291 static const WCHAR SDDL_FILE_READ[]        = {'F','R',0};
292 static const WCHAR SDDL_FILE_WRITE[]       = {'F','W',0};
293 static const WCHAR SDDL_FILE_EXECUTE[]     = {'F','X',0};
294
295 static const WCHAR SDDL_KEY_ALL[]          = {'K','A',0};
296 static const WCHAR SDDL_KEY_READ[]         = {'K','R',0};
297 static const WCHAR SDDL_KEY_WRITE[]        = {'K','W',0};
298 static const WCHAR SDDL_KEY_EXECUTE[]      = {'K','X',0};
299
300 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
301 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
302 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
303 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
304
305 /*
306  * ACL flags
307  */
308 static const WCHAR SDDL_PROTECTED[]             = {'P',0};
309 static const WCHAR SDDL_AUTO_INHERIT_REQ[]      = {'A','R',0};
310 static const WCHAR SDDL_AUTO_INHERITED[]        = {'A','I',0};
311
312 /*
313  * ACE types
314  */
315 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
316 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
317 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
319 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
320 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
321 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
322 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
323
324 /*
325  * ACE flags
326  */
327 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
328 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
329 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
330 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
331 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
332 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
333 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
334
335 const char * debugstr_sid(PSID sid)
336 {
337     int auth = 0;
338     SID * psid = (SID *)sid;
339
340     if (psid == NULL)
341         return "(null)";
342
343     auth = psid->IdentifierAuthority.Value[5] +
344            (psid->IdentifierAuthority.Value[4] << 8) +
345            (psid->IdentifierAuthority.Value[3] << 16) +
346            (psid->IdentifierAuthority.Value[2] << 24);
347
348     switch (psid->SubAuthorityCount) {
349     case 0:
350         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
351     case 1:
352         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
353             psid->SubAuthority[0]);
354     case 2:
355         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
356             psid->SubAuthority[0], psid->SubAuthority[1]);
357     case 3:
358         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
359             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
360     case 4:
361         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
362             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
363             psid->SubAuthority[3]);
364     case 5:
365         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
366             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
367             psid->SubAuthority[3], psid->SubAuthority[4]);
368     case 6:
369         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
370             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
371             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
372     case 7:
373         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
374             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
375             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
376             psid->SubAuthority[6]);
377     case 8:
378         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
380             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
381             psid->SubAuthority[6], psid->SubAuthority[7]);
382     }
383     return "(too-big)";
384 }
385
386 /* set last error code from NT status and get the proper boolean return value */
387 /* used for functions that are a simple wrapper around the corresponding ntdll API */
388 static inline BOOL set_ntstatus( NTSTATUS status )
389 {
390     if (status) SetLastError( RtlNtStatusToDosError( status ));
391     return !status;
392 }
393
394 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
395
396 static void GetWorldAccessACL(PACL pACL)
397 {
398     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
399
400     pACL->AclRevision = ACL_REVISION;
401     pACL->Sbz1 = 0;
402     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
403     pACL->AceCount = 1;
404     pACL->Sbz2 = 0;
405
406     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
407     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
408     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
409     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
410     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
411 }
412
413 /************************************************************
414  *                ADVAPI_IsLocalComputer
415  *
416  * Checks whether the server name indicates local machine.
417  */
418 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
419 {
420     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
421     BOOL Result;
422     LPWSTR buf;
423
424     if (!ServerName || !ServerName[0])
425         return TRUE;
426
427     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
428     Result = GetComputerNameW(buf,  &dwSize);
429     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
430         ServerName += 2;
431     Result = Result && !lstrcmpW(ServerName, buf);
432     HeapFree(GetProcessHeap(), 0, buf);
433
434     return Result;
435 }
436
437 /************************************************************
438  *                ADVAPI_GetComputerSid
439  *
440  * Reads the computer SID from the registry.
441  */
442 BOOL ADVAPI_GetComputerSid(PSID sid)
443 {
444     HKEY key;
445     LONG ret;
446     BOOL retval = FALSE;
447     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
448     static const WCHAR V[] = { 'V',0 };
449
450     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
451         KEY_READ, &key)) == ERROR_SUCCESS)
452     {
453         DWORD size = 0;
454         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
455         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
456         {
457             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
458             if (data)
459             {
460                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
461                      data, &size)) == ERROR_SUCCESS)
462                 {
463                     /* the SID is in the last 24 bytes of the binary data */
464                     CopyMemory(sid, &data[size-24], 24);
465                     retval = TRUE;
466                 }
467                 HeapFree(GetProcessHeap(), 0, data);
468             }
469         }
470         RegCloseKey(key);
471     }
472
473     if(retval == TRUE) return retval;
474
475     /* create a new random SID */
476     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
477         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
478     {
479         PSID new_sid;
480         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
481         DWORD id[3];
482
483         if (RtlGenRandom(&id, sizeof(id)))
484         {
485             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
486             {
487                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
488                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
489
490                 FreeSid(new_sid);
491             }
492         }
493         RegCloseKey(key);
494     }
495
496     return retval;
497 }
498
499 /*      ##############################
500         ######  TOKEN FUNCTIONS ######
501         ##############################
502 */
503
504 /******************************************************************************
505  * OpenProcessToken                     [ADVAPI32.@]
506  * Opens the access token associated with a process handle.
507  *
508  * PARAMS
509  *   ProcessHandle [I] Handle to process
510  *   DesiredAccess [I] Desired access to process
511  *   TokenHandle   [O] Pointer to handle of open access token
512  *
513  * RETURNS
514  *  Success: TRUE. TokenHandle contains the access token.
515  *  Failure: FALSE.
516  *
517  * NOTES
518  *  See NtOpenProcessToken.
519  */
520 BOOL WINAPI
521 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
522                   HANDLE *TokenHandle )
523 {
524         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
525 }
526
527 /******************************************************************************
528  * OpenThreadToken [ADVAPI32.@]
529  *
530  * Opens the access token associated with a thread handle.
531  *
532  * PARAMS
533  *   ThreadHandle  [I] Handle to process
534  *   DesiredAccess [I] Desired access to the thread
535  *   OpenAsSelf    [I] ???
536  *   TokenHandle   [O] Destination for the token handle
537  *
538  * RETURNS
539  *  Success: TRUE. TokenHandle contains the access token.
540  *  Failure: FALSE.
541  *
542  * NOTES
543  *  See NtOpenThreadToken.
544  */
545 BOOL WINAPI
546 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
547                  BOOL OpenAsSelf, HANDLE *TokenHandle)
548 {
549         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
550 }
551
552 BOOL WINAPI
553 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
554                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
555 {
556     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
557                                              PreviousState, ReturnLength));
558 }
559
560 /******************************************************************************
561  * AdjustTokenPrivileges [ADVAPI32.@]
562  *
563  * Adjust the privileges of an open token handle.
564  * 
565  * PARAMS
566  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
567  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
568  *  NewState             [I]   Desired new privileges of the token
569  *  BufferLength         [I]   Length of NewState
570  *  PreviousState        [O]   Destination for the previous state
571  *  ReturnLength         [I/O] Size of PreviousState
572  *
573  *
574  * RETURNS
575  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
576  *  Failure: FALSE.
577  *
578  * NOTES
579  *  See NtAdjustPrivilegesToken.
580  */
581 BOOL WINAPI
582 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
583                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
584                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
585 {
586     NTSTATUS status;
587
588     TRACE("\n");
589     
590     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
591                                                      NewState, BufferLength, PreviousState,
592                                                      ReturnLength);
593     SetLastError( RtlNtStatusToDosError( status ));
594     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
595         return TRUE;
596     else
597         return FALSE;
598 }
599
600 /******************************************************************************
601  * CheckTokenMembership [ADVAPI32.@]
602  *
603  * Determine if an access token is a member of a SID.
604  * 
605  * PARAMS
606  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
607  *   SidToCheck  [I] SID that possibly contains the token
608  *   IsMember    [O] Destination for result.
609  *
610  * RETURNS
611  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
612  *  Failure: FALSE.
613  */
614 BOOL WINAPI
615 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
616                       PBOOL IsMember )
617 {
618   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
619
620   *IsMember = TRUE;
621   return(TRUE);
622 }
623
624 /******************************************************************************
625  * GetTokenInformation [ADVAPI32.@]
626  *
627  * Get a type of information about an access token.
628  *
629  * PARAMS
630  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
631  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
632  *   tokeninfo       [O] Destination for token information
633  *   tokeninfolength [I] Length of tokeninfo
634  *   retlen          [O] Destination for returned token information length
635  *
636  * RETURNS
637  *  Success: TRUE. tokeninfo contains retlen bytes of token information
638  *  Failure: FALSE.
639  *
640  * NOTES
641  *  See NtQueryInformationToken.
642  */
643 BOOL WINAPI
644 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
645                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
646 {
647     TRACE("(%p, %s, %p, %d, %p):\n",
648           token,
649           (tokeninfoclass == TokenUser) ? "TokenUser" :
650           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
651           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
652           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
653           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
654           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
655           (tokeninfoclass == TokenSource) ? "TokenSource" :
656           (tokeninfoclass == TokenType) ? "TokenType" :
657           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
658           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
659           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
660           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
661           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
662           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
663           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
664           "Unknown",
665           tokeninfo, tokeninfolength, retlen);
666     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
667                                                   tokeninfolength, retlen));
668 }
669
670 /******************************************************************************
671  * SetTokenInformation [ADVAPI32.@]
672  *
673  * Set information for an access token.
674  *
675  * PARAMS
676  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
677  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
678  *   tokeninfo       [I] Token information to set
679  *   tokeninfolength [I] Length of tokeninfo
680  *
681  * RETURNS
682  *  Success: TRUE. The information for the token is set to tokeninfo.
683  *  Failure: FALSE.
684  */
685 BOOL WINAPI
686 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
687                      LPVOID tokeninfo, DWORD tokeninfolength )
688 {
689     TRACE("(%p, %s, %p, %d): stub\n",
690           token,
691           (tokeninfoclass == TokenUser) ? "TokenUser" :
692           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
693           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
694           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
695           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
696           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
697           (tokeninfoclass == TokenSource) ? "TokenSource" :
698           (tokeninfoclass == TokenType) ? "TokenType" :
699           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
700           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
701           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
702           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
703           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
704           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
705           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
706           "Unknown",
707           tokeninfo, tokeninfolength);
708
709     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
710 }
711
712 /*************************************************************************
713  * SetThreadToken [ADVAPI32.@]
714  *
715  * Assigns an 'impersonation token' to a thread so it can assume the
716  * security privileges of another thread or process.  Can also remove
717  * a previously assigned token. 
718  *
719  * PARAMS
720  *   thread          [O] Handle to thread to set the token for
721  *   token           [I] Token to set
722  *
723  * RETURNS
724  *  Success: TRUE. The threads access token is set to token
725  *  Failure: FALSE.
726  *
727  * NOTES
728  *  Only supported on NT or higher. On Win9X this function does nothing.
729  *  See SetTokenInformation.
730  */
731 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
732 {
733     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
734                                                  ThreadImpersonationToken, &token, sizeof token ));
735 }
736
737 /*      ##############################
738         ######  SID FUNCTIONS   ######
739         ##############################
740 */
741
742 /******************************************************************************
743  * AllocateAndInitializeSid [ADVAPI32.@]
744  *
745  * PARAMS
746  *   pIdentifierAuthority []
747  *   nSubAuthorityCount   []
748  *   nSubAuthority0       []
749  *   nSubAuthority1       []
750  *   nSubAuthority2       []
751  *   nSubAuthority3       []
752  *   nSubAuthority4       []
753  *   nSubAuthority5       []
754  *   nSubAuthority6       []
755  *   nSubAuthority7       []
756  *   pSid                 []
757  */
758 BOOL WINAPI
759 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
760                           BYTE nSubAuthorityCount,
761                           DWORD nSubAuthority0, DWORD nSubAuthority1,
762                           DWORD nSubAuthority2, DWORD nSubAuthority3,
763                           DWORD nSubAuthority4, DWORD nSubAuthority5,
764                           DWORD nSubAuthority6, DWORD nSubAuthority7,
765                           PSID *pSid )
766 {
767     return set_ntstatus( RtlAllocateAndInitializeSid(
768                              pIdentifierAuthority, nSubAuthorityCount,
769                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
770                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
771                              pSid ));
772 }
773
774 /******************************************************************************
775  * FreeSid [ADVAPI32.@]
776  *
777  * PARAMS
778  *   pSid []
779  */
780 PVOID WINAPI
781 FreeSid( PSID pSid )
782 {
783         RtlFreeSid(pSid);
784         return NULL; /* is documented like this */
785 }
786
787 /******************************************************************************
788  * CopySid [ADVAPI32.@]
789  *
790  * PARAMS
791  *   nDestinationSidLength []
792  *   pDestinationSid       []
793  *   pSourceSid            []
794  */
795 BOOL WINAPI
796 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
797 {
798         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
799 }
800
801 /******************************************************************************
802  * CreateWellKnownSid [ADVAPI32.@]
803  */
804 BOOL WINAPI
805 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
806                     PSID DomainSid,
807                     PSID pSid,
808                     DWORD* cbSid)
809 {
810     unsigned int i;
811     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
812
813     if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
814         SetLastError(ERROR_INVALID_PARAMETER);
815         return FALSE;
816     }
817
818     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
819         if (WellKnownSids[i].Type == WellKnownSidType) {
820             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
821
822             if (*cbSid < length) {
823                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
824                 return FALSE;
825             }
826
827             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
828             *cbSid = length;
829             return TRUE;
830         }
831     }
832
833     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
834     {
835         SetLastError(ERROR_INVALID_PARAMETER);
836         return FALSE;
837     }
838
839     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
840         if (WellKnownRids[i].Type == WellKnownSidType) {
841             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
842             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
843             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
844
845             if (*cbSid < output_sid_length) {
846                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
847                 return FALSE;
848             }
849
850             CopyMemory(pSid, DomainSid, domain_sid_length);
851             (*GetSidSubAuthorityCount(pSid))++;
852             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
853             *cbSid = output_sid_length;
854             return TRUE;
855         }
856
857     SetLastError(ERROR_INVALID_PARAMETER);
858     return FALSE;
859 }
860
861 /******************************************************************************
862  * IsWellKnownSid [ADVAPI32.@]
863  */
864 BOOL WINAPI
865 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
866 {
867     unsigned int i;
868     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
869
870     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
871         if (WellKnownSids[i].Type == WellKnownSidType)
872             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
873                 return TRUE;
874
875     return FALSE;
876 }
877
878 BOOL WINAPI
879 IsTokenRestricted( HANDLE TokenHandle )
880 {
881     TOKEN_GROUPS *groups;
882     DWORD size;
883     NTSTATUS status;
884     BOOL restricted;
885
886     TRACE("(%p)\n", TokenHandle);
887  
888     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
889     if (status != STATUS_BUFFER_TOO_SMALL)
890         return FALSE;
891  
892     groups = HeapAlloc(GetProcessHeap(), 0, size);
893     if (!groups)
894     {
895         SetLastError(ERROR_OUTOFMEMORY);
896         return FALSE;
897     }
898  
899     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
900     if (status != STATUS_SUCCESS)
901     {
902         HeapFree(GetProcessHeap(), 0, groups);
903         return set_ntstatus(status);
904     }
905  
906     if (groups->GroupCount)
907         restricted = TRUE;
908     else
909         restricted = FALSE;
910      
911     HeapFree(GetProcessHeap(), 0, groups);
912  
913     return restricted;
914 }
915
916 /******************************************************************************
917  * IsValidSid [ADVAPI32.@]
918  *
919  * PARAMS
920  *   pSid []
921  */
922 BOOL WINAPI
923 IsValidSid( PSID pSid )
924 {
925         return RtlValidSid( pSid );
926 }
927
928 /******************************************************************************
929  * EqualSid [ADVAPI32.@]
930  *
931  * PARAMS
932  *   pSid1 []
933  *   pSid2 []
934  */
935 BOOL WINAPI
936 EqualSid( PSID pSid1, PSID pSid2 )
937 {
938         return RtlEqualSid( pSid1, pSid2 );
939 }
940
941 /******************************************************************************
942  * EqualPrefixSid [ADVAPI32.@]
943  */
944 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
945 {
946         return RtlEqualPrefixSid(pSid1, pSid2);
947 }
948
949 /******************************************************************************
950  * GetSidLengthRequired [ADVAPI32.@]
951  *
952  * PARAMS
953  *   nSubAuthorityCount []
954  */
955 DWORD WINAPI
956 GetSidLengthRequired( BYTE nSubAuthorityCount )
957 {
958         return RtlLengthRequiredSid(nSubAuthorityCount);
959 }
960
961 /******************************************************************************
962  * InitializeSid [ADVAPI32.@]
963  *
964  * PARAMS
965  *   pIdentifierAuthority []
966  */
967 BOOL WINAPI
968 InitializeSid (
969         PSID pSid,
970         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
971         BYTE nSubAuthorityCount)
972 {
973         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
974 }
975
976 DWORD WINAPI
977 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
978 {
979     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
980
981     return 1;
982 }
983
984 DWORD WINAPI
985 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
986 {
987     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
988
989     return 1;
990 }
991
992 /******************************************************************************
993  * GetSidIdentifierAuthority [ADVAPI32.@]
994  *
995  * PARAMS
996  *   pSid []
997  */
998 PSID_IDENTIFIER_AUTHORITY WINAPI
999 GetSidIdentifierAuthority( PSID pSid )
1000 {
1001         return RtlIdentifierAuthoritySid(pSid);
1002 }
1003
1004 /******************************************************************************
1005  * GetSidSubAuthority [ADVAPI32.@]
1006  *
1007  * PARAMS
1008  *   pSid          []
1009  *   nSubAuthority []
1010  */
1011 PDWORD WINAPI
1012 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1013 {
1014         return RtlSubAuthoritySid(pSid, nSubAuthority);
1015 }
1016
1017 /******************************************************************************
1018  * GetSidSubAuthorityCount [ADVAPI32.@]
1019  *
1020  * PARAMS
1021  *   pSid []
1022  */
1023 PUCHAR WINAPI
1024 GetSidSubAuthorityCount (PSID pSid)
1025 {
1026         return RtlSubAuthorityCountSid(pSid);
1027 }
1028
1029 /******************************************************************************
1030  * GetLengthSid [ADVAPI32.@]
1031  *
1032  * PARAMS
1033  *   pSid []
1034  */
1035 DWORD WINAPI
1036 GetLengthSid (PSID pSid)
1037 {
1038         return RtlLengthSid(pSid);
1039 }
1040
1041 /*      ##############################################
1042         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1043         ##############################################
1044 */
1045
1046  /****************************************************************************** 
1047  * BuildSecurityDescriptorA [ADVAPI32.@]
1048  *
1049  * Builds a SD from 
1050  *
1051  * PARAMS
1052  *  pOwner                [I]
1053  *  pGroup                [I]
1054  *  cCountOfAccessEntries [I]
1055  *  pListOfAccessEntries  [I]
1056  *  cCountOfAuditEntries  [I]
1057  *  pListofAuditEntries   [I]
1058  *  pOldSD                [I]
1059  *  lpdwBufferLength      [I/O]
1060  *  pNewSD                [O]
1061  *
1062  * RETURNS
1063  *  Success: ERROR_SUCCESS
1064  *  Failure: nonzero error code from Winerror.h
1065  */
1066 DWORD WINAPI BuildSecurityDescriptorA(
1067     IN PTRUSTEEA pOwner,
1068     IN PTRUSTEEA pGroup,
1069     IN ULONG cCountOfAccessEntries,
1070     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1071     IN ULONG cCountOfAuditEntries,
1072     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1073     IN PSECURITY_DESCRIPTOR pOldSD,
1074     IN OUT PULONG lpdwBufferLength,
1075     OUT PSECURITY_DESCRIPTOR* pNewSD)
1076
1077     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1078           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1079           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1080  
1081     return ERROR_CALL_NOT_IMPLEMENTED;
1082
1083  
1084 /******************************************************************************
1085  * BuildSecurityDescriptorW [ADVAPI32.@]
1086  *
1087  * See BuildSecurityDescriptorA.
1088  */
1089 DWORD WINAPI BuildSecurityDescriptorW(
1090     IN PTRUSTEEW pOwner,
1091     IN PTRUSTEEW pGroup,
1092     IN ULONG cCountOfAccessEntries,
1093     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1094     IN ULONG cCountOfAuditEntries,
1095     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1096     IN PSECURITY_DESCRIPTOR pOldSD,
1097     IN OUT PULONG lpdwBufferLength,
1098     OUT PSECURITY_DESCRIPTOR* pNewSD)
1099
1100     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1101           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1102           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1103  
1104     return ERROR_CALL_NOT_IMPLEMENTED;
1105
1106
1107 /******************************************************************************
1108  * InitializeSecurityDescriptor [ADVAPI32.@]
1109  *
1110  * PARAMS
1111  *   pDescr   []
1112  *   revision []
1113  */
1114 BOOL WINAPI
1115 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1116 {
1117         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1118 }
1119
1120
1121 /******************************************************************************
1122  * MakeAbsoluteSD [ADVAPI32.@]
1123  */
1124 BOOL WINAPI MakeAbsoluteSD (
1125         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1126         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1127         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1128         OUT PACL pDacl,
1129         OUT LPDWORD lpdwDaclSize,
1130         OUT PACL pSacl,
1131         OUT LPDWORD lpdwSaclSize,
1132         OUT PSID pOwner,
1133         OUT LPDWORD lpdwOwnerSize,
1134         OUT PSID pPrimaryGroup,
1135         OUT LPDWORD lpdwPrimaryGroupSize)
1136 {
1137     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1138                                                      pAbsoluteSecurityDescriptor,
1139                                                      lpdwAbsoluteSecurityDescriptorSize,
1140                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1141                                                      pOwner, lpdwOwnerSize,
1142                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1143 }
1144
1145 /******************************************************************************
1146  * GetKernelObjectSecurity [ADVAPI32.@]
1147  */
1148 BOOL WINAPI GetKernelObjectSecurity(
1149         HANDLE Handle,
1150         SECURITY_INFORMATION RequestedInformation,
1151         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1152         DWORD nLength,
1153         LPDWORD lpnLengthNeeded )
1154 {
1155     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1156           pSecurityDescriptor, nLength, lpnLengthNeeded);
1157
1158     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1159                                                nLength, lpnLengthNeeded ));
1160 }
1161
1162 /******************************************************************************
1163  * GetPrivateObjectSecurity [ADVAPI32.@]
1164  */
1165 BOOL WINAPI GetPrivateObjectSecurity(
1166         PSECURITY_DESCRIPTOR ObjectDescriptor,
1167         SECURITY_INFORMATION SecurityInformation,
1168         PSECURITY_DESCRIPTOR ResultantDescriptor,
1169         DWORD DescriptorLength,
1170         PDWORD ReturnLength )
1171 {
1172     SECURITY_DESCRIPTOR desc;
1173     BOOL defaulted, present;
1174     PACL pacl;
1175     PSID psid;
1176
1177     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1178           ResultantDescriptor, DescriptorLength, ReturnLength);
1179
1180     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1181         return FALSE;
1182
1183     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1184     {
1185         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1186             return FALSE;
1187         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1188     }
1189
1190     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1191     {
1192         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1193             return FALSE;
1194         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1195     }
1196
1197     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1198     {
1199         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1200             return FALSE;
1201         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1202     }
1203
1204     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1205     {
1206         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1207             return FALSE;
1208         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1209     }
1210
1211     *ReturnLength = DescriptorLength;
1212     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1213 }
1214
1215 /******************************************************************************
1216  * GetSecurityDescriptorLength [ADVAPI32.@]
1217  */
1218 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1219 {
1220         return RtlLengthSecurityDescriptor(pDescr);
1221 }
1222
1223 /******************************************************************************
1224  * GetSecurityDescriptorOwner [ADVAPI32.@]
1225  *
1226  * PARAMS
1227  *   pOwner            []
1228  *   lpbOwnerDefaulted []
1229  */
1230 BOOL WINAPI
1231 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1232                             LPBOOL lpbOwnerDefaulted )
1233 {
1234     BOOLEAN defaulted;
1235     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1236     *lpbOwnerDefaulted = defaulted;
1237     return ret;
1238 }
1239
1240 /******************************************************************************
1241  * SetSecurityDescriptorOwner [ADVAPI32.@]
1242  *
1243  * PARAMS
1244  */
1245 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1246                                    PSID pOwner, BOOL bOwnerDefaulted)
1247 {
1248     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1249 }
1250 /******************************************************************************
1251  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1252  */
1253 BOOL WINAPI GetSecurityDescriptorGroup(
1254         PSECURITY_DESCRIPTOR SecurityDescriptor,
1255         PSID *Group,
1256         LPBOOL GroupDefaulted)
1257 {
1258     BOOLEAN defaulted;
1259     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1260     *GroupDefaulted = defaulted;
1261     return ret;
1262 }
1263 /******************************************************************************
1264  * SetSecurityDescriptorGroup [ADVAPI32.@]
1265  */
1266 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1267                                            PSID Group, BOOL GroupDefaulted)
1268 {
1269     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1270 }
1271
1272 /******************************************************************************
1273  * IsValidSecurityDescriptor [ADVAPI32.@]
1274  *
1275  * PARAMS
1276  *   lpsecdesc []
1277  */
1278 BOOL WINAPI
1279 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1280 {
1281     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1282 }
1283
1284 /******************************************************************************
1285  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1286  */
1287 BOOL WINAPI GetSecurityDescriptorDacl(
1288         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1289         OUT LPBOOL lpbDaclPresent,
1290         OUT PACL *pDacl,
1291         OUT LPBOOL lpbDaclDefaulted)
1292 {
1293     BOOLEAN present, defaulted;
1294     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1295     *lpbDaclPresent = present;
1296     *lpbDaclDefaulted = defaulted;
1297     return ret;
1298 }
1299
1300 /******************************************************************************
1301  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1302  */
1303 BOOL WINAPI
1304 SetSecurityDescriptorDacl (
1305         PSECURITY_DESCRIPTOR lpsd,
1306         BOOL daclpresent,
1307         PACL dacl,
1308         BOOL dacldefaulted )
1309 {
1310     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1311 }
1312 /******************************************************************************
1313  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1314  */
1315 BOOL WINAPI GetSecurityDescriptorSacl(
1316         IN PSECURITY_DESCRIPTOR lpsd,
1317         OUT LPBOOL lpbSaclPresent,
1318         OUT PACL *pSacl,
1319         OUT LPBOOL lpbSaclDefaulted)
1320 {
1321     BOOLEAN present, defaulted;
1322     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1323     *lpbSaclPresent = present;
1324     *lpbSaclDefaulted = defaulted;
1325     return ret;
1326 }
1327
1328 /**************************************************************************
1329  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1330  */
1331 BOOL WINAPI SetSecurityDescriptorSacl (
1332         PSECURITY_DESCRIPTOR lpsd,
1333         BOOL saclpresent,
1334         PACL lpsacl,
1335         BOOL sacldefaulted)
1336 {
1337     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1338 }
1339 /******************************************************************************
1340  * MakeSelfRelativeSD [ADVAPI32.@]
1341  *
1342  * PARAMS
1343  *   lpabssecdesc  []
1344  *   lpselfsecdesc []
1345  *   lpbuflen      []
1346  */
1347 BOOL WINAPI
1348 MakeSelfRelativeSD(
1349         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1350         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1351         IN OUT LPDWORD lpdwBufferLength)
1352 {
1353     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1354                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1355 }
1356
1357 /******************************************************************************
1358  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1359  */
1360
1361 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1362                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1363 {
1364     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1365 }
1366
1367 /******************************************************************************
1368  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1369  */
1370 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1371   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1372   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1373 {
1374     return set_ntstatus( RtlSetControlSecurityDescriptor(
1375         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1376 }
1377
1378 /*      ##############################
1379         ######  ACL FUNCTIONS   ######
1380         ##############################
1381 */
1382
1383 /*************************************************************************
1384  * InitializeAcl [ADVAPI32.@]
1385  */
1386 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1387 {
1388     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1389 }
1390
1391 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1392 {
1393     IO_STATUS_BLOCK io_block;
1394
1395     TRACE("(%p)\n", hNamedPipe);
1396
1397     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1398                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1399 }
1400
1401 /******************************************************************************
1402  *  AddAccessAllowedAce [ADVAPI32.@]
1403  */
1404 BOOL WINAPI AddAccessAllowedAce(
1405         IN OUT PACL pAcl,
1406         IN DWORD dwAceRevision,
1407         IN DWORD AccessMask,
1408         IN PSID pSid)
1409 {
1410     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1411 }
1412
1413 /******************************************************************************
1414  *  AddAccessAllowedAceEx [ADVAPI32.@]
1415  */
1416 BOOL WINAPI AddAccessAllowedAceEx(
1417         IN OUT PACL pAcl,
1418         IN DWORD dwAceRevision,
1419         IN DWORD AceFlags,
1420         IN DWORD AccessMask,
1421         IN PSID pSid)
1422 {
1423     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1424 }
1425
1426 /******************************************************************************
1427  *  AddAccessDeniedAce [ADVAPI32.@]
1428  */
1429 BOOL WINAPI AddAccessDeniedAce(
1430         IN OUT PACL pAcl,
1431         IN DWORD dwAceRevision,
1432         IN DWORD AccessMask,
1433         IN PSID pSid)
1434 {
1435     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1436 }
1437
1438 /******************************************************************************
1439  *  AddAccessDeniedAceEx [ADVAPI32.@]
1440  */
1441 BOOL WINAPI AddAccessDeniedAceEx(
1442         IN OUT PACL pAcl,
1443         IN DWORD dwAceRevision,
1444         IN DWORD AceFlags,
1445         IN DWORD AccessMask,
1446         IN PSID pSid)
1447 {
1448     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1449 }
1450
1451 /******************************************************************************
1452  *  AddAce [ADVAPI32.@]
1453  */
1454 BOOL WINAPI AddAce(
1455         IN OUT PACL pAcl,
1456         IN DWORD dwAceRevision,
1457         IN DWORD dwStartingAceIndex,
1458         LPVOID pAceList,
1459         DWORD nAceListLength)
1460 {
1461     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1462 }
1463
1464 /******************************************************************************
1465  * DeleteAce [ADVAPI32.@]
1466  */
1467 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1468 {
1469     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1470 }
1471
1472 /******************************************************************************
1473  *  FindFirstFreeAce [ADVAPI32.@]
1474  */
1475 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1476 {
1477         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1478 }
1479
1480 /******************************************************************************
1481  * GetAce [ADVAPI32.@]
1482  */
1483 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1484 {
1485     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1486 }
1487
1488 /******************************************************************************
1489  * GetAclInformation [ADVAPI32.@]
1490  */
1491 BOOL WINAPI GetAclInformation(
1492   PACL pAcl,
1493   LPVOID pAclInformation,
1494   DWORD nAclInformationLength,
1495   ACL_INFORMATION_CLASS dwAclInformationClass)
1496 {
1497     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1498                                                nAclInformationLength, dwAclInformationClass));
1499 }
1500
1501 /******************************************************************************
1502  *  IsValidAcl [ADVAPI32.@]
1503  */
1504 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1505 {
1506         return RtlValidAcl(pAcl);
1507 }
1508
1509 /*      ##############################
1510         ######  MISC FUNCTIONS  ######
1511         ##############################
1512 */
1513
1514 /******************************************************************************
1515  * AllocateLocallyUniqueId [ADVAPI32.@]
1516  *
1517  * PARAMS
1518  *   lpLuid []
1519  */
1520 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1521 {
1522     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1523 }
1524
1525 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1526  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1527 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1528  { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1529 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1530  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1531 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1532  { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1533 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1534  { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1535 static const WCHAR SE_TCB_NAME_W[] =
1536  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1537 static const WCHAR SE_SECURITY_NAME_W[] =
1538  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1539 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1540  { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1541 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1542  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1543 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1544  { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1545 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1546  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1547 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1548  { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1549 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1550  { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1551 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1552  { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1553 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1554  { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1555 static const WCHAR SE_BACKUP_NAME_W[] =
1556  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1557 static const WCHAR SE_RESTORE_NAME_W[] =
1558  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1559 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1560  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1561 static const WCHAR SE_DEBUG_NAME_W[] =
1562  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1563 static const WCHAR SE_AUDIT_NAME_W[] =
1564  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1565 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1566  { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1567 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1568  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1570  { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1571 static const WCHAR SE_UNDOCK_NAME_W[] =
1572  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1574  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1575 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1576  { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1578  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1580  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1581 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1582  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1583
1584 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1585 {
1586     NULL,
1587     NULL,
1588     SE_CREATE_TOKEN_NAME_W,
1589     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1590     SE_LOCK_MEMORY_NAME_W,
1591     SE_INCREASE_QUOTA_NAME_W,
1592     SE_MACHINE_ACCOUNT_NAME_W,
1593     SE_TCB_NAME_W,
1594     SE_SECURITY_NAME_W,
1595     SE_TAKE_OWNERSHIP_NAME_W,
1596     SE_LOAD_DRIVER_NAME_W,
1597     SE_SYSTEM_PROFILE_NAME_W,
1598     SE_SYSTEMTIME_NAME_W,
1599     SE_PROF_SINGLE_PROCESS_NAME_W,
1600     SE_INC_BASE_PRIORITY_NAME_W,
1601     SE_CREATE_PAGEFILE_NAME_W,
1602     SE_CREATE_PERMANENT_NAME_W,
1603     SE_BACKUP_NAME_W,
1604     SE_RESTORE_NAME_W,
1605     SE_SHUTDOWN_NAME_W,
1606     SE_DEBUG_NAME_W,
1607     SE_AUDIT_NAME_W,
1608     SE_SYSTEM_ENVIRONMENT_NAME_W,
1609     SE_CHANGE_NOTIFY_NAME_W,
1610     SE_REMOTE_SHUTDOWN_NAME_W,
1611     SE_UNDOCK_NAME_W,
1612     SE_SYNC_AGENT_NAME_W,
1613     SE_ENABLE_DELEGATION_NAME_W,
1614     SE_MANAGE_VOLUME_NAME_W,
1615     SE_IMPERSONATE_NAME_W,
1616     SE_CREATE_GLOBAL_NAME_W,
1617 };
1618
1619 /******************************************************************************
1620  * LookupPrivilegeValueW                        [ADVAPI32.@]
1621  *
1622  * See LookupPrivilegeValueA.
1623  */
1624 BOOL WINAPI
1625 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1626 {
1627     UINT i;
1628
1629     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1630
1631     if (!ADVAPI_IsLocalComputer(lpSystemName))
1632     {
1633         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1634         return FALSE;
1635     }
1636     if (!lpName)
1637     {
1638         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1639         return FALSE;
1640     }
1641     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1642     {
1643         if( !WellKnownPrivNames[i] )
1644             continue;
1645         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1646             continue;
1647         lpLuid->LowPart = i;
1648         lpLuid->HighPart = 0;
1649         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1650                lpLuid->HighPart, lpLuid->LowPart );
1651         return TRUE;
1652     }
1653     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1654     return FALSE;
1655 }
1656
1657 /******************************************************************************
1658  * LookupPrivilegeValueA                        [ADVAPI32.@]
1659  *
1660  * Retrieves LUID used on a system to represent the privilege name.
1661  *
1662  * PARAMS
1663  *  lpSystemName [I] Name of the system
1664  *  lpName       [I] Name of the privilege
1665  *  lpLuid       [O] Destination for the resulting LUID
1666  *
1667  * RETURNS
1668  *  Success: TRUE. lpLuid contains the requested LUID.
1669  *  Failure: FALSE.
1670  */
1671 BOOL WINAPI
1672 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1673 {
1674     UNICODE_STRING lpSystemNameW;
1675     UNICODE_STRING lpNameW;
1676     BOOL ret;
1677
1678     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1679     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1680     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1681     RtlFreeUnicodeString(&lpNameW);
1682     RtlFreeUnicodeString(&lpSystemNameW);
1683     return ret;
1684 }
1685
1686 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1687                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1688 {
1689     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1690           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1691
1692     return FALSE;
1693 }
1694
1695 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1696                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1697 {
1698     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1699           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1700
1701     return FALSE;
1702 }
1703
1704 /******************************************************************************
1705  * LookupPrivilegeNameA                 [ADVAPI32.@]
1706  *
1707  * See LookupPrivilegeNameW.
1708  */
1709 BOOL WINAPI
1710 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1711  LPDWORD cchName)
1712 {
1713     UNICODE_STRING lpSystemNameW;
1714     BOOL ret;
1715     DWORD wLen = 0;
1716
1717     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1718
1719     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1720     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1721     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1722     {
1723         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1724
1725         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1726          &wLen);
1727         if (ret)
1728         {
1729             /* Windows crashes if cchName is NULL, so will I */
1730             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1731              *cchName, NULL, NULL);
1732
1733             if (len == 0)
1734             {
1735                 /* WideCharToMultiByte failed */
1736                 ret = FALSE;
1737             }
1738             else if (len > *cchName)
1739             {
1740                 *cchName = len;
1741                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1742                 ret = FALSE;
1743             }
1744             else
1745             {
1746                 /* WideCharToMultiByte succeeded, output length needs to be
1747                  * length not including NULL terminator
1748                  */
1749                 *cchName = len - 1;
1750             }
1751         }
1752         HeapFree(GetProcessHeap(), 0, lpNameW);
1753     }
1754     RtlFreeUnicodeString(&lpSystemNameW);
1755     return ret;
1756 }
1757
1758 /******************************************************************************
1759  * LookupPrivilegeNameW                 [ADVAPI32.@]
1760  *
1761  * Retrieves the privilege name referred to by the LUID lpLuid.
1762  *
1763  * PARAMS
1764  *  lpSystemName [I]   Name of the system
1765  *  lpLuid       [I]   Privilege value
1766  *  lpName       [O]   Name of the privilege
1767  *  cchName      [I/O] Number of characters in lpName.
1768  *
1769  * RETURNS
1770  *  Success: TRUE. lpName contains the name of the privilege whose value is
1771  *  *lpLuid.
1772  *  Failure: FALSE.
1773  *
1774  * REMARKS
1775  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1776  *  using this function.
1777  *  If the length of lpName is too small, on return *cchName will contain the
1778  *  number of WCHARs needed to contain the privilege, including the NULL
1779  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1780  *  On success, *cchName will contain the number of characters stored in
1781  *  lpName, NOT including the NULL terminator.
1782  */
1783 BOOL WINAPI
1784 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1785  LPDWORD cchName)
1786 {
1787     size_t privNameLen;
1788
1789     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1790
1791     if (!ADVAPI_IsLocalComputer(lpSystemName))
1792     {
1793         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1794         return FALSE;
1795     }
1796     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1797      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1798     {
1799         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1800         return FALSE;
1801     }
1802     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1803     /* Windows crashes if cchName is NULL, so will I */
1804     if (*cchName <= privNameLen)
1805     {
1806         *cchName = privNameLen + 1;
1807         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1808         return FALSE;
1809     }
1810     else
1811     {
1812         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1813         *cchName = privNameLen;
1814         return TRUE;
1815     }
1816 }
1817
1818 /******************************************************************************
1819  * GetFileSecurityA [ADVAPI32.@]
1820  *
1821  * Obtains Specified information about the security of a file or directory.
1822  *
1823  * PARAMS
1824  *  lpFileName           [I] Name of the file to get info for
1825  *  RequestedInformation [I] SE_ flags from "winnt.h"
1826  *  pSecurityDescriptor  [O] Destination for security information
1827  *  nLength              [I] Length of pSecurityDescriptor
1828  *  lpnLengthNeeded      [O] Destination for length of returned security information
1829  *
1830  * RETURNS
1831  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1832  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1833  *
1834  * NOTES
1835  *  The information returned is constrained by the callers access rights and
1836  *  privileges.
1837  */
1838 BOOL WINAPI
1839 GetFileSecurityA( LPCSTR lpFileName,
1840                     SECURITY_INFORMATION RequestedInformation,
1841                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1842                     DWORD nLength, LPDWORD lpnLengthNeeded )
1843 {
1844     DWORD len;
1845     BOOL r;
1846     LPWSTR name = NULL;
1847
1848     if( lpFileName )
1849     {
1850         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1851         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1852         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1853     }
1854
1855     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1856                           nLength, lpnLengthNeeded );
1857     HeapFree( GetProcessHeap(), 0, name );
1858
1859     return r;
1860 }
1861
1862 /******************************************************************************
1863  * GetFileSecurityW [ADVAPI32.@]
1864  *
1865  * See GetFileSecurityA.
1866  */
1867 BOOL WINAPI
1868 GetFileSecurityW( LPCWSTR lpFileName,
1869                     SECURITY_INFORMATION RequestedInformation,
1870                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1871                     DWORD nLength, LPDWORD lpnLengthNeeded )
1872 {
1873     HANDLE hfile;
1874     NTSTATUS status;
1875     DWORD access = 0;
1876
1877     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1878                                 DACL_SECURITY_INFORMATION))
1879         access |= READ_CONTROL;
1880     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1881         access |= ACCESS_SYSTEM_SECURITY;
1882
1883     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1884                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1885     if ( hfile == INVALID_HANDLE_VALUE )
1886         return FALSE;
1887
1888     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1889                                     nLength, lpnLengthNeeded );
1890     CloseHandle( hfile );
1891     return set_ntstatus( status );
1892 }
1893
1894
1895 /******************************************************************************
1896  * LookupAccountSidA [ADVAPI32.@]
1897  */
1898 BOOL WINAPI
1899 LookupAccountSidA(
1900         IN LPCSTR system,
1901         IN PSID sid,
1902         OUT LPSTR account,
1903         IN OUT LPDWORD accountSize,
1904         OUT LPSTR domain,
1905         IN OUT LPDWORD domainSize,
1906         OUT PSID_NAME_USE name_use )
1907 {
1908     DWORD len;
1909     BOOL r;
1910     LPWSTR systemW = NULL;
1911     LPWSTR accountW = NULL;
1912     LPWSTR domainW = NULL;
1913     DWORD accountSizeW = *accountSize;
1914     DWORD domainSizeW = *domainSize;
1915
1916     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1917           debugstr_a(system),debugstr_sid(sid),
1918           account,accountSize,accountSize?*accountSize:0,
1919           domain,domainSize,domainSize?*domainSize:0,
1920           name_use);
1921
1922     if (system) {
1923         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1924         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1925         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1926     }
1927     if (account)
1928         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1929     if (domain)
1930         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1931
1932     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1933
1934     if (r) {
1935         if (accountW && *accountSize) {
1936             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1937             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1938             *accountSize = len;
1939         } else
1940             *accountSize = accountSizeW + 1;
1941
1942         if (domainW && *domainSize) {
1943             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1944             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1945             *domainSize = len;
1946         } else
1947             *domainSize = domainSizeW + 1;
1948     }
1949
1950     HeapFree( GetProcessHeap(), 0, systemW );
1951     HeapFree( GetProcessHeap(), 0, accountW );
1952     HeapFree( GetProcessHeap(), 0, domainW );
1953
1954     return r;
1955 }
1956
1957 /******************************************************************************
1958  * LookupAccountSidW [ADVAPI32.@]
1959  *
1960  * PARAMS
1961  *   system      []
1962  *   sid         []
1963  *   account     []
1964  *   accountSize []
1965  *   domain      []
1966  *   domainSize  []
1967  *   name_use    []
1968  */
1969
1970 BOOL WINAPI
1971 LookupAccountSidW(
1972         IN LPCWSTR system,
1973         IN PSID sid,
1974         OUT LPWSTR account,
1975         IN OUT LPDWORD accountSize,
1976         OUT LPWSTR domain,
1977         IN OUT LPDWORD domainSize,
1978         OUT PSID_NAME_USE name_use )
1979 {
1980     unsigned int i, j;
1981     const WCHAR * ac = NULL;
1982     const WCHAR * dm = NULL;
1983     SID_NAME_USE use = 0;
1984     LPWSTR computer_name = NULL;
1985
1986     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1987           debugstr_w(system),debugstr_sid(sid),
1988           account,accountSize,accountSize?*accountSize:0,
1989           domain,domainSize,domainSize?*domainSize:0,
1990           name_use);
1991
1992     if (!ADVAPI_IsLocalComputer(system)) {
1993         FIXME("Only local computer supported!\n");
1994         SetLastError(ERROR_NONE_MAPPED);
1995         return FALSE;
1996     }
1997
1998     /* check the well known SIDs first */
1999     for (i = 0; i <= 60; i++) {
2000         if (IsWellKnownSid(sid, i)) {
2001             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2002                 if (ACCOUNT_SIDS[j].type == i) {
2003                     ac = ACCOUNT_SIDS[j].account;
2004                     dm = ACCOUNT_SIDS[j].domain;
2005                     use = ACCOUNT_SIDS[j].name_use;
2006                 }
2007             }
2008             break;
2009         }
2010     }
2011
2012     if (dm == NULL) {
2013         MAX_SID local;
2014
2015         /* check for the local computer next */
2016         if (ADVAPI_GetComputerSid(&local)) {
2017             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2018             BOOL result;
2019
2020             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2021             result = GetComputerNameW(computer_name,  &size);
2022
2023             if (result) {
2024                 if (EqualSid(sid, &local)) {
2025                     dm = computer_name;
2026                     ac = Blank;
2027                     use = 3;
2028                 } else {
2029                     local.SubAuthorityCount++;
2030
2031                     if (EqualPrefixSid(sid, &local)) {
2032                         dm = computer_name;
2033                         use = 1;
2034                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2035                         case DOMAIN_USER_RID_ADMIN:
2036                             ac = Administrator;
2037                             break;
2038                         case DOMAIN_USER_RID_GUEST:
2039                             ac = Guest;
2040                             break;
2041                         case DOMAIN_GROUP_RID_ADMINS:
2042                             ac = Domain_Admins;
2043                             break;
2044                         case DOMAIN_GROUP_RID_USERS:
2045                             ac = Domain_Users;
2046                             break;
2047                         case DOMAIN_GROUP_RID_GUESTS:
2048                             ac = Domain_Guests;
2049                             break;
2050                         case DOMAIN_GROUP_RID_COMPUTERS:
2051                             ac = Domain_Computers;
2052                             break;
2053                         case DOMAIN_GROUP_RID_CONTROLLERS:
2054                             ac = Domain_Controllers;
2055                             break;
2056                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2057                             ac = Cert_Publishers;
2058                             break;
2059                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2060                             ac = Schema_Admins;
2061                             break;
2062                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2063                             ac = Enterprise_Admins;
2064                             break;
2065                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2066                             ac = Group_Policy_Creator_Owners;
2067                             break;
2068                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2069                             ac = RAS_and_IAS_Servers;
2070                             break;
2071                         default:
2072                             dm = NULL;
2073                             break;
2074                         }
2075                     }
2076                 }
2077             }
2078         }
2079     }
2080
2081     if (dm) {
2082         BOOL status = TRUE;
2083         if (*accountSize > lstrlenW(ac)) {
2084             if (account)
2085                 lstrcpyW(account, ac);
2086         }
2087         if (*domainSize > lstrlenW(dm)) {
2088             if (domain)
2089                 lstrcpyW(domain, dm);
2090         }
2091         if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2092             ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2093             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2094             status = FALSE;
2095         }
2096         if (*domainSize)
2097             *domainSize = strlenW(dm);
2098         else
2099             *domainSize = strlenW(dm) + 1;
2100         if (*accountSize)
2101             *accountSize = strlenW(ac);
2102         else
2103             *accountSize = strlenW(ac) + 1;
2104         *name_use = use;
2105         HeapFree(GetProcessHeap(), 0, computer_name);
2106         return status;
2107     }
2108
2109     HeapFree(GetProcessHeap(), 0, computer_name);
2110     SetLastError(ERROR_NONE_MAPPED);
2111     return FALSE;
2112 }
2113
2114 /******************************************************************************
2115  * SetFileSecurityA [ADVAPI32.@]
2116  *
2117  * See SetFileSecurityW.
2118  */
2119 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2120                                 SECURITY_INFORMATION RequestedInformation,
2121                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2122 {
2123     DWORD len;
2124     BOOL r;
2125     LPWSTR name = NULL;
2126
2127     if( lpFileName )
2128     {
2129         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2130         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2131         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2132     }
2133
2134     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2135     HeapFree( GetProcessHeap(), 0, name );
2136
2137     return r;
2138 }
2139
2140 /******************************************************************************
2141  * SetFileSecurityW [ADVAPI32.@]
2142  *
2143  * Sets the security of a file or directory.
2144  *
2145  * PARAMS
2146  *   lpFileName           []
2147  *   RequestedInformation []
2148  *   pSecurityDescriptor  []
2149  *
2150  * RETURNS
2151  *  Success: TRUE.
2152  *  Failure: FALSE.
2153  */
2154 BOOL WINAPI
2155 SetFileSecurityW( LPCWSTR lpFileName,
2156                     SECURITY_INFORMATION RequestedInformation,
2157                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2158 {
2159     HANDLE file;
2160     DWORD access = 0;
2161     NTSTATUS status;
2162
2163     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2164           pSecurityDescriptor );
2165
2166     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2167         RequestedInformation & GROUP_SECURITY_INFORMATION)
2168         access |= WRITE_OWNER;
2169     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2170         access |= ACCESS_SYSTEM_SECURITY;
2171     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2172         access |= WRITE_DAC;
2173
2174     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2175                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2176     if (file == INVALID_HANDLE_VALUE)
2177         return FALSE;
2178
2179     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2180     CloseHandle( file );
2181     return set_ntstatus( status );
2182 }
2183
2184 /******************************************************************************
2185  * QueryWindows31FilesMigration [ADVAPI32.@]
2186  *
2187  * PARAMS
2188  *   x1 []
2189  */
2190 BOOL WINAPI
2191 QueryWindows31FilesMigration( DWORD x1 )
2192 {
2193         FIXME("(%d):stub\n",x1);
2194         return TRUE;
2195 }
2196
2197 /******************************************************************************
2198  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2199  *
2200  * PARAMS
2201  *   x1 []
2202  *   x2 []
2203  *   x3 []
2204  *   x4 []
2205  */
2206 BOOL WINAPI
2207 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2208                                                DWORD x4 )
2209 {
2210         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2211         return TRUE;
2212 }
2213
2214 /******************************************************************************
2215  * NotifyBootConfigStatus [ADVAPI32.@]
2216  *
2217  * PARAMS
2218  *   x1 []
2219  */
2220 BOOL WINAPI
2221 NotifyBootConfigStatus( BOOL x1 )
2222 {
2223         FIXME("(0x%08d):stub\n",x1);
2224         return 1;
2225 }
2226
2227 /******************************************************************************
2228  * RevertToSelf [ADVAPI32.@]
2229  *
2230  * Ends the impersonation of a user.
2231  *
2232  * PARAMS
2233  *   void []
2234  *
2235  * RETURNS
2236  *  Success: TRUE.
2237  *  Failure: FALSE.
2238  */
2239 BOOL WINAPI
2240 RevertToSelf( void )
2241 {
2242     HANDLE Token = NULL;
2243     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2244         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2245 }
2246
2247 /******************************************************************************
2248  * ImpersonateSelf [ADVAPI32.@]
2249  *
2250  * Makes an impersonation token that represents the process user and assigns
2251  * to the current thread.
2252  *
2253  * PARAMS
2254  *  ImpersonationLevel [I] Level at which to impersonate.
2255  *
2256  * RETURNS
2257  *  Success: TRUE.
2258  *  Failure: FALSE.
2259  */
2260 BOOL WINAPI
2261 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2262 {
2263     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2264 }
2265
2266 /******************************************************************************
2267  * ImpersonateLoggedOnUser [ADVAPI32.@]
2268  */
2269 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2270 {
2271     DWORD size;
2272     NTSTATUS Status;
2273     HANDLE ImpersonationToken;
2274     TOKEN_TYPE Type;
2275
2276     FIXME( "(%p)\n", hToken );
2277
2278     if (!GetTokenInformation( hToken, TokenType, &Type,
2279                               sizeof(TOKEN_TYPE), &size ))
2280         return FALSE;
2281
2282     if (Type == TokenPrimary)
2283     {
2284         OBJECT_ATTRIBUTES ObjectAttributes;
2285
2286         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2287
2288         Status = NtDuplicateToken( hToken,
2289                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2290                                    &ObjectAttributes,
2291                                    SecurityImpersonation,
2292                                    TokenImpersonation,
2293                                    &ImpersonationToken );
2294         if (Status != STATUS_SUCCESS)
2295         {
2296             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2297             SetLastError( RtlNtStatusToDosError( Status ) );
2298             return FALSE;
2299         }
2300     }
2301     else
2302         ImpersonationToken = hToken;
2303
2304     Status = NtSetInformationThread( GetCurrentThread(),
2305                                      ThreadImpersonationToken,
2306                                      &ImpersonationToken,
2307                                      sizeof(ImpersonationToken) );
2308
2309     if (Type == TokenPrimary)
2310         NtClose( ImpersonationToken );
2311
2312     if (Status != STATUS_SUCCESS)
2313     {
2314         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2315         SetLastError( RtlNtStatusToDosError( Status ) );
2316         return FALSE;
2317     }
2318
2319     return TRUE;
2320 }
2321
2322 /******************************************************************************
2323  * AccessCheck [ADVAPI32.@]
2324  */
2325 BOOL WINAPI
2326 AccessCheck(
2327         PSECURITY_DESCRIPTOR SecurityDescriptor,
2328         HANDLE ClientToken,
2329         DWORD DesiredAccess,
2330         PGENERIC_MAPPING GenericMapping,
2331         PPRIVILEGE_SET PrivilegeSet,
2332         LPDWORD PrivilegeSetLength,
2333         LPDWORD GrantedAccess,
2334         LPBOOL AccessStatus)
2335 {
2336     NTSTATUS access_status;
2337     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2338                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2339                                            GrantedAccess, &access_status) );
2340     if (ret) *AccessStatus = set_ntstatus( access_status );
2341     return ret;
2342 }
2343
2344
2345 /******************************************************************************
2346  * AccessCheckByType [ADVAPI32.@]
2347  */
2348 BOOL WINAPI AccessCheckByType(
2349     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2350     PSID PrincipalSelfSid,
2351     HANDLE ClientToken, 
2352     DWORD DesiredAccess, 
2353     POBJECT_TYPE_LIST ObjectTypeList,
2354     DWORD ObjectTypeListLength,
2355     PGENERIC_MAPPING GenericMapping,
2356     PPRIVILEGE_SET PrivilegeSet,
2357     LPDWORD PrivilegeSetLength, 
2358     LPDWORD GrantedAccess,
2359     LPBOOL AccessStatus)
2360 {
2361         FIXME("stub\n");
2362
2363         *AccessStatus = TRUE;
2364
2365         return !*AccessStatus;
2366 }
2367
2368 /******************************************************************************
2369  * MapGenericMask [ADVAPI32.@]
2370  *
2371  * Maps generic access rights into specific access rights according to the
2372  * supplied mapping.
2373  *
2374  * PARAMS
2375  *  AccessMask     [I/O] Access rights.
2376  *  GenericMapping [I] The mapping between generic and specific rights.
2377  *
2378  * RETURNS
2379  *  Nothing.
2380  */
2381 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2382 {
2383     RtlMapGenericMask( AccessMask, GenericMapping );
2384 }
2385
2386 /*************************************************************************
2387  * SetKernelObjectSecurity [ADVAPI32.@]
2388  */
2389 BOOL WINAPI SetKernelObjectSecurity (
2390         IN HANDLE Handle,
2391         IN SECURITY_INFORMATION SecurityInformation,
2392         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2393 {
2394     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2395 }
2396
2397
2398 /******************************************************************************
2399  *  AddAuditAccessAce [ADVAPI32.@]
2400  */
2401 BOOL WINAPI AddAuditAccessAce(
2402     IN OUT PACL pAcl, 
2403     IN DWORD dwAceRevision, 
2404     IN DWORD dwAccessMask, 
2405     IN PSID pSid, 
2406     IN BOOL bAuditSuccess, 
2407     IN BOOL bAuditFailure) 
2408 {
2409     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2410                                               bAuditSuccess, bAuditFailure) ); 
2411 }
2412
2413 /******************************************************************************
2414  *  AddAuditAccessAce [ADVAPI32.@]
2415  */
2416 BOOL WINAPI AddAuditAccessAceEx(
2417     IN OUT PACL pAcl,
2418     IN DWORD dwAceRevision,
2419     IN DWORD dwAceFlags,
2420     IN DWORD dwAccessMask,
2421     IN PSID pSid,
2422     IN BOOL bAuditSuccess,
2423     IN BOOL bAuditFailure)
2424 {
2425     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2426                                               bAuditSuccess, bAuditFailure) );
2427 }
2428
2429 /******************************************************************************
2430  * LookupAccountNameA [ADVAPI32.@]
2431  */
2432 BOOL WINAPI
2433 LookupAccountNameA(
2434         IN LPCSTR system,
2435         IN LPCSTR account,
2436         OUT PSID sid,
2437         OUT LPDWORD cbSid,
2438         LPSTR ReferencedDomainName,
2439         IN OUT LPDWORD cbReferencedDomainName,
2440         OUT PSID_NAME_USE name_use )
2441 {
2442     BOOL ret;
2443     UNICODE_STRING lpSystemW;
2444     UNICODE_STRING lpAccountW;
2445     LPWSTR lpReferencedDomainNameW = NULL;
2446
2447     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2448     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2449
2450     if (ReferencedDomainName)
2451         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2452
2453     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2454         cbReferencedDomainName, name_use);
2455
2456     if (ret && lpReferencedDomainNameW)
2457     {
2458         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2459             ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2460     }
2461
2462     RtlFreeUnicodeString(&lpSystemW);
2463     RtlFreeUnicodeString(&lpAccountW);
2464     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2465
2466     return ret;
2467 }
2468
2469 /******************************************************************************
2470  * LookupAccountNameW [ADVAPI32.@]
2471  */
2472 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2473                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2474                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2475 {
2476     /* Default implementation: Always return a default SID */
2477     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2478     BOOL ret;
2479     PSID pSid;
2480     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2481
2482     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2483           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2484
2485     ret = AllocateAndInitializeSid(&identifierAuthority,
2486         2,
2487         SECURITY_BUILTIN_DOMAIN_RID,
2488         DOMAIN_ALIAS_RID_ADMINS,
2489         0, 0, 0, 0, 0, 0,
2490         &pSid);
2491
2492     if (!ret)
2493        return FALSE;
2494
2495     if (!RtlValidSid(pSid))
2496     {
2497        FreeSid(pSid);
2498        return FALSE;
2499     }
2500
2501     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2502        CopySid(*cbSid, Sid, pSid);
2503     if (*cbSid < GetLengthSid(pSid))
2504     {
2505        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2506        ret = FALSE;
2507     }
2508     *cbSid = GetLengthSid(pSid);
2509     
2510     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2511       strcpyW(ReferencedDomainName, dm);
2512
2513     if (*cchReferencedDomainName <= strlenW(dm))
2514     {
2515        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2516        ret = FALSE;
2517     }
2518
2519     *cchReferencedDomainName = strlenW(dm)+1;
2520
2521     FreeSid(pSid);
2522
2523     return ret;
2524 }
2525
2526 /******************************************************************************
2527  * PrivilegeCheck [ADVAPI32.@]
2528  */
2529 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2530 {
2531     BOOL ret;
2532     BOOLEAN Result;
2533
2534     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2535
2536     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2537     if (ret)
2538         *pfResult = Result;
2539     return ret;
2540 }
2541
2542 /******************************************************************************
2543  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2544  */
2545 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2546   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2547   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2548   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2549 {
2550         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2551                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2552                 SecurityDescriptor, DesiredAccess, GenericMapping,
2553                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2554         return TRUE;
2555 }
2556
2557 /******************************************************************************
2558  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2559  */
2560 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2561   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2562   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2563   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2564 {
2565         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2566                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2567                 SecurityDescriptor, DesiredAccess, GenericMapping,
2568                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2569         return TRUE;
2570 }
2571
2572 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2573 {
2574     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2575
2576     return TRUE;
2577 }
2578
2579 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2580 {
2581     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2582
2583     return TRUE;
2584 }
2585
2586 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2587 {
2588     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2589
2590     return TRUE;
2591 }
2592
2593 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2594   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2595   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2596   LPBOOL GenerateOnClose)
2597 {
2598         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2599                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2600         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2601         GenerateOnClose);
2602
2603     return TRUE;
2604 }
2605
2606 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2607   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2608   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2609   LPBOOL GenerateOnClose)
2610 {
2611     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2612         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2613         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2614         GenerateOnClose);
2615
2616     return TRUE;
2617 }
2618
2619 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2620   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2621 {
2622     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2623           DesiredAccess, Privileges, AccessGranted);
2624
2625     return TRUE;
2626 }
2627
2628 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2629   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2630 {
2631     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2632           DesiredAccess, Privileges, AccessGranted);
2633
2634     return TRUE;
2635 }
2636
2637 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2638                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2639 {
2640     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2641           ClientToken, Privileges, AccessGranted);
2642
2643     return TRUE;
2644 }
2645
2646 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2647                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2648 {
2649     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2650           ClientToken, Privileges, AccessGranted);
2651
2652     return TRUE;
2653 }
2654
2655 /******************************************************************************
2656  * GetSecurityInfo [ADVAPI32.@]
2657  */
2658 DWORD WINAPI GetSecurityInfo(
2659     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2660     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2661     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2662     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2663 )
2664 {
2665   FIXME("stub!\n");
2666   return ERROR_BAD_PROVIDER;
2667 }
2668
2669 /******************************************************************************
2670  * GetSecurityInfoExW [ADVAPI32.@]
2671  */
2672 DWORD WINAPI GetSecurityInfoExW(
2673         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2674         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2675         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2676         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2677 )
2678 {
2679   FIXME("stub!\n");
2680   return ERROR_BAD_PROVIDER; 
2681 }
2682
2683 /******************************************************************************
2684  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2685  */
2686 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2687                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2688                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2689 {
2690     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2691           AccessPermissions, AccessMode, Inheritance);
2692
2693     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2694     pExplicitAccess->grfAccessMode = AccessMode;
2695     pExplicitAccess->grfInheritance = Inheritance;
2696
2697     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2698     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2699     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2700     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2701     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2702 }
2703
2704 /******************************************************************************
2705  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2706  */
2707 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2708                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2709                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2710 {
2711     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2712           AccessPermissions, AccessMode, Inheritance);
2713
2714     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2715     pExplicitAccess->grfAccessMode = AccessMode;
2716     pExplicitAccess->grfInheritance = Inheritance;
2717
2718     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2719     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2720     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2721     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2722     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2723 }
2724
2725 /******************************************************************************
2726  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2727  */
2728 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2729                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2730                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2731 {
2732     DWORD ObjectsPresent = 0;
2733
2734     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2735           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2736
2737     /* Fill the OBJECTS_AND_NAME structure */
2738     pObjName->ObjectType = ObjectType;
2739     if (ObjectTypeName != NULL)
2740     {
2741         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2742     }
2743
2744     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2745     if (InheritedObjectTypeName != NULL)
2746     {
2747         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2748     }
2749
2750     pObjName->ObjectsPresent = ObjectsPresent;
2751     pObjName->ptstrName = Name;
2752
2753     /* Fill the TRUSTEE structure */
2754     pTrustee->pMultipleTrustee = NULL;
2755     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2756     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2757     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2758     pTrustee->ptstrName = (LPSTR)pObjName;
2759 }
2760
2761 /******************************************************************************
2762  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2763  */
2764 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2765                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2766                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2767 {
2768     DWORD ObjectsPresent = 0;
2769
2770     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2771           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2772
2773     /* Fill the OBJECTS_AND_NAME structure */
2774     pObjName->ObjectType = ObjectType;
2775     if (ObjectTypeName != NULL)
2776     {
2777         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2778     }
2779
2780     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2781     if (InheritedObjectTypeName != NULL)
2782     {
2783         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2784     }
2785
2786     pObjName->ObjectsPresent = ObjectsPresent;
2787     pObjName->ptstrName = Name;
2788
2789     /* Fill the TRUSTEE structure */
2790     pTrustee->pMultipleTrustee = NULL;
2791     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2792     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2793     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2794     pTrustee->ptstrName = (LPWSTR)pObjName;
2795 }
2796
2797 /******************************************************************************
2798  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2799  */
2800 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2801                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2802 {
2803     DWORD ObjectsPresent = 0;
2804
2805     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2806
2807     /* Fill the OBJECTS_AND_SID structure */
2808     if (pObjectGuid != NULL)
2809     {
2810         pObjSid->ObjectTypeGuid = *pObjectGuid;
2811         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2812     }
2813     else
2814     {
2815         ZeroMemory(&pObjSid->ObjectTypeGuid,
2816                    sizeof(GUID));
2817     }
2818
2819     if (pInheritedObjectGuid != NULL)
2820     {
2821         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2822         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2823     }
2824     else
2825     {
2826         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2827                    sizeof(GUID));
2828     }
2829
2830     pObjSid->ObjectsPresent = ObjectsPresent;
2831     pObjSid->pSid = pSid;
2832
2833     /* Fill the TRUSTEE structure */
2834     pTrustee->pMultipleTrustee = NULL;
2835     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2836     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2837     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2838     pTrustee->ptstrName = (LPSTR) pObjSid;
2839 }
2840
2841 /******************************************************************************
2842  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2843  */
2844 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2845                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2846 {
2847     DWORD ObjectsPresent = 0;
2848
2849     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2850
2851     /* Fill the OBJECTS_AND_SID structure */
2852     if (pObjectGuid != NULL)
2853     {
2854         pObjSid->ObjectTypeGuid = *pObjectGuid;
2855         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2856     }
2857     else
2858     {
2859         ZeroMemory(&pObjSid->ObjectTypeGuid,
2860                    sizeof(GUID));
2861     }
2862
2863     if (pInheritedObjectGuid != NULL)
2864     {
2865         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2866         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2867     }
2868     else
2869     {
2870         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2871                    sizeof(GUID));
2872     }
2873
2874     pObjSid->ObjectsPresent = ObjectsPresent;
2875     pObjSid->pSid = pSid;
2876
2877     /* Fill the TRUSTEE structure */
2878     pTrustee->pMultipleTrustee = NULL;
2879     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2880     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2881     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2882     pTrustee->ptstrName = (LPWSTR) pObjSid;
2883 }
2884
2885 /******************************************************************************
2886  * BuildTrusteeWithSidA [ADVAPI32.@]
2887  */
2888 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2889 {
2890     TRACE("%p %p\n", pTrustee, pSid);
2891
2892     pTrustee->pMultipleTrustee = NULL;
2893     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2894     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2895     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2896     pTrustee->ptstrName = (LPSTR) pSid;
2897 }
2898
2899 /******************************************************************************
2900  * BuildTrusteeWithSidW [ADVAPI32.@]
2901  */
2902 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2903 {
2904     TRACE("%p %p\n", pTrustee, pSid);
2905
2906     pTrustee->pMultipleTrustee = NULL;
2907     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2908     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2909     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2910     pTrustee->ptstrName = (LPWSTR) pSid;
2911 }
2912
2913 /******************************************************************************
2914  * BuildTrusteeWithNameA [ADVAPI32.@]
2915  */
2916 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2917 {
2918     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2919
2920     pTrustee->pMultipleTrustee = NULL;
2921     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2922     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2923     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2924     pTrustee->ptstrName = name;
2925 }
2926
2927 /******************************************************************************
2928  * BuildTrusteeWithNameW [ADVAPI32.@]
2929  */
2930 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2931 {
2932     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2933
2934     pTrustee->pMultipleTrustee = NULL;
2935     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2936     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2937     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2938     pTrustee->ptstrName = name;
2939 }
2940
2941 /****************************************************************************** 
2942  * GetTrusteeFormA [ADVAPI32.@] 
2943  */ 
2944 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2945 {  
2946     TRACE("(%p)\n", pTrustee); 
2947   
2948     if (!pTrustee) 
2949         return TRUSTEE_BAD_FORM; 
2950   
2951     return pTrustee->TrusteeForm; 
2952 }  
2953   
2954 /****************************************************************************** 
2955  * GetTrusteeFormW [ADVAPI32.@] 
2956  */ 
2957 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2958 {  
2959     TRACE("(%p)\n", pTrustee); 
2960   
2961     if (!pTrustee) 
2962         return TRUSTEE_BAD_FORM; 
2963   
2964     return pTrustee->TrusteeForm; 
2965 }  
2966   
2967 /****************************************************************************** 
2968  * GetTrusteeNameA [ADVAPI32.@] 
2969  */ 
2970 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2971 {  
2972     TRACE("(%p)\n", pTrustee); 
2973   
2974     if (!pTrustee) 
2975         return NULL; 
2976   
2977     return pTrustee->ptstrName; 
2978 }  
2979   
2980 /****************************************************************************** 
2981  * GetTrusteeNameW [ADVAPI32.@] 
2982  */ 
2983 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2984 {  
2985     TRACE("(%p)\n", pTrustee); 
2986   
2987     if (!pTrustee) 
2988         return NULL; 
2989   
2990     return pTrustee->ptstrName; 
2991 }  
2992   
2993 /****************************************************************************** 
2994  * GetTrusteeTypeA [ADVAPI32.@] 
2995  */ 
2996 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2997 {  
2998     TRACE("(%p)\n", pTrustee); 
2999   
3000     if (!pTrustee) 
3001         return TRUSTEE_IS_UNKNOWN; 
3002   
3003     return pTrustee->TrusteeType; 
3004 }  
3005   
3006 /****************************************************************************** 
3007  * GetTrusteeTypeW [ADVAPI32.@] 
3008  */ 
3009 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3010 {  
3011     TRACE("(%p)\n", pTrustee); 
3012   
3013     if (!pTrustee) 
3014         return TRUSTEE_IS_UNKNOWN; 
3015   
3016     return pTrustee->TrusteeType; 
3017
3018  
3019 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3020                                DWORD nAclInformationLength,
3021                                ACL_INFORMATION_CLASS dwAclInformationClass )
3022 {
3023     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3024           nAclInformationLength, dwAclInformationClass);
3025
3026     return TRUE;
3027 }
3028
3029 /******************************************************************************
3030  * SetEntriesInAclA [ADVAPI32.@]
3031  */
3032 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3033                                PACL OldAcl, PACL* NewAcl )
3034 {
3035     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3036     *NewAcl = NULL;
3037     return ERROR_SUCCESS;
3038 }
3039
3040 /******************************************************************************
3041  * SetEntriesInAclW [ADVAPI32.@]
3042  */
3043 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3044                                PACL OldAcl, PACL* NewAcl )
3045 {
3046     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3047     *NewAcl = NULL;
3048     return ERROR_SUCCESS;
3049 }
3050
3051 /******************************************************************************
3052  * SetNamedSecurityInfoA [ADVAPI32.@]
3053  */
3054 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3055         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3056         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3057 {
3058     DWORD len;
3059     LPWSTR wstr = NULL;
3060     DWORD r;
3061
3062     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3063            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3064
3065     if( pObjectName )
3066     {
3067         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3068         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3069         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3070     }
3071
3072     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3073                            psidGroup, pDacl, pSacl );
3074
3075     HeapFree( GetProcessHeap(), 0, wstr );
3076
3077     return r;
3078 }
3079
3080 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3081     PSECURITY_DESCRIPTOR ModificationDescriptor,
3082     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3083     PGENERIC_MAPPING GenericMapping,
3084     HANDLE Token )
3085 {
3086     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3087           ObjectsSecurityDescriptor, GenericMapping, Token);
3088
3089     return TRUE;
3090 }
3091
3092 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3093 {
3094     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3095 }
3096
3097 /******************************************************************************
3098  * AreAnyAccessesGranted [ADVAPI32.@]
3099  *
3100  * Determines whether or not any of a set of specified access permissions have
3101  * been granted or not.
3102  *
3103  * PARAMS
3104  *   GrantedAccess [I] The permissions that have been granted.
3105  *   DesiredAccess [I] The permissions that you want to have.
3106  *
3107  * RETURNS
3108  *   Nonzero if any of the permissions have been granted, zero if none of the
3109  *   permissions have been granted.
3110  */
3111
3112 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3113 {
3114     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3115 }
3116
3117 /******************************************************************************
3118  * SetNamedSecurityInfoW [ADVAPI32.@]
3119  */
3120 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3121         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3122         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3123 {
3124     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3125            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3126     return ERROR_SUCCESS;
3127 }
3128
3129 /******************************************************************************
3130  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3131  */
3132 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3133         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3134 {
3135     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3136     return ERROR_CALL_NOT_IMPLEMENTED;
3137 }
3138
3139 /******************************************************************************
3140  * GetExplicitEntriesFromAclW [ADVAPI32.@]
3141  */
3142 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3143         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3144 {
3145     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3146     return ERROR_CALL_NOT_IMPLEMENTED;
3147 }
3148
3149
3150 /******************************************************************************
3151  * ParseAclStringFlags
3152  */
3153 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3154 {
3155     DWORD flags = 0;
3156     LPCWSTR szAcl = *StringAcl;
3157
3158     while (*szAcl != '(')
3159     {
3160         if (*szAcl == 'P')
3161         {
3162             flags |= SE_DACL_PROTECTED;
3163         }
3164         else if (*szAcl == 'A')
3165         {
3166             szAcl++;
3167             if (*szAcl == 'R')
3168                 flags |= SE_DACL_AUTO_INHERIT_REQ;
3169             else if (*szAcl == 'I')
3170                 flags |= SE_DACL_AUTO_INHERITED;
3171         }
3172         szAcl++;
3173     }
3174
3175     *StringAcl = szAcl;
3176     return flags;
3177 }
3178
3179 /******************************************************************************
3180  * ParseAceStringType
3181  */
3182 static const ACEFLAG AceType[] =
3183 {
3184     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
3185     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
3186     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3187     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
3188     /*
3189     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3190     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
3191     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
3192     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3193     */
3194     { NULL, 0 },
3195 };
3196
3197 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3198 {
3199     UINT len = 0;
3200     LPCWSTR szAcl = *StringAcl;
3201     const ACEFLAG *lpaf = AceType;
3202
3203     while (lpaf->wstr &&
3204         (len = strlenW(lpaf->wstr)) &&
3205         strncmpW(lpaf->wstr, szAcl, len))
3206         lpaf++;
3207
3208     if (!lpaf->wstr)
3209         return 0;
3210
3211     *StringAcl += len;
3212     return lpaf->value;
3213 }
3214
3215
3216 /******************************************************************************
3217  * ParseAceStringFlags
3218  */
3219 static const ACEFLAG AceFlags[] =
3220 {
3221     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3222     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
3223     { SDDL_INHERITED,         INHERITED_ACE },
3224     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
3225     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
3226     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
3227     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
3228     { NULL, 0 },
3229 };
3230
3231 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3232 {
3233     UINT len = 0;
3234     BYTE flags = 0;
3235     LPCWSTR szAcl = *StringAcl;
3236
3237     while (*szAcl != ';')
3238     {
3239         const ACEFLAG *lpaf = AceFlags;
3240
3241         while (lpaf->wstr &&
3242                (len = strlenW(lpaf->wstr)) &&
3243                strncmpW(lpaf->wstr, szAcl, len))
3244             lpaf++;
3245
3246         if (!lpaf->wstr)
3247             return 0;
3248
3249         flags |= lpaf->value;
3250         szAcl += len;
3251     }
3252
3253     *StringAcl = szAcl;
3254     return flags;
3255 }
3256
3257
3258 /******************************************************************************
3259  * ParseAceStringRights
3260  */
3261 static const ACEFLAG AceRights[] =
3262 {
3263     { SDDL_GENERIC_ALL,     GENERIC_ALL },
3264     { SDDL_GENERIC_READ,    GENERIC_READ },
3265     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
3266     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3267
3268     { SDDL_READ_CONTROL,    READ_CONTROL },
3269     { SDDL_STANDARD_DELETE, DELETE },
3270     { SDDL_WRITE_DAC,       WRITE_DAC },
3271     { SDDL_WRITE_OWNER,     WRITE_OWNER },
3272
3273     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
3274     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
3275     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
3276     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
3277     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
3278     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
3279     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
3280     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
3281     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
3282
3283     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
3284     { SDDL_FILE_READ,       FILE_GENERIC_READ },
3285     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
3286     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
3287
3288     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
3289     { SDDL_KEY_READ,        KEY_READ },
3290     { SDDL_KEY_WRITE,       KEY_WRITE },
3291     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
3292     { NULL, 0 },
3293 };
3294
3295 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3296 {
3297     UINT len = 0;
3298     DWORD rights = 0;
3299     LPCWSTR szAcl = *StringAcl;
3300
3301     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3302     {
3303         LPCWSTR p = szAcl;
3304
3305         while (*p && *p != ';')
3306             p++;
3307
3308         if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3309         {
3310             rights = strtoulW(szAcl, NULL, 16);
3311             szAcl = p;
3312         }
3313         else
3314             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3315     }
3316     else
3317     {
3318         while (*szAcl != ';')
3319         {
3320             const ACEFLAG *lpaf = AceRights;
3321
3322             while (lpaf->wstr &&
3323                (len = strlenW(lpaf->wstr)) &&
3324                strncmpW(lpaf->wstr, szAcl, len))
3325             {
3326                lpaf++;
3327             }
3328
3329             if (!lpaf->wstr)
3330                 return 0;
3331
3332             rights |= lpaf->value;
3333             szAcl += len;
3334         }
3335     }
3336
3337     *StringAcl = szAcl;
3338     return rights;
3339 }
3340
3341
3342 /******************************************************************************
3343  * ParseStringAclToAcl
3344  * 
3345  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
3346  */
3347 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
3348     PACL pAcl, LPDWORD cBytes)
3349 {
3350     DWORD val;
3351     DWORD sidlen;
3352     DWORD length = sizeof(ACL);
3353     DWORD acesize = 0;
3354     DWORD acecount = 0;
3355     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3356
3357     TRACE("%s\n", debugstr_w(StringAcl));
3358
3359     if (!StringAcl)
3360         return FALSE;
3361
3362     if (pAcl) /* pAce is only useful if we're setting values */
3363         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3364
3365     /* Parse ACL flags */
3366     *lpdwFlags = ParseAclStringFlags(&StringAcl);
3367
3368     /* Parse ACE */
3369     while (*StringAcl == '(')
3370     {
3371         StringAcl++;
3372
3373         /* Parse ACE type */
3374         val = ParseAceStringType(&StringAcl);
3375         if (pAce)
3376             pAce->Header.AceType = (BYTE) val;
3377         if (*StringAcl != ';')
3378             goto lerr;
3379         StringAcl++;
3380
3381         /* Parse ACE flags */
3382         val = ParseAceStringFlags(&StringAcl);
3383         if (pAce)
3384             pAce->Header.AceFlags = (BYTE) val;
3385         if (*StringAcl != ';')
3386             goto lerr;
3387         StringAcl++;
3388
3389         /* Parse ACE rights */
3390         val = ParseAceStringRights(&StringAcl);
3391         if (pAce)
3392             pAce->Mask = val;
3393         if (*StringAcl != ';')
3394             goto lerr;
3395         StringAcl++;
3396
3397         /* Parse ACE object guid */
3398         if (*StringAcl != ';')
3399         {
3400             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3401             goto lerr;
3402         }
3403         StringAcl++;
3404
3405         /* Parse ACE inherit object guid */
3406         if (*StringAcl != ';')
3407         {
3408             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3409             goto lerr;
3410         }
3411         StringAcl++;
3412
3413         /* Parse ACE account sid */
3414         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3415         {
3416             while (*StringAcl && *StringAcl != ')')
3417                 StringAcl++;
3418         }
3419
3420         if (*StringAcl != ')')
3421             goto lerr;
3422         StringAcl++;
3423
3424         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3425         length += acesize;
3426         if (pAce)
3427         {
3428             pAce->Header.AceSize = acesize;
3429             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3430         }
3431         acecount++;
3432     }
3433
3434     *cBytes = length;
3435
3436     if (length > 0xffff)
3437     {
3438         ERR("ACL too large\n");
3439         goto lerr;
3440     }
3441
3442     if (pAcl)
3443     {
3444         pAcl->AclRevision = ACL_REVISION;
3445         pAcl->Sbz1 = 0;
3446         pAcl->AclSize = length;
3447         pAcl->AceCount = acecount++;
3448         pAcl->Sbz2 = 0;
3449     }
3450     return TRUE;
3451
3452 lerr:
3453     WARN("Invalid ACE string format\n");
3454     return FALSE;
3455 }
3456
3457
3458 /******************************************************************************
3459  * ParseStringSecurityDescriptorToSecurityDescriptor
3460  */
3461 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3462     LPCWSTR StringSecurityDescriptor,
3463     SECURITY_DESCRIPTOR* SecurityDescriptor,
3464     LPDWORD cBytes)
3465 {
3466     BOOL bret = FALSE;
3467     WCHAR toktype;
3468     WCHAR tok[MAX_PATH];
3469     LPCWSTR lptoken;
3470     LPBYTE lpNext = NULL;
3471     DWORD len;
3472
3473     *cBytes = sizeof(SECURITY_DESCRIPTOR);
3474
3475     if (SecurityDescriptor)
3476         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3477
3478     while (*StringSecurityDescriptor)
3479     {
3480         toktype = *StringSecurityDescriptor;
3481
3482         /* Expect char identifier followed by ':' */
3483         StringSecurityDescriptor++;
3484         if (*StringSecurityDescriptor != ':')
3485         {
3486             SetLastError(ERROR_INVALID_PARAMETER);
3487             goto lend;
3488         }
3489         StringSecurityDescriptor++;
3490
3491         /* Extract token */
3492         lptoken = StringSecurityDescriptor;
3493         while (*lptoken && *lptoken != ':')
3494             lptoken++;
3495
3496         if (*lptoken)
3497             lptoken--;
3498
3499         len = lptoken - StringSecurityDescriptor;
3500         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3501         tok[len] = 0;
3502
3503         switch (toktype)
3504         {
3505             case 'O':
3506             {
3507                 DWORD bytes;
3508
3509                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3510                     goto lend;
3511
3512                 if (SecurityDescriptor)
3513                 {
3514                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3515                     lpNext += bytes; /* Advance to next token */
3516                 }
3517
3518                 *cBytes += bytes;
3519
3520                 break;
3521             }
3522
3523             case 'G':
3524             {
3525                 DWORD bytes;
3526
3527                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3528                     goto lend;
3529
3530                 if (SecurityDescriptor)
3531                 {
3532                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3533                     lpNext += bytes; /* Advance to next token */
3534                 }
3535
3536                 *cBytes += bytes;
3537
3538                 break;
3539             }
3540
3541             case 'D':
3542             {
3543                 DWORD flags;
3544                 DWORD bytes;
3545
3546                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3547                     goto lend;
3548
3549                 if (SecurityDescriptor)
3550                 {
3551                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3552                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3553                     lpNext += bytes; /* Advance to next token */
3554                 }
3555
3556                 *cBytes += bytes;
3557
3558                 break;
3559             }
3560
3561             case 'S':
3562             {
3563                 DWORD flags;
3564                 DWORD bytes;
3565
3566                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3567                     goto lend;
3568
3569                 if (SecurityDescriptor)
3570                 {
3571                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3572                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3573                     lpNext += bytes; /* Advance to next token */
3574                 }
3575
3576                 *cBytes += bytes;
3577
3578                 break;
3579             }
3580
3581             default:
3582                 FIXME("Unknown token\n");
3583                 SetLastError(ERROR_INVALID_PARAMETER);
3584                 goto lend;
3585         }
3586
3587         StringSecurityDescriptor = lptoken;
3588     }
3589
3590     bret = TRUE;
3591
3592 lend:
3593     return bret;
3594 }
3595
3596 /******************************************************************************
3597  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3598  */
3599 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3600         LPCSTR StringSecurityDescriptor,
3601         DWORD StringSDRevision,
3602         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3603         PULONG SecurityDescriptorSize)
3604 {
3605     UINT len;
3606     BOOL ret = FALSE;
3607     LPWSTR StringSecurityDescriptorW;
3608
3609     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3610     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3611
3612     if (StringSecurityDescriptorW)
3613     {
3614         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3615
3616         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3617                                                                    StringSDRevision, SecurityDescriptor,
3618                                                                    SecurityDescriptorSize);
3619         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3620     }
3621
3622     return ret;
3623 }
3624
3625 /******************************************************************************
3626  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3627  */
3628 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3629         LPCWSTR StringSecurityDescriptor,
3630         DWORD StringSDRevision,
3631         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3632         PULONG SecurityDescriptorSize)
3633 {
3634     DWORD cBytes;
3635     SECURITY_DESCRIPTOR* psd;
3636     BOOL bret = FALSE;
3637
3638     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3639
3640     if (GetVersion() & 0x80000000)
3641     {
3642         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3643         goto lend;
3644     }
3645     else if (StringSDRevision != SID_REVISION)
3646     {
3647         SetLastError(ERROR_UNKNOWN_REVISION);
3648         goto lend;
3649     }
3650
3651     /* Compute security descriptor length */
3652     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3653         NULL, &cBytes))
3654         goto lend;
3655
3656     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3657         GMEM_ZEROINIT, cBytes);
3658     if (!psd) goto lend;
3659
3660     psd->Revision = SID_REVISION;
3661     psd->Control |= SE_SELF_RELATIVE;
3662
3663     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3664         psd, &cBytes))
3665     {
3666         LocalFree(psd);
3667         goto lend;
3668     }
3669
3670     if (SecurityDescriptorSize)
3671         *SecurityDescriptorSize = cBytes;
3672
3673     bret = TRUE;
3674  
3675 lend:
3676     TRACE(" ret=%d\n", bret);
3677     return bret;
3678 }
3679
3680 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3681 {
3682     if (cch == -1)
3683         cch = strlenW(string);
3684
3685     if (plen)
3686         *plen += cch;
3687
3688     if (pwptr)
3689     {
3690         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3691         *pwptr += cch;
3692     }
3693 }
3694
3695 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3696 {
3697     DWORD i;
3698     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3699     WCHAR subauthfmt[] = { '-','%','u',0 };
3700     WCHAR buf[26];
3701     SID *pisid = psid;
3702
3703     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3704     {
3705         SetLastError(ERROR_INVALID_SID);
3706         return FALSE;
3707     }
3708
3709     if (pisid->IdentifierAuthority.Value[0] ||
3710      pisid->IdentifierAuthority.Value[1])
3711     {
3712         FIXME("not matching MS' bugs\n");
3713         SetLastError(ERROR_INVALID_SID);
3714         return FALSE;
3715     }
3716
3717     sprintfW( buf, fmt, pisid->Revision,
3718         MAKELONG(
3719             MAKEWORD( pisid->IdentifierAuthority.Value[5],
3720                     pisid->IdentifierAuthority.Value[4] ),
3721             MAKEWORD( pisid->IdentifierAuthority.Value[3],
3722                     pisid->IdentifierAuthority.Value[2] )
3723         ) );
3724     DumpString(buf, -1, pwptr, plen);
3725
3726     for( i=0; i<pisid->SubAuthorityCount; i++ )
3727     {
3728         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3729         DumpString(buf, -1, pwptr, plen);
3730     }
3731     return TRUE;
3732 }
3733
3734 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3735 {
3736     int i;
3737     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3738     {
3739         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3740         {
3741             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3742             return TRUE;
3743         }
3744     }
3745
3746     return DumpSidNumeric(psid, pwptr, plen);
3747 }
3748
3749 static const LPCWSTR AceRightBitNames[32] = {
3750         SDDL_CREATE_CHILD,        /*  0 */
3751         SDDL_DELETE_CHILD,
3752         SDDL_LIST_CHILDREN,
3753         SDDL_SELF_WRITE,
3754         SDDL_READ_PROPERTY,       /*  4 */
3755         SDDL_WRITE_PROPERTY,
3756         SDDL_DELETE_TREE,
3757         SDDL_LIST_OBJECT,
3758         SDDL_CONTROL_ACCESS,      /*  8 */
3759         NULL,
3760         NULL,
3761         NULL,
3762         NULL,                     /* 12 */
3763         NULL,
3764         NULL,
3765         NULL,
3766         SDDL_STANDARD_DELETE,     /* 16 */
3767         SDDL_READ_CONTROL,
3768         SDDL_WRITE_DAC,
3769         SDDL_WRITE_OWNER,
3770         NULL,                     /* 20 */
3771         NULL,
3772         NULL,
3773         NULL,
3774         NULL,                     /* 24 */
3775         NULL,
3776         NULL,
3777         NULL,
3778         SDDL_GENERIC_ALL,         /* 28 */
3779         SDDL_GENERIC_EXECUTE,
3780         SDDL_GENERIC_WRITE,
3781         SDDL_GENERIC_READ
3782 };
3783
3784 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
3785 {
3786     static const WCHAR fmtW[] = {'0','x','%','x',0};
3787     WCHAR buf[15];
3788     int i;
3789
3790     if (mask == 0)
3791         return;
3792
3793     /* first check if the right have name */
3794     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
3795     {
3796         if (AceRights[i].wstr == NULL)
3797             break;
3798         if (mask == AceRights[i].value)
3799         {
3800             DumpString(AceRights[i].wstr, -1, pwptr, plen);
3801             return;
3802         }
3803     }
3804
3805     /* then check if it can be built from bit names */
3806     for (i = 0; i < 32; i++)
3807     {
3808         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
3809         {
3810             /* can't be built from bit names */
3811             sprintfW(buf, fmtW, mask);
3812             DumpString(buf, -1, pwptr, plen);
3813             return;
3814         }
3815     }
3816
3817     /* build from bit names */
3818     for (i = 0; i < 32; i++)
3819         if (mask & (1 << i))
3820             DumpString(AceRightBitNames[i], -1, pwptr, plen);
3821 }
3822
3823 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
3824 {
3825     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
3826     static const WCHAR openbr = '(';
3827     static const WCHAR closebr = ')';
3828     static const WCHAR semicolon = ';';
3829
3830     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
3831     {
3832         SetLastError(ERROR_INVALID_ACL);
3833         return FALSE;
3834     }
3835
3836     piace = (ACCESS_ALLOWED_ACE *)pace;
3837     DumpString(&openbr, 1, pwptr, plen);
3838     switch (piace->Header.AceType)
3839     {
3840         case ACCESS_ALLOWED_ACE_TYPE:
3841             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
3842             break;
3843         case ACCESS_DENIED_ACE_TYPE:
3844             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
3845             break;
3846         case SYSTEM_AUDIT_ACE_TYPE:
3847             DumpString(SDDL_AUDIT, -1, pwptr, plen);
3848             break;
3849         case SYSTEM_ALARM_ACE_TYPE:
3850             DumpString(SDDL_ALARM, -1, pwptr, plen);
3851             break;
3852     }
3853     DumpString(&semicolon, 1, pwptr, plen);
3854
3855     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
3856         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
3857     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
3858         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
3859     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
3860         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
3861     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
3862         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
3863     if (piace->Header.AceFlags & INHERITED_ACE)
3864         DumpString(SDDL_INHERITED, -1, pwptr, plen);
3865     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
3866         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
3867     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
3868         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
3869     DumpString(&semicolon, 1, pwptr, plen);
3870     DumpRights(piace->Mask, pwptr, plen);
3871     DumpString(&semicolon, 1, pwptr, plen);
3872     /* objects not supported */
3873     DumpString(&semicolon, 1, pwptr, plen);
3874     /* objects not supported */
3875     DumpString(&semicolon, 1, pwptr, plen);
3876     if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
3877         return FALSE;
3878     DumpString(&closebr, 1, pwptr, plen);
3879     return TRUE;
3880 }
3881
3882 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
3883 {
3884     WORD count;
3885     int i;
3886
3887     if (protected)
3888         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
3889     if (autoInheritReq)
3890         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3891     if (autoInherited)
3892         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3893
3894     if (pacl == NULL)
3895         return TRUE;
3896
3897     if (!IsValidAcl(pacl))
3898         return FALSE;
3899
3900     count = pacl->AceCount;
3901     for (i = 0; i < count; i++)
3902     {
3903         LPVOID ace;
3904         if (!GetAce(pacl, i, &ace))
3905             return FALSE;
3906         if (!DumpAce(ace, pwptr, plen))
3907             return FALSE;
3908     }
3909
3910     return TRUE;
3911 }
3912
3913 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3914 {
3915     static const WCHAR prefix[] = {'O',':',0};
3916     BOOL bDefaulted;
3917     PSID psid;
3918
3919     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3920         return FALSE;
3921
3922     if (psid == NULL)
3923         return TRUE;
3924
3925     DumpString(prefix, -1, pwptr, plen);
3926     if (!DumpSid(psid, pwptr, plen))
3927         return FALSE;
3928     return TRUE;
3929 }
3930
3931 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3932 {
3933     static const WCHAR prefix[] = {'G',':',0};
3934     BOOL bDefaulted;
3935     PSID psid;
3936
3937     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3938         return FALSE;
3939
3940     if (psid == NULL)
3941         return TRUE;
3942
3943     DumpString(prefix, -1, pwptr, plen);
3944     if (!DumpSid(psid, pwptr, plen))
3945         return FALSE;
3946     return TRUE;
3947 }
3948
3949 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3950 {
3951     static const WCHAR dacl[] = {'D',':',0};
3952     SECURITY_DESCRIPTOR_CONTROL control;
3953     BOOL present, defaulted;
3954     DWORD revision;
3955     PACL pacl;
3956
3957     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3958         return FALSE;
3959
3960     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3961         return FALSE;
3962
3963     if (!present)
3964         return TRUE;
3965
3966     DumpString(dacl, 2, pwptr, plen);
3967     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3968         return FALSE;
3969     return TRUE;
3970 }
3971
3972 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3973 {
3974     static const WCHAR sacl[] = {'S',':',0};
3975     SECURITY_DESCRIPTOR_CONTROL control;
3976     BOOL present, defaulted;
3977     DWORD revision;
3978     PACL pacl;
3979
3980     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3981         return FALSE;
3982
3983     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3984         return FALSE;
3985
3986     if (!present)
3987         return TRUE;
3988
3989     DumpString(sacl, 2, pwptr, plen);
3990     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3991         return FALSE;
3992     return TRUE;
3993 }
3994
3995 /******************************************************************************
3996  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3997  */
3998 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
3999 {
4000     ULONG len;
4001     WCHAR *wptr, *wstr;
4002
4003     if (SDRevision != SDDL_REVISION_1)
4004     {
4005         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4006         SetLastError(ERROR_UNKNOWN_REVISION);
4007         return FALSE;
4008     }
4009
4010     len = 0;
4011     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4012         if (!DumpOwner(SecurityDescriptor, NULL, &len))
4013             return FALSE;
4014     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4015         if (!DumpGroup(SecurityDescriptor, NULL, &len))
4016             return FALSE;
4017     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4018         if (!DumpDacl(SecurityDescriptor, NULL, &len))
4019             return FALSE;
4020     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4021         if (!DumpSacl(SecurityDescriptor, NULL, &len))
4022             return FALSE;
4023
4024     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4025     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4026         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4027             return FALSE;
4028     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4029         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4030             return FALSE;
4031     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4032         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4033             return FALSE;
4034     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4035         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4036             return FALSE;
4037     *wptr = 0;
4038
4039     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4040     *OutputString = wstr;
4041     if (OutputLen)
4042         *OutputLen = strlenW(*OutputString)+1;
4043     return TRUE;
4044 }
4045
4046 /******************************************************************************
4047  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4048  */
4049 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4050 {
4051     LPWSTR wstr;
4052     ULONG len;
4053     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4054     {
4055         int lenA;
4056
4057         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4058         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4059         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4060         LocalFree(wstr);
4061
4062         if (OutputLen != NULL)
4063             *OutputLen = lenA;
4064         return TRUE;
4065     }
4066     else
4067     {
4068         *OutputString = NULL;
4069         if (OutputLen)
4070             *OutputLen = 0;
4071         return FALSE;
4072     }
4073 }
4074
4075 /******************************************************************************
4076  * ConvertStringSidToSidW [ADVAPI32.@]
4077  */
4078 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4079 {
4080     BOOL bret = FALSE;
4081     DWORD cBytes;
4082
4083     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4084     if (GetVersion() & 0x80000000)
4085         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4086     else if (!StringSid || !Sid)
4087         SetLastError(ERROR_INVALID_PARAMETER);
4088     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4089     {
4090         PSID pSid = *Sid = LocalAlloc(0, cBytes);
4091
4092         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4093         if (!bret)
4094             LocalFree(*Sid); 
4095     }
4096     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4097     return bret;
4098 }
4099
4100 /******************************************************************************
4101  * ConvertStringSidToSidA [ADVAPI32.@]
4102  */
4103 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4104 {
4105     BOOL bret = FALSE;
4106
4107     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4108     if (GetVersion() & 0x80000000)
4109         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4110     else if (!StringSid || !Sid)
4111         SetLastError(ERROR_INVALID_PARAMETER);
4112     else
4113     {
4114         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4115         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4116          len * sizeof(WCHAR));
4117
4118         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4119         bret = ConvertStringSidToSidW(wStringSid, Sid);
4120         HeapFree(GetProcessHeap(), 0, wStringSid);
4121     }
4122     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4123     return bret;
4124 }
4125
4126 /******************************************************************************
4127  * ConvertSidToStringSidW [ADVAPI32.@]
4128  *
4129  *  format of SID string is:
4130  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4131  *  where
4132  *    <rev> is the revision of the SID encoded as decimal
4133  *    <auth> is the identifier authority encoded as hex
4134  *    <subauthN> is the subauthority id encoded as decimal
4135  */
4136 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4137 {
4138     DWORD len = 0;
4139     LPWSTR wstr, wptr;
4140
4141     TRACE("%p %p\n", pSid, pstr );
4142
4143     len = 0;
4144     if (!DumpSidNumeric(pSid, NULL, &len))
4145         return FALSE;
4146     wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4147     DumpSidNumeric(pSid, &wptr, NULL);
4148     *wptr = 0;
4149
4150     *pstr = wstr;
4151     return TRUE;
4152 }
4153
4154 /******************************************************************************
4155  * ConvertSidToStringSidA [ADVAPI32.@]
4156  */
4157 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4158 {
4159     LPWSTR wstr = NULL;
4160     LPSTR str;
4161     UINT len;
4162
4163     TRACE("%p %p\n", pSid, pstr );
4164
4165     if( !ConvertSidToStringSidW( pSid, &wstr ) )
4166         return FALSE;
4167
4168     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4169     str = LocalAlloc( 0, len );
4170     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4171     LocalFree( wstr );
4172
4173     *pstr = str;
4174
4175     return TRUE;
4176 }
4177
4178 BOOL WINAPI CreatePrivateObjectSecurity(
4179         PSECURITY_DESCRIPTOR ParentDescriptor,
4180         PSECURITY_DESCRIPTOR CreatorDescriptor,
4181         PSECURITY_DESCRIPTOR* NewDescriptor,
4182         BOOL IsDirectoryObject,
4183         HANDLE Token,
4184         PGENERIC_MAPPING GenericMapping )
4185 {
4186     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4187           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4188
4189     return FALSE;
4190 }
4191
4192 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4193 {
4194     FIXME("%p - stub\n", ObjectDescriptor);
4195
4196     return TRUE;
4197 }
4198
4199 BOOL WINAPI CreateProcessAsUserA(
4200         HANDLE hToken,
4201         LPCSTR lpApplicationName,
4202         LPSTR lpCommandLine,
4203         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4204         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4205         BOOL bInheritHandles,
4206         DWORD dwCreationFlags,
4207         LPVOID lpEnvironment,
4208         LPCSTR lpCurrentDirectory,
4209         LPSTARTUPINFOA lpStartupInfo,
4210         LPPROCESS_INFORMATION lpProcessInformation )
4211 {
4212     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4213           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4214           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4215
4216     return FALSE;
4217 }
4218
4219 BOOL WINAPI CreateProcessAsUserW(
4220         HANDLE hToken,
4221         LPCWSTR lpApplicationName,
4222         LPWSTR lpCommandLine,
4223         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4224         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4225         BOOL bInheritHandles,
4226         DWORD dwCreationFlags,
4227         LPVOID lpEnvironment,
4228         LPCWSTR lpCurrentDirectory,
4229         LPSTARTUPINFOW lpStartupInfo,
4230         LPPROCESS_INFORMATION lpProcessInformation )
4231 {
4232     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
4233           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4234           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
4235           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4236
4237     /* We should create the process with a suspended main thread */
4238     if (!CreateProcessW (lpApplicationName,
4239                          lpCommandLine,
4240                          lpProcessAttributes,
4241                          lpThreadAttributes,
4242                          bInheritHandles,
4243                          dwCreationFlags, /* CREATE_SUSPENDED */
4244                          lpEnvironment,
4245                          lpCurrentDirectory,
4246                          lpStartupInfo,
4247                          lpProcessInformation))
4248     {
4249       return FALSE;
4250     }
4251
4252     return TRUE;
4253 }
4254
4255 /******************************************************************************
4256  * CreateProcessWithLogonW
4257  */
4258 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4259     LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4260     LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4261 {
4262     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4263     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4264     debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4265     lpStartupInfo, lpProcessInformation);
4266
4267     return FALSE;
4268 }
4269
4270 /******************************************************************************
4271  * DuplicateTokenEx [ADVAPI32.@]
4272  */
4273 BOOL WINAPI DuplicateTokenEx(
4274         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4275         LPSECURITY_ATTRIBUTES lpTokenAttributes,
4276         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4277         TOKEN_TYPE TokenType,
4278         PHANDLE DuplicateTokenHandle )
4279 {
4280     OBJECT_ATTRIBUTES ObjectAttributes;
4281
4282     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4283           ImpersonationLevel, TokenType, DuplicateTokenHandle);
4284
4285     InitializeObjectAttributes(
4286         &ObjectAttributes,
4287         NULL,
4288         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4289         NULL,
4290         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4291
4292     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4293                                            dwDesiredAccess,
4294                                            &ObjectAttributes,
4295                                            ImpersonationLevel,
4296                                            TokenType,
4297                                            DuplicateTokenHandle ) );
4298 }
4299
4300 BOOL WINAPI DuplicateToken(
4301         HANDLE ExistingTokenHandle,
4302         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4303         PHANDLE DuplicateTokenHandle )
4304 {
4305     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4306                              NULL, ImpersonationLevel, TokenImpersonation,
4307                              DuplicateTokenHandle );
4308 }
4309
4310 BOOL WINAPI EnumDependentServicesA(
4311         SC_HANDLE hService,
4312         DWORD dwServiceState,
4313         LPENUM_SERVICE_STATUSA lpServices,
4314         DWORD cbBufSize,
4315         LPDWORD pcbBytesNeeded,
4316         LPDWORD lpServicesReturned )
4317 {
4318     FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4319           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4320
4321     return FALSE;
4322 }
4323
4324 BOOL WINAPI EnumDependentServicesW(
4325         SC_HANDLE hService,
4326         DWORD dwServiceState,
4327         LPENUM_SERVICE_STATUSW lpServices,
4328         DWORD cbBufSize,
4329         LPDWORD pcbBytesNeeded,
4330         LPDWORD lpServicesReturned )
4331 {
4332     FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4333           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4334
4335     return FALSE;
4336 }
4337
4338 /******************************************************************************
4339  * ComputeStringSidSize
4340  */
4341 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4342 {
4343     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4344     {
4345         int ctok = 0;
4346         while (*StringSid)
4347         {
4348             if (*StringSid == '-')
4349                 ctok++;
4350             StringSid++;
4351         }
4352
4353         if (ctok >= 3)
4354             return GetSidLengthRequired(ctok - 2);
4355     }
4356     else /* String constant format  - Only available in winxp and above */
4357     {
4358         unsigned int i;
4359
4360         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4361             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4362                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4363     }
4364
4365     return GetSidLengthRequired(0);
4366 }
4367
4368 /******************************************************************************
4369  * ParseStringSidToSid
4370  */
4371 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4372 {
4373     BOOL bret = FALSE;
4374     SID* pisid=pSid;
4375
4376     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4377     if (!StringSid)
4378     {
4379         SetLastError(ERROR_INVALID_PARAMETER);
4380         TRACE("StringSid is NULL, returning FALSE\n");
4381         return FALSE;
4382     }
4383
4384     *cBytes = ComputeStringSidSize(StringSid);
4385     if (!pisid) /* Simply compute the size */
4386     {
4387         TRACE("only size requested, returning TRUE\n");
4388         return TRUE;
4389     }
4390
4391     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4392     {
4393         DWORD i = 0, identAuth;
4394         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4395
4396         StringSid += 2; /* Advance to Revision */
4397         pisid->Revision = atoiW(StringSid);
4398
4399         if (pisid->Revision != SDDL_REVISION)
4400         {
4401             TRACE("Revision %d is unknown\n", pisid->Revision);
4402             goto lend; /* ERROR_INVALID_SID */
4403         }
4404         if (csubauth == 0)
4405         {
4406             TRACE("SubAuthorityCount is 0\n");
4407             goto lend; /* ERROR_INVALID_SID */
4408         }
4409
4410         pisid->SubAuthorityCount = csubauth;
4411
4412         /* Advance to identifier authority */
4413         while (*StringSid && *StringSid != '-')
4414             StringSid++;
4415         if (*StringSid == '-')
4416             StringSid++;
4417
4418         /* MS' implementation can't handle values greater than 2^32 - 1, so
4419          * we don't either; assume most significant bytes are always 0
4420          */
4421         pisid->IdentifierAuthority.Value[0] = 0;
4422         pisid->IdentifierAuthority.Value[1] = 0;
4423         identAuth = atoiW(StringSid);
4424         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4425         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4426         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4427         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4428
4429         /* Advance to first sub authority */
4430         while (*StringSid && *StringSid != '-')
4431             StringSid++;
4432         if (*StringSid == '-')
4433             StringSid++;
4434
4435         while (*StringSid)
4436         {
4437             pisid->SubAuthority[i++] = atoiW(StringSid);
4438
4439             while (*StringSid && *StringSid != '-')
4440                 StringSid++;
4441             if (*StringSid == '-')
4442                 StringSid++;
4443         }
4444
4445         if (i != pisid->SubAuthorityCount)
4446             goto lend; /* ERROR_INVALID_SID */
4447
4448         bret = TRUE;
4449     }
4450     else /* String constant format  - Only available in winxp and above */
4451     {
4452         unsigned int i;
4453         pisid->Revision = SDDL_REVISION;
4454
4455         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4456             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4457             {
4458                 DWORD j;
4459                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4460                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4461                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4462                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4463                 bret = TRUE;
4464             }
4465
4466         if (!bret)
4467             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4468     }
4469
4470 lend:
4471     if (!bret)
4472         SetLastError(ERROR_INVALID_SID);
4473
4474     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4475     return bret;
4476 }
4477
4478 /******************************************************************************
4479  * GetNamedSecurityInfoA [ADVAPI32.@]
4480  */
4481 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4482         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4483         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4484         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4485 {
4486     DWORD len;
4487     LPWSTR wstr = NULL;
4488     DWORD r;
4489
4490     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4491         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4492
4493     if( pObjectName )
4494     {
4495         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4496         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4497         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4498     }
4499
4500     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4501                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4502
4503     HeapFree( GetProcessHeap(), 0, wstr );
4504
4505     return r;
4506 }
4507
4508 /******************************************************************************
4509  * GetNamedSecurityInfoW [ADVAPI32.@]
4510  */
4511 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4512     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4513     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4514 {
4515     DWORD needed, offset;
4516     SECURITY_DESCRIPTOR_RELATIVE *relative;
4517     BYTE *buffer;
4518
4519     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4520            group, dacl, sacl, descriptor );
4521
4522     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4523
4524     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4525     if (info & OWNER_SECURITY_INFORMATION)
4526         needed += sizeof(sidWorld);
4527     if (info & GROUP_SECURITY_INFORMATION)
4528         needed += sizeof(sidWorld);
4529     if (info & DACL_SECURITY_INFORMATION)
4530         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4531     if (info & SACL_SECURITY_INFORMATION)
4532         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4533
4534     /* must be freed by caller */
4535     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4536     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4537
4538     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4539     {
4540         HeapFree( GetProcessHeap(), 0, *descriptor );
4541         return ERROR_INVALID_SECURITY_DESCR;
4542     }
4543
4544     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4545     relative->Control |= SE_SELF_RELATIVE;
4546     buffer = (BYTE *)relative;
4547     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4548
4549     if (info & OWNER_SECURITY_INFORMATION)
4550     {
4551         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4552         relative->Owner = offset;
4553         if (owner)
4554             *owner = buffer + offset;
4555         offset += sizeof(sidWorld);
4556     }
4557     if (info & GROUP_SECURITY_INFORMATION)
4558     {
4559         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4560         relative->Group = offset;
4561         if (group)
4562             *group = buffer + offset;
4563         offset += sizeof(sidWorld);
4564     }
4565     if (info & DACL_SECURITY_INFORMATION)
4566     {
4567         relative->Control |= SE_DACL_PRESENT;
4568         GetWorldAccessACL( (PACL)(buffer + offset) );
4569         relative->Dacl = offset;
4570         if (dacl)
4571             *dacl = (PACL)(buffer + offset);
4572         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4573     }
4574     if (info & SACL_SECURITY_INFORMATION)
4575     {
4576         relative->Control |= SE_SACL_PRESENT;
4577         GetWorldAccessACL( (PACL)(buffer + offset) );
4578         relative->Sacl = offset;
4579         if (sacl)
4580             *sacl = (PACL)(buffer + offset);
4581     }
4582     return ERROR_SUCCESS;
4583 }
4584
4585 /******************************************************************************
4586  * DecryptFileW [ADVAPI32.@]
4587  */
4588 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4589 {
4590     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4591     return TRUE;
4592 }
4593
4594 /******************************************************************************
4595  * DecryptFileA [ADVAPI32.@]
4596  */
4597 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4598 {
4599     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4600     return TRUE;
4601 }
4602
4603 /******************************************************************************
4604  * EncryptFileW [ADVAPI32.@]
4605  */
4606 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4607 {
4608     FIXME("%s\n", debugstr_w(lpFileName));
4609     return TRUE;
4610 }
4611
4612 /******************************************************************************
4613  * EncryptFileA [ADVAPI32.@]
4614  */
4615 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4616 {
4617     FIXME("%s\n", debugstr_a(lpFileName));
4618     return TRUE;
4619 }
4620
4621 /******************************************************************************
4622  * FileEncryptionStatusW [ADVAPI32.@]
4623  */
4624 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4625 {
4626     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4627     if (!lpStatus)
4628         return FALSE;
4629     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4630     return TRUE;
4631 }
4632
4633 /******************************************************************************
4634  * FileEncryptionStatusA [ADVAPI32.@]
4635  */
4636 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4637 {
4638     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4639     if (!lpStatus)
4640         return FALSE;
4641     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4642     return TRUE;
4643 }
4644
4645 /******************************************************************************
4646  * SetSecurityInfo [ADVAPI32.@]
4647  */
4648 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
4649                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4650                       PSID psidGroup, PACL pDacl, PACL pSacl) {
4651     FIXME("stub\n");
4652     return ERROR_SUCCESS;
4653 }