po: Updated Korean translation.
[wine.git] / dlls / advapi32 / security.c
blobc3454a87622d710ce5a177ca3d8887705462e890
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_RELATIVE* 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 CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 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 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 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 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 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 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 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 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 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 };
216 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 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 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 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 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 };
223 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 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 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 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 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 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 BOOL ADVAPI_GetComputerSid(PSID sid)
452 static const struct /* same fields as struct SID */
454 BYTE Revision;
455 BYTE SubAuthorityCount;
456 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
457 DWORD SubAuthority[4];
458 } computer_sid =
459 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
461 memcpy( sid, &computer_sid, sizeof(computer_sid) );
462 return TRUE;
465 /* ##############################
466 ###### TOKEN FUNCTIONS ######
467 ##############################
470 /******************************************************************************
471 * OpenProcessToken [ADVAPI32.@]
472 * Opens the access token associated with a process handle.
474 * PARAMS
475 * ProcessHandle [I] Handle to process
476 * DesiredAccess [I] Desired access to process
477 * TokenHandle [O] Pointer to handle of open access token
479 * RETURNS
480 * Success: TRUE. TokenHandle contains the access token.
481 * Failure: FALSE.
483 * NOTES
484 * See NtOpenProcessToken.
486 BOOL WINAPI
487 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
488 HANDLE *TokenHandle )
490 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
493 /******************************************************************************
494 * OpenThreadToken [ADVAPI32.@]
496 * Opens the access token associated with a thread handle.
498 * PARAMS
499 * ThreadHandle [I] Handle to process
500 * DesiredAccess [I] Desired access to the thread
501 * OpenAsSelf [I] ???
502 * TokenHandle [O] Destination for the token handle
504 * RETURNS
505 * Success: TRUE. TokenHandle contains the access token.
506 * Failure: FALSE.
508 * NOTES
509 * See NtOpenThreadToken.
511 BOOL WINAPI
512 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
513 BOOL OpenAsSelf, HANDLE *TokenHandle)
515 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
518 BOOL WINAPI
519 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
520 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
522 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
523 PreviousState, ReturnLength));
526 /******************************************************************************
527 * AdjustTokenPrivileges [ADVAPI32.@]
529 * Adjust the privileges of an open token handle.
531 * PARAMS
532 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
533 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
534 * NewState [I] Desired new privileges of the token
535 * BufferLength [I] Length of NewState
536 * PreviousState [O] Destination for the previous state
537 * ReturnLength [I/O] Size of PreviousState
540 * RETURNS
541 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
542 * Failure: FALSE.
544 * NOTES
545 * See NtAdjustPrivilegesToken.
547 BOOL WINAPI
548 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
549 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
550 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
552 NTSTATUS status;
554 TRACE("\n");
556 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
557 NewState, BufferLength, PreviousState,
558 ReturnLength);
559 SetLastError( RtlNtStatusToDosError( status ));
560 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
561 return TRUE;
562 else
563 return FALSE;
566 /******************************************************************************
567 * CheckTokenMembership [ADVAPI32.@]
569 * Determine if an access token is a member of a SID.
571 * PARAMS
572 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573 * SidToCheck [I] SID that possibly contains the token
574 * IsMember [O] Destination for result.
576 * RETURNS
577 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
578 * Failure: FALSE.
580 BOOL WINAPI
581 CheckTokenMembership( HANDLE token, PSID sid_to_check,
582 PBOOL is_member )
584 PTOKEN_GROUPS token_groups = NULL;
585 HANDLE thread_token = NULL;
586 DWORD size, i;
587 BOOL ret;
589 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
591 *is_member = FALSE;
593 if (!token)
595 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
597 HANDLE process_token;
598 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
599 if (!ret)
600 goto exit;
601 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
602 NULL, SecurityImpersonation, TokenImpersonation,
603 &thread_token);
604 CloseHandle(process_token);
605 if (!ret)
606 goto exit;
608 token = thread_token;
611 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
612 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
613 goto exit;
615 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
616 if (!token_groups)
618 ret = FALSE;
619 goto exit;
622 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
623 if (!ret)
624 goto exit;
626 for (i = 0; i < token_groups->GroupCount; i++)
628 TRACE("Groups[%d]: {0x%x, %s}\n", i,
629 token_groups->Groups[i].Attributes,
630 debugstr_sid(token_groups->Groups[i].Sid));
631 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
632 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
634 *is_member = TRUE;
635 TRACE("sid enabled and found in token\n");
636 break;
640 exit:
641 HeapFree(GetProcessHeap(), 0, token_groups);
642 if (thread_token != NULL) CloseHandle(thread_token);
644 return ret;
647 /******************************************************************************
648 * GetTokenInformation [ADVAPI32.@]
650 * Get a type of information about an access token.
652 * PARAMS
653 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
654 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
655 * tokeninfo [O] Destination for token information
656 * tokeninfolength [I] Length of tokeninfo
657 * retlen [O] Destination for returned token information length
659 * RETURNS
660 * Success: TRUE. tokeninfo contains retlen bytes of token information
661 * Failure: FALSE.
663 * NOTES
664 * See NtQueryInformationToken.
666 BOOL WINAPI
667 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
668 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
670 TRACE("(%p, %s, %p, %d, %p):\n",
671 token,
672 (tokeninfoclass == TokenUser) ? "TokenUser" :
673 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
674 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
675 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
676 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
677 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
678 (tokeninfoclass == TokenSource) ? "TokenSource" :
679 (tokeninfoclass == TokenType) ? "TokenType" :
680 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
681 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
682 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
683 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
684 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
685 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
686 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
687 "Unknown",
688 tokeninfo, tokeninfolength, retlen);
689 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
690 tokeninfolength, retlen));
693 /******************************************************************************
694 * SetTokenInformation [ADVAPI32.@]
696 * Set information for an access token.
698 * PARAMS
699 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
700 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
701 * tokeninfo [I] Token information to set
702 * tokeninfolength [I] Length of tokeninfo
704 * RETURNS
705 * Success: TRUE. The information for the token is set to tokeninfo.
706 * Failure: FALSE.
708 BOOL WINAPI
709 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
710 LPVOID tokeninfo, DWORD tokeninfolength )
712 TRACE("(%p, %s, %p, %d): stub\n",
713 token,
714 (tokeninfoclass == TokenUser) ? "TokenUser" :
715 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
716 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
717 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
718 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
719 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
720 (tokeninfoclass == TokenSource) ? "TokenSource" :
721 (tokeninfoclass == TokenType) ? "TokenType" :
722 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
723 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
724 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
725 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
726 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
727 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
728 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
729 "Unknown",
730 tokeninfo, tokeninfolength);
732 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
735 /*************************************************************************
736 * SetThreadToken [ADVAPI32.@]
738 * Assigns an 'impersonation token' to a thread so it can assume the
739 * security privileges of another thread or process. Can also remove
740 * a previously assigned token.
742 * PARAMS
743 * thread [O] Handle to thread to set the token for
744 * token [I] Token to set
746 * RETURNS
747 * Success: TRUE. The threads access token is set to token
748 * Failure: FALSE.
750 * NOTES
751 * Only supported on NT or higher. On Win9X this function does nothing.
752 * See SetTokenInformation.
754 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
756 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
757 ThreadImpersonationToken, &token, sizeof token ));
760 /*************************************************************************
761 * CreateRestrictedToken [ADVAPI32.@]
763 * Create a new more restricted token from an existing token.
765 * PARAMS
766 * baseToken [I] Token to base the new restricted token on
767 * flags [I] Options
768 * nDisableSids [I] Length of disableSids array
769 * disableSids [I] Array of SIDs to disable in the new token
770 * nDeletePrivs [I] Length of deletePrivs array
771 * deletePrivs [I] Array of privileges to delete in the new token
772 * nRestrictSids [I] Length of restrictSids array
773 * restrictSids [I] Array of SIDs to restrict in the new token
774 * newToken [O] Address where the new token is stored
776 * RETURNS
777 * Success: TRUE
778 * Failure: FALSE
780 BOOL WINAPI CreateRestrictedToken(
781 HANDLE baseToken,
782 DWORD flags,
783 DWORD nDisableSids,
784 PSID_AND_ATTRIBUTES disableSids,
785 DWORD nDeletePrivs,
786 PLUID_AND_ATTRIBUTES deletePrivs,
787 DWORD nRestrictSids,
788 PSID_AND_ATTRIBUTES restrictSids,
789 PHANDLE newToken)
791 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
792 baseToken, flags, nDisableSids, disableSids,
793 nDeletePrivs, deletePrivs,
794 nRestrictSids, restrictSids,
795 newToken);
796 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
797 return FALSE;
800 /* ##############################
801 ###### SID FUNCTIONS ######
802 ##############################
805 /******************************************************************************
806 * AllocateAndInitializeSid [ADVAPI32.@]
808 * PARAMS
809 * pIdentifierAuthority []
810 * nSubAuthorityCount []
811 * nSubAuthority0 []
812 * nSubAuthority1 []
813 * nSubAuthority2 []
814 * nSubAuthority3 []
815 * nSubAuthority4 []
816 * nSubAuthority5 []
817 * nSubAuthority6 []
818 * nSubAuthority7 []
819 * pSid []
821 BOOL WINAPI
822 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
823 BYTE nSubAuthorityCount,
824 DWORD nSubAuthority0, DWORD nSubAuthority1,
825 DWORD nSubAuthority2, DWORD nSubAuthority3,
826 DWORD nSubAuthority4, DWORD nSubAuthority5,
827 DWORD nSubAuthority6, DWORD nSubAuthority7,
828 PSID *pSid )
830 return set_ntstatus( RtlAllocateAndInitializeSid(
831 pIdentifierAuthority, nSubAuthorityCount,
832 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
833 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
834 pSid ));
837 /******************************************************************************
838 * FreeSid [ADVAPI32.@]
840 * PARAMS
841 * pSid []
843 PVOID WINAPI
844 FreeSid( PSID pSid )
846 RtlFreeSid(pSid);
847 return NULL; /* is documented like this */
850 /******************************************************************************
851 * CopySid [ADVAPI32.@]
853 * PARAMS
854 * nDestinationSidLength []
855 * pDestinationSid []
856 * pSourceSid []
858 BOOL WINAPI
859 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
861 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
864 /******************************************************************************
865 * CreateWellKnownSid [ADVAPI32.@]
867 BOOL WINAPI
868 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
869 PSID DomainSid,
870 PSID pSid,
871 DWORD* cbSid)
873 unsigned int i;
874 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
876 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
878 SetLastError(ERROR_INVALID_PARAMETER);
879 return FALSE;
882 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
883 if (WellKnownSids[i].Type == WellKnownSidType) {
884 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
886 if (*cbSid < length)
888 *cbSid = length;
889 SetLastError(ERROR_INSUFFICIENT_BUFFER);
890 return FALSE;
892 if (!pSid)
894 SetLastError(ERROR_INVALID_PARAMETER);
895 return FALSE;
897 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
898 *cbSid = length;
899 return TRUE;
903 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
905 SetLastError(ERROR_INVALID_PARAMETER);
906 return FALSE;
909 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
910 if (WellKnownRids[i].Type == WellKnownSidType) {
911 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
912 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
913 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
915 if (*cbSid < output_sid_length)
917 *cbSid = output_sid_length;
918 SetLastError(ERROR_INSUFFICIENT_BUFFER);
919 return FALSE;
921 if (!pSid)
923 SetLastError(ERROR_INVALID_PARAMETER);
924 return FALSE;
926 CopyMemory(pSid, DomainSid, domain_sid_length);
927 (*GetSidSubAuthorityCount(pSid))++;
928 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
929 *cbSid = output_sid_length;
930 return TRUE;
933 SetLastError(ERROR_INVALID_PARAMETER);
934 return FALSE;
937 /******************************************************************************
938 * IsWellKnownSid [ADVAPI32.@]
940 BOOL WINAPI
941 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
943 unsigned int i;
944 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
946 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
947 if (WellKnownSids[i].Type == WellKnownSidType)
948 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
949 return TRUE;
951 return FALSE;
954 BOOL WINAPI
955 IsTokenRestricted( HANDLE TokenHandle )
957 TOKEN_GROUPS *groups;
958 DWORD size;
959 NTSTATUS status;
960 BOOL restricted;
962 TRACE("(%p)\n", TokenHandle);
964 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
965 if (status != STATUS_BUFFER_TOO_SMALL)
966 return FALSE;
968 groups = HeapAlloc(GetProcessHeap(), 0, size);
969 if (!groups)
971 SetLastError(ERROR_OUTOFMEMORY);
972 return FALSE;
975 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
976 if (status != STATUS_SUCCESS)
978 HeapFree(GetProcessHeap(), 0, groups);
979 return set_ntstatus(status);
982 if (groups->GroupCount)
983 restricted = TRUE;
984 else
985 restricted = FALSE;
987 HeapFree(GetProcessHeap(), 0, groups);
989 return restricted;
992 /******************************************************************************
993 * IsValidSid [ADVAPI32.@]
995 * PARAMS
996 * pSid []
998 BOOL WINAPI
999 IsValidSid( PSID pSid )
1001 return RtlValidSid( pSid );
1004 /******************************************************************************
1005 * EqualSid [ADVAPI32.@]
1007 * PARAMS
1008 * pSid1 []
1009 * pSid2 []
1011 BOOL WINAPI
1012 EqualSid( PSID pSid1, PSID pSid2 )
1014 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1015 SetLastError(ERROR_SUCCESS);
1016 return ret;
1019 /******************************************************************************
1020 * EqualPrefixSid [ADVAPI32.@]
1022 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1024 return RtlEqualPrefixSid(pSid1, pSid2);
1027 /******************************************************************************
1028 * GetSidLengthRequired [ADVAPI32.@]
1030 * PARAMS
1031 * nSubAuthorityCount []
1033 DWORD WINAPI
1034 GetSidLengthRequired( BYTE nSubAuthorityCount )
1036 return RtlLengthRequiredSid(nSubAuthorityCount);
1039 /******************************************************************************
1040 * InitializeSid [ADVAPI32.@]
1042 * PARAMS
1043 * pIdentifierAuthority []
1045 BOOL WINAPI
1046 InitializeSid (
1047 PSID pSid,
1048 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1049 BYTE nSubAuthorityCount)
1051 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1054 DWORD WINAPI
1055 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1057 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1059 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1060 return 0;
1063 DWORD WINAPI
1064 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1066 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1068 return 1;
1071 /******************************************************************************
1072 * GetSidIdentifierAuthority [ADVAPI32.@]
1074 * PARAMS
1075 * pSid []
1077 PSID_IDENTIFIER_AUTHORITY WINAPI
1078 GetSidIdentifierAuthority( PSID pSid )
1080 return RtlIdentifierAuthoritySid(pSid);
1083 /******************************************************************************
1084 * GetSidSubAuthority [ADVAPI32.@]
1086 * PARAMS
1087 * pSid []
1088 * nSubAuthority []
1090 PDWORD WINAPI
1091 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1093 SetLastError(ERROR_SUCCESS);
1094 return RtlSubAuthoritySid(pSid, nSubAuthority);
1097 /******************************************************************************
1098 * GetSidSubAuthorityCount [ADVAPI32.@]
1100 * PARAMS
1101 * pSid []
1103 PUCHAR WINAPI
1104 GetSidSubAuthorityCount (PSID pSid)
1106 SetLastError(ERROR_SUCCESS);
1107 return RtlSubAuthorityCountSid(pSid);
1110 /******************************************************************************
1111 * GetLengthSid [ADVAPI32.@]
1113 * PARAMS
1114 * pSid []
1116 DWORD WINAPI
1117 GetLengthSid (PSID pSid)
1119 return RtlLengthSid(pSid);
1122 /* ##############################################
1123 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1124 ##############################################
1127 /******************************************************************************
1128 * BuildSecurityDescriptorA [ADVAPI32.@]
1130 * Builds a SD from
1132 * PARAMS
1133 * pOwner [I]
1134 * pGroup [I]
1135 * cCountOfAccessEntries [I]
1136 * pListOfAccessEntries [I]
1137 * cCountOfAuditEntries [I]
1138 * pListofAuditEntries [I]
1139 * pOldSD [I]
1140 * lpdwBufferLength [I/O]
1141 * pNewSD [O]
1143 * RETURNS
1144 * Success: ERROR_SUCCESS
1145 * Failure: nonzero error code from Winerror.h
1147 DWORD WINAPI BuildSecurityDescriptorA(
1148 IN PTRUSTEEA pOwner,
1149 IN PTRUSTEEA pGroup,
1150 IN ULONG cCountOfAccessEntries,
1151 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1152 IN ULONG cCountOfAuditEntries,
1153 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1154 IN PSECURITY_DESCRIPTOR pOldSD,
1155 IN OUT PULONG lpdwBufferLength,
1156 OUT PSECURITY_DESCRIPTOR* pNewSD)
1158 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1159 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1160 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1162 return ERROR_CALL_NOT_IMPLEMENTED;
1165 /******************************************************************************
1166 * BuildSecurityDescriptorW [ADVAPI32.@]
1168 * See BuildSecurityDescriptorA.
1170 DWORD WINAPI BuildSecurityDescriptorW(
1171 IN PTRUSTEEW pOwner,
1172 IN PTRUSTEEW pGroup,
1173 IN ULONG cCountOfAccessEntries,
1174 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1175 IN ULONG cCountOfAuditEntries,
1176 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1177 IN PSECURITY_DESCRIPTOR pOldSD,
1178 IN OUT PULONG lpdwBufferLength,
1179 OUT PSECURITY_DESCRIPTOR* pNewSD)
1181 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1182 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1183 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1185 return ERROR_CALL_NOT_IMPLEMENTED;
1188 /******************************************************************************
1189 * InitializeSecurityDescriptor [ADVAPI32.@]
1191 * PARAMS
1192 * pDescr []
1193 * revision []
1195 BOOL WINAPI
1196 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1198 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1202 /******************************************************************************
1203 * MakeAbsoluteSD [ADVAPI32.@]
1205 BOOL WINAPI MakeAbsoluteSD (
1206 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1207 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1208 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1209 OUT PACL pDacl,
1210 OUT LPDWORD lpdwDaclSize,
1211 OUT PACL pSacl,
1212 OUT LPDWORD lpdwSaclSize,
1213 OUT PSID pOwner,
1214 OUT LPDWORD lpdwOwnerSize,
1215 OUT PSID pPrimaryGroup,
1216 OUT LPDWORD lpdwPrimaryGroupSize)
1218 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1219 pAbsoluteSecurityDescriptor,
1220 lpdwAbsoluteSecurityDescriptorSize,
1221 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1222 pOwner, lpdwOwnerSize,
1223 pPrimaryGroup, lpdwPrimaryGroupSize));
1226 /******************************************************************************
1227 * GetKernelObjectSecurity [ADVAPI32.@]
1229 BOOL WINAPI GetKernelObjectSecurity(
1230 HANDLE Handle,
1231 SECURITY_INFORMATION RequestedInformation,
1232 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1233 DWORD nLength,
1234 LPDWORD lpnLengthNeeded )
1236 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1237 pSecurityDescriptor, nLength, lpnLengthNeeded);
1239 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1240 nLength, lpnLengthNeeded ));
1243 /******************************************************************************
1244 * GetPrivateObjectSecurity [ADVAPI32.@]
1246 BOOL WINAPI GetPrivateObjectSecurity(
1247 PSECURITY_DESCRIPTOR ObjectDescriptor,
1248 SECURITY_INFORMATION SecurityInformation,
1249 PSECURITY_DESCRIPTOR ResultantDescriptor,
1250 DWORD DescriptorLength,
1251 PDWORD ReturnLength )
1253 SECURITY_DESCRIPTOR desc;
1254 BOOL defaulted, present;
1255 PACL pacl;
1256 PSID psid;
1258 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1259 ResultantDescriptor, DescriptorLength, ReturnLength);
1261 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1262 return FALSE;
1264 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1266 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1267 return FALSE;
1268 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1271 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1273 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1274 return FALSE;
1275 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1278 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1280 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1281 return FALSE;
1282 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1285 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1287 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1288 return FALSE;
1289 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1292 *ReturnLength = DescriptorLength;
1293 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1296 /******************************************************************************
1297 * GetSecurityDescriptorLength [ADVAPI32.@]
1299 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1301 return RtlLengthSecurityDescriptor(pDescr);
1304 /******************************************************************************
1305 * GetSecurityDescriptorOwner [ADVAPI32.@]
1307 * PARAMS
1308 * pOwner []
1309 * lpbOwnerDefaulted []
1311 BOOL WINAPI
1312 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1313 LPBOOL lpbOwnerDefaulted )
1315 BOOLEAN defaulted;
1316 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1317 *lpbOwnerDefaulted = defaulted;
1318 return ret;
1321 /******************************************************************************
1322 * SetSecurityDescriptorOwner [ADVAPI32.@]
1324 * PARAMS
1326 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1327 PSID pOwner, BOOL bOwnerDefaulted)
1329 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1331 /******************************************************************************
1332 * GetSecurityDescriptorGroup [ADVAPI32.@]
1334 BOOL WINAPI GetSecurityDescriptorGroup(
1335 PSECURITY_DESCRIPTOR SecurityDescriptor,
1336 PSID *Group,
1337 LPBOOL GroupDefaulted)
1339 BOOLEAN defaulted;
1340 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1341 *GroupDefaulted = defaulted;
1342 return ret;
1344 /******************************************************************************
1345 * SetSecurityDescriptorGroup [ADVAPI32.@]
1347 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1348 PSID Group, BOOL GroupDefaulted)
1350 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1353 /******************************************************************************
1354 * IsValidSecurityDescriptor [ADVAPI32.@]
1356 * PARAMS
1357 * lpsecdesc []
1359 BOOL WINAPI
1360 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1362 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1365 /******************************************************************************
1366 * GetSecurityDescriptorDacl [ADVAPI32.@]
1368 BOOL WINAPI GetSecurityDescriptorDacl(
1369 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1370 OUT LPBOOL lpbDaclPresent,
1371 OUT PACL *pDacl,
1372 OUT LPBOOL lpbDaclDefaulted)
1374 BOOLEAN present, defaulted;
1375 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1376 *lpbDaclPresent = present;
1377 *lpbDaclDefaulted = defaulted;
1378 return ret;
1381 /******************************************************************************
1382 * SetSecurityDescriptorDacl [ADVAPI32.@]
1384 BOOL WINAPI
1385 SetSecurityDescriptorDacl (
1386 PSECURITY_DESCRIPTOR lpsd,
1387 BOOL daclpresent,
1388 PACL dacl,
1389 BOOL dacldefaulted )
1391 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1393 /******************************************************************************
1394 * GetSecurityDescriptorSacl [ADVAPI32.@]
1396 BOOL WINAPI GetSecurityDescriptorSacl(
1397 IN PSECURITY_DESCRIPTOR lpsd,
1398 OUT LPBOOL lpbSaclPresent,
1399 OUT PACL *pSacl,
1400 OUT LPBOOL lpbSaclDefaulted)
1402 BOOLEAN present, defaulted;
1403 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1404 *lpbSaclPresent = present;
1405 *lpbSaclDefaulted = defaulted;
1406 return ret;
1409 /**************************************************************************
1410 * SetSecurityDescriptorSacl [ADVAPI32.@]
1412 BOOL WINAPI SetSecurityDescriptorSacl (
1413 PSECURITY_DESCRIPTOR lpsd,
1414 BOOL saclpresent,
1415 PACL lpsacl,
1416 BOOL sacldefaulted)
1418 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1420 /******************************************************************************
1421 * MakeSelfRelativeSD [ADVAPI32.@]
1423 * PARAMS
1424 * lpabssecdesc []
1425 * lpselfsecdesc []
1426 * lpbuflen []
1428 BOOL WINAPI
1429 MakeSelfRelativeSD(
1430 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1431 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1432 IN OUT LPDWORD lpdwBufferLength)
1434 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1435 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1438 /******************************************************************************
1439 * GetSecurityDescriptorControl [ADVAPI32.@]
1442 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1443 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1445 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1448 /******************************************************************************
1449 * SetSecurityDescriptorControl [ADVAPI32.@]
1451 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1452 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1453 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1455 return set_ntstatus( RtlSetControlSecurityDescriptor(
1456 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1459 /* ##############################
1460 ###### ACL FUNCTIONS ######
1461 ##############################
1464 /*************************************************************************
1465 * InitializeAcl [ADVAPI32.@]
1467 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1469 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1472 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1474 IO_STATUS_BLOCK io_block;
1476 TRACE("(%p)\n", hNamedPipe);
1478 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1479 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1482 /******************************************************************************
1483 * AddAccessAllowedAce [ADVAPI32.@]
1485 BOOL WINAPI AddAccessAllowedAce(
1486 IN OUT PACL pAcl,
1487 IN DWORD dwAceRevision,
1488 IN DWORD AccessMask,
1489 IN PSID pSid)
1491 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1494 /******************************************************************************
1495 * AddAccessAllowedAceEx [ADVAPI32.@]
1497 BOOL WINAPI AddAccessAllowedAceEx(
1498 IN OUT PACL pAcl,
1499 IN DWORD dwAceRevision,
1500 IN DWORD AceFlags,
1501 IN DWORD AccessMask,
1502 IN PSID pSid)
1504 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1507 /******************************************************************************
1508 * AddAccessDeniedAce [ADVAPI32.@]
1510 BOOL WINAPI AddAccessDeniedAce(
1511 IN OUT PACL pAcl,
1512 IN DWORD dwAceRevision,
1513 IN DWORD AccessMask,
1514 IN PSID pSid)
1516 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1519 /******************************************************************************
1520 * AddAccessDeniedAceEx [ADVAPI32.@]
1522 BOOL WINAPI AddAccessDeniedAceEx(
1523 IN OUT PACL pAcl,
1524 IN DWORD dwAceRevision,
1525 IN DWORD AceFlags,
1526 IN DWORD AccessMask,
1527 IN PSID pSid)
1529 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1532 /******************************************************************************
1533 * AddAce [ADVAPI32.@]
1535 BOOL WINAPI AddAce(
1536 IN OUT PACL pAcl,
1537 IN DWORD dwAceRevision,
1538 IN DWORD dwStartingAceIndex,
1539 LPVOID pAceList,
1540 DWORD nAceListLength)
1542 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1545 /******************************************************************************
1546 * DeleteAce [ADVAPI32.@]
1548 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1550 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1553 /******************************************************************************
1554 * FindFirstFreeAce [ADVAPI32.@]
1556 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1558 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1561 /******************************************************************************
1562 * GetAce [ADVAPI32.@]
1564 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1566 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1569 /******************************************************************************
1570 * GetAclInformation [ADVAPI32.@]
1572 BOOL WINAPI GetAclInformation(
1573 PACL pAcl,
1574 LPVOID pAclInformation,
1575 DWORD nAclInformationLength,
1576 ACL_INFORMATION_CLASS dwAclInformationClass)
1578 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1579 nAclInformationLength, dwAclInformationClass));
1582 /******************************************************************************
1583 * IsValidAcl [ADVAPI32.@]
1585 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1587 return RtlValidAcl(pAcl);
1590 /* ##############################
1591 ###### MISC FUNCTIONS ######
1592 ##############################
1595 /******************************************************************************
1596 * AllocateLocallyUniqueId [ADVAPI32.@]
1598 * PARAMS
1599 * lpLuid []
1601 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1603 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1606 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1607 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1609 { '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 };
1610 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1611 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1613 { '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 };
1614 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1615 { '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 };
1616 static const WCHAR SE_TCB_NAME_W[] =
1617 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1618 static const WCHAR SE_SECURITY_NAME_W[] =
1619 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1620 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1621 { '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 };
1622 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1623 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1625 { '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 };
1626 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1627 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1629 { '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 };
1630 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1631 { '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 };
1632 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1633 { '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 };
1634 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1635 { '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 };
1636 static const WCHAR SE_BACKUP_NAME_W[] =
1637 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1638 static const WCHAR SE_RESTORE_NAME_W[] =
1639 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1640 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1641 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1642 static const WCHAR SE_DEBUG_NAME_W[] =
1643 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1644 static const WCHAR SE_AUDIT_NAME_W[] =
1645 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1647 { '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 };
1648 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1649 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1650 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1651 { '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 };
1652 static const WCHAR SE_UNDOCK_NAME_W[] =
1653 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1654 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1655 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1656 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1657 { '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 };
1658 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1659 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1660 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1661 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1662 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1663 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1665 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1667 NULL,
1668 NULL,
1669 SE_CREATE_TOKEN_NAME_W,
1670 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1671 SE_LOCK_MEMORY_NAME_W,
1672 SE_INCREASE_QUOTA_NAME_W,
1673 SE_MACHINE_ACCOUNT_NAME_W,
1674 SE_TCB_NAME_W,
1675 SE_SECURITY_NAME_W,
1676 SE_TAKE_OWNERSHIP_NAME_W,
1677 SE_LOAD_DRIVER_NAME_W,
1678 SE_SYSTEM_PROFILE_NAME_W,
1679 SE_SYSTEMTIME_NAME_W,
1680 SE_PROF_SINGLE_PROCESS_NAME_W,
1681 SE_INC_BASE_PRIORITY_NAME_W,
1682 SE_CREATE_PAGEFILE_NAME_W,
1683 SE_CREATE_PERMANENT_NAME_W,
1684 SE_BACKUP_NAME_W,
1685 SE_RESTORE_NAME_W,
1686 SE_SHUTDOWN_NAME_W,
1687 SE_DEBUG_NAME_W,
1688 SE_AUDIT_NAME_W,
1689 SE_SYSTEM_ENVIRONMENT_NAME_W,
1690 SE_CHANGE_NOTIFY_NAME_W,
1691 SE_REMOTE_SHUTDOWN_NAME_W,
1692 SE_UNDOCK_NAME_W,
1693 SE_SYNC_AGENT_NAME_W,
1694 SE_ENABLE_DELEGATION_NAME_W,
1695 SE_MANAGE_VOLUME_NAME_W,
1696 SE_IMPERSONATE_NAME_W,
1697 SE_CREATE_GLOBAL_NAME_W,
1700 /******************************************************************************
1701 * LookupPrivilegeValueW [ADVAPI32.@]
1703 * See LookupPrivilegeValueA.
1705 BOOL WINAPI
1706 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1708 UINT i;
1710 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1712 if (!ADVAPI_IsLocalComputer(lpSystemName))
1714 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1715 return FALSE;
1717 if (!lpName)
1719 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1720 return FALSE;
1722 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1724 if( !WellKnownPrivNames[i] )
1725 continue;
1726 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1727 continue;
1728 lpLuid->LowPart = i;
1729 lpLuid->HighPart = 0;
1730 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1731 lpLuid->HighPart, lpLuid->LowPart );
1732 return TRUE;
1734 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1735 return FALSE;
1738 /******************************************************************************
1739 * LookupPrivilegeValueA [ADVAPI32.@]
1741 * Retrieves LUID used on a system to represent the privilege name.
1743 * PARAMS
1744 * lpSystemName [I] Name of the system
1745 * lpName [I] Name of the privilege
1746 * lpLuid [O] Destination for the resulting LUID
1748 * RETURNS
1749 * Success: TRUE. lpLuid contains the requested LUID.
1750 * Failure: FALSE.
1752 BOOL WINAPI
1753 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1755 UNICODE_STRING lpSystemNameW;
1756 UNICODE_STRING lpNameW;
1757 BOOL ret;
1759 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1760 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1761 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1762 RtlFreeUnicodeString(&lpNameW);
1763 RtlFreeUnicodeString(&lpSystemNameW);
1764 return ret;
1767 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1768 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1770 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1771 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1773 return FALSE;
1776 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1777 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1779 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1780 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1782 return FALSE;
1785 /******************************************************************************
1786 * LookupPrivilegeNameA [ADVAPI32.@]
1788 * See LookupPrivilegeNameW.
1790 BOOL WINAPI
1791 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1792 LPDWORD cchName)
1794 UNICODE_STRING lpSystemNameW;
1795 BOOL ret;
1796 DWORD wLen = 0;
1798 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1800 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1801 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1802 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1804 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1806 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1807 &wLen);
1808 if (ret)
1810 /* Windows crashes if cchName is NULL, so will I */
1811 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1812 *cchName, NULL, NULL);
1814 if (len == 0)
1816 /* WideCharToMultiByte failed */
1817 ret = FALSE;
1819 else if (len > *cchName)
1821 *cchName = len;
1822 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1823 ret = FALSE;
1825 else
1827 /* WideCharToMultiByte succeeded, output length needs to be
1828 * length not including NULL terminator
1830 *cchName = len - 1;
1833 HeapFree(GetProcessHeap(), 0, lpNameW);
1835 RtlFreeUnicodeString(&lpSystemNameW);
1836 return ret;
1839 /******************************************************************************
1840 * LookupPrivilegeNameW [ADVAPI32.@]
1842 * Retrieves the privilege name referred to by the LUID lpLuid.
1844 * PARAMS
1845 * lpSystemName [I] Name of the system
1846 * lpLuid [I] Privilege value
1847 * lpName [O] Name of the privilege
1848 * cchName [I/O] Number of characters in lpName.
1850 * RETURNS
1851 * Success: TRUE. lpName contains the name of the privilege whose value is
1852 * *lpLuid.
1853 * Failure: FALSE.
1855 * REMARKS
1856 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1857 * using this function.
1858 * If the length of lpName is too small, on return *cchName will contain the
1859 * number of WCHARs needed to contain the privilege, including the NULL
1860 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1861 * On success, *cchName will contain the number of characters stored in
1862 * lpName, NOT including the NULL terminator.
1864 BOOL WINAPI
1865 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1866 LPDWORD cchName)
1868 size_t privNameLen;
1870 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1872 if (!ADVAPI_IsLocalComputer(lpSystemName))
1874 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1875 return FALSE;
1877 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1878 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1880 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1881 return FALSE;
1883 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1884 /* Windows crashes if cchName is NULL, so will I */
1885 if (*cchName <= privNameLen)
1887 *cchName = privNameLen + 1;
1888 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1889 return FALSE;
1891 else
1893 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1894 *cchName = privNameLen;
1895 return TRUE;
1899 /******************************************************************************
1900 * GetFileSecurityA [ADVAPI32.@]
1902 * Obtains Specified information about the security of a file or directory.
1904 * PARAMS
1905 * lpFileName [I] Name of the file to get info for
1906 * RequestedInformation [I] SE_ flags from "winnt.h"
1907 * pSecurityDescriptor [O] Destination for security information
1908 * nLength [I] Length of pSecurityDescriptor
1909 * lpnLengthNeeded [O] Destination for length of returned security information
1911 * RETURNS
1912 * Success: TRUE. pSecurityDescriptor contains the requested information.
1913 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1915 * NOTES
1916 * The information returned is constrained by the callers access rights and
1917 * privileges.
1919 BOOL WINAPI
1920 GetFileSecurityA( LPCSTR lpFileName,
1921 SECURITY_INFORMATION RequestedInformation,
1922 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1923 DWORD nLength, LPDWORD lpnLengthNeeded )
1925 DWORD len;
1926 BOOL r;
1927 LPWSTR name = NULL;
1929 if( lpFileName )
1931 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1932 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1933 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1936 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1937 nLength, lpnLengthNeeded );
1938 HeapFree( GetProcessHeap(), 0, name );
1940 return r;
1943 /******************************************************************************
1944 * GetFileSecurityW [ADVAPI32.@]
1946 * See GetFileSecurityA.
1948 BOOL WINAPI
1949 GetFileSecurityW( LPCWSTR lpFileName,
1950 SECURITY_INFORMATION RequestedInformation,
1951 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1952 DWORD nLength, LPDWORD lpnLengthNeeded )
1954 HANDLE hfile;
1955 NTSTATUS status;
1956 DWORD access = 0;
1958 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1959 RequestedInformation, pSecurityDescriptor,
1960 nLength, lpnLengthNeeded);
1962 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1963 DACL_SECURITY_INFORMATION))
1964 access |= READ_CONTROL;
1965 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1966 access |= ACCESS_SYSTEM_SECURITY;
1968 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1969 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1970 if ( hfile == INVALID_HANDLE_VALUE )
1971 return FALSE;
1973 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1974 nLength, lpnLengthNeeded );
1975 CloseHandle( hfile );
1976 return set_ntstatus( status );
1980 /******************************************************************************
1981 * LookupAccountSidA [ADVAPI32.@]
1983 BOOL WINAPI
1984 LookupAccountSidA(
1985 IN LPCSTR system,
1986 IN PSID sid,
1987 OUT LPSTR account,
1988 IN OUT LPDWORD accountSize,
1989 OUT LPSTR domain,
1990 IN OUT LPDWORD domainSize,
1991 OUT PSID_NAME_USE name_use )
1993 DWORD len;
1994 BOOL r;
1995 LPWSTR systemW = NULL;
1996 LPWSTR accountW = NULL;
1997 LPWSTR domainW = NULL;
1998 DWORD accountSizeW = *accountSize;
1999 DWORD domainSizeW = *domainSize;
2001 if (system) {
2002 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2003 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2004 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2006 if (account)
2007 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2008 if (domain)
2009 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2011 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2013 if (r) {
2014 if (accountW && *accountSize) {
2015 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2016 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2017 *accountSize = len;
2018 } else
2019 *accountSize = accountSizeW + 1;
2021 if (domainW && *domainSize) {
2022 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2023 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2024 *domainSize = len;
2025 } else
2026 *domainSize = domainSizeW + 1;
2028 else
2030 *accountSize = accountSizeW + 1;
2031 *domainSize = domainSizeW + 1;
2034 HeapFree( GetProcessHeap(), 0, systemW );
2035 HeapFree( GetProcessHeap(), 0, accountW );
2036 HeapFree( GetProcessHeap(), 0, domainW );
2038 return r;
2041 /******************************************************************************
2042 * LookupAccountSidW [ADVAPI32.@]
2044 * PARAMS
2045 * system []
2046 * sid []
2047 * account []
2048 * accountSize []
2049 * domain []
2050 * domainSize []
2051 * name_use []
2054 BOOL WINAPI
2055 LookupAccountSidW(
2056 IN LPCWSTR system,
2057 IN PSID sid,
2058 OUT LPWSTR account,
2059 IN OUT LPDWORD accountSize,
2060 OUT LPWSTR domain,
2061 IN OUT LPDWORD domainSize,
2062 OUT PSID_NAME_USE name_use )
2064 unsigned int i, j;
2065 const WCHAR * ac = NULL;
2066 const WCHAR * dm = NULL;
2067 SID_NAME_USE use = 0;
2068 LPWSTR computer_name = NULL;
2069 LPWSTR account_name = NULL;
2071 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2072 debugstr_w(system),debugstr_sid(sid),
2073 account,accountSize,accountSize?*accountSize:0,
2074 domain,domainSize,domainSize?*domainSize:0,
2075 name_use);
2077 if (!ADVAPI_IsLocalComputer(system)) {
2078 FIXME("Only local computer supported!\n");
2079 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2080 return FALSE;
2083 /* check the well known SIDs first */
2084 for (i = 0; i <= 60; i++) {
2085 if (IsWellKnownSid(sid, i)) {
2086 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2087 if (ACCOUNT_SIDS[j].type == i) {
2088 ac = ACCOUNT_SIDS[j].account;
2089 dm = ACCOUNT_SIDS[j].domain;
2090 use = ACCOUNT_SIDS[j].name_use;
2093 break;
2097 if (dm == NULL) {
2098 MAX_SID local;
2100 /* check for the local computer next */
2101 if (ADVAPI_GetComputerSid(&local)) {
2102 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2103 BOOL result;
2105 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2106 result = GetComputerNameW(computer_name, &size);
2108 if (result) {
2109 if (EqualSid(sid, &local)) {
2110 dm = computer_name;
2111 ac = Blank;
2112 use = 3;
2113 } else {
2114 local.SubAuthorityCount++;
2116 if (EqualPrefixSid(sid, &local)) {
2117 dm = computer_name;
2118 use = 1;
2119 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2120 case DOMAIN_USER_RID_ADMIN:
2121 ac = Administrator;
2122 break;
2123 case DOMAIN_USER_RID_GUEST:
2124 ac = Guest;
2125 break;
2126 case DOMAIN_GROUP_RID_ADMINS:
2127 ac = Domain_Admins;
2128 break;
2129 case DOMAIN_GROUP_RID_USERS:
2130 ac = Domain_Users;
2131 break;
2132 case DOMAIN_GROUP_RID_GUESTS:
2133 ac = Domain_Guests;
2134 break;
2135 case DOMAIN_GROUP_RID_COMPUTERS:
2136 ac = Domain_Computers;
2137 break;
2138 case DOMAIN_GROUP_RID_CONTROLLERS:
2139 ac = Domain_Controllers;
2140 break;
2141 case DOMAIN_GROUP_RID_CERT_ADMINS:
2142 ac = Cert_Publishers;
2143 break;
2144 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2145 ac = Schema_Admins;
2146 break;
2147 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2148 ac = Enterprise_Admins;
2149 break;
2150 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2151 ac = Group_Policy_Creator_Owners;
2152 break;
2153 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2154 ac = RAS_and_IAS_Servers;
2155 break;
2156 case 1000: /* first user account */
2157 size = UNLEN + 1;
2158 account_name = HeapAlloc(
2159 GetProcessHeap(), 0, size * sizeof(WCHAR));
2160 if (GetUserNameW(account_name, &size))
2161 ac = account_name;
2162 else
2163 dm = NULL;
2165 break;
2166 default:
2167 dm = NULL;
2168 break;
2176 if (dm) {
2177 DWORD ac_len = lstrlenW(ac);
2178 DWORD dm_len = lstrlenW(dm);
2179 BOOL status = TRUE;
2181 if (*accountSize > ac_len) {
2182 if (account)
2183 lstrcpyW(account, ac);
2185 if (*domainSize > dm_len) {
2186 if (domain)
2187 lstrcpyW(domain, dm);
2189 if ((*accountSize && *accountSize < ac_len) ||
2190 (!account && !*accountSize && ac_len) ||
2191 (*domainSize && *domainSize < dm_len) ||
2192 (!domain && !*domainSize && dm_len))
2194 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2195 status = FALSE;
2197 if (*domainSize)
2198 *domainSize = dm_len;
2199 else
2200 *domainSize = dm_len + 1;
2201 if (*accountSize)
2202 *accountSize = ac_len;
2203 else
2204 *accountSize = ac_len + 1;
2206 HeapFree(GetProcessHeap(), 0, account_name);
2207 HeapFree(GetProcessHeap(), 0, computer_name);
2208 if (status) *name_use = use;
2209 return status;
2212 HeapFree(GetProcessHeap(), 0, account_name);
2213 HeapFree(GetProcessHeap(), 0, computer_name);
2214 SetLastError(ERROR_NONE_MAPPED);
2215 return FALSE;
2218 /******************************************************************************
2219 * SetFileSecurityA [ADVAPI32.@]
2221 * See SetFileSecurityW.
2223 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2224 SECURITY_INFORMATION RequestedInformation,
2225 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2227 DWORD len;
2228 BOOL r;
2229 LPWSTR name = NULL;
2231 if( lpFileName )
2233 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2234 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2235 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2238 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2239 HeapFree( GetProcessHeap(), 0, name );
2241 return r;
2244 /******************************************************************************
2245 * SetFileSecurityW [ADVAPI32.@]
2247 * Sets the security of a file or directory.
2249 * PARAMS
2250 * lpFileName []
2251 * RequestedInformation []
2252 * pSecurityDescriptor []
2254 * RETURNS
2255 * Success: TRUE.
2256 * Failure: FALSE.
2258 BOOL WINAPI
2259 SetFileSecurityW( LPCWSTR lpFileName,
2260 SECURITY_INFORMATION RequestedInformation,
2261 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2263 HANDLE file;
2264 DWORD access = 0;
2265 NTSTATUS status;
2267 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2268 pSecurityDescriptor );
2270 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2271 RequestedInformation & GROUP_SECURITY_INFORMATION)
2272 access |= WRITE_OWNER;
2273 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2274 access |= ACCESS_SYSTEM_SECURITY;
2275 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2276 access |= WRITE_DAC;
2278 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2279 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2280 if (file == INVALID_HANDLE_VALUE)
2281 return FALSE;
2283 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2284 CloseHandle( file );
2285 return set_ntstatus( status );
2288 /******************************************************************************
2289 * QueryWindows31FilesMigration [ADVAPI32.@]
2291 * PARAMS
2292 * x1 []
2294 BOOL WINAPI
2295 QueryWindows31FilesMigration( DWORD x1 )
2297 FIXME("(%d):stub\n",x1);
2298 return TRUE;
2301 /******************************************************************************
2302 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2304 * PARAMS
2305 * x1 []
2306 * x2 []
2307 * x3 []
2308 * x4 []
2310 BOOL WINAPI
2311 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2312 DWORD x4 )
2314 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2315 return TRUE;
2318 /******************************************************************************
2319 * NotifyBootConfigStatus [ADVAPI32.@]
2321 * PARAMS
2322 * x1 []
2324 BOOL WINAPI
2325 NotifyBootConfigStatus( BOOL x1 )
2327 FIXME("(0x%08d):stub\n",x1);
2328 return 1;
2331 /******************************************************************************
2332 * RevertToSelf [ADVAPI32.@]
2334 * Ends the impersonation of a user.
2336 * PARAMS
2337 * void []
2339 * RETURNS
2340 * Success: TRUE.
2341 * Failure: FALSE.
2343 BOOL WINAPI
2344 RevertToSelf( void )
2346 HANDLE Token = NULL;
2347 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2348 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2351 /******************************************************************************
2352 * ImpersonateSelf [ADVAPI32.@]
2354 * Makes an impersonation token that represents the process user and assigns
2355 * to the current thread.
2357 * PARAMS
2358 * ImpersonationLevel [I] Level at which to impersonate.
2360 * RETURNS
2361 * Success: TRUE.
2362 * Failure: FALSE.
2364 BOOL WINAPI
2365 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2367 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2370 /******************************************************************************
2371 * ImpersonateLoggedOnUser [ADVAPI32.@]
2373 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2375 DWORD size;
2376 NTSTATUS Status;
2377 HANDLE ImpersonationToken;
2378 TOKEN_TYPE Type;
2379 static BOOL warn = TRUE;
2381 if (warn)
2383 FIXME( "(%p)\n", hToken );
2384 warn = FALSE;
2386 if (!GetTokenInformation( hToken, TokenType, &Type,
2387 sizeof(TOKEN_TYPE), &size ))
2388 return FALSE;
2390 if (Type == TokenPrimary)
2392 OBJECT_ATTRIBUTES ObjectAttributes;
2394 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2396 Status = NtDuplicateToken( hToken,
2397 TOKEN_IMPERSONATE | TOKEN_QUERY,
2398 &ObjectAttributes,
2399 SecurityImpersonation,
2400 TokenImpersonation,
2401 &ImpersonationToken );
2402 if (Status != STATUS_SUCCESS)
2404 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2405 SetLastError( RtlNtStatusToDosError( Status ) );
2406 return FALSE;
2409 else
2410 ImpersonationToken = hToken;
2412 Status = NtSetInformationThread( GetCurrentThread(),
2413 ThreadImpersonationToken,
2414 &ImpersonationToken,
2415 sizeof(ImpersonationToken) );
2417 if (Type == TokenPrimary)
2418 NtClose( ImpersonationToken );
2420 if (Status != STATUS_SUCCESS)
2422 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2423 SetLastError( RtlNtStatusToDosError( Status ) );
2424 return FALSE;
2427 return TRUE;
2430 /******************************************************************************
2431 * AccessCheck [ADVAPI32.@]
2433 BOOL WINAPI
2434 AccessCheck(
2435 PSECURITY_DESCRIPTOR SecurityDescriptor,
2436 HANDLE ClientToken,
2437 DWORD DesiredAccess,
2438 PGENERIC_MAPPING GenericMapping,
2439 PPRIVILEGE_SET PrivilegeSet,
2440 LPDWORD PrivilegeSetLength,
2441 LPDWORD GrantedAccess,
2442 LPBOOL AccessStatus)
2444 NTSTATUS access_status;
2445 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2446 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2447 GrantedAccess, &access_status) );
2448 if (ret) *AccessStatus = set_ntstatus( access_status );
2449 return ret;
2453 /******************************************************************************
2454 * AccessCheckByType [ADVAPI32.@]
2456 BOOL WINAPI AccessCheckByType(
2457 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2458 PSID PrincipalSelfSid,
2459 HANDLE ClientToken,
2460 DWORD DesiredAccess,
2461 POBJECT_TYPE_LIST ObjectTypeList,
2462 DWORD ObjectTypeListLength,
2463 PGENERIC_MAPPING GenericMapping,
2464 PPRIVILEGE_SET PrivilegeSet,
2465 LPDWORD PrivilegeSetLength,
2466 LPDWORD GrantedAccess,
2467 LPBOOL AccessStatus)
2469 FIXME("stub\n");
2471 *AccessStatus = TRUE;
2473 return !*AccessStatus;
2476 /******************************************************************************
2477 * MapGenericMask [ADVAPI32.@]
2479 * Maps generic access rights into specific access rights according to the
2480 * supplied mapping.
2482 * PARAMS
2483 * AccessMask [I/O] Access rights.
2484 * GenericMapping [I] The mapping between generic and specific rights.
2486 * RETURNS
2487 * Nothing.
2489 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2491 RtlMapGenericMask( AccessMask, GenericMapping );
2494 /*************************************************************************
2495 * SetKernelObjectSecurity [ADVAPI32.@]
2497 BOOL WINAPI SetKernelObjectSecurity (
2498 IN HANDLE Handle,
2499 IN SECURITY_INFORMATION SecurityInformation,
2500 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2502 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2506 /******************************************************************************
2507 * AddAuditAccessAce [ADVAPI32.@]
2509 BOOL WINAPI AddAuditAccessAce(
2510 IN OUT PACL pAcl,
2511 IN DWORD dwAceRevision,
2512 IN DWORD dwAccessMask,
2513 IN PSID pSid,
2514 IN BOOL bAuditSuccess,
2515 IN BOOL bAuditFailure)
2517 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2518 bAuditSuccess, bAuditFailure) );
2521 /******************************************************************************
2522 * AddAuditAccessAce [ADVAPI32.@]
2524 BOOL WINAPI AddAuditAccessAceEx(
2525 IN OUT PACL pAcl,
2526 IN DWORD dwAceRevision,
2527 IN DWORD dwAceFlags,
2528 IN DWORD dwAccessMask,
2529 IN PSID pSid,
2530 IN BOOL bAuditSuccess,
2531 IN BOOL bAuditFailure)
2533 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2534 bAuditSuccess, bAuditFailure) );
2537 /******************************************************************************
2538 * LookupAccountNameA [ADVAPI32.@]
2540 BOOL WINAPI
2541 LookupAccountNameA(
2542 IN LPCSTR system,
2543 IN LPCSTR account,
2544 OUT PSID sid,
2545 OUT LPDWORD cbSid,
2546 LPSTR ReferencedDomainName,
2547 IN OUT LPDWORD cbReferencedDomainName,
2548 OUT PSID_NAME_USE name_use )
2550 BOOL ret;
2551 UNICODE_STRING lpSystemW;
2552 UNICODE_STRING lpAccountW;
2553 LPWSTR lpReferencedDomainNameW = NULL;
2555 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2556 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2558 if (ReferencedDomainName)
2559 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2561 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2562 cbReferencedDomainName, name_use);
2564 if (ret && lpReferencedDomainNameW)
2566 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2567 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2570 RtlFreeUnicodeString(&lpSystemW);
2571 RtlFreeUnicodeString(&lpAccountW);
2572 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2574 return ret;
2577 /******************************************************************************
2578 * lookup_user_account_name
2580 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2581 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2583 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2584 DWORD len = sizeof(buffer);
2585 HANDLE token;
2586 BOOL ret;
2587 PSID pSid;
2588 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2589 DWORD nameLen;
2591 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2593 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2594 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2597 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2598 CloseHandle( token );
2600 if (!ret) return FALSE;
2602 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2604 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2605 CopySid(*cbSid, Sid, pSid);
2606 if (*cbSid < GetLengthSid(pSid))
2608 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2609 ret = FALSE;
2611 *cbSid = GetLengthSid(pSid);
2613 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2614 if (!GetComputerNameW(domainName, &nameLen))
2616 domainName[0] = 0;
2617 nameLen = 0;
2619 if (*cchReferencedDomainName <= nameLen || !ret)
2621 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2622 nameLen += 1;
2623 ret = FALSE;
2625 else if (ReferencedDomainName)
2626 strcpyW(ReferencedDomainName, domainName);
2628 *cchReferencedDomainName = nameLen;
2630 if (ret)
2631 *peUse = SidTypeUser;
2633 return ret;
2636 /******************************************************************************
2637 * lookup_computer_account_name
2639 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2640 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2642 MAX_SID local;
2643 BOOL ret;
2644 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2645 DWORD nameLen;
2647 if ((ret = ADVAPI_GetComputerSid(&local)))
2649 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2650 CopySid(*cbSid, Sid, &local);
2651 if (*cbSid < GetLengthSid(&local))
2653 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2654 ret = FALSE;
2656 *cbSid = GetLengthSid(&local);
2659 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2660 if (!GetComputerNameW(domainName, &nameLen))
2662 domainName[0] = 0;
2663 nameLen = 0;
2665 if (*cchReferencedDomainName <= nameLen || !ret)
2667 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2668 nameLen += 1;
2669 ret = FALSE;
2671 else if (ReferencedDomainName)
2672 strcpyW(ReferencedDomainName, domainName);
2674 *cchReferencedDomainName = nameLen;
2676 if (ret)
2677 *peUse = SidTypeDomain;
2679 return ret;
2682 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2683 LSA_UNICODE_STRING *domain )
2685 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2687 while (p > str->Buffer && *p != '\\') p--;
2689 if (*p == '\\')
2691 domain->Buffer = str->Buffer;
2692 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2694 account->Buffer = p + 1;
2695 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2697 else
2699 domain->Buffer = NULL;
2700 domain->Length = 0;
2702 account->Buffer = str->Buffer;
2703 account->Length = str->Length;
2707 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2709 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2711 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2712 return TRUE;
2714 return FALSE;
2717 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2719 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2721 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2722 return TRUE;
2724 if (ACCOUNT_SIDS[idx].alias)
2726 len = strlenW( ACCOUNT_SIDS[idx].alias );
2727 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2728 return TRUE;
2730 return FALSE;
2734 * Helper function for LookupAccountNameW
2736 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2737 PSID Sid, LPDWORD cbSid,
2738 LPWSTR ReferencedDomainName,
2739 LPDWORD cchReferencedDomainName,
2740 PSID_NAME_USE peUse, BOOL *handled )
2742 PSID pSid;
2743 LSA_UNICODE_STRING account, domain;
2744 BOOL ret = TRUE;
2745 ULONG i;
2747 *handled = FALSE;
2748 split_domain_account( account_and_domain, &account, &domain );
2750 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2752 /* check domain first */
2753 if (domain.Buffer && !match_domain( i, &domain )) continue;
2755 if (match_account( i, &account ))
2757 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2759 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2761 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2763 if (*cbSid < sidLen)
2765 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2766 ret = FALSE;
2768 else if (Sid)
2770 CopySid(*cbSid, Sid, pSid);
2772 *cbSid = sidLen;
2775 len = strlenW( ACCOUNT_SIDS[i].domain );
2776 if (*cchReferencedDomainName <= len || !ret)
2778 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2779 len++;
2780 ret = FALSE;
2782 else if (ReferencedDomainName)
2784 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2787 *cchReferencedDomainName = len;
2788 if (ret)
2789 *peUse = ACCOUNT_SIDS[i].name_use;
2791 HeapFree(GetProcessHeap(), 0, pSid);
2792 *handled = TRUE;
2793 return ret;
2796 return ret;
2799 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2800 PSID Sid, LPDWORD cbSid,
2801 LPWSTR ReferencedDomainName,
2802 LPDWORD cchReferencedDomainName,
2803 PSID_NAME_USE peUse, BOOL *handled )
2805 DWORD nameLen;
2806 LPWSTR userName = NULL;
2807 LSA_UNICODE_STRING account, domain;
2808 BOOL ret = TRUE;
2810 *handled = FALSE;
2811 split_domain_account( account_and_domain, &account, &domain );
2813 /* Let the current Unix user id masquerade as first Windows user account */
2815 nameLen = UNLEN + 1;
2816 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2818 if (domain.Buffer)
2820 /* check to make sure this account is on this computer */
2821 if (GetComputerNameW( userName, &nameLen ) &&
2822 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2824 SetLastError(ERROR_NONE_MAPPED);
2825 ret = FALSE;
2827 nameLen = UNLEN + 1;
2830 if (GetUserNameW( userName, &nameLen ) &&
2831 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2833 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2834 *handled = TRUE;
2836 else
2838 nameLen = UNLEN + 1;
2839 if (GetComputerNameW( userName, &nameLen ) &&
2840 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2842 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2843 *handled = TRUE;
2847 HeapFree(GetProcessHeap(), 0, userName);
2848 return ret;
2851 /******************************************************************************
2852 * LookupAccountNameW [ADVAPI32.@]
2854 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2855 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2856 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2858 BOOL ret, handled;
2859 LSA_UNICODE_STRING account;
2861 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2862 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2864 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2866 FIXME("remote computer not supported\n");
2867 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2868 return FALSE;
2871 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2873 lpAccountName = BUILTIN;
2876 RtlInitUnicodeString( &account, lpAccountName );
2878 /* Check well known SIDs first */
2879 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2880 cchReferencedDomainName, peUse, &handled );
2881 if (handled)
2882 return ret;
2884 /* Check user names */
2885 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2886 cchReferencedDomainName, peUse, &handled);
2887 if (handled)
2888 return ret;
2890 SetLastError( ERROR_NONE_MAPPED );
2891 return FALSE;
2894 /******************************************************************************
2895 * PrivilegeCheck [ADVAPI32.@]
2897 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2899 BOOL ret;
2900 BOOLEAN Result;
2902 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2904 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2905 if (ret)
2906 *pfResult = Result;
2907 return ret;
2910 /******************************************************************************
2911 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2913 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2914 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2915 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2916 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2918 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2919 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2920 SecurityDescriptor, DesiredAccess, GenericMapping,
2921 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2922 return TRUE;
2925 /******************************************************************************
2926 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2928 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2929 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2930 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2931 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2933 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2934 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2935 SecurityDescriptor, DesiredAccess, GenericMapping,
2936 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2937 return TRUE;
2940 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2942 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2944 return TRUE;
2947 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2949 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2951 return TRUE;
2954 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2956 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2958 return TRUE;
2961 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2962 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2963 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2964 LPBOOL GenerateOnClose)
2966 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2967 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2968 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2969 GenerateOnClose);
2971 return TRUE;
2974 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2975 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2976 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2977 LPBOOL GenerateOnClose)
2979 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2980 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2981 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2982 GenerateOnClose);
2984 return TRUE;
2987 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2988 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2990 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2991 DesiredAccess, Privileges, AccessGranted);
2993 return TRUE;
2996 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2997 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2999 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3000 DesiredAccess, Privileges, AccessGranted);
3002 return TRUE;
3005 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3006 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3008 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3009 ClientToken, Privileges, AccessGranted);
3011 return TRUE;
3014 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3015 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3017 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3018 ClientToken, Privileges, AccessGranted);
3020 return TRUE;
3023 /******************************************************************************
3024 * GetSecurityInfo [ADVAPI32.@]
3026 * Retrieves a copy of the security descriptor associated with an object.
3028 * PARAMS
3029 * hObject [I] A handle for the object.
3030 * ObjectType [I] The type of object.
3031 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3032 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3033 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3034 * ppDacl [O] If non-null, receives a pointer to the DACL.
3035 * ppSacl [O] If non-null, receives a pointer to the SACL.
3036 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3037 * which must be freed with LocalFree.
3039 * RETURNS
3040 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3042 DWORD WINAPI GetSecurityInfo(
3043 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3044 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3045 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3046 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3049 PSECURITY_DESCRIPTOR sd;
3050 NTSTATUS status;
3051 ULONG n1, n2;
3052 BOOL present, defaulted;
3054 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3055 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3056 return RtlNtStatusToDosError(status);
3058 sd = LocalAlloc(0, n1);
3059 if (!sd)
3060 return ERROR_NOT_ENOUGH_MEMORY;
3062 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3063 if (status != STATUS_SUCCESS)
3065 LocalFree(sd);
3066 return RtlNtStatusToDosError(status);
3069 if (ppsidOwner)
3071 *ppsidOwner = NULL;
3072 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3074 if (ppsidGroup)
3076 *ppsidGroup = NULL;
3077 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3079 if (ppDacl)
3081 *ppDacl = NULL;
3082 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3084 if (ppSacl)
3086 *ppSacl = NULL;
3087 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3089 if (ppSecurityDescriptor)
3090 *ppSecurityDescriptor = sd;
3092 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3093 * NULL, because native happily returns the SIDs and ACLs that are requested
3094 * in this case.
3097 return ERROR_SUCCESS;
3100 /******************************************************************************
3101 * GetSecurityInfoExA [ADVAPI32.@]
3103 DWORD WINAPI GetSecurityInfoExA(
3104 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3105 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3106 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3107 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3110 FIXME("stub!\n");
3111 return ERROR_BAD_PROVIDER;
3114 /******************************************************************************
3115 * GetSecurityInfoExW [ADVAPI32.@]
3117 DWORD WINAPI GetSecurityInfoExW(
3118 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3119 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3120 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3121 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3124 FIXME("stub!\n");
3125 return ERROR_BAD_PROVIDER;
3128 /******************************************************************************
3129 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3131 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3132 LPSTR pTrusteeName, DWORD AccessPermissions,
3133 ACCESS_MODE AccessMode, DWORD Inheritance )
3135 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3136 AccessPermissions, AccessMode, Inheritance);
3138 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3139 pExplicitAccess->grfAccessMode = AccessMode;
3140 pExplicitAccess->grfInheritance = Inheritance;
3142 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3143 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3144 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3145 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3146 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3149 /******************************************************************************
3150 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3152 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3153 LPWSTR pTrusteeName, DWORD AccessPermissions,
3154 ACCESS_MODE AccessMode, DWORD Inheritance )
3156 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3157 AccessPermissions, AccessMode, Inheritance);
3159 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3160 pExplicitAccess->grfAccessMode = AccessMode;
3161 pExplicitAccess->grfInheritance = Inheritance;
3163 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3164 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3165 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3166 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3167 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3170 /******************************************************************************
3171 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3173 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3174 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3175 LPSTR InheritedObjectTypeName, LPSTR Name )
3177 DWORD ObjectsPresent = 0;
3179 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3180 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3182 /* Fill the OBJECTS_AND_NAME structure */
3183 pObjName->ObjectType = ObjectType;
3184 if (ObjectTypeName != NULL)
3186 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3189 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3190 if (InheritedObjectTypeName != NULL)
3192 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3195 pObjName->ObjectsPresent = ObjectsPresent;
3196 pObjName->ptstrName = Name;
3198 /* Fill the TRUSTEE structure */
3199 pTrustee->pMultipleTrustee = NULL;
3200 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3201 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3202 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3203 pTrustee->ptstrName = (LPSTR)pObjName;
3206 /******************************************************************************
3207 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3209 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3210 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3211 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3213 DWORD ObjectsPresent = 0;
3215 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3216 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3218 /* Fill the OBJECTS_AND_NAME structure */
3219 pObjName->ObjectType = ObjectType;
3220 if (ObjectTypeName != NULL)
3222 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3225 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3226 if (InheritedObjectTypeName != NULL)
3228 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3231 pObjName->ObjectsPresent = ObjectsPresent;
3232 pObjName->ptstrName = Name;
3234 /* Fill the TRUSTEE structure */
3235 pTrustee->pMultipleTrustee = NULL;
3236 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3237 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3238 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3239 pTrustee->ptstrName = (LPWSTR)pObjName;
3242 /******************************************************************************
3243 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3245 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3246 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3248 DWORD ObjectsPresent = 0;
3250 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3252 /* Fill the OBJECTS_AND_SID structure */
3253 if (pObjectGuid != NULL)
3255 pObjSid->ObjectTypeGuid = *pObjectGuid;
3256 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3258 else
3260 ZeroMemory(&pObjSid->ObjectTypeGuid,
3261 sizeof(GUID));
3264 if (pInheritedObjectGuid != NULL)
3266 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3267 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3269 else
3271 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3272 sizeof(GUID));
3275 pObjSid->ObjectsPresent = ObjectsPresent;
3276 pObjSid->pSid = pSid;
3278 /* Fill the TRUSTEE structure */
3279 pTrustee->pMultipleTrustee = NULL;
3280 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3281 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3282 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3283 pTrustee->ptstrName = (LPSTR) pObjSid;
3286 /******************************************************************************
3287 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3289 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3290 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3292 DWORD ObjectsPresent = 0;
3294 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3296 /* Fill the OBJECTS_AND_SID structure */
3297 if (pObjectGuid != NULL)
3299 pObjSid->ObjectTypeGuid = *pObjectGuid;
3300 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3302 else
3304 ZeroMemory(&pObjSid->ObjectTypeGuid,
3305 sizeof(GUID));
3308 if (pInheritedObjectGuid != NULL)
3310 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3311 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3313 else
3315 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3316 sizeof(GUID));
3319 pObjSid->ObjectsPresent = ObjectsPresent;
3320 pObjSid->pSid = pSid;
3322 /* Fill the TRUSTEE structure */
3323 pTrustee->pMultipleTrustee = NULL;
3324 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3325 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3326 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3327 pTrustee->ptstrName = (LPWSTR) pObjSid;
3330 /******************************************************************************
3331 * BuildTrusteeWithSidA [ADVAPI32.@]
3333 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3335 TRACE("%p %p\n", pTrustee, pSid);
3337 pTrustee->pMultipleTrustee = NULL;
3338 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3339 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3340 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3341 pTrustee->ptstrName = pSid;
3344 /******************************************************************************
3345 * BuildTrusteeWithSidW [ADVAPI32.@]
3347 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3349 TRACE("%p %p\n", pTrustee, pSid);
3351 pTrustee->pMultipleTrustee = NULL;
3352 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3353 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3354 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3355 pTrustee->ptstrName = pSid;
3358 /******************************************************************************
3359 * BuildTrusteeWithNameA [ADVAPI32.@]
3361 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3363 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3365 pTrustee->pMultipleTrustee = NULL;
3366 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3367 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3368 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3369 pTrustee->ptstrName = name;
3372 /******************************************************************************
3373 * BuildTrusteeWithNameW [ADVAPI32.@]
3375 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3377 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3379 pTrustee->pMultipleTrustee = NULL;
3380 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3381 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3382 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3383 pTrustee->ptstrName = name;
3386 /******************************************************************************
3387 * GetTrusteeFormA [ADVAPI32.@]
3389 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3391 TRACE("(%p)\n", pTrustee);
3393 if (!pTrustee)
3394 return TRUSTEE_BAD_FORM;
3396 return pTrustee->TrusteeForm;
3399 /******************************************************************************
3400 * GetTrusteeFormW [ADVAPI32.@]
3402 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3404 TRACE("(%p)\n", pTrustee);
3406 if (!pTrustee)
3407 return TRUSTEE_BAD_FORM;
3409 return pTrustee->TrusteeForm;
3412 /******************************************************************************
3413 * GetTrusteeNameA [ADVAPI32.@]
3415 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3417 TRACE("(%p)\n", pTrustee);
3419 if (!pTrustee)
3420 return NULL;
3422 return pTrustee->ptstrName;
3425 /******************************************************************************
3426 * GetTrusteeNameW [ADVAPI32.@]
3428 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3430 TRACE("(%p)\n", pTrustee);
3432 if (!pTrustee)
3433 return NULL;
3435 return pTrustee->ptstrName;
3438 /******************************************************************************
3439 * GetTrusteeTypeA [ADVAPI32.@]
3441 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3443 TRACE("(%p)\n", pTrustee);
3445 if (!pTrustee)
3446 return TRUSTEE_IS_UNKNOWN;
3448 return pTrustee->TrusteeType;
3451 /******************************************************************************
3452 * GetTrusteeTypeW [ADVAPI32.@]
3454 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3456 TRACE("(%p)\n", pTrustee);
3458 if (!pTrustee)
3459 return TRUSTEE_IS_UNKNOWN;
3461 return pTrustee->TrusteeType;
3464 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3465 DWORD nAclInformationLength,
3466 ACL_INFORMATION_CLASS dwAclInformationClass )
3468 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3469 nAclInformationLength, dwAclInformationClass);
3471 return TRUE;
3474 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3476 DWORD len;
3478 switch (form)
3480 case TRUSTEE_IS_NAME:
3482 WCHAR *wstr = NULL;
3484 if (trustee_nameA)
3486 len = MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, NULL, 0 );
3487 if (!(wstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3488 return ERROR_NOT_ENOUGH_MEMORY;
3490 MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, wstr, len );
3493 *ptrustee_nameW = wstr;
3494 return ERROR_SUCCESS;
3496 case TRUSTEE_IS_OBJECTS_AND_NAME:
3498 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3499 OBJECTS_AND_NAME_W *objW = NULL;
3501 if (objA)
3503 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3504 return ERROR_NOT_ENOUGH_MEMORY;
3506 objW->ObjectsPresent = objA->ObjectsPresent;
3507 objW->ObjectType = objA->ObjectType;
3508 objW->ObjectTypeName = NULL;
3509 objW->InheritedObjectTypeName = NULL;
3510 objW->ptstrName = NULL;
3512 if (objA->ObjectTypeName)
3514 len = MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, NULL, 0 );
3515 if (!(objW->ObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3516 goto error;
3517 MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, objW->ObjectTypeName, len );
3520 if (objA->InheritedObjectTypeName)
3522 len = MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, NULL, 0 );
3523 if (!(objW->InheritedObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3524 goto error;
3525 MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, objW->InheritedObjectTypeName, len );
3528 if (objA->ptstrName)
3530 len = MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, NULL, 0 );
3531 if (!(objW->ptstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3532 goto error;
3533 MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, objW->ptstrName, len );
3537 *ptrustee_nameW = (WCHAR *)objW;
3538 return ERROR_SUCCESS;
3539 error:
3540 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3541 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3542 HeapFree( GetProcessHeap(), 0, objW );
3543 return ERROR_NOT_ENOUGH_MEMORY;
3545 /* These forms do not require conversion. */
3546 case TRUSTEE_IS_SID:
3547 case TRUSTEE_IS_OBJECTS_AND_SID:
3548 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3549 return ERROR_SUCCESS;
3550 default:
3551 return ERROR_INVALID_PARAMETER;
3555 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3557 switch (form)
3559 case TRUSTEE_IS_NAME:
3560 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3561 break;
3562 case TRUSTEE_IS_OBJECTS_AND_NAME:
3564 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3566 if (objW)
3568 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3569 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3570 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3571 HeapFree( GetProcessHeap(), 0, objW );
3574 break;
3576 /* Other forms did not require allocation, so no freeing is necessary. */
3577 default:
3578 break;
3582 /******************************************************************************
3583 * SetEntriesInAclA [ADVAPI32.@]
3585 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3586 PACL OldAcl, PACL* NewAcl )
3588 DWORD err = ERROR_SUCCESS;
3589 EXPLICIT_ACCESSW *pEntriesW;
3590 int alloc_index, free_index;
3592 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3594 if (NewAcl)
3595 *NewAcl = NULL;
3597 if (!count && !OldAcl)
3598 return ERROR_SUCCESS;
3600 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3601 if (!pEntriesW)
3602 return ERROR_NOT_ENOUGH_MEMORY;
3604 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3606 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3607 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3608 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3609 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3610 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3611 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3612 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3614 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3615 pEntries[alloc_index].Trustee.ptstrName,
3616 &pEntriesW[alloc_index].Trustee.ptstrName );
3617 if (err != ERROR_SUCCESS)
3619 if (err == ERROR_INVALID_PARAMETER)
3620 WARN("bad trustee form %d for trustee %d\n",
3621 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3623 goto cleanup;
3627 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3629 cleanup:
3630 /* Free any previously allocated trustee name buffers, taking into account
3631 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3632 * list. */
3633 for (free_index = 0; free_index < alloc_index; ++free_index)
3634 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3636 HeapFree( GetProcessHeap(), 0, pEntriesW );
3637 return err;
3640 /******************************************************************************
3641 * SetEntriesInAclW [ADVAPI32.@]
3643 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3644 PACL OldAcl, PACL* NewAcl )
3646 ULONG i;
3647 PSID *ppsid;
3648 DWORD ret = ERROR_SUCCESS;
3649 DWORD acl_size = sizeof(ACL);
3650 NTSTATUS status;
3652 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3654 if (NewAcl)
3655 *NewAcl = NULL;
3657 if (!count && !OldAcl)
3658 return ERROR_SUCCESS;
3660 /* allocate array of maximum sized sids allowed */
3661 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3662 if (!ppsid)
3663 return ERROR_OUTOFMEMORY;
3665 for (i = 0; i < count; i++)
3667 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3669 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3670 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3671 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3672 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3673 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3674 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3675 pEntries[i].Trustee.ptstrName);
3677 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3679 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3680 ret = ERROR_INVALID_PARAMETER;
3681 goto exit;
3684 switch (pEntries[i].Trustee.TrusteeForm)
3686 case TRUSTEE_IS_SID:
3687 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3688 ppsid[i], pEntries[i].Trustee.ptstrName))
3690 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3691 ret = ERROR_INVALID_PARAMETER;
3692 goto exit;
3694 break;
3695 case TRUSTEE_IS_NAME:
3697 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3698 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3699 SID_NAME_USE use;
3700 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3702 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3704 ret = GetLastError();
3705 goto exit;
3708 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3710 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3711 ret = ERROR_INVALID_PARAMETER;
3712 goto exit;
3714 break;
3716 case TRUSTEE_IS_OBJECTS_AND_SID:
3717 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3718 break;
3719 case TRUSTEE_IS_OBJECTS_AND_NAME:
3720 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3721 break;
3722 default:
3723 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3724 ret = ERROR_INVALID_PARAMETER;
3725 goto exit;
3728 /* Note: we overestimate the ACL size here as a tradeoff between
3729 * instructions (simplicity) and memory */
3730 switch (pEntries[i].grfAccessMode)
3732 case GRANT_ACCESS:
3733 case SET_ACCESS:
3734 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3735 break;
3736 case DENY_ACCESS:
3737 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3738 break;
3739 case SET_AUDIT_SUCCESS:
3740 case SET_AUDIT_FAILURE:
3741 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3742 break;
3743 case REVOKE_ACCESS:
3744 break;
3745 default:
3746 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3747 ret = ERROR_INVALID_PARAMETER;
3748 goto exit;
3752 if (OldAcl)
3754 ACL_SIZE_INFORMATION size_info;
3756 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3757 if (status != STATUS_SUCCESS)
3759 ret = RtlNtStatusToDosError(status);
3760 goto exit;
3762 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3765 *NewAcl = LocalAlloc(0, acl_size);
3766 if (!*NewAcl)
3768 ret = ERROR_OUTOFMEMORY;
3769 goto exit;
3772 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3773 if (status != STATUS_SUCCESS)
3775 ret = RtlNtStatusToDosError(status);
3776 goto exit;
3779 for (i = 0; i < count; i++)
3781 switch (pEntries[i].grfAccessMode)
3783 case GRANT_ACCESS:
3784 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3785 pEntries[i].grfInheritance,
3786 pEntries[i].grfAccessPermissions,
3787 ppsid[i]);
3788 break;
3789 case SET_ACCESS:
3791 ULONG j;
3792 BOOL add = TRUE;
3793 if (OldAcl)
3795 for (j = 0; ; j++)
3797 const ACE_HEADER *existing_ace_header;
3798 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3799 if (status != STATUS_SUCCESS)
3800 break;
3801 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3802 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3803 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3805 add = FALSE;
3806 break;
3810 if (add)
3811 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3812 pEntries[i].grfInheritance,
3813 pEntries[i].grfAccessPermissions,
3814 ppsid[i]);
3815 break;
3817 case DENY_ACCESS:
3818 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3819 pEntries[i].grfInheritance,
3820 pEntries[i].grfAccessPermissions,
3821 ppsid[i]);
3822 break;
3823 case SET_AUDIT_SUCCESS:
3824 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3825 pEntries[i].grfInheritance,
3826 pEntries[i].grfAccessPermissions,
3827 ppsid[i], TRUE, FALSE);
3828 break;
3829 case SET_AUDIT_FAILURE:
3830 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3831 pEntries[i].grfInheritance,
3832 pEntries[i].grfAccessPermissions,
3833 ppsid[i], FALSE, TRUE);
3834 break;
3835 default:
3836 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3840 if (OldAcl)
3842 for (i = 0; ; i++)
3844 BOOL add = TRUE;
3845 ULONG j;
3846 const ACE_HEADER *old_ace_header;
3847 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3848 if (status != STATUS_SUCCESS) break;
3849 for (j = 0; j < count; j++)
3851 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3852 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3853 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3855 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3856 add = FALSE;
3857 break;
3859 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3861 switch (old_ace_header->AceType)
3863 case ACCESS_ALLOWED_ACE_TYPE:
3864 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3865 add = FALSE;
3866 break;
3867 case ACCESS_DENIED_ACE_TYPE:
3868 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3869 add = FALSE;
3870 break;
3871 case SYSTEM_AUDIT_ACE_TYPE:
3872 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3873 add = FALSE;
3874 break;
3875 case SYSTEM_ALARM_ACE_TYPE:
3876 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3877 add = FALSE;
3878 break;
3879 default:
3880 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3883 if (!add)
3884 break;
3887 if (add)
3888 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3889 if (status != STATUS_SUCCESS)
3891 WARN("RtlAddAce failed with error 0x%08x\n", status);
3892 ret = RtlNtStatusToDosError(status);
3893 break;
3898 exit:
3899 HeapFree(GetProcessHeap(), 0, ppsid);
3900 return ret;
3903 /******************************************************************************
3904 * SetNamedSecurityInfoA [ADVAPI32.@]
3906 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3907 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3908 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3910 DWORD len;
3911 LPWSTR wstr = NULL;
3912 DWORD r;
3914 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3915 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3917 if( pObjectName )
3919 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3920 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3921 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3924 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3925 psidGroup, pDacl, pSacl );
3927 HeapFree( GetProcessHeap(), 0, wstr );
3929 return r;
3932 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3933 PSECURITY_DESCRIPTOR ModificationDescriptor,
3934 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3935 PGENERIC_MAPPING GenericMapping,
3936 HANDLE Token )
3938 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3939 ObjectsSecurityDescriptor, GenericMapping, Token);
3941 return TRUE;
3944 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3946 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3949 /******************************************************************************
3950 * AreAnyAccessesGranted [ADVAPI32.@]
3952 * Determines whether or not any of a set of specified access permissions have
3953 * been granted or not.
3955 * PARAMS
3956 * GrantedAccess [I] The permissions that have been granted.
3957 * DesiredAccess [I] The permissions that you want to have.
3959 * RETURNS
3960 * Nonzero if any of the permissions have been granted, zero if none of the
3961 * permissions have been granted.
3964 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3966 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3969 /******************************************************************************
3970 * SetNamedSecurityInfoW [ADVAPI32.@]
3972 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3973 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3974 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3976 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3977 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3978 return ERROR_SUCCESS;
3981 /******************************************************************************
3982 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3984 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3985 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3987 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3988 return ERROR_CALL_NOT_IMPLEMENTED;
3991 /******************************************************************************
3992 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3994 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3995 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3997 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3998 return ERROR_CALL_NOT_IMPLEMENTED;
4001 /******************************************************************************
4002 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4004 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4005 PACCESS_MASK pFailedAuditRights)
4007 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4008 return ERROR_CALL_NOT_IMPLEMENTED;
4012 /******************************************************************************
4013 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4015 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4016 PACCESS_MASK pFailedAuditRights)
4018 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4019 return ERROR_CALL_NOT_IMPLEMENTED;
4023 /******************************************************************************
4024 * ParseAclStringFlags
4026 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4028 DWORD flags = 0;
4029 LPCWSTR szAcl = *StringAcl;
4031 while (*szAcl != '(')
4033 if (*szAcl == 'P')
4035 flags |= SE_DACL_PROTECTED;
4037 else if (*szAcl == 'A')
4039 szAcl++;
4040 if (*szAcl == 'R')
4041 flags |= SE_DACL_AUTO_INHERIT_REQ;
4042 else if (*szAcl == 'I')
4043 flags |= SE_DACL_AUTO_INHERITED;
4045 szAcl++;
4048 *StringAcl = szAcl;
4049 return flags;
4052 /******************************************************************************
4053 * ParseAceStringType
4055 static const ACEFLAG AceType[] =
4057 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4058 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4059 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4060 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4062 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4063 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4064 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4065 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4067 { NULL, 0 },
4070 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4072 UINT len = 0;
4073 LPCWSTR szAcl = *StringAcl;
4074 const ACEFLAG *lpaf = AceType;
4076 while (*szAcl == ' ')
4077 szAcl++;
4079 while (lpaf->wstr &&
4080 (len = strlenW(lpaf->wstr)) &&
4081 strncmpW(lpaf->wstr, szAcl, len))
4082 lpaf++;
4084 if (!lpaf->wstr)
4085 return 0;
4087 *StringAcl = szAcl + len;
4088 return lpaf->value;
4092 /******************************************************************************
4093 * ParseAceStringFlags
4095 static const ACEFLAG AceFlags[] =
4097 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4098 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4099 { SDDL_INHERITED, INHERITED_ACE },
4100 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4101 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4102 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4103 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4104 { NULL, 0 },
4107 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4109 UINT len = 0;
4110 BYTE flags = 0;
4111 LPCWSTR szAcl = *StringAcl;
4113 while (*szAcl == ' ')
4114 szAcl++;
4116 while (*szAcl != ';')
4118 const ACEFLAG *lpaf = AceFlags;
4120 while (lpaf->wstr &&
4121 (len = strlenW(lpaf->wstr)) &&
4122 strncmpW(lpaf->wstr, szAcl, len))
4123 lpaf++;
4125 if (!lpaf->wstr)
4126 return 0;
4128 flags |= lpaf->value;
4129 szAcl += len;
4132 *StringAcl = szAcl;
4133 return flags;
4137 /******************************************************************************
4138 * ParseAceStringRights
4140 static const ACEFLAG AceRights[] =
4142 { SDDL_GENERIC_ALL, GENERIC_ALL },
4143 { SDDL_GENERIC_READ, GENERIC_READ },
4144 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4145 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4147 { SDDL_READ_CONTROL, READ_CONTROL },
4148 { SDDL_STANDARD_DELETE, DELETE },
4149 { SDDL_WRITE_DAC, WRITE_DAC },
4150 { SDDL_WRITE_OWNER, WRITE_OWNER },
4152 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4153 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4154 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4155 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4156 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4157 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4158 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4159 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4160 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4162 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4163 { SDDL_FILE_READ, FILE_GENERIC_READ },
4164 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4165 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4167 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4168 { SDDL_KEY_READ, KEY_READ },
4169 { SDDL_KEY_WRITE, KEY_WRITE },
4170 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4171 { NULL, 0 },
4174 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4176 UINT len = 0;
4177 DWORD rights = 0;
4178 LPCWSTR szAcl = *StringAcl;
4180 while (*szAcl == ' ')
4181 szAcl++;
4183 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4185 LPCWSTR p = szAcl;
4187 while (*p && *p != ';')
4188 p++;
4190 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4192 rights = strtoulW(szAcl, NULL, 16);
4193 szAcl = p;
4195 else
4196 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4198 else
4200 while (*szAcl != ';')
4202 const ACEFLAG *lpaf = AceRights;
4204 while (lpaf->wstr &&
4205 (len = strlenW(lpaf->wstr)) &&
4206 strncmpW(lpaf->wstr, szAcl, len))
4208 lpaf++;
4211 if (!lpaf->wstr)
4212 return 0;
4214 rights |= lpaf->value;
4215 szAcl += len;
4219 *StringAcl = szAcl;
4220 return rights;
4224 /******************************************************************************
4225 * ParseStringAclToAcl
4227 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4229 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4230 PACL pAcl, LPDWORD cBytes)
4232 DWORD val;
4233 DWORD sidlen;
4234 DWORD length = sizeof(ACL);
4235 DWORD acesize = 0;
4236 DWORD acecount = 0;
4237 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4238 DWORD error = ERROR_INVALID_ACL;
4240 TRACE("%s\n", debugstr_w(StringAcl));
4242 if (!StringAcl)
4243 return FALSE;
4245 if (pAcl) /* pAce is only useful if we're setting values */
4246 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4248 /* Parse ACL flags */
4249 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4251 /* Parse ACE */
4252 while (*StringAcl == '(')
4254 StringAcl++;
4256 /* Parse ACE type */
4257 val = ParseAceStringType(&StringAcl);
4258 if (pAce)
4259 pAce->Header.AceType = (BYTE) val;
4260 if (*StringAcl != ';')
4262 error = RPC_S_INVALID_STRING_UUID;
4263 goto lerr;
4265 StringAcl++;
4267 /* Parse ACE flags */
4268 val = ParseAceStringFlags(&StringAcl);
4269 if (pAce)
4270 pAce->Header.AceFlags = (BYTE) val;
4271 if (*StringAcl != ';')
4272 goto lerr;
4273 StringAcl++;
4275 /* Parse ACE rights */
4276 val = ParseAceStringRights(&StringAcl);
4277 if (pAce)
4278 pAce->Mask = val;
4279 if (*StringAcl != ';')
4280 goto lerr;
4281 StringAcl++;
4283 /* Parse ACE object guid */
4284 while (*StringAcl == ' ')
4285 StringAcl++;
4286 if (*StringAcl != ';')
4288 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4289 goto lerr;
4291 StringAcl++;
4293 /* Parse ACE inherit object guid */
4294 while (*StringAcl == ' ')
4295 StringAcl++;
4296 if (*StringAcl != ';')
4298 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4299 goto lerr;
4301 StringAcl++;
4303 /* Parse ACE account sid */
4304 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4306 while (*StringAcl && *StringAcl != ')')
4307 StringAcl++;
4310 if (*StringAcl != ')')
4311 goto lerr;
4312 StringAcl++;
4314 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4315 length += acesize;
4316 if (pAce)
4318 pAce->Header.AceSize = acesize;
4319 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4321 acecount++;
4324 *cBytes = length;
4326 if (length > 0xffff)
4328 ERR("ACL too large\n");
4329 goto lerr;
4332 if (pAcl)
4334 pAcl->AclRevision = ACL_REVISION;
4335 pAcl->Sbz1 = 0;
4336 pAcl->AclSize = length;
4337 pAcl->AceCount = acecount++;
4338 pAcl->Sbz2 = 0;
4340 return TRUE;
4342 lerr:
4343 SetLastError(error);
4344 WARN("Invalid ACE string format\n");
4345 return FALSE;
4349 /******************************************************************************
4350 * ParseStringSecurityDescriptorToSecurityDescriptor
4352 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4353 LPCWSTR StringSecurityDescriptor,
4354 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4355 LPDWORD cBytes)
4357 BOOL bret = FALSE;
4358 WCHAR toktype;
4359 WCHAR tok[MAX_PATH];
4360 LPCWSTR lptoken;
4361 LPBYTE lpNext = NULL;
4362 DWORD len;
4364 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4366 if (SecurityDescriptor)
4367 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4369 while (*StringSecurityDescriptor == ' ')
4370 StringSecurityDescriptor++;
4372 while (*StringSecurityDescriptor)
4374 toktype = *StringSecurityDescriptor;
4376 /* Expect char identifier followed by ':' */
4377 StringSecurityDescriptor++;
4378 if (*StringSecurityDescriptor != ':')
4380 SetLastError(ERROR_INVALID_PARAMETER);
4381 goto lend;
4383 StringSecurityDescriptor++;
4385 /* Extract token */
4386 lptoken = StringSecurityDescriptor;
4387 while (*lptoken && *lptoken != ':')
4388 lptoken++;
4390 if (*lptoken)
4391 lptoken--;
4393 len = lptoken - StringSecurityDescriptor;
4394 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4395 tok[len] = 0;
4397 switch (toktype)
4399 case 'O':
4401 DWORD bytes;
4403 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4404 goto lend;
4406 if (SecurityDescriptor)
4408 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4409 lpNext += bytes; /* Advance to next token */
4412 *cBytes += bytes;
4414 break;
4417 case 'G':
4419 DWORD bytes;
4421 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4422 goto lend;
4424 if (SecurityDescriptor)
4426 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4427 lpNext += bytes; /* Advance to next token */
4430 *cBytes += bytes;
4432 break;
4435 case 'D':
4437 DWORD flags;
4438 DWORD bytes;
4440 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4441 goto lend;
4443 if (SecurityDescriptor)
4445 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4446 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4447 lpNext += bytes; /* Advance to next token */
4450 *cBytes += bytes;
4452 break;
4455 case 'S':
4457 DWORD flags;
4458 DWORD bytes;
4460 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4461 goto lend;
4463 if (SecurityDescriptor)
4465 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4466 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4467 lpNext += bytes; /* Advance to next token */
4470 *cBytes += bytes;
4472 break;
4475 default:
4476 FIXME("Unknown token\n");
4477 SetLastError(ERROR_INVALID_PARAMETER);
4478 goto lend;
4481 StringSecurityDescriptor = lptoken;
4484 bret = TRUE;
4486 lend:
4487 return bret;
4490 /******************************************************************************
4491 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4493 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4494 LPCSTR StringSecurityDescriptor,
4495 DWORD StringSDRevision,
4496 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4497 PULONG SecurityDescriptorSize)
4499 UINT len;
4500 BOOL ret = FALSE;
4501 LPWSTR StringSecurityDescriptorW;
4503 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4504 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4506 if (StringSecurityDescriptorW)
4508 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4510 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4511 StringSDRevision, SecurityDescriptor,
4512 SecurityDescriptorSize);
4513 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4516 return ret;
4519 /******************************************************************************
4520 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4522 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4523 LPCWSTR StringSecurityDescriptor,
4524 DWORD StringSDRevision,
4525 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4526 PULONG SecurityDescriptorSize)
4528 DWORD cBytes;
4529 SECURITY_DESCRIPTOR* psd;
4530 BOOL bret = FALSE;
4532 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4534 if (GetVersion() & 0x80000000)
4536 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4537 goto lend;
4539 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4541 SetLastError(ERROR_INVALID_PARAMETER);
4542 goto lend;
4544 else if (StringSDRevision != SID_REVISION)
4546 SetLastError(ERROR_UNKNOWN_REVISION);
4547 goto lend;
4550 /* Compute security descriptor length */
4551 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4552 NULL, &cBytes))
4553 goto lend;
4555 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4556 if (!psd) goto lend;
4558 psd->Revision = SID_REVISION;
4559 psd->Control |= SE_SELF_RELATIVE;
4561 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4562 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4564 LocalFree(psd);
4565 goto lend;
4568 if (SecurityDescriptorSize)
4569 *SecurityDescriptorSize = cBytes;
4571 bret = TRUE;
4573 lend:
4574 TRACE(" ret=%d\n", bret);
4575 return bret;
4578 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4580 if (cch == -1)
4581 cch = strlenW(string);
4583 if (plen)
4584 *plen += cch;
4586 if (pwptr)
4588 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4589 *pwptr += cch;
4593 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4595 DWORD i;
4596 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4597 WCHAR subauthfmt[] = { '-','%','u',0 };
4598 WCHAR buf[26];
4599 SID *pisid = psid;
4601 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4603 SetLastError(ERROR_INVALID_SID);
4604 return FALSE;
4607 if (pisid->IdentifierAuthority.Value[0] ||
4608 pisid->IdentifierAuthority.Value[1])
4610 FIXME("not matching MS' bugs\n");
4611 SetLastError(ERROR_INVALID_SID);
4612 return FALSE;
4615 sprintfW( buf, fmt, pisid->Revision,
4616 MAKELONG(
4617 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4618 pisid->IdentifierAuthority.Value[4] ),
4619 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4620 pisid->IdentifierAuthority.Value[2] )
4621 ) );
4622 DumpString(buf, -1, pwptr, plen);
4624 for( i=0; i<pisid->SubAuthorityCount; i++ )
4626 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4627 DumpString(buf, -1, pwptr, plen);
4629 return TRUE;
4632 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4634 size_t i;
4635 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4637 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4639 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4640 return TRUE;
4644 return DumpSidNumeric(psid, pwptr, plen);
4647 static const LPCWSTR AceRightBitNames[32] = {
4648 SDDL_CREATE_CHILD, /* 0 */
4649 SDDL_DELETE_CHILD,
4650 SDDL_LIST_CHILDREN,
4651 SDDL_SELF_WRITE,
4652 SDDL_READ_PROPERTY, /* 4 */
4653 SDDL_WRITE_PROPERTY,
4654 SDDL_DELETE_TREE,
4655 SDDL_LIST_OBJECT,
4656 SDDL_CONTROL_ACCESS, /* 8 */
4657 NULL,
4658 NULL,
4659 NULL,
4660 NULL, /* 12 */
4661 NULL,
4662 NULL,
4663 NULL,
4664 SDDL_STANDARD_DELETE, /* 16 */
4665 SDDL_READ_CONTROL,
4666 SDDL_WRITE_DAC,
4667 SDDL_WRITE_OWNER,
4668 NULL, /* 20 */
4669 NULL,
4670 NULL,
4671 NULL,
4672 NULL, /* 24 */
4673 NULL,
4674 NULL,
4675 NULL,
4676 SDDL_GENERIC_ALL, /* 28 */
4677 SDDL_GENERIC_EXECUTE,
4678 SDDL_GENERIC_WRITE,
4679 SDDL_GENERIC_READ
4682 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4684 static const WCHAR fmtW[] = {'0','x','%','x',0};
4685 WCHAR buf[15];
4686 size_t i;
4688 if (mask == 0)
4689 return;
4691 /* first check if the right have name */
4692 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4694 if (AceRights[i].wstr == NULL)
4695 break;
4696 if (mask == AceRights[i].value)
4698 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4699 return;
4703 /* then check if it can be built from bit names */
4704 for (i = 0; i < 32; i++)
4706 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4708 /* can't be built from bit names */
4709 sprintfW(buf, fmtW, mask);
4710 DumpString(buf, -1, pwptr, plen);
4711 return;
4715 /* build from bit names */
4716 for (i = 0; i < 32; i++)
4717 if (mask & (1 << i))
4718 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4721 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4723 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4724 static const WCHAR openbr = '(';
4725 static const WCHAR closebr = ')';
4726 static const WCHAR semicolon = ';';
4728 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4730 SetLastError(ERROR_INVALID_ACL);
4731 return FALSE;
4734 piace = pace;
4735 DumpString(&openbr, 1, pwptr, plen);
4736 switch (piace->Header.AceType)
4738 case ACCESS_ALLOWED_ACE_TYPE:
4739 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4740 break;
4741 case ACCESS_DENIED_ACE_TYPE:
4742 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4743 break;
4744 case SYSTEM_AUDIT_ACE_TYPE:
4745 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4746 break;
4747 case SYSTEM_ALARM_ACE_TYPE:
4748 DumpString(SDDL_ALARM, -1, pwptr, plen);
4749 break;
4751 DumpString(&semicolon, 1, pwptr, plen);
4753 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4754 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4755 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4756 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4757 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4758 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4759 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4760 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4761 if (piace->Header.AceFlags & INHERITED_ACE)
4762 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4763 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4764 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4765 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4766 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4767 DumpString(&semicolon, 1, pwptr, plen);
4768 DumpRights(piace->Mask, pwptr, plen);
4769 DumpString(&semicolon, 1, pwptr, plen);
4770 /* objects not supported */
4771 DumpString(&semicolon, 1, pwptr, plen);
4772 /* objects not supported */
4773 DumpString(&semicolon, 1, pwptr, plen);
4774 if (!DumpSid(&piace->SidStart, pwptr, plen))
4775 return FALSE;
4776 DumpString(&closebr, 1, pwptr, plen);
4777 return TRUE;
4780 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4782 WORD count;
4783 int i;
4785 if (protected)
4786 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4787 if (autoInheritReq)
4788 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4789 if (autoInherited)
4790 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4792 if (pacl == NULL)
4793 return TRUE;
4795 if (!IsValidAcl(pacl))
4796 return FALSE;
4798 count = pacl->AceCount;
4799 for (i = 0; i < count; i++)
4801 LPVOID ace;
4802 if (!GetAce(pacl, i, &ace))
4803 return FALSE;
4804 if (!DumpAce(ace, pwptr, plen))
4805 return FALSE;
4808 return TRUE;
4811 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4813 static const WCHAR prefix[] = {'O',':',0};
4814 BOOL bDefaulted;
4815 PSID psid;
4817 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4818 return FALSE;
4820 if (psid == NULL)
4821 return TRUE;
4823 DumpString(prefix, -1, pwptr, plen);
4824 if (!DumpSid(psid, pwptr, plen))
4825 return FALSE;
4826 return TRUE;
4829 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4831 static const WCHAR prefix[] = {'G',':',0};
4832 BOOL bDefaulted;
4833 PSID psid;
4835 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4836 return FALSE;
4838 if (psid == NULL)
4839 return TRUE;
4841 DumpString(prefix, -1, pwptr, plen);
4842 if (!DumpSid(psid, pwptr, plen))
4843 return FALSE;
4844 return TRUE;
4847 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4849 static const WCHAR dacl[] = {'D',':',0};
4850 SECURITY_DESCRIPTOR_CONTROL control;
4851 BOOL present, defaulted;
4852 DWORD revision;
4853 PACL pacl;
4855 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4856 return FALSE;
4858 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4859 return FALSE;
4861 if (!present)
4862 return TRUE;
4864 DumpString(dacl, 2, pwptr, plen);
4865 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4866 return FALSE;
4867 return TRUE;
4870 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4872 static const WCHAR sacl[] = {'S',':',0};
4873 SECURITY_DESCRIPTOR_CONTROL control;
4874 BOOL present, defaulted;
4875 DWORD revision;
4876 PACL pacl;
4878 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4879 return FALSE;
4881 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4882 return FALSE;
4884 if (!present)
4885 return TRUE;
4887 DumpString(sacl, 2, pwptr, plen);
4888 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4889 return FALSE;
4890 return TRUE;
4893 /******************************************************************************
4894 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4896 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4898 ULONG len;
4899 WCHAR *wptr, *wstr;
4901 if (SDRevision != SDDL_REVISION_1)
4903 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4904 SetLastError(ERROR_UNKNOWN_REVISION);
4905 return FALSE;
4908 len = 0;
4909 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4910 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4911 return FALSE;
4912 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4913 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4914 return FALSE;
4915 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4916 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4917 return FALSE;
4918 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4919 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4920 return FALSE;
4922 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4923 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4924 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4925 return FALSE;
4926 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4927 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4928 return FALSE;
4929 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4930 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4931 return FALSE;
4932 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4933 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4934 return FALSE;
4935 *wptr = 0;
4937 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4938 *OutputString = wstr;
4939 if (OutputLen)
4940 *OutputLen = strlenW(*OutputString)+1;
4941 return TRUE;
4944 /******************************************************************************
4945 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4947 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4949 LPWSTR wstr;
4950 ULONG len;
4951 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4953 int lenA;
4955 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4956 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4957 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4958 LocalFree(wstr);
4960 if (OutputLen != NULL)
4961 *OutputLen = lenA;
4962 return TRUE;
4964 else
4966 *OutputString = NULL;
4967 if (OutputLen)
4968 *OutputLen = 0;
4969 return FALSE;
4973 /******************************************************************************
4974 * ConvertStringSidToSidW [ADVAPI32.@]
4976 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4978 BOOL bret = FALSE;
4979 DWORD cBytes;
4981 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4982 if (GetVersion() & 0x80000000)
4983 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4984 else if (!StringSid || !Sid)
4985 SetLastError(ERROR_INVALID_PARAMETER);
4986 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4988 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4990 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4991 if (!bret)
4992 LocalFree(*Sid);
4994 return bret;
4997 /******************************************************************************
4998 * ConvertStringSidToSidA [ADVAPI32.@]
5000 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5002 BOOL bret = FALSE;
5004 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5005 if (GetVersion() & 0x80000000)
5006 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5007 else if (!StringSid || !Sid)
5008 SetLastError(ERROR_INVALID_PARAMETER);
5009 else
5011 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
5012 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
5013 len * sizeof(WCHAR));
5015 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
5016 bret = ConvertStringSidToSidW(wStringSid, Sid);
5017 HeapFree(GetProcessHeap(), 0, wStringSid);
5019 return bret;
5022 /******************************************************************************
5023 * ConvertSidToStringSidW [ADVAPI32.@]
5025 * format of SID string is:
5026 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5027 * where
5028 * <rev> is the revision of the SID encoded as decimal
5029 * <auth> is the identifier authority encoded as hex
5030 * <subauthN> is the subauthority id encoded as decimal
5032 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5034 DWORD len = 0;
5035 LPWSTR wstr, wptr;
5037 TRACE("%p %p\n", pSid, pstr );
5039 len = 0;
5040 if (!DumpSidNumeric(pSid, NULL, &len))
5041 return FALSE;
5042 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5043 DumpSidNumeric(pSid, &wptr, NULL);
5044 *wptr = 0;
5046 *pstr = wstr;
5047 return TRUE;
5050 /******************************************************************************
5051 * ConvertSidToStringSidA [ADVAPI32.@]
5053 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5055 LPWSTR wstr = NULL;
5056 LPSTR str;
5057 UINT len;
5059 TRACE("%p %p\n", pSid, pstr );
5061 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5062 return FALSE;
5064 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5065 str = LocalAlloc( 0, len );
5066 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5067 LocalFree( wstr );
5069 *pstr = str;
5071 return TRUE;
5074 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5075 PSECURITY_DESCRIPTOR pdesc,
5076 PSECURITY_DESCRIPTOR cdesc,
5077 PSECURITY_DESCRIPTOR* ndesc,
5078 GUID* objtype,
5079 BOOL isdir,
5080 PGENERIC_MAPPING genmap )
5082 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5084 return FALSE;
5087 BOOL WINAPI CreatePrivateObjectSecurity(
5088 PSECURITY_DESCRIPTOR ParentDescriptor,
5089 PSECURITY_DESCRIPTOR CreatorDescriptor,
5090 PSECURITY_DESCRIPTOR* NewDescriptor,
5091 BOOL IsDirectoryObject,
5092 HANDLE Token,
5093 PGENERIC_MAPPING GenericMapping )
5095 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
5096 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5098 return FALSE;
5101 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5103 FIXME("%p - stub\n", ObjectDescriptor);
5105 return TRUE;
5108 BOOL WINAPI CreateProcessAsUserA(
5109 HANDLE hToken,
5110 LPCSTR lpApplicationName,
5111 LPSTR lpCommandLine,
5112 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5113 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5114 BOOL bInheritHandles,
5115 DWORD dwCreationFlags,
5116 LPVOID lpEnvironment,
5117 LPCSTR lpCurrentDirectory,
5118 LPSTARTUPINFOA lpStartupInfo,
5119 LPPROCESS_INFORMATION lpProcessInformation )
5121 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
5122 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5123 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5125 return FALSE;
5128 BOOL WINAPI CreateProcessAsUserW(
5129 HANDLE hToken,
5130 LPCWSTR lpApplicationName,
5131 LPWSTR lpCommandLine,
5132 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5133 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5134 BOOL bInheritHandles,
5135 DWORD dwCreationFlags,
5136 LPVOID lpEnvironment,
5137 LPCWSTR lpCurrentDirectory,
5138 LPSTARTUPINFOW lpStartupInfo,
5139 LPPROCESS_INFORMATION lpProcessInformation )
5141 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5142 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5143 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5144 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5146 /* We should create the process with a suspended main thread */
5147 if (!CreateProcessW (lpApplicationName,
5148 lpCommandLine,
5149 lpProcessAttributes,
5150 lpThreadAttributes,
5151 bInheritHandles,
5152 dwCreationFlags, /* CREATE_SUSPENDED */
5153 lpEnvironment,
5154 lpCurrentDirectory,
5155 lpStartupInfo,
5156 lpProcessInformation))
5158 return FALSE;
5161 return TRUE;
5164 /******************************************************************************
5165 * CreateProcessWithLogonW
5167 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5168 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5169 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5171 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5172 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5173 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5174 lpStartupInfo, lpProcessInformation);
5176 return FALSE;
5179 /******************************************************************************
5180 * DuplicateTokenEx [ADVAPI32.@]
5182 BOOL WINAPI DuplicateTokenEx(
5183 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5184 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5185 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5186 TOKEN_TYPE TokenType,
5187 PHANDLE DuplicateTokenHandle )
5189 OBJECT_ATTRIBUTES ObjectAttributes;
5191 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5192 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5194 InitializeObjectAttributes(
5195 &ObjectAttributes,
5196 NULL,
5197 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5198 NULL,
5199 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5201 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5202 dwDesiredAccess,
5203 &ObjectAttributes,
5204 ImpersonationLevel,
5205 TokenType,
5206 DuplicateTokenHandle ) );
5209 BOOL WINAPI DuplicateToken(
5210 HANDLE ExistingTokenHandle,
5211 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5212 PHANDLE DuplicateTokenHandle )
5214 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5215 NULL, ImpersonationLevel, TokenImpersonation,
5216 DuplicateTokenHandle );
5219 /******************************************************************************
5220 * ComputeStringSidSize
5222 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5224 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5226 int ctok = 0;
5227 while (*StringSid)
5229 if (*StringSid == '-')
5230 ctok++;
5231 StringSid++;
5234 if (ctok >= 3)
5235 return GetSidLengthRequired(ctok - 2);
5237 else /* String constant format - Only available in winxp and above */
5239 unsigned int i;
5241 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5242 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5243 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5246 return GetSidLengthRequired(0);
5249 /******************************************************************************
5250 * ParseStringSidToSid
5252 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5254 BOOL bret = FALSE;
5255 SID* pisid=pSid;
5257 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5258 if (!StringSid)
5260 SetLastError(ERROR_INVALID_PARAMETER);
5261 TRACE("StringSid is NULL, returning FALSE\n");
5262 return FALSE;
5265 while (*StringSid == ' ')
5266 StringSid++;
5268 *cBytes = ComputeStringSidSize(StringSid);
5269 if (!pisid) /* Simply compute the size */
5271 TRACE("only size requested, returning TRUE\n");
5272 return TRUE;
5275 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5277 DWORD i = 0, identAuth;
5278 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5280 StringSid += 2; /* Advance to Revision */
5281 pisid->Revision = atoiW(StringSid);
5283 if (pisid->Revision != SDDL_REVISION)
5285 TRACE("Revision %d is unknown\n", pisid->Revision);
5286 goto lend; /* ERROR_INVALID_SID */
5288 if (csubauth == 0)
5290 TRACE("SubAuthorityCount is 0\n");
5291 goto lend; /* ERROR_INVALID_SID */
5294 pisid->SubAuthorityCount = csubauth;
5296 /* Advance to identifier authority */
5297 while (*StringSid && *StringSid != '-')
5298 StringSid++;
5299 if (*StringSid == '-')
5300 StringSid++;
5302 /* MS' implementation can't handle values greater than 2^32 - 1, so
5303 * we don't either; assume most significant bytes are always 0
5305 pisid->IdentifierAuthority.Value[0] = 0;
5306 pisid->IdentifierAuthority.Value[1] = 0;
5307 identAuth = atoiW(StringSid);
5308 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5309 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5310 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5311 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5313 /* Advance to first sub authority */
5314 while (*StringSid && *StringSid != '-')
5315 StringSid++;
5316 if (*StringSid == '-')
5317 StringSid++;
5319 while (*StringSid)
5321 pisid->SubAuthority[i++] = atoiW(StringSid);
5323 while (*StringSid && *StringSid != '-')
5324 StringSid++;
5325 if (*StringSid == '-')
5326 StringSid++;
5329 if (i != pisid->SubAuthorityCount)
5330 goto lend; /* ERROR_INVALID_SID */
5332 bret = TRUE;
5334 else /* String constant format - Only available in winxp and above */
5336 unsigned int i;
5337 pisid->Revision = SDDL_REVISION;
5339 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5340 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5342 DWORD j;
5343 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5344 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5345 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5346 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5347 bret = TRUE;
5350 if (!bret)
5351 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5354 lend:
5355 if (!bret)
5356 SetLastError(ERROR_INVALID_SID);
5358 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5359 return bret;
5362 /******************************************************************************
5363 * GetNamedSecurityInfoA [ADVAPI32.@]
5365 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5366 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5367 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5368 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5370 DWORD len;
5371 LPWSTR wstr = NULL;
5372 DWORD r;
5374 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5375 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5377 if( pObjectName )
5379 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5380 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5381 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5384 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5385 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5387 HeapFree( GetProcessHeap(), 0, wstr );
5389 return r;
5392 /******************************************************************************
5393 * GetNamedSecurityInfoW [ADVAPI32.@]
5395 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5396 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5397 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5399 DWORD needed, offset;
5400 SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
5401 BYTE *buffer;
5403 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5404 group, dacl, sacl, descriptor );
5406 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5407 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5409 /* If no descriptor, we have to check that there's a pointer for the requested information */
5410 if( !descriptor && (
5411 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5412 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5413 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5414 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5415 return ERROR_INVALID_PARAMETER;
5417 needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5418 if (info & OWNER_SECURITY_INFORMATION)
5419 needed += sizeof(sidWorld);
5420 if (info & GROUP_SECURITY_INFORMATION)
5421 needed += sizeof(sidWorld);
5422 if (info & DACL_SECURITY_INFORMATION)
5423 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5424 if (info & SACL_SECURITY_INFORMATION)
5425 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5427 if(descriptor)
5429 /* must be freed by caller */
5430 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5431 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5433 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5435 HeapFree( GetProcessHeap(), 0, *descriptor );
5436 return ERROR_INVALID_SECURITY_DESCR;
5439 relative = *descriptor;
5440 relative->Control |= SE_SELF_RELATIVE;
5442 buffer = (BYTE *)relative;
5443 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5445 else
5447 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
5448 if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
5449 offset = 0;
5452 if (info & OWNER_SECURITY_INFORMATION)
5454 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5455 if(relative)
5456 relative->Owner = offset;
5457 if (owner)
5458 *owner = buffer + offset;
5459 offset += sizeof(sidWorld);
5461 if (info & GROUP_SECURITY_INFORMATION)
5463 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5464 if(relative)
5465 relative->Group = offset;
5466 if (group)
5467 *group = buffer + offset;
5468 offset += sizeof(sidWorld);
5470 if (info & DACL_SECURITY_INFORMATION)
5472 GetWorldAccessACL( (PACL)(buffer + offset) );
5473 if(relative)
5475 relative->Control |= SE_DACL_PRESENT;
5476 relative->Dacl = offset;
5478 if (dacl)
5479 *dacl = (PACL)(buffer + offset);
5480 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5482 if (info & SACL_SECURITY_INFORMATION)
5484 GetWorldAccessACL( (PACL)(buffer + offset) );
5485 if(relative)
5487 relative->Control |= SE_SACL_PRESENT;
5488 relative->Sacl = offset;
5490 if (sacl)
5491 *sacl = (PACL)(buffer + offset);
5494 return ERROR_SUCCESS;
5497 /******************************************************************************
5498 * GetNamedSecurityInfoExW [ADVAPI32.@]
5500 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5501 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5502 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5504 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5505 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5506 return ERROR_CALL_NOT_IMPLEMENTED;
5509 /******************************************************************************
5510 * GetNamedSecurityInfoExA [ADVAPI32.@]
5512 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5513 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5514 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5516 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5517 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5518 return ERROR_CALL_NOT_IMPLEMENTED;
5521 /******************************************************************************
5522 * DecryptFileW [ADVAPI32.@]
5524 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5526 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5527 return TRUE;
5530 /******************************************************************************
5531 * DecryptFileA [ADVAPI32.@]
5533 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5535 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5536 return TRUE;
5539 /******************************************************************************
5540 * EncryptFileW [ADVAPI32.@]
5542 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5544 FIXME("%s\n", debugstr_w(lpFileName));
5545 return TRUE;
5548 /******************************************************************************
5549 * EncryptFileA [ADVAPI32.@]
5551 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5553 FIXME("%s\n", debugstr_a(lpFileName));
5554 return TRUE;
5557 /******************************************************************************
5558 * FileEncryptionStatusW [ADVAPI32.@]
5560 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5562 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5563 if (!lpStatus)
5564 return FALSE;
5565 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5566 return TRUE;
5569 /******************************************************************************
5570 * FileEncryptionStatusA [ADVAPI32.@]
5572 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5574 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5575 if (!lpStatus)
5576 return FALSE;
5577 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5578 return TRUE;
5581 /******************************************************************************
5582 * SetSecurityInfo [ADVAPI32.@]
5584 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5585 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5586 PSID psidGroup, PACL pDacl, PACL pSacl) {
5587 FIXME("stub\n");
5588 return ERROR_SUCCESS;
5591 /******************************************************************************
5592 * SaferCreateLevel [ADVAPI32.@]
5594 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5595 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5597 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5599 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5600 return TRUE;
5603 /******************************************************************************
5604 * SaferComputeTokenFromLevel [ADVAPI32.@]
5606 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5607 DWORD flags, LPVOID reserved)
5609 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5611 *access_token = (HANDLE)0xdeadbeef;
5612 return TRUE;
5615 /******************************************************************************
5616 * SaferCloseLevel [ADVAPI32.@]
5618 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5620 FIXME("(%p) stub\n", handle);
5621 return TRUE;
5624 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5625 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5626 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5627 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5628 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5630 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5631 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5632 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5634 return ERROR_SUCCESS;
5637 /******************************************************************************
5638 * SaferGetPolicyInformation [ADVAPI32.@]
5640 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5641 PVOID buffer, PDWORD required, LPVOID lpReserved)
5643 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5644 return FALSE;
5647 /******************************************************************************
5648 * SaferSetLevelInformation [ADVAPI32.@]
5650 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5651 LPVOID buffer, DWORD size)
5653 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5654 return FALSE;