msi/tests: Remove unused variable.
[wine.git] / dlls / advapi32 / security.c
blobefe34f4265334005b4123aa903de3f1ab9c1828b
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 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 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 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 };
187 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
188 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 };
189 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
190 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
191 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
192 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
193 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
194 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
195 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
196 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 };
197 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
198 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 };
199 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
200 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
201 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
202 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
203 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
205 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
206 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 };
207 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
208 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
209 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
210 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
211 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
212 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
213 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
214 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 };
215 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 };
216 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
217 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 };
218 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
219 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
220 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
221 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 };
222 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 };
223 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
224 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
225 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 };
226 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
227 static const WCHAR SELF[] = { 'S','E','L','F',0 };
228 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
229 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
230 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
231 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 };
232 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
233 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
235 static const AccountSid ACCOUNT_SIDS[] = {
236 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
237 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
238 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
239 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
240 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
241 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
242 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
244 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
259 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
260 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
261 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
262 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
264 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
265 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
270 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
271 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
272 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
273 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
279 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
282 * ACE access rights
284 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
285 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
286 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
287 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
289 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
290 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
291 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
292 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
293 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
294 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
295 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
296 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
297 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
299 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
300 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
301 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
302 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
304 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
305 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
306 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
307 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
309 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
310 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
311 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
312 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
315 * ACL flags
317 static const WCHAR SDDL_PROTECTED[] = {'P',0};
318 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
319 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
322 * ACE types
324 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
325 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
326 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
328 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
329 static const WCHAR SDDL_ALARM[] = {'A','L',0};
330 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
331 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
334 * ACE flags
336 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
337 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
338 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
339 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
340 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
341 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
342 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
344 const char * debugstr_sid(PSID sid)
346 int auth = 0;
347 SID * psid = sid;
349 if (psid == NULL)
350 return "(null)";
352 auth = psid->IdentifierAuthority.Value[5] +
353 (psid->IdentifierAuthority.Value[4] << 8) +
354 (psid->IdentifierAuthority.Value[3] << 16) +
355 (psid->IdentifierAuthority.Value[2] << 24);
357 switch (psid->SubAuthorityCount) {
358 case 0:
359 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
360 case 1:
361 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
362 psid->SubAuthority[0]);
363 case 2:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1]);
366 case 3:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
369 case 4:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[3]);
373 case 5:
374 return wine_dbg_sprintf("S-%d-%d-%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]);
377 case 6:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
381 case 7:
382 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
383 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
384 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
385 psid->SubAuthority[6]);
386 case 8:
387 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
388 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
389 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
390 psid->SubAuthority[6], psid->SubAuthority[7]);
392 return "(too-big)";
395 /* set last error code from NT status and get the proper boolean return value */
396 /* used for functions that are a simple wrapper around the corresponding ntdll API */
397 static inline BOOL set_ntstatus( NTSTATUS status )
399 if (status) SetLastError( RtlNtStatusToDosError( status ));
400 return !status;
403 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405 static void GetWorldAccessACL(PACL pACL)
407 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409 pACL->AclRevision = ACL_REVISION;
410 pACL->Sbz1 = 0;
411 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
412 pACL->AceCount = 1;
413 pACL->Sbz2 = 0;
415 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
416 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
417 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
418 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
419 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
422 /************************************************************
423 * ADVAPI_IsLocalComputer
425 * Checks whether the server name indicates local machine.
427 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
430 BOOL Result;
431 LPWSTR buf;
433 if (!ServerName || !ServerName[0])
434 return TRUE;
436 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
437 Result = GetComputerNameW(buf, &dwSize);
438 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
439 ServerName += 2;
440 Result = Result && !lstrcmpW(ServerName, buf);
441 HeapFree(GetProcessHeap(), 0, buf);
443 return Result;
446 /************************************************************
447 * ADVAPI_GetComputerSid
449 * Reads the computer SID from the registry.
451 BOOL ADVAPI_GetComputerSid(PSID sid)
453 HKEY key;
454 LONG ret;
455 BOOL retval = FALSE;
456 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 };
457 static const WCHAR V[] = { 'V',0 };
459 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
460 KEY_READ, &key)) == ERROR_SUCCESS)
462 DWORD size = 0;
463 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
464 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
467 if (data)
469 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
470 data, &size)) == ERROR_SUCCESS)
472 /* the SID is in the last 24 bytes of the binary data */
473 CopyMemory(sid, &data[size-24], 24);
474 retval = TRUE;
476 HeapFree(GetProcessHeap(), 0, data);
479 RegCloseKey(key);
482 if(retval == TRUE) return retval;
484 /* create a new random SID */
485 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
486 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488 PSID new_sid;
489 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
490 DWORD id[3];
492 if (RtlGenRandom(id, sizeof(id)))
494 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
497 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499 FreeSid(new_sid);
502 RegCloseKey(key);
505 return retval;
508 /* ##############################
509 ###### TOKEN FUNCTIONS ######
510 ##############################
513 /******************************************************************************
514 * OpenProcessToken [ADVAPI32.@]
515 * Opens the access token associated with a process handle.
517 * PARAMS
518 * ProcessHandle [I] Handle to process
519 * DesiredAccess [I] Desired access to process
520 * TokenHandle [O] Pointer to handle of open access token
522 * RETURNS
523 * Success: TRUE. TokenHandle contains the access token.
524 * Failure: FALSE.
526 * NOTES
527 * See NtOpenProcessToken.
529 BOOL WINAPI
530 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
531 HANDLE *TokenHandle )
533 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
536 /******************************************************************************
537 * OpenThreadToken [ADVAPI32.@]
539 * Opens the access token associated with a thread handle.
541 * PARAMS
542 * ThreadHandle [I] Handle to process
543 * DesiredAccess [I] Desired access to the thread
544 * OpenAsSelf [I] ???
545 * TokenHandle [O] Destination for the token handle
547 * RETURNS
548 * Success: TRUE. TokenHandle contains the access token.
549 * Failure: FALSE.
551 * NOTES
552 * See NtOpenThreadToken.
554 BOOL WINAPI
555 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
556 BOOL OpenAsSelf, HANDLE *TokenHandle)
558 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
561 BOOL WINAPI
562 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
563 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
566 PreviousState, ReturnLength));
569 /******************************************************************************
570 * AdjustTokenPrivileges [ADVAPI32.@]
572 * Adjust the privileges of an open token handle.
574 * PARAMS
575 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
576 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
577 * NewState [I] Desired new privileges of the token
578 * BufferLength [I] Length of NewState
579 * PreviousState [O] Destination for the previous state
580 * ReturnLength [I/O] Size of PreviousState
583 * RETURNS
584 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
585 * Failure: FALSE.
587 * NOTES
588 * See NtAdjustPrivilegesToken.
590 BOOL WINAPI
591 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
592 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
593 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 NTSTATUS status;
597 TRACE("\n");
599 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
600 NewState, BufferLength, PreviousState,
601 ReturnLength);
602 SetLastError( RtlNtStatusToDosError( status ));
603 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
604 return TRUE;
605 else
606 return FALSE;
609 /******************************************************************************
610 * CheckTokenMembership [ADVAPI32.@]
612 * Determine if an access token is a member of a SID.
614 * PARAMS
615 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
616 * SidToCheck [I] SID that possibly contains the token
617 * IsMember [O] Destination for result.
619 * RETURNS
620 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
621 * Failure: FALSE.
623 BOOL WINAPI
624 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
625 PBOOL IsMember )
627 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629 *IsMember = TRUE;
630 return(TRUE);
633 /******************************************************************************
634 * GetTokenInformation [ADVAPI32.@]
636 * Get a type of information about an access token.
638 * PARAMS
639 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
640 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
641 * tokeninfo [O] Destination for token information
642 * tokeninfolength [I] Length of tokeninfo
643 * retlen [O] Destination for returned token information length
645 * RETURNS
646 * Success: TRUE. tokeninfo contains retlen bytes of token information
647 * Failure: FALSE.
649 * NOTES
650 * See NtQueryInformationToken.
652 BOOL WINAPI
653 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
654 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 TRACE("(%p, %s, %p, %d, %p):\n",
657 token,
658 (tokeninfoclass == TokenUser) ? "TokenUser" :
659 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
660 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
661 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
662 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
663 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
664 (tokeninfoclass == TokenSource) ? "TokenSource" :
665 (tokeninfoclass == TokenType) ? "TokenType" :
666 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
667 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
668 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
669 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
670 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
671 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
672 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
673 "Unknown",
674 tokeninfo, tokeninfolength, retlen);
675 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
676 tokeninfolength, retlen));
679 /******************************************************************************
680 * SetTokenInformation [ADVAPI32.@]
682 * Set information for an access token.
684 * PARAMS
685 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
686 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
687 * tokeninfo [I] Token information to set
688 * tokeninfolength [I] Length of tokeninfo
690 * RETURNS
691 * Success: TRUE. The information for the token is set to tokeninfo.
692 * Failure: FALSE.
694 BOOL WINAPI
695 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
696 LPVOID tokeninfo, DWORD tokeninfolength )
698 TRACE("(%p, %s, %p, %d): stub\n",
699 token,
700 (tokeninfoclass == TokenUser) ? "TokenUser" :
701 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
702 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
703 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
704 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
705 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
706 (tokeninfoclass == TokenSource) ? "TokenSource" :
707 (tokeninfoclass == TokenType) ? "TokenType" :
708 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
709 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
710 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
711 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
712 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
713 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
714 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
715 "Unknown",
716 tokeninfo, tokeninfolength);
718 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
721 /*************************************************************************
722 * SetThreadToken [ADVAPI32.@]
724 * Assigns an 'impersonation token' to a thread so it can assume the
725 * security privileges of another thread or process. Can also remove
726 * a previously assigned token.
728 * PARAMS
729 * thread [O] Handle to thread to set the token for
730 * token [I] Token to set
732 * RETURNS
733 * Success: TRUE. The threads access token is set to token
734 * Failure: FALSE.
736 * NOTES
737 * Only supported on NT or higher. On Win9X this function does nothing.
738 * See SetTokenInformation.
740 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
743 ThreadImpersonationToken, &token, sizeof token ));
746 /*************************************************************************
747 * CreateRestrictedToken [ADVAPI32.@]
749 * Create a new more restricted token from an existing token.
751 * PARAMS
752 * baseToken [I] Token to base the new restricted token on
753 * flags [I] Options
754 * nDisableSids [I] Length of disableSids array
755 * disableSids [I] Array of SIDs to disable in the new token
756 * nDeletePrivs [I] Length of deletePrivs array
757 * deletePrivs [I] Array of privileges to delete in the new token
758 * nRestrictSids [I] Length of restrictSids array
759 * restrictSids [I] Array of SIDs to restrict in the new token
760 * newToken [O] Address where the new token is stored
762 * RETURNS
763 * Success: TRUE
764 * Failure: FALSE
766 BOOL WINAPI CreateRestrictedToken(
767 HANDLE baseToken,
768 DWORD flags,
769 DWORD nDisableSids,
770 PSID_AND_ATTRIBUTES disableSids,
771 DWORD nDeletePrivs,
772 PLUID_AND_ATTRIBUTES deletePrivs,
773 DWORD nRestrictSids,
774 PSID_AND_ATTRIBUTES restrictSids,
775 PHANDLE newToken)
777 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
778 baseToken, flags, nDisableSids, disableSids,
779 nDeletePrivs, deletePrivs,
780 nRestrictSids, restrictSids,
781 newToken);
782 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
783 return FALSE;
786 /* ##############################
787 ###### SID FUNCTIONS ######
788 ##############################
791 /******************************************************************************
792 * AllocateAndInitializeSid [ADVAPI32.@]
794 * PARAMS
795 * pIdentifierAuthority []
796 * nSubAuthorityCount []
797 * nSubAuthority0 []
798 * nSubAuthority1 []
799 * nSubAuthority2 []
800 * nSubAuthority3 []
801 * nSubAuthority4 []
802 * nSubAuthority5 []
803 * nSubAuthority6 []
804 * nSubAuthority7 []
805 * pSid []
807 BOOL WINAPI
808 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
809 BYTE nSubAuthorityCount,
810 DWORD nSubAuthority0, DWORD nSubAuthority1,
811 DWORD nSubAuthority2, DWORD nSubAuthority3,
812 DWORD nSubAuthority4, DWORD nSubAuthority5,
813 DWORD nSubAuthority6, DWORD nSubAuthority7,
814 PSID *pSid )
816 return set_ntstatus( RtlAllocateAndInitializeSid(
817 pIdentifierAuthority, nSubAuthorityCount,
818 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
819 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
820 pSid ));
823 /******************************************************************************
824 * FreeSid [ADVAPI32.@]
826 * PARAMS
827 * pSid []
829 PVOID WINAPI
830 FreeSid( PSID pSid )
832 RtlFreeSid(pSid);
833 return NULL; /* is documented like this */
836 /******************************************************************************
837 * CopySid [ADVAPI32.@]
839 * PARAMS
840 * nDestinationSidLength []
841 * pDestinationSid []
842 * pSourceSid []
844 BOOL WINAPI
845 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
850 /******************************************************************************
851 * CreateWellKnownSid [ADVAPI32.@]
853 BOOL WINAPI
854 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
855 PSID DomainSid,
856 PSID pSid,
857 DWORD* cbSid)
859 unsigned int i;
860 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
864 SetLastError(ERROR_INVALID_PARAMETER);
865 return FALSE;
868 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
869 if (WellKnownSids[i].Type == WellKnownSidType) {
870 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
872 if (*cbSid < length)
874 *cbSid = length;
875 SetLastError(ERROR_INSUFFICIENT_BUFFER);
876 return FALSE;
878 if (!pSid)
880 SetLastError(ERROR_INVALID_PARAMETER);
881 return FALSE;
883 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
884 *cbSid = length;
885 return TRUE;
889 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
891 SetLastError(ERROR_INVALID_PARAMETER);
892 return FALSE;
895 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
896 if (WellKnownRids[i].Type == WellKnownSidType) {
897 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
898 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
899 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
901 if (*cbSid < output_sid_length)
903 *cbSid = output_sid_length;
904 SetLastError(ERROR_INSUFFICIENT_BUFFER);
905 return FALSE;
907 if (!pSid)
909 SetLastError(ERROR_INVALID_PARAMETER);
910 return FALSE;
912 CopyMemory(pSid, DomainSid, domain_sid_length);
913 (*GetSidSubAuthorityCount(pSid))++;
914 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
915 *cbSid = output_sid_length;
916 return TRUE;
919 SetLastError(ERROR_INVALID_PARAMETER);
920 return FALSE;
923 /******************************************************************************
924 * IsWellKnownSid [ADVAPI32.@]
926 BOOL WINAPI
927 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
929 unsigned int i;
930 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
932 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
933 if (WellKnownSids[i].Type == WellKnownSidType)
934 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
935 return TRUE;
937 return FALSE;
940 BOOL WINAPI
941 IsTokenRestricted( HANDLE TokenHandle )
943 TOKEN_GROUPS *groups;
944 DWORD size;
945 NTSTATUS status;
946 BOOL restricted;
948 TRACE("(%p)\n", TokenHandle);
950 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
951 if (status != STATUS_BUFFER_TOO_SMALL)
952 return FALSE;
954 groups = HeapAlloc(GetProcessHeap(), 0, size);
955 if (!groups)
957 SetLastError(ERROR_OUTOFMEMORY);
958 return FALSE;
961 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
962 if (status != STATUS_SUCCESS)
964 HeapFree(GetProcessHeap(), 0, groups);
965 return set_ntstatus(status);
968 if (groups->GroupCount)
969 restricted = TRUE;
970 else
971 restricted = FALSE;
973 HeapFree(GetProcessHeap(), 0, groups);
975 return restricted;
978 /******************************************************************************
979 * IsValidSid [ADVAPI32.@]
981 * PARAMS
982 * pSid []
984 BOOL WINAPI
985 IsValidSid( PSID pSid )
987 return RtlValidSid( pSid );
990 /******************************************************************************
991 * EqualSid [ADVAPI32.@]
993 * PARAMS
994 * pSid1 []
995 * pSid2 []
997 BOOL WINAPI
998 EqualSid( PSID pSid1, PSID pSid2 )
1000 return RtlEqualSid( pSid1, pSid2 );
1003 /******************************************************************************
1004 * EqualPrefixSid [ADVAPI32.@]
1006 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1008 return RtlEqualPrefixSid(pSid1, pSid2);
1011 /******************************************************************************
1012 * GetSidLengthRequired [ADVAPI32.@]
1014 * PARAMS
1015 * nSubAuthorityCount []
1017 DWORD WINAPI
1018 GetSidLengthRequired( BYTE nSubAuthorityCount )
1020 return RtlLengthRequiredSid(nSubAuthorityCount);
1023 /******************************************************************************
1024 * InitializeSid [ADVAPI32.@]
1026 * PARAMS
1027 * pIdentifierAuthority []
1029 BOOL WINAPI
1030 InitializeSid (
1031 PSID pSid,
1032 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1033 BYTE nSubAuthorityCount)
1035 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1038 DWORD WINAPI
1039 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1041 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1043 return 1;
1046 DWORD WINAPI
1047 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1049 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1051 return 1;
1054 /******************************************************************************
1055 * GetSidIdentifierAuthority [ADVAPI32.@]
1057 * PARAMS
1058 * pSid []
1060 PSID_IDENTIFIER_AUTHORITY WINAPI
1061 GetSidIdentifierAuthority( PSID pSid )
1063 return RtlIdentifierAuthoritySid(pSid);
1066 /******************************************************************************
1067 * GetSidSubAuthority [ADVAPI32.@]
1069 * PARAMS
1070 * pSid []
1071 * nSubAuthority []
1073 PDWORD WINAPI
1074 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1076 return RtlSubAuthoritySid(pSid, nSubAuthority);
1079 /******************************************************************************
1080 * GetSidSubAuthorityCount [ADVAPI32.@]
1082 * PARAMS
1083 * pSid []
1085 PUCHAR WINAPI
1086 GetSidSubAuthorityCount (PSID pSid)
1088 return RtlSubAuthorityCountSid(pSid);
1091 /******************************************************************************
1092 * GetLengthSid [ADVAPI32.@]
1094 * PARAMS
1095 * pSid []
1097 DWORD WINAPI
1098 GetLengthSid (PSID pSid)
1100 return RtlLengthSid(pSid);
1103 /* ##############################################
1104 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1105 ##############################################
1108 /******************************************************************************
1109 * BuildSecurityDescriptorA [ADVAPI32.@]
1111 * Builds a SD from
1113 * PARAMS
1114 * pOwner [I]
1115 * pGroup [I]
1116 * cCountOfAccessEntries [I]
1117 * pListOfAccessEntries [I]
1118 * cCountOfAuditEntries [I]
1119 * pListofAuditEntries [I]
1120 * pOldSD [I]
1121 * lpdwBufferLength [I/O]
1122 * pNewSD [O]
1124 * RETURNS
1125 * Success: ERROR_SUCCESS
1126 * Failure: nonzero error code from Winerror.h
1128 DWORD WINAPI BuildSecurityDescriptorA(
1129 IN PTRUSTEEA pOwner,
1130 IN PTRUSTEEA pGroup,
1131 IN ULONG cCountOfAccessEntries,
1132 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1133 IN ULONG cCountOfAuditEntries,
1134 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1135 IN PSECURITY_DESCRIPTOR pOldSD,
1136 IN OUT PULONG lpdwBufferLength,
1137 OUT PSECURITY_DESCRIPTOR* pNewSD)
1139 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1140 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1141 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1143 return ERROR_CALL_NOT_IMPLEMENTED;
1146 /******************************************************************************
1147 * BuildSecurityDescriptorW [ADVAPI32.@]
1149 * See BuildSecurityDescriptorA.
1151 DWORD WINAPI BuildSecurityDescriptorW(
1152 IN PTRUSTEEW pOwner,
1153 IN PTRUSTEEW pGroup,
1154 IN ULONG cCountOfAccessEntries,
1155 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1156 IN ULONG cCountOfAuditEntries,
1157 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1158 IN PSECURITY_DESCRIPTOR pOldSD,
1159 IN OUT PULONG lpdwBufferLength,
1160 OUT PSECURITY_DESCRIPTOR* pNewSD)
1162 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1163 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1164 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1166 return ERROR_CALL_NOT_IMPLEMENTED;
1169 /******************************************************************************
1170 * InitializeSecurityDescriptor [ADVAPI32.@]
1172 * PARAMS
1173 * pDescr []
1174 * revision []
1176 BOOL WINAPI
1177 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1179 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1183 /******************************************************************************
1184 * MakeAbsoluteSD [ADVAPI32.@]
1186 BOOL WINAPI MakeAbsoluteSD (
1187 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1188 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1189 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1190 OUT PACL pDacl,
1191 OUT LPDWORD lpdwDaclSize,
1192 OUT PACL pSacl,
1193 OUT LPDWORD lpdwSaclSize,
1194 OUT PSID pOwner,
1195 OUT LPDWORD lpdwOwnerSize,
1196 OUT PSID pPrimaryGroup,
1197 OUT LPDWORD lpdwPrimaryGroupSize)
1199 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1200 pAbsoluteSecurityDescriptor,
1201 lpdwAbsoluteSecurityDescriptorSize,
1202 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1203 pOwner, lpdwOwnerSize,
1204 pPrimaryGroup, lpdwPrimaryGroupSize));
1207 /******************************************************************************
1208 * GetKernelObjectSecurity [ADVAPI32.@]
1210 BOOL WINAPI GetKernelObjectSecurity(
1211 HANDLE Handle,
1212 SECURITY_INFORMATION RequestedInformation,
1213 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1214 DWORD nLength,
1215 LPDWORD lpnLengthNeeded )
1217 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1218 pSecurityDescriptor, nLength, lpnLengthNeeded);
1220 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1221 nLength, lpnLengthNeeded ));
1224 /******************************************************************************
1225 * GetPrivateObjectSecurity [ADVAPI32.@]
1227 BOOL WINAPI GetPrivateObjectSecurity(
1228 PSECURITY_DESCRIPTOR ObjectDescriptor,
1229 SECURITY_INFORMATION SecurityInformation,
1230 PSECURITY_DESCRIPTOR ResultantDescriptor,
1231 DWORD DescriptorLength,
1232 PDWORD ReturnLength )
1234 SECURITY_DESCRIPTOR desc;
1235 BOOL defaulted, present;
1236 PACL pacl;
1237 PSID psid;
1239 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1240 ResultantDescriptor, DescriptorLength, ReturnLength);
1242 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1243 return FALSE;
1245 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1247 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1248 return FALSE;
1249 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1252 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1254 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1255 return FALSE;
1256 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1259 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1261 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1262 return FALSE;
1263 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1266 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1268 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1269 return FALSE;
1270 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1273 *ReturnLength = DescriptorLength;
1274 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1277 /******************************************************************************
1278 * GetSecurityDescriptorLength [ADVAPI32.@]
1280 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1282 return RtlLengthSecurityDescriptor(pDescr);
1285 /******************************************************************************
1286 * GetSecurityDescriptorOwner [ADVAPI32.@]
1288 * PARAMS
1289 * pOwner []
1290 * lpbOwnerDefaulted []
1292 BOOL WINAPI
1293 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1294 LPBOOL lpbOwnerDefaulted )
1296 BOOLEAN defaulted;
1297 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1298 *lpbOwnerDefaulted = defaulted;
1299 return ret;
1302 /******************************************************************************
1303 * SetSecurityDescriptorOwner [ADVAPI32.@]
1305 * PARAMS
1307 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1308 PSID pOwner, BOOL bOwnerDefaulted)
1310 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1312 /******************************************************************************
1313 * GetSecurityDescriptorGroup [ADVAPI32.@]
1315 BOOL WINAPI GetSecurityDescriptorGroup(
1316 PSECURITY_DESCRIPTOR SecurityDescriptor,
1317 PSID *Group,
1318 LPBOOL GroupDefaulted)
1320 BOOLEAN defaulted;
1321 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1322 *GroupDefaulted = defaulted;
1323 return ret;
1325 /******************************************************************************
1326 * SetSecurityDescriptorGroup [ADVAPI32.@]
1328 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1329 PSID Group, BOOL GroupDefaulted)
1331 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1334 /******************************************************************************
1335 * IsValidSecurityDescriptor [ADVAPI32.@]
1337 * PARAMS
1338 * lpsecdesc []
1340 BOOL WINAPI
1341 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1343 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1346 /******************************************************************************
1347 * GetSecurityDescriptorDacl [ADVAPI32.@]
1349 BOOL WINAPI GetSecurityDescriptorDacl(
1350 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1351 OUT LPBOOL lpbDaclPresent,
1352 OUT PACL *pDacl,
1353 OUT LPBOOL lpbDaclDefaulted)
1355 BOOLEAN present, defaulted;
1356 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1357 *lpbDaclPresent = present;
1358 *lpbDaclDefaulted = defaulted;
1359 return ret;
1362 /******************************************************************************
1363 * SetSecurityDescriptorDacl [ADVAPI32.@]
1365 BOOL WINAPI
1366 SetSecurityDescriptorDacl (
1367 PSECURITY_DESCRIPTOR lpsd,
1368 BOOL daclpresent,
1369 PACL dacl,
1370 BOOL dacldefaulted )
1372 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1374 /******************************************************************************
1375 * GetSecurityDescriptorSacl [ADVAPI32.@]
1377 BOOL WINAPI GetSecurityDescriptorSacl(
1378 IN PSECURITY_DESCRIPTOR lpsd,
1379 OUT LPBOOL lpbSaclPresent,
1380 OUT PACL *pSacl,
1381 OUT LPBOOL lpbSaclDefaulted)
1383 BOOLEAN present, defaulted;
1384 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1385 *lpbSaclPresent = present;
1386 *lpbSaclDefaulted = defaulted;
1387 return ret;
1390 /**************************************************************************
1391 * SetSecurityDescriptorSacl [ADVAPI32.@]
1393 BOOL WINAPI SetSecurityDescriptorSacl (
1394 PSECURITY_DESCRIPTOR lpsd,
1395 BOOL saclpresent,
1396 PACL lpsacl,
1397 BOOL sacldefaulted)
1399 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1401 /******************************************************************************
1402 * MakeSelfRelativeSD [ADVAPI32.@]
1404 * PARAMS
1405 * lpabssecdesc []
1406 * lpselfsecdesc []
1407 * lpbuflen []
1409 BOOL WINAPI
1410 MakeSelfRelativeSD(
1411 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1412 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1413 IN OUT LPDWORD lpdwBufferLength)
1415 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1416 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1419 /******************************************************************************
1420 * GetSecurityDescriptorControl [ADVAPI32.@]
1423 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1424 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1426 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1429 /******************************************************************************
1430 * SetSecurityDescriptorControl [ADVAPI32.@]
1432 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1433 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1434 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1436 return set_ntstatus( RtlSetControlSecurityDescriptor(
1437 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1440 /* ##############################
1441 ###### ACL FUNCTIONS ######
1442 ##############################
1445 /*************************************************************************
1446 * InitializeAcl [ADVAPI32.@]
1448 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1450 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1453 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1455 IO_STATUS_BLOCK io_block;
1457 TRACE("(%p)\n", hNamedPipe);
1459 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1460 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1463 /******************************************************************************
1464 * AddAccessAllowedAce [ADVAPI32.@]
1466 BOOL WINAPI AddAccessAllowedAce(
1467 IN OUT PACL pAcl,
1468 IN DWORD dwAceRevision,
1469 IN DWORD AccessMask,
1470 IN PSID pSid)
1472 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1475 /******************************************************************************
1476 * AddAccessAllowedAceEx [ADVAPI32.@]
1478 BOOL WINAPI AddAccessAllowedAceEx(
1479 IN OUT PACL pAcl,
1480 IN DWORD dwAceRevision,
1481 IN DWORD AceFlags,
1482 IN DWORD AccessMask,
1483 IN PSID pSid)
1485 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1488 /******************************************************************************
1489 * AddAccessDeniedAce [ADVAPI32.@]
1491 BOOL WINAPI AddAccessDeniedAce(
1492 IN OUT PACL pAcl,
1493 IN DWORD dwAceRevision,
1494 IN DWORD AccessMask,
1495 IN PSID pSid)
1497 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1500 /******************************************************************************
1501 * AddAccessDeniedAceEx [ADVAPI32.@]
1503 BOOL WINAPI AddAccessDeniedAceEx(
1504 IN OUT PACL pAcl,
1505 IN DWORD dwAceRevision,
1506 IN DWORD AceFlags,
1507 IN DWORD AccessMask,
1508 IN PSID pSid)
1510 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1513 /******************************************************************************
1514 * AddAce [ADVAPI32.@]
1516 BOOL WINAPI AddAce(
1517 IN OUT PACL pAcl,
1518 IN DWORD dwAceRevision,
1519 IN DWORD dwStartingAceIndex,
1520 LPVOID pAceList,
1521 DWORD nAceListLength)
1523 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1526 /******************************************************************************
1527 * DeleteAce [ADVAPI32.@]
1529 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1531 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1534 /******************************************************************************
1535 * FindFirstFreeAce [ADVAPI32.@]
1537 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1539 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1542 /******************************************************************************
1543 * GetAce [ADVAPI32.@]
1545 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1547 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1550 /******************************************************************************
1551 * GetAclInformation [ADVAPI32.@]
1553 BOOL WINAPI GetAclInformation(
1554 PACL pAcl,
1555 LPVOID pAclInformation,
1556 DWORD nAclInformationLength,
1557 ACL_INFORMATION_CLASS dwAclInformationClass)
1559 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1560 nAclInformationLength, dwAclInformationClass));
1563 /******************************************************************************
1564 * IsValidAcl [ADVAPI32.@]
1566 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1568 return RtlValidAcl(pAcl);
1571 /* ##############################
1572 ###### MISC FUNCTIONS ######
1573 ##############################
1576 /******************************************************************************
1577 * AllocateLocallyUniqueId [ADVAPI32.@]
1579 * PARAMS
1580 * lpLuid []
1582 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1584 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1587 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1588 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1592 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1596 { '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 };
1597 static const WCHAR SE_TCB_NAME_W[] =
1598 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_SECURITY_NAME_W[] =
1600 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1602 { '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 };
1603 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1604 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1606 { '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 };
1607 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1608 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1610 { '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 };
1611 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1612 { '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 };
1613 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1614 { '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 };
1615 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_BACKUP_NAME_W[] =
1618 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_RESTORE_NAME_W[] =
1620 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1622 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1623 static const WCHAR SE_DEBUG_NAME_W[] =
1624 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_AUDIT_NAME_W[] =
1626 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1627 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1628 { '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 };
1629 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1630 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1631 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1632 { '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 };
1633 static const WCHAR SE_UNDOCK_NAME_W[] =
1634 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1635 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1636 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1637 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1638 { '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 };
1639 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1640 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1641 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1642 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1643 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1644 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1648 NULL,
1649 NULL,
1650 SE_CREATE_TOKEN_NAME_W,
1651 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1652 SE_LOCK_MEMORY_NAME_W,
1653 SE_INCREASE_QUOTA_NAME_W,
1654 SE_MACHINE_ACCOUNT_NAME_W,
1655 SE_TCB_NAME_W,
1656 SE_SECURITY_NAME_W,
1657 SE_TAKE_OWNERSHIP_NAME_W,
1658 SE_LOAD_DRIVER_NAME_W,
1659 SE_SYSTEM_PROFILE_NAME_W,
1660 SE_SYSTEMTIME_NAME_W,
1661 SE_PROF_SINGLE_PROCESS_NAME_W,
1662 SE_INC_BASE_PRIORITY_NAME_W,
1663 SE_CREATE_PAGEFILE_NAME_W,
1664 SE_CREATE_PERMANENT_NAME_W,
1665 SE_BACKUP_NAME_W,
1666 SE_RESTORE_NAME_W,
1667 SE_SHUTDOWN_NAME_W,
1668 SE_DEBUG_NAME_W,
1669 SE_AUDIT_NAME_W,
1670 SE_SYSTEM_ENVIRONMENT_NAME_W,
1671 SE_CHANGE_NOTIFY_NAME_W,
1672 SE_REMOTE_SHUTDOWN_NAME_W,
1673 SE_UNDOCK_NAME_W,
1674 SE_SYNC_AGENT_NAME_W,
1675 SE_ENABLE_DELEGATION_NAME_W,
1676 SE_MANAGE_VOLUME_NAME_W,
1677 SE_IMPERSONATE_NAME_W,
1678 SE_CREATE_GLOBAL_NAME_W,
1681 /******************************************************************************
1682 * LookupPrivilegeValueW [ADVAPI32.@]
1684 * See LookupPrivilegeValueA.
1686 BOOL WINAPI
1687 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1689 UINT i;
1691 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1693 if (!ADVAPI_IsLocalComputer(lpSystemName))
1695 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1696 return FALSE;
1698 if (!lpName)
1700 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1701 return FALSE;
1703 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1705 if( !WellKnownPrivNames[i] )
1706 continue;
1707 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1708 continue;
1709 lpLuid->LowPart = i;
1710 lpLuid->HighPart = 0;
1711 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1712 lpLuid->HighPart, lpLuid->LowPart );
1713 return TRUE;
1715 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1716 return FALSE;
1719 /******************************************************************************
1720 * LookupPrivilegeValueA [ADVAPI32.@]
1722 * Retrieves LUID used on a system to represent the privilege name.
1724 * PARAMS
1725 * lpSystemName [I] Name of the system
1726 * lpName [I] Name of the privilege
1727 * lpLuid [O] Destination for the resulting LUID
1729 * RETURNS
1730 * Success: TRUE. lpLuid contains the requested LUID.
1731 * Failure: FALSE.
1733 BOOL WINAPI
1734 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1736 UNICODE_STRING lpSystemNameW;
1737 UNICODE_STRING lpNameW;
1738 BOOL ret;
1740 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1741 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1742 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1743 RtlFreeUnicodeString(&lpNameW);
1744 RtlFreeUnicodeString(&lpSystemNameW);
1745 return ret;
1748 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1749 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1751 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1752 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1754 return FALSE;
1757 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1758 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1760 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1761 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1763 return FALSE;
1766 /******************************************************************************
1767 * LookupPrivilegeNameA [ADVAPI32.@]
1769 * See LookupPrivilegeNameW.
1771 BOOL WINAPI
1772 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1773 LPDWORD cchName)
1775 UNICODE_STRING lpSystemNameW;
1776 BOOL ret;
1777 DWORD wLen = 0;
1779 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1781 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1782 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1783 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1785 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1787 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1788 &wLen);
1789 if (ret)
1791 /* Windows crashes if cchName is NULL, so will I */
1792 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1793 *cchName, NULL, NULL);
1795 if (len == 0)
1797 /* WideCharToMultiByte failed */
1798 ret = FALSE;
1800 else if (len > *cchName)
1802 *cchName = len;
1803 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1804 ret = FALSE;
1806 else
1808 /* WideCharToMultiByte succeeded, output length needs to be
1809 * length not including NULL terminator
1811 *cchName = len - 1;
1814 HeapFree(GetProcessHeap(), 0, lpNameW);
1816 RtlFreeUnicodeString(&lpSystemNameW);
1817 return ret;
1820 /******************************************************************************
1821 * LookupPrivilegeNameW [ADVAPI32.@]
1823 * Retrieves the privilege name referred to by the LUID lpLuid.
1825 * PARAMS
1826 * lpSystemName [I] Name of the system
1827 * lpLuid [I] Privilege value
1828 * lpName [O] Name of the privilege
1829 * cchName [I/O] Number of characters in lpName.
1831 * RETURNS
1832 * Success: TRUE. lpName contains the name of the privilege whose value is
1833 * *lpLuid.
1834 * Failure: FALSE.
1836 * REMARKS
1837 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1838 * using this function.
1839 * If the length of lpName is too small, on return *cchName will contain the
1840 * number of WCHARs needed to contain the privilege, including the NULL
1841 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1842 * On success, *cchName will contain the number of characters stored in
1843 * lpName, NOT including the NULL terminator.
1845 BOOL WINAPI
1846 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1847 LPDWORD cchName)
1849 size_t privNameLen;
1851 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1853 if (!ADVAPI_IsLocalComputer(lpSystemName))
1855 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1856 return FALSE;
1858 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1859 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1861 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1862 return FALSE;
1864 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1865 /* Windows crashes if cchName is NULL, so will I */
1866 if (*cchName <= privNameLen)
1868 *cchName = privNameLen + 1;
1869 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1870 return FALSE;
1872 else
1874 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1875 *cchName = privNameLen;
1876 return TRUE;
1880 /******************************************************************************
1881 * GetFileSecurityA [ADVAPI32.@]
1883 * Obtains Specified information about the security of a file or directory.
1885 * PARAMS
1886 * lpFileName [I] Name of the file to get info for
1887 * RequestedInformation [I] SE_ flags from "winnt.h"
1888 * pSecurityDescriptor [O] Destination for security information
1889 * nLength [I] Length of pSecurityDescriptor
1890 * lpnLengthNeeded [O] Destination for length of returned security information
1892 * RETURNS
1893 * Success: TRUE. pSecurityDescriptor contains the requested information.
1894 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1896 * NOTES
1897 * The information returned is constrained by the callers access rights and
1898 * privileges.
1900 BOOL WINAPI
1901 GetFileSecurityA( LPCSTR lpFileName,
1902 SECURITY_INFORMATION RequestedInformation,
1903 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1904 DWORD nLength, LPDWORD lpnLengthNeeded )
1906 DWORD len;
1907 BOOL r;
1908 LPWSTR name = NULL;
1910 if( lpFileName )
1912 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1913 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1914 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1917 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1918 nLength, lpnLengthNeeded );
1919 HeapFree( GetProcessHeap(), 0, name );
1921 return r;
1924 /******************************************************************************
1925 * GetFileSecurityW [ADVAPI32.@]
1927 * See GetFileSecurityA.
1929 BOOL WINAPI
1930 GetFileSecurityW( LPCWSTR lpFileName,
1931 SECURITY_INFORMATION RequestedInformation,
1932 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1933 DWORD nLength, LPDWORD lpnLengthNeeded )
1935 HANDLE hfile;
1936 NTSTATUS status;
1937 DWORD access = 0;
1939 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1940 RequestedInformation, pSecurityDescriptor,
1941 nLength, lpnLengthNeeded);
1943 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1944 DACL_SECURITY_INFORMATION))
1945 access |= READ_CONTROL;
1946 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1947 access |= ACCESS_SYSTEM_SECURITY;
1949 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1950 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1951 if ( hfile == INVALID_HANDLE_VALUE )
1952 return FALSE;
1954 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1955 nLength, lpnLengthNeeded );
1956 CloseHandle( hfile );
1957 return set_ntstatus( status );
1961 /******************************************************************************
1962 * LookupAccountSidA [ADVAPI32.@]
1964 BOOL WINAPI
1965 LookupAccountSidA(
1966 IN LPCSTR system,
1967 IN PSID sid,
1968 OUT LPSTR account,
1969 IN OUT LPDWORD accountSize,
1970 OUT LPSTR domain,
1971 IN OUT LPDWORD domainSize,
1972 OUT PSID_NAME_USE name_use )
1974 DWORD len;
1975 BOOL r;
1976 LPWSTR systemW = NULL;
1977 LPWSTR accountW = NULL;
1978 LPWSTR domainW = NULL;
1979 DWORD accountSizeW = *accountSize;
1980 DWORD domainSizeW = *domainSize;
1982 if (system) {
1983 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1984 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1985 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1987 if (account)
1988 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1989 if (domain)
1990 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1992 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1994 if (r) {
1995 if (accountW && *accountSize) {
1996 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1997 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1998 *accountSize = len;
1999 } else
2000 *accountSize = accountSizeW + 1;
2002 if (domainW && *domainSize) {
2003 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2004 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2005 *domainSize = len;
2006 } else
2007 *domainSize = domainSizeW + 1;
2010 HeapFree( GetProcessHeap(), 0, systemW );
2011 HeapFree( GetProcessHeap(), 0, accountW );
2012 HeapFree( GetProcessHeap(), 0, domainW );
2014 return r;
2017 /******************************************************************************
2018 * LookupAccountSidW [ADVAPI32.@]
2020 * PARAMS
2021 * system []
2022 * sid []
2023 * account []
2024 * accountSize []
2025 * domain []
2026 * domainSize []
2027 * name_use []
2030 BOOL WINAPI
2031 LookupAccountSidW(
2032 IN LPCWSTR system,
2033 IN PSID sid,
2034 OUT LPWSTR account,
2035 IN OUT LPDWORD accountSize,
2036 OUT LPWSTR domain,
2037 IN OUT LPDWORD domainSize,
2038 OUT PSID_NAME_USE name_use )
2040 unsigned int i, j;
2041 const WCHAR * ac = NULL;
2042 const WCHAR * dm = NULL;
2043 SID_NAME_USE use = 0;
2044 LPWSTR computer_name = NULL;
2045 LPWSTR account_name = NULL;
2047 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2048 debugstr_w(system),debugstr_sid(sid),
2049 account,accountSize,accountSize?*accountSize:0,
2050 domain,domainSize,domainSize?*domainSize:0,
2051 name_use);
2053 if (!ADVAPI_IsLocalComputer(system)) {
2054 FIXME("Only local computer supported!\n");
2055 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2056 return FALSE;
2059 /* check the well known SIDs first */
2060 for (i = 0; i <= 60; i++) {
2061 if (IsWellKnownSid(sid, i)) {
2062 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2063 if (ACCOUNT_SIDS[j].type == i) {
2064 ac = ACCOUNT_SIDS[j].account;
2065 dm = ACCOUNT_SIDS[j].domain;
2066 use = ACCOUNT_SIDS[j].name_use;
2069 break;
2073 if (dm == NULL) {
2074 MAX_SID local;
2076 /* check for the local computer next */
2077 if (ADVAPI_GetComputerSid(&local)) {
2078 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2079 BOOL result;
2081 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2082 result = GetComputerNameW(computer_name, &size);
2084 if (result) {
2085 if (EqualSid(sid, &local)) {
2086 dm = computer_name;
2087 ac = Blank;
2088 use = 3;
2089 } else {
2090 local.SubAuthorityCount++;
2092 if (EqualPrefixSid(sid, &local)) {
2093 dm = computer_name;
2094 use = 1;
2095 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2096 case DOMAIN_USER_RID_ADMIN:
2097 ac = Administrator;
2098 break;
2099 case DOMAIN_USER_RID_GUEST:
2100 ac = Guest;
2101 break;
2102 case DOMAIN_GROUP_RID_ADMINS:
2103 ac = Domain_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_USERS:
2106 ac = Domain_Users;
2107 break;
2108 case DOMAIN_GROUP_RID_GUESTS:
2109 ac = Domain_Guests;
2110 break;
2111 case DOMAIN_GROUP_RID_COMPUTERS:
2112 ac = Domain_Computers;
2113 break;
2114 case DOMAIN_GROUP_RID_CONTROLLERS:
2115 ac = Domain_Controllers;
2116 break;
2117 case DOMAIN_GROUP_RID_CERT_ADMINS:
2118 ac = Cert_Publishers;
2119 break;
2120 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2121 ac = Schema_Admins;
2122 break;
2123 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2124 ac = Enterprise_Admins;
2125 break;
2126 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2127 ac = Group_Policy_Creator_Owners;
2128 break;
2129 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2130 ac = RAS_and_IAS_Servers;
2131 break;
2132 case 1000: /* first user account */
2133 size = UNLEN + 1;
2134 account_name = HeapAlloc(
2135 GetProcessHeap(), 0, size * sizeof(WCHAR));
2136 if (GetUserNameW(account_name, &size))
2137 ac = account_name;
2138 else
2139 dm = NULL;
2141 break;
2142 default:
2143 dm = NULL;
2144 break;
2152 if (dm) {
2153 DWORD ac_len = lstrlenW(ac);
2154 DWORD dm_len = lstrlenW(dm);
2155 BOOL status = TRUE;
2157 if (*accountSize > ac_len) {
2158 if (account)
2159 lstrcpyW(account, ac);
2161 if (*domainSize > dm_len) {
2162 if (domain)
2163 lstrcpyW(domain, dm);
2165 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2166 ((*domainSize != 0) && (*domainSize < dm_len))) {
2167 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2168 status = FALSE;
2170 if (*domainSize)
2171 *domainSize = dm_len;
2172 else
2173 *domainSize = dm_len + 1;
2174 if (*accountSize)
2175 *accountSize = ac_len;
2176 else
2177 *accountSize = ac_len + 1;
2178 *name_use = use;
2179 HeapFree(GetProcessHeap(), 0, account_name);
2180 HeapFree(GetProcessHeap(), 0, computer_name);
2181 return status;
2184 HeapFree(GetProcessHeap(), 0, account_name);
2185 HeapFree(GetProcessHeap(), 0, computer_name);
2186 SetLastError(ERROR_NONE_MAPPED);
2187 return FALSE;
2190 /******************************************************************************
2191 * SetFileSecurityA [ADVAPI32.@]
2193 * See SetFileSecurityW.
2195 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2196 SECURITY_INFORMATION RequestedInformation,
2197 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2199 DWORD len;
2200 BOOL r;
2201 LPWSTR name = NULL;
2203 if( lpFileName )
2205 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2206 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2207 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2210 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2211 HeapFree( GetProcessHeap(), 0, name );
2213 return r;
2216 /******************************************************************************
2217 * SetFileSecurityW [ADVAPI32.@]
2219 * Sets the security of a file or directory.
2221 * PARAMS
2222 * lpFileName []
2223 * RequestedInformation []
2224 * pSecurityDescriptor []
2226 * RETURNS
2227 * Success: TRUE.
2228 * Failure: FALSE.
2230 BOOL WINAPI
2231 SetFileSecurityW( LPCWSTR lpFileName,
2232 SECURITY_INFORMATION RequestedInformation,
2233 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2235 HANDLE file;
2236 DWORD access = 0;
2237 NTSTATUS status;
2239 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2240 pSecurityDescriptor );
2242 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2243 RequestedInformation & GROUP_SECURITY_INFORMATION)
2244 access |= WRITE_OWNER;
2245 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2246 access |= ACCESS_SYSTEM_SECURITY;
2247 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2248 access |= WRITE_DAC;
2250 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2251 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2252 if (file == INVALID_HANDLE_VALUE)
2253 return FALSE;
2255 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2256 CloseHandle( file );
2257 return set_ntstatus( status );
2260 /******************************************************************************
2261 * QueryWindows31FilesMigration [ADVAPI32.@]
2263 * PARAMS
2264 * x1 []
2266 BOOL WINAPI
2267 QueryWindows31FilesMigration( DWORD x1 )
2269 FIXME("(%d):stub\n",x1);
2270 return TRUE;
2273 /******************************************************************************
2274 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2276 * PARAMS
2277 * x1 []
2278 * x2 []
2279 * x3 []
2280 * x4 []
2282 BOOL WINAPI
2283 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2284 DWORD x4 )
2286 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2287 return TRUE;
2290 /******************************************************************************
2291 * NotifyBootConfigStatus [ADVAPI32.@]
2293 * PARAMS
2294 * x1 []
2296 BOOL WINAPI
2297 NotifyBootConfigStatus( BOOL x1 )
2299 FIXME("(0x%08d):stub\n",x1);
2300 return 1;
2303 /******************************************************************************
2304 * RevertToSelf [ADVAPI32.@]
2306 * Ends the impersonation of a user.
2308 * PARAMS
2309 * void []
2311 * RETURNS
2312 * Success: TRUE.
2313 * Failure: FALSE.
2315 BOOL WINAPI
2316 RevertToSelf( void )
2318 HANDLE Token = NULL;
2319 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2320 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2323 /******************************************************************************
2324 * ImpersonateSelf [ADVAPI32.@]
2326 * Makes an impersonation token that represents the process user and assigns
2327 * to the current thread.
2329 * PARAMS
2330 * ImpersonationLevel [I] Level at which to impersonate.
2332 * RETURNS
2333 * Success: TRUE.
2334 * Failure: FALSE.
2336 BOOL WINAPI
2337 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2339 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2342 /******************************************************************************
2343 * ImpersonateLoggedOnUser [ADVAPI32.@]
2345 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2347 DWORD size;
2348 NTSTATUS Status;
2349 HANDLE ImpersonationToken;
2350 TOKEN_TYPE Type;
2351 static BOOL warn = TRUE;
2353 if (warn)
2355 FIXME( "(%p)\n", hToken );
2356 warn = FALSE;
2358 if (!GetTokenInformation( hToken, TokenType, &Type,
2359 sizeof(TOKEN_TYPE), &size ))
2360 return FALSE;
2362 if (Type == TokenPrimary)
2364 OBJECT_ATTRIBUTES ObjectAttributes;
2366 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2368 Status = NtDuplicateToken( hToken,
2369 TOKEN_IMPERSONATE | TOKEN_QUERY,
2370 &ObjectAttributes,
2371 SecurityImpersonation,
2372 TokenImpersonation,
2373 &ImpersonationToken );
2374 if (Status != STATUS_SUCCESS)
2376 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2377 SetLastError( RtlNtStatusToDosError( Status ) );
2378 return FALSE;
2381 else
2382 ImpersonationToken = hToken;
2384 Status = NtSetInformationThread( GetCurrentThread(),
2385 ThreadImpersonationToken,
2386 &ImpersonationToken,
2387 sizeof(ImpersonationToken) );
2389 if (Type == TokenPrimary)
2390 NtClose( ImpersonationToken );
2392 if (Status != STATUS_SUCCESS)
2394 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2395 SetLastError( RtlNtStatusToDosError( Status ) );
2396 return FALSE;
2399 return TRUE;
2402 /******************************************************************************
2403 * AccessCheck [ADVAPI32.@]
2405 BOOL WINAPI
2406 AccessCheck(
2407 PSECURITY_DESCRIPTOR SecurityDescriptor,
2408 HANDLE ClientToken,
2409 DWORD DesiredAccess,
2410 PGENERIC_MAPPING GenericMapping,
2411 PPRIVILEGE_SET PrivilegeSet,
2412 LPDWORD PrivilegeSetLength,
2413 LPDWORD GrantedAccess,
2414 LPBOOL AccessStatus)
2416 NTSTATUS access_status;
2417 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2418 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2419 GrantedAccess, &access_status) );
2420 if (ret) *AccessStatus = set_ntstatus( access_status );
2421 return ret;
2425 /******************************************************************************
2426 * AccessCheckByType [ADVAPI32.@]
2428 BOOL WINAPI AccessCheckByType(
2429 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2430 PSID PrincipalSelfSid,
2431 HANDLE ClientToken,
2432 DWORD DesiredAccess,
2433 POBJECT_TYPE_LIST ObjectTypeList,
2434 DWORD ObjectTypeListLength,
2435 PGENERIC_MAPPING GenericMapping,
2436 PPRIVILEGE_SET PrivilegeSet,
2437 LPDWORD PrivilegeSetLength,
2438 LPDWORD GrantedAccess,
2439 LPBOOL AccessStatus)
2441 FIXME("stub\n");
2443 *AccessStatus = TRUE;
2445 return !*AccessStatus;
2448 /******************************************************************************
2449 * MapGenericMask [ADVAPI32.@]
2451 * Maps generic access rights into specific access rights according to the
2452 * supplied mapping.
2454 * PARAMS
2455 * AccessMask [I/O] Access rights.
2456 * GenericMapping [I] The mapping between generic and specific rights.
2458 * RETURNS
2459 * Nothing.
2461 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2463 RtlMapGenericMask( AccessMask, GenericMapping );
2466 /*************************************************************************
2467 * SetKernelObjectSecurity [ADVAPI32.@]
2469 BOOL WINAPI SetKernelObjectSecurity (
2470 IN HANDLE Handle,
2471 IN SECURITY_INFORMATION SecurityInformation,
2472 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2474 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2478 /******************************************************************************
2479 * AddAuditAccessAce [ADVAPI32.@]
2481 BOOL WINAPI AddAuditAccessAce(
2482 IN OUT PACL pAcl,
2483 IN DWORD dwAceRevision,
2484 IN DWORD dwAccessMask,
2485 IN PSID pSid,
2486 IN BOOL bAuditSuccess,
2487 IN BOOL bAuditFailure)
2489 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2490 bAuditSuccess, bAuditFailure) );
2493 /******************************************************************************
2494 * AddAuditAccessAce [ADVAPI32.@]
2496 BOOL WINAPI AddAuditAccessAceEx(
2497 IN OUT PACL pAcl,
2498 IN DWORD dwAceRevision,
2499 IN DWORD dwAceFlags,
2500 IN DWORD dwAccessMask,
2501 IN PSID pSid,
2502 IN BOOL bAuditSuccess,
2503 IN BOOL bAuditFailure)
2505 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2506 bAuditSuccess, bAuditFailure) );
2509 /******************************************************************************
2510 * LookupAccountNameA [ADVAPI32.@]
2512 BOOL WINAPI
2513 LookupAccountNameA(
2514 IN LPCSTR system,
2515 IN LPCSTR account,
2516 OUT PSID sid,
2517 OUT LPDWORD cbSid,
2518 LPSTR ReferencedDomainName,
2519 IN OUT LPDWORD cbReferencedDomainName,
2520 OUT PSID_NAME_USE name_use )
2522 BOOL ret;
2523 UNICODE_STRING lpSystemW;
2524 UNICODE_STRING lpAccountW;
2525 LPWSTR lpReferencedDomainNameW = NULL;
2527 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2528 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2530 if (ReferencedDomainName)
2531 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2533 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2534 cbReferencedDomainName, name_use);
2536 if (ret && lpReferencedDomainNameW)
2538 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2539 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2542 RtlFreeUnicodeString(&lpSystemW);
2543 RtlFreeUnicodeString(&lpAccountW);
2544 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2546 return ret;
2549 /******************************************************************************
2550 * lookup_user_account_name
2552 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2553 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2555 /* Default implementation: Always return a default SID */
2556 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2557 BOOL ret;
2558 PSID pSid;
2559 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2560 DWORD nameLen;
2561 LPCWSTR domainName;
2563 ret = AllocateAndInitializeSid(&identifierAuthority,
2565 SECURITY_BUILTIN_DOMAIN_RID,
2566 DOMAIN_ALIAS_RID_ADMINS,
2567 0, 0, 0, 0, 0, 0,
2568 &pSid);
2570 if (!ret)
2571 return FALSE;
2573 if (!RtlValidSid(pSid))
2575 FreeSid(pSid);
2576 return FALSE;
2579 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2580 CopySid(*cbSid, Sid, pSid);
2581 if (*cbSid < GetLengthSid(pSid))
2583 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2584 ret = FALSE;
2586 *cbSid = GetLengthSid(pSid);
2588 domainName = dm;
2589 nameLen = strlenW(domainName);
2591 if (*cchReferencedDomainName <= nameLen || !ret)
2593 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2594 nameLen += 1;
2595 ret = FALSE;
2597 else if (ReferencedDomainName)
2598 strcpyW(ReferencedDomainName, domainName);
2600 *cchReferencedDomainName = nameLen;
2602 if (ret)
2603 *peUse = SidTypeUser;
2605 FreeSid(pSid);
2607 return ret;
2610 /******************************************************************************
2611 * lookup_computer_account_name
2613 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2614 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2616 MAX_SID local;
2617 BOOL ret;
2618 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2619 DWORD nameLen;
2620 LPCWSTR domainName;
2622 if ((ret = ADVAPI_GetComputerSid(&local)))
2624 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2625 CopySid(*cbSid, Sid, &local);
2626 if (*cbSid < GetLengthSid(&local))
2628 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2629 ret = FALSE;
2631 *cbSid = GetLengthSid(&local);
2634 domainName = dm;
2635 nameLen = strlenW(domainName);
2637 if (*cchReferencedDomainName <= nameLen || !ret)
2639 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2640 nameLen += 1;
2641 ret = FALSE;
2643 else if (ReferencedDomainName)
2644 strcpyW(ReferencedDomainName, domainName);
2646 *cchReferencedDomainName = nameLen;
2648 if (ret)
2649 *peUse = SidTypeDomain;
2651 return ret;
2654 /******************************************************************************
2655 * LookupAccountNameW [ADVAPI32.@]
2657 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2658 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2659 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2661 BOOL ret;
2662 PSID pSid;
2663 unsigned int i;
2664 DWORD nameLen;
2665 LPWSTR userName = NULL;
2666 LPCWSTR domainName;
2667 LPCWSTR lpAccountNamePtr;
2668 LPCWSTR lpDomainNamePtr = NULL;
2670 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2671 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2673 if (!ADVAPI_IsLocalComputer(lpSystemName))
2675 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2676 return FALSE;
2679 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2681 lpAccountName = BUILTIN;
2684 /* Check well known SIDs first */
2685 if ((lpAccountNamePtr = strrchrW(lpAccountName,'\\')))
2687 lpAccountNamePtr++;
2688 lpDomainNamePtr = lpAccountName;
2690 else
2691 lpAccountNamePtr = lpAccountName;
2693 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2695 /* check domain first */
2696 if (lpDomainNamePtr && (strncmpiW(lpDomainNamePtr, ACCOUNT_SIDS[i].domain, strlenW(ACCOUNT_SIDS[i].domain)) || lpDomainNamePtr[strlenW(ACCOUNT_SIDS[i].domain)]!='\\'))
2697 continue;
2699 if (!strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].account) ||
2700 (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].alias)))
2702 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2704 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2706 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2708 if (ret)
2710 if (*cbSid < sidLen)
2712 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2713 ret = FALSE;
2715 else if (Sid)
2717 CopySid(*cbSid, Sid, pSid);
2720 *cbSid = sidLen;
2723 domainName = ACCOUNT_SIDS[i].domain;
2724 nameLen = strlenW(domainName);
2726 if (*cchReferencedDomainName <= nameLen || !ret)
2728 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2729 nameLen += 1;
2730 ret = FALSE;
2732 else if (ReferencedDomainName)
2734 strcpyW(ReferencedDomainName, domainName);
2737 *cchReferencedDomainName = nameLen;
2739 if (ret)
2741 *peUse = ACCOUNT_SIDS[i].name_use;
2744 HeapFree(GetProcessHeap(), 0, pSid);
2746 return ret;
2750 /* Let the current Unix user id masquerade as first Windows user account */
2752 nameLen = UNLEN + 1;
2754 userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2756 if (lpDomainNamePtr)
2758 /* check to make sure this account is on this computer */
2759 if (GetComputerNameW(userName, &nameLen) && strcmpW(lpDomainNamePtr, userName))
2761 SetLastError(ERROR_NONE_MAPPED);
2762 ret = FALSE;
2766 if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2767 ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2768 cchReferencedDomainName, peUse);
2769 else
2771 nameLen = UNLEN + 1;
2772 if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2773 ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2774 cchReferencedDomainName, peUse);
2775 else
2777 SetLastError(ERROR_NONE_MAPPED);
2778 ret = FALSE;
2782 HeapFree(GetProcessHeap(), 0, userName);
2784 return ret;
2787 /******************************************************************************
2788 * PrivilegeCheck [ADVAPI32.@]
2790 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2792 BOOL ret;
2793 BOOLEAN Result;
2795 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2797 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2798 if (ret)
2799 *pfResult = Result;
2800 return ret;
2803 /******************************************************************************
2804 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2806 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2807 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2808 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2809 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2811 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2812 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2813 SecurityDescriptor, DesiredAccess, GenericMapping,
2814 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2815 return TRUE;
2818 /******************************************************************************
2819 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2821 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2822 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2823 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2824 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2826 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2827 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2828 SecurityDescriptor, DesiredAccess, GenericMapping,
2829 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2830 return TRUE;
2833 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2835 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2837 return TRUE;
2840 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2842 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2844 return TRUE;
2847 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2849 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2851 return TRUE;
2854 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2855 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2856 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2857 LPBOOL GenerateOnClose)
2859 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2860 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2861 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2862 GenerateOnClose);
2864 return TRUE;
2867 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2868 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2869 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2870 LPBOOL GenerateOnClose)
2872 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2873 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2874 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2875 GenerateOnClose);
2877 return TRUE;
2880 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2881 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2883 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2884 DesiredAccess, Privileges, AccessGranted);
2886 return TRUE;
2889 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2890 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2892 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2893 DesiredAccess, Privileges, AccessGranted);
2895 return TRUE;
2898 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2899 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2901 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2902 ClientToken, Privileges, AccessGranted);
2904 return TRUE;
2907 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2908 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2910 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2911 ClientToken, Privileges, AccessGranted);
2913 return TRUE;
2916 /******************************************************************************
2917 * GetSecurityInfo [ADVAPI32.@]
2919 * Retrieves a copy of the security descriptor associated with an object.
2921 * PARAMS
2922 * hObject [I] A handle for the object.
2923 * ObjectType [I] The type of object.
2924 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2925 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2926 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2927 * ppDacl [O] If non-null, receives a pointer to the DACL.
2928 * ppSacl [O] If non-null, receives a pointer to the SACL.
2929 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2930 * which must be freed with LocalFree.
2932 * RETURNS
2933 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2935 DWORD WINAPI GetSecurityInfo(
2936 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2937 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2938 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2939 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2942 PSECURITY_DESCRIPTOR sd;
2943 NTSTATUS status;
2944 ULONG n1, n2;
2945 BOOL present, defaulted;
2947 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2948 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2949 return RtlNtStatusToDosError(status);
2951 sd = LocalAlloc(0, n1);
2952 if (!sd)
2953 return ERROR_NOT_ENOUGH_MEMORY;
2955 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2956 if (status != STATUS_SUCCESS)
2958 LocalFree(sd);
2959 return RtlNtStatusToDosError(status);
2962 if (ppsidOwner)
2964 *ppsidOwner = NULL;
2965 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2967 if (ppsidGroup)
2969 *ppsidGroup = NULL;
2970 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2972 if (ppDacl)
2974 *ppDacl = NULL;
2975 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2977 if (ppSacl)
2979 *ppSacl = NULL;
2980 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2982 if (ppSecurityDescriptor)
2983 *ppSecurityDescriptor = sd;
2985 return ERROR_SUCCESS;
2988 /******************************************************************************
2989 * GetSecurityInfoExA [ADVAPI32.@]
2991 DWORD WINAPI GetSecurityInfoExA(
2992 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2993 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2994 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2995 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2998 FIXME("stub!\n");
2999 return ERROR_BAD_PROVIDER;
3002 /******************************************************************************
3003 * GetSecurityInfoExW [ADVAPI32.@]
3005 DWORD WINAPI GetSecurityInfoExW(
3006 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3007 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3008 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3009 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3012 FIXME("stub!\n");
3013 return ERROR_BAD_PROVIDER;
3016 /******************************************************************************
3017 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3019 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3020 LPSTR pTrusteeName, DWORD AccessPermissions,
3021 ACCESS_MODE AccessMode, DWORD Inheritance )
3023 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3024 AccessPermissions, AccessMode, Inheritance);
3026 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3027 pExplicitAccess->grfAccessMode = AccessMode;
3028 pExplicitAccess->grfInheritance = Inheritance;
3030 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3031 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3032 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3033 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3034 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3037 /******************************************************************************
3038 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3040 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3041 LPWSTR pTrusteeName, DWORD AccessPermissions,
3042 ACCESS_MODE AccessMode, DWORD Inheritance )
3044 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3045 AccessPermissions, AccessMode, Inheritance);
3047 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3048 pExplicitAccess->grfAccessMode = AccessMode;
3049 pExplicitAccess->grfInheritance = Inheritance;
3051 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3052 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3053 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3054 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3055 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3058 /******************************************************************************
3059 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3061 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3062 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3063 LPSTR InheritedObjectTypeName, LPSTR Name )
3065 DWORD ObjectsPresent = 0;
3067 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3068 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3070 /* Fill the OBJECTS_AND_NAME structure */
3071 pObjName->ObjectType = ObjectType;
3072 if (ObjectTypeName != NULL)
3074 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3077 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3078 if (InheritedObjectTypeName != NULL)
3080 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3083 pObjName->ObjectsPresent = ObjectsPresent;
3084 pObjName->ptstrName = Name;
3086 /* Fill the TRUSTEE structure */
3087 pTrustee->pMultipleTrustee = NULL;
3088 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3089 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3090 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3091 pTrustee->ptstrName = (LPSTR)pObjName;
3094 /******************************************************************************
3095 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3097 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3098 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3099 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3101 DWORD ObjectsPresent = 0;
3103 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3104 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3106 /* Fill the OBJECTS_AND_NAME structure */
3107 pObjName->ObjectType = ObjectType;
3108 if (ObjectTypeName != NULL)
3110 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3113 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3114 if (InheritedObjectTypeName != NULL)
3116 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3119 pObjName->ObjectsPresent = ObjectsPresent;
3120 pObjName->ptstrName = Name;
3122 /* Fill the TRUSTEE structure */
3123 pTrustee->pMultipleTrustee = NULL;
3124 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3125 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3126 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3127 pTrustee->ptstrName = (LPWSTR)pObjName;
3130 /******************************************************************************
3131 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3133 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3134 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3136 DWORD ObjectsPresent = 0;
3138 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3140 /* Fill the OBJECTS_AND_SID structure */
3141 if (pObjectGuid != NULL)
3143 pObjSid->ObjectTypeGuid = *pObjectGuid;
3144 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3146 else
3148 ZeroMemory(&pObjSid->ObjectTypeGuid,
3149 sizeof(GUID));
3152 if (pInheritedObjectGuid != NULL)
3154 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3155 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3157 else
3159 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3160 sizeof(GUID));
3163 pObjSid->ObjectsPresent = ObjectsPresent;
3164 pObjSid->pSid = pSid;
3166 /* Fill the TRUSTEE structure */
3167 pTrustee->pMultipleTrustee = NULL;
3168 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3169 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3170 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3171 pTrustee->ptstrName = (LPSTR) pObjSid;
3174 /******************************************************************************
3175 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3177 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3178 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3180 DWORD ObjectsPresent = 0;
3182 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3184 /* Fill the OBJECTS_AND_SID structure */
3185 if (pObjectGuid != NULL)
3187 pObjSid->ObjectTypeGuid = *pObjectGuid;
3188 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3190 else
3192 ZeroMemory(&pObjSid->ObjectTypeGuid,
3193 sizeof(GUID));
3196 if (pInheritedObjectGuid != NULL)
3198 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3199 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3201 else
3203 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3204 sizeof(GUID));
3207 pObjSid->ObjectsPresent = ObjectsPresent;
3208 pObjSid->pSid = pSid;
3210 /* Fill the TRUSTEE structure */
3211 pTrustee->pMultipleTrustee = NULL;
3212 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3213 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3214 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3215 pTrustee->ptstrName = (LPWSTR) pObjSid;
3218 /******************************************************************************
3219 * BuildTrusteeWithSidA [ADVAPI32.@]
3221 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3223 TRACE("%p %p\n", pTrustee, pSid);
3225 pTrustee->pMultipleTrustee = NULL;
3226 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3227 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3228 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3229 pTrustee->ptstrName = pSid;
3232 /******************************************************************************
3233 * BuildTrusteeWithSidW [ADVAPI32.@]
3235 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3237 TRACE("%p %p\n", pTrustee, pSid);
3239 pTrustee->pMultipleTrustee = NULL;
3240 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3241 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3242 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3243 pTrustee->ptstrName = pSid;
3246 /******************************************************************************
3247 * BuildTrusteeWithNameA [ADVAPI32.@]
3249 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3251 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3253 pTrustee->pMultipleTrustee = NULL;
3254 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3255 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3256 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3257 pTrustee->ptstrName = name;
3260 /******************************************************************************
3261 * BuildTrusteeWithNameW [ADVAPI32.@]
3263 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3265 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3267 pTrustee->pMultipleTrustee = NULL;
3268 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3269 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3270 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3271 pTrustee->ptstrName = name;
3274 /******************************************************************************
3275 * GetTrusteeFormA [ADVAPI32.@]
3277 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3279 TRACE("(%p)\n", pTrustee);
3281 if (!pTrustee)
3282 return TRUSTEE_BAD_FORM;
3284 return pTrustee->TrusteeForm;
3287 /******************************************************************************
3288 * GetTrusteeFormW [ADVAPI32.@]
3290 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3292 TRACE("(%p)\n", pTrustee);
3294 if (!pTrustee)
3295 return TRUSTEE_BAD_FORM;
3297 return pTrustee->TrusteeForm;
3300 /******************************************************************************
3301 * GetTrusteeNameA [ADVAPI32.@]
3303 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3305 TRACE("(%p)\n", pTrustee);
3307 if (!pTrustee)
3308 return NULL;
3310 return pTrustee->ptstrName;
3313 /******************************************************************************
3314 * GetTrusteeNameW [ADVAPI32.@]
3316 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3318 TRACE("(%p)\n", pTrustee);
3320 if (!pTrustee)
3321 return NULL;
3323 return pTrustee->ptstrName;
3326 /******************************************************************************
3327 * GetTrusteeTypeA [ADVAPI32.@]
3329 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3331 TRACE("(%p)\n", pTrustee);
3333 if (!pTrustee)
3334 return TRUSTEE_IS_UNKNOWN;
3336 return pTrustee->TrusteeType;
3339 /******************************************************************************
3340 * GetTrusteeTypeW [ADVAPI32.@]
3342 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3344 TRACE("(%p)\n", pTrustee);
3346 if (!pTrustee)
3347 return TRUSTEE_IS_UNKNOWN;
3349 return pTrustee->TrusteeType;
3352 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3353 DWORD nAclInformationLength,
3354 ACL_INFORMATION_CLASS dwAclInformationClass )
3356 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3357 nAclInformationLength, dwAclInformationClass);
3359 return TRUE;
3362 /******************************************************************************
3363 * SetEntriesInAclA [ADVAPI32.@]
3365 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3366 PACL OldAcl, PACL* NewAcl )
3368 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3369 if (NewAcl)
3370 *NewAcl = NULL;
3371 return ERROR_SUCCESS;
3374 /******************************************************************************
3375 * SetEntriesInAclW [ADVAPI32.@]
3377 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3378 PACL OldAcl, PACL* NewAcl )
3380 ULONG i;
3381 PSID *ppsid;
3382 DWORD ret = ERROR_SUCCESS;
3383 DWORD acl_size = sizeof(ACL);
3384 NTSTATUS status;
3386 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3388 *NewAcl = NULL;
3390 if (!count && !OldAcl)
3391 return ERROR_SUCCESS;
3393 /* allocate array of maximum sized sids allowed */
3394 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3395 if (!ppsid)
3396 return ERROR_OUTOFMEMORY;
3398 for (i = 0; i < count; i++)
3400 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3402 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3403 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3404 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3405 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3406 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3407 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3408 pEntries[i].Trustee.ptstrName);
3410 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3412 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3413 ret = ERROR_INVALID_PARAMETER;
3414 goto exit;
3417 switch (pEntries[i].Trustee.TrusteeForm)
3419 case TRUSTEE_IS_SID:
3420 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3421 ppsid[i], pEntries[i].Trustee.ptstrName))
3423 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3424 ret = ERROR_INVALID_PARAMETER;
3425 goto exit;
3427 break;
3428 case TRUSTEE_IS_NAME:
3430 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3431 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3432 SID_NAME_USE use;
3433 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3435 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3436 ret = ERROR_INVALID_PARAMETER;
3437 goto exit;
3439 break;
3441 case TRUSTEE_IS_OBJECTS_AND_SID:
3442 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3443 break;
3444 case TRUSTEE_IS_OBJECTS_AND_NAME:
3445 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3446 break;
3447 default:
3448 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3449 ret = ERROR_INVALID_PARAMETER;
3450 goto exit;
3453 /* Note: we overestimate the ACL size here as a tradeoff between
3454 * instructions (simplicity) and memory */
3455 switch (pEntries[i].grfAccessMode)
3457 case GRANT_ACCESS:
3458 case SET_ACCESS:
3459 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3460 break;
3461 case DENY_ACCESS:
3462 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3463 break;
3464 case SET_AUDIT_SUCCESS:
3465 case SET_AUDIT_FAILURE:
3466 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3467 break;
3468 case REVOKE_ACCESS:
3469 break;
3470 default:
3471 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3472 ret = ERROR_INVALID_PARAMETER;
3473 goto exit;
3477 if (OldAcl)
3479 ACL_SIZE_INFORMATION size_info;
3481 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3482 if (status != STATUS_SUCCESS)
3484 ret = RtlNtStatusToDosError(status);
3485 goto exit;
3487 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3490 *NewAcl = LocalAlloc(0, acl_size);
3491 if (!*NewAcl)
3493 ret = ERROR_OUTOFMEMORY;
3494 goto exit;
3497 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3498 if (status != STATUS_SUCCESS)
3500 ret = RtlNtStatusToDosError(status);
3501 goto exit;
3504 for (i = 0; i < count; i++)
3506 switch (pEntries[i].grfAccessMode)
3508 case GRANT_ACCESS:
3509 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3510 pEntries[i].grfInheritance,
3511 pEntries[i].grfAccessPermissions,
3512 ppsid[i]);
3513 break;
3514 case SET_ACCESS:
3516 ULONG j;
3517 BOOL add = TRUE;
3518 if (OldAcl)
3520 for (j = 0; ; j++)
3522 const ACE_HEADER *existing_ace_header;
3523 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3524 if (status != STATUS_SUCCESS)
3525 break;
3526 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3527 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3528 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3530 add = FALSE;
3531 break;
3535 if (add)
3536 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3537 pEntries[i].grfInheritance,
3538 pEntries[i].grfAccessPermissions,
3539 ppsid[i]);
3540 break;
3542 case DENY_ACCESS:
3543 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3544 pEntries[i].grfInheritance,
3545 pEntries[i].grfAccessPermissions,
3546 ppsid[i]);
3547 break;
3548 case SET_AUDIT_SUCCESS:
3549 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3550 pEntries[i].grfInheritance,
3551 pEntries[i].grfAccessPermissions,
3552 ppsid[i], TRUE, FALSE);
3553 break;
3554 case SET_AUDIT_FAILURE:
3555 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3556 pEntries[i].grfInheritance,
3557 pEntries[i].grfAccessPermissions,
3558 ppsid[i], FALSE, TRUE);
3559 break;
3560 default:
3561 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3565 if (OldAcl)
3567 for (i = 0; ; i++)
3569 BOOL add = TRUE;
3570 ULONG j;
3571 const ACE_HEADER *old_ace_header;
3572 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3573 if (status != STATUS_SUCCESS) break;
3574 for (j = 0; j < count; j++)
3576 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3577 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3578 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3580 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3581 add = FALSE;
3582 break;
3584 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3586 switch (old_ace_header->AceType)
3588 case ACCESS_ALLOWED_ACE_TYPE:
3589 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3590 add = FALSE;
3591 break;
3592 case ACCESS_DENIED_ACE_TYPE:
3593 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3594 add = FALSE;
3595 break;
3596 case SYSTEM_AUDIT_ACE_TYPE:
3597 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3598 add = FALSE;
3599 break;
3600 case SYSTEM_ALARM_ACE_TYPE:
3601 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3602 add = FALSE;
3603 break;
3604 default:
3605 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3608 if (!add)
3609 break;
3612 if (add)
3613 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3614 if (status != STATUS_SUCCESS)
3616 WARN("RtlAddAce failed with error 0x%08x\n", status);
3617 ret = RtlNtStatusToDosError(status);
3618 break;
3623 exit:
3624 HeapFree(GetProcessHeap(), 0, ppsid);
3625 return ret;
3628 /******************************************************************************
3629 * SetNamedSecurityInfoA [ADVAPI32.@]
3631 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3632 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3633 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3635 DWORD len;
3636 LPWSTR wstr = NULL;
3637 DWORD r;
3639 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3640 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3642 if( pObjectName )
3644 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3645 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3646 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3649 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3650 psidGroup, pDacl, pSacl );
3652 HeapFree( GetProcessHeap(), 0, wstr );
3654 return r;
3657 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3658 PSECURITY_DESCRIPTOR ModificationDescriptor,
3659 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3660 PGENERIC_MAPPING GenericMapping,
3661 HANDLE Token )
3663 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3664 ObjectsSecurityDescriptor, GenericMapping, Token);
3666 return TRUE;
3669 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3671 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3674 /******************************************************************************
3675 * AreAnyAccessesGranted [ADVAPI32.@]
3677 * Determines whether or not any of a set of specified access permissions have
3678 * been granted or not.
3680 * PARAMS
3681 * GrantedAccess [I] The permissions that have been granted.
3682 * DesiredAccess [I] The permissions that you want to have.
3684 * RETURNS
3685 * Nonzero if any of the permissions have been granted, zero if none of the
3686 * permissions have been granted.
3689 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3691 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3694 /******************************************************************************
3695 * SetNamedSecurityInfoW [ADVAPI32.@]
3697 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3698 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3699 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3701 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3702 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3703 return ERROR_SUCCESS;
3706 /******************************************************************************
3707 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3709 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3710 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3712 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3713 return ERROR_CALL_NOT_IMPLEMENTED;
3716 /******************************************************************************
3717 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3719 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3720 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3722 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3723 return ERROR_CALL_NOT_IMPLEMENTED;
3726 /******************************************************************************
3727 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3729 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3730 PACCESS_MASK pFailedAuditRights)
3732 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3733 return ERROR_CALL_NOT_IMPLEMENTED;
3737 /******************************************************************************
3738 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3740 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3741 PACCESS_MASK pFailedAuditRights)
3743 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3744 return ERROR_CALL_NOT_IMPLEMENTED;
3748 /******************************************************************************
3749 * ParseAclStringFlags
3751 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3753 DWORD flags = 0;
3754 LPCWSTR szAcl = *StringAcl;
3756 while (*szAcl != '(')
3758 if (*szAcl == 'P')
3760 flags |= SE_DACL_PROTECTED;
3762 else if (*szAcl == 'A')
3764 szAcl++;
3765 if (*szAcl == 'R')
3766 flags |= SE_DACL_AUTO_INHERIT_REQ;
3767 else if (*szAcl == 'I')
3768 flags |= SE_DACL_AUTO_INHERITED;
3770 szAcl++;
3773 *StringAcl = szAcl;
3774 return flags;
3777 /******************************************************************************
3778 * ParseAceStringType
3780 static const ACEFLAG AceType[] =
3782 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3783 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3784 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3785 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3787 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3788 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3789 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3790 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3792 { NULL, 0 },
3795 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3797 UINT len = 0;
3798 LPCWSTR szAcl = *StringAcl;
3799 const ACEFLAG *lpaf = AceType;
3801 while (lpaf->wstr &&
3802 (len = strlenW(lpaf->wstr)) &&
3803 strncmpW(lpaf->wstr, szAcl, len))
3804 lpaf++;
3806 if (!lpaf->wstr)
3807 return 0;
3809 *StringAcl += len;
3810 return lpaf->value;
3814 /******************************************************************************
3815 * ParseAceStringFlags
3817 static const ACEFLAG AceFlags[] =
3819 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3820 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3821 { SDDL_INHERITED, INHERITED_ACE },
3822 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3823 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3824 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3825 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3826 { NULL, 0 },
3829 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3831 UINT len = 0;
3832 BYTE flags = 0;
3833 LPCWSTR szAcl = *StringAcl;
3835 while (*szAcl != ';')
3837 const ACEFLAG *lpaf = AceFlags;
3839 while (lpaf->wstr &&
3840 (len = strlenW(lpaf->wstr)) &&
3841 strncmpW(lpaf->wstr, szAcl, len))
3842 lpaf++;
3844 if (!lpaf->wstr)
3845 return 0;
3847 flags |= lpaf->value;
3848 szAcl += len;
3851 *StringAcl = szAcl;
3852 return flags;
3856 /******************************************************************************
3857 * ParseAceStringRights
3859 static const ACEFLAG AceRights[] =
3861 { SDDL_GENERIC_ALL, GENERIC_ALL },
3862 { SDDL_GENERIC_READ, GENERIC_READ },
3863 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3864 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3866 { SDDL_READ_CONTROL, READ_CONTROL },
3867 { SDDL_STANDARD_DELETE, DELETE },
3868 { SDDL_WRITE_DAC, WRITE_DAC },
3869 { SDDL_WRITE_OWNER, WRITE_OWNER },
3871 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3872 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3873 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3874 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3875 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3876 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3877 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3878 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3879 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3881 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3882 { SDDL_FILE_READ, FILE_GENERIC_READ },
3883 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3884 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3886 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3887 { SDDL_KEY_READ, KEY_READ },
3888 { SDDL_KEY_WRITE, KEY_WRITE },
3889 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3890 { NULL, 0 },
3893 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3895 UINT len = 0;
3896 DWORD rights = 0;
3897 LPCWSTR szAcl = *StringAcl;
3899 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3901 LPCWSTR p = szAcl;
3903 while (*p && *p != ';')
3904 p++;
3906 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3908 rights = strtoulW(szAcl, NULL, 16);
3909 szAcl = p;
3911 else
3912 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3914 else
3916 while (*szAcl != ';')
3918 const ACEFLAG *lpaf = AceRights;
3920 while (lpaf->wstr &&
3921 (len = strlenW(lpaf->wstr)) &&
3922 strncmpW(lpaf->wstr, szAcl, len))
3924 lpaf++;
3927 if (!lpaf->wstr)
3928 return 0;
3930 rights |= lpaf->value;
3931 szAcl += len;
3935 *StringAcl = szAcl;
3936 return rights;
3940 /******************************************************************************
3941 * ParseStringAclToAcl
3943 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3945 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3946 PACL pAcl, LPDWORD cBytes)
3948 DWORD val;
3949 DWORD sidlen;
3950 DWORD length = sizeof(ACL);
3951 DWORD acesize = 0;
3952 DWORD acecount = 0;
3953 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3955 TRACE("%s\n", debugstr_w(StringAcl));
3957 if (!StringAcl)
3958 return FALSE;
3960 if (pAcl) /* pAce is only useful if we're setting values */
3961 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3963 /* Parse ACL flags */
3964 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3966 /* Parse ACE */
3967 while (*StringAcl == '(')
3969 StringAcl++;
3971 /* Parse ACE type */
3972 val = ParseAceStringType(&StringAcl);
3973 if (pAce)
3974 pAce->Header.AceType = (BYTE) val;
3975 if (*StringAcl != ';')
3976 goto lerr;
3977 StringAcl++;
3979 /* Parse ACE flags */
3980 val = ParseAceStringFlags(&StringAcl);
3981 if (pAce)
3982 pAce->Header.AceFlags = (BYTE) val;
3983 if (*StringAcl != ';')
3984 goto lerr;
3985 StringAcl++;
3987 /* Parse ACE rights */
3988 val = ParseAceStringRights(&StringAcl);
3989 if (pAce)
3990 pAce->Mask = val;
3991 if (*StringAcl != ';')
3992 goto lerr;
3993 StringAcl++;
3995 /* Parse ACE object guid */
3996 if (*StringAcl != ';')
3998 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3999 goto lerr;
4001 StringAcl++;
4003 /* Parse ACE inherit object guid */
4004 if (*StringAcl != ';')
4006 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4007 goto lerr;
4009 StringAcl++;
4011 /* Parse ACE account sid */
4012 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4014 while (*StringAcl && *StringAcl != ')')
4015 StringAcl++;
4018 if (*StringAcl != ')')
4019 goto lerr;
4020 StringAcl++;
4022 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4023 length += acesize;
4024 if (pAce)
4026 pAce->Header.AceSize = acesize;
4027 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4029 acecount++;
4032 *cBytes = length;
4034 if (length > 0xffff)
4036 ERR("ACL too large\n");
4037 goto lerr;
4040 if (pAcl)
4042 pAcl->AclRevision = ACL_REVISION;
4043 pAcl->Sbz1 = 0;
4044 pAcl->AclSize = length;
4045 pAcl->AceCount = acecount++;
4046 pAcl->Sbz2 = 0;
4048 return TRUE;
4050 lerr:
4051 SetLastError(ERROR_INVALID_ACL);
4052 WARN("Invalid ACE string format\n");
4053 return FALSE;
4057 /******************************************************************************
4058 * ParseStringSecurityDescriptorToSecurityDescriptor
4060 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4061 LPCWSTR StringSecurityDescriptor,
4062 SECURITY_DESCRIPTOR* SecurityDescriptor,
4063 LPDWORD cBytes)
4065 BOOL bret = FALSE;
4066 WCHAR toktype;
4067 WCHAR tok[MAX_PATH];
4068 LPCWSTR lptoken;
4069 LPBYTE lpNext = NULL;
4070 DWORD len;
4072 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4074 if (SecurityDescriptor)
4075 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
4077 while (*StringSecurityDescriptor)
4079 toktype = *StringSecurityDescriptor;
4081 /* Expect char identifier followed by ':' */
4082 StringSecurityDescriptor++;
4083 if (*StringSecurityDescriptor != ':')
4085 SetLastError(ERROR_INVALID_PARAMETER);
4086 goto lend;
4088 StringSecurityDescriptor++;
4090 /* Extract token */
4091 lptoken = StringSecurityDescriptor;
4092 while (*lptoken && *lptoken != ':')
4093 lptoken++;
4095 if (*lptoken)
4096 lptoken--;
4098 len = lptoken - StringSecurityDescriptor;
4099 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4100 tok[len] = 0;
4102 switch (toktype)
4104 case 'O':
4106 DWORD bytes;
4108 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4109 goto lend;
4111 if (SecurityDescriptor)
4113 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4114 lpNext += bytes; /* Advance to next token */
4117 *cBytes += bytes;
4119 break;
4122 case 'G':
4124 DWORD bytes;
4126 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4127 goto lend;
4129 if (SecurityDescriptor)
4131 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4132 lpNext += bytes; /* Advance to next token */
4135 *cBytes += bytes;
4137 break;
4140 case 'D':
4142 DWORD flags;
4143 DWORD bytes;
4145 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4146 goto lend;
4148 if (SecurityDescriptor)
4150 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4151 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4152 lpNext += bytes; /* Advance to next token */
4155 *cBytes += bytes;
4157 break;
4160 case 'S':
4162 DWORD flags;
4163 DWORD bytes;
4165 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4166 goto lend;
4168 if (SecurityDescriptor)
4170 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4171 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4172 lpNext += bytes; /* Advance to next token */
4175 *cBytes += bytes;
4177 break;
4180 default:
4181 FIXME("Unknown token\n");
4182 SetLastError(ERROR_INVALID_PARAMETER);
4183 goto lend;
4186 StringSecurityDescriptor = lptoken;
4189 bret = TRUE;
4191 lend:
4192 return bret;
4195 /******************************************************************************
4196 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4198 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4199 LPCSTR StringSecurityDescriptor,
4200 DWORD StringSDRevision,
4201 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4202 PULONG SecurityDescriptorSize)
4204 UINT len;
4205 BOOL ret = FALSE;
4206 LPWSTR StringSecurityDescriptorW;
4208 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4209 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4211 if (StringSecurityDescriptorW)
4213 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4215 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4216 StringSDRevision, SecurityDescriptor,
4217 SecurityDescriptorSize);
4218 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4221 return ret;
4224 /******************************************************************************
4225 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4227 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4228 LPCWSTR StringSecurityDescriptor,
4229 DWORD StringSDRevision,
4230 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4231 PULONG SecurityDescriptorSize)
4233 DWORD cBytes;
4234 SECURITY_DESCRIPTOR* psd;
4235 BOOL bret = FALSE;
4237 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4239 if (GetVersion() & 0x80000000)
4241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4242 goto lend;
4244 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4246 SetLastError(ERROR_INVALID_PARAMETER);
4247 goto lend;
4249 else if (StringSDRevision != SID_REVISION)
4251 SetLastError(ERROR_UNKNOWN_REVISION);
4252 goto lend;
4255 /* Compute security descriptor length */
4256 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4257 NULL, &cBytes))
4258 goto lend;
4260 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4261 if (!psd) goto lend;
4263 psd->Revision = SID_REVISION;
4264 psd->Control |= SE_SELF_RELATIVE;
4266 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4267 psd, &cBytes))
4269 LocalFree(psd);
4270 goto lend;
4273 if (SecurityDescriptorSize)
4274 *SecurityDescriptorSize = cBytes;
4276 bret = TRUE;
4278 lend:
4279 TRACE(" ret=%d\n", bret);
4280 return bret;
4283 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4285 if (cch == -1)
4286 cch = strlenW(string);
4288 if (plen)
4289 *plen += cch;
4291 if (pwptr)
4293 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4294 *pwptr += cch;
4298 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4300 DWORD i;
4301 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4302 WCHAR subauthfmt[] = { '-','%','u',0 };
4303 WCHAR buf[26];
4304 SID *pisid = psid;
4306 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4308 SetLastError(ERROR_INVALID_SID);
4309 return FALSE;
4312 if (pisid->IdentifierAuthority.Value[0] ||
4313 pisid->IdentifierAuthority.Value[1])
4315 FIXME("not matching MS' bugs\n");
4316 SetLastError(ERROR_INVALID_SID);
4317 return FALSE;
4320 sprintfW( buf, fmt, pisid->Revision,
4321 MAKELONG(
4322 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4323 pisid->IdentifierAuthority.Value[4] ),
4324 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4325 pisid->IdentifierAuthority.Value[2] )
4326 ) );
4327 DumpString(buf, -1, pwptr, plen);
4329 for( i=0; i<pisid->SubAuthorityCount; i++ )
4331 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4332 DumpString(buf, -1, pwptr, plen);
4334 return TRUE;
4337 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4339 size_t i;
4340 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4342 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4344 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4345 return TRUE;
4349 return DumpSidNumeric(psid, pwptr, plen);
4352 static const LPCWSTR AceRightBitNames[32] = {
4353 SDDL_CREATE_CHILD, /* 0 */
4354 SDDL_DELETE_CHILD,
4355 SDDL_LIST_CHILDREN,
4356 SDDL_SELF_WRITE,
4357 SDDL_READ_PROPERTY, /* 4 */
4358 SDDL_WRITE_PROPERTY,
4359 SDDL_DELETE_TREE,
4360 SDDL_LIST_OBJECT,
4361 SDDL_CONTROL_ACCESS, /* 8 */
4362 NULL,
4363 NULL,
4364 NULL,
4365 NULL, /* 12 */
4366 NULL,
4367 NULL,
4368 NULL,
4369 SDDL_STANDARD_DELETE, /* 16 */
4370 SDDL_READ_CONTROL,
4371 SDDL_WRITE_DAC,
4372 SDDL_WRITE_OWNER,
4373 NULL, /* 20 */
4374 NULL,
4375 NULL,
4376 NULL,
4377 NULL, /* 24 */
4378 NULL,
4379 NULL,
4380 NULL,
4381 SDDL_GENERIC_ALL, /* 28 */
4382 SDDL_GENERIC_EXECUTE,
4383 SDDL_GENERIC_WRITE,
4384 SDDL_GENERIC_READ
4387 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4389 static const WCHAR fmtW[] = {'0','x','%','x',0};
4390 WCHAR buf[15];
4391 size_t i;
4393 if (mask == 0)
4394 return;
4396 /* first check if the right have name */
4397 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4399 if (AceRights[i].wstr == NULL)
4400 break;
4401 if (mask == AceRights[i].value)
4403 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4404 return;
4408 /* then check if it can be built from bit names */
4409 for (i = 0; i < 32; i++)
4411 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4413 /* can't be built from bit names */
4414 sprintfW(buf, fmtW, mask);
4415 DumpString(buf, -1, pwptr, plen);
4416 return;
4420 /* build from bit names */
4421 for (i = 0; i < 32; i++)
4422 if (mask & (1 << i))
4423 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4426 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4428 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4429 static const WCHAR openbr = '(';
4430 static const WCHAR closebr = ')';
4431 static const WCHAR semicolon = ';';
4433 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4435 SetLastError(ERROR_INVALID_ACL);
4436 return FALSE;
4439 piace = pace;
4440 DumpString(&openbr, 1, pwptr, plen);
4441 switch (piace->Header.AceType)
4443 case ACCESS_ALLOWED_ACE_TYPE:
4444 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4445 break;
4446 case ACCESS_DENIED_ACE_TYPE:
4447 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4448 break;
4449 case SYSTEM_AUDIT_ACE_TYPE:
4450 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4451 break;
4452 case SYSTEM_ALARM_ACE_TYPE:
4453 DumpString(SDDL_ALARM, -1, pwptr, plen);
4454 break;
4456 DumpString(&semicolon, 1, pwptr, plen);
4458 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4459 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4460 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4461 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4462 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4463 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4464 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4465 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4466 if (piace->Header.AceFlags & INHERITED_ACE)
4467 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4468 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4469 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4470 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4471 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4472 DumpString(&semicolon, 1, pwptr, plen);
4473 DumpRights(piace->Mask, pwptr, plen);
4474 DumpString(&semicolon, 1, pwptr, plen);
4475 /* objects not supported */
4476 DumpString(&semicolon, 1, pwptr, plen);
4477 /* objects not supported */
4478 DumpString(&semicolon, 1, pwptr, plen);
4479 if (!DumpSid(&piace->SidStart, pwptr, plen))
4480 return FALSE;
4481 DumpString(&closebr, 1, pwptr, plen);
4482 return TRUE;
4485 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4487 WORD count;
4488 int i;
4490 if (protected)
4491 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4492 if (autoInheritReq)
4493 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4494 if (autoInherited)
4495 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4497 if (pacl == NULL)
4498 return TRUE;
4500 if (!IsValidAcl(pacl))
4501 return FALSE;
4503 count = pacl->AceCount;
4504 for (i = 0; i < count; i++)
4506 LPVOID ace;
4507 if (!GetAce(pacl, i, &ace))
4508 return FALSE;
4509 if (!DumpAce(ace, pwptr, plen))
4510 return FALSE;
4513 return TRUE;
4516 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4518 static const WCHAR prefix[] = {'O',':',0};
4519 BOOL bDefaulted;
4520 PSID psid;
4522 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4523 return FALSE;
4525 if (psid == NULL)
4526 return TRUE;
4528 DumpString(prefix, -1, pwptr, plen);
4529 if (!DumpSid(psid, pwptr, plen))
4530 return FALSE;
4531 return TRUE;
4534 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4536 static const WCHAR prefix[] = {'G',':',0};
4537 BOOL bDefaulted;
4538 PSID psid;
4540 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4541 return FALSE;
4543 if (psid == NULL)
4544 return TRUE;
4546 DumpString(prefix, -1, pwptr, plen);
4547 if (!DumpSid(psid, pwptr, plen))
4548 return FALSE;
4549 return TRUE;
4552 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4554 static const WCHAR dacl[] = {'D',':',0};
4555 SECURITY_DESCRIPTOR_CONTROL control;
4556 BOOL present, defaulted;
4557 DWORD revision;
4558 PACL pacl;
4560 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4561 return FALSE;
4563 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4564 return FALSE;
4566 if (!present)
4567 return TRUE;
4569 DumpString(dacl, 2, pwptr, plen);
4570 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4571 return FALSE;
4572 return TRUE;
4575 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4577 static const WCHAR sacl[] = {'S',':',0};
4578 SECURITY_DESCRIPTOR_CONTROL control;
4579 BOOL present, defaulted;
4580 DWORD revision;
4581 PACL pacl;
4583 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4584 return FALSE;
4586 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4587 return FALSE;
4589 if (!present)
4590 return TRUE;
4592 DumpString(sacl, 2, pwptr, plen);
4593 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4594 return FALSE;
4595 return TRUE;
4598 /******************************************************************************
4599 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4601 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4603 ULONG len;
4604 WCHAR *wptr, *wstr;
4606 if (SDRevision != SDDL_REVISION_1)
4608 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4609 SetLastError(ERROR_UNKNOWN_REVISION);
4610 return FALSE;
4613 len = 0;
4614 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4615 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4616 return FALSE;
4617 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4618 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4619 return FALSE;
4620 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4621 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4622 return FALSE;
4623 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4624 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4625 return FALSE;
4627 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4628 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4629 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4630 return FALSE;
4631 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4632 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4633 return FALSE;
4634 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4635 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4636 return FALSE;
4637 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4638 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4639 return FALSE;
4640 *wptr = 0;
4642 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4643 *OutputString = wstr;
4644 if (OutputLen)
4645 *OutputLen = strlenW(*OutputString)+1;
4646 return TRUE;
4649 /******************************************************************************
4650 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4652 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4654 LPWSTR wstr;
4655 ULONG len;
4656 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4658 int lenA;
4660 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4661 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4662 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4663 LocalFree(wstr);
4665 if (OutputLen != NULL)
4666 *OutputLen = lenA;
4667 return TRUE;
4669 else
4671 *OutputString = NULL;
4672 if (OutputLen)
4673 *OutputLen = 0;
4674 return FALSE;
4678 /******************************************************************************
4679 * ConvertStringSidToSidW [ADVAPI32.@]
4681 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4683 BOOL bret = FALSE;
4684 DWORD cBytes;
4686 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4687 if (GetVersion() & 0x80000000)
4688 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4689 else if (!StringSid || !Sid)
4690 SetLastError(ERROR_INVALID_PARAMETER);
4691 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4693 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4695 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4696 if (!bret)
4697 LocalFree(*Sid);
4699 return bret;
4702 /******************************************************************************
4703 * ConvertStringSidToSidA [ADVAPI32.@]
4705 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4707 BOOL bret = FALSE;
4709 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4710 if (GetVersion() & 0x80000000)
4711 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4712 else if (!StringSid || !Sid)
4713 SetLastError(ERROR_INVALID_PARAMETER);
4714 else
4716 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4717 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4718 len * sizeof(WCHAR));
4720 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4721 bret = ConvertStringSidToSidW(wStringSid, Sid);
4722 HeapFree(GetProcessHeap(), 0, wStringSid);
4724 return bret;
4727 /******************************************************************************
4728 * ConvertSidToStringSidW [ADVAPI32.@]
4730 * format of SID string is:
4731 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4732 * where
4733 * <rev> is the revision of the SID encoded as decimal
4734 * <auth> is the identifier authority encoded as hex
4735 * <subauthN> is the subauthority id encoded as decimal
4737 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4739 DWORD len = 0;
4740 LPWSTR wstr, wptr;
4742 TRACE("%p %p\n", pSid, pstr );
4744 len = 0;
4745 if (!DumpSidNumeric(pSid, NULL, &len))
4746 return FALSE;
4747 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4748 DumpSidNumeric(pSid, &wptr, NULL);
4749 *wptr = 0;
4751 *pstr = wstr;
4752 return TRUE;
4755 /******************************************************************************
4756 * ConvertSidToStringSidA [ADVAPI32.@]
4758 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4760 LPWSTR wstr = NULL;
4761 LPSTR str;
4762 UINT len;
4764 TRACE("%p %p\n", pSid, pstr );
4766 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4767 return FALSE;
4769 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4770 str = LocalAlloc( 0, len );
4771 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4772 LocalFree( wstr );
4774 *pstr = str;
4776 return TRUE;
4779 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4780 PSECURITY_DESCRIPTOR pdesc,
4781 PSECURITY_DESCRIPTOR cdesc,
4782 PSECURITY_DESCRIPTOR* ndesc,
4783 GUID* objtype,
4784 BOOL isdir,
4785 PGENERIC_MAPPING genmap )
4787 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4789 return FALSE;
4792 BOOL WINAPI CreatePrivateObjectSecurity(
4793 PSECURITY_DESCRIPTOR ParentDescriptor,
4794 PSECURITY_DESCRIPTOR CreatorDescriptor,
4795 PSECURITY_DESCRIPTOR* NewDescriptor,
4796 BOOL IsDirectoryObject,
4797 HANDLE Token,
4798 PGENERIC_MAPPING GenericMapping )
4800 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4801 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4803 return FALSE;
4806 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4808 FIXME("%p - stub\n", ObjectDescriptor);
4810 return TRUE;
4813 BOOL WINAPI CreateProcessAsUserA(
4814 HANDLE hToken,
4815 LPCSTR lpApplicationName,
4816 LPSTR lpCommandLine,
4817 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4818 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4819 BOOL bInheritHandles,
4820 DWORD dwCreationFlags,
4821 LPVOID lpEnvironment,
4822 LPCSTR lpCurrentDirectory,
4823 LPSTARTUPINFOA lpStartupInfo,
4824 LPPROCESS_INFORMATION lpProcessInformation )
4826 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4827 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4828 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4830 return FALSE;
4833 BOOL WINAPI CreateProcessAsUserW(
4834 HANDLE hToken,
4835 LPCWSTR lpApplicationName,
4836 LPWSTR lpCommandLine,
4837 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4838 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4839 BOOL bInheritHandles,
4840 DWORD dwCreationFlags,
4841 LPVOID lpEnvironment,
4842 LPCWSTR lpCurrentDirectory,
4843 LPSTARTUPINFOW lpStartupInfo,
4844 LPPROCESS_INFORMATION lpProcessInformation )
4846 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4847 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4848 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4849 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4851 /* We should create the process with a suspended main thread */
4852 if (!CreateProcessW (lpApplicationName,
4853 lpCommandLine,
4854 lpProcessAttributes,
4855 lpThreadAttributes,
4856 bInheritHandles,
4857 dwCreationFlags, /* CREATE_SUSPENDED */
4858 lpEnvironment,
4859 lpCurrentDirectory,
4860 lpStartupInfo,
4861 lpProcessInformation))
4863 return FALSE;
4866 return TRUE;
4869 /******************************************************************************
4870 * CreateProcessWithLogonW
4872 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4873 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4874 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4876 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4877 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4878 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4879 lpStartupInfo, lpProcessInformation);
4881 return FALSE;
4884 /******************************************************************************
4885 * DuplicateTokenEx [ADVAPI32.@]
4887 BOOL WINAPI DuplicateTokenEx(
4888 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4889 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4890 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4891 TOKEN_TYPE TokenType,
4892 PHANDLE DuplicateTokenHandle )
4894 OBJECT_ATTRIBUTES ObjectAttributes;
4896 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4897 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4899 InitializeObjectAttributes(
4900 &ObjectAttributes,
4901 NULL,
4902 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4903 NULL,
4904 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4906 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4907 dwDesiredAccess,
4908 &ObjectAttributes,
4909 ImpersonationLevel,
4910 TokenType,
4911 DuplicateTokenHandle ) );
4914 BOOL WINAPI DuplicateToken(
4915 HANDLE ExistingTokenHandle,
4916 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4917 PHANDLE DuplicateTokenHandle )
4919 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4920 NULL, ImpersonationLevel, TokenImpersonation,
4921 DuplicateTokenHandle );
4924 /******************************************************************************
4925 * ComputeStringSidSize
4927 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4929 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4931 int ctok = 0;
4932 while (*StringSid)
4934 if (*StringSid == '-')
4935 ctok++;
4936 StringSid++;
4939 if (ctok >= 3)
4940 return GetSidLengthRequired(ctok - 2);
4942 else /* String constant format - Only available in winxp and above */
4944 unsigned int i;
4946 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4947 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4948 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4951 return GetSidLengthRequired(0);
4954 /******************************************************************************
4955 * ParseStringSidToSid
4957 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4959 BOOL bret = FALSE;
4960 SID* pisid=pSid;
4962 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4963 if (!StringSid)
4965 SetLastError(ERROR_INVALID_PARAMETER);
4966 TRACE("StringSid is NULL, returning FALSE\n");
4967 return FALSE;
4970 *cBytes = ComputeStringSidSize(StringSid);
4971 if (!pisid) /* Simply compute the size */
4973 TRACE("only size requested, returning TRUE\n");
4974 return TRUE;
4977 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4979 DWORD i = 0, identAuth;
4980 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4982 StringSid += 2; /* Advance to Revision */
4983 pisid->Revision = atoiW(StringSid);
4985 if (pisid->Revision != SDDL_REVISION)
4987 TRACE("Revision %d is unknown\n", pisid->Revision);
4988 goto lend; /* ERROR_INVALID_SID */
4990 if (csubauth == 0)
4992 TRACE("SubAuthorityCount is 0\n");
4993 goto lend; /* ERROR_INVALID_SID */
4996 pisid->SubAuthorityCount = csubauth;
4998 /* Advance to identifier authority */
4999 while (*StringSid && *StringSid != '-')
5000 StringSid++;
5001 if (*StringSid == '-')
5002 StringSid++;
5004 /* MS' implementation can't handle values greater than 2^32 - 1, so
5005 * we don't either; assume most significant bytes are always 0
5007 pisid->IdentifierAuthority.Value[0] = 0;
5008 pisid->IdentifierAuthority.Value[1] = 0;
5009 identAuth = atoiW(StringSid);
5010 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5011 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5012 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5013 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5015 /* Advance to first sub authority */
5016 while (*StringSid && *StringSid != '-')
5017 StringSid++;
5018 if (*StringSid == '-')
5019 StringSid++;
5021 while (*StringSid)
5023 pisid->SubAuthority[i++] = atoiW(StringSid);
5025 while (*StringSid && *StringSid != '-')
5026 StringSid++;
5027 if (*StringSid == '-')
5028 StringSid++;
5031 if (i != pisid->SubAuthorityCount)
5032 goto lend; /* ERROR_INVALID_SID */
5034 bret = TRUE;
5036 else /* String constant format - Only available in winxp and above */
5038 unsigned int i;
5039 pisid->Revision = SDDL_REVISION;
5041 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5042 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5044 DWORD j;
5045 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5046 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5047 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5048 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5049 bret = TRUE;
5052 if (!bret)
5053 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5056 lend:
5057 if (!bret)
5058 SetLastError(ERROR_INVALID_SID);
5060 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5061 return bret;
5064 /******************************************************************************
5065 * GetNamedSecurityInfoA [ADVAPI32.@]
5067 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5068 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5069 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5070 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5072 DWORD len;
5073 LPWSTR wstr = NULL;
5074 DWORD r;
5076 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5077 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5079 if( pObjectName )
5081 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5082 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5083 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5086 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5087 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5089 HeapFree( GetProcessHeap(), 0, wstr );
5091 return r;
5094 /******************************************************************************
5095 * GetNamedSecurityInfoW [ADVAPI32.@]
5097 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5098 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5099 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5101 DWORD needed, offset;
5102 SECURITY_DESCRIPTOR_RELATIVE *relative;
5103 BYTE *buffer;
5105 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5106 group, dacl, sacl, descriptor );
5108 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5110 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5111 if (info & OWNER_SECURITY_INFORMATION)
5112 needed += sizeof(sidWorld);
5113 if (info & GROUP_SECURITY_INFORMATION)
5114 needed += sizeof(sidWorld);
5115 if (info & DACL_SECURITY_INFORMATION)
5116 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5117 if (info & SACL_SECURITY_INFORMATION)
5118 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5120 /* must be freed by caller */
5121 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5122 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5124 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5126 HeapFree( GetProcessHeap(), 0, *descriptor );
5127 return ERROR_INVALID_SECURITY_DESCR;
5130 relative = *descriptor;
5131 relative->Control |= SE_SELF_RELATIVE;
5132 buffer = (BYTE *)relative;
5133 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5135 if (info & OWNER_SECURITY_INFORMATION)
5137 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5138 relative->Owner = offset;
5139 if (owner)
5140 *owner = buffer + offset;
5141 offset += sizeof(sidWorld);
5143 if (info & GROUP_SECURITY_INFORMATION)
5145 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5146 relative->Group = offset;
5147 if (group)
5148 *group = buffer + offset;
5149 offset += sizeof(sidWorld);
5151 if (info & DACL_SECURITY_INFORMATION)
5153 relative->Control |= SE_DACL_PRESENT;
5154 GetWorldAccessACL( (PACL)(buffer + offset) );
5155 relative->Dacl = offset;
5156 if (dacl)
5157 *dacl = (PACL)(buffer + offset);
5158 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5160 if (info & SACL_SECURITY_INFORMATION)
5162 relative->Control |= SE_SACL_PRESENT;
5163 GetWorldAccessACL( (PACL)(buffer + offset) );
5164 relative->Sacl = offset;
5165 if (sacl)
5166 *sacl = (PACL)(buffer + offset);
5168 return ERROR_SUCCESS;
5171 /******************************************************************************
5172 * DecryptFileW [ADVAPI32.@]
5174 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5176 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5177 return TRUE;
5180 /******************************************************************************
5181 * DecryptFileA [ADVAPI32.@]
5183 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5185 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5186 return TRUE;
5189 /******************************************************************************
5190 * EncryptFileW [ADVAPI32.@]
5192 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5194 FIXME("%s\n", debugstr_w(lpFileName));
5195 return TRUE;
5198 /******************************************************************************
5199 * EncryptFileA [ADVAPI32.@]
5201 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5203 FIXME("%s\n", debugstr_a(lpFileName));
5204 return TRUE;
5207 /******************************************************************************
5208 * FileEncryptionStatusW [ADVAPI32.@]
5210 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5212 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5213 if (!lpStatus)
5214 return FALSE;
5215 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5216 return TRUE;
5219 /******************************************************************************
5220 * FileEncryptionStatusA [ADVAPI32.@]
5222 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5224 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5225 if (!lpStatus)
5226 return FALSE;
5227 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5228 return TRUE;
5231 /******************************************************************************
5232 * SetSecurityInfo [ADVAPI32.@]
5234 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5235 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5236 PSID psidGroup, PACL pDacl, PACL pSacl) {
5237 FIXME("stub\n");
5238 return ERROR_SUCCESS;
5241 /******************************************************************************
5242 * SaferCreateLevel [ADVAPI32.@]
5244 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5245 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5247 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5248 return FALSE;
5251 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5252 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5253 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5254 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5255 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5257 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5258 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5259 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5261 return ERROR_SUCCESS;