1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "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"
43
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48
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);
60
61 typedef struct _ACEFLAG
62 {
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
66
67 typedef struct _MAX_SID
68 {
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;
75
76 typedef struct WELLKNOWNSID
77 {
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
82
83 static const WELLKNOWNSID WellKnownSids[] =
84 {
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 } } },
137 };
138
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
141 {
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
145
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 },
160 };
161
162
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
164
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;
172
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','','','',' ','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 };
235
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 },
281 };
282 /*
283 * ACE access rights
284 */
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};
289
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};
299
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};
304
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};
309
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};
314
315 /*
316 * ACL flags
317 */
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};
321
322 /*
323 * ACE types
324 */
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};
333
334 /*
335 * ACE flags
336 */
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};
344
345 const char * debugstr_sid(PSID sid)
346 {
347 int auth = 0;
348 SID * psid = sid;
349
350 if (psid == NULL)
351 return "(null)";
352
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
357
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]);
392 }
393 return "(too-big)";
394 }
395
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 )
399 {
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
402 }
403
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405
406 static void GetWorldAccessACL(PACL pACL)
407 {
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409
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;
415
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));
421 }
422
423 /************************************************************
424 * ADVAPI_IsLocalComputer
425 *
426 * Checks whether the server name indicates local machine.
427 */
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 {
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
433
434 if (!ServerName || !ServerName[0])
435 return TRUE;
436
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);
443
444 return Result;
445 }
446
447 /************************************************************
448 * ADVAPI_GetComputerSid
449 *
450 * Reads the computer SID from the registry.
451 */
452 BOOL ADVAPI_GetComputerSid(PSID sid)
453 {
454 HKEY key;
455 LONG ret;
456 BOOL retval = FALSE;
457 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
458 static const WCHAR V[] = { 'V',0 };
459
460 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461 KEY_READ, &key)) == ERROR_SUCCESS)
462 {
463 DWORD size = 0;
464 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466 {
467 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468 if (data)
469 {
470 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471 data, &size)) == ERROR_SUCCESS)
472 {
473 /* the SID is in the last 24 bytes of the binary data */
474 CopyMemory(sid, &data[size-24], 24);
475 retval = TRUE;
476 }
477 HeapFree(GetProcessHeap(), 0, data);
478 }
479 }
480 RegCloseKey(key);
481 }
482
483 if(retval == TRUE) return retval;
484
485 /* create a new random SID */
486 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488 {
489 PSID new_sid;
490 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491 DWORD id[3];
492
493 if (RtlGenRandom(id, sizeof(id)))
494 {
495 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496 {
497 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499
500 FreeSid(new_sid);
501 }
502 }
503 RegCloseKey(key);
504 }
505
506 return retval;
507 }
508
509 /* ##############################
510 ###### TOKEN FUNCTIONS ######
511 ##############################
512 */
513
514 /******************************************************************************
515 * OpenProcessToken [ADVAPI32.@]
516 * Opens the access token associated with a process handle.
517 *
518 * PARAMS
519 * ProcessHandle [I] Handle to process
520 * DesiredAccess [I] Desired access to process
521 * TokenHandle [O] Pointer to handle of open access token
522 *
523 * RETURNS
524 * Success: TRUE. TokenHandle contains the access token.
525 * Failure: FALSE.
526 *
527 * NOTES
528 * See NtOpenProcessToken.
529 */
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532 HANDLE *TokenHandle )
533 {
534 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
535 }
536
537 /******************************************************************************
538 * OpenThreadToken [ADVAPI32.@]
539 *
540 * Opens the access token associated with a thread handle.
541 *
542 * PARAMS
543 * ThreadHandle [I] Handle to process
544 * DesiredAccess [I] Desired access to the thread
545 * OpenAsSelf [I] ???
546 * TokenHandle [O] Destination for the token handle
547 *
548 * RETURNS
549 * Success: TRUE. TokenHandle contains the access token.
550 * Failure: FALSE.
551 *
552 * NOTES
553 * See NtOpenThreadToken.
554 */
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557 BOOL OpenAsSelf, HANDLE *TokenHandle)
558 {
559 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
560 }
561
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 {
566 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567 PreviousState, ReturnLength));
568 }
569
570 /******************************************************************************
571 * AdjustTokenPrivileges [ADVAPI32.@]
572 *
573 * Adjust the privileges of an open token handle.
574 *
575 * PARAMS
576 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
577 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
578 * NewState [I] Desired new privileges of the token
579 * BufferLength [I] Length of NewState
580 * PreviousState [O] Destination for the previous state
581 * ReturnLength [I/O] Size of PreviousState
582 *
583 *
584 * RETURNS
585 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586 * Failure: FALSE.
587 *
588 * NOTES
589 * See NtAdjustPrivilegesToken.
590 */
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 {
596 NTSTATUS status;
597
598 TRACE("\n");
599
600 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601 NewState, BufferLength, PreviousState,
602 ReturnLength);
603 SetLastError( RtlNtStatusToDosError( status ));
604 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605 return TRUE;
606 else
607 return FALSE;
608 }
609
610 /******************************************************************************
611 * CheckTokenMembership [ADVAPI32.@]
612 *
613 * Determine if an access token is a member of a SID.
614 *
615 * PARAMS
616 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617 * SidToCheck [I] SID that possibly contains the token
618 * IsMember [O] Destination for result.
619 *
620 * RETURNS
621 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622 * Failure: FALSE.
623 */
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE token, PSID sid_to_check,
626 PBOOL is_member )
627 {
628 PTOKEN_GROUPS token_groups = NULL;
629 HANDLE thread_token = NULL;
630 DWORD size, i;
631 BOOL ret;
632
633 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
634
635 *is_member = FALSE;
636
637 if (!token)
638 {
639 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
640 {
641 HANDLE process_token;
642 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
643 if (!ret)
644 goto exit;
645 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
646 NULL, SecurityImpersonation, TokenImpersonation,
647 &thread_token);
648 CloseHandle(process_token);
649 if (!ret)
650 goto exit;
651 }
652 token = thread_token;
653 }
654
655 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
656 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
657 goto exit;
658
659 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
660 if (!token_groups)
661 {
662 ret = FALSE;
663 goto exit;
664 }
665
666 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
667 if (!ret)
668 goto exit;
669
670 for (i = 0; i < token_groups->GroupCount; i++)
671 {
672 TRACE("Groups[%d]: {0x%x, %s}\n", i,
673 token_groups->Groups[i].Attributes,
674 debugstr_sid(token_groups->Groups[i].Sid));
675 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
676 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
677 {
678 *is_member = TRUE;
679 TRACE("sid enabled and found in token\n");
680 break;
681 }
682 }
683
684 exit:
685 HeapFree(GetProcessHeap(), 0, token_groups);
686 if (thread_token != NULL) CloseHandle(thread_token);
687
688 return ret;
689 }
690
691 /******************************************************************************
692 * GetTokenInformation [ADVAPI32.@]
693 *
694 * Get a type of information about an access token.
695 *
696 * PARAMS
697 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
698 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
699 * tokeninfo [O] Destination for token information
700 * tokeninfolength [I] Length of tokeninfo
701 * retlen [O] Destination for returned token information length
702 *
703 * RETURNS
704 * Success: TRUE. tokeninfo contains retlen bytes of token information
705 * Failure: FALSE.
706 *
707 * NOTES
708 * See NtQueryInformationToken.
709 */
710 BOOL WINAPI
711 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
712 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
713 {
714 TRACE("(%p, %s, %p, %d, %p):\n",
715 token,
716 (tokeninfoclass == TokenUser) ? "TokenUser" :
717 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
718 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
719 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
720 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
721 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
722 (tokeninfoclass == TokenSource) ? "TokenSource" :
723 (tokeninfoclass == TokenType) ? "TokenType" :
724 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
725 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
726 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
727 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
728 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
729 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
730 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
731 "Unknown",
732 tokeninfo, tokeninfolength, retlen);
733 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
734 tokeninfolength, retlen));
735 }
736
737 /******************************************************************************
738 * SetTokenInformation [ADVAPI32.@]
739 *
740 * Set information for an access token.
741 *
742 * PARAMS
743 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
744 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
745 * tokeninfo [I] Token information to set
746 * tokeninfolength [I] Length of tokeninfo
747 *
748 * RETURNS
749 * Success: TRUE. The information for the token is set to tokeninfo.
750 * Failure: FALSE.
751 */
752 BOOL WINAPI
753 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
754 LPVOID tokeninfo, DWORD tokeninfolength )
755 {
756 TRACE("(%p, %s, %p, %d): stub\n",
757 token,
758 (tokeninfoclass == TokenUser) ? "TokenUser" :
759 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
760 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
761 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
762 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
763 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
764 (tokeninfoclass == TokenSource) ? "TokenSource" :
765 (tokeninfoclass == TokenType) ? "TokenType" :
766 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
767 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
768 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
769 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
770 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
771 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
772 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
773 "Unknown",
774 tokeninfo, tokeninfolength);
775
776 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
777 }
778
779 /*************************************************************************
780 * SetThreadToken [ADVAPI32.@]
781 *
782 * Assigns an 'impersonation token' to a thread so it can assume the
783 * security privileges of another thread or process. Can also remove
784 * a previously assigned token.
785 *
786 * PARAMS
787 * thread [O] Handle to thread to set the token for
788 * token [I] Token to set
789 *
790 * RETURNS
791 * Success: TRUE. The threads access token is set to token
792 * Failure: FALSE.
793 *
794 * NOTES
795 * Only supported on NT or higher. On Win9X this function does nothing.
796 * See SetTokenInformation.
797 */
798 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
799 {
800 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
801 ThreadImpersonationToken, &token, sizeof token ));
802 }
803
804 /*************************************************************************
805 * CreateRestrictedToken [ADVAPI32.@]
806 *
807 * Create a new more restricted token from an existing token.
808 *
809 * PARAMS
810 * baseToken [I] Token to base the new restricted token on
811 * flags [I] Options
812 * nDisableSids [I] Length of disableSids array
813 * disableSids [I] Array of SIDs to disable in the new token
814 * nDeletePrivs [I] Length of deletePrivs array
815 * deletePrivs [I] Array of privileges to delete in the new token
816 * nRestrictSids [I] Length of restrictSids array
817 * restrictSids [I] Array of SIDs to restrict in the new token
818 * newToken [O] Address where the new token is stored
819 *
820 * RETURNS
821 * Success: TRUE
822 * Failure: FALSE
823 */
824 BOOL WINAPI CreateRestrictedToken(
825 HANDLE baseToken,
826 DWORD flags,
827 DWORD nDisableSids,
828 PSID_AND_ATTRIBUTES disableSids,
829 DWORD nDeletePrivs,
830 PLUID_AND_ATTRIBUTES deletePrivs,
831 DWORD nRestrictSids,
832 PSID_AND_ATTRIBUTES restrictSids,
833 PHANDLE newToken)
834 {
835 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
836 baseToken, flags, nDisableSids, disableSids,
837 nDeletePrivs, deletePrivs,
838 nRestrictSids, restrictSids,
839 newToken);
840 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
841 return FALSE;
842 }
843
844 /* ##############################
845 ###### SID FUNCTIONS ######
846 ##############################
847 */
848
849 /******************************************************************************
850 * AllocateAndInitializeSid [ADVAPI32.@]
851 *
852 * PARAMS
853 * pIdentifierAuthority []
854 * nSubAuthorityCount []
855 * nSubAuthority0 []
856 * nSubAuthority1 []
857 * nSubAuthority2 []
858 * nSubAuthority3 []
859 * nSubAuthority4 []
860 * nSubAuthority5 []
861 * nSubAuthority6 []
862 * nSubAuthority7 []
863 * pSid []
864 */
865 BOOL WINAPI
866 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
867 BYTE nSubAuthorityCount,
868 DWORD nSubAuthority0, DWORD nSubAuthority1,
869 DWORD nSubAuthority2, DWORD nSubAuthority3,
870 DWORD nSubAuthority4, DWORD nSubAuthority5,
871 DWORD nSubAuthority6, DWORD nSubAuthority7,
872 PSID *pSid )
873 {
874 return set_ntstatus( RtlAllocateAndInitializeSid(
875 pIdentifierAuthority, nSubAuthorityCount,
876 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
877 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
878 pSid ));
879 }
880
881 /******************************************************************************
882 * FreeSid [ADVAPI32.@]
883 *
884 * PARAMS
885 * pSid []
886 */
887 PVOID WINAPI
888 FreeSid( PSID pSid )
889 {
890 RtlFreeSid(pSid);
891 return NULL; /* is documented like this */
892 }
893
894 /******************************************************************************
895 * CopySid [ADVAPI32.@]
896 *
897 * PARAMS
898 * nDestinationSidLength []
899 * pDestinationSid []
900 * pSourceSid []
901 */
902 BOOL WINAPI
903 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
904 {
905 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
906 }
907
908 /******************************************************************************
909 * CreateWellKnownSid [ADVAPI32.@]
910 */
911 BOOL WINAPI
912 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
913 PSID DomainSid,
914 PSID pSid,
915 DWORD* cbSid)
916 {
917 unsigned int i;
918 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
919
920 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
921 {
922 SetLastError(ERROR_INVALID_PARAMETER);
923 return FALSE;
924 }
925
926 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
927 if (WellKnownSids[i].Type == WellKnownSidType) {
928 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
929
930 if (*cbSid < length)
931 {
932 *cbSid = length;
933 SetLastError(ERROR_INSUFFICIENT_BUFFER);
934 return FALSE;
935 }
936 if (!pSid)
937 {
938 SetLastError(ERROR_INVALID_PARAMETER);
939 return FALSE;
940 }
941 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
942 *cbSid = length;
943 return TRUE;
944 }
945 }
946
947 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
948 {
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return FALSE;
951 }
952
953 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
954 if (WellKnownRids[i].Type == WellKnownSidType) {
955 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
956 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
957 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
958
959 if (*cbSid < output_sid_length)
960 {
961 *cbSid = output_sid_length;
962 SetLastError(ERROR_INSUFFICIENT_BUFFER);
963 return FALSE;
964 }
965 if (!pSid)
966 {
967 SetLastError(ERROR_INVALID_PARAMETER);
968 return FALSE;
969 }
970 CopyMemory(pSid, DomainSid, domain_sid_length);
971 (*GetSidSubAuthorityCount(pSid))++;
972 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
973 *cbSid = output_sid_length;
974 return TRUE;
975 }
976
977 SetLastError(ERROR_INVALID_PARAMETER);
978 return FALSE;
979 }
980
981 /******************************************************************************
982 * IsWellKnownSid [ADVAPI32.@]
983 */
984 BOOL WINAPI
985 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
986 {
987 unsigned int i;
988 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
989
990 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
991 if (WellKnownSids[i].Type == WellKnownSidType)
992 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
993 return TRUE;
994
995 return FALSE;
996 }
997
998 BOOL WINAPI
999 IsTokenRestricted( HANDLE TokenHandle )
1000 {
1001 TOKEN_GROUPS *groups;
1002 DWORD size;
1003 NTSTATUS status;
1004 BOOL restricted;
1005
1006 TRACE("(%p)\n", TokenHandle);
1007
1008 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1009 if (status != STATUS_BUFFER_TOO_SMALL)
1010 return FALSE;
1011
1012 groups = HeapAlloc(GetProcessHeap(), 0, size);
1013 if (!groups)
1014 {
1015 SetLastError(ERROR_OUTOFMEMORY);
1016 return FALSE;
1017 }
1018
1019 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1020 if (status != STATUS_SUCCESS)
1021 {
1022 HeapFree(GetProcessHeap(), 0, groups);
1023 return set_ntstatus(status);
1024 }
1025
1026 if (groups->GroupCount)
1027 restricted = TRUE;
1028 else
1029 restricted = FALSE;
1030
1031 HeapFree(GetProcessHeap(), 0, groups);
1032
1033 return restricted;
1034 }
1035
1036 /******************************************************************************
1037 * IsValidSid [ADVAPI32.@]
1038 *
1039 * PARAMS
1040 * pSid []
1041 */
1042 BOOL WINAPI
1043 IsValidSid( PSID pSid )
1044 {
1045 return RtlValidSid( pSid );
1046 }
1047
1048 /******************************************************************************
1049 * EqualSid [ADVAPI32.@]
1050 *
1051 * PARAMS
1052 * pSid1 []
1053 * pSid2 []
1054 */
1055 BOOL WINAPI
1056 EqualSid( PSID pSid1, PSID pSid2 )
1057 {
1058 return RtlEqualSid( pSid1, pSid2 );
1059 }
1060
1061 /******************************************************************************
1062 * EqualPrefixSid [ADVAPI32.@]
1063 */
1064 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1065 {
1066 return RtlEqualPrefixSid(pSid1, pSid2);
1067 }
1068
1069 /******************************************************************************
1070 * GetSidLengthRequired [ADVAPI32.@]
1071 *
1072 * PARAMS
1073 * nSubAuthorityCount []
1074 */
1075 DWORD WINAPI
1076 GetSidLengthRequired( BYTE nSubAuthorityCount )
1077 {
1078 return RtlLengthRequiredSid(nSubAuthorityCount);
1079 }
1080
1081 /******************************************************************************
1082 * InitializeSid [ADVAPI32.@]
1083 *
1084 * PARAMS
1085 * pIdentifierAuthority []
1086 */
1087 BOOL WINAPI
1088 InitializeSid (
1089 PSID pSid,
1090 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1091 BYTE nSubAuthorityCount)
1092 {
1093 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1094 }
1095
1096 DWORD WINAPI
1097 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1098 {
1099 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1100
1101 return 1;
1102 }
1103
1104 DWORD WINAPI
1105 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1106 {
1107 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1108
1109 return 1;
1110 }
1111
1112 /******************************************************************************
1113 * GetSidIdentifierAuthority [ADVAPI32.@]
1114 *
1115 * PARAMS
1116 * pSid []
1117 */
1118 PSID_IDENTIFIER_AUTHORITY WINAPI
1119 GetSidIdentifierAuthority( PSID pSid )
1120 {
1121 return RtlIdentifierAuthoritySid(pSid);
1122 }
1123
1124 /******************************************************************************
1125 * GetSidSubAuthority [ADVAPI32.@]
1126 *
1127 * PARAMS
1128 * pSid []
1129 * nSubAuthority []
1130 */
1131 PDWORD WINAPI
1132 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1133 {
1134 SetLastError(ERROR_SUCCESS);
1135 return RtlSubAuthoritySid(pSid, nSubAuthority);
1136 }
1137
1138 /******************************************************************************
1139 * GetSidSubAuthorityCount [ADVAPI32.@]
1140 *
1141 * PARAMS
1142 * pSid []
1143 */
1144 PUCHAR WINAPI
1145 GetSidSubAuthorityCount (PSID pSid)
1146 {
1147 SetLastError(ERROR_SUCCESS);
1148 return RtlSubAuthorityCountSid(pSid);
1149 }
1150
1151 /******************************************************************************
1152 * GetLengthSid [ADVAPI32.@]
1153 *
1154 * PARAMS
1155 * pSid []
1156 */
1157 DWORD WINAPI
1158 GetLengthSid (PSID pSid)
1159 {
1160 return RtlLengthSid(pSid);
1161 }
1162
1163 /* ##############################################
1164 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1165 ##############################################
1166 */
1167
1168 /******************************************************************************
1169 * BuildSecurityDescriptorA [ADVAPI32.@]
1170 *
1171 * Builds a SD from
1172 *
1173 * PARAMS
1174 * pOwner [I]
1175 * pGroup [I]
1176 * cCountOfAccessEntries [I]
1177 * pListOfAccessEntries [I]
1178 * cCountOfAuditEntries [I]
1179 * pListofAuditEntries [I]
1180 * pOldSD [I]
1181 * lpdwBufferLength [I/O]
1182 * pNewSD [O]
1183 *
1184 * RETURNS
1185 * Success: ERROR_SUCCESS
1186 * Failure: nonzero error code from Winerror.h
1187 */
1188 DWORD WINAPI BuildSecurityDescriptorA(
1189 IN PTRUSTEEA pOwner,
1190 IN PTRUSTEEA pGroup,
1191 IN ULONG cCountOfAccessEntries,
1192 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1193 IN ULONG cCountOfAuditEntries,
1194 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1195 IN PSECURITY_DESCRIPTOR pOldSD,
1196 IN OUT PULONG lpdwBufferLength,
1197 OUT PSECURITY_DESCRIPTOR* pNewSD)
1198 {
1199 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1200 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1201 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1202
1203 return ERROR_CALL_NOT_IMPLEMENTED;
1204 }
1205
1206 /******************************************************************************
1207 * BuildSecurityDescriptorW [ADVAPI32.@]
1208 *
1209 * See BuildSecurityDescriptorA.
1210 */
1211 DWORD WINAPI BuildSecurityDescriptorW(
1212 IN PTRUSTEEW pOwner,
1213 IN PTRUSTEEW pGroup,
1214 IN ULONG cCountOfAccessEntries,
1215 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1216 IN ULONG cCountOfAuditEntries,
1217 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1218 IN PSECURITY_DESCRIPTOR pOldSD,
1219 IN OUT PULONG lpdwBufferLength,
1220 OUT PSECURITY_DESCRIPTOR* pNewSD)
1221 {
1222 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1223 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1224 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1225
1226 return ERROR_CALL_NOT_IMPLEMENTED;
1227 }
1228
1229 /******************************************************************************
1230 * InitializeSecurityDescriptor [ADVAPI32.@]
1231 *
1232 * PARAMS
1233 * pDescr []
1234 * revision []
1235 */
1236 BOOL WINAPI
1237 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1238 {
1239 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1240 }
1241
1242
1243 /******************************************************************************
1244 * MakeAbsoluteSD [ADVAPI32.@]
1245 */
1246 BOOL WINAPI MakeAbsoluteSD (
1247 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1248 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1249 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1250 OUT PACL pDacl,
1251 OUT LPDWORD lpdwDaclSize,
1252 OUT PACL pSacl,
1253 OUT LPDWORD lpdwSaclSize,
1254 OUT PSID pOwner,
1255 OUT LPDWORD lpdwOwnerSize,
1256 OUT PSID pPrimaryGroup,
1257 OUT LPDWORD lpdwPrimaryGroupSize)
1258 {
1259 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1260 pAbsoluteSecurityDescriptor,
1261 lpdwAbsoluteSecurityDescriptorSize,
1262 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1263 pOwner, lpdwOwnerSize,
1264 pPrimaryGroup, lpdwPrimaryGroupSize));
1265 }
1266
1267 /******************************************************************************
1268 * GetKernelObjectSecurity [ADVAPI32.@]
1269 */
1270 BOOL WINAPI GetKernelObjectSecurity(
1271 HANDLE Handle,
1272 SECURITY_INFORMATION RequestedInformation,
1273 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1274 DWORD nLength,
1275 LPDWORD lpnLengthNeeded )
1276 {
1277 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1278 pSecurityDescriptor, nLength, lpnLengthNeeded);
1279
1280 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1281 nLength, lpnLengthNeeded ));
1282 }
1283
1284 /******************************************************************************
1285 * GetPrivateObjectSecurity [ADVAPI32.@]
1286 */
1287 BOOL WINAPI GetPrivateObjectSecurity(
1288 PSECURITY_DESCRIPTOR ObjectDescriptor,
1289 SECURITY_INFORMATION SecurityInformation,
1290 PSECURITY_DESCRIPTOR ResultantDescriptor,
1291 DWORD DescriptorLength,
1292 PDWORD ReturnLength )
1293 {
1294 SECURITY_DESCRIPTOR desc;
1295 BOOL defaulted, present;
1296 PACL pacl;
1297 PSID psid;
1298
1299 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1300 ResultantDescriptor, DescriptorLength, ReturnLength);
1301
1302 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1303 return FALSE;
1304
1305 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1306 {
1307 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1308 return FALSE;
1309 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1310 }
1311
1312 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1313 {
1314 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1315 return FALSE;
1316 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1317 }
1318
1319 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1320 {
1321 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1322 return FALSE;
1323 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1324 }
1325
1326 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1327 {
1328 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1329 return FALSE;
1330 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1331 }
1332
1333 *ReturnLength = DescriptorLength;
1334 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1335 }
1336
1337 /******************************************************************************
1338 * GetSecurityDescriptorLength [ADVAPI32.@]
1339 */
1340 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1341 {
1342 return RtlLengthSecurityDescriptor(pDescr);
1343 }
1344
1345 /******************************************************************************
1346 * GetSecurityDescriptorOwner [ADVAPI32.@]
1347 *
1348 * PARAMS
1349 * pOwner []
1350 * lpbOwnerDefaulted []
1351 */
1352 BOOL WINAPI
1353 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1354 LPBOOL lpbOwnerDefaulted )
1355 {
1356 BOOLEAN defaulted;
1357 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1358 *lpbOwnerDefaulted = defaulted;
1359 return ret;
1360 }
1361
1362 /******************************************************************************
1363 * SetSecurityDescriptorOwner [ADVAPI32.@]
1364 *
1365 * PARAMS
1366 */
1367 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1368 PSID pOwner, BOOL bOwnerDefaulted)
1369 {
1370 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1371 }
1372 /******************************************************************************
1373 * GetSecurityDescriptorGroup [ADVAPI32.@]
1374 */
1375 BOOL WINAPI GetSecurityDescriptorGroup(
1376 PSECURITY_DESCRIPTOR SecurityDescriptor,
1377 PSID *Group,
1378 LPBOOL GroupDefaulted)
1379 {
1380 BOOLEAN defaulted;
1381 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1382 *GroupDefaulted = defaulted;
1383 return ret;
1384 }
1385 /******************************************************************************
1386 * SetSecurityDescriptorGroup [ADVAPI32.@]
1387 */
1388 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1389 PSID Group, BOOL GroupDefaulted)
1390 {
1391 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1392 }
1393
1394 /******************************************************************************
1395 * IsValidSecurityDescriptor [ADVAPI32.@]
1396 *
1397 * PARAMS
1398 * lpsecdesc []
1399 */
1400 BOOL WINAPI
1401 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1402 {
1403 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1404 }
1405
1406 /******************************************************************************
1407 * GetSecurityDescriptorDacl [ADVAPI32.@]
1408 */
1409 BOOL WINAPI GetSecurityDescriptorDacl(
1410 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 OUT LPBOOL lpbDaclPresent,
1412 OUT PACL *pDacl,
1413 OUT LPBOOL lpbDaclDefaulted)
1414 {
1415 BOOLEAN present, defaulted;
1416 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1417 *lpbDaclPresent = present;
1418 *lpbDaclDefaulted = defaulted;
1419 return ret;
1420 }
1421
1422 /******************************************************************************
1423 * SetSecurityDescriptorDacl [ADVAPI32.@]
1424 */
1425 BOOL WINAPI
1426 SetSecurityDescriptorDacl (
1427 PSECURITY_DESCRIPTOR lpsd,
1428 BOOL daclpresent,
1429 PACL dacl,
1430 BOOL dacldefaulted )
1431 {
1432 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1433 }
1434 /******************************************************************************
1435 * GetSecurityDescriptorSacl [ADVAPI32.@]
1436 */
1437 BOOL WINAPI GetSecurityDescriptorSacl(
1438 IN PSECURITY_DESCRIPTOR lpsd,
1439 OUT LPBOOL lpbSaclPresent,
1440 OUT PACL *pSacl,
1441 OUT LPBOOL lpbSaclDefaulted)
1442 {
1443 BOOLEAN present, defaulted;
1444 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1445 *lpbSaclPresent = present;
1446 *lpbSaclDefaulted = defaulted;
1447 return ret;
1448 }
1449
1450 /**************************************************************************
1451 * SetSecurityDescriptorSacl [ADVAPI32.@]
1452 */
1453 BOOL WINAPI SetSecurityDescriptorSacl (
1454 PSECURITY_DESCRIPTOR lpsd,
1455 BOOL saclpresent,
1456 PACL lpsacl,
1457 BOOL sacldefaulted)
1458 {
1459 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1460 }
1461 /******************************************************************************
1462 * MakeSelfRelativeSD [ADVAPI32.@]
1463 *
1464 * PARAMS
1465 * lpabssecdesc []
1466 * lpselfsecdesc []
1467 * lpbuflen []
1468 */
1469 BOOL WINAPI
1470 MakeSelfRelativeSD(
1471 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1472 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1473 IN OUT LPDWORD lpdwBufferLength)
1474 {
1475 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1476 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1477 }
1478
1479 /******************************************************************************
1480 * GetSecurityDescriptorControl [ADVAPI32.@]
1481 */
1482
1483 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1484 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1485 {
1486 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1487 }
1488
1489 /******************************************************************************
1490 * SetSecurityDescriptorControl [ADVAPI32.@]
1491 */
1492 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1493 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1494 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1495 {
1496 return set_ntstatus( RtlSetControlSecurityDescriptor(
1497 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1498 }
1499
1500 /* ##############################
1501 ###### ACL FUNCTIONS ######
1502 ##############################
1503 */
1504
1505 /*************************************************************************
1506 * InitializeAcl [ADVAPI32.@]
1507 */
1508 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1509 {
1510 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1511 }
1512
1513 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1514 {
1515 IO_STATUS_BLOCK io_block;
1516
1517 TRACE("(%p)\n", hNamedPipe);
1518
1519 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1520 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1521 }
1522
1523 /******************************************************************************
1524 * AddAccessAllowedAce [ADVAPI32.@]
1525 */
1526 BOOL WINAPI AddAccessAllowedAce(
1527 IN OUT PACL pAcl,
1528 IN DWORD dwAceRevision,
1529 IN DWORD AccessMask,
1530 IN PSID pSid)
1531 {
1532 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1533 }
1534
1535 /******************************************************************************
1536 * AddAccessAllowedAceEx [ADVAPI32.@]
1537 */
1538 BOOL WINAPI AddAccessAllowedAceEx(
1539 IN OUT PACL pAcl,
1540 IN DWORD dwAceRevision,
1541 IN DWORD AceFlags,
1542 IN DWORD AccessMask,
1543 IN PSID pSid)
1544 {
1545 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1546 }
1547
1548 /******************************************************************************
1549 * AddAccessDeniedAce [ADVAPI32.@]
1550 */
1551 BOOL WINAPI AddAccessDeniedAce(
1552 IN OUT PACL pAcl,
1553 IN DWORD dwAceRevision,
1554 IN DWORD AccessMask,
1555 IN PSID pSid)
1556 {
1557 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1558 }
1559
1560 /******************************************************************************
1561 * AddAccessDeniedAceEx [ADVAPI32.@]
1562 */
1563 BOOL WINAPI AddAccessDeniedAceEx(
1564 IN OUT PACL pAcl,
1565 IN DWORD dwAceRevision,
1566 IN DWORD AceFlags,
1567 IN DWORD AccessMask,
1568 IN PSID pSid)
1569 {
1570 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1571 }
1572
1573 /******************************************************************************
1574 * AddAce [ADVAPI32.@]
1575 */
1576 BOOL WINAPI AddAce(
1577 IN OUT PACL pAcl,
1578 IN DWORD dwAceRevision,
1579 IN DWORD dwStartingAceIndex,
1580 LPVOID pAceList,
1581 DWORD nAceListLength)
1582 {
1583 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1584 }
1585
1586 /******************************************************************************
1587 * DeleteAce [ADVAPI32.@]
1588 */
1589 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1590 {
1591 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1592 }
1593
1594 /******************************************************************************
1595 * FindFirstFreeAce [ADVAPI32.@]
1596 */
1597 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1598 {
1599 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1600 }
1601
1602 /******************************************************************************
1603 * GetAce [ADVAPI32.@]
1604 */
1605 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1606 {
1607 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1608 }
1609
1610 /******************************************************************************
1611 * GetAclInformation [ADVAPI32.@]
1612 */
1613 BOOL WINAPI GetAclInformation(
1614 PACL pAcl,
1615 LPVOID pAclInformation,
1616 DWORD nAclInformationLength,
1617 ACL_INFORMATION_CLASS dwAclInformationClass)
1618 {
1619 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1620 nAclInformationLength, dwAclInformationClass));
1621 }
1622
1623 /******************************************************************************
1624 * IsValidAcl [ADVAPI32.@]
1625 */
1626 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1627 {
1628 return RtlValidAcl(pAcl);
1629 }
1630
1631 /* ##############################
1632 ###### MISC FUNCTIONS ######
1633 ##############################
1634 */
1635
1636 /******************************************************************************
1637 * AllocateLocallyUniqueId [ADVAPI32.@]
1638 *
1639 * PARAMS
1640 * lpLuid []
1641 */
1642 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1643 {
1644 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1645 }
1646
1647 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1648 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1649 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1650 { '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 };
1651 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1652 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1653 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1654 { '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 };
1655 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1656 { '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 };
1657 static const WCHAR SE_TCB_NAME_W[] =
1658 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1659 static const WCHAR SE_SECURITY_NAME_W[] =
1660 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1661 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1662 { '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 };
1663 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1664 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1665 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1666 { '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 };
1667 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1668 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1669 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1670 { '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 };
1671 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1672 { '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 };
1673 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1674 { '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 };
1675 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1676 { '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 };
1677 static const WCHAR SE_BACKUP_NAME_W[] =
1678 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1679 static const WCHAR SE_RESTORE_NAME_W[] =
1680 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1681 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1682 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1683 static const WCHAR SE_DEBUG_NAME_W[] =
1684 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1685 static const WCHAR SE_AUDIT_NAME_W[] =
1686 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1687 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1688 { '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 };
1689 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1690 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1691 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1692 { '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 };
1693 static const WCHAR SE_UNDOCK_NAME_W[] =
1694 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1695 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1696 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1697 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1698 { '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 };
1699 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1700 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1701 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1702 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1703 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1704 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1705
1706 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1707 {
1708 NULL,
1709 NULL,
1710 SE_CREATE_TOKEN_NAME_W,
1711 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1712 SE_LOCK_MEMORY_NAME_W,
1713 SE_INCREASE_QUOTA_NAME_W,
1714 SE_MACHINE_ACCOUNT_NAME_W,
1715 SE_TCB_NAME_W,
1716 SE_SECURITY_NAME_W,
1717 SE_TAKE_OWNERSHIP_NAME_W,
1718 SE_LOAD_DRIVER_NAME_W,
1719 SE_SYSTEM_PROFILE_NAME_W,
1720 SE_SYSTEMTIME_NAME_W,
1721 SE_PROF_SINGLE_PROCESS_NAME_W,
1722 SE_INC_BASE_PRIORITY_NAME_W,
1723 SE_CREATE_PAGEFILE_NAME_W,
1724 SE_CREATE_PERMANENT_NAME_W,
1725 SE_BACKUP_NAME_W,
1726 SE_RESTORE_NAME_W,
1727 SE_SHUTDOWN_NAME_W,
1728 SE_DEBUG_NAME_W,
1729 SE_AUDIT_NAME_W,
1730 SE_SYSTEM_ENVIRONMENT_NAME_W,
1731 SE_CHANGE_NOTIFY_NAME_W,
1732 SE_REMOTE_SHUTDOWN_NAME_W,
1733 SE_UNDOCK_NAME_W,
1734 SE_SYNC_AGENT_NAME_W,
1735 SE_ENABLE_DELEGATION_NAME_W,
1736 SE_MANAGE_VOLUME_NAME_W,
1737 SE_IMPERSONATE_NAME_W,
1738 SE_CREATE_GLOBAL_NAME_W,
1739 };
1740
1741 /******************************************************************************
1742 * LookupPrivilegeValueW [ADVAPI32.@]
1743 *
1744 * See LookupPrivilegeValueA.
1745 */
1746 BOOL WINAPI
1747 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1748 {
1749 UINT i;
1750
1751 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1752
1753 if (!ADVAPI_IsLocalComputer(lpSystemName))
1754 {
1755 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1756 return FALSE;
1757 }
1758 if (!lpName)
1759 {
1760 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1761 return FALSE;
1762 }
1763 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1764 {
1765 if( !WellKnownPrivNames[i] )
1766 continue;
1767 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1768 continue;
1769 lpLuid->LowPart = i;
1770 lpLuid->HighPart = 0;
1771 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1772 lpLuid->HighPart, lpLuid->LowPart );
1773 return TRUE;
1774 }
1775 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1776 return FALSE;
1777 }
1778
1779 /******************************************************************************
1780 * LookupPrivilegeValueA [ADVAPI32.@]
1781 *
1782 * Retrieves LUID used on a system to represent the privilege name.
1783 *
1784 * PARAMS
1785 * lpSystemName [I] Name of the system
1786 * lpName [I] Name of the privilege
1787 * lpLuid [O] Destination for the resulting LUID
1788 *
1789 * RETURNS
1790 * Success: TRUE. lpLuid contains the requested LUID.
1791 * Failure: FALSE.
1792 */
1793 BOOL WINAPI
1794 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1795 {
1796 UNICODE_STRING lpSystemNameW;
1797 UNICODE_STRING lpNameW;
1798 BOOL ret;
1799
1800 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1801 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1802 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1803 RtlFreeUnicodeString(&lpNameW);
1804 RtlFreeUnicodeString(&lpSystemNameW);
1805 return ret;
1806 }
1807
1808 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1809 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1810 {
1811 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1812 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1813
1814 return FALSE;
1815 }
1816
1817 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1818 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1819 {
1820 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1821 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1822
1823 return FALSE;
1824 }
1825
1826 /******************************************************************************
1827 * LookupPrivilegeNameA [ADVAPI32.@]
1828 *
1829 * See LookupPrivilegeNameW.
1830 */
1831 BOOL WINAPI
1832 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1833 LPDWORD cchName)
1834 {
1835 UNICODE_STRING lpSystemNameW;
1836 BOOL ret;
1837 DWORD wLen = 0;
1838
1839 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1840
1841 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1842 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1843 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1844 {
1845 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1846
1847 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1848 &wLen);
1849 if (ret)
1850 {
1851 /* Windows crashes if cchName is NULL, so will I */
1852 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1853 *cchName, NULL, NULL);
1854
1855 if (len == 0)
1856 {
1857 /* WideCharToMultiByte failed */
1858 ret = FALSE;
1859 }
1860 else if (len > *cchName)
1861 {
1862 *cchName = len;
1863 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1864 ret = FALSE;
1865 }
1866 else
1867 {
1868 /* WideCharToMultiByte succeeded, output length needs to be
1869 * length not including NULL terminator
1870 */
1871 *cchName = len - 1;
1872 }
1873 }
1874 HeapFree(GetProcessHeap(), 0, lpNameW);
1875 }
1876 RtlFreeUnicodeString(&lpSystemNameW);
1877 return ret;
1878 }
1879
1880 /******************************************************************************
1881 * LookupPrivilegeNameW [ADVAPI32.@]
1882 *
1883 * Retrieves the privilege name referred to by the LUID lpLuid.
1884 *
1885 * PARAMS
1886 * lpSystemName [I] Name of the system
1887 * lpLuid [I] Privilege value
1888 * lpName [O] Name of the privilege
1889 * cchName [I/O] Number of characters in lpName.
1890 *
1891 * RETURNS
1892 * Success: TRUE. lpName contains the name of the privilege whose value is
1893 * *lpLuid.
1894 * Failure: FALSE.
1895 *
1896 * REMARKS
1897 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1898 * using this function.
1899 * If the length of lpName is too small, on return *cchName will contain the
1900 * number of WCHARs needed to contain the privilege, including the NULL
1901 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1902 * On success, *cchName will contain the number of characters stored in
1903 * lpName, NOT including the NULL terminator.
1904 */
1905 BOOL WINAPI
1906 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1907 LPDWORD cchName)
1908 {
1909 size_t privNameLen;
1910
1911 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1912
1913 if (!ADVAPI_IsLocalComputer(lpSystemName))
1914 {
1915 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1916 return FALSE;
1917 }
1918 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1919 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1920 {
1921 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1922 return FALSE;
1923 }
1924 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1925 /* Windows crashes if cchName is NULL, so will I */
1926 if (*cchName <= privNameLen)
1927 {
1928 *cchName = privNameLen + 1;
1929 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1930 return FALSE;
1931 }
1932 else
1933 {
1934 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1935 *cchName = privNameLen;
1936 return TRUE;
1937 }
1938 }
1939
1940 /******************************************************************************
1941 * GetFileSecurityA [ADVAPI32.@]
1942 *
1943 * Obtains Specified information about the security of a file or directory.
1944 *
1945 * PARAMS
1946 * lpFileName [I] Name of the file to get info for
1947 * RequestedInformation [I] SE_ flags from "winnt.h"
1948 * pSecurityDescriptor [O] Destination for security information
1949 * nLength [I] Length of pSecurityDescriptor
1950 * lpnLengthNeeded [O] Destination for length of returned security information
1951 *
1952 * RETURNS
1953 * Success: TRUE. pSecurityDescriptor contains the requested information.
1954 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1955 *
1956 * NOTES
1957 * The information returned is constrained by the callers access rights and
1958 * privileges.
1959 */
1960 BOOL WINAPI
1961 GetFileSecurityA( LPCSTR lpFileName,
1962 SECURITY_INFORMATION RequestedInformation,
1963 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1964 DWORD nLength, LPDWORD lpnLengthNeeded )
1965 {
1966 DWORD len;
1967 BOOL r;
1968 LPWSTR name = NULL;
1969
1970 if( lpFileName )
1971 {
1972 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1973 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1974 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1975 }
1976
1977 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1978 nLength, lpnLengthNeeded );
1979 HeapFree( GetProcessHeap(), 0, name );
1980
1981 return r;
1982 }
1983
1984 /******************************************************************************
1985 * GetFileSecurityW [ADVAPI32.@]
1986 *
1987 * See GetFileSecurityA.
1988 */
1989 BOOL WINAPI
1990 GetFileSecurityW( LPCWSTR lpFileName,
1991 SECURITY_INFORMATION RequestedInformation,
1992 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1993 DWORD nLength, LPDWORD lpnLengthNeeded )
1994 {
1995 HANDLE hfile;
1996 NTSTATUS status;
1997 DWORD access = 0;
1998
1999 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2000 RequestedInformation, pSecurityDescriptor,
2001 nLength, lpnLengthNeeded);
2002
2003 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2004 DACL_SECURITY_INFORMATION))
2005 access |= READ_CONTROL;
2006 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2007 access |= ACCESS_SYSTEM_SECURITY;
2008
2009 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2010 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2011 if ( hfile == INVALID_HANDLE_VALUE )
2012 return FALSE;
2013
2014 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2015 nLength, lpnLengthNeeded );
2016 CloseHandle( hfile );
2017 return set_ntstatus( status );
2018 }
2019
2020
2021 /******************************************************************************
2022 * LookupAccountSidA [ADVAPI32.@]
2023 */
2024 BOOL WINAPI
2025 LookupAccountSidA(
2026 IN LPCSTR system,
2027 IN PSID sid,
2028 OUT LPSTR account,
2029 IN OUT LPDWORD accountSize,
2030 OUT LPSTR domain,
2031 IN OUT LPDWORD domainSize,
2032 OUT PSID_NAME_USE name_use )
2033 {
2034 DWORD len;
2035 BOOL r;
2036 LPWSTR systemW = NULL;
2037 LPWSTR accountW = NULL;
2038 LPWSTR domainW = NULL;
2039 DWORD accountSizeW = *accountSize;
2040 DWORD domainSizeW = *domainSize;
2041
2042 if (system) {
2043 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2044 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2045 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2046 }
2047 if (account)
2048 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2049 if (domain)
2050 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2051
2052 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2053
2054 if (r) {
2055 if (accountW && *accountSize) {
2056 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2057 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2058 *accountSize = len;
2059 } else
2060 *accountSize = accountSizeW + 1;
2061
2062 if (domainW && *domainSize) {
2063 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2064 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2065 *domainSize = len;
2066 } else
2067 *domainSize = domainSizeW + 1;
2068 }
2069
2070 HeapFree( GetProcessHeap(), 0, systemW );
2071 HeapFree( GetProcessHeap(), 0, accountW );
2072 HeapFree( GetProcessHeap(), 0, domainW );
2073
2074 return r;
2075 }
2076
2077 /******************************************************************************
2078 * LookupAccountSidW [ADVAPI32.@]
2079 *
2080 * PARAMS
2081 * system []
2082 * sid []
2083 * account []
2084 * accountSize []
2085 * domain []
2086 * domainSize []
2087 * name_use []
2088 */
2089
2090 BOOL WINAPI
2091 LookupAccountSidW(
2092 IN LPCWSTR system,
2093 IN PSID sid,
2094 OUT LPWSTR account,
2095 IN OUT LPDWORD accountSize,
2096 OUT LPWSTR domain,
2097 IN OUT LPDWORD domainSize,
2098 OUT PSID_NAME_USE name_use )
2099 {
2100 unsigned int i, j;
2101 const WCHAR * ac = NULL;
2102 const WCHAR * dm = NULL;
2103 SID_NAME_USE use = 0;
2104 LPWSTR computer_name = NULL;
2105 LPWSTR account_name = NULL;
2106
2107 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2108 debugstr_w(system),debugstr_sid(sid),
2109 account,accountSize,accountSize?*accountSize:0,
2110 domain,domainSize,domainSize?*domainSize:0,
2111 name_use);
2112
2113 if (!ADVAPI_IsLocalComputer(system)) {
2114 FIXME("Only local computer supported!\n");
2115 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2116 return FALSE;
2117 }
2118
2119 /* check the well known SIDs first */
2120 for (i = 0; i <= 60; i++) {
2121 if (IsWellKnownSid(sid, i)) {
2122 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2123 if (ACCOUNT_SIDS[j].type == i) {
2124 ac = ACCOUNT_SIDS[j].account;
2125 dm = ACCOUNT_SIDS[j].domain;
2126 use = ACCOUNT_SIDS[j].name_use;
2127 }
2128 }
2129 break;
2130 }
2131 }
2132
2133 if (dm == NULL) {
2134 MAX_SID local;
2135
2136 /* check for the local computer next */
2137 if (ADVAPI_GetComputerSid(&local)) {
2138 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2139 BOOL result;
2140
2141 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2142 result = GetComputerNameW(computer_name, &size);
2143
2144 if (result) {
2145 if (EqualSid(sid, &local)) {
2146 dm = computer_name;
2147 ac = Blank;
2148 use = 3;
2149 } else {
2150 local.SubAuthorityCount++;
2151
2152 if (EqualPrefixSid(sid, &local)) {
2153 dm = computer_name;
2154 use = 1;
2155 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2156 case DOMAIN_USER_RID_ADMIN:
2157 ac = Administrator;
2158 break;
2159 case DOMAIN_USER_RID_GUEST:
2160 ac = Guest;
2161 break;
2162 case DOMAIN_GROUP_RID_ADMINS:
2163 ac = Domain_Admins;
2164 break;
2165 case DOMAIN_GROUP_RID_USERS:
2166 ac = Domain_Users;
2167 break;
2168 case DOMAIN_GROUP_RID_GUESTS:
2169 ac = Domain_Guests;
2170 break;
2171 case DOMAIN_GROUP_RID_COMPUTERS:
2172 ac = Domain_Computers;
2173 break;
2174 case DOMAIN_GROUP_RID_CONTROLLERS:
2175 ac = Domain_Controllers;
2176 break;
2177 case DOMAIN_GROUP_RID_CERT_ADMINS:
2178 ac = Cert_Publishers;
2179 break;
2180 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2181 ac = Schema_Admins;
2182 break;
2183 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2184 ac = Enterprise_Admins;
2185 break;
2186 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2187 ac = Group_Policy_Creator_Owners;
2188 break;
2189 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2190 ac = RAS_and_IAS_Servers;
2191 break;
2192 case 1000: /* first user account */
2193 size = UNLEN + 1;
2194 account_name = HeapAlloc(
2195 GetProcessHeap(), 0, size * sizeof(WCHAR));
2196 if (GetUserNameW(account_name, &size))
2197 ac = account_name;
2198 else
2199 dm = NULL;
2200
2201 break;
2202 default:
2203 dm = NULL;
2204 break;
2205 }
2206 }
2207 }
2208 }
2209 }
2210 }
2211
2212 if (dm) {
2213 DWORD ac_len = lstrlenW(ac);
2214 DWORD dm_len = lstrlenW(dm);
2215 BOOL status = TRUE;
2216
2217 if (*accountSize > ac_len) {
2218 if (account)
2219 lstrcpyW(account, ac);
2220 }
2221 if (*domainSize > dm_len) {
2222 if (domain)
2223 lstrcpyW(domain, dm);
2224 }
2225 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2226 ((*domainSize != 0) && (*domainSize < dm_len))) {
2227 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2228 status = FALSE;
2229 }
2230 if (*domainSize)
2231 *domainSize = dm_len;
2232 else
2233 *domainSize = dm_len + 1;
2234 if (*accountSize)
2235 *accountSize = ac_len;
2236 else
2237 *accountSize = ac_len + 1;
2238 *name_use = use;
2239 HeapFree(GetProcessHeap(), 0, account_name);
2240 HeapFree(GetProcessHeap(), 0, computer_name);
2241 return status;
2242 }
2243
2244 HeapFree(GetProcessHeap(), 0, account_name);
2245 HeapFree(GetProcessHeap(), 0, computer_name);
2246 SetLastError(ERROR_NONE_MAPPED);
2247 return FALSE;
2248 }
2249
2250 /******************************************************************************
2251 * SetFileSecurityA [ADVAPI32.@]
2252 *
2253 * See SetFileSecurityW.
2254 */
2255 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2256 SECURITY_INFORMATION RequestedInformation,
2257 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2258 {
2259 DWORD len;
2260 BOOL r;
2261 LPWSTR name = NULL;
2262
2263 if( lpFileName )
2264 {
2265 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2266 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2267 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2268 }
2269
2270 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2271 HeapFree( GetProcessHeap(), 0, name );
2272
2273 return r;
2274 }
2275
2276 /******************************************************************************
2277 * SetFileSecurityW [ADVAPI32.@]
2278 *
2279 * Sets the security of a file or directory.
2280 *
2281 * PARAMS
2282 * lpFileName []
2283 * RequestedInformation []
2284 * pSecurityDescriptor []
2285 *
2286 * RETURNS
2287 * Success: TRUE.
2288 * Failure: FALSE.
2289 */
2290 BOOL WINAPI
2291 SetFileSecurityW( LPCWSTR lpFileName,
2292 SECURITY_INFORMATION RequestedInformation,
2293 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2294 {
2295 HANDLE file;
2296 DWORD access = 0;
2297 NTSTATUS status;
2298
2299 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2300 pSecurityDescriptor );
2301
2302 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2303 RequestedInformation & GROUP_SECURITY_INFORMATION)
2304 access |= WRITE_OWNER;
2305 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2306 access |= ACCESS_SYSTEM_SECURITY;
2307 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2308 access |= WRITE_DAC;
2309
2310 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2311 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2312 if (file == INVALID_HANDLE_VALUE)
2313 return FALSE;
2314
2315 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2316 CloseHandle( file );
2317 return set_ntstatus( status );
2318 }
2319
2320 /******************************************************************************
2321 * QueryWindows31FilesMigration [ADVAPI32.@]
2322 *
2323 * PARAMS
2324 * x1 []
2325 */
2326 BOOL WINAPI
2327 QueryWindows31FilesMigration( DWORD x1 )
2328 {
2329 FIXME("(%d):stub\n",x1);
2330 return TRUE;
2331 }
2332
2333 /******************************************************************************
2334 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2335 *
2336 * PARAMS
2337 * x1 []
2338 * x2 []
2339 * x3 []
2340 * x4 []
2341 */
2342 BOOL WINAPI
2343 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2344 DWORD x4 )
2345 {
2346 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2347 return TRUE;
2348 }
2349
2350 /******************************************************************************
2351 * NotifyBootConfigStatus [ADVAPI32.@]
2352 *
2353 * PARAMS
2354 * x1 []
2355 */
2356 BOOL WINAPI
2357 NotifyBootConfigStatus( BOOL x1 )
2358 {
2359 FIXME("(0x%08d):stub\n",x1);
2360 return 1;
2361 }
2362
2363 /******************************************************************************
2364 * RevertToSelf [ADVAPI32.@]
2365 *
2366 * Ends the impersonation of a user.
2367 *
2368 * PARAMS
2369 * void []
2370 *
2371 * RETURNS
2372 * Success: TRUE.
2373 * Failure: FALSE.
2374 */
2375 BOOL WINAPI
2376 RevertToSelf( void )
2377 {
2378 HANDLE Token = NULL;
2379 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2380 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2381 }
2382
2383 /******************************************************************************
2384 * ImpersonateSelf [ADVAPI32.@]
2385 *
2386 * Makes an impersonation token that represents the process user and assigns
2387 * to the current thread.
2388 *
2389 * PARAMS
2390 * ImpersonationLevel [I] Level at which to impersonate.
2391 *
2392 * RETURNS
2393 * Success: TRUE.
2394 * Failure: FALSE.
2395 */
2396 BOOL WINAPI
2397 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2398 {
2399 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2400 }
2401
2402 /******************************************************************************
2403 * ImpersonateLoggedOnUser [ADVAPI32.@]
2404 */
2405 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2406 {
2407 DWORD size;
2408 NTSTATUS Status;
2409 HANDLE ImpersonationToken;
2410 TOKEN_TYPE Type;
2411 static BOOL warn = TRUE;
2412
2413 if (warn)
2414 {
2415 FIXME( "(%p)\n", hToken );
2416 warn = FALSE;
2417 }
2418 if (!GetTokenInformation( hToken, TokenType, &Type,
2419 sizeof(TOKEN_TYPE), &size ))
2420 return FALSE;
2421
2422 if (Type == TokenPrimary)
2423 {
2424 OBJECT_ATTRIBUTES ObjectAttributes;
2425
2426 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2427
2428 Status = NtDuplicateToken( hToken,
2429 TOKEN_IMPERSONATE | TOKEN_QUERY,
2430 &ObjectAttributes,
2431 SecurityImpersonation,
2432 TokenImpersonation,
2433 &ImpersonationToken );
2434 if (Status != STATUS_SUCCESS)
2435 {
2436 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2437 SetLastError( RtlNtStatusToDosError( Status ) );
2438 return FALSE;
2439 }
2440 }
2441 else
2442 ImpersonationToken = hToken;
2443
2444 Status = NtSetInformationThread( GetCurrentThread(),
2445 ThreadImpersonationToken,
2446 &ImpersonationToken,
2447 sizeof(ImpersonationToken) );
2448
2449 if (Type == TokenPrimary)
2450 NtClose( ImpersonationToken );
2451
2452 if (Status != STATUS_SUCCESS)
2453 {
2454 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2455 SetLastError( RtlNtStatusToDosError( Status ) );
2456 return FALSE;
2457 }
2458
2459 return TRUE;
2460 }
2461
2462 /******************************************************************************
2463 * AccessCheck [ADVAPI32.@]
2464 */
2465 BOOL WINAPI
2466 AccessCheck(
2467 PSECURITY_DESCRIPTOR SecurityDescriptor,
2468 HANDLE ClientToken,
2469 DWORD DesiredAccess,
2470 PGENERIC_MAPPING GenericMapping,
2471 PPRIVILEGE_SET PrivilegeSet,
2472 LPDWORD PrivilegeSetLength,
2473 LPDWORD GrantedAccess,
2474 LPBOOL AccessStatus)
2475 {
2476 NTSTATUS access_status;
2477 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2478 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2479 GrantedAccess, &access_status) );
2480 if (ret) *AccessStatus = set_ntstatus( access_status );
2481 return ret;
2482 }
2483
2484
2485 /******************************************************************************
2486 * AccessCheckByType [ADVAPI32.@]
2487 */
2488 BOOL WINAPI AccessCheckByType(
2489 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2490 PSID PrincipalSelfSid,
2491 HANDLE ClientToken,
2492 DWORD DesiredAccess,
2493 POBJECT_TYPE_LIST ObjectTypeList,
2494 DWORD ObjectTypeListLength,
2495 PGENERIC_MAPPING GenericMapping,
2496 PPRIVILEGE_SET PrivilegeSet,
2497 LPDWORD PrivilegeSetLength,
2498 LPDWORD GrantedAccess,
2499 LPBOOL AccessStatus)
2500 {
2501 FIXME("stub\n");
2502
2503 *AccessStatus = TRUE;
2504
2505 return !*AccessStatus;
2506 }
2507
2508 /******************************************************************************
2509 * MapGenericMask [ADVAPI32.@]
2510 *
2511 * Maps generic access rights into specific access rights according to the
2512 * supplied mapping.
2513 *
2514 * PARAMS
2515 * AccessMask [I/O] Access rights.
2516 * GenericMapping [I] The mapping between generic and specific rights.
2517 *
2518 * RETURNS
2519 * Nothing.
2520 */
2521 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2522 {
2523 RtlMapGenericMask( AccessMask, GenericMapping );
2524 }
2525
2526 /*************************************************************************
2527 * SetKernelObjectSecurity [ADVAPI32.@]
2528 */
2529 BOOL WINAPI SetKernelObjectSecurity (
2530 IN HANDLE Handle,
2531 IN SECURITY_INFORMATION SecurityInformation,
2532 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2533 {
2534 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2535 }
2536
2537
2538 /******************************************************************************
2539 * AddAuditAccessAce [ADVAPI32.@]
2540 */
2541 BOOL WINAPI AddAuditAccessAce(
2542 IN OUT PACL pAcl,
2543 IN DWORD dwAceRevision,
2544 IN DWORD dwAccessMask,
2545 IN PSID pSid,
2546 IN BOOL bAuditSuccess,
2547 IN BOOL bAuditFailure)
2548 {
2549 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2550 bAuditSuccess, bAuditFailure) );
2551 }
2552
2553 /******************************************************************************
2554 * AddAuditAccessAce [ADVAPI32.@]
2555 */
2556 BOOL WINAPI AddAuditAccessAceEx(
2557 IN OUT PACL pAcl,
2558 IN DWORD dwAceRevision,
2559 IN DWORD dwAceFlags,
2560 IN DWORD dwAccessMask,
2561 IN PSID pSid,
2562 IN BOOL bAuditSuccess,
2563 IN BOOL bAuditFailure)
2564 {
2565 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2566 bAuditSuccess, bAuditFailure) );
2567 }
2568
2569 /******************************************************************************
2570 * LookupAccountNameA [ADVAPI32.@]
2571 */
2572 BOOL WINAPI
2573 LookupAccountNameA(
2574 IN LPCSTR system,
2575 IN LPCSTR account,
2576 OUT PSID sid,
2577 OUT LPDWORD cbSid,
2578 LPSTR ReferencedDomainName,
2579 IN OUT LPDWORD cbReferencedDomainName,
2580 OUT PSID_NAME_USE name_use )
2581 {
2582 BOOL ret;
2583 UNICODE_STRING lpSystemW;
2584 UNICODE_STRING lpAccountW;
2585 LPWSTR lpReferencedDomainNameW = NULL;
2586
2587 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2588 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2589
2590 if (ReferencedDomainName)
2591 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2592
2593 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2594 cbReferencedDomainName, name_use);
2595
2596 if (ret && lpReferencedDomainNameW)
2597 {
2598 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2599 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2600 }
2601
2602 RtlFreeUnicodeString(&lpSystemW);
2603 RtlFreeUnicodeString(&lpAccountW);
2604 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2605
2606 return ret;
2607 }
2608
2609 /******************************************************************************
2610 * lookup_user_account_name
2611 */
2612 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2613 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2614 {
2615 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2616 DWORD len = sizeof(buffer);
2617 HANDLE token;
2618 BOOL ret;
2619 PSID pSid;
2620 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2621 DWORD nameLen;
2622 LPCWSTR domainName;
2623
2624 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2625 {
2626 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2627 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2628 }
2629
2630 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2631 CloseHandle( token );
2632
2633 if (!ret) return FALSE;
2634
2635 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2636
2637 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2638 CopySid(*cbSid, Sid, pSid);
2639 if (*cbSid < GetLengthSid(pSid))
2640 {
2641 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2642 ret = FALSE;
2643 }
2644 *cbSid = GetLengthSid(pSid);
2645
2646 domainName = dm;
2647 nameLen = strlenW(domainName);
2648
2649 if (*cchReferencedDomainName <= nameLen || !ret)
2650 {
2651 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2652 nameLen += 1;
2653 ret = FALSE;
2654 }
2655 else if (ReferencedDomainName)
2656 strcpyW(ReferencedDomainName, domainName);
2657
2658 *cchReferencedDomainName = nameLen;
2659
2660 if (ret)
2661 *peUse = SidTypeUser;
2662
2663 return ret;
2664 }
2665
2666 /******************************************************************************
2667 * lookup_computer_account_name
2668 */
2669 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2670 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2671 {
2672 MAX_SID local;
2673 BOOL ret;
2674 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2675 DWORD nameLen;
2676 LPCWSTR domainName;
2677
2678 if ((ret = ADVAPI_GetComputerSid(&local)))
2679 {
2680 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2681 CopySid(*cbSid, Sid, &local);
2682 if (*cbSid < GetLengthSid(&local))
2683 {
2684 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2685 ret = FALSE;
2686 }
2687 *cbSid = GetLengthSid(&local);
2688 }
2689
2690 domainName = dm;
2691 nameLen = strlenW(domainName);
2692
2693 if (*cchReferencedDomainName <= nameLen || !ret)
2694 {
2695 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2696 nameLen += 1;
2697 ret = FALSE;
2698 }
2699 else if (ReferencedDomainName)
2700 strcpyW(ReferencedDomainName, domainName);
2701
2702 *cchReferencedDomainName = nameLen;
2703
2704 if (ret)
2705 *peUse = SidTypeDomain;
2706
2707 return ret;
2708 }
2709
2710 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2711 LSA_UNICODE_STRING *domain )
2712 {
2713 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2714
2715 while (p > str->Buffer && *p != '\\') p--;
2716
2717 if (*p == '\\')
2718 {
2719 domain->Buffer = str->Buffer;
2720 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2721
2722 account->Buffer = p + 1;
2723 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2724 }
2725 else
2726 {
2727 domain->Buffer = NULL;
2728 domain->Length = 0;
2729
2730 account->Buffer = str->Buffer;
2731 account->Length = str->Length;
2732 }
2733 }
2734
2735 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2736 {
2737 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2738
2739 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2740 return TRUE;
2741
2742 return FALSE;
2743 }
2744
2745 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2746 {
2747 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2748
2749 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2750 return TRUE;
2751
2752 if (ACCOUNT_SIDS[idx].alias)
2753 {
2754 len = strlenW( ACCOUNT_SIDS[idx].alias );
2755 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2756 return TRUE;
2757 }
2758 return FALSE;
2759 }
2760
2761 /*
2762 * Helper function for LookupAccountNameW
2763 */
2764 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2765 PSID Sid, LPDWORD cbSid,
2766 LPWSTR ReferencedDomainName,
2767 LPDWORD cchReferencedDomainName,
2768 PSID_NAME_USE peUse, BOOL *handled )
2769 {
2770 PSID pSid;
2771 LSA_UNICODE_STRING account, domain;
2772 BOOL ret = TRUE;
2773 ULONG i;
2774
2775 *handled = FALSE;
2776 split_domain_account( account_and_domain, &account, &domain );
2777
2778 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2779 {
2780 /* check domain first */
2781 if (domain.Buffer && !match_domain( i, &domain )) continue;
2782
2783 if (match_account( i, &account ))
2784 {
2785 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2786
2787 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2788
2789 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2790 {
2791 if (*cbSid < sidLen)
2792 {
2793 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2794 ret = FALSE;
2795 }
2796 else if (Sid)
2797 {
2798 CopySid(*cbSid, Sid, pSid);
2799 }
2800 *cbSid = sidLen;
2801 }
2802
2803 len = strlenW( ACCOUNT_SIDS[i].domain );
2804 if (*cchReferencedDomainName <= len || !ret)
2805 {
2806 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2807 len++;
2808 ret = FALSE;
2809 }
2810 else if (ReferencedDomainName)
2811 {
2812 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2813 }
2814
2815 *cchReferencedDomainName = len;
2816 if (ret)
2817 *peUse = ACCOUNT_SIDS[i].name_use;
2818
2819 HeapFree(GetProcessHeap(), 0, pSid);
2820 *handled = TRUE;
2821 return ret;
2822 }
2823 }
2824 return ret;
2825 }
2826
2827 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2828 PSID Sid, LPDWORD cbSid,
2829 LPWSTR ReferencedDomainName,
2830 LPDWORD cchReferencedDomainName,
2831 PSID_NAME_USE peUse, BOOL *handled )
2832 {
2833 DWORD nameLen;
2834 LPWSTR userName = NULL;
2835 LSA_UNICODE_STRING account, domain;
2836 BOOL ret = TRUE;
2837
2838 *handled = FALSE;
2839 split_domain_account( account_and_domain, &account, &domain );
2840
2841 /* Let the current Unix user id masquerade as first Windows user account */
2842
2843 nameLen = UNLEN + 1;
2844 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2845
2846 if (domain.Buffer)
2847 {
2848 /* check to make sure this account is on this computer */
2849 if (GetComputerNameW( userName, &nameLen ) &&
2850 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2851 {
2852 SetLastError(ERROR_NONE_MAPPED);
2853 ret = FALSE;
2854 }
2855 nameLen = UNLEN + 1;
2856 }
2857
2858 if (GetUserNameW( userName, &nameLen ) &&
2859 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2860 {
2861 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2862 *handled = TRUE;
2863 }
2864 else
2865 {
2866 nameLen = UNLEN + 1;
2867 if (GetComputerNameW( userName, &nameLen ) &&
2868 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2869 {
2870 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2871 *handled = TRUE;
2872 }
2873 }
2874
2875 HeapFree(GetProcessHeap(), 0, userName);
2876 return ret;
2877 }
2878
2879 /******************************************************************************
2880 * LookupAccountNameW [ADVAPI32.@]
2881 */
2882 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2883 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2884 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2885 {
2886 BOOL ret, handled;
2887 LSA_UNICODE_STRING account;
2888
2889 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2890 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2891
2892 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2893 {
2894 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2895 return FALSE;
2896 }
2897
2898 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2899 {
2900 lpAccountName = BUILTIN;
2901 }
2902
2903 RtlInitUnicodeString( &account, lpAccountName );
2904
2905 /* Check well known SIDs first */
2906 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2907 cchReferencedDomainName, peUse, &handled );
2908 if (handled)
2909 return ret;
2910
2911 /* Check user names */
2912 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2913 cchReferencedDomainName, peUse, &handled);
2914 if (handled)
2915 return ret;
2916
2917 SetLastError( ERROR_NONE_MAPPED );
2918 return FALSE;
2919 }
2920
2921 /******************************************************************************
2922 * PrivilegeCheck [ADVAPI32.@]
2923 */
2924 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2925 {
2926 BOOL ret;
2927 BOOLEAN Result;
2928
2929 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2930
2931 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2932 if (ret)
2933 *pfResult = Result;
2934 return ret;
2935 }
2936
2937 /******************************************************************************
2938 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2939 */
2940 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2941 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2942 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2943 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2944 {
2945 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2946 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2947 SecurityDescriptor, DesiredAccess, GenericMapping,
2948 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2949 return TRUE;
2950 }
2951
2952 /******************************************************************************
2953 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2954 */
2955 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2956 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2957 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2958 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2959 {
2960 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2961 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2962 SecurityDescriptor, DesiredAccess, GenericMapping,
2963 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2964 return TRUE;
2965 }
2966
2967 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2968 {
2969 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2970
2971 return TRUE;
2972 }
2973
2974 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2975 {
2976 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2977
2978 return TRUE;
2979 }
2980
2981 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2982 {
2983 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2984
2985 return TRUE;
2986 }
2987
2988 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2989 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2990 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2991 LPBOOL GenerateOnClose)
2992 {
2993 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2994 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2995 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2996 GenerateOnClose);
2997
2998 return TRUE;
2999 }
3000
3001 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3002 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3003 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3004 LPBOOL GenerateOnClose)
3005 {
3006 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3007 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3008 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3009 GenerateOnClose);
3010
3011 return TRUE;
3012 }
3013
3014 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3015 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3016 {
3017 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3018 DesiredAccess, Privileges, AccessGranted);
3019
3020 return TRUE;
3021 }
3022
3023 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3024 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3025 {
3026 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3027 DesiredAccess, Privileges, AccessGranted);
3028
3029 return TRUE;
3030 }
3031
3032 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3033 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3034 {
3035 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3036 ClientToken, Privileges, AccessGranted);
3037
3038 return TRUE;
3039 }
3040
3041 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3042 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3043 {
3044 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3045 ClientToken, Privileges, AccessGranted);
3046
3047 return TRUE;
3048 }
3049
3050 /******************************************************************************
3051 * GetSecurityInfo [ADVAPI32.@]
3052 *
3053 * Retrieves a copy of the security descriptor associated with an object.
3054 *
3055 * PARAMS
3056 * hObject [I] A handle for the object.
3057 * ObjectType [I] The type of object.
3058 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3059 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3060 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3061 * ppDacl [O] If non-null, receives a pointer to the DACL.
3062 * ppSacl [O] If non-null, receives a pointer to the SACL.
3063 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3064 * which must be freed with LocalFree.
3065 *
3066 * RETURNS
3067 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3068 */
3069 DWORD WINAPI GetSecurityInfo(
3070 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3071 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3072 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3073 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3074 )
3075 {
3076 PSECURITY_DESCRIPTOR sd;
3077 NTSTATUS status;
3078 ULONG n1, n2;
3079 BOOL present, defaulted;
3080
3081 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3082 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3083 return RtlNtStatusToDosError(status);
3084
3085 sd = LocalAlloc(0, n1);
3086 if (!sd)
3087 return ERROR_NOT_ENOUGH_MEMORY;
3088
3089 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3090 if (status != STATUS_SUCCESS)
3091 {
3092 LocalFree(sd);
3093 return RtlNtStatusToDosError(status);
3094 }
3095
3096 if (ppsidOwner)
3097 {
3098 *ppsidOwner = NULL;
3099 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3100 }
3101 if (ppsidGroup)
3102 {
3103 *ppsidGroup = NULL;
3104 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3105 }
3106 if (ppDacl)
3107 {
3108 *ppDacl = NULL;
3109 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3110 }
3111 if (ppSacl)
3112 {
3113 *ppSacl = NULL;
3114 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3115 }
3116 if (ppSecurityDescriptor)
3117 *ppSecurityDescriptor = sd;
3118
3119 return ERROR_SUCCESS;
3120 }
3121
3122 /******************************************************************************
3123 * GetSecurityInfoExA [ADVAPI32.@]
3124 */
3125 DWORD WINAPI GetSecurityInfoExA(
3126 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3127 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3128 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3129 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3130 )
3131 {
3132 FIXME("stub!\n");
3133 return ERROR_BAD_PROVIDER;
3134 }
3135
3136 /******************************************************************************
3137 * GetSecurityInfoExW [ADVAPI32.@]
3138 */
3139 DWORD WINAPI GetSecurityInfoExW(
3140 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3141 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3142 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3143 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3144 )
3145 {
3146 FIXME("stub!\n");
3147 return ERROR_BAD_PROVIDER;
3148 }
3149
3150 /******************************************************************************
3151 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3152 */
3153 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3154 LPSTR pTrusteeName, DWORD AccessPermissions,
3155 ACCESS_MODE AccessMode, DWORD Inheritance )
3156 {
3157 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3158 AccessPermissions, AccessMode, Inheritance);
3159
3160 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3161 pExplicitAccess->grfAccessMode = AccessMode;
3162 pExplicitAccess->grfInheritance = Inheritance;
3163
3164 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3165 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3166 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3167 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3168 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3169 }
3170
3171 /******************************************************************************
3172 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3173 */
3174 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3175 LPWSTR pTrusteeName, DWORD AccessPermissions,
3176 ACCESS_MODE AccessMode, DWORD Inheritance )
3177 {
3178 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3179 AccessPermissions, AccessMode, Inheritance);
3180
3181 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3182 pExplicitAccess->grfAccessMode = AccessMode;
3183 pExplicitAccess->grfInheritance = Inheritance;
3184
3185 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3186 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3187 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3188 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3189 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3190 }
3191
3192 /******************************************************************************
3193 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3194 */
3195 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3196 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3197 LPSTR InheritedObjectTypeName, LPSTR Name )
3198 {
3199 DWORD ObjectsPresent = 0;
3200
3201 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3202 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3203
3204 /* Fill the OBJECTS_AND_NAME structure */
3205 pObjName->ObjectType = ObjectType;
3206 if (ObjectTypeName != NULL)
3207 {
3208 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3209 }
3210
3211 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3212 if (InheritedObjectTypeName != NULL)
3213 {
3214 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3215 }
3216
3217 pObjName->ObjectsPresent = ObjectsPresent;
3218 pObjName->ptstrName = Name;
3219
3220 /* Fill the TRUSTEE structure */
3221 pTrustee->pMultipleTrustee = NULL;
3222 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3223 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3224 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3225 pTrustee->ptstrName = (LPSTR)pObjName;
3226 }
3227
3228 /******************************************************************************
3229 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3230 */
3231 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3232 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3233 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3234 {
3235 DWORD ObjectsPresent = 0;
3236
3237 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3238 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3239
3240 /* Fill the OBJECTS_AND_NAME structure */
3241 pObjName->ObjectType = ObjectType;
3242 if (ObjectTypeName != NULL)
3243 {
3244 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3245 }
3246
3247 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3248 if (InheritedObjectTypeName != NULL)
3249 {
3250 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3251 }
3252
3253 pObjName->ObjectsPresent = ObjectsPresent;
3254 pObjName->ptstrName = Name;
3255
3256 /* Fill the TRUSTEE structure */
3257 pTrustee->pMultipleTrustee = NULL;
3258 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3259 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3260 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3261 pTrustee->ptstrName = (LPWSTR)pObjName;
3262 }
3263
3264 /******************************************************************************
3265 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3266 */
3267 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3268 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3269 {
3270 DWORD ObjectsPresent = 0;
3271
3272 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3273
3274 /* Fill the OBJECTS_AND_SID structure */
3275 if (pObjectGuid != NULL)
3276 {
3277 pObjSid->ObjectTypeGuid = *pObjectGuid;
3278 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3279 }
3280 else
3281 {
3282 ZeroMemory(&pObjSid->ObjectTypeGuid,
3283 sizeof(GUID));
3284 }
3285
3286 if (pInheritedObjectGuid != NULL)
3287 {
3288 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3289 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3290 }
3291 else
3292 {
3293 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3294 sizeof(GUID));
3295 }
3296
3297 pObjSid->ObjectsPresent = ObjectsPresent;
3298 pObjSid->pSid = pSid;
3299
3300 /* Fill the TRUSTEE structure */
3301 pTrustee->pMultipleTrustee = NULL;
3302 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3303 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3304 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3305 pTrustee->ptstrName = (LPSTR) pObjSid;
3306 }
3307
3308 /******************************************************************************
3309 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3310 */
3311 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3312 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3313 {
3314 DWORD ObjectsPresent = 0;
3315
3316 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3317
3318 /* Fill the OBJECTS_AND_SID structure */
3319 if (pObjectGuid != NULL)
3320 {
3321 pObjSid->ObjectTypeGuid = *pObjectGuid;
3322 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3323 }
3324 else
3325 {
3326 ZeroMemory(&pObjSid->ObjectTypeGuid,
3327 sizeof(GUID));
3328 }
3329
3330 if (pInheritedObjectGuid != NULL)
3331 {
3332 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3333 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3334 }
3335 else
3336 {
3337 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3338 sizeof(GUID));
3339 }
3340
3341 pObjSid->ObjectsPresent = ObjectsPresent;
3342 pObjSid->pSid = pSid;
3343
3344 /* Fill the TRUSTEE structure */
3345 pTrustee->pMultipleTrustee = NULL;
3346 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3347 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3348 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3349 pTrustee->ptstrName = (LPWSTR) pObjSid;
3350 }
3351
3352 /******************************************************************************
3353 * BuildTrusteeWithSidA [ADVAPI32.@]
3354 */
3355 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3356 {
3357 TRACE("%p %p\n", pTrustee, pSid);
3358
3359 pTrustee->pMultipleTrustee = NULL;
3360 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3361 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3362 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3363 pTrustee->ptstrName = pSid;
3364 }
3365
3366 /******************************************************************************
3367 * BuildTrusteeWithSidW [ADVAPI32.@]
3368 */
3369 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3370 {
3371 TRACE("%p %p\n", pTrustee, pSid);
3372
3373 pTrustee->pMultipleTrustee = NULL;
3374 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3375 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3376 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3377 pTrustee->ptstrName = pSid;
3378 }
3379
3380 /******************************************************************************
3381 * BuildTrusteeWithNameA [ADVAPI32.@]
3382 */
3383 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3384 {
3385 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3386
3387 pTrustee->pMultipleTrustee = NULL;
3388 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3389 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3390 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3391 pTrustee->ptstrName = name;
3392 }
3393
3394 /******************************************************************************
3395 * BuildTrusteeWithNameW [ADVAPI32.@]
3396 */
3397 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3398 {
3399 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3400
3401 pTrustee->pMultipleTrustee = NULL;
3402 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3403 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3404 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3405 pTrustee->ptstrName = name;
3406 }
3407
3408 /******************************************************************************
3409 * GetTrusteeFormA [ADVAPI32.@]
3410 */
3411 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3412 {
3413 TRACE("(%p)\n", pTrustee);
3414
3415 if (!pTrustee)
3416 return TRUSTEE_BAD_FORM;
3417
3418 return pTrustee->TrusteeForm;
3419 }
3420
3421 /******************************************************************************
3422 * GetTrusteeFormW [ADVAPI32.@]
3423 */
3424 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3425 {
3426 TRACE("(%p)\n", pTrustee);
3427
3428 if (!pTrustee)
3429 return TRUSTEE_BAD_FORM;
3430
3431 return pTrustee->TrusteeForm;
3432 }
3433
3434 /******************************************************************************
3435 * GetTrusteeNameA [ADVAPI32.@]
3436 */
3437 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3438 {
3439 TRACE("(%p)\n", pTrustee);
3440
3441 if (!pTrustee)
3442 return NULL;
3443
3444 return pTrustee->ptstrName;
3445 }
3446
3447 /******************************************************************************
3448 * GetTrusteeNameW [ADVAPI32.@]
3449 */
3450 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3451 {
3452 TRACE("(%p)\n", pTrustee);
3453
3454 if (!pTrustee)
3455 return NULL;
3456
3457 return pTrustee->ptstrName;
3458 }
3459
3460 /******************************************************************************
3461 * GetTrusteeTypeA [ADVAPI32.@]
3462 */
3463 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3464 {
3465 TRACE("(%p)\n", pTrustee);
3466
3467 if (!pTrustee)
3468 return TRUSTEE_IS_UNKNOWN;
3469
3470 return pTrustee->TrusteeType;
3471 }
3472
3473 /******************************************************************************
3474 * GetTrusteeTypeW [ADVAPI32.@]
3475 */
3476 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3477 {
3478 TRACE("(%p)\n", pTrustee);
3479
3480 if (!pTrustee)
3481 return TRUSTEE_IS_UNKNOWN;
3482
3483 return pTrustee->TrusteeType;
3484 }
3485
3486 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3487 DWORD nAclInformationLength,
3488 ACL_INFORMATION_CLASS dwAclInformationClass )
3489 {
3490 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3491 nAclInformationLength, dwAclInformationClass);
3492
3493 return TRUE;
3494 }
3495
3496 /******************************************************************************
3497 * SetEntriesInAclA [ADVAPI32.@]
3498 */
3499 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3500 PACL OldAcl, PACL* NewAcl )
3501 {
3502 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3503 if (NewAcl)
3504 *NewAcl = NULL;
3505 return ERROR_SUCCESS;
3506 }
3507
3508 /******************************************************************************
3509 * SetEntriesInAclW [ADVAPI32.@]
3510 */
3511 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3512 PACL OldAcl, PACL* NewAcl )
3513 {
3514 ULONG i;
3515 PSID *ppsid;
3516 DWORD ret = ERROR_SUCCESS;
3517 DWORD acl_size = sizeof(ACL);
3518 NTSTATUS status;
3519
3520 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3521
3522 *NewAcl = NULL;
3523
3524 if (!count && !OldAcl)
3525 return ERROR_SUCCESS;
3526
3527 /* allocate array of maximum sized sids allowed */
3528 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3529 if (!ppsid)
3530 return ERROR_OUTOFMEMORY;
3531
3532 for (i = 0; i < count; i++)
3533 {
3534 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3535
3536 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3537 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3538 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3539 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3540 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3541 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3542 pEntries[i].Trustee.ptstrName);
3543
3544 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3545 {
3546 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3547 ret = ERROR_INVALID_PARAMETER;
3548 goto exit;
3549 }
3550
3551 switch (pEntries[i].Trustee.TrusteeForm)
3552 {
3553 case TRUSTEE_IS_SID:
3554 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3555 ppsid[i], pEntries[i].Trustee.ptstrName))
3556 {
3557 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3558 ret = ERROR_INVALID_PARAMETER;
3559 goto exit;
3560 }
3561 break;
3562 case TRUSTEE_IS_NAME:
3563 {
3564 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3565 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3566 SID_NAME_USE use;
3567 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3568 {
3569 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3570 {
3571 ret = GetLastError();
3572 goto exit;
3573 }
3574 }
3575 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3576 {
3577 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3578 ret = ERROR_INVALID_PARAMETER;
3579 goto exit;
3580 }
3581 break;
3582 }
3583 case TRUSTEE_IS_OBJECTS_AND_SID:
3584 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3585 break;
3586 case TRUSTEE_IS_OBJECTS_AND_NAME:
3587 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3588 break;
3589 default:
3590 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3591 ret = ERROR_INVALID_PARAMETER;
3592 goto exit;
3593 }
3594
3595 /* Note: we overestimate the ACL size here as a tradeoff between
3596 * instructions (simplicity) and memory */
3597 switch (pEntries[i].grfAccessMode)
3598 {
3599 case GRANT_ACCESS:
3600 case SET_ACCESS:
3601 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3602 break;
3603 case DENY_ACCESS:
3604 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3605 break;
3606 case SET_AUDIT_SUCCESS:
3607 case SET_AUDIT_FAILURE:
3608 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3609 break;
3610 case REVOKE_ACCESS:
3611 break;
3612 default:
3613 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3614 ret = ERROR_INVALID_PARAMETER;
3615 goto exit;
3616 }
3617 }
3618
3619 if (OldAcl)
3620 {
3621 ACL_SIZE_INFORMATION size_info;
3622
3623 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3624 if (status != STATUS_SUCCESS)
3625 {
3626 ret = RtlNtStatusToDosError(status);
3627 goto exit;
3628 }
3629 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3630 }
3631
3632 *NewAcl = LocalAlloc(0, acl_size);
3633 if (!*NewAcl)
3634 {
3635 ret = ERROR_OUTOFMEMORY;
3636 goto exit;
3637 }
3638
3639 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3640 if (status != STATUS_SUCCESS)
3641 {
3642 ret = RtlNtStatusToDosError(status);
3643 goto exit;
3644 }
3645
3646 for (i = 0; i < count; i++)
3647 {
3648 switch (pEntries[i].grfAccessMode)
3649 {
3650 case GRANT_ACCESS:
3651 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3652 pEntries[i].grfInheritance,
3653 pEntries[i].grfAccessPermissions,
3654 ppsid[i]);
3655 break;
3656 case SET_ACCESS:
3657 {
3658 ULONG j;
3659 BOOL add = TRUE;
3660 if (OldAcl)
3661 {
3662 for (j = 0; ; j++)
3663 {
3664 const ACE_HEADER *existing_ace_header;
3665 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3666 if (status != STATUS_SUCCESS)
3667 break;
3668 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3669 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3670 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3671 {
3672 add = FALSE;
3673 break;
3674 }
3675 }
3676 }
3677 if (add)
3678 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3679 pEntries[i].grfInheritance,
3680 pEntries[i].grfAccessPermissions,
3681 ppsid[i]);
3682 break;
3683 }
3684 case DENY_ACCESS:
3685 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3686 pEntries[i].grfInheritance,
3687 pEntries[i].grfAccessPermissions,
3688 ppsid[i]);
3689 break;
3690 case SET_AUDIT_SUCCESS:
3691 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3692 pEntries[i].grfInheritance,
3693 pEntries[i].grfAccessPermissions,
3694 ppsid[i], TRUE, FALSE);
3695 break;
3696 case SET_AUDIT_FAILURE:
3697 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3698 pEntries[i].grfInheritance,
3699 pEntries[i].grfAccessPermissions,
3700 ppsid[i], FALSE, TRUE);
3701 break;
3702 default:
3703 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3704 }
3705 }
3706
3707 if (OldAcl)
3708 {
3709 for (i = 0; ; i++)
3710 {
3711 BOOL add = TRUE;
3712 ULONG j;
3713 const ACE_HEADER *old_ace_header;
3714 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3715 if (status != STATUS_SUCCESS) break;
3716 for (j = 0; j < count; j++)
3717 {
3718 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3719 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3720 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3721 {
3722 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3723 add = FALSE;
3724 break;
3725 }
3726 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3727 {
3728 switch (old_ace_header->AceType)
3729 {
3730 case ACCESS_ALLOWED_ACE_TYPE:
3731 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3732 add = FALSE;
3733 break;
3734 case ACCESS_DENIED_ACE_TYPE:
3735 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3736 add = FALSE;
3737 break;
3738 case SYSTEM_AUDIT_ACE_TYPE:
3739 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3740 add = FALSE;
3741 break;
3742 case SYSTEM_ALARM_ACE_TYPE:
3743 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3744 add = FALSE;
3745 break;
3746 default:
3747 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3748 }
3749
3750 if (!add)
3751 break;
3752 }
3753 }
3754 if (add)
3755 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3756 if (status != STATUS_SUCCESS)
3757 {
3758 WARN("RtlAddAce failed with error 0x%08x\n", status);
3759 ret = RtlNtStatusToDosError(status);
3760 break;
3761 }
3762 }
3763 }
3764
3765 exit:
3766 HeapFree(GetProcessHeap(), 0, ppsid);
3767 return ret;
3768 }
3769
3770 /******************************************************************************
3771 * SetNamedSecurityInfoA [ADVAPI32.@]
3772 */
3773 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3774 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3775 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3776 {
3777 DWORD len;
3778 LPWSTR wstr = NULL;
3779 DWORD r;
3780
3781 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3782 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3783
3784 if( pObjectName )
3785 {
3786 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3787 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3788 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3789 }
3790
3791 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3792 psidGroup, pDacl, pSacl );
3793
3794 HeapFree( GetProcessHeap(), 0, wstr );
3795
3796 return r;
3797 }
3798
3799 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3800 PSECURITY_DESCRIPTOR ModificationDescriptor,
3801 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3802 PGENERIC_MAPPING GenericMapping,
3803 HANDLE Token )
3804 {
3805 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3806 ObjectsSecurityDescriptor, GenericMapping, Token);
3807
3808 return TRUE;
3809 }
3810
3811 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3812 {
3813 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3814 }
3815
3816 /******************************************************************************
3817 * AreAnyAccessesGranted [ADVAPI32.@]
3818 *
3819 * Determines whether or not any of a set o