msvcrt/tests: Remove a space before a '\n'.
[wine/gsoc-2012-control.git] / dlls / advapi32 / security.c
blob43d6d07d328bc242251842470c2dc9e7613731cf
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
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.
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.
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
22 #include <stdarg.h>
23 #include <string.h>
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 "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
135 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
136 typedef struct WELLKNOWNRID
138 WELL_KNOWN_SID_TYPE Type;
139 DWORD Rid;
140 } WELLKNOWNRID;
142 static const WELLKNOWNRID WellKnownRids[] = {
143 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
144 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
145 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
146 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
147 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
148 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
149 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
150 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
151 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
152 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
153 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
154 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
155 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
159 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
161 typedef struct _AccountSid {
162 WELL_KNOWN_SID_TYPE type;
163 LPCWSTR account;
164 LPCWSTR domain;
165 SID_NAME_USE name_use;
166 } AccountSid;
168 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
169 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
170 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
171 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
172 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
173 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
175 static const WCHAR Blank[] = { 0 };
176 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
177 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
178 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
179 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 };
180 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
181 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 };
182 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
183 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 };
184 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
185 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
186 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
187 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
188 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
189 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
190 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
191 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 };
192 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
193 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 };
194 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
195 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
196 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
197 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
198 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
199 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
200 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 };
201 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
202 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
203 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
204 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
205 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
206 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
207 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 };
208 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 };
209 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
210 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 };
211 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
212 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
213 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
214 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 };
215 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 };
216 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
217 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
218 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 };
219 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
220 static const WCHAR SELF[] = { 'S','E','L','F',0 };
221 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
222 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
223 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
224 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 };
225 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
226 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
228 static const AccountSid ACCOUNT_SIDS[] = {
229 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
230 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
231 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
232 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
233 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
234 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
235 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
236 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
237 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
254 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
255 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
256 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
257 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
258 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
261 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
262 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
263 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
264 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
265 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
266 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
270 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
271 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
272 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
275 * ACE access rights
277 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
278 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
279 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
280 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
282 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
283 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
284 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
285 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
286 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
287 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
288 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
289 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
290 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
292 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
293 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
294 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
295 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
297 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
298 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
299 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
300 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
302 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
303 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
304 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
305 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
308 * ACL flags
310 static const WCHAR SDDL_PROTECTED[] = {'P',0};
311 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
312 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
315 * ACE types
317 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
318 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
319 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
320 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
321 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
322 static const WCHAR SDDL_ALARM[] = {'A','L',0};
323 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
324 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
327 * ACE flags
329 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
330 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
331 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
332 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
333 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
334 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
335 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
337 const char * debugstr_sid(PSID sid)
339 int auth = 0;
340 SID * psid = (SID *)sid;
342 if (psid == NULL)
343 return "(null)";
345 auth = psid->IdentifierAuthority.Value[5] +
346 (psid->IdentifierAuthority.Value[4] << 8) +
347 (psid->IdentifierAuthority.Value[3] << 16) +
348 (psid->IdentifierAuthority.Value[2] << 24);
350 switch (psid->SubAuthorityCount) {
351 case 0:
352 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
353 case 1:
354 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
355 psid->SubAuthority[0]);
356 case 2:
357 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
358 psid->SubAuthority[0], psid->SubAuthority[1]);
359 case 3:
360 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
361 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
362 case 4:
363 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
364 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
365 psid->SubAuthority[3]);
366 case 5:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
369 psid->SubAuthority[3], psid->SubAuthority[4]);
370 case 6:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
374 case 7:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
378 psid->SubAuthority[6]);
379 case 8:
380 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
381 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
382 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
383 psid->SubAuthority[6], psid->SubAuthority[7]);
385 return "(too-big)";
388 /* set last error code from NT status and get the proper boolean return value */
389 /* used for functions that are a simple wrapper around the corresponding ntdll API */
390 static inline BOOL set_ntstatus( NTSTATUS status )
392 if (status) SetLastError( RtlNtStatusToDosError( status ));
393 return !status;
396 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
398 static void GetWorldAccessACL(PACL pACL)
400 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
402 pACL->AclRevision = ACL_REVISION;
403 pACL->Sbz1 = 0;
404 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
405 pACL->AceCount = 1;
406 pACL->Sbz2 = 0;
408 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
409 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
410 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
411 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
412 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
415 /************************************************************
416 * ADVAPI_IsLocalComputer
418 * Checks whether the server name indicates local machine.
420 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
422 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
423 BOOL Result;
424 LPWSTR buf;
426 if (!ServerName || !ServerName[0])
427 return TRUE;
429 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
430 Result = GetComputerNameW(buf, &dwSize);
431 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
432 ServerName += 2;
433 Result = Result && !lstrcmpW(ServerName, buf);
434 HeapFree(GetProcessHeap(), 0, buf);
436 return Result;
439 /************************************************************
440 * ADVAPI_GetComputerSid
442 * Reads the computer SID from the registry.
444 BOOL ADVAPI_GetComputerSid(PSID sid)
446 HKEY key;
447 LONG ret;
448 BOOL retval = FALSE;
449 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 };
450 static const WCHAR V[] = { 'V',0 };
452 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
453 KEY_READ, &key)) == ERROR_SUCCESS)
455 DWORD size = 0;
456 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
457 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
459 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
460 if (data)
462 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
463 data, &size)) == ERROR_SUCCESS)
465 /* the SID is in the last 24 bytes of the binary data */
466 CopyMemory(sid, &data[size-24], 24);
467 retval = TRUE;
469 HeapFree(GetProcessHeap(), 0, data);
472 RegCloseKey(key);
475 if(retval == TRUE) return retval;
477 /* create a new random SID */
478 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
479 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
481 PSID new_sid;
482 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
483 DWORD id[3];
485 if (RtlGenRandom(id, sizeof(id)))
487 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
489 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
490 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
492 FreeSid(new_sid);
495 RegCloseKey(key);
498 return retval;
501 /* ##############################
502 ###### TOKEN FUNCTIONS ######
503 ##############################
506 /******************************************************************************
507 * OpenProcessToken [ADVAPI32.@]
508 * Opens the access token associated with a process handle.
510 * PARAMS
511 * ProcessHandle [I] Handle to process
512 * DesiredAccess [I] Desired access to process
513 * TokenHandle [O] Pointer to handle of open access token
515 * RETURNS
516 * Success: TRUE. TokenHandle contains the access token.
517 * Failure: FALSE.
519 * NOTES
520 * See NtOpenProcessToken.
522 BOOL WINAPI
523 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
524 HANDLE *TokenHandle )
526 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
529 /******************************************************************************
530 * OpenThreadToken [ADVAPI32.@]
532 * Opens the access token associated with a thread handle.
534 * PARAMS
535 * ThreadHandle [I] Handle to process
536 * DesiredAccess [I] Desired access to the thread
537 * OpenAsSelf [I] ???
538 * TokenHandle [O] Destination for the token handle
540 * RETURNS
541 * Success: TRUE. TokenHandle contains the access token.
542 * Failure: FALSE.
544 * NOTES
545 * See NtOpenThreadToken.
547 BOOL WINAPI
548 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
549 BOOL OpenAsSelf, HANDLE *TokenHandle)
551 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
554 BOOL WINAPI
555 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
556 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
558 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
559 PreviousState, ReturnLength));
562 /******************************************************************************
563 * AdjustTokenPrivileges [ADVAPI32.@]
565 * Adjust the privileges of an open token handle.
567 * PARAMS
568 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
569 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
570 * NewState [I] Desired new privileges of the token
571 * BufferLength [I] Length of NewState
572 * PreviousState [O] Destination for the previous state
573 * ReturnLength [I/O] Size of PreviousState
576 * RETURNS
577 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
578 * Failure: FALSE.
580 * NOTES
581 * See NtAdjustPrivilegesToken.
583 BOOL WINAPI
584 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
585 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
586 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
588 NTSTATUS status;
590 TRACE("\n");
592 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
593 NewState, BufferLength, PreviousState,
594 ReturnLength);
595 SetLastError( RtlNtStatusToDosError( status ));
596 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
597 return TRUE;
598 else
599 return FALSE;
602 /******************************************************************************
603 * CheckTokenMembership [ADVAPI32.@]
605 * Determine if an access token is a member of a SID.
607 * PARAMS
608 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
609 * SidToCheck [I] SID that possibly contains the token
610 * IsMember [O] Destination for result.
612 * RETURNS
613 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
614 * Failure: FALSE.
616 BOOL WINAPI
617 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
618 PBOOL IsMember )
620 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
622 *IsMember = TRUE;
623 return(TRUE);
626 /******************************************************************************
627 * GetTokenInformation [ADVAPI32.@]
629 * Get a type of information about an access token.
631 * PARAMS
632 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
633 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
634 * tokeninfo [O] Destination for token information
635 * tokeninfolength [I] Length of tokeninfo
636 * retlen [O] Destination for returned token information length
638 * RETURNS
639 * Success: TRUE. tokeninfo contains retlen bytes of token information
640 * Failure: FALSE.
642 * NOTES
643 * See NtQueryInformationToken.
645 BOOL WINAPI
646 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
647 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
649 TRACE("(%p, %s, %p, %d, %p):\n",
650 token,
651 (tokeninfoclass == TokenUser) ? "TokenUser" :
652 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
653 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
654 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
655 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
656 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
657 (tokeninfoclass == TokenSource) ? "TokenSource" :
658 (tokeninfoclass == TokenType) ? "TokenType" :
659 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
660 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
661 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
662 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
663 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
664 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
665 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
666 "Unknown",
667 tokeninfo, tokeninfolength, retlen);
668 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
669 tokeninfolength, retlen));
672 /******************************************************************************
673 * SetTokenInformation [ADVAPI32.@]
675 * Set information for an access token.
677 * PARAMS
678 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
679 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
680 * tokeninfo [I] Token information to set
681 * tokeninfolength [I] Length of tokeninfo
683 * RETURNS
684 * Success: TRUE. The information for the token is set to tokeninfo.
685 * Failure: FALSE.
687 BOOL WINAPI
688 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
689 LPVOID tokeninfo, DWORD tokeninfolength )
691 TRACE("(%p, %s, %p, %d): stub\n",
692 token,
693 (tokeninfoclass == TokenUser) ? "TokenUser" :
694 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
695 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
696 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
697 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
698 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
699 (tokeninfoclass == TokenSource) ? "TokenSource" :
700 (tokeninfoclass == TokenType) ? "TokenType" :
701 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
702 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
703 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
704 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
705 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
706 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
707 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
708 "Unknown",
709 tokeninfo, tokeninfolength);
711 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
714 /*************************************************************************
715 * SetThreadToken [ADVAPI32.@]
717 * Assigns an 'impersonation token' to a thread so it can assume the
718 * security privileges of another thread or process. Can also remove
719 * a previously assigned token.
721 * PARAMS
722 * thread [O] Handle to thread to set the token for
723 * token [I] Token to set
725 * RETURNS
726 * Success: TRUE. The threads access token is set to token
727 * Failure: FALSE.
729 * NOTES
730 * Only supported on NT or higher. On Win9X this function does nothing.
731 * See SetTokenInformation.
733 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
735 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
736 ThreadImpersonationToken, &token, sizeof token ));
739 /*************************************************************************
740 * CreateRestrictedToken [ADVAPI32.@]
742 * Create a new more restricted token from an existing token.
744 * PARAMS
745 * baseToken [I] Token to base the new restricted token on
746 * flags [I] Options
747 * nDisableSids [I] Length of disableSids array
748 * disableSids [I] Array of SIDs to disable in the new token
749 * nDeletePrivs [I] Length of deletePrivs array
750 * deletePrivs [I] Array of privileges to delete in the new token
751 * nRestrictSids [I] Length of restrictSids array
752 * restrictSids [I] Array of SIDs to restrict in the new token
753 * newToken [O] Address where the new token is stored
755 * RETURNS
756 * Success: TRUE
757 * Failure: FALSE
759 BOOL WINAPI CreateRestrictedToken(
760 HANDLE baseToken,
761 DWORD flags,
762 DWORD nDisableSids,
763 PSID_AND_ATTRIBUTES disableSids,
764 DWORD nDeletePrivs,
765 PLUID_AND_ATTRIBUTES deletePrivs,
766 DWORD nRestrictSids,
767 PSID_AND_ATTRIBUTES restrictSids,
768 PHANDLE newToken)
770 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
771 baseToken, flags, nDisableSids, disableSids,
772 nDeletePrivs, deletePrivs,
773 nRestrictSids, restrictSids,
774 newToken);
775 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
776 return FALSE;
779 /* ##############################
780 ###### SID FUNCTIONS ######
781 ##############################
784 /******************************************************************************
785 * AllocateAndInitializeSid [ADVAPI32.@]
787 * PARAMS
788 * pIdentifierAuthority []
789 * nSubAuthorityCount []
790 * nSubAuthority0 []
791 * nSubAuthority1 []
792 * nSubAuthority2 []
793 * nSubAuthority3 []
794 * nSubAuthority4 []
795 * nSubAuthority5 []
796 * nSubAuthority6 []
797 * nSubAuthority7 []
798 * pSid []
800 BOOL WINAPI
801 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
802 BYTE nSubAuthorityCount,
803 DWORD nSubAuthority0, DWORD nSubAuthority1,
804 DWORD nSubAuthority2, DWORD nSubAuthority3,
805 DWORD nSubAuthority4, DWORD nSubAuthority5,
806 DWORD nSubAuthority6, DWORD nSubAuthority7,
807 PSID *pSid )
809 return set_ntstatus( RtlAllocateAndInitializeSid(
810 pIdentifierAuthority, nSubAuthorityCount,
811 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
812 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
813 pSid ));
816 /******************************************************************************
817 * FreeSid [ADVAPI32.@]
819 * PARAMS
820 * pSid []
822 PVOID WINAPI
823 FreeSid( PSID pSid )
825 RtlFreeSid(pSid);
826 return NULL; /* is documented like this */
829 /******************************************************************************
830 * CopySid [ADVAPI32.@]
832 * PARAMS
833 * nDestinationSidLength []
834 * pDestinationSid []
835 * pSourceSid []
837 BOOL WINAPI
838 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
840 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
843 /******************************************************************************
844 * CreateWellKnownSid [ADVAPI32.@]
846 BOOL WINAPI
847 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
848 PSID DomainSid,
849 PSID pSid,
850 DWORD* cbSid)
852 unsigned int i;
853 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
855 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
856 SetLastError(ERROR_INVALID_PARAMETER);
857 return FALSE;
860 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
861 if (WellKnownSids[i].Type == WellKnownSidType) {
862 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
864 if (*cbSid < length) {
865 SetLastError(ERROR_INSUFFICIENT_BUFFER);
866 return FALSE;
869 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
870 *cbSid = length;
871 return TRUE;
875 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
877 SetLastError(ERROR_INVALID_PARAMETER);
878 return FALSE;
881 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
882 if (WellKnownRids[i].Type == WellKnownSidType) {
883 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
884 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
885 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
887 if (*cbSid < output_sid_length) {
888 SetLastError(ERROR_INSUFFICIENT_BUFFER);
889 return FALSE;
892 CopyMemory(pSid, DomainSid, domain_sid_length);
893 (*GetSidSubAuthorityCount(pSid))++;
894 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
895 *cbSid = output_sid_length;
896 return TRUE;
899 SetLastError(ERROR_INVALID_PARAMETER);
900 return FALSE;
903 /******************************************************************************
904 * IsWellKnownSid [ADVAPI32.@]
906 BOOL WINAPI
907 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
909 unsigned int i;
910 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
912 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
913 if (WellKnownSids[i].Type == WellKnownSidType)
914 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
915 return TRUE;
917 return FALSE;
920 BOOL WINAPI
921 IsTokenRestricted( HANDLE TokenHandle )
923 TOKEN_GROUPS *groups;
924 DWORD size;
925 NTSTATUS status;
926 BOOL restricted;
928 TRACE("(%p)\n", TokenHandle);
930 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
931 if (status != STATUS_BUFFER_TOO_SMALL)
932 return FALSE;
934 groups = HeapAlloc(GetProcessHeap(), 0, size);
935 if (!groups)
937 SetLastError(ERROR_OUTOFMEMORY);
938 return FALSE;
941 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
942 if (status != STATUS_SUCCESS)
944 HeapFree(GetProcessHeap(), 0, groups);
945 return set_ntstatus(status);
948 if (groups->GroupCount)
949 restricted = TRUE;
950 else
951 restricted = FALSE;
953 HeapFree(GetProcessHeap(), 0, groups);
955 return restricted;
958 /******************************************************************************
959 * IsValidSid [ADVAPI32.@]
961 * PARAMS
962 * pSid []
964 BOOL WINAPI
965 IsValidSid( PSID pSid )
967 return RtlValidSid( pSid );
970 /******************************************************************************
971 * EqualSid [ADVAPI32.@]
973 * PARAMS
974 * pSid1 []
975 * pSid2 []
977 BOOL WINAPI
978 EqualSid( PSID pSid1, PSID pSid2 )
980 return RtlEqualSid( pSid1, pSid2 );
983 /******************************************************************************
984 * EqualPrefixSid [ADVAPI32.@]
986 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
988 return RtlEqualPrefixSid(pSid1, pSid2);
991 /******************************************************************************
992 * GetSidLengthRequired [ADVAPI32.@]
994 * PARAMS
995 * nSubAuthorityCount []
997 DWORD WINAPI
998 GetSidLengthRequired( BYTE nSubAuthorityCount )
1000 return RtlLengthRequiredSid(nSubAuthorityCount);
1003 /******************************************************************************
1004 * InitializeSid [ADVAPI32.@]
1006 * PARAMS
1007 * pIdentifierAuthority []
1009 BOOL WINAPI
1010 InitializeSid (
1011 PSID pSid,
1012 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1013 BYTE nSubAuthorityCount)
1015 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1018 DWORD WINAPI
1019 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1021 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1023 return 1;
1026 DWORD WINAPI
1027 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1029 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1031 return 1;
1034 /******************************************************************************
1035 * GetSidIdentifierAuthority [ADVAPI32.@]
1037 * PARAMS
1038 * pSid []
1040 PSID_IDENTIFIER_AUTHORITY WINAPI
1041 GetSidIdentifierAuthority( PSID pSid )
1043 return RtlIdentifierAuthoritySid(pSid);
1046 /******************************************************************************
1047 * GetSidSubAuthority [ADVAPI32.@]
1049 * PARAMS
1050 * pSid []
1051 * nSubAuthority []
1053 PDWORD WINAPI
1054 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1056 return RtlSubAuthoritySid(pSid, nSubAuthority);
1059 /******************************************************************************
1060 * GetSidSubAuthorityCount [ADVAPI32.@]
1062 * PARAMS
1063 * pSid []
1065 PUCHAR WINAPI
1066 GetSidSubAuthorityCount (PSID pSid)
1068 return RtlSubAuthorityCountSid(pSid);
1071 /******************************************************************************
1072 * GetLengthSid [ADVAPI32.@]
1074 * PARAMS
1075 * pSid []
1077 DWORD WINAPI
1078 GetLengthSid (PSID pSid)
1080 return RtlLengthSid(pSid);
1083 /* ##############################################
1084 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1085 ##############################################
1088 /******************************************************************************
1089 * BuildSecurityDescriptorA [ADVAPI32.@]
1091 * Builds a SD from
1093 * PARAMS
1094 * pOwner [I]
1095 * pGroup [I]
1096 * cCountOfAccessEntries [I]
1097 * pListOfAccessEntries [I]
1098 * cCountOfAuditEntries [I]
1099 * pListofAuditEntries [I]
1100 * pOldSD [I]
1101 * lpdwBufferLength [I/O]
1102 * pNewSD [O]
1104 * RETURNS
1105 * Success: ERROR_SUCCESS
1106 * Failure: nonzero error code from Winerror.h
1108 DWORD WINAPI BuildSecurityDescriptorA(
1109 IN PTRUSTEEA pOwner,
1110 IN PTRUSTEEA pGroup,
1111 IN ULONG cCountOfAccessEntries,
1112 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1113 IN ULONG cCountOfAuditEntries,
1114 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1115 IN PSECURITY_DESCRIPTOR pOldSD,
1116 IN OUT PULONG lpdwBufferLength,
1117 OUT PSECURITY_DESCRIPTOR* pNewSD)
1119 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1120 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1121 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1123 return ERROR_CALL_NOT_IMPLEMENTED;
1126 /******************************************************************************
1127 * BuildSecurityDescriptorW [ADVAPI32.@]
1129 * See BuildSecurityDescriptorA.
1131 DWORD WINAPI BuildSecurityDescriptorW(
1132 IN PTRUSTEEW pOwner,
1133 IN PTRUSTEEW pGroup,
1134 IN ULONG cCountOfAccessEntries,
1135 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1136 IN ULONG cCountOfAuditEntries,
1137 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1138 IN PSECURITY_DESCRIPTOR pOldSD,
1139 IN OUT PULONG lpdwBufferLength,
1140 OUT PSECURITY_DESCRIPTOR* pNewSD)
1142 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1146 return ERROR_CALL_NOT_IMPLEMENTED;
1149 /******************************************************************************
1150 * InitializeSecurityDescriptor [ADVAPI32.@]
1152 * PARAMS
1153 * pDescr []
1154 * revision []
1156 BOOL WINAPI
1157 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1159 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1163 /******************************************************************************
1164 * MakeAbsoluteSD [ADVAPI32.@]
1166 BOOL WINAPI MakeAbsoluteSD (
1167 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1168 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1169 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1170 OUT PACL pDacl,
1171 OUT LPDWORD lpdwDaclSize,
1172 OUT PACL pSacl,
1173 OUT LPDWORD lpdwSaclSize,
1174 OUT PSID pOwner,
1175 OUT LPDWORD lpdwOwnerSize,
1176 OUT PSID pPrimaryGroup,
1177 OUT LPDWORD lpdwPrimaryGroupSize)
1179 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1180 pAbsoluteSecurityDescriptor,
1181 lpdwAbsoluteSecurityDescriptorSize,
1182 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1183 pOwner, lpdwOwnerSize,
1184 pPrimaryGroup, lpdwPrimaryGroupSize));
1187 /******************************************************************************
1188 * GetKernelObjectSecurity [ADVAPI32.@]
1190 BOOL WINAPI GetKernelObjectSecurity(
1191 HANDLE Handle,
1192 SECURITY_INFORMATION RequestedInformation,
1193 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1194 DWORD nLength,
1195 LPDWORD lpnLengthNeeded )
1197 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1198 pSecurityDescriptor, nLength, lpnLengthNeeded);
1200 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1201 nLength, lpnLengthNeeded ));
1204 /******************************************************************************
1205 * GetPrivateObjectSecurity [ADVAPI32.@]
1207 BOOL WINAPI GetPrivateObjectSecurity(
1208 PSECURITY_DESCRIPTOR ObjectDescriptor,
1209 SECURITY_INFORMATION SecurityInformation,
1210 PSECURITY_DESCRIPTOR ResultantDescriptor,
1211 DWORD DescriptorLength,
1212 PDWORD ReturnLength )
1214 SECURITY_DESCRIPTOR desc;
1215 BOOL defaulted, present;
1216 PACL pacl;
1217 PSID psid;
1219 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1220 ResultantDescriptor, DescriptorLength, ReturnLength);
1222 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1223 return FALSE;
1225 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1227 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1228 return FALSE;
1229 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1232 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1234 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1235 return FALSE;
1236 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1239 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1241 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1242 return FALSE;
1243 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1246 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1248 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1249 return FALSE;
1250 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1253 *ReturnLength = DescriptorLength;
1254 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1257 /******************************************************************************
1258 * GetSecurityDescriptorLength [ADVAPI32.@]
1260 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1262 return RtlLengthSecurityDescriptor(pDescr);
1265 /******************************************************************************
1266 * GetSecurityDescriptorOwner [ADVAPI32.@]
1268 * PARAMS
1269 * pOwner []
1270 * lpbOwnerDefaulted []
1272 BOOL WINAPI
1273 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1274 LPBOOL lpbOwnerDefaulted )
1276 BOOLEAN defaulted;
1277 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1278 *lpbOwnerDefaulted = defaulted;
1279 return ret;
1282 /******************************************************************************
1283 * SetSecurityDescriptorOwner [ADVAPI32.@]
1285 * PARAMS
1287 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1288 PSID pOwner, BOOL bOwnerDefaulted)
1290 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1292 /******************************************************************************
1293 * GetSecurityDescriptorGroup [ADVAPI32.@]
1295 BOOL WINAPI GetSecurityDescriptorGroup(
1296 PSECURITY_DESCRIPTOR SecurityDescriptor,
1297 PSID *Group,
1298 LPBOOL GroupDefaulted)
1300 BOOLEAN defaulted;
1301 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1302 *GroupDefaulted = defaulted;
1303 return ret;
1305 /******************************************************************************
1306 * SetSecurityDescriptorGroup [ADVAPI32.@]
1308 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1309 PSID Group, BOOL GroupDefaulted)
1311 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1314 /******************************************************************************
1315 * IsValidSecurityDescriptor [ADVAPI32.@]
1317 * PARAMS
1318 * lpsecdesc []
1320 BOOL WINAPI
1321 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1323 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1326 /******************************************************************************
1327 * GetSecurityDescriptorDacl [ADVAPI32.@]
1329 BOOL WINAPI GetSecurityDescriptorDacl(
1330 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1331 OUT LPBOOL lpbDaclPresent,
1332 OUT PACL *pDacl,
1333 OUT LPBOOL lpbDaclDefaulted)
1335 BOOLEAN present, defaulted;
1336 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1337 *lpbDaclPresent = present;
1338 *lpbDaclDefaulted = defaulted;
1339 return ret;
1342 /******************************************************************************
1343 * SetSecurityDescriptorDacl [ADVAPI32.@]
1345 BOOL WINAPI
1346 SetSecurityDescriptorDacl (
1347 PSECURITY_DESCRIPTOR lpsd,
1348 BOOL daclpresent,
1349 PACL dacl,
1350 BOOL dacldefaulted )
1352 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1354 /******************************************************************************
1355 * GetSecurityDescriptorSacl [ADVAPI32.@]
1357 BOOL WINAPI GetSecurityDescriptorSacl(
1358 IN PSECURITY_DESCRIPTOR lpsd,
1359 OUT LPBOOL lpbSaclPresent,
1360 OUT PACL *pSacl,
1361 OUT LPBOOL lpbSaclDefaulted)
1363 BOOLEAN present, defaulted;
1364 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1365 *lpbSaclPresent = present;
1366 *lpbSaclDefaulted = defaulted;
1367 return ret;
1370 /**************************************************************************
1371 * SetSecurityDescriptorSacl [ADVAPI32.@]
1373 BOOL WINAPI SetSecurityDescriptorSacl (
1374 PSECURITY_DESCRIPTOR lpsd,
1375 BOOL saclpresent,
1376 PACL lpsacl,
1377 BOOL sacldefaulted)
1379 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1381 /******************************************************************************
1382 * MakeSelfRelativeSD [ADVAPI32.@]
1384 * PARAMS
1385 * lpabssecdesc []
1386 * lpselfsecdesc []
1387 * lpbuflen []
1389 BOOL WINAPI
1390 MakeSelfRelativeSD(
1391 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1392 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1393 IN OUT LPDWORD lpdwBufferLength)
1395 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1396 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1399 /******************************************************************************
1400 * GetSecurityDescriptorControl [ADVAPI32.@]
1403 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1404 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1406 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1409 /******************************************************************************
1410 * SetSecurityDescriptorControl [ADVAPI32.@]
1412 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1413 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1414 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1416 return set_ntstatus( RtlSetControlSecurityDescriptor(
1417 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1420 /* ##############################
1421 ###### ACL FUNCTIONS ######
1422 ##############################
1425 /*************************************************************************
1426 * InitializeAcl [ADVAPI32.@]
1428 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1430 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1433 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1435 IO_STATUS_BLOCK io_block;
1437 TRACE("(%p)\n", hNamedPipe);
1439 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1440 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1443 /******************************************************************************
1444 * AddAccessAllowedAce [ADVAPI32.@]
1446 BOOL WINAPI AddAccessAllowedAce(
1447 IN OUT PACL pAcl,
1448 IN DWORD dwAceRevision,
1449 IN DWORD AccessMask,
1450 IN PSID pSid)
1452 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1455 /******************************************************************************
1456 * AddAccessAllowedAceEx [ADVAPI32.@]
1458 BOOL WINAPI AddAccessAllowedAceEx(
1459 IN OUT PACL pAcl,
1460 IN DWORD dwAceRevision,
1461 IN DWORD AceFlags,
1462 IN DWORD AccessMask,
1463 IN PSID pSid)
1465 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1468 /******************************************************************************
1469 * AddAccessDeniedAce [ADVAPI32.@]
1471 BOOL WINAPI AddAccessDeniedAce(
1472 IN OUT PACL pAcl,
1473 IN DWORD dwAceRevision,
1474 IN DWORD AccessMask,
1475 IN PSID pSid)
1477 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1480 /******************************************************************************
1481 * AddAccessDeniedAceEx [ADVAPI32.@]
1483 BOOL WINAPI AddAccessDeniedAceEx(
1484 IN OUT PACL pAcl,
1485 IN DWORD dwAceRevision,
1486 IN DWORD AceFlags,
1487 IN DWORD AccessMask,
1488 IN PSID pSid)
1490 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1493 /******************************************************************************
1494 * AddAce [ADVAPI32.@]
1496 BOOL WINAPI AddAce(
1497 IN OUT PACL pAcl,
1498 IN DWORD dwAceRevision,
1499 IN DWORD dwStartingAceIndex,
1500 LPVOID pAceList,
1501 DWORD nAceListLength)
1503 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1506 /******************************************************************************
1507 * DeleteAce [ADVAPI32.@]
1509 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1511 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1514 /******************************************************************************
1515 * FindFirstFreeAce [ADVAPI32.@]
1517 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1519 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1522 /******************************************************************************
1523 * GetAce [ADVAPI32.@]
1525 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1527 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1530 /******************************************************************************
1531 * GetAclInformation [ADVAPI32.@]
1533 BOOL WINAPI GetAclInformation(
1534 PACL pAcl,
1535 LPVOID pAclInformation,
1536 DWORD nAclInformationLength,
1537 ACL_INFORMATION_CLASS dwAclInformationClass)
1539 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1540 nAclInformationLength, dwAclInformationClass));
1543 /******************************************************************************
1544 * IsValidAcl [ADVAPI32.@]
1546 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1548 return RtlValidAcl(pAcl);
1551 /* ##############################
1552 ###### MISC FUNCTIONS ######
1553 ##############################
1556 /******************************************************************************
1557 * AllocateLocallyUniqueId [ADVAPI32.@]
1559 * PARAMS
1560 * lpLuid []
1562 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1564 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1567 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1568 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1570 { '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 };
1571 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1572 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1574 { '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 };
1575 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1576 { '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 };
1577 static const WCHAR SE_TCB_NAME_W[] =
1578 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_SECURITY_NAME_W[] =
1580 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1581 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1582 { '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 };
1583 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1584 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1585 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1586 { '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 };
1587 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1588 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1592 { '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 };
1593 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1596 { '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 };
1597 static const WCHAR SE_BACKUP_NAME_W[] =
1598 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_RESTORE_NAME_W[] =
1600 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1602 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_DEBUG_NAME_W[] =
1604 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_AUDIT_NAME_W[] =
1606 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1608 { '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 };
1609 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1610 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1612 { '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 };
1613 static const WCHAR SE_UNDOCK_NAME_W[] =
1614 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1616 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1617 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1618 { '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 };
1619 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1620 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1622 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1623 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1624 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1626 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1628 NULL,
1629 NULL,
1630 SE_CREATE_TOKEN_NAME_W,
1631 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1632 SE_LOCK_MEMORY_NAME_W,
1633 SE_INCREASE_QUOTA_NAME_W,
1634 SE_MACHINE_ACCOUNT_NAME_W,
1635 SE_TCB_NAME_W,
1636 SE_SECURITY_NAME_W,
1637 SE_TAKE_OWNERSHIP_NAME_W,
1638 SE_LOAD_DRIVER_NAME_W,
1639 SE_SYSTEM_PROFILE_NAME_W,
1640 SE_SYSTEMTIME_NAME_W,
1641 SE_PROF_SINGLE_PROCESS_NAME_W,
1642 SE_INC_BASE_PRIORITY_NAME_W,
1643 SE_CREATE_PAGEFILE_NAME_W,
1644 SE_CREATE_PERMANENT_NAME_W,
1645 SE_BACKUP_NAME_W,
1646 SE_RESTORE_NAME_W,
1647 SE_SHUTDOWN_NAME_W,
1648 SE_DEBUG_NAME_W,
1649 SE_AUDIT_NAME_W,
1650 SE_SYSTEM_ENVIRONMENT_NAME_W,
1651 SE_CHANGE_NOTIFY_NAME_W,
1652 SE_REMOTE_SHUTDOWN_NAME_W,
1653 SE_UNDOCK_NAME_W,
1654 SE_SYNC_AGENT_NAME_W,
1655 SE_ENABLE_DELEGATION_NAME_W,
1656 SE_MANAGE_VOLUME_NAME_W,
1657 SE_IMPERSONATE_NAME_W,
1658 SE_CREATE_GLOBAL_NAME_W,
1661 /******************************************************************************
1662 * LookupPrivilegeValueW [ADVAPI32.@]
1664 * See LookupPrivilegeValueA.
1666 BOOL WINAPI
1667 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1669 UINT i;
1671 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1673 if (!ADVAPI_IsLocalComputer(lpSystemName))
1675 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1676 return FALSE;
1678 if (!lpName)
1680 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1681 return FALSE;
1683 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1685 if( !WellKnownPrivNames[i] )
1686 continue;
1687 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1688 continue;
1689 lpLuid->LowPart = i;
1690 lpLuid->HighPart = 0;
1691 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1692 lpLuid->HighPart, lpLuid->LowPart );
1693 return TRUE;
1695 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1696 return FALSE;
1699 /******************************************************************************
1700 * LookupPrivilegeValueA [ADVAPI32.@]
1702 * Retrieves LUID used on a system to represent the privilege name.
1704 * PARAMS
1705 * lpSystemName [I] Name of the system
1706 * lpName [I] Name of the privilege
1707 * lpLuid [O] Destination for the resulting LUID
1709 * RETURNS
1710 * Success: TRUE. lpLuid contains the requested LUID.
1711 * Failure: FALSE.
1713 BOOL WINAPI
1714 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1716 UNICODE_STRING lpSystemNameW;
1717 UNICODE_STRING lpNameW;
1718 BOOL ret;
1720 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1721 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1722 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1723 RtlFreeUnicodeString(&lpNameW);
1724 RtlFreeUnicodeString(&lpSystemNameW);
1725 return ret;
1728 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1729 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1731 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1732 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1734 return FALSE;
1737 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1738 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1740 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1741 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1743 return FALSE;
1746 /******************************************************************************
1747 * LookupPrivilegeNameA [ADVAPI32.@]
1749 * See LookupPrivilegeNameW.
1751 BOOL WINAPI
1752 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1753 LPDWORD cchName)
1755 UNICODE_STRING lpSystemNameW;
1756 BOOL ret;
1757 DWORD wLen = 0;
1759 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1761 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1762 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1763 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1765 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1767 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1768 &wLen);
1769 if (ret)
1771 /* Windows crashes if cchName is NULL, so will I */
1772 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1773 *cchName, NULL, NULL);
1775 if (len == 0)
1777 /* WideCharToMultiByte failed */
1778 ret = FALSE;
1780 else if (len > *cchName)
1782 *cchName = len;
1783 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1784 ret = FALSE;
1786 else
1788 /* WideCharToMultiByte succeeded, output length needs to be
1789 * length not including NULL terminator
1791 *cchName = len - 1;
1794 HeapFree(GetProcessHeap(), 0, lpNameW);
1796 RtlFreeUnicodeString(&lpSystemNameW);
1797 return ret;
1800 /******************************************************************************
1801 * LookupPrivilegeNameW [ADVAPI32.@]
1803 * Retrieves the privilege name referred to by the LUID lpLuid.
1805 * PARAMS
1806 * lpSystemName [I] Name of the system
1807 * lpLuid [I] Privilege value
1808 * lpName [O] Name of the privilege
1809 * cchName [I/O] Number of characters in lpName.
1811 * RETURNS
1812 * Success: TRUE. lpName contains the name of the privilege whose value is
1813 * *lpLuid.
1814 * Failure: FALSE.
1816 * REMARKS
1817 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1818 * using this function.
1819 * If the length of lpName is too small, on return *cchName will contain the
1820 * number of WCHARs needed to contain the privilege, including the NULL
1821 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1822 * On success, *cchName will contain the number of characters stored in
1823 * lpName, NOT including the NULL terminator.
1825 BOOL WINAPI
1826 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1827 LPDWORD cchName)
1829 size_t privNameLen;
1831 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1833 if (!ADVAPI_IsLocalComputer(lpSystemName))
1835 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1836 return FALSE;
1838 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1839 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1841 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1842 return FALSE;
1844 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1845 /* Windows crashes if cchName is NULL, so will I */
1846 if (*cchName <= privNameLen)
1848 *cchName = privNameLen + 1;
1849 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1850 return FALSE;
1852 else
1854 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1855 *cchName = privNameLen;
1856 return TRUE;
1860 /******************************************************************************
1861 * GetFileSecurityA [ADVAPI32.@]
1863 * Obtains Specified information about the security of a file or directory.
1865 * PARAMS
1866 * lpFileName [I] Name of the file to get info for
1867 * RequestedInformation [I] SE_ flags from "winnt.h"
1868 * pSecurityDescriptor [O] Destination for security information
1869 * nLength [I] Length of pSecurityDescriptor
1870 * lpnLengthNeeded [O] Destination for length of returned security information
1872 * RETURNS
1873 * Success: TRUE. pSecurityDescriptor contains the requested information.
1874 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1876 * NOTES
1877 * The information returned is constrained by the callers access rights and
1878 * privileges.
1880 BOOL WINAPI
1881 GetFileSecurityA( LPCSTR lpFileName,
1882 SECURITY_INFORMATION RequestedInformation,
1883 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1884 DWORD nLength, LPDWORD lpnLengthNeeded )
1886 DWORD len;
1887 BOOL r;
1888 LPWSTR name = NULL;
1890 if( lpFileName )
1892 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1893 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1894 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1897 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1898 nLength, lpnLengthNeeded );
1899 HeapFree( GetProcessHeap(), 0, name );
1901 return r;
1904 /******************************************************************************
1905 * GetFileSecurityW [ADVAPI32.@]
1907 * See GetFileSecurityA.
1909 BOOL WINAPI
1910 GetFileSecurityW( LPCWSTR lpFileName,
1911 SECURITY_INFORMATION RequestedInformation,
1912 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1913 DWORD nLength, LPDWORD lpnLengthNeeded )
1915 HANDLE hfile;
1916 NTSTATUS status;
1917 DWORD access = 0;
1919 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1920 RequestedInformation, pSecurityDescriptor,
1921 nLength, lpnLengthNeeded);
1923 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1924 DACL_SECURITY_INFORMATION))
1925 access |= READ_CONTROL;
1926 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1927 access |= ACCESS_SYSTEM_SECURITY;
1929 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1930 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1931 if ( hfile == INVALID_HANDLE_VALUE )
1932 return FALSE;
1934 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1935 nLength, lpnLengthNeeded );
1936 CloseHandle( hfile );
1937 return set_ntstatus( status );
1941 /******************************************************************************
1942 * LookupAccountSidA [ADVAPI32.@]
1944 BOOL WINAPI
1945 LookupAccountSidA(
1946 IN LPCSTR system,
1947 IN PSID sid,
1948 OUT LPSTR account,
1949 IN OUT LPDWORD accountSize,
1950 OUT LPSTR domain,
1951 IN OUT LPDWORD domainSize,
1952 OUT PSID_NAME_USE name_use )
1954 DWORD len;
1955 BOOL r;
1956 LPWSTR systemW = NULL;
1957 LPWSTR accountW = NULL;
1958 LPWSTR domainW = NULL;
1959 DWORD accountSizeW = *accountSize;
1960 DWORD domainSizeW = *domainSize;
1962 if (system) {
1963 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1964 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1965 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1967 if (account)
1968 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1969 if (domain)
1970 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1972 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1974 if (r) {
1975 if (accountW && *accountSize) {
1976 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1977 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1978 *accountSize = len;
1979 } else
1980 *accountSize = accountSizeW + 1;
1982 if (domainW && *domainSize) {
1983 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1984 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1985 *domainSize = len;
1986 } else
1987 *domainSize = domainSizeW + 1;
1990 HeapFree( GetProcessHeap(), 0, systemW );
1991 HeapFree( GetProcessHeap(), 0, accountW );
1992 HeapFree( GetProcessHeap(), 0, domainW );
1994 return r;
1997 /******************************************************************************
1998 * LookupAccountSidW [ADVAPI32.@]
2000 * PARAMS
2001 * system []
2002 * sid []
2003 * account []
2004 * accountSize []
2005 * domain []
2006 * domainSize []
2007 * name_use []
2010 BOOL WINAPI
2011 LookupAccountSidW(
2012 IN LPCWSTR system,
2013 IN PSID sid,
2014 OUT LPWSTR account,
2015 IN OUT LPDWORD accountSize,
2016 OUT LPWSTR domain,
2017 IN OUT LPDWORD domainSize,
2018 OUT PSID_NAME_USE name_use )
2020 unsigned int i, j;
2021 const WCHAR * ac = NULL;
2022 const WCHAR * dm = NULL;
2023 SID_NAME_USE use = 0;
2024 LPWSTR computer_name = NULL;
2025 LPWSTR account_name = NULL;
2027 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2028 debugstr_w(system),debugstr_sid(sid),
2029 account,accountSize,accountSize?*accountSize:0,
2030 domain,domainSize,domainSize?*domainSize:0,
2031 name_use);
2033 if (!ADVAPI_IsLocalComputer(system)) {
2034 FIXME("Only local computer supported!\n");
2035 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2036 return FALSE;
2039 /* check the well known SIDs first */
2040 for (i = 0; i <= 60; i++) {
2041 if (IsWellKnownSid(sid, i)) {
2042 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2043 if (ACCOUNT_SIDS[j].type == i) {
2044 ac = ACCOUNT_SIDS[j].account;
2045 dm = ACCOUNT_SIDS[j].domain;
2046 use = ACCOUNT_SIDS[j].name_use;
2049 break;
2053 if (dm == NULL) {
2054 MAX_SID local;
2056 /* check for the local computer next */
2057 if (ADVAPI_GetComputerSid(&local)) {
2058 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2059 BOOL result;
2061 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2062 result = GetComputerNameW(computer_name, &size);
2064 if (result) {
2065 if (EqualSid(sid, &local)) {
2066 dm = computer_name;
2067 ac = Blank;
2068 use = 3;
2069 } else {
2070 local.SubAuthorityCount++;
2072 if (EqualPrefixSid(sid, &local)) {
2073 dm = computer_name;
2074 use = 1;
2075 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2076 case DOMAIN_USER_RID_ADMIN:
2077 ac = Administrator;
2078 break;
2079 case DOMAIN_USER_RID_GUEST:
2080 ac = Guest;
2081 break;
2082 case DOMAIN_GROUP_RID_ADMINS:
2083 ac = Domain_Admins;
2084 break;
2085 case DOMAIN_GROUP_RID_USERS:
2086 ac = Domain_Users;
2087 break;
2088 case DOMAIN_GROUP_RID_GUESTS:
2089 ac = Domain_Guests;
2090 break;
2091 case DOMAIN_GROUP_RID_COMPUTERS:
2092 ac = Domain_Computers;
2093 break;
2094 case DOMAIN_GROUP_RID_CONTROLLERS:
2095 ac = Domain_Controllers;
2096 break;
2097 case DOMAIN_GROUP_RID_CERT_ADMINS:
2098 ac = Cert_Publishers;
2099 break;
2100 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2101 ac = Schema_Admins;
2102 break;
2103 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2104 ac = Enterprise_Admins;
2105 break;
2106 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2107 ac = Group_Policy_Creator_Owners;
2108 break;
2109 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2110 ac = RAS_and_IAS_Servers;
2111 break;
2112 case 1000: /* first user account */
2113 size = UNLEN + 1;
2114 account_name = HeapAlloc(
2115 GetProcessHeap(), 0, size * sizeof(WCHAR));
2116 if (GetUserNameW(account_name, &size))
2117 ac = account_name;
2118 else
2119 dm = NULL;
2121 break;
2122 default:
2123 dm = NULL;
2124 break;
2132 if (dm) {
2133 DWORD ac_len = lstrlenW(ac);
2134 DWORD dm_len = lstrlenW(dm);
2135 BOOL status = TRUE;
2137 if (*accountSize > ac_len) {
2138 if (account)
2139 lstrcpyW(account, ac);
2141 if (*domainSize > dm_len) {
2142 if (domain)
2143 lstrcpyW(domain, dm);
2145 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2146 ((*domainSize != 0) && (*domainSize < dm_len))) {
2147 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2148 status = FALSE;
2150 if (*domainSize)
2151 *domainSize = dm_len;
2152 else
2153 *domainSize = dm_len + 1;
2154 if (*accountSize)
2155 *accountSize = ac_len;
2156 else
2157 *accountSize = ac_len + 1;
2158 *name_use = use;
2159 HeapFree(GetProcessHeap(), 0, account_name);
2160 HeapFree(GetProcessHeap(), 0, computer_name);
2161 return status;
2164 HeapFree(GetProcessHeap(), 0, account_name);
2165 HeapFree(GetProcessHeap(), 0, computer_name);
2166 SetLastError(ERROR_NONE_MAPPED);
2167 return FALSE;
2170 /******************************************************************************
2171 * SetFileSecurityA [ADVAPI32.@]
2173 * See SetFileSecurityW.
2175 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2176 SECURITY_INFORMATION RequestedInformation,
2177 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2179 DWORD len;
2180 BOOL r;
2181 LPWSTR name = NULL;
2183 if( lpFileName )
2185 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2186 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2187 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2190 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2191 HeapFree( GetProcessHeap(), 0, name );
2193 return r;
2196 /******************************************************************************
2197 * SetFileSecurityW [ADVAPI32.@]
2199 * Sets the security of a file or directory.
2201 * PARAMS
2202 * lpFileName []
2203 * RequestedInformation []
2204 * pSecurityDescriptor []
2206 * RETURNS
2207 * Success: TRUE.
2208 * Failure: FALSE.
2210 BOOL WINAPI
2211 SetFileSecurityW( LPCWSTR lpFileName,
2212 SECURITY_INFORMATION RequestedInformation,
2213 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2215 HANDLE file;
2216 DWORD access = 0;
2217 NTSTATUS status;
2219 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2220 pSecurityDescriptor );
2222 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2223 RequestedInformation & GROUP_SECURITY_INFORMATION)
2224 access |= WRITE_OWNER;
2225 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2226 access |= ACCESS_SYSTEM_SECURITY;
2227 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2228 access |= WRITE_DAC;
2230 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2231 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2232 if (file == INVALID_HANDLE_VALUE)
2233 return FALSE;
2235 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2236 CloseHandle( file );
2237 return set_ntstatus( status );
2240 /******************************************************************************
2241 * QueryWindows31FilesMigration [ADVAPI32.@]
2243 * PARAMS
2244 * x1 []
2246 BOOL WINAPI
2247 QueryWindows31FilesMigration( DWORD x1 )
2249 FIXME("(%d):stub\n",x1);
2250 return TRUE;
2253 /******************************************************************************
2254 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2256 * PARAMS
2257 * x1 []
2258 * x2 []
2259 * x3 []
2260 * x4 []
2262 BOOL WINAPI
2263 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2264 DWORD x4 )
2266 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2267 return TRUE;
2270 /******************************************************************************
2271 * NotifyBootConfigStatus [ADVAPI32.@]
2273 * PARAMS
2274 * x1 []
2276 BOOL WINAPI
2277 NotifyBootConfigStatus( BOOL x1 )
2279 FIXME("(0x%08d):stub\n",x1);
2280 return 1;
2283 /******************************************************************************
2284 * RevertToSelf [ADVAPI32.@]
2286 * Ends the impersonation of a user.
2288 * PARAMS
2289 * void []
2291 * RETURNS
2292 * Success: TRUE.
2293 * Failure: FALSE.
2295 BOOL WINAPI
2296 RevertToSelf( void )
2298 HANDLE Token = NULL;
2299 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2300 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2303 /******************************************************************************
2304 * ImpersonateSelf [ADVAPI32.@]
2306 * Makes an impersonation token that represents the process user and assigns
2307 * to the current thread.
2309 * PARAMS
2310 * ImpersonationLevel [I] Level at which to impersonate.
2312 * RETURNS
2313 * Success: TRUE.
2314 * Failure: FALSE.
2316 BOOL WINAPI
2317 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2319 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2322 /******************************************************************************
2323 * ImpersonateLoggedOnUser [ADVAPI32.@]
2325 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2327 DWORD size;
2328 NTSTATUS Status;
2329 HANDLE ImpersonationToken;
2330 TOKEN_TYPE Type;
2331 static BOOL warn = TRUE;
2333 if (warn)
2335 FIXME( "(%p)\n", hToken );
2336 warn = FALSE;
2338 if (!GetTokenInformation( hToken, TokenType, &Type,
2339 sizeof(TOKEN_TYPE), &size ))
2340 return FALSE;
2342 if (Type == TokenPrimary)
2344 OBJECT_ATTRIBUTES ObjectAttributes;
2346 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2348 Status = NtDuplicateToken( hToken,
2349 TOKEN_IMPERSONATE | TOKEN_QUERY,
2350 &ObjectAttributes,
2351 SecurityImpersonation,
2352 TokenImpersonation,
2353 &ImpersonationToken );
2354 if (Status != STATUS_SUCCESS)
2356 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2357 SetLastError( RtlNtStatusToDosError( Status ) );
2358 return FALSE;
2361 else
2362 ImpersonationToken = hToken;
2364 Status = NtSetInformationThread( GetCurrentThread(),
2365 ThreadImpersonationToken,
2366 &ImpersonationToken,
2367 sizeof(ImpersonationToken) );
2369 if (Type == TokenPrimary)
2370 NtClose( ImpersonationToken );
2372 if (Status != STATUS_SUCCESS)
2374 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2375 SetLastError( RtlNtStatusToDosError( Status ) );
2376 return FALSE;
2379 return TRUE;
2382 /******************************************************************************
2383 * AccessCheck [ADVAPI32.@]
2385 BOOL WINAPI
2386 AccessCheck(
2387 PSECURITY_DESCRIPTOR SecurityDescriptor,
2388 HANDLE ClientToken,
2389 DWORD DesiredAccess,
2390 PGENERIC_MAPPING GenericMapping,
2391 PPRIVILEGE_SET PrivilegeSet,
2392 LPDWORD PrivilegeSetLength,
2393 LPDWORD GrantedAccess,
2394 LPBOOL AccessStatus)
2396 NTSTATUS access_status;
2397 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2398 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2399 GrantedAccess, &access_status) );
2400 if (ret) *AccessStatus = set_ntstatus( access_status );
2401 return ret;
2405 /******************************************************************************
2406 * AccessCheckByType [ADVAPI32.@]
2408 BOOL WINAPI AccessCheckByType(
2409 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2410 PSID PrincipalSelfSid,
2411 HANDLE ClientToken,
2412 DWORD DesiredAccess,
2413 POBJECT_TYPE_LIST ObjectTypeList,
2414 DWORD ObjectTypeListLength,
2415 PGENERIC_MAPPING GenericMapping,
2416 PPRIVILEGE_SET PrivilegeSet,
2417 LPDWORD PrivilegeSetLength,
2418 LPDWORD GrantedAccess,
2419 LPBOOL AccessStatus)
2421 FIXME("stub\n");
2423 *AccessStatus = TRUE;
2425 return !*AccessStatus;
2428 /******************************************************************************
2429 * MapGenericMask [ADVAPI32.@]
2431 * Maps generic access rights into specific access rights according to the
2432 * supplied mapping.
2434 * PARAMS
2435 * AccessMask [I/O] Access rights.
2436 * GenericMapping [I] The mapping between generic and specific rights.
2438 * RETURNS
2439 * Nothing.
2441 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2443 RtlMapGenericMask( AccessMask, GenericMapping );
2446 /*************************************************************************
2447 * SetKernelObjectSecurity [ADVAPI32.@]
2449 BOOL WINAPI SetKernelObjectSecurity (
2450 IN HANDLE Handle,
2451 IN SECURITY_INFORMATION SecurityInformation,
2452 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2454 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2458 /******************************************************************************
2459 * AddAuditAccessAce [ADVAPI32.@]
2461 BOOL WINAPI AddAuditAccessAce(
2462 IN OUT PACL pAcl,
2463 IN DWORD dwAceRevision,
2464 IN DWORD dwAccessMask,
2465 IN PSID pSid,
2466 IN BOOL bAuditSuccess,
2467 IN BOOL bAuditFailure)
2469 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2470 bAuditSuccess, bAuditFailure) );
2473 /******************************************************************************
2474 * AddAuditAccessAce [ADVAPI32.@]
2476 BOOL WINAPI AddAuditAccessAceEx(
2477 IN OUT PACL pAcl,
2478 IN DWORD dwAceRevision,
2479 IN DWORD dwAceFlags,
2480 IN DWORD dwAccessMask,
2481 IN PSID pSid,
2482 IN BOOL bAuditSuccess,
2483 IN BOOL bAuditFailure)
2485 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2486 bAuditSuccess, bAuditFailure) );
2489 /******************************************************************************
2490 * LookupAccountNameA [ADVAPI32.@]
2492 BOOL WINAPI
2493 LookupAccountNameA(
2494 IN LPCSTR system,
2495 IN LPCSTR account,
2496 OUT PSID sid,
2497 OUT LPDWORD cbSid,
2498 LPSTR ReferencedDomainName,
2499 IN OUT LPDWORD cbReferencedDomainName,
2500 OUT PSID_NAME_USE name_use )
2502 BOOL ret;
2503 UNICODE_STRING lpSystemW;
2504 UNICODE_STRING lpAccountW;
2505 LPWSTR lpReferencedDomainNameW = NULL;
2507 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2508 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2510 if (ReferencedDomainName)
2511 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2513 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2514 cbReferencedDomainName, name_use);
2516 if (ret && lpReferencedDomainNameW)
2518 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2519 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2522 RtlFreeUnicodeString(&lpSystemW);
2523 RtlFreeUnicodeString(&lpAccountW);
2524 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2526 return ret;
2529 /******************************************************************************
2530 * LookupAccountNameW [ADVAPI32.@]
2532 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2533 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2534 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2536 /* Default implementation: Always return a default SID */
2537 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2538 BOOL ret;
2539 PSID pSid;
2540 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2541 unsigned int i;
2542 DWORD nameLen;
2543 LPWSTR userName = NULL;
2544 LPCWSTR domainName;
2546 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2547 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2549 if (!ADVAPI_IsLocalComputer(lpSystemName))
2551 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2552 return FALSE;
2555 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2557 lpAccountName = BUILTIN;
2560 /* Check well known SIDs first */
2562 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2564 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2566 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2568 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2570 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2572 if (ret)
2574 if (*cbSid < sidLen)
2576 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2577 ret = FALSE;
2579 else if (Sid)
2581 CopySid(*cbSid, Sid, pSid);
2584 *cbSid = sidLen;
2587 domainName = ACCOUNT_SIDS[i].domain;
2588 nameLen = strlenW(domainName);
2590 if (*cchReferencedDomainName <= nameLen || !ret)
2592 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2593 nameLen += 1;
2594 ret = FALSE;
2596 else if (ReferencedDomainName && domainName)
2598 strcpyW(ReferencedDomainName, domainName);
2601 *cchReferencedDomainName = nameLen;
2603 if (ret)
2605 *peUse = ACCOUNT_SIDS[i].name_use;
2608 HeapFree(GetProcessHeap(), 0, pSid);
2610 return ret;
2614 /* Let the current Unix user id masquerade as first Windows user account */
2616 nameLen = UNLEN + 1;
2618 userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2620 ret = GetUserNameW(userName, &nameLen);
2622 if (ret && strcmpW(lpAccountName, userName) != 0)
2624 SetLastError(ERROR_NONE_MAPPED);
2625 ret = FALSE;
2628 HeapFree(GetProcessHeap(), 0, userName);
2630 if (!ret)
2632 return ret;
2635 ret = AllocateAndInitializeSid(&identifierAuthority,
2637 SECURITY_BUILTIN_DOMAIN_RID,
2638 DOMAIN_ALIAS_RID_ADMINS,
2639 0, 0, 0, 0, 0, 0,
2640 &pSid);
2642 if (!ret)
2643 return FALSE;
2645 if (!RtlValidSid(pSid))
2647 FreeSid(pSid);
2648 return FALSE;
2651 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2652 CopySid(*cbSid, Sid, pSid);
2653 if (*cbSid < GetLengthSid(pSid))
2655 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2656 ret = FALSE;
2658 *cbSid = GetLengthSid(pSid);
2660 domainName = dm;
2661 nameLen = strlenW(domainName);
2663 if (*cchReferencedDomainName <= nameLen || !ret)
2665 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2666 nameLen += 1;
2667 ret = FALSE;
2669 else if (ReferencedDomainName)
2671 strcpyW(ReferencedDomainName, domainName);
2674 *cchReferencedDomainName = nameLen;
2676 if (ret)
2678 *peUse = SidTypeUser;
2681 FreeSid(pSid);
2683 return ret;
2686 /******************************************************************************
2687 * PrivilegeCheck [ADVAPI32.@]
2689 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2691 BOOL ret;
2692 BOOLEAN Result;
2694 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2696 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2697 if (ret)
2698 *pfResult = Result;
2699 return ret;
2702 /******************************************************************************
2703 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2705 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2706 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2707 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2708 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2710 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2711 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2712 SecurityDescriptor, DesiredAccess, GenericMapping,
2713 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2714 return TRUE;
2717 /******************************************************************************
2718 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2720 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2721 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2722 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2723 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2725 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2726 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2727 SecurityDescriptor, DesiredAccess, GenericMapping,
2728 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2729 return TRUE;
2732 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2734 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2736 return TRUE;
2739 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2741 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2743 return TRUE;
2746 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2748 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2750 return TRUE;
2753 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2754 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2755 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2756 LPBOOL GenerateOnClose)
2758 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2759 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2760 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2761 GenerateOnClose);
2763 return TRUE;
2766 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2767 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2768 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2769 LPBOOL GenerateOnClose)
2771 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2772 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2773 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2774 GenerateOnClose);
2776 return TRUE;
2779 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2780 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2782 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2783 DesiredAccess, Privileges, AccessGranted);
2785 return TRUE;
2788 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2789 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2791 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2792 DesiredAccess, Privileges, AccessGranted);
2794 return TRUE;
2797 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2798 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2800 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2801 ClientToken, Privileges, AccessGranted);
2803 return TRUE;
2806 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2807 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2809 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2810 ClientToken, Privileges, AccessGranted);
2812 return TRUE;
2815 /******************************************************************************
2816 * GetSecurityInfo [ADVAPI32.@]
2818 * Retrieves a copy of the security descriptor associated with an object.
2820 * PARAMS
2821 * hObject [I] A handle for the object.
2822 * ObjectType [I] The type of object.
2823 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2824 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2825 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2826 * ppDacl [O] If non-null, receives a pointer to the DACL.
2827 * ppSacl [O] If non-null, receives a pointer to the SACL.
2828 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2829 * which must be freed with LocalFree.
2831 * RETURNS
2832 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2834 DWORD WINAPI GetSecurityInfo(
2835 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2836 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2837 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2838 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2841 PSECURITY_DESCRIPTOR sd;
2842 NTSTATUS status;
2843 ULONG n1, n2;
2844 BOOL present, defaulted;
2846 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2847 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2848 return RtlNtStatusToDosError(status);
2850 sd = LocalAlloc(0, n1);
2851 if (!sd)
2852 return ERROR_NOT_ENOUGH_MEMORY;
2854 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2855 if (status != STATUS_SUCCESS)
2857 LocalFree(sd);
2858 return RtlNtStatusToDosError(status);
2861 if (ppsidOwner)
2863 *ppsidOwner = NULL;
2864 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2866 if (ppsidGroup)
2868 *ppsidGroup = NULL;
2869 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2871 if (ppDacl)
2873 *ppDacl = NULL;
2874 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2876 if (ppSacl)
2878 *ppSacl = NULL;
2879 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2881 if (ppSecurityDescriptor)
2882 *ppSecurityDescriptor = sd;
2884 return ERROR_SUCCESS;
2887 /******************************************************************************
2888 * GetSecurityInfoExW [ADVAPI32.@]
2890 DWORD WINAPI GetSecurityInfoExW(
2891 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2892 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2893 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2894 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2897 FIXME("stub!\n");
2898 return ERROR_BAD_PROVIDER;
2901 /******************************************************************************
2902 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2904 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2905 LPSTR pTrusteeName, DWORD AccessPermissions,
2906 ACCESS_MODE AccessMode, DWORD Inheritance )
2908 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2909 AccessPermissions, AccessMode, Inheritance);
2911 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2912 pExplicitAccess->grfAccessMode = AccessMode;
2913 pExplicitAccess->grfInheritance = Inheritance;
2915 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2916 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2917 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2918 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2919 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2922 /******************************************************************************
2923 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2925 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2926 LPWSTR pTrusteeName, DWORD AccessPermissions,
2927 ACCESS_MODE AccessMode, DWORD Inheritance )
2929 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2930 AccessPermissions, AccessMode, Inheritance);
2932 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2933 pExplicitAccess->grfAccessMode = AccessMode;
2934 pExplicitAccess->grfInheritance = Inheritance;
2936 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2937 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2938 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2939 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2940 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2943 /******************************************************************************
2944 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2946 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2947 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2948 LPSTR InheritedObjectTypeName, LPSTR Name )
2950 DWORD ObjectsPresent = 0;
2952 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2953 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2955 /* Fill the OBJECTS_AND_NAME structure */
2956 pObjName->ObjectType = ObjectType;
2957 if (ObjectTypeName != NULL)
2959 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2962 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2963 if (InheritedObjectTypeName != NULL)
2965 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2968 pObjName->ObjectsPresent = ObjectsPresent;
2969 pObjName->ptstrName = Name;
2971 /* Fill the TRUSTEE structure */
2972 pTrustee->pMultipleTrustee = NULL;
2973 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2974 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2975 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2976 pTrustee->ptstrName = (LPSTR)pObjName;
2979 /******************************************************************************
2980 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2982 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2983 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2984 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2986 DWORD ObjectsPresent = 0;
2988 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2989 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2991 /* Fill the OBJECTS_AND_NAME structure */
2992 pObjName->ObjectType = ObjectType;
2993 if (ObjectTypeName != NULL)
2995 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2998 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2999 if (InheritedObjectTypeName != NULL)
3001 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3004 pObjName->ObjectsPresent = ObjectsPresent;
3005 pObjName->ptstrName = Name;
3007 /* Fill the TRUSTEE structure */
3008 pTrustee->pMultipleTrustee = NULL;
3009 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3010 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3011 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3012 pTrustee->ptstrName = (LPWSTR)pObjName;
3015 /******************************************************************************
3016 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3018 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3019 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3021 DWORD ObjectsPresent = 0;
3023 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3025 /* Fill the OBJECTS_AND_SID structure */
3026 if (pObjectGuid != NULL)
3028 pObjSid->ObjectTypeGuid = *pObjectGuid;
3029 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3031 else
3033 ZeroMemory(&pObjSid->ObjectTypeGuid,
3034 sizeof(GUID));
3037 if (pInheritedObjectGuid != NULL)
3039 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3040 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3042 else
3044 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3045 sizeof(GUID));
3048 pObjSid->ObjectsPresent = ObjectsPresent;
3049 pObjSid->pSid = pSid;
3051 /* Fill the TRUSTEE structure */
3052 pTrustee->pMultipleTrustee = NULL;
3053 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3054 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3055 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3056 pTrustee->ptstrName = (LPSTR) pObjSid;
3059 /******************************************************************************
3060 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3062 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3063 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3065 DWORD ObjectsPresent = 0;
3067 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3069 /* Fill the OBJECTS_AND_SID structure */
3070 if (pObjectGuid != NULL)
3072 pObjSid->ObjectTypeGuid = *pObjectGuid;
3073 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3075 else
3077 ZeroMemory(&pObjSid->ObjectTypeGuid,
3078 sizeof(GUID));
3081 if (pInheritedObjectGuid != NULL)
3083 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3084 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3086 else
3088 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3089 sizeof(GUID));
3092 pObjSid->ObjectsPresent = ObjectsPresent;
3093 pObjSid->pSid = pSid;
3095 /* Fill the TRUSTEE structure */
3096 pTrustee->pMultipleTrustee = NULL;
3097 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3098 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3099 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3100 pTrustee->ptstrName = (LPWSTR) pObjSid;
3103 /******************************************************************************
3104 * BuildTrusteeWithSidA [ADVAPI32.@]
3106 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3108 TRACE("%p %p\n", pTrustee, pSid);
3110 pTrustee->pMultipleTrustee = NULL;
3111 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3112 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3113 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3114 pTrustee->ptstrName = (LPSTR) pSid;
3117 /******************************************************************************
3118 * BuildTrusteeWithSidW [ADVAPI32.@]
3120 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3122 TRACE("%p %p\n", pTrustee, pSid);
3124 pTrustee->pMultipleTrustee = NULL;
3125 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3126 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3127 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3128 pTrustee->ptstrName = (LPWSTR) pSid;
3131 /******************************************************************************
3132 * BuildTrusteeWithNameA [ADVAPI32.@]
3134 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3136 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3138 pTrustee->pMultipleTrustee = NULL;
3139 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3140 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3141 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3142 pTrustee->ptstrName = name;
3145 /******************************************************************************
3146 * BuildTrusteeWithNameW [ADVAPI32.@]
3148 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3150 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3152 pTrustee->pMultipleTrustee = NULL;
3153 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3154 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3155 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3156 pTrustee->ptstrName = name;
3159 /******************************************************************************
3160 * GetTrusteeFormA [ADVAPI32.@]
3162 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3164 TRACE("(%p)\n", pTrustee);
3166 if (!pTrustee)
3167 return TRUSTEE_BAD_FORM;
3169 return pTrustee->TrusteeForm;
3172 /******************************************************************************
3173 * GetTrusteeFormW [ADVAPI32.@]
3175 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3177 TRACE("(%p)\n", pTrustee);
3179 if (!pTrustee)
3180 return TRUSTEE_BAD_FORM;
3182 return pTrustee->TrusteeForm;
3185 /******************************************************************************
3186 * GetTrusteeNameA [ADVAPI32.@]
3188 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3190 TRACE("(%p)\n", pTrustee);
3192 if (!pTrustee)
3193 return NULL;
3195 return pTrustee->ptstrName;
3198 /******************************************************************************
3199 * GetTrusteeNameW [ADVAPI32.@]
3201 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3203 TRACE("(%p)\n", pTrustee);
3205 if (!pTrustee)
3206 return NULL;
3208 return pTrustee->ptstrName;
3211 /******************************************************************************
3212 * GetTrusteeTypeA [ADVAPI32.@]
3214 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3216 TRACE("(%p)\n", pTrustee);
3218 if (!pTrustee)
3219 return TRUSTEE_IS_UNKNOWN;
3221 return pTrustee->TrusteeType;
3224 /******************************************************************************
3225 * GetTrusteeTypeW [ADVAPI32.@]
3227 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3229 TRACE("(%p)\n", pTrustee);
3231 if (!pTrustee)
3232 return TRUSTEE_IS_UNKNOWN;
3234 return pTrustee->TrusteeType;
3237 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3238 DWORD nAclInformationLength,
3239 ACL_INFORMATION_CLASS dwAclInformationClass )
3241 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3242 nAclInformationLength, dwAclInformationClass);
3244 return TRUE;
3247 /******************************************************************************
3248 * SetEntriesInAclA [ADVAPI32.@]
3250 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3251 PACL OldAcl, PACL* NewAcl )
3253 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3254 if (NewAcl)
3255 *NewAcl = NULL;
3256 return ERROR_SUCCESS;
3259 /******************************************************************************
3260 * SetEntriesInAclW [ADVAPI32.@]
3262 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3263 PACL OldAcl, PACL* NewAcl )
3265 ULONG i;
3266 PSID *ppsid;
3267 DWORD ret = ERROR_SUCCESS;
3268 DWORD acl_size = sizeof(ACL);
3269 NTSTATUS status;
3271 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3273 *NewAcl = NULL;
3275 if (!count && !OldAcl)
3276 return ERROR_SUCCESS;
3278 /* allocate array of maximum sized sids allowed */
3279 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3280 if (!ppsid)
3281 return ERROR_OUTOFMEMORY;
3283 for (i = 0; i < count; i++)
3285 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3287 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3288 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3289 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3290 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3291 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3292 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3293 pEntries[i].Trustee.ptstrName);
3295 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3297 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3298 ret = ERROR_INVALID_PARAMETER;
3299 goto exit;
3302 switch (pEntries[i].Trustee.TrusteeForm)
3304 case TRUSTEE_IS_SID:
3305 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3306 ppsid[i], pEntries[i].Trustee.ptstrName))
3308 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3309 ret = ERROR_INVALID_PARAMETER;
3310 goto exit;
3312 break;
3313 case TRUSTEE_IS_NAME:
3315 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3316 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3317 SID_NAME_USE use;
3318 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3320 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3321 ret = ERROR_INVALID_PARAMETER;
3322 goto exit;
3324 break;
3326 case TRUSTEE_IS_OBJECTS_AND_SID:
3327 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3328 break;
3329 case TRUSTEE_IS_OBJECTS_AND_NAME:
3330 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3331 break;
3332 default:
3333 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3334 ret = ERROR_INVALID_PARAMETER;
3335 goto exit;
3338 /* Note: we overestimate the ACL size here as a tradeoff between
3339 * instructions (simplicity) and memory */
3340 switch (pEntries[i].grfAccessMode)
3342 case GRANT_ACCESS:
3343 case SET_ACCESS:
3344 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3345 break;
3346 case DENY_ACCESS:
3347 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3348 break;
3349 case SET_AUDIT_SUCCESS:
3350 case SET_AUDIT_FAILURE:
3351 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3352 break;
3353 case REVOKE_ACCESS:
3354 break;
3355 default:
3356 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3357 ret = ERROR_INVALID_PARAMETER;
3358 goto exit;
3362 if (OldAcl)
3364 ACL_SIZE_INFORMATION size_info;
3366 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3367 if (status != STATUS_SUCCESS)
3369 ret = RtlNtStatusToDosError(status);
3370 goto exit;
3372 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3375 *NewAcl = LocalAlloc(0, acl_size);
3376 if (!*NewAcl)
3378 ret = ERROR_OUTOFMEMORY;
3379 goto exit;
3382 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3383 if (status != STATUS_SUCCESS)
3385 ret = RtlNtStatusToDosError(status);
3386 goto exit;
3389 for (i = 0; i < count; i++)
3391 switch (pEntries[i].grfAccessMode)
3393 case GRANT_ACCESS:
3394 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3395 pEntries[i].grfInheritance,
3396 pEntries[i].grfAccessPermissions,
3397 ppsid[i]);
3398 break;
3399 case SET_ACCESS:
3401 ULONG j;
3402 BOOL add = TRUE;
3403 if (OldAcl)
3405 for (j = 0; ; j++)
3407 const ACE_HEADER *existing_ace_header;
3408 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3409 if (status != STATUS_SUCCESS)
3410 break;
3411 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3412 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3413 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3415 add = FALSE;
3416 break;
3420 if (add)
3421 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3422 pEntries[i].grfInheritance,
3423 pEntries[i].grfAccessPermissions,
3424 ppsid[i]);
3425 break;
3427 case DENY_ACCESS:
3428 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3429 pEntries[i].grfInheritance,
3430 pEntries[i].grfAccessPermissions,
3431 ppsid[i]);
3432 break;
3433 case SET_AUDIT_SUCCESS:
3434 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3435 pEntries[i].grfInheritance,
3436 pEntries[i].grfAccessPermissions,
3437 ppsid[i], TRUE, FALSE);
3438 break;
3439 case SET_AUDIT_FAILURE:
3440 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3441 pEntries[i].grfInheritance,
3442 pEntries[i].grfAccessPermissions,
3443 ppsid[i], FALSE, TRUE);
3444 break;
3445 default:
3446 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3450 if (OldAcl)
3452 for (i = 0; ; i++)
3454 BOOL add = TRUE;
3455 ULONG j;
3456 const ACE_HEADER *old_ace_header;
3457 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3458 if (status != STATUS_SUCCESS) break;
3459 for (j = 0; j < count; j++)
3461 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3462 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3463 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3465 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3466 add = FALSE;
3467 break;
3469 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3471 switch (old_ace_header->AceType)
3473 case ACCESS_ALLOWED_ACE_TYPE:
3474 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3475 add = FALSE;
3476 break;
3477 case ACCESS_DENIED_ACE_TYPE:
3478 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3479 add = FALSE;
3480 break;
3481 case SYSTEM_AUDIT_ACE_TYPE:
3482 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3483 add = FALSE;
3484 break;
3485 case SYSTEM_ALARM_ACE_TYPE:
3486 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3487 add = FALSE;
3488 break;
3489 default:
3490 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3493 if (!add)
3494 break;
3497 if (add)
3498 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3499 if (status != STATUS_SUCCESS)
3501 WARN("RtlAddAce failed with error 0x%08x\n", status);
3502 ret = RtlNtStatusToDosError(status);
3503 break;
3508 exit:
3509 HeapFree(GetProcessHeap(), 0, ppsid);
3510 return ret;
3513 /******************************************************************************
3514 * SetNamedSecurityInfoA [ADVAPI32.@]
3516 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3517 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3518 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3520 DWORD len;
3521 LPWSTR wstr = NULL;
3522 DWORD r;
3524 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3525 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3527 if( pObjectName )
3529 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3530 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3531 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3534 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3535 psidGroup, pDacl, pSacl );
3537 HeapFree( GetProcessHeap(), 0, wstr );
3539 return r;
3542 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3543 PSECURITY_DESCRIPTOR ModificationDescriptor,
3544 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3545 PGENERIC_MAPPING GenericMapping,
3546 HANDLE Token )
3548 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3549 ObjectsSecurityDescriptor, GenericMapping, Token);
3551 return TRUE;
3554 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3556 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3559 /******************************************************************************
3560 * AreAnyAccessesGranted [ADVAPI32.@]
3562 * Determines whether or not any of a set of specified access permissions have
3563 * been granted or not.
3565 * PARAMS
3566 * GrantedAccess [I] The permissions that have been granted.
3567 * DesiredAccess [I] The permissions that you want to have.
3569 * RETURNS
3570 * Nonzero if any of the permissions have been granted, zero if none of the
3571 * permissions have been granted.
3574 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3576 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3579 /******************************************************************************
3580 * SetNamedSecurityInfoW [ADVAPI32.@]
3582 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3583 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3584 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3586 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3587 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3588 return ERROR_SUCCESS;
3591 /******************************************************************************
3592 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3594 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3595 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3597 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3598 return ERROR_CALL_NOT_IMPLEMENTED;
3601 /******************************************************************************
3602 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3604 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3605 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3607 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3608 return ERROR_CALL_NOT_IMPLEMENTED;
3611 /******************************************************************************
3612 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3614 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3615 PACCESS_MASK pFailedAuditRights)
3617 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3618 return ERROR_CALL_NOT_IMPLEMENTED;
3622 /******************************************************************************
3623 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3625 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3626 PACCESS_MASK pFailedAuditRights)
3628 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3629 return ERROR_CALL_NOT_IMPLEMENTED;
3633 /******************************************************************************
3634 * ParseAclStringFlags
3636 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3638 DWORD flags = 0;
3639 LPCWSTR szAcl = *StringAcl;
3641 while (*szAcl != '(')
3643 if (*szAcl == 'P')
3645 flags |= SE_DACL_PROTECTED;
3647 else if (*szAcl == 'A')
3649 szAcl++;
3650 if (*szAcl == 'R')
3651 flags |= SE_DACL_AUTO_INHERIT_REQ;
3652 else if (*szAcl == 'I')
3653 flags |= SE_DACL_AUTO_INHERITED;
3655 szAcl++;
3658 *StringAcl = szAcl;
3659 return flags;
3662 /******************************************************************************
3663 * ParseAceStringType
3665 static const ACEFLAG AceType[] =
3667 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3668 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3669 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3670 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3672 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3673 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3674 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3675 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3677 { NULL, 0 },
3680 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3682 UINT len = 0;
3683 LPCWSTR szAcl = *StringAcl;
3684 const ACEFLAG *lpaf = AceType;
3686 while (lpaf->wstr &&
3687 (len = strlenW(lpaf->wstr)) &&
3688 strncmpW(lpaf->wstr, szAcl, len))
3689 lpaf++;
3691 if (!lpaf->wstr)
3692 return 0;
3694 *StringAcl += len;
3695 return lpaf->value;
3699 /******************************************************************************
3700 * ParseAceStringFlags
3702 static const ACEFLAG AceFlags[] =
3704 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3705 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3706 { SDDL_INHERITED, INHERITED_ACE },
3707 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3708 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3709 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3710 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3711 { NULL, 0 },
3714 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3716 UINT len = 0;
3717 BYTE flags = 0;
3718 LPCWSTR szAcl = *StringAcl;
3720 while (*szAcl != ';')
3722 const ACEFLAG *lpaf = AceFlags;
3724 while (lpaf->wstr &&
3725 (len = strlenW(lpaf->wstr)) &&
3726 strncmpW(lpaf->wstr, szAcl, len))
3727 lpaf++;
3729 if (!lpaf->wstr)
3730 return 0;
3732 flags |= lpaf->value;
3733 szAcl += len;
3736 *StringAcl = szAcl;
3737 return flags;
3741 /******************************************************************************
3742 * ParseAceStringRights
3744 static const ACEFLAG AceRights[] =
3746 { SDDL_GENERIC_ALL, GENERIC_ALL },
3747 { SDDL_GENERIC_READ, GENERIC_READ },
3748 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3749 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3751 { SDDL_READ_CONTROL, READ_CONTROL },
3752 { SDDL_STANDARD_DELETE, DELETE },
3753 { SDDL_WRITE_DAC, WRITE_DAC },
3754 { SDDL_WRITE_OWNER, WRITE_OWNER },
3756 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3757 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3758 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3759 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3760 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3761 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3762 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3763 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3764 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3766 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3767 { SDDL_FILE_READ, FILE_GENERIC_READ },
3768 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3769 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3771 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3772 { SDDL_KEY_READ, KEY_READ },
3773 { SDDL_KEY_WRITE, KEY_WRITE },
3774 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3775 { NULL, 0 },
3778 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3780 UINT len = 0;
3781 DWORD rights = 0;
3782 LPCWSTR szAcl = *StringAcl;
3784 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3786 LPCWSTR p = szAcl;
3788 while (*p && *p != ';')
3789 p++;
3791 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3793 rights = strtoulW(szAcl, NULL, 16);
3794 szAcl = p;
3796 else
3797 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3799 else
3801 while (*szAcl != ';')
3803 const ACEFLAG *lpaf = AceRights;
3805 while (lpaf->wstr &&
3806 (len = strlenW(lpaf->wstr)) &&
3807 strncmpW(lpaf->wstr, szAcl, len))
3809 lpaf++;
3812 if (!lpaf->wstr)
3813 return 0;
3815 rights |= lpaf->value;
3816 szAcl += len;
3820 *StringAcl = szAcl;
3821 return rights;
3825 /******************************************************************************
3826 * ParseStringAclToAcl
3828 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3830 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3831 PACL pAcl, LPDWORD cBytes)
3833 DWORD val;
3834 DWORD sidlen;
3835 DWORD length = sizeof(ACL);
3836 DWORD acesize = 0;
3837 DWORD acecount = 0;
3838 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3840 TRACE("%s\n", debugstr_w(StringAcl));
3842 if (!StringAcl)
3843 return FALSE;
3845 if (pAcl) /* pAce is only useful if we're setting values */
3846 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3848 /* Parse ACL flags */
3849 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3851 /* Parse ACE */
3852 while (*StringAcl == '(')
3854 StringAcl++;
3856 /* Parse ACE type */
3857 val = ParseAceStringType(&StringAcl);
3858 if (pAce)
3859 pAce->Header.AceType = (BYTE) val;
3860 if (*StringAcl != ';')
3861 goto lerr;
3862 StringAcl++;
3864 /* Parse ACE flags */
3865 val = ParseAceStringFlags(&StringAcl);
3866 if (pAce)
3867 pAce->Header.AceFlags = (BYTE) val;
3868 if (*StringAcl != ';')
3869 goto lerr;
3870 StringAcl++;
3872 /* Parse ACE rights */
3873 val = ParseAceStringRights(&StringAcl);
3874 if (pAce)
3875 pAce->Mask = val;
3876 if (*StringAcl != ';')
3877 goto lerr;
3878 StringAcl++;
3880 /* Parse ACE object guid */
3881 if (*StringAcl != ';')
3883 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3884 goto lerr;
3886 StringAcl++;
3888 /* Parse ACE inherit object guid */
3889 if (*StringAcl != ';')
3891 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3892 goto lerr;
3894 StringAcl++;
3896 /* Parse ACE account sid */
3897 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3899 while (*StringAcl && *StringAcl != ')')
3900 StringAcl++;
3903 if (*StringAcl != ')')
3904 goto lerr;
3905 StringAcl++;
3907 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3908 length += acesize;
3909 if (pAce)
3911 pAce->Header.AceSize = acesize;
3912 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3914 acecount++;
3917 *cBytes = length;
3919 if (length > 0xffff)
3921 ERR("ACL too large\n");
3922 goto lerr;
3925 if (pAcl)
3927 pAcl->AclRevision = ACL_REVISION;
3928 pAcl->Sbz1 = 0;
3929 pAcl->AclSize = length;
3930 pAcl->AceCount = acecount++;
3931 pAcl->Sbz2 = 0;
3933 return TRUE;
3935 lerr:
3936 SetLastError(ERROR_INVALID_ACL);
3937 WARN("Invalid ACE string format\n");
3938 return FALSE;
3942 /******************************************************************************
3943 * ParseStringSecurityDescriptorToSecurityDescriptor
3945 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3946 LPCWSTR StringSecurityDescriptor,
3947 SECURITY_DESCRIPTOR* SecurityDescriptor,
3948 LPDWORD cBytes)
3950 BOOL bret = FALSE;
3951 WCHAR toktype;
3952 WCHAR tok[MAX_PATH];
3953 LPCWSTR lptoken;
3954 LPBYTE lpNext = NULL;
3955 DWORD len;
3957 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3959 if (SecurityDescriptor)
3960 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3962 while (*StringSecurityDescriptor)
3964 toktype = *StringSecurityDescriptor;
3966 /* Expect char identifier followed by ':' */
3967 StringSecurityDescriptor++;
3968 if (*StringSecurityDescriptor != ':')
3970 SetLastError(ERROR_INVALID_PARAMETER);
3971 goto lend;
3973 StringSecurityDescriptor++;
3975 /* Extract token */
3976 lptoken = StringSecurityDescriptor;
3977 while (*lptoken && *lptoken != ':')
3978 lptoken++;
3980 if (*lptoken)
3981 lptoken--;
3983 len = lptoken - StringSecurityDescriptor;
3984 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3985 tok[len] = 0;
3987 switch (toktype)
3989 case 'O':
3991 DWORD bytes;
3993 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3994 goto lend;
3996 if (SecurityDescriptor)
3998 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3999 lpNext += bytes; /* Advance to next token */
4002 *cBytes += bytes;
4004 break;
4007 case 'G':
4009 DWORD bytes;
4011 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4012 goto lend;
4014 if (SecurityDescriptor)
4016 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4017 lpNext += bytes; /* Advance to next token */
4020 *cBytes += bytes;
4022 break;
4025 case 'D':
4027 DWORD flags;
4028 DWORD bytes;
4030 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4031 goto lend;
4033 if (SecurityDescriptor)
4035 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4036 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4037 lpNext += bytes; /* Advance to next token */
4040 *cBytes += bytes;
4042 break;
4045 case 'S':
4047 DWORD flags;
4048 DWORD bytes;
4050 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4051 goto lend;
4053 if (SecurityDescriptor)
4055 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4056 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4057 lpNext += bytes; /* Advance to next token */
4060 *cBytes += bytes;
4062 break;
4065 default:
4066 FIXME("Unknown token\n");
4067 SetLastError(ERROR_INVALID_PARAMETER);
4068 goto lend;
4071 StringSecurityDescriptor = lptoken;
4074 bret = TRUE;
4076 lend:
4077 return bret;
4080 /******************************************************************************
4081 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4083 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4084 LPCSTR StringSecurityDescriptor,
4085 DWORD StringSDRevision,
4086 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4087 PULONG SecurityDescriptorSize)
4089 UINT len;
4090 BOOL ret = FALSE;
4091 LPWSTR StringSecurityDescriptorW;
4093 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4094 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4096 if (StringSecurityDescriptorW)
4098 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4100 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4101 StringSDRevision, SecurityDescriptor,
4102 SecurityDescriptorSize);
4103 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4106 return ret;
4109 /******************************************************************************
4110 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4112 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4113 LPCWSTR StringSecurityDescriptor,
4114 DWORD StringSDRevision,
4115 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4116 PULONG SecurityDescriptorSize)
4118 DWORD cBytes;
4119 SECURITY_DESCRIPTOR* psd;
4120 BOOL bret = FALSE;
4122 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4124 if (GetVersion() & 0x80000000)
4126 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4127 goto lend;
4129 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4131 SetLastError(ERROR_INVALID_PARAMETER);
4132 goto lend;
4134 else if (StringSDRevision != SID_REVISION)
4136 SetLastError(ERROR_UNKNOWN_REVISION);
4137 goto lend;
4140 /* Compute security descriptor length */
4141 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4142 NULL, &cBytes))
4143 goto lend;
4145 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4146 GMEM_ZEROINIT, cBytes);
4147 if (!psd) goto lend;
4149 psd->Revision = SID_REVISION;
4150 psd->Control |= SE_SELF_RELATIVE;
4152 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4153 psd, &cBytes))
4155 LocalFree(psd);
4156 goto lend;
4159 if (SecurityDescriptorSize)
4160 *SecurityDescriptorSize = cBytes;
4162 bret = TRUE;
4164 lend:
4165 TRACE(" ret=%d\n", bret);
4166 return bret;
4169 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4171 if (cch == -1)
4172 cch = strlenW(string);
4174 if (plen)
4175 *plen += cch;
4177 if (pwptr)
4179 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4180 *pwptr += cch;
4184 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4186 DWORD i;
4187 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4188 WCHAR subauthfmt[] = { '-','%','u',0 };
4189 WCHAR buf[26];
4190 SID *pisid = psid;
4192 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4194 SetLastError(ERROR_INVALID_SID);
4195 return FALSE;
4198 if (pisid->IdentifierAuthority.Value[0] ||
4199 pisid->IdentifierAuthority.Value[1])
4201 FIXME("not matching MS' bugs\n");
4202 SetLastError(ERROR_INVALID_SID);
4203 return FALSE;
4206 sprintfW( buf, fmt, pisid->Revision,
4207 MAKELONG(
4208 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4209 pisid->IdentifierAuthority.Value[4] ),
4210 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4211 pisid->IdentifierAuthority.Value[2] )
4212 ) );
4213 DumpString(buf, -1, pwptr, plen);
4215 for( i=0; i<pisid->SubAuthorityCount; i++ )
4217 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4218 DumpString(buf, -1, pwptr, plen);
4220 return TRUE;
4223 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4225 size_t i;
4226 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4228 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4230 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4231 return TRUE;
4235 return DumpSidNumeric(psid, pwptr, plen);
4238 static const LPCWSTR AceRightBitNames[32] = {
4239 SDDL_CREATE_CHILD, /* 0 */
4240 SDDL_DELETE_CHILD,
4241 SDDL_LIST_CHILDREN,
4242 SDDL_SELF_WRITE,
4243 SDDL_READ_PROPERTY, /* 4 */
4244 SDDL_WRITE_PROPERTY,
4245 SDDL_DELETE_TREE,
4246 SDDL_LIST_OBJECT,
4247 SDDL_CONTROL_ACCESS, /* 8 */
4248 NULL,
4249 NULL,
4250 NULL,
4251 NULL, /* 12 */
4252 NULL,
4253 NULL,
4254 NULL,
4255 SDDL_STANDARD_DELETE, /* 16 */
4256 SDDL_READ_CONTROL,
4257 SDDL_WRITE_DAC,
4258 SDDL_WRITE_OWNER,
4259 NULL, /* 20 */
4260 NULL,
4261 NULL,
4262 NULL,
4263 NULL, /* 24 */
4264 NULL,
4265 NULL,
4266 NULL,
4267 SDDL_GENERIC_ALL, /* 28 */
4268 SDDL_GENERIC_EXECUTE,
4269 SDDL_GENERIC_WRITE,
4270 SDDL_GENERIC_READ
4273 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4275 static const WCHAR fmtW[] = {'0','x','%','x',0};
4276 WCHAR buf[15];
4277 size_t i;
4279 if (mask == 0)
4280 return;
4282 /* first check if the right have name */
4283 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4285 if (AceRights[i].wstr == NULL)
4286 break;
4287 if (mask == AceRights[i].value)
4289 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4290 return;
4294 /* then check if it can be built from bit names */
4295 for (i = 0; i < 32; i++)
4297 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4299 /* can't be built from bit names */
4300 sprintfW(buf, fmtW, mask);
4301 DumpString(buf, -1, pwptr, plen);
4302 return;
4306 /* build from bit names */
4307 for (i = 0; i < 32; i++)
4308 if (mask & (1 << i))
4309 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4312 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4314 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4315 static const WCHAR openbr = '(';
4316 static const WCHAR closebr = ')';
4317 static const WCHAR semicolon = ';';
4319 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4321 SetLastError(ERROR_INVALID_ACL);
4322 return FALSE;
4325 piace = (ACCESS_ALLOWED_ACE *)pace;
4326 DumpString(&openbr, 1, pwptr, plen);
4327 switch (piace->Header.AceType)
4329 case ACCESS_ALLOWED_ACE_TYPE:
4330 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4331 break;
4332 case ACCESS_DENIED_ACE_TYPE:
4333 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4334 break;
4335 case SYSTEM_AUDIT_ACE_TYPE:
4336 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4337 break;
4338 case SYSTEM_ALARM_ACE_TYPE:
4339 DumpString(SDDL_ALARM, -1, pwptr, plen);
4340 break;
4342 DumpString(&semicolon, 1, pwptr, plen);
4344 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4345 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4346 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4347 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4348 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4349 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4350 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4351 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4352 if (piace->Header.AceFlags & INHERITED_ACE)
4353 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4354 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4355 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4356 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4357 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4358 DumpString(&semicolon, 1, pwptr, plen);
4359 DumpRights(piace->Mask, pwptr, plen);
4360 DumpString(&semicolon, 1, pwptr, plen);
4361 /* objects not supported */
4362 DumpString(&semicolon, 1, pwptr, plen);
4363 /* objects not supported */
4364 DumpString(&semicolon, 1, pwptr, plen);
4365 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4366 return FALSE;
4367 DumpString(&closebr, 1, pwptr, plen);
4368 return TRUE;
4371 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4373 WORD count;
4374 int i;
4376 if (protected)
4377 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4378 if (autoInheritReq)
4379 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4380 if (autoInherited)
4381 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4383 if (pacl == NULL)
4384 return TRUE;
4386 if (!IsValidAcl(pacl))
4387 return FALSE;
4389 count = pacl->AceCount;
4390 for (i = 0; i < count; i++)
4392 LPVOID ace;
4393 if (!GetAce(pacl, i, &ace))
4394 return FALSE;
4395 if (!DumpAce(ace, pwptr, plen))
4396 return FALSE;
4399 return TRUE;
4402 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4404 static const WCHAR prefix[] = {'O',':',0};
4405 BOOL bDefaulted;
4406 PSID psid;
4408 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4409 return FALSE;
4411 if (psid == NULL)
4412 return TRUE;
4414 DumpString(prefix, -1, pwptr, plen);
4415 if (!DumpSid(psid, pwptr, plen))
4416 return FALSE;
4417 return TRUE;
4420 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4422 static const WCHAR prefix[] = {'G',':',0};
4423 BOOL bDefaulted;
4424 PSID psid;
4426 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4427 return FALSE;
4429 if (psid == NULL)
4430 return TRUE;
4432 DumpString(prefix, -1, pwptr, plen);
4433 if (!DumpSid(psid, pwptr, plen))
4434 return FALSE;
4435 return TRUE;
4438 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4440 static const WCHAR dacl[] = {'D',':',0};
4441 SECURITY_DESCRIPTOR_CONTROL control;
4442 BOOL present, defaulted;
4443 DWORD revision;
4444 PACL pacl;
4446 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4447 return FALSE;
4449 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4450 return FALSE;
4452 if (!present)
4453 return TRUE;
4455 DumpString(dacl, 2, pwptr, plen);
4456 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4457 return FALSE;
4458 return TRUE;
4461 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4463 static const WCHAR sacl[] = {'S',':',0};
4464 SECURITY_DESCRIPTOR_CONTROL control;
4465 BOOL present, defaulted;
4466 DWORD revision;
4467 PACL pacl;
4469 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4470 return FALSE;
4472 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4473 return FALSE;
4475 if (!present)
4476 return TRUE;
4478 DumpString(sacl, 2, pwptr, plen);
4479 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4480 return FALSE;
4481 return TRUE;
4484 /******************************************************************************
4485 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4487 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4489 ULONG len;
4490 WCHAR *wptr, *wstr;
4492 if (SDRevision != SDDL_REVISION_1)
4494 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4495 SetLastError(ERROR_UNKNOWN_REVISION);
4496 return FALSE;
4499 len = 0;
4500 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4501 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4502 return FALSE;
4503 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4504 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4505 return FALSE;
4506 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4507 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4508 return FALSE;
4509 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4510 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4511 return FALSE;
4513 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4514 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4515 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4516 return FALSE;
4517 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4518 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4519 return FALSE;
4520 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4521 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4522 return FALSE;
4523 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4524 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4525 return FALSE;
4526 *wptr = 0;
4528 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4529 *OutputString = wstr;
4530 if (OutputLen)
4531 *OutputLen = strlenW(*OutputString)+1;
4532 return TRUE;
4535 /******************************************************************************
4536 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4538 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4540 LPWSTR wstr;
4541 ULONG len;
4542 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4544 int lenA;
4546 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4547 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4548 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4549 LocalFree(wstr);
4551 if (OutputLen != NULL)
4552 *OutputLen = lenA;
4553 return TRUE;
4555 else
4557 *OutputString = NULL;
4558 if (OutputLen)
4559 *OutputLen = 0;
4560 return FALSE;
4564 /******************************************************************************
4565 * ConvertStringSidToSidW [ADVAPI32.@]
4567 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4569 BOOL bret = FALSE;
4570 DWORD cBytes;
4572 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4573 if (GetVersion() & 0x80000000)
4574 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4575 else if (!StringSid || !Sid)
4576 SetLastError(ERROR_INVALID_PARAMETER);
4577 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4579 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4581 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4582 if (!bret)
4583 LocalFree(*Sid);
4585 return bret;
4588 /******************************************************************************
4589 * ConvertStringSidToSidA [ADVAPI32.@]
4591 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4593 BOOL bret = FALSE;
4595 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4596 if (GetVersion() & 0x80000000)
4597 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4598 else if (!StringSid || !Sid)
4599 SetLastError(ERROR_INVALID_PARAMETER);
4600 else
4602 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4603 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4604 len * sizeof(WCHAR));
4606 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4607 bret = ConvertStringSidToSidW(wStringSid, Sid);
4608 HeapFree(GetProcessHeap(), 0, wStringSid);
4610 return bret;
4613 /******************************************************************************
4614 * ConvertSidToStringSidW [ADVAPI32.@]
4616 * format of SID string is:
4617 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4618 * where
4619 * <rev> is the revision of the SID encoded as decimal
4620 * <auth> is the identifier authority encoded as hex
4621 * <subauthN> is the subauthority id encoded as decimal
4623 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4625 DWORD len = 0;
4626 LPWSTR wstr, wptr;
4628 TRACE("%p %p\n", pSid, pstr );
4630 len = 0;
4631 if (!DumpSidNumeric(pSid, NULL, &len))
4632 return FALSE;
4633 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4634 DumpSidNumeric(pSid, &wptr, NULL);
4635 *wptr = 0;
4637 *pstr = wstr;
4638 return TRUE;
4641 /******************************************************************************
4642 * ConvertSidToStringSidA [ADVAPI32.@]
4644 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4646 LPWSTR wstr = NULL;
4647 LPSTR str;
4648 UINT len;
4650 TRACE("%p %p\n", pSid, pstr );
4652 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4653 return FALSE;
4655 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4656 str = LocalAlloc( 0, len );
4657 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4658 LocalFree( wstr );
4660 *pstr = str;
4662 return TRUE;
4665 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4666 PSECURITY_DESCRIPTOR pdesc,
4667 PSECURITY_DESCRIPTOR cdesc,
4668 PSECURITY_DESCRIPTOR* ndesc,
4669 GUID* objtype,
4670 BOOL isdir,
4671 PGENERIC_MAPPING genmap )
4673 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4675 return FALSE;
4678 BOOL WINAPI CreatePrivateObjectSecurity(
4679 PSECURITY_DESCRIPTOR ParentDescriptor,
4680 PSECURITY_DESCRIPTOR CreatorDescriptor,
4681 PSECURITY_DESCRIPTOR* NewDescriptor,
4682 BOOL IsDirectoryObject,
4683 HANDLE Token,
4684 PGENERIC_MAPPING GenericMapping )
4686 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4687 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4689 return FALSE;
4692 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4694 FIXME("%p - stub\n", ObjectDescriptor);
4696 return TRUE;
4699 BOOL WINAPI CreateProcessAsUserA(
4700 HANDLE hToken,
4701 LPCSTR lpApplicationName,
4702 LPSTR lpCommandLine,
4703 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4704 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4705 BOOL bInheritHandles,
4706 DWORD dwCreationFlags,
4707 LPVOID lpEnvironment,
4708 LPCSTR lpCurrentDirectory,
4709 LPSTARTUPINFOA lpStartupInfo,
4710 LPPROCESS_INFORMATION lpProcessInformation )
4712 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4713 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4714 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4716 return FALSE;
4719 BOOL WINAPI CreateProcessAsUserW(
4720 HANDLE hToken,
4721 LPCWSTR lpApplicationName,
4722 LPWSTR lpCommandLine,
4723 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4724 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4725 BOOL bInheritHandles,
4726 DWORD dwCreationFlags,
4727 LPVOID lpEnvironment,
4728 LPCWSTR lpCurrentDirectory,
4729 LPSTARTUPINFOW lpStartupInfo,
4730 LPPROCESS_INFORMATION lpProcessInformation )
4732 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4733 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4734 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4735 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4737 /* We should create the process with a suspended main thread */
4738 if (!CreateProcessW (lpApplicationName,
4739 lpCommandLine,
4740 lpProcessAttributes,
4741 lpThreadAttributes,
4742 bInheritHandles,
4743 dwCreationFlags, /* CREATE_SUSPENDED */
4744 lpEnvironment,
4745 lpCurrentDirectory,
4746 lpStartupInfo,
4747 lpProcessInformation))
4749 return FALSE;
4752 return TRUE;
4755 /******************************************************************************
4756 * CreateProcessWithLogonW
4758 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4759 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4760 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4762 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4763 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4764 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4765 lpStartupInfo, lpProcessInformation);
4767 return FALSE;
4770 /******************************************************************************
4771 * DuplicateTokenEx [ADVAPI32.@]
4773 BOOL WINAPI DuplicateTokenEx(
4774 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4775 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4776 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4777 TOKEN_TYPE TokenType,
4778 PHANDLE DuplicateTokenHandle )
4780 OBJECT_ATTRIBUTES ObjectAttributes;
4782 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4783 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4785 InitializeObjectAttributes(
4786 &ObjectAttributes,
4787 NULL,
4788 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4789 NULL,
4790 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4792 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4793 dwDesiredAccess,
4794 &ObjectAttributes,
4795 ImpersonationLevel,
4796 TokenType,
4797 DuplicateTokenHandle ) );
4800 BOOL WINAPI DuplicateToken(
4801 HANDLE ExistingTokenHandle,
4802 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4803 PHANDLE DuplicateTokenHandle )
4805 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4806 NULL, ImpersonationLevel, TokenImpersonation,
4807 DuplicateTokenHandle );
4810 /******************************************************************************
4811 * ComputeStringSidSize
4813 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4815 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4817 int ctok = 0;
4818 while (*StringSid)
4820 if (*StringSid == '-')
4821 ctok++;
4822 StringSid++;
4825 if (ctok >= 3)
4826 return GetSidLengthRequired(ctok - 2);
4828 else /* String constant format - Only available in winxp and above */
4830 unsigned int i;
4832 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4833 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4834 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4837 return GetSidLengthRequired(0);
4840 /******************************************************************************
4841 * ParseStringSidToSid
4843 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4845 BOOL bret = FALSE;
4846 SID* pisid=pSid;
4848 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4849 if (!StringSid)
4851 SetLastError(ERROR_INVALID_PARAMETER);
4852 TRACE("StringSid is NULL, returning FALSE\n");
4853 return FALSE;
4856 *cBytes = ComputeStringSidSize(StringSid);
4857 if (!pisid) /* Simply compute the size */
4859 TRACE("only size requested, returning TRUE\n");
4860 return TRUE;
4863 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4865 DWORD i = 0, identAuth;
4866 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4868 StringSid += 2; /* Advance to Revision */
4869 pisid->Revision = atoiW(StringSid);
4871 if (pisid->Revision != SDDL_REVISION)
4873 TRACE("Revision %d is unknown\n", pisid->Revision);
4874 goto lend; /* ERROR_INVALID_SID */
4876 if (csubauth == 0)
4878 TRACE("SubAuthorityCount is 0\n");
4879 goto lend; /* ERROR_INVALID_SID */
4882 pisid->SubAuthorityCount = csubauth;
4884 /* Advance to identifier authority */
4885 while (*StringSid && *StringSid != '-')
4886 StringSid++;
4887 if (*StringSid == '-')
4888 StringSid++;
4890 /* MS' implementation can't handle values greater than 2^32 - 1, so
4891 * we don't either; assume most significant bytes are always 0
4893 pisid->IdentifierAuthority.Value[0] = 0;
4894 pisid->IdentifierAuthority.Value[1] = 0;
4895 identAuth = atoiW(StringSid);
4896 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4897 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4898 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4899 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4901 /* Advance to first sub authority */
4902 while (*StringSid && *StringSid != '-')
4903 StringSid++;
4904 if (*StringSid == '-')
4905 StringSid++;
4907 while (*StringSid)
4909 pisid->SubAuthority[i++] = atoiW(StringSid);
4911 while (*StringSid && *StringSid != '-')
4912 StringSid++;
4913 if (*StringSid == '-')
4914 StringSid++;
4917 if (i != pisid->SubAuthorityCount)
4918 goto lend; /* ERROR_INVALID_SID */
4920 bret = TRUE;
4922 else /* String constant format - Only available in winxp and above */
4924 unsigned int i;
4925 pisid->Revision = SDDL_REVISION;
4927 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4928 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4930 DWORD j;
4931 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4932 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4933 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4934 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4935 bret = TRUE;
4938 if (!bret)
4939 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4942 lend:
4943 if (!bret)
4944 SetLastError(ERROR_INVALID_SID);
4946 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4947 return bret;
4950 /******************************************************************************
4951 * GetNamedSecurityInfoA [ADVAPI32.@]
4953 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4954 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4955 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4956 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4958 DWORD len;
4959 LPWSTR wstr = NULL;
4960 DWORD r;
4962 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4963 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4965 if( pObjectName )
4967 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4968 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4969 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4972 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4973 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4975 HeapFree( GetProcessHeap(), 0, wstr );
4977 return r;
4980 /******************************************************************************
4981 * GetNamedSecurityInfoW [ADVAPI32.@]
4983 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4984 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4985 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4987 DWORD needed, offset;
4988 SECURITY_DESCRIPTOR_RELATIVE *relative;
4989 BYTE *buffer;
4991 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4992 group, dacl, sacl, descriptor );
4994 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4996 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4997 if (info & OWNER_SECURITY_INFORMATION)
4998 needed += sizeof(sidWorld);
4999 if (info & GROUP_SECURITY_INFORMATION)
5000 needed += sizeof(sidWorld);
5001 if (info & DACL_SECURITY_INFORMATION)
5002 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5003 if (info & SACL_SECURITY_INFORMATION)
5004 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5006 /* must be freed by caller */
5007 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5008 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5010 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5012 HeapFree( GetProcessHeap(), 0, *descriptor );
5013 return ERROR_INVALID_SECURITY_DESCR;
5016 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
5017 relative->Control |= SE_SELF_RELATIVE;
5018 buffer = (BYTE *)relative;
5019 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5021 if (info & OWNER_SECURITY_INFORMATION)
5023 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5024 relative->Owner = offset;
5025 if (owner)
5026 *owner = buffer + offset;
5027 offset += sizeof(sidWorld);
5029 if (info & GROUP_SECURITY_INFORMATION)
5031 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5032 relative->Group = offset;
5033 if (group)
5034 *group = buffer + offset;
5035 offset += sizeof(sidWorld);
5037 if (info & DACL_SECURITY_INFORMATION)
5039 relative->Control |= SE_DACL_PRESENT;
5040 GetWorldAccessACL( (PACL)(buffer + offset) );
5041 relative->Dacl = offset;
5042 if (dacl)
5043 *dacl = (PACL)(buffer + offset);
5044 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5046 if (info & SACL_SECURITY_INFORMATION)
5048 relative->Control |= SE_SACL_PRESENT;
5049 GetWorldAccessACL( (PACL)(buffer + offset) );
5050 relative->Sacl = offset;
5051 if (sacl)
5052 *sacl = (PACL)(buffer + offset);
5054 return ERROR_SUCCESS;
5057 /******************************************************************************
5058 * DecryptFileW [ADVAPI32.@]
5060 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5062 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5063 return TRUE;
5066 /******************************************************************************
5067 * DecryptFileA [ADVAPI32.@]
5069 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5071 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5072 return TRUE;
5075 /******************************************************************************
5076 * EncryptFileW [ADVAPI32.@]
5078 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5080 FIXME("%s\n", debugstr_w(lpFileName));
5081 return TRUE;
5084 /******************************************************************************
5085 * EncryptFileA [ADVAPI32.@]
5087 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5089 FIXME("%s\n", debugstr_a(lpFileName));
5090 return TRUE;
5093 /******************************************************************************
5094 * FileEncryptionStatusW [ADVAPI32.@]
5096 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5098 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5099 if (!lpStatus)
5100 return FALSE;
5101 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5102 return TRUE;
5105 /******************************************************************************
5106 * FileEncryptionStatusA [ADVAPI32.@]
5108 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5110 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5111 if (!lpStatus)
5112 return FALSE;
5113 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5114 return TRUE;
5117 /******************************************************************************
5118 * SetSecurityInfo [ADVAPI32.@]
5120 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5121 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5122 PSID psidGroup, PACL pDacl, PACL pSacl) {
5123 FIXME("stub\n");
5124 return ERROR_SUCCESS;
5127 /******************************************************************************
5128 * SaferCreateLevel [ADVAPI32.@]
5130 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5131 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5133 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5134 return FALSE;