widl: Make the generated string pointers const as well.
[wine/multimedia.git] / dlls / advapi32 / security.c
blob822937770b3444f1398e95c799a2df67f1baa323
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 "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
41 #include "lmcons.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
49 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
50 PACL pAcl, LPDWORD cBytes);
51 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
52 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
53 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
54 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
55 LPCWSTR StringSecurityDescriptor,
56 SECURITY_DESCRIPTOR* SecurityDescriptor,
57 LPDWORD cBytes);
58 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
60 typedef struct _ACEFLAG
62 LPCWSTR wstr;
63 DWORD value;
64 } ACEFLAG, *LPACEFLAG;
66 typedef struct _MAX_SID
68 /* same fields as struct _SID */
69 BYTE Revision;
70 BYTE SubAuthorityCount;
71 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
72 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
73 } MAX_SID;
75 typedef struct WELLKNOWNSID
77 WCHAR wstr[2];
78 WELL_KNOWN_SID_TYPE Type;
79 MAX_SID Sid;
80 } WELLKNOWNSID;
82 static const WELLKNOWNSID WellKnownSids[] =
84 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
85 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
86 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
87 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
88 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
89 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
90 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
91 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
92 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
93 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
94 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
95 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
96 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
97 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
98 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
99 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
100 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
101 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
102 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
103 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
104 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
105 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
106 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
107 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
108 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
109 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
110 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
111 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
112 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
113 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
114 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
115 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
116 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
117 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
118 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
119 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
120 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
121 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
122 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
123 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
124 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
125 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
126 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
127 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
128 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
129 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
130 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
131 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
134 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
135 typedef struct WELLKNOWNRID
137 WELL_KNOWN_SID_TYPE Type;
138 DWORD Rid;
139 } WELLKNOWNRID;
141 static const WELLKNOWNRID WellKnownRids[] = {
142 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
143 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
144 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
145 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
146 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
147 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
148 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
149 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
150 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
151 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
152 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
153 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
154 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
158 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
160 typedef struct _AccountSid {
161 WELL_KNOWN_SID_TYPE type;
162 LPCWSTR account;
163 LPCWSTR domain;
164 SID_NAME_USE name_use;
165 } AccountSid;
167 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
168 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
169 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
170 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
171 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
172 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
173 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
174 static const WCHAR Blank[] = { 0 };
175 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
176 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
177 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
178 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 };
179 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
180 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 };
181 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
182 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 };
183 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
184 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
185 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
186 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
187 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
188 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
189 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
190 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 };
191 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
192 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 };
193 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
194 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
195 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
196 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
197 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
198 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
199 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 };
200 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
201 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
202 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
203 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
204 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
205 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
206 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 };
207 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 };
208 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
209 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 };
210 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
211 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
212 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
213 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 };
214 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 };
215 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
216 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
217 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 };
218 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
219 static const WCHAR SELF[] = { 'S','E','L','F',0 };
220 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
221 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
222 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
223 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 };
224 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
225 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
227 static const AccountSid ACCOUNT_SIDS[] = {
228 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
229 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
230 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
231 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
232 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
233 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
234 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
235 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
236 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
253 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
254 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
255 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
256 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
257 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
261 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
262 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
263 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
265 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
270 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
271 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
274 * ACE access rights
276 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
277 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
278 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
279 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
281 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
282 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
283 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
284 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
285 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
286 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
287 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
288 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
289 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
291 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
292 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
293 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
294 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
296 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
297 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
298 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
299 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
301 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
302 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
303 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
304 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
307 * ACL flags
309 static const WCHAR SDDL_PROTECTED[] = {'P',0};
310 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
311 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
314 * ACE types
316 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
317 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
319 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
320 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
321 static const WCHAR SDDL_ALARM[] = {'A','L',0};
322 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
323 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
326 * ACE flags
328 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
329 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
330 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
331 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
332 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
333 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
334 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
336 const char * debugstr_sid(PSID sid)
338 int auth = 0;
339 SID * psid = (SID *)sid;
341 if (psid == NULL)
342 return "(null)";
344 auth = psid->IdentifierAuthority.Value[5] +
345 (psid->IdentifierAuthority.Value[4] << 8) +
346 (psid->IdentifierAuthority.Value[3] << 16) +
347 (psid->IdentifierAuthority.Value[2] << 24);
349 switch (psid->SubAuthorityCount) {
350 case 0:
351 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
352 case 1:
353 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
354 psid->SubAuthority[0]);
355 case 2:
356 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
357 psid->SubAuthority[0], psid->SubAuthority[1]);
358 case 3:
359 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
360 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
361 case 4:
362 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
363 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
364 psid->SubAuthority[3]);
365 case 5:
366 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
367 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
368 psid->SubAuthority[3], psid->SubAuthority[4]);
369 case 6:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
373 case 7:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
377 psid->SubAuthority[6]);
378 case 8:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
382 psid->SubAuthority[6], psid->SubAuthority[7]);
384 return "(too-big)";
387 /* set last error code from NT status and get the proper boolean return value */
388 /* used for functions that are a simple wrapper around the corresponding ntdll API */
389 static inline BOOL set_ntstatus( NTSTATUS status )
391 if (status) SetLastError( RtlNtStatusToDosError( status ));
392 return !status;
395 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
397 static void GetWorldAccessACL(PACL pACL)
399 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
401 pACL->AclRevision = ACL_REVISION;
402 pACL->Sbz1 = 0;
403 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
404 pACL->AceCount = 1;
405 pACL->Sbz2 = 0;
407 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
408 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
409 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
410 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
411 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
414 /************************************************************
415 * ADVAPI_IsLocalComputer
417 * Checks whether the server name indicates local machine.
419 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
421 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
422 BOOL Result;
423 LPWSTR buf;
425 if (!ServerName || !ServerName[0])
426 return TRUE;
428 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
429 Result = GetComputerNameW(buf, &dwSize);
430 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
431 ServerName += 2;
432 Result = Result && !lstrcmpW(ServerName, buf);
433 HeapFree(GetProcessHeap(), 0, buf);
435 return Result;
438 /************************************************************
439 * ADVAPI_GetComputerSid
441 * Reads the computer SID from the registry.
443 BOOL ADVAPI_GetComputerSid(PSID sid)
445 HKEY key;
446 LONG ret;
447 BOOL retval = FALSE;
448 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 };
449 static const WCHAR V[] = { 'V',0 };
451 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
452 KEY_READ, &key)) == ERROR_SUCCESS)
454 DWORD size = 0;
455 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
456 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
458 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
459 if (data)
461 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
462 data, &size)) == ERROR_SUCCESS)
464 /* the SID is in the last 24 bytes of the binary data */
465 CopyMemory(sid, &data[size-24], 24);
466 retval = TRUE;
468 HeapFree(GetProcessHeap(), 0, data);
471 RegCloseKey(key);
474 if(retval == TRUE) return retval;
476 /* create a new random SID */
477 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
478 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
480 PSID new_sid;
481 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
482 DWORD id[3];
484 if (RtlGenRandom(id, sizeof(id)))
486 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
488 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
489 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
491 FreeSid(new_sid);
494 RegCloseKey(key);
497 return retval;
500 /* ##############################
501 ###### TOKEN FUNCTIONS ######
502 ##############################
505 /******************************************************************************
506 * OpenProcessToken [ADVAPI32.@]
507 * Opens the access token associated with a process handle.
509 * PARAMS
510 * ProcessHandle [I] Handle to process
511 * DesiredAccess [I] Desired access to process
512 * TokenHandle [O] Pointer to handle of open access token
514 * RETURNS
515 * Success: TRUE. TokenHandle contains the access token.
516 * Failure: FALSE.
518 * NOTES
519 * See NtOpenProcessToken.
521 BOOL WINAPI
522 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
523 HANDLE *TokenHandle )
525 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
528 /******************************************************************************
529 * OpenThreadToken [ADVAPI32.@]
531 * Opens the access token associated with a thread handle.
533 * PARAMS
534 * ThreadHandle [I] Handle to process
535 * DesiredAccess [I] Desired access to the thread
536 * OpenAsSelf [I] ???
537 * TokenHandle [O] Destination for the token handle
539 * RETURNS
540 * Success: TRUE. TokenHandle contains the access token.
541 * Failure: FALSE.
543 * NOTES
544 * See NtOpenThreadToken.
546 BOOL WINAPI
547 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
548 BOOL OpenAsSelf, HANDLE *TokenHandle)
550 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
553 BOOL WINAPI
554 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
555 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
557 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
558 PreviousState, ReturnLength));
561 /******************************************************************************
562 * AdjustTokenPrivileges [ADVAPI32.@]
564 * Adjust the privileges of an open token handle.
566 * PARAMS
567 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
568 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
569 * NewState [I] Desired new privileges of the token
570 * BufferLength [I] Length of NewState
571 * PreviousState [O] Destination for the previous state
572 * ReturnLength [I/O] Size of PreviousState
575 * RETURNS
576 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
577 * Failure: FALSE.
579 * NOTES
580 * See NtAdjustPrivilegesToken.
582 BOOL WINAPI
583 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
584 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
585 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
587 NTSTATUS status;
589 TRACE("\n");
591 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
592 NewState, BufferLength, PreviousState,
593 ReturnLength);
594 SetLastError( RtlNtStatusToDosError( status ));
595 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
596 return TRUE;
597 else
598 return FALSE;
601 /******************************************************************************
602 * CheckTokenMembership [ADVAPI32.@]
604 * Determine if an access token is a member of a SID.
606 * PARAMS
607 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
608 * SidToCheck [I] SID that possibly contains the token
609 * IsMember [O] Destination for result.
611 * RETURNS
612 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
613 * Failure: FALSE.
615 BOOL WINAPI
616 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
617 PBOOL IsMember )
619 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
621 *IsMember = TRUE;
622 return(TRUE);
625 /******************************************************************************
626 * GetTokenInformation [ADVAPI32.@]
628 * Get a type of information about an access token.
630 * PARAMS
631 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
632 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
633 * tokeninfo [O] Destination for token information
634 * tokeninfolength [I] Length of tokeninfo
635 * retlen [O] Destination for returned token information length
637 * RETURNS
638 * Success: TRUE. tokeninfo contains retlen bytes of token information
639 * Failure: FALSE.
641 * NOTES
642 * See NtQueryInformationToken.
644 BOOL WINAPI
645 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
646 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
648 TRACE("(%p, %s, %p, %d, %p):\n",
649 token,
650 (tokeninfoclass == TokenUser) ? "TokenUser" :
651 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
652 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
653 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
654 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
655 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
656 (tokeninfoclass == TokenSource) ? "TokenSource" :
657 (tokeninfoclass == TokenType) ? "TokenType" :
658 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
659 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
660 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
661 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
662 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
663 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
664 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
665 "Unknown",
666 tokeninfo, tokeninfolength, retlen);
667 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
668 tokeninfolength, retlen));
671 /******************************************************************************
672 * SetTokenInformation [ADVAPI32.@]
674 * Set information for an access token.
676 * PARAMS
677 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
678 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
679 * tokeninfo [I] Token information to set
680 * tokeninfolength [I] Length of tokeninfo
682 * RETURNS
683 * Success: TRUE. The information for the token is set to tokeninfo.
684 * Failure: FALSE.
686 BOOL WINAPI
687 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
688 LPVOID tokeninfo, DWORD tokeninfolength )
690 TRACE("(%p, %s, %p, %d): stub\n",
691 token,
692 (tokeninfoclass == TokenUser) ? "TokenUser" :
693 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
694 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
695 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
696 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
697 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
698 (tokeninfoclass == TokenSource) ? "TokenSource" :
699 (tokeninfoclass == TokenType) ? "TokenType" :
700 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
701 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
702 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
703 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
704 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
705 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
706 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
707 "Unknown",
708 tokeninfo, tokeninfolength);
710 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
713 /*************************************************************************
714 * SetThreadToken [ADVAPI32.@]
716 * Assigns an 'impersonation token' to a thread so it can assume the
717 * security privileges of another thread or process. Can also remove
718 * a previously assigned token.
720 * PARAMS
721 * thread [O] Handle to thread to set the token for
722 * token [I] Token to set
724 * RETURNS
725 * Success: TRUE. The threads access token is set to token
726 * Failure: FALSE.
728 * NOTES
729 * Only supported on NT or higher. On Win9X this function does nothing.
730 * See SetTokenInformation.
732 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
734 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
735 ThreadImpersonationToken, &token, sizeof token ));
738 /*************************************************************************
739 * CreateRestrictedToken [ADVAPI32.@]
741 * Create a new more restricted token from an existing token.
743 * PARAMS
744 * baseToken [I] Token to base the new restricted token on
745 * flags [I] Options
746 * nDisableSids [I] Length of disableSids array
747 * disableSids [I] Array of SIDs to disable in the new token
748 * nDeletePrivs [I] Length of deletePrivs array
749 * deletePrivs [I] Array of privileges to delete in the new token
750 * nRestrictSids [I] Length of restrictSids array
751 * restrictSids [I] Array of SIDs to restrict in the new token
752 * newToken [O] Address where the new token is stored
754 * RETURNS
755 * Success: TRUE
756 * Failure: FALSE
758 BOOL WINAPI CreateRestrictedToken(
759 HANDLE baseToken,
760 DWORD flags,
761 DWORD nDisableSids,
762 PSID_AND_ATTRIBUTES disableSids,
763 DWORD nDeletePrivs,
764 PLUID_AND_ATTRIBUTES deletePrivs,
765 DWORD nRestrictSids,
766 PSID_AND_ATTRIBUTES restrictSids,
767 PHANDLE newToken)
769 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
770 baseToken, flags, nDisableSids, disableSids,
771 nDeletePrivs, deletePrivs,
772 nRestrictSids, restrictSids,
773 newToken);
774 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
775 return FALSE;
778 /* ##############################
779 ###### SID FUNCTIONS ######
780 ##############################
783 /******************************************************************************
784 * AllocateAndInitializeSid [ADVAPI32.@]
786 * PARAMS
787 * pIdentifierAuthority []
788 * nSubAuthorityCount []
789 * nSubAuthority0 []
790 * nSubAuthority1 []
791 * nSubAuthority2 []
792 * nSubAuthority3 []
793 * nSubAuthority4 []
794 * nSubAuthority5 []
795 * nSubAuthority6 []
796 * nSubAuthority7 []
797 * pSid []
799 BOOL WINAPI
800 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
801 BYTE nSubAuthorityCount,
802 DWORD nSubAuthority0, DWORD nSubAuthority1,
803 DWORD nSubAuthority2, DWORD nSubAuthority3,
804 DWORD nSubAuthority4, DWORD nSubAuthority5,
805 DWORD nSubAuthority6, DWORD nSubAuthority7,
806 PSID *pSid )
808 return set_ntstatus( RtlAllocateAndInitializeSid(
809 pIdentifierAuthority, nSubAuthorityCount,
810 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
811 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
812 pSid ));
815 /******************************************************************************
816 * FreeSid [ADVAPI32.@]
818 * PARAMS
819 * pSid []
821 PVOID WINAPI
822 FreeSid( PSID pSid )
824 RtlFreeSid(pSid);
825 return NULL; /* is documented like this */
828 /******************************************************************************
829 * CopySid [ADVAPI32.@]
831 * PARAMS
832 * nDestinationSidLength []
833 * pDestinationSid []
834 * pSourceSid []
836 BOOL WINAPI
837 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
839 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
842 /******************************************************************************
843 * CreateWellKnownSid [ADVAPI32.@]
845 BOOL WINAPI
846 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
847 PSID DomainSid,
848 PSID pSid,
849 DWORD* cbSid)
851 unsigned int i;
852 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
854 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
855 SetLastError(ERROR_INVALID_PARAMETER);
856 return FALSE;
859 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
860 if (WellKnownSids[i].Type == WellKnownSidType) {
861 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
863 if (*cbSid < length) {
864 SetLastError(ERROR_INSUFFICIENT_BUFFER);
865 return FALSE;
868 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
869 *cbSid = length;
870 return TRUE;
874 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
876 SetLastError(ERROR_INVALID_PARAMETER);
877 return FALSE;
880 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
881 if (WellKnownRids[i].Type == WellKnownSidType) {
882 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
883 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
884 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
886 if (*cbSid < output_sid_length) {
887 SetLastError(ERROR_INSUFFICIENT_BUFFER);
888 return FALSE;
891 CopyMemory(pSid, DomainSid, domain_sid_length);
892 (*GetSidSubAuthorityCount(pSid))++;
893 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
894 *cbSid = output_sid_length;
895 return TRUE;
898 SetLastError(ERROR_INVALID_PARAMETER);
899 return FALSE;
902 /******************************************************************************
903 * IsWellKnownSid [ADVAPI32.@]
905 BOOL WINAPI
906 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
908 unsigned int i;
909 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
911 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
912 if (WellKnownSids[i].Type == WellKnownSidType)
913 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
914 return TRUE;
916 return FALSE;
919 BOOL WINAPI
920 IsTokenRestricted( HANDLE TokenHandle )
922 TOKEN_GROUPS *groups;
923 DWORD size;
924 NTSTATUS status;
925 BOOL restricted;
927 TRACE("(%p)\n", TokenHandle);
929 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
930 if (status != STATUS_BUFFER_TOO_SMALL)
931 return FALSE;
933 groups = HeapAlloc(GetProcessHeap(), 0, size);
934 if (!groups)
936 SetLastError(ERROR_OUTOFMEMORY);
937 return FALSE;
940 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
941 if (status != STATUS_SUCCESS)
943 HeapFree(GetProcessHeap(), 0, groups);
944 return set_ntstatus(status);
947 if (groups->GroupCount)
948 restricted = TRUE;
949 else
950 restricted = FALSE;
952 HeapFree(GetProcessHeap(), 0, groups);
954 return restricted;
957 /******************************************************************************
958 * IsValidSid [ADVAPI32.@]
960 * PARAMS
961 * pSid []
963 BOOL WINAPI
964 IsValidSid( PSID pSid )
966 return RtlValidSid( pSid );
969 /******************************************************************************
970 * EqualSid [ADVAPI32.@]
972 * PARAMS
973 * pSid1 []
974 * pSid2 []
976 BOOL WINAPI
977 EqualSid( PSID pSid1, PSID pSid2 )
979 return RtlEqualSid( pSid1, pSid2 );
982 /******************************************************************************
983 * EqualPrefixSid [ADVAPI32.@]
985 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
987 return RtlEqualPrefixSid(pSid1, pSid2);
990 /******************************************************************************
991 * GetSidLengthRequired [ADVAPI32.@]
993 * PARAMS
994 * nSubAuthorityCount []
996 DWORD WINAPI
997 GetSidLengthRequired( BYTE nSubAuthorityCount )
999 return RtlLengthRequiredSid(nSubAuthorityCount);
1002 /******************************************************************************
1003 * InitializeSid [ADVAPI32.@]
1005 * PARAMS
1006 * pIdentifierAuthority []
1008 BOOL WINAPI
1009 InitializeSid (
1010 PSID pSid,
1011 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1012 BYTE nSubAuthorityCount)
1014 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1017 DWORD WINAPI
1018 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1020 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1022 return 1;
1025 DWORD WINAPI
1026 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1028 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1030 return 1;
1033 /******************************************************************************
1034 * GetSidIdentifierAuthority [ADVAPI32.@]
1036 * PARAMS
1037 * pSid []
1039 PSID_IDENTIFIER_AUTHORITY WINAPI
1040 GetSidIdentifierAuthority( PSID pSid )
1042 return RtlIdentifierAuthoritySid(pSid);
1045 /******************************************************************************
1046 * GetSidSubAuthority [ADVAPI32.@]
1048 * PARAMS
1049 * pSid []
1050 * nSubAuthority []
1052 PDWORD WINAPI
1053 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1055 return RtlSubAuthoritySid(pSid, nSubAuthority);
1058 /******************************************************************************
1059 * GetSidSubAuthorityCount [ADVAPI32.@]
1061 * PARAMS
1062 * pSid []
1064 PUCHAR WINAPI
1065 GetSidSubAuthorityCount (PSID pSid)
1067 return RtlSubAuthorityCountSid(pSid);
1070 /******************************************************************************
1071 * GetLengthSid [ADVAPI32.@]
1073 * PARAMS
1074 * pSid []
1076 DWORD WINAPI
1077 GetLengthSid (PSID pSid)
1079 return RtlLengthSid(pSid);
1082 /* ##############################################
1083 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1084 ##############################################
1087 /******************************************************************************
1088 * BuildSecurityDescriptorA [ADVAPI32.@]
1090 * Builds a SD from
1092 * PARAMS
1093 * pOwner [I]
1094 * pGroup [I]
1095 * cCountOfAccessEntries [I]
1096 * pListOfAccessEntries [I]
1097 * cCountOfAuditEntries [I]
1098 * pListofAuditEntries [I]
1099 * pOldSD [I]
1100 * lpdwBufferLength [I/O]
1101 * pNewSD [O]
1103 * RETURNS
1104 * Success: ERROR_SUCCESS
1105 * Failure: nonzero error code from Winerror.h
1107 DWORD WINAPI BuildSecurityDescriptorA(
1108 IN PTRUSTEEA pOwner,
1109 IN PTRUSTEEA pGroup,
1110 IN ULONG cCountOfAccessEntries,
1111 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1112 IN ULONG cCountOfAuditEntries,
1113 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1114 IN PSECURITY_DESCRIPTOR pOldSD,
1115 IN OUT PULONG lpdwBufferLength,
1116 OUT PSECURITY_DESCRIPTOR* pNewSD)
1118 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1119 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1120 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1122 return ERROR_CALL_NOT_IMPLEMENTED;
1125 /******************************************************************************
1126 * BuildSecurityDescriptorW [ADVAPI32.@]
1128 * See BuildSecurityDescriptorA.
1130 DWORD WINAPI BuildSecurityDescriptorW(
1131 IN PTRUSTEEW pOwner,
1132 IN PTRUSTEEW pGroup,
1133 IN ULONG cCountOfAccessEntries,
1134 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1135 IN ULONG cCountOfAuditEntries,
1136 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1137 IN PSECURITY_DESCRIPTOR pOldSD,
1138 IN OUT PULONG lpdwBufferLength,
1139 OUT PSECURITY_DESCRIPTOR* pNewSD)
1141 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1142 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1143 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145 return ERROR_CALL_NOT_IMPLEMENTED;
1148 /******************************************************************************
1149 * InitializeSecurityDescriptor [ADVAPI32.@]
1151 * PARAMS
1152 * pDescr []
1153 * revision []
1155 BOOL WINAPI
1156 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1158 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1162 /******************************************************************************
1163 * MakeAbsoluteSD [ADVAPI32.@]
1165 BOOL WINAPI MakeAbsoluteSD (
1166 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1167 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1168 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1169 OUT PACL pDacl,
1170 OUT LPDWORD lpdwDaclSize,
1171 OUT PACL pSacl,
1172 OUT LPDWORD lpdwSaclSize,
1173 OUT PSID pOwner,
1174 OUT LPDWORD lpdwOwnerSize,
1175 OUT PSID pPrimaryGroup,
1176 OUT LPDWORD lpdwPrimaryGroupSize)
1178 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1179 pAbsoluteSecurityDescriptor,
1180 lpdwAbsoluteSecurityDescriptorSize,
1181 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1182 pOwner, lpdwOwnerSize,
1183 pPrimaryGroup, lpdwPrimaryGroupSize));
1186 /******************************************************************************
1187 * GetKernelObjectSecurity [ADVAPI32.@]
1189 BOOL WINAPI GetKernelObjectSecurity(
1190 HANDLE Handle,
1191 SECURITY_INFORMATION RequestedInformation,
1192 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1193 DWORD nLength,
1194 LPDWORD lpnLengthNeeded )
1196 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1197 pSecurityDescriptor, nLength, lpnLengthNeeded);
1199 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1200 nLength, lpnLengthNeeded ));
1203 /******************************************************************************
1204 * GetPrivateObjectSecurity [ADVAPI32.@]
1206 BOOL WINAPI GetPrivateObjectSecurity(
1207 PSECURITY_DESCRIPTOR ObjectDescriptor,
1208 SECURITY_INFORMATION SecurityInformation,
1209 PSECURITY_DESCRIPTOR ResultantDescriptor,
1210 DWORD DescriptorLength,
1211 PDWORD ReturnLength )
1213 SECURITY_DESCRIPTOR desc;
1214 BOOL defaulted, present;
1215 PACL pacl;
1216 PSID psid;
1218 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1219 ResultantDescriptor, DescriptorLength, ReturnLength);
1221 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1222 return FALSE;
1224 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1226 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1227 return FALSE;
1228 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1231 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1233 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1234 return FALSE;
1235 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1238 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1240 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1241 return FALSE;
1242 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1245 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1247 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1248 return FALSE;
1249 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1252 *ReturnLength = DescriptorLength;
1253 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1256 /******************************************************************************
1257 * GetSecurityDescriptorLength [ADVAPI32.@]
1259 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1261 return RtlLengthSecurityDescriptor(pDescr);
1264 /******************************************************************************
1265 * GetSecurityDescriptorOwner [ADVAPI32.@]
1267 * PARAMS
1268 * pOwner []
1269 * lpbOwnerDefaulted []
1271 BOOL WINAPI
1272 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1273 LPBOOL lpbOwnerDefaulted )
1275 BOOLEAN defaulted;
1276 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1277 *lpbOwnerDefaulted = defaulted;
1278 return ret;
1281 /******************************************************************************
1282 * SetSecurityDescriptorOwner [ADVAPI32.@]
1284 * PARAMS
1286 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1287 PSID pOwner, BOOL bOwnerDefaulted)
1289 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1291 /******************************************************************************
1292 * GetSecurityDescriptorGroup [ADVAPI32.@]
1294 BOOL WINAPI GetSecurityDescriptorGroup(
1295 PSECURITY_DESCRIPTOR SecurityDescriptor,
1296 PSID *Group,
1297 LPBOOL GroupDefaulted)
1299 BOOLEAN defaulted;
1300 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1301 *GroupDefaulted = defaulted;
1302 return ret;
1304 /******************************************************************************
1305 * SetSecurityDescriptorGroup [ADVAPI32.@]
1307 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1308 PSID Group, BOOL GroupDefaulted)
1310 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1313 /******************************************************************************
1314 * IsValidSecurityDescriptor [ADVAPI32.@]
1316 * PARAMS
1317 * lpsecdesc []
1319 BOOL WINAPI
1320 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1322 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1325 /******************************************************************************
1326 * GetSecurityDescriptorDacl [ADVAPI32.@]
1328 BOOL WINAPI GetSecurityDescriptorDacl(
1329 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1330 OUT LPBOOL lpbDaclPresent,
1331 OUT PACL *pDacl,
1332 OUT LPBOOL lpbDaclDefaulted)
1334 BOOLEAN present, defaulted;
1335 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1336 *lpbDaclPresent = present;
1337 *lpbDaclDefaulted = defaulted;
1338 return ret;
1341 /******************************************************************************
1342 * SetSecurityDescriptorDacl [ADVAPI32.@]
1344 BOOL WINAPI
1345 SetSecurityDescriptorDacl (
1346 PSECURITY_DESCRIPTOR lpsd,
1347 BOOL daclpresent,
1348 PACL dacl,
1349 BOOL dacldefaulted )
1351 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1353 /******************************************************************************
1354 * GetSecurityDescriptorSacl [ADVAPI32.@]
1356 BOOL WINAPI GetSecurityDescriptorSacl(
1357 IN PSECURITY_DESCRIPTOR lpsd,
1358 OUT LPBOOL lpbSaclPresent,
1359 OUT PACL *pSacl,
1360 OUT LPBOOL lpbSaclDefaulted)
1362 BOOLEAN present, defaulted;
1363 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1364 *lpbSaclPresent = present;
1365 *lpbSaclDefaulted = defaulted;
1366 return ret;
1369 /**************************************************************************
1370 * SetSecurityDescriptorSacl [ADVAPI32.@]
1372 BOOL WINAPI SetSecurityDescriptorSacl (
1373 PSECURITY_DESCRIPTOR lpsd,
1374 BOOL saclpresent,
1375 PACL lpsacl,
1376 BOOL sacldefaulted)
1378 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1380 /******************************************************************************
1381 * MakeSelfRelativeSD [ADVAPI32.@]
1383 * PARAMS
1384 * lpabssecdesc []
1385 * lpselfsecdesc []
1386 * lpbuflen []
1388 BOOL WINAPI
1389 MakeSelfRelativeSD(
1390 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1391 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1392 IN OUT LPDWORD lpdwBufferLength)
1394 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1395 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1398 /******************************************************************************
1399 * GetSecurityDescriptorControl [ADVAPI32.@]
1402 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1403 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1405 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1408 /******************************************************************************
1409 * SetSecurityDescriptorControl [ADVAPI32.@]
1411 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1412 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1413 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1415 return set_ntstatus( RtlSetControlSecurityDescriptor(
1416 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1419 /* ##############################
1420 ###### ACL FUNCTIONS ######
1421 ##############################
1424 /*************************************************************************
1425 * InitializeAcl [ADVAPI32.@]
1427 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1429 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1432 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1434 IO_STATUS_BLOCK io_block;
1436 TRACE("(%p)\n", hNamedPipe);
1438 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1439 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1442 /******************************************************************************
1443 * AddAccessAllowedAce [ADVAPI32.@]
1445 BOOL WINAPI AddAccessAllowedAce(
1446 IN OUT PACL pAcl,
1447 IN DWORD dwAceRevision,
1448 IN DWORD AccessMask,
1449 IN PSID pSid)
1451 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1454 /******************************************************************************
1455 * AddAccessAllowedAceEx [ADVAPI32.@]
1457 BOOL WINAPI AddAccessAllowedAceEx(
1458 IN OUT PACL pAcl,
1459 IN DWORD dwAceRevision,
1460 IN DWORD AceFlags,
1461 IN DWORD AccessMask,
1462 IN PSID pSid)
1464 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1467 /******************************************************************************
1468 * AddAccessDeniedAce [ADVAPI32.@]
1470 BOOL WINAPI AddAccessDeniedAce(
1471 IN OUT PACL pAcl,
1472 IN DWORD dwAceRevision,
1473 IN DWORD AccessMask,
1474 IN PSID pSid)
1476 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1479 /******************************************************************************
1480 * AddAccessDeniedAceEx [ADVAPI32.@]
1482 BOOL WINAPI AddAccessDeniedAceEx(
1483 IN OUT PACL pAcl,
1484 IN DWORD dwAceRevision,
1485 IN DWORD AceFlags,
1486 IN DWORD AccessMask,
1487 IN PSID pSid)
1489 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1492 /******************************************************************************
1493 * AddAce [ADVAPI32.@]
1495 BOOL WINAPI AddAce(
1496 IN OUT PACL pAcl,
1497 IN DWORD dwAceRevision,
1498 IN DWORD dwStartingAceIndex,
1499 LPVOID pAceList,
1500 DWORD nAceListLength)
1502 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1505 /******************************************************************************
1506 * DeleteAce [ADVAPI32.@]
1508 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1510 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1513 /******************************************************************************
1514 * FindFirstFreeAce [ADVAPI32.@]
1516 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1518 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1521 /******************************************************************************
1522 * GetAce [ADVAPI32.@]
1524 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1526 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1529 /******************************************************************************
1530 * GetAclInformation [ADVAPI32.@]
1532 BOOL WINAPI GetAclInformation(
1533 PACL pAcl,
1534 LPVOID pAclInformation,
1535 DWORD nAclInformationLength,
1536 ACL_INFORMATION_CLASS dwAclInformationClass)
1538 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1539 nAclInformationLength, dwAclInformationClass));
1542 /******************************************************************************
1543 * IsValidAcl [ADVAPI32.@]
1545 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1547 return RtlValidAcl(pAcl);
1550 /* ##############################
1551 ###### MISC FUNCTIONS ######
1552 ##############################
1555 /******************************************************************************
1556 * AllocateLocallyUniqueId [ADVAPI32.@]
1558 * PARAMS
1559 * lpLuid []
1561 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1563 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1566 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1567 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1568 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1569 { '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 };
1570 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1571 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1572 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1573 { '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 };
1574 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1575 { '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 };
1576 static const WCHAR SE_TCB_NAME_W[] =
1577 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1578 static const WCHAR SE_SECURITY_NAME_W[] =
1579 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1580 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1581 { '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 };
1582 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1583 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1584 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1585 { '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 };
1586 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1587 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1588 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1589 { '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 };
1590 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1591 { '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 };
1592 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1593 { '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 };
1594 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1595 { '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 };
1596 static const WCHAR SE_BACKUP_NAME_W[] =
1597 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1598 static const WCHAR SE_RESTORE_NAME_W[] =
1599 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1600 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1601 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_DEBUG_NAME_W[] =
1603 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_AUDIT_NAME_W[] =
1605 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1606 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1607 { '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 };
1608 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1609 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1610 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1611 { '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 };
1612 static const WCHAR SE_UNDOCK_NAME_W[] =
1613 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1614 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1615 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1616 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1617 { '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 };
1618 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1619 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1620 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1621 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1623 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1627 NULL,
1628 NULL,
1629 SE_CREATE_TOKEN_NAME_W,
1630 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1631 SE_LOCK_MEMORY_NAME_W,
1632 SE_INCREASE_QUOTA_NAME_W,
1633 SE_MACHINE_ACCOUNT_NAME_W,
1634 SE_TCB_NAME_W,
1635 SE_SECURITY_NAME_W,
1636 SE_TAKE_OWNERSHIP_NAME_W,
1637 SE_LOAD_DRIVER_NAME_W,
1638 SE_SYSTEM_PROFILE_NAME_W,
1639 SE_SYSTEMTIME_NAME_W,
1640 SE_PROF_SINGLE_PROCESS_NAME_W,
1641 SE_INC_BASE_PRIORITY_NAME_W,
1642 SE_CREATE_PAGEFILE_NAME_W,
1643 SE_CREATE_PERMANENT_NAME_W,
1644 SE_BACKUP_NAME_W,
1645 SE_RESTORE_NAME_W,
1646 SE_SHUTDOWN_NAME_W,
1647 SE_DEBUG_NAME_W,
1648 SE_AUDIT_NAME_W,
1649 SE_SYSTEM_ENVIRONMENT_NAME_W,
1650 SE_CHANGE_NOTIFY_NAME_W,
1651 SE_REMOTE_SHUTDOWN_NAME_W,
1652 SE_UNDOCK_NAME_W,
1653 SE_SYNC_AGENT_NAME_W,
1654 SE_ENABLE_DELEGATION_NAME_W,
1655 SE_MANAGE_VOLUME_NAME_W,
1656 SE_IMPERSONATE_NAME_W,
1657 SE_CREATE_GLOBAL_NAME_W,
1660 /******************************************************************************
1661 * LookupPrivilegeValueW [ADVAPI32.@]
1663 * See LookupPrivilegeValueA.
1665 BOOL WINAPI
1666 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1668 UINT i;
1670 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1672 if (!ADVAPI_IsLocalComputer(lpSystemName))
1674 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1675 return FALSE;
1677 if (!lpName)
1679 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1680 return FALSE;
1682 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1684 if( !WellKnownPrivNames[i] )
1685 continue;
1686 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1687 continue;
1688 lpLuid->LowPart = i;
1689 lpLuid->HighPart = 0;
1690 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1691 lpLuid->HighPart, lpLuid->LowPart );
1692 return TRUE;
1694 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1695 return FALSE;
1698 /******************************************************************************
1699 * LookupPrivilegeValueA [ADVAPI32.@]
1701 * Retrieves LUID used on a system to represent the privilege name.
1703 * PARAMS
1704 * lpSystemName [I] Name of the system
1705 * lpName [I] Name of the privilege
1706 * lpLuid [O] Destination for the resulting LUID
1708 * RETURNS
1709 * Success: TRUE. lpLuid contains the requested LUID.
1710 * Failure: FALSE.
1712 BOOL WINAPI
1713 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1715 UNICODE_STRING lpSystemNameW;
1716 UNICODE_STRING lpNameW;
1717 BOOL ret;
1719 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1720 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1721 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1722 RtlFreeUnicodeString(&lpNameW);
1723 RtlFreeUnicodeString(&lpSystemNameW);
1724 return ret;
1727 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1728 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1730 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1731 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1733 return FALSE;
1736 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1737 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1739 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1740 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1742 return FALSE;
1745 /******************************************************************************
1746 * LookupPrivilegeNameA [ADVAPI32.@]
1748 * See LookupPrivilegeNameW.
1750 BOOL WINAPI
1751 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1752 LPDWORD cchName)
1754 UNICODE_STRING lpSystemNameW;
1755 BOOL ret;
1756 DWORD wLen = 0;
1758 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1760 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1761 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1762 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1764 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1766 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1767 &wLen);
1768 if (ret)
1770 /* Windows crashes if cchName is NULL, so will I */
1771 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1772 *cchName, NULL, NULL);
1774 if (len == 0)
1776 /* WideCharToMultiByte failed */
1777 ret = FALSE;
1779 else if (len > *cchName)
1781 *cchName = len;
1782 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1783 ret = FALSE;
1785 else
1787 /* WideCharToMultiByte succeeded, output length needs to be
1788 * length not including NULL terminator
1790 *cchName = len - 1;
1793 HeapFree(GetProcessHeap(), 0, lpNameW);
1795 RtlFreeUnicodeString(&lpSystemNameW);
1796 return ret;
1799 /******************************************************************************
1800 * LookupPrivilegeNameW [ADVAPI32.@]
1802 * Retrieves the privilege name referred to by the LUID lpLuid.
1804 * PARAMS
1805 * lpSystemName [I] Name of the system
1806 * lpLuid [I] Privilege value
1807 * lpName [O] Name of the privilege
1808 * cchName [I/O] Number of characters in lpName.
1810 * RETURNS
1811 * Success: TRUE. lpName contains the name of the privilege whose value is
1812 * *lpLuid.
1813 * Failure: FALSE.
1815 * REMARKS
1816 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1817 * using this function.
1818 * If the length of lpName is too small, on return *cchName will contain the
1819 * number of WCHARs needed to contain the privilege, including the NULL
1820 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1821 * On success, *cchName will contain the number of characters stored in
1822 * lpName, NOT including the NULL terminator.
1824 BOOL WINAPI
1825 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1826 LPDWORD cchName)
1828 size_t privNameLen;
1830 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1832 if (!ADVAPI_IsLocalComputer(lpSystemName))
1834 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1835 return FALSE;
1837 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1838 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1840 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1841 return FALSE;
1843 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1844 /* Windows crashes if cchName is NULL, so will I */
1845 if (*cchName <= privNameLen)
1847 *cchName = privNameLen + 1;
1848 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1849 return FALSE;
1851 else
1853 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1854 *cchName = privNameLen;
1855 return TRUE;
1859 /******************************************************************************
1860 * GetFileSecurityA [ADVAPI32.@]
1862 * Obtains Specified information about the security of a file or directory.
1864 * PARAMS
1865 * lpFileName [I] Name of the file to get info for
1866 * RequestedInformation [I] SE_ flags from "winnt.h"
1867 * pSecurityDescriptor [O] Destination for security information
1868 * nLength [I] Length of pSecurityDescriptor
1869 * lpnLengthNeeded [O] Destination for length of returned security information
1871 * RETURNS
1872 * Success: TRUE. pSecurityDescriptor contains the requested information.
1873 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1875 * NOTES
1876 * The information returned is constrained by the callers access rights and
1877 * privileges.
1879 BOOL WINAPI
1880 GetFileSecurityA( LPCSTR lpFileName,
1881 SECURITY_INFORMATION RequestedInformation,
1882 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1883 DWORD nLength, LPDWORD lpnLengthNeeded )
1885 DWORD len;
1886 BOOL r;
1887 LPWSTR name = NULL;
1889 if( lpFileName )
1891 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1892 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1893 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1896 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1897 nLength, lpnLengthNeeded );
1898 HeapFree( GetProcessHeap(), 0, name );
1900 return r;
1903 /******************************************************************************
1904 * GetFileSecurityW [ADVAPI32.@]
1906 * See GetFileSecurityA.
1908 BOOL WINAPI
1909 GetFileSecurityW( LPCWSTR lpFileName,
1910 SECURITY_INFORMATION RequestedInformation,
1911 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1912 DWORD nLength, LPDWORD lpnLengthNeeded )
1914 HANDLE hfile;
1915 NTSTATUS status;
1916 DWORD access = 0;
1918 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1919 RequestedInformation, pSecurityDescriptor,
1920 nLength, lpnLengthNeeded);
1922 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1923 DACL_SECURITY_INFORMATION))
1924 access |= READ_CONTROL;
1925 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1926 access |= ACCESS_SYSTEM_SECURITY;
1928 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1929 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1930 if ( hfile == INVALID_HANDLE_VALUE )
1931 return FALSE;
1933 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1934 nLength, lpnLengthNeeded );
1935 CloseHandle( hfile );
1936 return set_ntstatus( status );
1940 /******************************************************************************
1941 * LookupAccountSidA [ADVAPI32.@]
1943 BOOL WINAPI
1944 LookupAccountSidA(
1945 IN LPCSTR system,
1946 IN PSID sid,
1947 OUT LPSTR account,
1948 IN OUT LPDWORD accountSize,
1949 OUT LPSTR domain,
1950 IN OUT LPDWORD domainSize,
1951 OUT PSID_NAME_USE name_use )
1953 DWORD len;
1954 BOOL r;
1955 LPWSTR systemW = NULL;
1956 LPWSTR accountW = NULL;
1957 LPWSTR domainW = NULL;
1958 DWORD accountSizeW = *accountSize;
1959 DWORD domainSizeW = *domainSize;
1961 if (system) {
1962 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1963 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1964 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1966 if (account)
1967 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1968 if (domain)
1969 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1971 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1973 if (r) {
1974 if (accountW && *accountSize) {
1975 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1976 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1977 *accountSize = len;
1978 } else
1979 *accountSize = accountSizeW + 1;
1981 if (domainW && *domainSize) {
1982 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1983 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1984 *domainSize = len;
1985 } else
1986 *domainSize = domainSizeW + 1;
1989 HeapFree( GetProcessHeap(), 0, systemW );
1990 HeapFree( GetProcessHeap(), 0, accountW );
1991 HeapFree( GetProcessHeap(), 0, domainW );
1993 return r;
1996 /******************************************************************************
1997 * LookupAccountSidW [ADVAPI32.@]
1999 * PARAMS
2000 * system []
2001 * sid []
2002 * account []
2003 * accountSize []
2004 * domain []
2005 * domainSize []
2006 * name_use []
2009 BOOL WINAPI
2010 LookupAccountSidW(
2011 IN LPCWSTR system,
2012 IN PSID sid,
2013 OUT LPWSTR account,
2014 IN OUT LPDWORD accountSize,
2015 OUT LPWSTR domain,
2016 IN OUT LPDWORD domainSize,
2017 OUT PSID_NAME_USE name_use )
2019 unsigned int i, j;
2020 const WCHAR * ac = NULL;
2021 const WCHAR * dm = NULL;
2022 SID_NAME_USE use = 0;
2023 LPWSTR computer_name = NULL;
2024 LPWSTR account_name = NULL;
2026 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2027 debugstr_w(system),debugstr_sid(sid),
2028 account,accountSize,accountSize?*accountSize:0,
2029 domain,domainSize,domainSize?*domainSize:0,
2030 name_use);
2032 if (!ADVAPI_IsLocalComputer(system)) {
2033 FIXME("Only local computer supported!\n");
2034 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2035 return FALSE;
2038 /* check the well known SIDs first */
2039 for (i = 0; i <= 60; i++) {
2040 if (IsWellKnownSid(sid, i)) {
2041 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2042 if (ACCOUNT_SIDS[j].type == i) {
2043 ac = ACCOUNT_SIDS[j].account;
2044 dm = ACCOUNT_SIDS[j].domain;
2045 use = ACCOUNT_SIDS[j].name_use;
2048 break;
2052 if (dm == NULL) {
2053 MAX_SID local;
2055 /* check for the local computer next */
2056 if (ADVAPI_GetComputerSid(&local)) {
2057 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2058 BOOL result;
2060 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2061 result = GetComputerNameW(computer_name, &size);
2063 if (result) {
2064 if (EqualSid(sid, &local)) {
2065 dm = computer_name;
2066 ac = Blank;
2067 use = 3;
2068 } else {
2069 local.SubAuthorityCount++;
2071 if (EqualPrefixSid(sid, &local)) {
2072 dm = computer_name;
2073 use = 1;
2074 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2075 case DOMAIN_USER_RID_ADMIN:
2076 ac = Administrator;
2077 break;
2078 case DOMAIN_USER_RID_GUEST:
2079 ac = Guest;
2080 break;
2081 case DOMAIN_GROUP_RID_ADMINS:
2082 ac = Domain_Admins;
2083 break;
2084 case DOMAIN_GROUP_RID_USERS:
2085 ac = Domain_Users;
2086 break;
2087 case DOMAIN_GROUP_RID_GUESTS:
2088 ac = Domain_Guests;
2089 break;
2090 case DOMAIN_GROUP_RID_COMPUTERS:
2091 ac = Domain_Computers;
2092 break;
2093 case DOMAIN_GROUP_RID_CONTROLLERS:
2094 ac = Domain_Controllers;
2095 break;
2096 case DOMAIN_GROUP_RID_CERT_ADMINS:
2097 ac = Cert_Publishers;
2098 break;
2099 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2100 ac = Schema_Admins;
2101 break;
2102 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2103 ac = Enterprise_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2106 ac = Group_Policy_Creator_Owners;
2107 break;
2108 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2109 ac = RAS_and_IAS_Servers;
2110 break;
2111 case 1000: /* first user account */
2112 size = UNLEN + 1;
2113 account_name = HeapAlloc(
2114 GetProcessHeap(), 0, size * sizeof(WCHAR));
2115 if (GetUserNameW(account_name, &size))
2116 ac = account_name;
2117 else
2118 dm = NULL;
2120 break;
2121 default:
2122 dm = NULL;
2123 break;
2131 if (dm) {
2132 DWORD ac_len = lstrlenW(ac);
2133 DWORD dm_len = lstrlenW(dm);
2134 BOOL status = TRUE;
2136 if (*accountSize > ac_len) {
2137 if (account)
2138 lstrcpyW(account, ac);
2140 if (*domainSize > dm_len) {
2141 if (domain)
2142 lstrcpyW(domain, dm);
2144 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2145 ((*domainSize != 0) && (*domainSize < dm_len))) {
2146 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2147 status = FALSE;
2149 if (*domainSize)
2150 *domainSize = dm_len;
2151 else
2152 *domainSize = dm_len + 1;
2153 if (*accountSize)
2154 *accountSize = ac_len;
2155 else
2156 *accountSize = ac_len + 1;
2157 *name_use = use;
2158 HeapFree(GetProcessHeap(), 0, account_name);
2159 HeapFree(GetProcessHeap(), 0, computer_name);
2160 return status;
2163 HeapFree(GetProcessHeap(), 0, account_name);
2164 HeapFree(GetProcessHeap(), 0, computer_name);
2165 SetLastError(ERROR_NONE_MAPPED);
2166 return FALSE;
2169 /******************************************************************************
2170 * SetFileSecurityA [ADVAPI32.@]
2172 * See SetFileSecurityW.
2174 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2175 SECURITY_INFORMATION RequestedInformation,
2176 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2178 DWORD len;
2179 BOOL r;
2180 LPWSTR name = NULL;
2182 if( lpFileName )
2184 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2185 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2186 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2189 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2190 HeapFree( GetProcessHeap(), 0, name );
2192 return r;
2195 /******************************************************************************
2196 * SetFileSecurityW [ADVAPI32.@]
2198 * Sets the security of a file or directory.
2200 * PARAMS
2201 * lpFileName []
2202 * RequestedInformation []
2203 * pSecurityDescriptor []
2205 * RETURNS
2206 * Success: TRUE.
2207 * Failure: FALSE.
2209 BOOL WINAPI
2210 SetFileSecurityW( LPCWSTR lpFileName,
2211 SECURITY_INFORMATION RequestedInformation,
2212 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2214 HANDLE file;
2215 DWORD access = 0;
2216 NTSTATUS status;
2218 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2219 pSecurityDescriptor );
2221 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2222 RequestedInformation & GROUP_SECURITY_INFORMATION)
2223 access |= WRITE_OWNER;
2224 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2225 access |= ACCESS_SYSTEM_SECURITY;
2226 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2227 access |= WRITE_DAC;
2229 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2230 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2231 if (file == INVALID_HANDLE_VALUE)
2232 return FALSE;
2234 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2235 CloseHandle( file );
2236 return set_ntstatus( status );
2239 /******************************************************************************
2240 * QueryWindows31FilesMigration [ADVAPI32.@]
2242 * PARAMS
2243 * x1 []
2245 BOOL WINAPI
2246 QueryWindows31FilesMigration( DWORD x1 )
2248 FIXME("(%d):stub\n",x1);
2249 return TRUE;
2252 /******************************************************************************
2253 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2255 * PARAMS
2256 * x1 []
2257 * x2 []
2258 * x3 []
2259 * x4 []
2261 BOOL WINAPI
2262 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2263 DWORD x4 )
2265 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2266 return TRUE;
2269 /******************************************************************************
2270 * NotifyBootConfigStatus [ADVAPI32.@]
2272 * PARAMS
2273 * x1 []
2275 BOOL WINAPI
2276 NotifyBootConfigStatus( BOOL x1 )
2278 FIXME("(0x%08d):stub\n",x1);
2279 return 1;
2282 /******************************************************************************
2283 * RevertToSelf [ADVAPI32.@]
2285 * Ends the impersonation of a user.
2287 * PARAMS
2288 * void []
2290 * RETURNS
2291 * Success: TRUE.
2292 * Failure: FALSE.
2294 BOOL WINAPI
2295 RevertToSelf( void )
2297 HANDLE Token = NULL;
2298 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2299 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2302 /******************************************************************************
2303 * ImpersonateSelf [ADVAPI32.@]
2305 * Makes an impersonation token that represents the process user and assigns
2306 * to the current thread.
2308 * PARAMS
2309 * ImpersonationLevel [I] Level at which to impersonate.
2311 * RETURNS
2312 * Success: TRUE.
2313 * Failure: FALSE.
2315 BOOL WINAPI
2316 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2318 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2321 /******************************************************************************
2322 * ImpersonateLoggedOnUser [ADVAPI32.@]
2324 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2326 DWORD size;
2327 NTSTATUS Status;
2328 HANDLE ImpersonationToken;
2329 TOKEN_TYPE Type;
2330 static BOOL warn = TRUE;
2332 if (warn)
2334 FIXME( "(%p)\n", hToken );
2335 warn = FALSE;
2337 if (!GetTokenInformation( hToken, TokenType, &Type,
2338 sizeof(TOKEN_TYPE), &size ))
2339 return FALSE;
2341 if (Type == TokenPrimary)
2343 OBJECT_ATTRIBUTES ObjectAttributes;
2345 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2347 Status = NtDuplicateToken( hToken,
2348 TOKEN_IMPERSONATE | TOKEN_QUERY,
2349 &ObjectAttributes,
2350 SecurityImpersonation,
2351 TokenImpersonation,
2352 &ImpersonationToken );
2353 if (Status != STATUS_SUCCESS)
2355 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2356 SetLastError( RtlNtStatusToDosError( Status ) );
2357 return FALSE;
2360 else
2361 ImpersonationToken = hToken;
2363 Status = NtSetInformationThread( GetCurrentThread(),
2364 ThreadImpersonationToken,
2365 &ImpersonationToken,
2366 sizeof(ImpersonationToken) );
2368 if (Type == TokenPrimary)
2369 NtClose( ImpersonationToken );
2371 if (Status != STATUS_SUCCESS)
2373 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2374 SetLastError( RtlNtStatusToDosError( Status ) );
2375 return FALSE;
2378 return TRUE;
2381 /******************************************************************************
2382 * AccessCheck [ADVAPI32.@]
2384 BOOL WINAPI
2385 AccessCheck(
2386 PSECURITY_DESCRIPTOR SecurityDescriptor,
2387 HANDLE ClientToken,
2388 DWORD DesiredAccess,
2389 PGENERIC_MAPPING GenericMapping,
2390 PPRIVILEGE_SET PrivilegeSet,
2391 LPDWORD PrivilegeSetLength,
2392 LPDWORD GrantedAccess,
2393 LPBOOL AccessStatus)
2395 NTSTATUS access_status;
2396 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2397 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2398 GrantedAccess, &access_status) );
2399 if (ret) *AccessStatus = set_ntstatus( access_status );
2400 return ret;
2404 /******************************************************************************
2405 * AccessCheckByType [ADVAPI32.@]
2407 BOOL WINAPI AccessCheckByType(
2408 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2409 PSID PrincipalSelfSid,
2410 HANDLE ClientToken,
2411 DWORD DesiredAccess,
2412 POBJECT_TYPE_LIST ObjectTypeList,
2413 DWORD ObjectTypeListLength,
2414 PGENERIC_MAPPING GenericMapping,
2415 PPRIVILEGE_SET PrivilegeSet,
2416 LPDWORD PrivilegeSetLength,
2417 LPDWORD GrantedAccess,
2418 LPBOOL AccessStatus)
2420 FIXME("stub\n");
2422 *AccessStatus = TRUE;
2424 return !*AccessStatus;
2427 /******************************************************************************
2428 * MapGenericMask [ADVAPI32.@]
2430 * Maps generic access rights into specific access rights according to the
2431 * supplied mapping.
2433 * PARAMS
2434 * AccessMask [I/O] Access rights.
2435 * GenericMapping [I] The mapping between generic and specific rights.
2437 * RETURNS
2438 * Nothing.
2440 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2442 RtlMapGenericMask( AccessMask, GenericMapping );
2445 /*************************************************************************
2446 * SetKernelObjectSecurity [ADVAPI32.@]
2448 BOOL WINAPI SetKernelObjectSecurity (
2449 IN HANDLE Handle,
2450 IN SECURITY_INFORMATION SecurityInformation,
2451 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2453 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2457 /******************************************************************************
2458 * AddAuditAccessAce [ADVAPI32.@]
2460 BOOL WINAPI AddAuditAccessAce(
2461 IN OUT PACL pAcl,
2462 IN DWORD dwAceRevision,
2463 IN DWORD dwAccessMask,
2464 IN PSID pSid,
2465 IN BOOL bAuditSuccess,
2466 IN BOOL bAuditFailure)
2468 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2469 bAuditSuccess, bAuditFailure) );
2472 /******************************************************************************
2473 * AddAuditAccessAce [ADVAPI32.@]
2475 BOOL WINAPI AddAuditAccessAceEx(
2476 IN OUT PACL pAcl,
2477 IN DWORD dwAceRevision,
2478 IN DWORD dwAceFlags,
2479 IN DWORD dwAccessMask,
2480 IN PSID pSid,
2481 IN BOOL bAuditSuccess,
2482 IN BOOL bAuditFailure)
2484 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2485 bAuditSuccess, bAuditFailure) );
2488 /******************************************************************************
2489 * LookupAccountNameA [ADVAPI32.@]
2491 BOOL WINAPI
2492 LookupAccountNameA(
2493 IN LPCSTR system,
2494 IN LPCSTR account,
2495 OUT PSID sid,
2496 OUT LPDWORD cbSid,
2497 LPSTR ReferencedDomainName,
2498 IN OUT LPDWORD cbReferencedDomainName,
2499 OUT PSID_NAME_USE name_use )
2501 BOOL ret;
2502 UNICODE_STRING lpSystemW;
2503 UNICODE_STRING lpAccountW;
2504 LPWSTR lpReferencedDomainNameW = NULL;
2506 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2507 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2509 if (ReferencedDomainName)
2510 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2512 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2513 cbReferencedDomainName, name_use);
2515 if (ret && lpReferencedDomainNameW)
2517 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2518 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2521 RtlFreeUnicodeString(&lpSystemW);
2522 RtlFreeUnicodeString(&lpAccountW);
2523 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2525 return ret;
2528 /******************************************************************************
2529 * LookupAccountNameW [ADVAPI32.@]
2531 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2532 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2533 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2535 /* Default implementation: Always return a default SID */
2536 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2537 BOOL ret;
2538 PSID pSid;
2539 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2540 unsigned int i;
2541 DWORD nameLen;
2542 LPWSTR userName = NULL;
2543 LPCWSTR domainName;
2545 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2546 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2548 if (!ADVAPI_IsLocalComputer(lpSystemName))
2550 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2551 return FALSE;
2554 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2556 lpAccountName = BUILTIN;
2559 /* Check well known SIDs first */
2561 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2563 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2565 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2567 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2569 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2571 if (ret)
2573 if (*cbSid < sidLen)
2575 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2576 ret = FALSE;
2578 else if (Sid)
2580 CopySid(*cbSid, Sid, pSid);
2583 *cbSid = sidLen;
2586 domainName = ACCOUNT_SIDS[i].domain;
2587 nameLen = strlenW(domainName);
2589 if (*cchReferencedDomainName <= nameLen || !ret)
2591 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2592 nameLen += 1;
2593 ret = FALSE;
2595 else if (ReferencedDomainName && domainName)
2597 strcpyW(ReferencedDomainName, domainName);
2600 *cchReferencedDomainName = nameLen;
2602 if (ret)
2604 *peUse = ACCOUNT_SIDS[i].name_use;
2607 HeapFree(GetProcessHeap(), 0, pSid);
2609 return ret;
2613 /* Let the current Unix user id masquerade as first Windows user account */
2615 nameLen = UNLEN + 1;
2617 userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2619 ret = GetUserNameW(userName, &nameLen);
2621 if (ret && strcmpW(lpAccountName, userName) != 0)
2623 SetLastError(ERROR_NONE_MAPPED);
2624 ret = FALSE;
2627 HeapFree(GetProcessHeap(), 0, userName);
2629 if (!ret)
2631 return ret;
2634 ret = AllocateAndInitializeSid(&identifierAuthority,
2636 SECURITY_BUILTIN_DOMAIN_RID,
2637 DOMAIN_ALIAS_RID_ADMINS,
2638 0, 0, 0, 0, 0, 0,
2639 &pSid);
2641 if (!ret)
2642 return FALSE;
2644 if (!RtlValidSid(pSid))
2646 FreeSid(pSid);
2647 return FALSE;
2650 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2651 CopySid(*cbSid, Sid, pSid);
2652 if (*cbSid < GetLengthSid(pSid))
2654 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2655 ret = FALSE;
2657 *cbSid = GetLengthSid(pSid);
2659 domainName = dm;
2660 nameLen = strlenW(domainName);
2662 if (*cchReferencedDomainName <= nameLen || !ret)
2664 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2665 nameLen += 1;
2666 ret = FALSE;
2668 else if (ReferencedDomainName)
2670 strcpyW(ReferencedDomainName, domainName);
2673 *cchReferencedDomainName = nameLen;
2675 if (ret)
2677 *peUse = SidTypeUser;
2680 FreeSid(pSid);
2682 return ret;
2685 /******************************************************************************
2686 * PrivilegeCheck [ADVAPI32.@]
2688 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2690 BOOL ret;
2691 BOOLEAN Result;
2693 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2695 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2696 if (ret)
2697 *pfResult = Result;
2698 return ret;
2701 /******************************************************************************
2702 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2704 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2705 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2706 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2707 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2709 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2710 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2711 SecurityDescriptor, DesiredAccess, GenericMapping,
2712 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2713 return TRUE;
2716 /******************************************************************************
2717 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2719 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2720 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2721 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2722 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2724 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2725 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2726 SecurityDescriptor, DesiredAccess, GenericMapping,
2727 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2728 return TRUE;
2731 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2733 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2735 return TRUE;
2738 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2740 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2742 return TRUE;
2745 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2747 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2749 return TRUE;
2752 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2753 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2754 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2755 LPBOOL GenerateOnClose)
2757 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2758 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2759 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2760 GenerateOnClose);
2762 return TRUE;
2765 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2766 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2767 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2768 LPBOOL GenerateOnClose)
2770 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2771 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2772 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2773 GenerateOnClose);
2775 return TRUE;
2778 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2779 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2781 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2782 DesiredAccess, Privileges, AccessGranted);
2784 return TRUE;
2787 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2788 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2790 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2791 DesiredAccess, Privileges, AccessGranted);
2793 return TRUE;
2796 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2797 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2799 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2800 ClientToken, Privileges, AccessGranted);
2802 return TRUE;
2805 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2806 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2808 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2809 ClientToken, Privileges, AccessGranted);
2811 return TRUE;
2814 /******************************************************************************
2815 * GetSecurityInfo [ADVAPI32.@]
2817 * Retrieves a copy of the security descriptor associated with an object.
2819 * PARAMS
2820 * hObject [I] A handle for the object.
2821 * ObjectType [I] The type of object.
2822 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2823 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2824 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2825 * ppDacl [O] If non-null, receives a pointer to the DACL.
2826 * ppSacl [O] If non-null, receives a pointer to the SACL.
2827 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2828 * which must be freed with LocalFree.
2830 * RETURNS
2831 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2833 DWORD WINAPI GetSecurityInfo(
2834 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2835 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2836 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2837 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2840 PSECURITY_DESCRIPTOR sd;
2841 NTSTATUS status;
2842 ULONG n1, n2;
2843 BOOL present, defaulted;
2845 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2846 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2847 return RtlNtStatusToDosError(status);
2849 sd = LocalAlloc(0, n1);
2850 if (!sd)
2851 return ERROR_NOT_ENOUGH_MEMORY;
2853 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2854 if (status != STATUS_SUCCESS)
2856 LocalFree(sd);
2857 return RtlNtStatusToDosError(status);
2860 if (ppsidOwner)
2862 *ppsidOwner = NULL;
2863 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2865 if (ppsidGroup)
2867 *ppsidGroup = NULL;
2868 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2870 if (ppDacl)
2872 *ppDacl = NULL;
2873 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2875 if (ppSacl)
2877 *ppSacl = NULL;
2878 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2880 if (ppSecurityDescriptor)
2881 *ppSecurityDescriptor = sd;
2883 return ERROR_SUCCESS;
2886 /******************************************************************************
2887 * GetSecurityInfoExW [ADVAPI32.@]
2889 DWORD WINAPI GetSecurityInfoExW(
2890 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2891 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2892 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2893 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2896 FIXME("stub!\n");
2897 return ERROR_BAD_PROVIDER;
2900 /******************************************************************************
2901 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2903 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2904 LPSTR pTrusteeName, DWORD AccessPermissions,
2905 ACCESS_MODE AccessMode, DWORD Inheritance )
2907 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2908 AccessPermissions, AccessMode, Inheritance);
2910 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2911 pExplicitAccess->grfAccessMode = AccessMode;
2912 pExplicitAccess->grfInheritance = Inheritance;
2914 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2915 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2916 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2917 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2918 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2921 /******************************************************************************
2922 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2924 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2925 LPWSTR pTrusteeName, DWORD AccessPermissions,
2926 ACCESS_MODE AccessMode, DWORD Inheritance )
2928 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2929 AccessPermissions, AccessMode, Inheritance);
2931 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2932 pExplicitAccess->grfAccessMode = AccessMode;
2933 pExplicitAccess->grfInheritance = Inheritance;
2935 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2936 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2937 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2938 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2939 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2942 /******************************************************************************
2943 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2945 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2946 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2947 LPSTR InheritedObjectTypeName, LPSTR Name )
2949 DWORD ObjectsPresent = 0;
2951 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2952 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2954 /* Fill the OBJECTS_AND_NAME structure */
2955 pObjName->ObjectType = ObjectType;
2956 if (ObjectTypeName != NULL)
2958 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2961 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2962 if (InheritedObjectTypeName != NULL)
2964 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2967 pObjName->ObjectsPresent = ObjectsPresent;
2968 pObjName->ptstrName = Name;
2970 /* Fill the TRUSTEE structure */
2971 pTrustee->pMultipleTrustee = NULL;
2972 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2973 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2974 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2975 pTrustee->ptstrName = (LPSTR)pObjName;
2978 /******************************************************************************
2979 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2981 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2982 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2983 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2985 DWORD ObjectsPresent = 0;
2987 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2988 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2990 /* Fill the OBJECTS_AND_NAME structure */
2991 pObjName->ObjectType = ObjectType;
2992 if (ObjectTypeName != NULL)
2994 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2997 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2998 if (InheritedObjectTypeName != NULL)
3000 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3003 pObjName->ObjectsPresent = ObjectsPresent;
3004 pObjName->ptstrName = Name;
3006 /* Fill the TRUSTEE structure */
3007 pTrustee->pMultipleTrustee = NULL;
3008 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3009 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3010 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3011 pTrustee->ptstrName = (LPWSTR)pObjName;
3014 /******************************************************************************
3015 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3017 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3018 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3020 DWORD ObjectsPresent = 0;
3022 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3024 /* Fill the OBJECTS_AND_SID structure */
3025 if (pObjectGuid != NULL)
3027 pObjSid->ObjectTypeGuid = *pObjectGuid;
3028 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3030 else
3032 ZeroMemory(&pObjSid->ObjectTypeGuid,
3033 sizeof(GUID));
3036 if (pInheritedObjectGuid != NULL)
3038 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3039 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3041 else
3043 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3044 sizeof(GUID));
3047 pObjSid->ObjectsPresent = ObjectsPresent;
3048 pObjSid->pSid = pSid;
3050 /* Fill the TRUSTEE structure */
3051 pTrustee->pMultipleTrustee = NULL;
3052 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3053 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3054 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3055 pTrustee->ptstrName = (LPSTR) pObjSid;
3058 /******************************************************************************
3059 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3061 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3062 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3064 DWORD ObjectsPresent = 0;
3066 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3068 /* Fill the OBJECTS_AND_SID structure */
3069 if (pObjectGuid != NULL)
3071 pObjSid->ObjectTypeGuid = *pObjectGuid;
3072 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3074 else
3076 ZeroMemory(&pObjSid->ObjectTypeGuid,
3077 sizeof(GUID));
3080 if (pInheritedObjectGuid != NULL)
3082 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3083 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3085 else
3087 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3088 sizeof(GUID));
3091 pObjSid->ObjectsPresent = ObjectsPresent;
3092 pObjSid->pSid = pSid;
3094 /* Fill the TRUSTEE structure */
3095 pTrustee->pMultipleTrustee = NULL;
3096 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3097 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3098 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3099 pTrustee->ptstrName = (LPWSTR) pObjSid;
3102 /******************************************************************************
3103 * BuildTrusteeWithSidA [ADVAPI32.@]
3105 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3107 TRACE("%p %p\n", pTrustee, pSid);
3109 pTrustee->pMultipleTrustee = NULL;
3110 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3111 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3112 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3113 pTrustee->ptstrName = (LPSTR) pSid;
3116 /******************************************************************************
3117 * BuildTrusteeWithSidW [ADVAPI32.@]
3119 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3121 TRACE("%p %p\n", pTrustee, pSid);
3123 pTrustee->pMultipleTrustee = NULL;
3124 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3125 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3126 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3127 pTrustee->ptstrName = (LPWSTR) pSid;
3130 /******************************************************************************
3131 * BuildTrusteeWithNameA [ADVAPI32.@]
3133 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3135 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3137 pTrustee->pMultipleTrustee = NULL;
3138 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3139 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3140 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3141 pTrustee->ptstrName = name;
3144 /******************************************************************************
3145 * BuildTrusteeWithNameW [ADVAPI32.@]
3147 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3149 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3151 pTrustee->pMultipleTrustee = NULL;
3152 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3153 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3154 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3155 pTrustee->ptstrName = name;
3158 /******************************************************************************
3159 * GetTrusteeFormA [ADVAPI32.@]
3161 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3163 TRACE("(%p)\n", pTrustee);
3165 if (!pTrustee)
3166 return TRUSTEE_BAD_FORM;
3168 return pTrustee->TrusteeForm;
3171 /******************************************************************************
3172 * GetTrusteeFormW [ADVAPI32.@]
3174 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3176 TRACE("(%p)\n", pTrustee);
3178 if (!pTrustee)
3179 return TRUSTEE_BAD_FORM;
3181 return pTrustee->TrusteeForm;
3184 /******************************************************************************
3185 * GetTrusteeNameA [ADVAPI32.@]
3187 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3189 TRACE("(%p)\n", pTrustee);
3191 if (!pTrustee)
3192 return NULL;
3194 return pTrustee->ptstrName;
3197 /******************************************************************************
3198 * GetTrusteeNameW [ADVAPI32.@]
3200 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3202 TRACE("(%p)\n", pTrustee);
3204 if (!pTrustee)
3205 return NULL;
3207 return pTrustee->ptstrName;
3210 /******************************************************************************
3211 * GetTrusteeTypeA [ADVAPI32.@]
3213 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3215 TRACE("(%p)\n", pTrustee);
3217 if (!pTrustee)
3218 return TRUSTEE_IS_UNKNOWN;
3220 return pTrustee->TrusteeType;
3223 /******************************************************************************
3224 * GetTrusteeTypeW [ADVAPI32.@]
3226 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3228 TRACE("(%p)\n", pTrustee);
3230 if (!pTrustee)
3231 return TRUSTEE_IS_UNKNOWN;
3233 return pTrustee->TrusteeType;
3236 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3237 DWORD nAclInformationLength,
3238 ACL_INFORMATION_CLASS dwAclInformationClass )
3240 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3241 nAclInformationLength, dwAclInformationClass);
3243 return TRUE;
3246 /******************************************************************************
3247 * SetEntriesInAclA [ADVAPI32.@]
3249 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3250 PACL OldAcl, PACL* NewAcl )
3252 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3253 if (NewAcl)
3254 *NewAcl = NULL;
3255 return ERROR_SUCCESS;
3258 /******************************************************************************
3259 * SetEntriesInAclW [ADVAPI32.@]
3261 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3262 PACL OldAcl, PACL* NewAcl )
3264 ULONG i;
3265 PSID *ppsid;
3266 DWORD ret = ERROR_SUCCESS;
3267 DWORD acl_size = sizeof(ACL);
3268 NTSTATUS status;
3270 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3272 *NewAcl = NULL;
3274 if (!count && !OldAcl)
3275 return ERROR_SUCCESS;
3277 /* allocate array of maximum sized sids allowed */
3278 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3279 if (!ppsid)
3280 return ERROR_OUTOFMEMORY;
3282 for (i = 0; i < count; i++)
3284 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3286 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3287 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3288 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3289 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3290 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3291 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3292 pEntries[i].Trustee.ptstrName);
3294 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3296 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3297 ret = ERROR_INVALID_PARAMETER;
3298 goto exit;
3301 switch (pEntries[i].Trustee.TrusteeForm)
3303 case TRUSTEE_IS_SID:
3304 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3305 ppsid[i], pEntries[i].Trustee.ptstrName))
3307 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3308 ret = ERROR_INVALID_PARAMETER;
3309 goto exit;
3311 break;
3312 case TRUSTEE_IS_NAME:
3314 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3315 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3316 SID_NAME_USE use;
3317 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3319 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3320 ret = ERROR_INVALID_PARAMETER;
3321 goto exit;
3323 break;
3325 case TRUSTEE_IS_OBJECTS_AND_SID:
3326 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3327 break;
3328 case TRUSTEE_IS_OBJECTS_AND_NAME:
3329 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3330 break;
3331 default:
3332 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3333 ret = ERROR_INVALID_PARAMETER;
3334 goto exit;
3337 /* Note: we overestimate the ACL size here as a tradeoff between
3338 * instructions (simplicity) and memory */
3339 switch (pEntries[i].grfAccessMode)
3341 case GRANT_ACCESS:
3342 case SET_ACCESS:
3343 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3344 break;
3345 case DENY_ACCESS:
3346 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3347 break;
3348 case SET_AUDIT_SUCCESS:
3349 case SET_AUDIT_FAILURE:
3350 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3351 break;
3352 case REVOKE_ACCESS:
3353 break;
3354 default:
3355 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3356 ret = ERROR_INVALID_PARAMETER;
3357 goto exit;
3361 if (OldAcl)
3363 ACL_SIZE_INFORMATION size_info;
3365 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3366 if (status != STATUS_SUCCESS)
3368 ret = RtlNtStatusToDosError(status);
3369 goto exit;
3371 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3374 *NewAcl = LocalAlloc(0, acl_size);
3375 if (!*NewAcl)
3377 ret = ERROR_OUTOFMEMORY;
3378 goto exit;
3381 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3382 if (status != STATUS_SUCCESS)
3384 ret = RtlNtStatusToDosError(status);
3385 goto exit;
3388 for (i = 0; i < count; i++)
3390 switch (pEntries[i].grfAccessMode)
3392 case GRANT_ACCESS:
3393 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3394 pEntries[i].grfInheritance,
3395 pEntries[i].grfAccessPermissions,
3396 ppsid[i]);
3397 break;
3398 case SET_ACCESS:
3400 ULONG j;
3401 BOOL add = TRUE;
3402 if (OldAcl)
3404 for (j = 0; ; j++)
3406 const ACE_HEADER *existing_ace_header;
3407 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3408 if (status != STATUS_SUCCESS)
3409 break;
3410 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3411 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3412 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3414 add = FALSE;
3415 break;
3419 if (add)
3420 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3421 pEntries[i].grfInheritance,
3422 pEntries[i].grfAccessPermissions,
3423 ppsid[i]);
3424 break;
3426 case DENY_ACCESS:
3427 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3428 pEntries[i].grfInheritance,
3429 pEntries[i].grfAccessPermissions,
3430 ppsid[i]);
3431 break;
3432 case SET_AUDIT_SUCCESS:
3433 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3434 pEntries[i].grfInheritance,
3435 pEntries[i].grfAccessPermissions,
3436 ppsid[i], TRUE, FALSE);
3437 break;
3438 case SET_AUDIT_FAILURE:
3439 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3440 pEntries[i].grfInheritance,
3441 pEntries[i].grfAccessPermissions,
3442 ppsid[i], FALSE, TRUE);
3443 break;
3444 default:
3445 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3449 if (OldAcl)
3451 for (i = 0; ; i++)
3453 BOOL add = TRUE;
3454 ULONG j;
3455 const ACE_HEADER *old_ace_header;
3456 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3457 if (status != STATUS_SUCCESS) break;
3458 for (j = 0; j < count; j++)
3460 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3461 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3462 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3464 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3465 add = FALSE;
3466 break;
3468 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3470 switch (old_ace_header->AceType)
3472 case ACCESS_ALLOWED_ACE_TYPE:
3473 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3474 add = FALSE;
3475 break;
3476 case ACCESS_DENIED_ACE_TYPE:
3477 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3478 add = FALSE;
3479 break;
3480 case SYSTEM_AUDIT_ACE_TYPE:
3481 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3482 add = FALSE;
3483 break;
3484 case SYSTEM_ALARM_ACE_TYPE:
3485 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3486 add = FALSE;
3487 break;
3488 default:
3489 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3492 if (!add)
3493 break;
3496 if (add)
3497 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3498 if (status != STATUS_SUCCESS)
3500 WARN("RtlAddAce failed with error 0x%08x\n", status);
3501 ret = RtlNtStatusToDosError(status);
3502 break;
3507 exit:
3508 HeapFree(GetProcessHeap(), 0, ppsid);
3509 return ret;
3512 /******************************************************************************
3513 * SetNamedSecurityInfoA [ADVAPI32.@]
3515 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3516 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3517 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3519 DWORD len;
3520 LPWSTR wstr = NULL;
3521 DWORD r;
3523 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3524 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3526 if( pObjectName )
3528 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3529 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3530 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3533 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3534 psidGroup, pDacl, pSacl );
3536 HeapFree( GetProcessHeap(), 0, wstr );
3538 return r;
3541 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3542 PSECURITY_DESCRIPTOR ModificationDescriptor,
3543 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3544 PGENERIC_MAPPING GenericMapping,
3545 HANDLE Token )
3547 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3548 ObjectsSecurityDescriptor, GenericMapping, Token);
3550 return TRUE;
3553 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3555 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3558 /******************************************************************************
3559 * AreAnyAccessesGranted [ADVAPI32.@]
3561 * Determines whether or not any of a set of specified access permissions have
3562 * been granted or not.
3564 * PARAMS
3565 * GrantedAccess [I] The permissions that have been granted.
3566 * DesiredAccess [I] The permissions that you want to have.
3568 * RETURNS
3569 * Nonzero if any of the permissions have been granted, zero if none of the
3570 * permissions have been granted.
3573 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3575 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3578 /******************************************************************************
3579 * SetNamedSecurityInfoW [ADVAPI32.@]
3581 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3582 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3583 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3585 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3586 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3587 return ERROR_SUCCESS;
3590 /******************************************************************************
3591 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3593 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3594 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3596 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3597 return ERROR_CALL_NOT_IMPLEMENTED;
3600 /******************************************************************************
3601 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3603 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3604 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3606 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3607 return ERROR_CALL_NOT_IMPLEMENTED;
3610 /******************************************************************************
3611 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3613 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3614 PACCESS_MASK pFailedAuditRights)
3616 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3617 return ERROR_CALL_NOT_IMPLEMENTED;
3621 /******************************************************************************
3622 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3624 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3625 PACCESS_MASK pFailedAuditRights)
3627 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3628 return ERROR_CALL_NOT_IMPLEMENTED;
3632 /******************************************************************************
3633 * ParseAclStringFlags
3635 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3637 DWORD flags = 0;
3638 LPCWSTR szAcl = *StringAcl;
3640 while (*szAcl != '(')
3642 if (*szAcl == 'P')
3644 flags |= SE_DACL_PROTECTED;
3646 else if (*szAcl == 'A')
3648 szAcl++;
3649 if (*szAcl == 'R')
3650 flags |= SE_DACL_AUTO_INHERIT_REQ;
3651 else if (*szAcl == 'I')
3652 flags |= SE_DACL_AUTO_INHERITED;
3654 szAcl++;
3657 *StringAcl = szAcl;
3658 return flags;
3661 /******************************************************************************
3662 * ParseAceStringType
3664 static const ACEFLAG AceType[] =
3666 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3667 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3668 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3669 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3671 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3672 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3673 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3674 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3676 { NULL, 0 },
3679 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3681 UINT len = 0;
3682 LPCWSTR szAcl = *StringAcl;
3683 const ACEFLAG *lpaf = AceType;
3685 while (lpaf->wstr &&
3686 (len = strlenW(lpaf->wstr)) &&
3687 strncmpW(lpaf->wstr, szAcl, len))
3688 lpaf++;
3690 if (!lpaf->wstr)
3691 return 0;
3693 *StringAcl += len;
3694 return lpaf->value;
3698 /******************************************************************************
3699 * ParseAceStringFlags
3701 static const ACEFLAG AceFlags[] =
3703 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3704 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3705 { SDDL_INHERITED, INHERITED_ACE },
3706 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3707 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3708 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3709 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3710 { NULL, 0 },
3713 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3715 UINT len = 0;
3716 BYTE flags = 0;
3717 LPCWSTR szAcl = *StringAcl;
3719 while (*szAcl != ';')
3721 const ACEFLAG *lpaf = AceFlags;
3723 while (lpaf->wstr &&
3724 (len = strlenW(lpaf->wstr)) &&
3725 strncmpW(lpaf->wstr, szAcl, len))
3726 lpaf++;
3728 if (!lpaf->wstr)
3729 return 0;
3731 flags |= lpaf->value;
3732 szAcl += len;
3735 *StringAcl = szAcl;
3736 return flags;
3740 /******************************************************************************
3741 * ParseAceStringRights
3743 static const ACEFLAG AceRights[] =
3745 { SDDL_GENERIC_ALL, GENERIC_ALL },
3746 { SDDL_GENERIC_READ, GENERIC_READ },
3747 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3748 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3750 { SDDL_READ_CONTROL, READ_CONTROL },
3751 { SDDL_STANDARD_DELETE, DELETE },
3752 { SDDL_WRITE_DAC, WRITE_DAC },
3753 { SDDL_WRITE_OWNER, WRITE_OWNER },
3755 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3756 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3757 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3758 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3759 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3760 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3761 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3762 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3763 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3765 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3766 { SDDL_FILE_READ, FILE_GENERIC_READ },
3767 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3768 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3770 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3771 { SDDL_KEY_READ, KEY_READ },
3772 { SDDL_KEY_WRITE, KEY_WRITE },
3773 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3774 { NULL, 0 },
3777 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3779 UINT len = 0;
3780 DWORD rights = 0;
3781 LPCWSTR szAcl = *StringAcl;
3783 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3785 LPCWSTR p = szAcl;
3787 while (*p && *p != ';')
3788 p++;
3790 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3792 rights = strtoulW(szAcl, NULL, 16);
3793 szAcl = p;
3795 else
3796 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3798 else
3800 while (*szAcl != ';')
3802 const ACEFLAG *lpaf = AceRights;
3804 while (lpaf->wstr &&
3805 (len = strlenW(lpaf->wstr)) &&
3806 strncmpW(lpaf->wstr, szAcl, len))
3808 lpaf++;
3811 if (!lpaf->wstr)
3812 return 0;
3814 rights |= lpaf->value;
3815 szAcl += len;
3819 *StringAcl = szAcl;
3820 return rights;
3824 /******************************************************************************
3825 * ParseStringAclToAcl
3827 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3829 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3830 PACL pAcl, LPDWORD cBytes)
3832 DWORD val;
3833 DWORD sidlen;
3834 DWORD length = sizeof(ACL);
3835 DWORD acesize = 0;
3836 DWORD acecount = 0;
3837 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3839 TRACE("%s\n", debugstr_w(StringAcl));
3841 if (!StringAcl)
3842 return FALSE;
3844 if (pAcl) /* pAce is only useful if we're setting values */
3845 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3847 /* Parse ACL flags */
3848 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3850 /* Parse ACE */
3851 while (*StringAcl == '(')
3853 StringAcl++;
3855 /* Parse ACE type */
3856 val = ParseAceStringType(&StringAcl);
3857 if (pAce)
3858 pAce->Header.AceType = (BYTE) val;
3859 if (*StringAcl != ';')
3860 goto lerr;
3861 StringAcl++;
3863 /* Parse ACE flags */
3864 val = ParseAceStringFlags(&StringAcl);
3865 if (pAce)
3866 pAce->Header.AceFlags = (BYTE) val;
3867 if (*StringAcl != ';')
3868 goto lerr;
3869 StringAcl++;
3871 /* Parse ACE rights */
3872 val = ParseAceStringRights(&StringAcl);
3873 if (pAce)
3874 pAce->Mask = val;
3875 if (*StringAcl != ';')
3876 goto lerr;
3877 StringAcl++;
3879 /* Parse ACE object guid */
3880 if (*StringAcl != ';')
3882 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3883 goto lerr;
3885 StringAcl++;
3887 /* Parse ACE inherit object guid */
3888 if (*StringAcl != ';')
3890 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3891 goto lerr;
3893 StringAcl++;
3895 /* Parse ACE account sid */
3896 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3898 while (*StringAcl && *StringAcl != ')')
3899 StringAcl++;
3902 if (*StringAcl != ')')
3903 goto lerr;
3904 StringAcl++;
3906 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3907 length += acesize;
3908 if (pAce)
3910 pAce->Header.AceSize = acesize;
3911 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3913 acecount++;
3916 *cBytes = length;
3918 if (length > 0xffff)
3920 ERR("ACL too large\n");
3921 goto lerr;
3924 if (pAcl)
3926 pAcl->AclRevision = ACL_REVISION;
3927 pAcl->Sbz1 = 0;
3928 pAcl->AclSize = length;
3929 pAcl->AceCount = acecount++;
3930 pAcl->Sbz2 = 0;
3932 return TRUE;
3934 lerr:
3935 SetLastError(ERROR_INVALID_ACL);
3936 WARN("Invalid ACE string format\n");
3937 return FALSE;
3941 /******************************************************************************
3942 * ParseStringSecurityDescriptorToSecurityDescriptor
3944 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3945 LPCWSTR StringSecurityDescriptor,
3946 SECURITY_DESCRIPTOR* SecurityDescriptor,
3947 LPDWORD cBytes)
3949 BOOL bret = FALSE;
3950 WCHAR toktype;
3951 WCHAR tok[MAX_PATH];
3952 LPCWSTR lptoken;
3953 LPBYTE lpNext = NULL;
3954 DWORD len;
3956 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3958 if (SecurityDescriptor)
3959 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3961 while (*StringSecurityDescriptor)
3963 toktype = *StringSecurityDescriptor;
3965 /* Expect char identifier followed by ':' */
3966 StringSecurityDescriptor++;
3967 if (*StringSecurityDescriptor != ':')
3969 SetLastError(ERROR_INVALID_PARAMETER);
3970 goto lend;
3972 StringSecurityDescriptor++;
3974 /* Extract token */
3975 lptoken = StringSecurityDescriptor;
3976 while (*lptoken && *lptoken != ':')
3977 lptoken++;
3979 if (*lptoken)
3980 lptoken--;
3982 len = lptoken - StringSecurityDescriptor;
3983 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3984 tok[len] = 0;
3986 switch (toktype)
3988 case 'O':
3990 DWORD bytes;
3992 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3993 goto lend;
3995 if (SecurityDescriptor)
3997 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3998 lpNext += bytes; /* Advance to next token */
4001 *cBytes += bytes;
4003 break;
4006 case 'G':
4008 DWORD bytes;
4010 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4011 goto lend;
4013 if (SecurityDescriptor)
4015 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4016 lpNext += bytes; /* Advance to next token */
4019 *cBytes += bytes;
4021 break;
4024 case 'D':
4026 DWORD flags;
4027 DWORD bytes;
4029 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4030 goto lend;
4032 if (SecurityDescriptor)
4034 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4035 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4036 lpNext += bytes; /* Advance to next token */
4039 *cBytes += bytes;
4041 break;
4044 case 'S':
4046 DWORD flags;
4047 DWORD bytes;
4049 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4050 goto lend;
4052 if (SecurityDescriptor)
4054 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4055 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4056 lpNext += bytes; /* Advance to next token */
4059 *cBytes += bytes;
4061 break;
4064 default:
4065 FIXME("Unknown token\n");
4066 SetLastError(ERROR_INVALID_PARAMETER);
4067 goto lend;
4070 StringSecurityDescriptor = lptoken;
4073 bret = TRUE;
4075 lend:
4076 return bret;
4079 /******************************************************************************
4080 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4082 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4083 LPCSTR StringSecurityDescriptor,
4084 DWORD StringSDRevision,
4085 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4086 PULONG SecurityDescriptorSize)
4088 UINT len;
4089 BOOL ret = FALSE;
4090 LPWSTR StringSecurityDescriptorW;
4092 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4093 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4095 if (StringSecurityDescriptorW)
4097 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4099 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4100 StringSDRevision, SecurityDescriptor,
4101 SecurityDescriptorSize);
4102 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4105 return ret;
4108 /******************************************************************************
4109 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4111 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4112 LPCWSTR StringSecurityDescriptor,
4113 DWORD StringSDRevision,
4114 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4115 PULONG SecurityDescriptorSize)
4117 DWORD cBytes;
4118 SECURITY_DESCRIPTOR* psd;
4119 BOOL bret = FALSE;
4121 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4123 if (GetVersion() & 0x80000000)
4125 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4126 goto lend;
4128 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4130 SetLastError(ERROR_INVALID_PARAMETER);
4131 goto lend;
4133 else if (StringSDRevision != SID_REVISION)
4135 SetLastError(ERROR_UNKNOWN_REVISION);
4136 goto lend;
4139 /* Compute security descriptor length */
4140 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4141 NULL, &cBytes))
4142 goto lend;
4144 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4145 GMEM_ZEROINIT, cBytes);
4146 if (!psd) goto lend;
4148 psd->Revision = SID_REVISION;
4149 psd->Control |= SE_SELF_RELATIVE;
4151 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4152 psd, &cBytes))
4154 LocalFree(psd);
4155 goto lend;
4158 if (SecurityDescriptorSize)
4159 *SecurityDescriptorSize = cBytes;
4161 bret = TRUE;
4163 lend:
4164 TRACE(" ret=%d\n", bret);
4165 return bret;
4168 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4170 if (cch == -1)
4171 cch = strlenW(string);
4173 if (plen)
4174 *plen += cch;
4176 if (pwptr)
4178 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4179 *pwptr += cch;
4183 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4185 DWORD i;
4186 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4187 WCHAR subauthfmt[] = { '-','%','u',0 };
4188 WCHAR buf[26];
4189 SID *pisid = psid;
4191 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4193 SetLastError(ERROR_INVALID_SID);
4194 return FALSE;
4197 if (pisid->IdentifierAuthority.Value[0] ||
4198 pisid->IdentifierAuthority.Value[1])
4200 FIXME("not matching MS' bugs\n");
4201 SetLastError(ERROR_INVALID_SID);
4202 return FALSE;
4205 sprintfW( buf, fmt, pisid->Revision,
4206 MAKELONG(
4207 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4208 pisid->IdentifierAuthority.Value[4] ),
4209 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4210 pisid->IdentifierAuthority.Value[2] )
4211 ) );
4212 DumpString(buf, -1, pwptr, plen);
4214 for( i=0; i<pisid->SubAuthorityCount; i++ )
4216 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4217 DumpString(buf, -1, pwptr, plen);
4219 return TRUE;
4222 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4224 size_t i;
4225 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4227 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4229 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4230 return TRUE;
4234 return DumpSidNumeric(psid, pwptr, plen);
4237 static const LPCWSTR AceRightBitNames[32] = {
4238 SDDL_CREATE_CHILD, /* 0 */
4239 SDDL_DELETE_CHILD,
4240 SDDL_LIST_CHILDREN,
4241 SDDL_SELF_WRITE,
4242 SDDL_READ_PROPERTY, /* 4 */
4243 SDDL_WRITE_PROPERTY,
4244 SDDL_DELETE_TREE,
4245 SDDL_LIST_OBJECT,
4246 SDDL_CONTROL_ACCESS, /* 8 */
4247 NULL,
4248 NULL,
4249 NULL,
4250 NULL, /* 12 */
4251 NULL,
4252 NULL,
4253 NULL,
4254 SDDL_STANDARD_DELETE, /* 16 */
4255 SDDL_READ_CONTROL,
4256 SDDL_WRITE_DAC,
4257 SDDL_WRITE_OWNER,
4258 NULL, /* 20 */
4259 NULL,
4260 NULL,
4261 NULL,
4262 NULL, /* 24 */
4263 NULL,
4264 NULL,
4265 NULL,
4266 SDDL_GENERIC_ALL, /* 28 */
4267 SDDL_GENERIC_EXECUTE,
4268 SDDL_GENERIC_WRITE,
4269 SDDL_GENERIC_READ
4272 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4274 static const WCHAR fmtW[] = {'0','x','%','x',0};
4275 WCHAR buf[15];
4276 size_t i;
4278 if (mask == 0)
4279 return;
4281 /* first check if the right have name */
4282 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4284 if (AceRights[i].wstr == NULL)
4285 break;
4286 if (mask == AceRights[i].value)
4288 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4289 return;
4293 /* then check if it can be built from bit names */
4294 for (i = 0; i < 32; i++)
4296 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4298 /* can't be built from bit names */
4299 sprintfW(buf, fmtW, mask);
4300 DumpString(buf, -1, pwptr, plen);
4301 return;
4305 /* build from bit names */
4306 for (i = 0; i < 32; i++)
4307 if (mask & (1 << i))
4308 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4311 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4313 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4314 static const WCHAR openbr = '(';
4315 static const WCHAR closebr = ')';
4316 static const WCHAR semicolon = ';';
4318 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4320 SetLastError(ERROR_INVALID_ACL);
4321 return FALSE;
4324 piace = (ACCESS_ALLOWED_ACE *)pace;
4325 DumpString(&openbr, 1, pwptr, plen);
4326 switch (piace->Header.AceType)
4328 case ACCESS_ALLOWED_ACE_TYPE:
4329 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4330 break;
4331 case ACCESS_DENIED_ACE_TYPE:
4332 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4333 break;
4334 case SYSTEM_AUDIT_ACE_TYPE:
4335 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4336 break;
4337 case SYSTEM_ALARM_ACE_TYPE:
4338 DumpString(SDDL_ALARM, -1, pwptr, plen);
4339 break;
4341 DumpString(&semicolon, 1, pwptr, plen);
4343 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4344 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4345 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4346 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4347 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4348 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4349 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4350 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4351 if (piace->Header.AceFlags & INHERITED_ACE)
4352 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4353 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4354 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4355 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4356 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4357 DumpString(&semicolon, 1, pwptr, plen);
4358 DumpRights(piace->Mask, pwptr, plen);
4359 DumpString(&semicolon, 1, pwptr, plen);
4360 /* objects not supported */
4361 DumpString(&semicolon, 1, pwptr, plen);
4362 /* objects not supported */
4363 DumpString(&semicolon, 1, pwptr, plen);
4364 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4365 return FALSE;
4366 DumpString(&closebr, 1, pwptr, plen);
4367 return TRUE;
4370 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4372 WORD count;
4373 int i;
4375 if (protected)
4376 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4377 if (autoInheritReq)
4378 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4379 if (autoInherited)
4380 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4382 if (pacl == NULL)
4383 return TRUE;
4385 if (!IsValidAcl(pacl))
4386 return FALSE;
4388 count = pacl->AceCount;
4389 for (i = 0; i < count; i++)
4391 LPVOID ace;
4392 if (!GetAce(pacl, i, &ace))
4393 return FALSE;
4394 if (!DumpAce(ace, pwptr, plen))
4395 return FALSE;
4398 return TRUE;
4401 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4403 static const WCHAR prefix[] = {'O',':',0};
4404 BOOL bDefaulted;
4405 PSID psid;
4407 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4408 return FALSE;
4410 if (psid == NULL)
4411 return TRUE;
4413 DumpString(prefix, -1, pwptr, plen);
4414 if (!DumpSid(psid, pwptr, plen))
4415 return FALSE;
4416 return TRUE;
4419 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4421 static const WCHAR prefix[] = {'G',':',0};
4422 BOOL bDefaulted;
4423 PSID psid;
4425 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4426 return FALSE;
4428 if (psid == NULL)
4429 return TRUE;
4431 DumpString(prefix, -1, pwptr, plen);
4432 if (!DumpSid(psid, pwptr, plen))
4433 return FALSE;
4434 return TRUE;
4437 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4439 static const WCHAR dacl[] = {'D',':',0};
4440 SECURITY_DESCRIPTOR_CONTROL control;
4441 BOOL present, defaulted;
4442 DWORD revision;
4443 PACL pacl;
4445 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4446 return FALSE;
4448 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4449 return FALSE;
4451 if (!present)
4452 return TRUE;
4454 DumpString(dacl, 2, pwptr, plen);
4455 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4456 return FALSE;
4457 return TRUE;
4460 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4462 static const WCHAR sacl[] = {'S',':',0};
4463 SECURITY_DESCRIPTOR_CONTROL control;
4464 BOOL present, defaulted;
4465 DWORD revision;
4466 PACL pacl;
4468 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4469 return FALSE;
4471 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4472 return FALSE;
4474 if (!present)
4475 return TRUE;
4477 DumpString(sacl, 2, pwptr, plen);
4478 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4479 return FALSE;
4480 return TRUE;
4483 /******************************************************************************
4484 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4486 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4488 ULONG len;
4489 WCHAR *wptr, *wstr;
4491 if (SDRevision != SDDL_REVISION_1)
4493 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4494 SetLastError(ERROR_UNKNOWN_REVISION);
4495 return FALSE;
4498 len = 0;
4499 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4500 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4501 return FALSE;
4502 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4503 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4504 return FALSE;
4505 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4506 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4507 return FALSE;
4508 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4509 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4510 return FALSE;
4512 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4513 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4514 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4515 return FALSE;
4516 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4517 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4518 return FALSE;
4519 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4520 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4521 return FALSE;
4522 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4523 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4524 return FALSE;
4525 *wptr = 0;
4527 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4528 *OutputString = wstr;
4529 if (OutputLen)
4530 *OutputLen = strlenW(*OutputString)+1;
4531 return TRUE;
4534 /******************************************************************************
4535 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4537 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4539 LPWSTR wstr;
4540 ULONG len;
4541 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4543 int lenA;
4545 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4546 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4547 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4548 LocalFree(wstr);
4550 if (OutputLen != NULL)
4551 *OutputLen = lenA;
4552 return TRUE;
4554 else
4556 *OutputString = NULL;
4557 if (OutputLen)
4558 *OutputLen = 0;
4559 return FALSE;
4563 /******************************************************************************
4564 * ConvertStringSidToSidW [ADVAPI32.@]
4566 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4568 BOOL bret = FALSE;
4569 DWORD cBytes;
4571 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4572 if (GetVersion() & 0x80000000)
4573 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4574 else if (!StringSid || !Sid)
4575 SetLastError(ERROR_INVALID_PARAMETER);
4576 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4578 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4580 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4581 if (!bret)
4582 LocalFree(*Sid);
4584 return bret;
4587 /******************************************************************************
4588 * ConvertStringSidToSidA [ADVAPI32.@]
4590 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4592 BOOL bret = FALSE;
4594 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4595 if (GetVersion() & 0x80000000)
4596 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4597 else if (!StringSid || !Sid)
4598 SetLastError(ERROR_INVALID_PARAMETER);
4599 else
4601 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4602 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4603 len * sizeof(WCHAR));
4605 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4606 bret = ConvertStringSidToSidW(wStringSid, Sid);
4607 HeapFree(GetProcessHeap(), 0, wStringSid);
4609 return bret;
4612 /******************************************************************************
4613 * ConvertSidToStringSidW [ADVAPI32.@]
4615 * format of SID string is:
4616 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4617 * where
4618 * <rev> is the revision of the SID encoded as decimal
4619 * <auth> is the identifier authority encoded as hex
4620 * <subauthN> is the subauthority id encoded as decimal
4622 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4624 DWORD len = 0;
4625 LPWSTR wstr, wptr;
4627 TRACE("%p %p\n", pSid, pstr );
4629 len = 0;
4630 if (!DumpSidNumeric(pSid, NULL, &len))
4631 return FALSE;
4632 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4633 DumpSidNumeric(pSid, &wptr, NULL);
4634 *wptr = 0;
4636 *pstr = wstr;
4637 return TRUE;
4640 /******************************************************************************
4641 * ConvertSidToStringSidA [ADVAPI32.@]
4643 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4645 LPWSTR wstr = NULL;
4646 LPSTR str;
4647 UINT len;
4649 TRACE("%p %p\n", pSid, pstr );
4651 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4652 return FALSE;
4654 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4655 str = LocalAlloc( 0, len );
4656 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4657 LocalFree( wstr );
4659 *pstr = str;
4661 return TRUE;
4664 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4665 PSECURITY_DESCRIPTOR pdesc,
4666 PSECURITY_DESCRIPTOR cdesc,
4667 PSECURITY_DESCRIPTOR* ndesc,
4668 GUID* objtype,
4669 BOOL isdir,
4670 PGENERIC_MAPPING genmap )
4672 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4674 return FALSE;
4677 BOOL WINAPI CreatePrivateObjectSecurity(
4678 PSECURITY_DESCRIPTOR ParentDescriptor,
4679 PSECURITY_DESCRIPTOR CreatorDescriptor,
4680 PSECURITY_DESCRIPTOR* NewDescriptor,
4681 BOOL IsDirectoryObject,
4682 HANDLE Token,
4683 PGENERIC_MAPPING GenericMapping )
4685 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4686 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4688 return FALSE;
4691 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4693 FIXME("%p - stub\n", ObjectDescriptor);
4695 return TRUE;
4698 BOOL WINAPI CreateProcessAsUserA(
4699 HANDLE hToken,
4700 LPCSTR lpApplicationName,
4701 LPSTR lpCommandLine,
4702 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4703 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4704 BOOL bInheritHandles,
4705 DWORD dwCreationFlags,
4706 LPVOID lpEnvironment,
4707 LPCSTR lpCurrentDirectory,
4708 LPSTARTUPINFOA lpStartupInfo,
4709 LPPROCESS_INFORMATION lpProcessInformation )
4711 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4712 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4713 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4715 return FALSE;
4718 BOOL WINAPI CreateProcessAsUserW(
4719 HANDLE hToken,
4720 LPCWSTR lpApplicationName,
4721 LPWSTR lpCommandLine,
4722 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4723 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4724 BOOL bInheritHandles,
4725 DWORD dwCreationFlags,
4726 LPVOID lpEnvironment,
4727 LPCWSTR lpCurrentDirectory,
4728 LPSTARTUPINFOW lpStartupInfo,
4729 LPPROCESS_INFORMATION lpProcessInformation )
4731 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4732 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4733 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4734 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4736 /* We should create the process with a suspended main thread */
4737 if (!CreateProcessW (lpApplicationName,
4738 lpCommandLine,
4739 lpProcessAttributes,
4740 lpThreadAttributes,
4741 bInheritHandles,
4742 dwCreationFlags, /* CREATE_SUSPENDED */
4743 lpEnvironment,
4744 lpCurrentDirectory,
4745 lpStartupInfo,
4746 lpProcessInformation))
4748 return FALSE;
4751 return TRUE;
4754 /******************************************************************************
4755 * CreateProcessWithLogonW
4757 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4758 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4759 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4761 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4762 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4763 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4764 lpStartupInfo, lpProcessInformation);
4766 return FALSE;
4769 /******************************************************************************
4770 * DuplicateTokenEx [ADVAPI32.@]
4772 BOOL WINAPI DuplicateTokenEx(
4773 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4774 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4775 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4776 TOKEN_TYPE TokenType,
4777 PHANDLE DuplicateTokenHandle )
4779 OBJECT_ATTRIBUTES ObjectAttributes;
4781 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4782 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4784 InitializeObjectAttributes(
4785 &ObjectAttributes,
4786 NULL,
4787 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4788 NULL,
4789 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4791 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4792 dwDesiredAccess,
4793 &ObjectAttributes,
4794 ImpersonationLevel,
4795 TokenType,
4796 DuplicateTokenHandle ) );
4799 BOOL WINAPI DuplicateToken(
4800 HANDLE ExistingTokenHandle,
4801 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4802 PHANDLE DuplicateTokenHandle )
4804 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4805 NULL, ImpersonationLevel, TokenImpersonation,
4806 DuplicateTokenHandle );
4809 /******************************************************************************
4810 * ComputeStringSidSize
4812 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4814 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4816 int ctok = 0;
4817 while (*StringSid)
4819 if (*StringSid == '-')
4820 ctok++;
4821 StringSid++;
4824 if (ctok >= 3)
4825 return GetSidLengthRequired(ctok - 2);
4827 else /* String constant format - Only available in winxp and above */
4829 unsigned int i;
4831 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4832 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4833 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4836 return GetSidLengthRequired(0);
4839 /******************************************************************************
4840 * ParseStringSidToSid
4842 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4844 BOOL bret = FALSE;
4845 SID* pisid=pSid;
4847 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4848 if (!StringSid)
4850 SetLastError(ERROR_INVALID_PARAMETER);
4851 TRACE("StringSid is NULL, returning FALSE\n");
4852 return FALSE;
4855 *cBytes = ComputeStringSidSize(StringSid);
4856 if (!pisid) /* Simply compute the size */
4858 TRACE("only size requested, returning TRUE\n");
4859 return TRUE;
4862 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4864 DWORD i = 0, identAuth;
4865 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4867 StringSid += 2; /* Advance to Revision */
4868 pisid->Revision = atoiW(StringSid);
4870 if (pisid->Revision != SDDL_REVISION)
4872 TRACE("Revision %d is unknown\n", pisid->Revision);
4873 goto lend; /* ERROR_INVALID_SID */
4875 if (csubauth == 0)
4877 TRACE("SubAuthorityCount is 0\n");
4878 goto lend; /* ERROR_INVALID_SID */
4881 pisid->SubAuthorityCount = csubauth;
4883 /* Advance to identifier authority */
4884 while (*StringSid && *StringSid != '-')
4885 StringSid++;
4886 if (*StringSid == '-')
4887 StringSid++;
4889 /* MS' implementation can't handle values greater than 2^32 - 1, so
4890 * we don't either; assume most significant bytes are always 0
4892 pisid->IdentifierAuthority.Value[0] = 0;
4893 pisid->IdentifierAuthority.Value[1] = 0;
4894 identAuth = atoiW(StringSid);
4895 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4896 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4897 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4898 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4900 /* Advance to first sub authority */
4901 while (*StringSid && *StringSid != '-')
4902 StringSid++;
4903 if (*StringSid == '-')
4904 StringSid++;
4906 while (*StringSid)
4908 pisid->SubAuthority[i++] = atoiW(StringSid);
4910 while (*StringSid && *StringSid != '-')
4911 StringSid++;
4912 if (*StringSid == '-')
4913 StringSid++;
4916 if (i != pisid->SubAuthorityCount)
4917 goto lend; /* ERROR_INVALID_SID */
4919 bret = TRUE;
4921 else /* String constant format - Only available in winxp and above */
4923 unsigned int i;
4924 pisid->Revision = SDDL_REVISION;
4926 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4927 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4929 DWORD j;
4930 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4931 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4932 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4933 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4934 bret = TRUE;
4937 if (!bret)
4938 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4941 lend:
4942 if (!bret)
4943 SetLastError(ERROR_INVALID_SID);
4945 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4946 return bret;
4949 /******************************************************************************
4950 * GetNamedSecurityInfoA [ADVAPI32.@]
4952 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4953 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4954 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4955 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4957 DWORD len;
4958 LPWSTR wstr = NULL;
4959 DWORD r;
4961 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4962 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4964 if( pObjectName )
4966 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4967 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4968 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4971 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4972 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4974 HeapFree( GetProcessHeap(), 0, wstr );
4976 return r;
4979 /******************************************************************************
4980 * GetNamedSecurityInfoW [ADVAPI32.@]
4982 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4983 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4984 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4986 DWORD needed, offset;
4987 SECURITY_DESCRIPTOR_RELATIVE *relative;
4988 BYTE *buffer;
4990 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4991 group, dacl, sacl, descriptor );
4993 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4995 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4996 if (info & OWNER_SECURITY_INFORMATION)
4997 needed += sizeof(sidWorld);
4998 if (info & GROUP_SECURITY_INFORMATION)
4999 needed += sizeof(sidWorld);
5000 if (info & DACL_SECURITY_INFORMATION)
5001 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5002 if (info & SACL_SECURITY_INFORMATION)
5003 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5005 /* must be freed by caller */
5006 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5007 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5009 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5011 HeapFree( GetProcessHeap(), 0, *descriptor );
5012 return ERROR_INVALID_SECURITY_DESCR;
5015 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
5016 relative->Control |= SE_SELF_RELATIVE;
5017 buffer = (BYTE *)relative;
5018 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5020 if (info & OWNER_SECURITY_INFORMATION)
5022 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5023 relative->Owner = offset;
5024 if (owner)
5025 *owner = buffer + offset;
5026 offset += sizeof(sidWorld);
5028 if (info & GROUP_SECURITY_INFORMATION)
5030 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5031 relative->Group = offset;
5032 if (group)
5033 *group = buffer + offset;
5034 offset += sizeof(sidWorld);
5036 if (info & DACL_SECURITY_INFORMATION)
5038 relative->Control |= SE_DACL_PRESENT;
5039 GetWorldAccessACL( (PACL)(buffer + offset) );
5040 relative->Dacl = offset;
5041 if (dacl)
5042 *dacl = (PACL)(buffer + offset);
5043 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5045 if (info & SACL_SECURITY_INFORMATION)
5047 relative->Control |= SE_SACL_PRESENT;
5048 GetWorldAccessACL( (PACL)(buffer + offset) );
5049 relative->Sacl = offset;
5050 if (sacl)
5051 *sacl = (PACL)(buffer + offset);
5053 return ERROR_SUCCESS;
5056 /******************************************************************************
5057 * DecryptFileW [ADVAPI32.@]
5059 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5061 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5062 return TRUE;
5065 /******************************************************************************
5066 * DecryptFileA [ADVAPI32.@]
5068 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5070 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5071 return TRUE;
5074 /******************************************************************************
5075 * EncryptFileW [ADVAPI32.@]
5077 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5079 FIXME("%s\n", debugstr_w(lpFileName));
5080 return TRUE;
5083 /******************************************************************************
5084 * EncryptFileA [ADVAPI32.@]
5086 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5088 FIXME("%s\n", debugstr_a(lpFileName));
5089 return TRUE;
5092 /******************************************************************************
5093 * FileEncryptionStatusW [ADVAPI32.@]
5095 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5097 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5098 if (!lpStatus)
5099 return FALSE;
5100 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5101 return TRUE;
5104 /******************************************************************************
5105 * FileEncryptionStatusA [ADVAPI32.@]
5107 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5109 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5110 if (!lpStatus)
5111 return FALSE;
5112 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5113 return TRUE;
5116 /******************************************************************************
5117 * SetSecurityInfo [ADVAPI32.@]
5119 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5120 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5121 PSID psidGroup, PACL pDacl, PACL pSacl) {
5122 FIXME("stub\n");
5123 return ERROR_SUCCESS;