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 TokenHandle, PSID SidToCheck,
626 PBOOL IsMember )
627 {
628 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629
630 *IsMember = TRUE;
631 return(TRUE);
632 }
633
634 /******************************************************************************
635 * GetTokenInformation [ADVAPI32.@]
636 *
637 * Get a type of information about an access token.
638 *
639 * PARAMS
640 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
641 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
642 * tokeninfo [O] Destination for token information
643 * tokeninfolength [I] Length of tokeninfo
644 * retlen [O] Destination for returned token information length
645 *
646 * RETURNS
647 * Success: TRUE. tokeninfo contains retlen bytes of token information
648 * Failure: FALSE.
649 *
650 * NOTES
651 * See NtQueryInformationToken.
652 */
653 BOOL WINAPI
654 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
655 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 {
657 TRACE("(%p, %s, %p, %d, %p):\n",
658 token,
659 (tokeninfoclass == TokenUser) ? "TokenUser" :
660 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
661 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
662 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
663 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
664 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
665 (tokeninfoclass == TokenSource) ? "TokenSource" :
666 (tokeninfoclass == TokenType) ? "TokenType" :
667 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
668 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
669 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
670 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
671 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
672 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
673 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
674 "Unknown",
675 tokeninfo, tokeninfolength, retlen);
676 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
677 tokeninfolength, retlen));
678 }
679
680 /******************************************************************************
681 * SetTokenInformation [ADVAPI32.@]
682 *
683 * Set information for an access token.
684 *
685 * PARAMS
686 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
687 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
688 * tokeninfo [I] Token information to set
689 * tokeninfolength [I] Length of tokeninfo
690 *
691 * RETURNS
692 * Success: TRUE. The information for the token is set to tokeninfo.
693 * Failure: FALSE.
694 */
695 BOOL WINAPI
696 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
697 LPVOID tokeninfo, DWORD tokeninfolength )
698 {
699 TRACE("(%p, %s, %p, %d): stub\n",
700 token,
701 (tokeninfoclass == TokenUser) ? "TokenUser" :
702 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
703 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
704 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
705 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
706 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
707 (tokeninfoclass == TokenSource) ? "TokenSource" :
708 (tokeninfoclass == TokenType) ? "TokenType" :
709 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
710 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
711 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
712 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
713 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
714 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
715 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
716 "Unknown",
717 tokeninfo, tokeninfolength);
718
719 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
720 }
721
722 /*************************************************************************
723 * SetThreadToken [ADVAPI32.@]
724 *
725 * Assigns an 'impersonation token' to a thread so it can assume the
726 * security privileges of another thread or process. Can also remove
727 * a previously assigned token.
728 *
729 * PARAMS
730 * thread [O] Handle to thread to set the token for
731 * token [I] Token to set
732 *
733 * RETURNS
734 * Success: TRUE. The threads access token is set to token
735 * Failure: FALSE.
736 *
737 * NOTES
738 * Only supported on NT or higher. On Win9X this function does nothing.
739 * See SetTokenInformation.
740 */
741 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 {
743 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
744 ThreadImpersonationToken, &token, sizeof token ));
745 }
746
747 /*************************************************************************
748 * CreateRestrictedToken [ADVAPI32.@]
749 *
750 * Create a new more restricted token from an existing token.
751 *
752 * PARAMS
753 * baseToken [I] Token to base the new restricted token on
754 * flags [I] Options
755 * nDisableSids [I] Length of disableSids array
756 * disableSids [I] Array of SIDs to disable in the new token
757 * nDeletePrivs [I] Length of deletePrivs array
758 * deletePrivs [I] Array of privileges to delete in the new token
759 * nRestrictSids [I] Length of restrictSids array
760 * restrictSids [I] Array of SIDs to restrict in the new token
761 * newToken [O] Address where the new token is stored
762 *
763 * RETURNS
764 * Success: TRUE
765 * Failure: FALSE
766 */
767 BOOL WINAPI CreateRestrictedToken(
768 HANDLE baseToken,
769 DWORD flags,
770 DWORD nDisableSids,
771 PSID_AND_ATTRIBUTES disableSids,
772 DWORD nDeletePrivs,
773 PLUID_AND_ATTRIBUTES deletePrivs,
774 DWORD nRestrictSids,
775 PSID_AND_ATTRIBUTES restrictSids,
776 PHANDLE newToken)
777 {
778 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
779 baseToken, flags, nDisableSids, disableSids,
780 nDeletePrivs, deletePrivs,
781 nRestrictSids, restrictSids,
782 newToken);
783 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
784 return FALSE;
785 }
786
787 /* ##############################
788 ###### SID FUNCTIONS ######
789 ##############################
790 */
791
792 /******************************************************************************
793 * AllocateAndInitializeSid [ADVAPI32.@]
794 *
795 * PARAMS
796 * pIdentifierAuthority []
797 * nSubAuthorityCount []
798 * nSubAuthority0 []
799 * nSubAuthority1 []
800 * nSubAuthority2 []
801 * nSubAuthority3 []
802 * nSubAuthority4 []
803 * nSubAuthority5 []
804 * nSubAuthority6 []
805 * nSubAuthority7 []
806 * pSid []
807 */
808 BOOL WINAPI
809 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
810 BYTE nSubAuthorityCount,
811 DWORD nSubAuthority0, DWORD nSubAuthority1,
812 DWORD nSubAuthority2, DWORD nSubAuthority3,
813 DWORD nSubAuthority4, DWORD nSubAuthority5,
814 DWORD nSubAuthority6, DWORD nSubAuthority7,
815 PSID *pSid )
816 {
817 return set_ntstatus( RtlAllocateAndInitializeSid(
818 pIdentifierAuthority, nSubAuthorityCount,
819 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
820 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
821 pSid ));
822 }
823
824 /******************************************************************************
825 * FreeSid [ADVAPI32.@]
826 *
827 * PARAMS
828 * pSid []
829 */
830 PVOID WINAPI
831 FreeSid( PSID pSid )
832 {
833 RtlFreeSid(pSid);
834 return NULL; /* is documented like this */
835 }
836
837 /******************************************************************************
838 * CopySid [ADVAPI32.@]
839 *
840 * PARAMS
841 * nDestinationSidLength []
842 * pDestinationSid []
843 * pSourceSid []
844 */
845 BOOL WINAPI
846 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 {
848 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
849 }
850
851 /******************************************************************************
852 * CreateWellKnownSid [ADVAPI32.@]
853 */
854 BOOL WINAPI
855 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
856 PSID DomainSid,
857 PSID pSid,
858 DWORD* cbSid)
859 {
860 unsigned int i;
861 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862
863 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
864 {
865 SetLastError(ERROR_INVALID_PARAMETER);
866 return FALSE;
867 }
868
869 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
870 if (WellKnownSids[i].Type == WellKnownSidType) {
871 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
872
873 if (*cbSid < length)
874 {
875 *cbSid = length;
876 SetLastError(ERROR_INSUFFICIENT_BUFFER);
877 return FALSE;
878 }
879 if (!pSid)
880 {
881 SetLastError(ERROR_INVALID_PARAMETER);
882 return FALSE;
883 }
884 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
885 *cbSid = length;
886 return TRUE;
887 }
888 }
889
890 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
891 {
892 SetLastError(ERROR_INVALID_PARAMETER);
893 return FALSE;
894 }
895
896 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
897 if (WellKnownRids[i].Type == WellKnownSidType) {
898 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
899 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
900 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
901
902 if (*cbSid < output_sid_length)
903 {
904 *cbSid = output_sid_length;
905 SetLastError(ERROR_INSUFFICIENT_BUFFER);
906 return FALSE;
907 }
908 if (!pSid)
909 {
910 SetLastError(ERROR_INVALID_PARAMETER);
911 return FALSE;
912 }
913 CopyMemory(pSid, DomainSid, domain_sid_length);
914 (*GetSidSubAuthorityCount(pSid))++;
915 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
916 *cbSid = output_sid_length;
917 return TRUE;
918 }
919
920 SetLastError(ERROR_INVALID_PARAMETER);
921 return FALSE;
922 }
923
924 /******************************************************************************
925 * IsWellKnownSid [ADVAPI32.@]
926 */
927 BOOL WINAPI
928 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
929 {
930 unsigned int i;
931 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
932
933 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
934 if (WellKnownSids[i].Type == WellKnownSidType)
935 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
936 return TRUE;
937
938 return FALSE;
939 }
940
941 BOOL WINAPI
942 IsTokenRestricted( HANDLE TokenHandle )
943 {
944 TOKEN_GROUPS *groups;
945 DWORD size;
946 NTSTATUS status;
947 BOOL restricted;
948
949 TRACE("(%p)\n", TokenHandle);
950
951 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
952 if (status != STATUS_BUFFER_TOO_SMALL)
953 return FALSE;
954
955 groups = HeapAlloc(GetProcessHeap(), 0, size);
956 if (!groups)
957 {
958 SetLastError(ERROR_OUTOFMEMORY);
959 return FALSE;
960 }
961
962 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
963 if (status != STATUS_SUCCESS)
964 {
965 HeapFree(GetProcessHeap(), 0, groups);
966 return set_ntstatus(status);
967 }
968
969 if (groups->GroupCount)
970 restricted = TRUE;
971 else
972 restricted = FALSE;
973
974 HeapFree(GetProcessHeap(), 0, groups);
975
976 return restricted;
977 }
978
979 /******************************************************************************
980 * IsValidSid [ADVAPI32.@]
981 *
982 * PARAMS
983 * pSid []
984 */
985 BOOL WINAPI
986 IsValidSid( PSID pSid )
987 {
988 return RtlValidSid( pSid );
989 }
990
991 /******************************************************************************
992 * EqualSid [ADVAPI32.@]
993 *
994 * PARAMS
995 * pSid1 []
996 * pSid2 []
997 */
998 BOOL WINAPI
999 EqualSid( PSID pSid1, PSID pSid2 )
1000 {
1001 return RtlEqualSid( pSid1, pSid2 );
1002 }
1003
1004 /******************************************************************************
1005 * EqualPrefixSid [ADVAPI32.@]
1006 */
1007 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1008 {
1009 return RtlEqualPrefixSid(pSid1, pSid2);
1010 }
1011
1012 /******************************************************************************
1013 * GetSidLengthRequired [ADVAPI32.@]
1014 *
1015 * PARAMS
1016 * nSubAuthorityCount []
1017 */
1018 DWORD WINAPI
1019 GetSidLengthRequired( BYTE nSubAuthorityCount )
1020 {
1021 return RtlLengthRequiredSid(nSubAuthorityCount);
1022 }
1023
1024 /******************************************************************************
1025 * InitializeSid [ADVAPI32.@]
1026 *
1027 * PARAMS
1028 * pIdentifierAuthority []
1029 */
1030 BOOL WINAPI
1031 InitializeSid (
1032 PSID pSid,
1033 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1034 BYTE nSubAuthorityCount)
1035 {
1036 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1037 }
1038
1039 DWORD WINAPI
1040 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1041 {
1042 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1043
1044 return 1;
1045 }
1046
1047 DWORD WINAPI
1048 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1049 {
1050 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1051
1052 return 1;
1053 }
1054
1055 /******************************************************************************
1056 * GetSidIdentifierAuthority [ADVAPI32.@]
1057 *
1058 * PARAMS
1059 * pSid []
1060 */
1061 PSID_IDENTIFIER_AUTHORITY WINAPI
1062 GetSidIdentifierAuthority( PSID pSid )
1063 {
1064 return RtlIdentifierAuthoritySid(pSid);
1065 }
1066
1067 /******************************************************************************
1068 * GetSidSubAuthority [ADVAPI32.@]
1069 *
1070 * PARAMS
1071 * pSid []
1072 * nSubAuthority []
1073 */
1074 PDWORD WINAPI
1075 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1076 {
1077 SetLastError(ERROR_SUCCESS);
1078 return RtlSubAuthoritySid(pSid, nSubAuthority);
1079 }
1080
1081 /******************************************************************************
1082 * GetSidSubAuthorityCount [ADVAPI32.@]
1083 *
1084 * PARAMS
1085 * pSid []
1086 */
1087 PUCHAR WINAPI
1088 GetSidSubAuthorityCount (PSID pSid)
1089 {
1090 SetLastError(ERROR_SUCCESS);
1091 return RtlSubAuthorityCountSid(pSid);
1092 }
1093
1094 /******************************************************************************
1095 * GetLengthSid [ADVAPI32.@]
1096 *
1097 * PARAMS
1098 * pSid []
1099 */
1100 DWORD WINAPI
1101 GetLengthSid (PSID pSid)
1102 {
1103 return RtlLengthSid(pSid);
1104 }
1105
1106 /* ##############################################
1107 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1108 ##############################################
1109 */
1110
1111 /******************************************************************************
1112 * BuildSecurityDescriptorA [ADVAPI32.@]
1113 *
1114 * Builds a SD from
1115 *
1116 * PARAMS
1117 * pOwner [I]
1118 * pGroup [I]
1119 * cCountOfAccessEntries [I]
1120 * pListOfAccessEntries [I]
1121 * cCountOfAuditEntries [I]
1122 * pListofAuditEntries [I]
1123 * pOldSD [I]
1124 * lpdwBufferLength [I/O]
1125 * pNewSD [O]
1126 *
1127 * RETURNS
1128 * Success: ERROR_SUCCESS
1129 * Failure: nonzero error code from Winerror.h
1130 */
1131 DWORD WINAPI BuildSecurityDescriptorA(
1132 IN PTRUSTEEA pOwner,
1133 IN PTRUSTEEA pGroup,
1134 IN ULONG cCountOfAccessEntries,
1135 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1136 IN ULONG cCountOfAuditEntries,
1137 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1138 IN PSECURITY_DESCRIPTOR pOldSD,
1139 IN OUT PULONG lpdwBufferLength,
1140 OUT PSECURITY_DESCRIPTOR* pNewSD)
1141 {
1142 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145
1146 return ERROR_CALL_NOT_IMPLEMENTED;
1147 }
1148
1149 /******************************************************************************
1150 * BuildSecurityDescriptorW [ADVAPI32.@]
1151 *
1152 * See BuildSecurityDescriptorA.
1153 */
1154 DWORD WINAPI BuildSecurityDescriptorW(
1155 IN PTRUSTEEW pOwner,
1156 IN PTRUSTEEW pGroup,
1157 IN ULONG cCountOfAccessEntries,
1158 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1159 IN ULONG cCountOfAuditEntries,
1160 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1161 IN PSECURITY_DESCRIPTOR pOldSD,
1162 IN OUT PULONG lpdwBufferLength,
1163 OUT PSECURITY_DESCRIPTOR* pNewSD)
1164 {
1165 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1166 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1167 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1168
1169 return ERROR_CALL_NOT_IMPLEMENTED;
1170 }
1171
1172 /******************************************************************************
1173 * InitializeSecurityDescriptor [ADVAPI32.@]
1174 *
1175 * PARAMS
1176 * pDescr []
1177 * revision []
1178 */
1179 BOOL WINAPI
1180 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1181 {
1182 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1183 }
1184
1185
1186 /******************************************************************************
1187 * MakeAbsoluteSD [ADVAPI32.@]
1188 */
1189 BOOL WINAPI MakeAbsoluteSD (
1190 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1191 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1192 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1193 OUT PACL pDacl,
1194 OUT LPDWORD lpdwDaclSize,
1195 OUT PACL pSacl,
1196 OUT LPDWORD lpdwSaclSize,
1197 OUT PSID pOwner,
1198 OUT LPDWORD lpdwOwnerSize,
1199 OUT PSID pPrimaryGroup,
1200 OUT LPDWORD lpdwPrimaryGroupSize)
1201 {
1202 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1203 pAbsoluteSecurityDescriptor,
1204 lpdwAbsoluteSecurityDescriptorSize,
1205 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1206 pOwner, lpdwOwnerSize,
1207 pPrimaryGroup, lpdwPrimaryGroupSize));
1208 }
1209
1210 /******************************************************************************
1211 * GetKernelObjectSecurity [ADVAPI32.@]
1212 */
1213 BOOL WINAPI GetKernelObjectSecurity(
1214 HANDLE Handle,
1215 SECURITY_INFORMATION RequestedInformation,
1216 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1217 DWORD nLength,
1218 LPDWORD lpnLengthNeeded )
1219 {
1220 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1221 pSecurityDescriptor, nLength, lpnLengthNeeded);
1222
1223 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1224 nLength, lpnLengthNeeded ));
1225 }
1226
1227 /******************************************************************************
1228 * GetPrivateObjectSecurity [ADVAPI32.@]
1229 */
1230 BOOL WINAPI GetPrivateObjectSecurity(
1231 PSECURITY_DESCRIPTOR ObjectDescriptor,
1232 SECURITY_INFORMATION SecurityInformation,
1233 PSECURITY_DESCRIPTOR ResultantDescriptor,
1234 DWORD DescriptorLength,
1235 PDWORD ReturnLength )
1236 {
1237 SECURITY_DESCRIPTOR desc;
1238 BOOL defaulted, present;
1239 PACL pacl;
1240 PSID psid;
1241
1242 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1243 ResultantDescriptor, DescriptorLength, ReturnLength);
1244
1245 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1246 return FALSE;
1247
1248 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1249 {
1250 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1251 return FALSE;
1252 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1253 }
1254
1255 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1256 {
1257 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1258 return FALSE;
1259 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1260 }
1261
1262 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1263 {
1264 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1265 return FALSE;
1266 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1267 }
1268
1269 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1270 {
1271 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1272 return FALSE;
1273 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1274 }
1275
1276 *ReturnLength = DescriptorLength;
1277 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1278 }
1279
1280 /******************************************************************************
1281 * GetSecurityDescriptorLength [ADVAPI32.@]
1282 */
1283 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1284 {
1285 return RtlLengthSecurityDescriptor(pDescr);
1286 }
1287
1288 /******************************************************************************
1289 * GetSecurityDescriptorOwner [ADVAPI32.@]
1290 *
1291 * PARAMS
1292 * pOwner []
1293 * lpbOwnerDefaulted []
1294 */
1295 BOOL WINAPI
1296 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1297 LPBOOL lpbOwnerDefaulted )
1298 {
1299 BOOLEAN defaulted;
1300 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1301 *lpbOwnerDefaulted = defaulted;
1302 return ret;
1303 }
1304
1305 /******************************************************************************
1306 * SetSecurityDescriptorOwner [ADVAPI32.@]
1307 *
1308 * PARAMS
1309 */
1310 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1311 PSID pOwner, BOOL bOwnerDefaulted)
1312 {
1313 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1314 }
1315 /******************************************************************************
1316 * GetSecurityDescriptorGroup [ADVAPI32.@]
1317 */
1318 BOOL WINAPI GetSecurityDescriptorGroup(
1319 PSECURITY_DESCRIPTOR SecurityDescriptor,
1320 PSID *Group,
1321 LPBOOL GroupDefaulted)
1322 {
1323 BOOLEAN defaulted;
1324 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1325 *GroupDefaulted = defaulted;
1326 return ret;
1327 }
1328 /******************************************************************************
1329 * SetSecurityDescriptorGroup [ADVAPI32.@]
1330 */
1331 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1332 PSID Group, BOOL GroupDefaulted)
1333 {
1334 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1335 }
1336
1337 /******************************************************************************
1338 * IsValidSecurityDescriptor [ADVAPI32.@]
1339 *
1340 * PARAMS
1341 * lpsecdesc []
1342 */
1343 BOOL WINAPI
1344 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1345 {
1346 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1347 }
1348
1349 /******************************************************************************
1350 * GetSecurityDescriptorDacl [ADVAPI32.@]
1351 */
1352 BOOL WINAPI GetSecurityDescriptorDacl(
1353 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1354 OUT LPBOOL lpbDaclPresent,
1355 OUT PACL *pDacl,
1356 OUT LPBOOL lpbDaclDefaulted)
1357 {
1358 BOOLEAN present, defaulted;
1359 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1360 *lpbDaclPresent = present;
1361 *lpbDaclDefaulted = defaulted;
1362 return ret;
1363 }
1364
1365 /******************************************************************************
1366 * SetSecurityDescriptorDacl [ADVAPI32.@]
1367 */
1368 BOOL WINAPI
1369 SetSecurityDescriptorDacl (
1370 PSECURITY_DESCRIPTOR lpsd,
1371 BOOL daclpresent,
1372 PACL dacl,
1373 BOOL dacldefaulted )
1374 {
1375 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1376 }
1377 /******************************************************************************
1378 * GetSecurityDescriptorSacl [ADVAPI32.@]
1379 */
1380 BOOL WINAPI GetSecurityDescriptorSacl(
1381 IN PSECURITY_DESCRIPTOR lpsd,
1382 OUT LPBOOL lpbSaclPresent,
1383 OUT PACL *pSacl,
1384 OUT LPBOOL lpbSaclDefaulted)
1385 {
1386 BOOLEAN present, defaulted;
1387 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1388 *lpbSaclPresent = present;
1389 *lpbSaclDefaulted = defaulted;
1390 return ret;
1391 }
1392
1393 /**************************************************************************
1394 * SetSecurityDescriptorSacl [ADVAPI32.@]
1395 */
1396 BOOL WINAPI SetSecurityDescriptorSacl (
1397 PSECURITY_DESCRIPTOR lpsd,
1398 BOOL saclpresent,
1399 PACL lpsacl,
1400 BOOL sacldefaulted)
1401 {
1402 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1403 }
1404 /******************************************************************************
1405 * MakeSelfRelativeSD [ADVAPI32.@]
1406 *
1407 * PARAMS
1408 * lpabssecdesc []
1409 * lpselfsecdesc []
1410 * lpbuflen []
1411 */
1412 BOOL WINAPI
1413 MakeSelfRelativeSD(
1414 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1415 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1416 IN OUT LPDWORD lpdwBufferLength)
1417 {
1418 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1419 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1420 }
1421
1422 /******************************************************************************
1423 * GetSecurityDescriptorControl [ADVAPI32.@]
1424 */
1425
1426 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1427 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1428 {
1429 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1430 }
1431
1432 /******************************************************************************
1433 * SetSecurityDescriptorControl [ADVAPI32.@]
1434 */
1435 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1436 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1437 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1438 {
1439 return set_ntstatus( RtlSetControlSecurityDescriptor(
1440 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1441 }
1442
1443 /* ##############################
1444 ###### ACL FUNCTIONS ######
1445 ##############################
1446 */
1447
1448 /*************************************************************************
1449 * InitializeAcl [ADVAPI32.@]
1450 */
1451 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1452 {
1453 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1454 }
1455
1456 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1457 {
1458 IO_STATUS_BLOCK io_block;
1459
1460 TRACE("(%p)\n", hNamedPipe);
1461
1462 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1463 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1464 }
1465
1466 /******************************************************************************
1467 * AddAccessAllowedAce [ADVAPI32.@]
1468 */
1469 BOOL WINAPI AddAccessAllowedAce(
1470 IN OUT PACL pAcl,
1471 IN DWORD dwAceRevision,
1472 IN DWORD AccessMask,
1473 IN PSID pSid)
1474 {
1475 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1476 }
1477
1478 /******************************************************************************
1479 * AddAccessAllowedAceEx [ADVAPI32.@]
1480 */
1481 BOOL WINAPI AddAccessAllowedAceEx(
1482 IN OUT PACL pAcl,
1483 IN DWORD dwAceRevision,
1484 IN DWORD AceFlags,
1485 IN DWORD AccessMask,
1486 IN PSID pSid)
1487 {
1488 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1489 }
1490
1491 /******************************************************************************
1492 * AddAccessDeniedAce [ADVAPI32.@]
1493 */
1494 BOOL WINAPI AddAccessDeniedAce(
1495 IN OUT PACL pAcl,
1496 IN DWORD dwAceRevision,
1497 IN DWORD AccessMask,
1498 IN PSID pSid)
1499 {
1500 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1501 }
1502
1503 /******************************************************************************
1504 * AddAccessDeniedAceEx [ADVAPI32.@]
1505 */
1506 BOOL WINAPI AddAccessDeniedAceEx(
1507 IN OUT PACL pAcl,
1508 IN DWORD dwAceRevision,
1509 IN DWORD AceFlags,
1510 IN DWORD AccessMask,
1511 IN PSID pSid)
1512 {
1513 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1514 }
1515
1516 /******************************************************************************
1517 * AddAce [ADVAPI32.@]
1518 */
1519 BOOL WINAPI AddAce(
1520 IN OUT PACL pAcl,
1521 IN DWORD dwAceRevision,
1522 IN DWORD dwStartingAceIndex,
1523 LPVOID pAceList,
1524 DWORD nAceListLength)
1525 {
1526 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1527 }
1528
1529 /******************************************************************************
1530 * DeleteAce [ADVAPI32.@]
1531 */
1532 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1533 {
1534 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1535 }
1536
1537 /******************************************************************************
1538 * FindFirstFreeAce [ADVAPI32.@]
1539 */
1540 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1541 {
1542 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1543 }
1544
1545 /******************************************************************************
1546 * GetAce [ADVAPI32.@]
1547 */
1548 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1549 {
1550 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1551 }
1552
1553 /******************************************************************************
1554 * GetAclInformation [ADVAPI32.@]
1555 */
1556 BOOL WINAPI GetAclInformation(
1557 PACL pAcl,
1558 LPVOID pAclInformation,
1559 DWORD nAclInformationLength,
1560 ACL_INFORMATION_CLASS dwAclInformationClass)
1561 {
1562 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1563 nAclInformationLength, dwAclInformationClass));
1564 }
1565
1566 /******************************************************************************
1567 * IsValidAcl [ADVAPI32.@]
1568 */
1569 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1570 {
1571 return RtlValidAcl(pAcl);
1572 }
1573
1574 /* ##############################
1575 ###### MISC FUNCTIONS ######
1576 ##############################
1577 */
1578
1579 /******************************************************************************
1580 * AllocateLocallyUniqueId [ADVAPI32.@]
1581 *
1582 * PARAMS
1583 * lpLuid []
1584 */
1585 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1586 {
1587 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1588 }
1589
1590 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1591 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1593 { '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 };
1594 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1595 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1597 { '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 };
1598 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1599 { '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 };
1600 static const WCHAR SE_TCB_NAME_W[] =
1601 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_SECURITY_NAME_W[] =
1603 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1605 { '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 };
1606 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1607 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1609 { '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 };
1610 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1611 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1613 { '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 };
1614 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1615 { '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 };
1616 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1617 { '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 };
1618 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1619 { '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 };
1620 static const WCHAR SE_BACKUP_NAME_W[] =
1621 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_RESTORE_NAME_W[] =
1623 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1625 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1626 static const WCHAR SE_DEBUG_NAME_W[] =
1627 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_AUDIT_NAME_W[] =
1629 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1631 { '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 };
1632 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1633 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1634 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1635 { '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 };
1636 static const WCHAR SE_UNDOCK_NAME_W[] =
1637 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1638 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1639 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1640 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1641 { '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 };
1642 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1643 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1644 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1645 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1647 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1648
1649 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1650 {
1651 NULL,
1652 NULL,
1653 SE_CREATE_TOKEN_NAME_W,
1654 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1655 SE_LOCK_MEMORY_NAME_W,
1656 SE_INCREASE_QUOTA_NAME_W,
1657 SE_MACHINE_ACCOUNT_NAME_W,
1658 SE_TCB_NAME_W,
1659 SE_SECURITY_NAME_W,
1660 SE_TAKE_OWNERSHIP_NAME_W,
1661 SE_LOAD_DRIVER_NAME_W,
1662 SE_SYSTEM_PROFILE_NAME_W,
1663 SE_SYSTEMTIME_NAME_W,
1664 SE_PROF_SINGLE_PROCESS_NAME_W,
1665 SE_INC_BASE_PRIORITY_NAME_W,
1666 SE_CREATE_PAGEFILE_NAME_W,
1667 SE_CREATE_PERMANENT_NAME_W,
1668 SE_BACKUP_NAME_W,
1669 SE_RESTORE_NAME_W,
1670 SE_SHUTDOWN_NAME_W,
1671 SE_DEBUG_NAME_W,
1672 SE_AUDIT_NAME_W,
1673 SE_SYSTEM_ENVIRONMENT_NAME_W,
1674 SE_CHANGE_NOTIFY_NAME_W,
1675 SE_REMOTE_SHUTDOWN_NAME_W,
1676 SE_UNDOCK_NAME_W,
1677 SE_SYNC_AGENT_NAME_W,
1678 SE_ENABLE_DELEGATION_NAME_W,
1679 SE_MANAGE_VOLUME_NAME_W,
1680 SE_IMPERSONATE_NAME_W,
1681 SE_CREATE_GLOBAL_NAME_W,
1682 };
1683
1684 /******************************************************************************
1685 * LookupPrivilegeValueW [ADVAPI32.@]
1686 *
1687 * See LookupPrivilegeValueA.
1688 */
1689 BOOL WINAPI
1690 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1691 {
1692 UINT i;
1693
1694 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1695
1696 if (!ADVAPI_IsLocalComputer(lpSystemName))
1697 {
1698 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1699 return FALSE;
1700 }
1701 if (!lpName)
1702 {
1703 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1704 return FALSE;
1705 }
1706 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1707 {
1708 if( !WellKnownPrivNames[i] )
1709 continue;
1710 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1711 continue;
1712 lpLuid->LowPart = i;
1713 lpLuid->HighPart = 0;
1714 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1715 lpLuid->HighPart, lpLuid->LowPart );
1716 return TRUE;
1717 }
1718 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1719 return FALSE;
1720 }
1721
1722 /******************************************************************************
1723 * LookupPrivilegeValueA [ADVAPI32.@]
1724 *
1725 * Retrieves LUID used on a system to represent the privilege name.
1726 *
1727 * PARAMS
1728 * lpSystemName [I] Name of the system
1729 * lpName [I] Name of the privilege
1730 * lpLuid [O] Destination for the resulting LUID
1731 *
1732 * RETURNS
1733 * Success: TRUE. lpLuid contains the requested LUID.
1734 * Failure: FALSE.
1735 */
1736 BOOL WINAPI
1737 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1738 {
1739 UNICODE_STRING lpSystemNameW;
1740 UNICODE_STRING lpNameW;
1741 BOOL ret;
1742
1743 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1744 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1745 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1746 RtlFreeUnicodeString(&lpNameW);
1747 RtlFreeUnicodeString(&lpSystemNameW);
1748 return ret;
1749 }
1750
1751 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1752 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1753 {
1754 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1755 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1756
1757 return FALSE;
1758 }
1759
1760 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1761 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1762 {
1763 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1764 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1765
1766 return FALSE;
1767 }
1768
1769 /******************************************************************************
1770 * LookupPrivilegeNameA [ADVAPI32.@]
1771 *
1772 * See LookupPrivilegeNameW.
1773 */
1774 BOOL WINAPI
1775 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1776 LPDWORD cchName)
1777 {
1778 UNICODE_STRING lpSystemNameW;
1779 BOOL ret;
1780 DWORD wLen = 0;
1781
1782 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1783
1784 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1785 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1786 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1787 {
1788 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1789
1790 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1791 &wLen);
1792 if (ret)
1793 {
1794 /* Windows crashes if cchName is NULL, so will I */
1795 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1796 *cchName, NULL, NULL);
1797
1798 if (len == 0)
1799 {
1800 /* WideCharToMultiByte failed */
1801 ret = FALSE;
1802 }
1803 else if (len > *cchName)
1804 {
1805 *cchName = len;
1806 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1807 ret = FALSE;
1808 }
1809 else
1810 {
1811 /* WideCharToMultiByte succeeded, output length needs to be
1812 * length not including NULL terminator
1813 */
1814 *cchName = len - 1;
1815 }
1816 }
1817 HeapFree(GetProcessHeap(), 0, lpNameW);
1818 }
1819 RtlFreeUnicodeString(&lpSystemNameW);
1820 return ret;
1821 }
1822
1823 /******************************************************************************
1824 * LookupPrivilegeNameW [ADVAPI32.@]
1825 *
1826 * Retrieves the privilege name referred to by the LUID lpLuid.
1827 *
1828 * PARAMS
1829 * lpSystemName [I] Name of the system
1830 * lpLuid [I] Privilege value
1831 * lpName [O] Name of the privilege
1832 * cchName [I/O] Number of characters in lpName.
1833 *
1834 * RETURNS
1835 * Success: TRUE. lpName contains the name of the privilege whose value is
1836 * *lpLuid.
1837 * Failure: FALSE.
1838 *
1839 * REMARKS
1840 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1841 * using this function.
1842 * If the length of lpName is too small, on return *cchName will contain the
1843 * number of WCHARs needed to contain the privilege, including the NULL
1844 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1845 * On success, *cchName will contain the number of characters stored in
1846 * lpName, NOT including the NULL terminator.
1847 */
1848 BOOL WINAPI
1849 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1850 LPDWORD cchName)
1851 {
1852 size_t privNameLen;
1853
1854 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1855
1856 if (!ADVAPI_IsLocalComputer(lpSystemName))
1857 {
1858 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1859 return FALSE;
1860 }
1861 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1862 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1863 {
1864 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1865 return FALSE;
1866 }
1867 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1868 /* Windows crashes if cchName is NULL, so will I */
1869 if (*cchName <= privNameLen)
1870 {
1871 *cchName = privNameLen + 1;
1872 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1873 return FALSE;
1874 }
1875 else
1876 {
1877 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1878 *cchName = privNameLen;
1879 return TRUE;
1880 }
1881 }
1882
1883 /******************************************************************************
1884 * GetFileSecurityA [ADVAPI32.@]
1885 *
1886 * Obtains Specified information about the security of a file or directory.
1887 *
1888 * PARAMS
1889 * lpFileName [I] Name of the file to get info for
1890 * RequestedInformation [I] SE_ flags from "winnt.h"
1891 * pSecurityDescriptor [O] Destination for security information
1892 * nLength [I] Length of pSecurityDescriptor
1893 * lpnLengthNeeded [O] Destination for length of returned security information
1894 *
1895 * RETURNS
1896 * Success: TRUE. pSecurityDescriptor contains the requested information.
1897 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1898 *
1899 * NOTES
1900 * The information returned is constrained by the callers access rights and
1901 * privileges.
1902 */
1903 BOOL WINAPI
1904 GetFileSecurityA( LPCSTR lpFileName,
1905 SECURITY_INFORMATION RequestedInformation,
1906 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1907 DWORD nLength, LPDWORD lpnLengthNeeded )
1908 {
1909 DWORD len;
1910 BOOL r;
1911 LPWSTR name = NULL;
1912
1913 if( lpFileName )
1914 {
1915 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1916 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1917 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1918 }
1919
1920 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1921 nLength, lpnLengthNeeded );
1922 HeapFree( GetProcessHeap(), 0, name );
1923
1924 return r;
1925 }
1926
1927 /******************************************************************************
1928 * GetFileSecurityW [ADVAPI32.@]
1929 *
1930 * See GetFileSecurityA.
1931 */
1932 BOOL WINAPI
1933 GetFileSecurityW( LPCWSTR lpFileName,
1934 SECURITY_INFORMATION RequestedInformation,
1935 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936 DWORD nLength, LPDWORD lpnLengthNeeded )
1937 {
1938 HANDLE hfile;
1939 NTSTATUS status;
1940 DWORD access = 0;
1941
1942 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1943 RequestedInformation, pSecurityDescriptor,
1944 nLength, lpnLengthNeeded);
1945
1946 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1947 DACL_SECURITY_INFORMATION))
1948 access |= READ_CONTROL;
1949 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1950 access |= ACCESS_SYSTEM_SECURITY;
1951
1952 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1953 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1954 if ( hfile == INVALID_HANDLE_VALUE )
1955 return FALSE;
1956
1957 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1958 nLength, lpnLengthNeeded );
1959 CloseHandle( hfile );
1960 return set_ntstatus( status );
1961 }
1962
1963
1964 /******************************************************************************
1965 * LookupAccountSidA [ADVAPI32.@]
1966 */
1967 BOOL WINAPI
1968 LookupAccountSidA(
1969 IN LPCSTR system,
1970 IN PSID sid,
1971 OUT LPSTR account,
1972 IN OUT LPDWORD accountSize,
1973 OUT LPSTR domain,
1974 IN OUT LPDWORD domainSize,
1975 OUT PSID_NAME_USE name_use )
1976 {
1977 DWORD len;
1978 BOOL r;
1979 LPWSTR systemW = NULL;
1980 LPWSTR accountW = NULL;
1981 LPWSTR domainW = NULL;
1982 DWORD accountSizeW = *accountSize;
1983 DWORD domainSizeW = *domainSize;
1984
1985 if (system) {
1986 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1987 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1988 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1989 }
1990 if (account)
1991 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1992 if (domain)
1993 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1994
1995 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1996
1997 if (r) {
1998 if (accountW && *accountSize) {
1999 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2000 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2001 *accountSize = len;
2002 } else
2003 *accountSize = accountSizeW + 1;
2004
2005 if (domainW && *domainSize) {
2006 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2007 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2008 *domainSize = len;
2009 } else
2010 *domainSize = domainSizeW + 1;
2011 }
2012
2013 HeapFree( GetProcessHeap(), 0, systemW );
2014 HeapFree( GetProcessHeap(), 0, accountW );
2015 HeapFree( GetProcessHeap(), 0, domainW );
2016
2017 return r;
2018 }
2019
2020 /******************************************************************************
2021 * LookupAccountSidW [ADVAPI32.@]
2022 *
2023 * PARAMS
2024 * system []
2025 * sid []
2026 * account []
2027 * accountSize []
2028 * domain []
2029 * domainSize []
2030 * name_use []
2031 */
2032
2033 BOOL WINAPI
2034 LookupAccountSidW(
2035 IN LPCWSTR system,
2036 IN PSID sid,
2037 OUT LPWSTR account,
2038 IN OUT LPDWORD accountSize,
2039 OUT LPWSTR domain,
2040 IN OUT LPDWORD domainSize,
2041 OUT PSID_NAME_USE name_use )
2042 {
2043 unsigned int i, j;
2044 const WCHAR * ac = NULL;
2045 const WCHAR * dm = NULL;
2046 SID_NAME_USE use = 0;
2047 LPWSTR computer_name = NULL;
2048 LPWSTR account_name = NULL;
2049
2050 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2051 debugstr_w(system),debugstr_sid(sid),
2052 account,accountSize,accountSize?*accountSize:0,
2053 domain,domainSize,domainSize?*domainSize:0,
2054 name_use);
2055
2056 if (!ADVAPI_IsLocalComputer(system)) {
2057 FIXME("Only local computer supported!\n");
2058 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2059 return FALSE;
2060 }
2061
2062 /* check the well known SIDs first */
2063 for (i = 0; i <= 60; i++) {
2064 if (IsWellKnownSid(sid, i)) {
2065 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2066 if (ACCOUNT_SIDS[j].type == i) {
2067 ac = ACCOUNT_SIDS[j].account;
2068 dm = ACCOUNT_SIDS[j].domain;
2069 use = ACCOUNT_SIDS[j].name_use;
2070 }
2071 }
2072 break;
2073 }
2074 }
2075
2076 if (dm == NULL) {
2077 MAX_SID local;
2078
2079 /* check for the local computer next */
2080 if (ADVAPI_GetComputerSid(&local)) {
2081 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2082 BOOL result;
2083
2084 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2085 result = GetComputerNameW(computer_name, &size);
2086
2087 if (result) {
2088 if (EqualSid(sid, &local)) {
2089 dm = computer_name;
2090 ac = Blank;
2091 use = 3;
2092 } else {
2093 local.SubAuthorityCount++;
2094
2095 if (EqualPrefixSid(sid, &local)) {
2096 dm = computer_name;
2097 use = 1;
2098 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2099 case DOMAIN_USER_RID_ADMIN:
2100 ac = Administrator;
2101 break;
2102 case DOMAIN_USER_RID_GUEST:
2103 ac = Guest;
2104 break;
2105 case DOMAIN_GROUP_RID_ADMINS:
2106 ac = Domain_Admins;
2107 break;
2108 case DOMAIN_GROUP_RID_USERS:
2109 ac = Domain_Users;
2110 break;
2111 case DOMAIN_GROUP_RID_GUESTS:
2112 ac = Domain_Guests;
2113 break;
2114 case DOMAIN_GROUP_RID_COMPUTERS:
2115 ac = Domain_Computers;
2116 break;
2117 case DOMAIN_GROUP_RID_CONTROLLERS:
2118 ac = Domain_Controllers;
2119 break;
2120 case DOMAIN_GROUP_RID_CERT_ADMINS:
2121 ac = Cert_Publishers;
2122 break;
2123 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2124 ac = Schema_Admins;
2125 break;
2126 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2127 ac = Enterprise_Admins;
2128 break;
2129 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2130 ac = Group_Policy_Creator_Owners;
2131 break;
2132 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2133 ac = RAS_and_IAS_Servers;
2134 break;
2135 case 1000: /* first user account */
2136 size = UNLEN + 1;
2137 account_name = HeapAlloc(
2138 GetProcessHeap(), 0, size * sizeof(WCHAR));
2139 if (GetUserNameW(account_name, &size))
2140 ac = account_name;
2141 else
2142 dm = NULL;
2143
2144 break;
2145 default:
2146 dm = NULL;
2147 break;
2148 }
2149 }
2150 }
2151 }
2152 }
2153 }
2154
2155 if (dm) {
2156 DWORD ac_len = lstrlenW(ac);
2157 DWORD dm_len = lstrlenW(dm);
2158 BOOL status = TRUE;
2159
2160 if (*accountSize > ac_len) {
2161 if (account)
2162 lstrcpyW(account, ac);
2163 }
2164 if (*domainSize > dm_len) {
2165 if (domain)
2166 lstrcpyW(domain, dm);
2167 }
2168 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2169 ((*domainSize != 0) && (*domainSize < dm_len))) {
2170 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2171 status = FALSE;
2172 }
2173 if (*domainSize)
2174 *domainSize = dm_len;
2175 else
2176 *domainSize = dm_len + 1;
2177 if (*accountSize)
2178 *accountSize = ac_len;
2179 else
2180 *accountSize = ac_len + 1;
2181 *name_use = use;
2182 HeapFree(GetProcessHeap(), 0, account_name);
2183 HeapFree(GetProcessHeap(), 0, computer_name);
2184 return status;
2185 }
2186
2187 HeapFree(GetProcessHeap(), 0, account_name);
2188 HeapFree(GetProcessHeap(), 0, computer_name);
2189 SetLastError(ERROR_NONE_MAPPED);
2190 return FALSE;
2191 }
2192
2193 /******************************************************************************
2194 * SetFileSecurityA [ADVAPI32.@]
2195 *
2196 * See SetFileSecurityW.
2197 */
2198 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2199 SECURITY_INFORMATION RequestedInformation,
2200 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2201 {
2202 DWORD len;
2203 BOOL r;
2204 LPWSTR name = NULL;
2205
2206 if( lpFileName )
2207 {
2208 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2209 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2210 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2211 }
2212
2213 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2214 HeapFree( GetProcessHeap(), 0, name );
2215
2216 return r;
2217 }
2218
2219 /******************************************************************************
2220 * SetFileSecurityW [ADVAPI32.@]
2221 *
2222 * Sets the security of a file or directory.
2223 *
2224 * PARAMS
2225 * lpFileName []
2226 * RequestedInformation []
2227 * pSecurityDescriptor []
2228 *
2229 * RETURNS
2230 * Success: TRUE.
2231 * Failure: FALSE.
2232 */
2233 BOOL WINAPI
2234 SetFileSecurityW( LPCWSTR lpFileName,
2235 SECURITY_INFORMATION RequestedInformation,
2236 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2237 {
2238 HANDLE file;
2239 DWORD access = 0;
2240 NTSTATUS status;
2241
2242 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2243 pSecurityDescriptor );
2244
2245 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2246 RequestedInformation & GROUP_SECURITY_INFORMATION)
2247 access |= WRITE_OWNER;
2248 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2249 access |= ACCESS_SYSTEM_SECURITY;
2250 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2251 access |= WRITE_DAC;
2252
2253 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2254 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2255 if (file == INVALID_HANDLE_VALUE)
2256 return FALSE;
2257
2258 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2259 CloseHandle( file );
2260 return set_ntstatus( status );
2261 }
2262
2263 /******************************************************************************
2264 * QueryWindows31FilesMigration [ADVAPI32.@]
2265 *
2266 * PARAMS
2267 * x1 []
2268 */
2269 BOOL WINAPI
2270 QueryWindows31FilesMigration( DWORD x1 )
2271 {
2272 FIXME("(%d):stub\n",x1);
2273 return TRUE;
2274 }
2275
2276 /******************************************************************************
2277 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2278 *
2279 * PARAMS
2280 * x1 []
2281 * x2 []
2282 * x3 []
2283 * x4 []
2284 */
2285 BOOL WINAPI
2286 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2287 DWORD x4 )
2288 {
2289 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2290 return TRUE;
2291 }
2292
2293 /******************************************************************************
2294 * NotifyBootConfigStatus [ADVAPI32.@]
2295 *
2296 * PARAMS
2297 * x1 []
2298 */
2299 BOOL WINAPI
2300 NotifyBootConfigStatus( BOOL x1 )
2301 {
2302 FIXME("(0x%08d):stub\n",x1);
2303 return 1;
2304 }
2305
2306 /******************************************************************************
2307 * RevertToSelf [ADVAPI32.@]
2308 *
2309 * Ends the impersonation of a user.
2310 *
2311 * PARAMS
2312 * void []
2313 *
2314 * RETURNS
2315 * Success: TRUE.
2316 * Failure: FALSE.
2317 */
2318 BOOL WINAPI
2319 RevertToSelf( void )
2320 {
2321 HANDLE Token = NULL;
2322 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2323 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2324 }
2325
2326 /******************************************************************************
2327 * ImpersonateSelf [ADVAPI32.@]
2328 *
2329 * Makes an impersonation token that represents the process user and assigns
2330 * to the current thread.
2331 *
2332 * PARAMS
2333 * ImpersonationLevel [I] Level at which to impersonate.
2334 *
2335 * RETURNS
2336 * Success: TRUE.
2337 * Failure: FALSE.
2338 */
2339 BOOL WINAPI
2340 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2341 {
2342 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2343 }
2344
2345 /******************************************************************************
2346 * ImpersonateLoggedOnUser [ADVAPI32.@]
2347 */
2348 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2349 {
2350 DWORD size;
2351 NTSTATUS Status;
2352 HANDLE ImpersonationToken;
2353 TOKEN_TYPE Type;
2354 static BOOL warn = TRUE;
2355
2356 if (warn)
2357 {
2358 FIXME( "(%p)\n", hToken );
2359 warn = FALSE;
2360 }
2361 if (!GetTokenInformation( hToken, TokenType, &Type,
2362 sizeof(TOKEN_TYPE), &size ))
2363 return FALSE;
2364
2365 if (Type == TokenPrimary)
2366 {
2367 OBJECT_ATTRIBUTES ObjectAttributes;
2368
2369 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2370
2371 Status = NtDuplicateToken( hToken,
2372 TOKEN_IMPERSONATE | TOKEN_QUERY,
2373 &ObjectAttributes,
2374 SecurityImpersonation,
2375 TokenImpersonation,
2376 &ImpersonationToken );
2377 if (Status != STATUS_SUCCESS)
2378 {
2379 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2380 SetLastError( RtlNtStatusToDosError( Status ) );
2381 return FALSE;
2382 }
2383 }
2384 else
2385 ImpersonationToken = hToken;
2386
2387 Status = NtSetInformationThread( GetCurrentThread(),
2388 ThreadImpersonationToken,
2389 &ImpersonationToken,
2390 sizeof(ImpersonationToken) );
2391
2392 if (Type == TokenPrimary)
2393 NtClose( ImpersonationToken );
2394
2395 if (Status != STATUS_SUCCESS)
2396 {
2397 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2398 SetLastError( RtlNtStatusToDosError( Status ) );
2399 return FALSE;
2400 }
2401
2402 return TRUE;
2403 }
2404
2405 /******************************************************************************
2406 * AccessCheck [ADVAPI32.@]
2407 */
2408 BOOL WINAPI
2409 AccessCheck(
2410 PSECURITY_DESCRIPTOR SecurityDescriptor,
2411 HANDLE ClientToken,
2412 DWORD DesiredAccess,
2413 PGENERIC_MAPPING GenericMapping,
2414 PPRIVILEGE_SET PrivilegeSet,
2415 LPDWORD PrivilegeSetLength,
2416 LPDWORD GrantedAccess,
2417 LPBOOL AccessStatus)
2418 {
2419 NTSTATUS access_status;
2420 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2421 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2422 GrantedAccess, &access_status) );
2423 if (ret) *AccessStatus = set_ntstatus( access_status );
2424 return ret;
2425 }
2426
2427
2428 /******************************************************************************
2429 * AccessCheckByType [ADVAPI32.@]
2430 */
2431 BOOL WINAPI AccessCheckByType(
2432 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2433 PSID PrincipalSelfSid,
2434 HANDLE ClientToken,
2435 DWORD DesiredAccess,
2436 POBJECT_TYPE_LIST ObjectTypeList,
2437 DWORD ObjectTypeListLength,
2438 PGENERIC_MAPPING GenericMapping,
2439 PPRIVILEGE_SET PrivilegeSet,
2440 LPDWORD PrivilegeSetLength,
2441 LPDWORD GrantedAccess,
2442 LPBOOL AccessStatus)
2443 {
2444 FIXME("stub\n");
2445
2446 *AccessStatus = TRUE;
2447
2448 return !*AccessStatus;
2449 }
2450
2451 /******************************************************************************
2452 * MapGenericMask [ADVAPI32.@]
2453 *
2454 * Maps generic access rights into specific access rights according to the
2455 * supplied mapping.
2456 *
2457 * PARAMS
2458 * AccessMask [I/O] Access rights.
2459 * GenericMapping [I] The mapping between generic and specific rights.
2460 *
2461 * RETURNS
2462 * Nothing.
2463 */
2464 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2465 {
2466 RtlMapGenericMask( AccessMask, GenericMapping );
2467 }
2468
2469 /*************************************************************************
2470 * SetKernelObjectSecurity [ADVAPI32.@]
2471 */
2472 BOOL WINAPI SetKernelObjectSecurity (
2473 IN HANDLE Handle,
2474 IN SECURITY_INFORMATION SecurityInformation,
2475 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2476 {
2477 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2478 }
2479
2480
2481 /******************************************************************************
2482 * AddAuditAccessAce [ADVAPI32.@]
2483 */
2484 BOOL WINAPI AddAuditAccessAce(
2485 IN OUT PACL pAcl,
2486 IN DWORD dwAceRevision,
2487 IN DWORD dwAccessMask,
2488 IN PSID pSid,
2489 IN BOOL bAuditSuccess,
2490 IN BOOL bAuditFailure)
2491 {
2492 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2493 bAuditSuccess, bAuditFailure) );
2494 }
2495
2496 /******************************************************************************
2497 * AddAuditAccessAce [ADVAPI32.@]
2498 */
2499 BOOL WINAPI AddAuditAccessAceEx(
2500 IN OUT PACL pAcl,
2501 IN DWORD dwAceRevision,
2502 IN DWORD dwAceFlags,
2503 IN DWORD dwAccessMask,
2504 IN PSID pSid,
2505 IN BOOL bAuditSuccess,
2506 IN BOOL bAuditFailure)
2507 {
2508 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2509 bAuditSuccess, bAuditFailure) );
2510 }
2511
2512 /******************************************************************************
2513 * LookupAccountNameA [ADVAPI32.@]
2514 */
2515 BOOL WINAPI
2516 LookupAccountNameA(
2517 IN LPCSTR system,
2518 IN LPCSTR account,
2519 OUT PSID sid,
2520 OUT LPDWORD cbSid,
2521 LPSTR ReferencedDomainName,
2522 IN OUT LPDWORD cbReferencedDomainName,
2523 OUT PSID_NAME_USE name_use )
2524 {
2525 BOOL ret;
2526 UNICODE_STRING lpSystemW;
2527 UNICODE_STRING lpAccountW;
2528 LPWSTR lpReferencedDomainNameW = NULL;
2529
2530 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2531 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2532
2533 if (ReferencedDomainName)
2534 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2535
2536 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2537 cbReferencedDomainName, name_use);
2538
2539 if (ret && lpReferencedDomainNameW)
2540 {
2541 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2542 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2543 }
2544
2545 RtlFreeUnicodeString(&lpSystemW);
2546 RtlFreeUnicodeString(&lpAccountW);
2547 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2548
2549 return ret;
2550 }
2551
2552 /******************************************************************************
2553 * lookup_user_account_name
2554 */
2555 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2556 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2557 {
2558 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2559 DWORD len = sizeof(buffer);
2560 HANDLE token;
2561 BOOL ret;
2562 PSID pSid;
2563 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2564 DWORD nameLen;
2565 LPCWSTR domainName;
2566
2567 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2568 {
2569 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2570 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2571 }
2572
2573 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2574 CloseHandle( token );
2575
2576 if (!ret) return FALSE;
2577
2578 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2579
2580 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2581 CopySid(*cbSid, Sid, pSid);
2582 if (*cbSid < GetLengthSid(pSid))
2583 {
2584 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2585 ret = FALSE;
2586 }
2587 *cbSid = GetLengthSid(pSid);
2588
2589 domainName = dm;
2590 nameLen = strlenW(domainName);
2591
2592 if (*cchReferencedDomainName <= nameLen || !ret)
2593 {
2594 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2595 nameLen += 1;
2596 ret = FALSE;
2597 }
2598 else if (ReferencedDomainName)
2599 strcpyW(ReferencedDomainName, domainName);
2600
2601 *cchReferencedDomainName = nameLen;
2602
2603 if (ret)
2604 *peUse = SidTypeUser;
2605
2606 return ret;
2607 }
2608
2609 /******************************************************************************
2610 * lookup_computer_account_name
2611 */
2612 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2613 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2614 {
2615 MAX_SID local;
2616 BOOL ret;
2617 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2618 DWORD nameLen;
2619 LPCWSTR domainName;
2620
2621 if ((ret = ADVAPI_GetComputerSid(&local)))
2622 {
2623 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2624 CopySid(*cbSid, Sid, &local);
2625 if (*cbSid < GetLengthSid(&local))
2626 {
2627 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2628 ret = FALSE;
2629 }
2630 *cbSid = GetLengthSid(&local);
2631 }
2632
2633 domainName = dm;
2634 nameLen = strlenW(domainName);
2635
2636 if (*cchReferencedDomainName <= nameLen || !ret)
2637 {
2638 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2639 nameLen += 1;
2640 ret = FALSE;
2641 }
2642 else if (ReferencedDomainName)
2643 strcpyW(ReferencedDomainName, domainName);
2644
2645 *cchReferencedDomainName = nameLen;
2646
2647 if (ret)
2648 *peUse = SidTypeDomain;
2649
2650 return ret;
2651 }
2652
2653 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2654 LSA_UNICODE_STRING *domain )
2655 {
2656 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2657
2658 while (p > str->Buffer && *p != '\\') p--;
2659
2660 if (*p == '\\')
2661 {
2662 domain->Buffer = str->Buffer;
2663 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2664
2665 account->Buffer = p + 1;
2666 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2667 }
2668 else
2669 {
2670 domain->Buffer = NULL;
2671 domain->Length = 0;
2672
2673 account->Buffer = str->Buffer;
2674 account->Length = str->Length;
2675 }
2676 }
2677
2678 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2679 {
2680 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2681
2682 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2683 return TRUE;
2684
2685 return FALSE;
2686 }
2687
2688 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2689 {
2690 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2691
2692 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2693 return TRUE;
2694
2695 if (ACCOUNT_SIDS[idx].alias)
2696 {
2697 len = strlenW( ACCOUNT_SIDS[idx].alias );
2698 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2699 return TRUE;
2700 }
2701 return FALSE;
2702 }
2703
2704 /*
2705 * Helper function for LookupAccountNameW
2706 */
2707 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2708 PSID Sid, LPDWORD cbSid,
2709 LPWSTR ReferencedDomainName,
2710 LPDWORD cchReferencedDomainName,
2711 PSID_NAME_USE peUse, BOOL *handled )
2712 {
2713 PSID pSid;
2714 LSA_UNICODE_STRING account, domain;
2715 BOOL ret = TRUE;
2716 ULONG i;
2717
2718 *handled = FALSE;
2719 split_domain_account( account_and_domain, &account, &domain );
2720
2721 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2722 {
2723 /* check domain first */
2724 if (domain.Buffer && !match_domain( i, &domain )) continue;
2725
2726 if (match_account( i, &account ))
2727 {
2728 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2729
2730 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2731
2732 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2733 {
2734 if (*cbSid < sidLen)
2735 {
2736 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2737 ret = FALSE;
2738 }
2739 else if (Sid)
2740 {
2741 CopySid(*cbSid, Sid, pSid);
2742 }
2743 *cbSid = sidLen;
2744 }
2745
2746 len = strlenW( ACCOUNT_SIDS[i].domain );
2747 if (*cchReferencedDomainName <= len || !ret)
2748 {
2749 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2750 len++;
2751 ret = FALSE;
2752 }
2753 else if (ReferencedDomainName)
2754 {
2755 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2756 }
2757
2758 *cchReferencedDomainName = len;
2759 if (ret)
2760 *peUse = ACCOUNT_SIDS[i].name_use;
2761
2762 HeapFree(GetProcessHeap(), 0, pSid);
2763 *handled = TRUE;
2764 return ret;
2765 }
2766 }
2767 return ret;
2768 }
2769
2770 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2771 PSID Sid, LPDWORD cbSid,
2772 LPWSTR ReferencedDomainName,
2773 LPDWORD cchReferencedDomainName,
2774 PSID_NAME_USE peUse, BOOL *handled )
2775 {
2776 DWORD nameLen;
2777 LPWSTR userName = NULL;
2778 LSA_UNICODE_STRING account, domain;
2779 BOOL ret = TRUE;
2780
2781 *handled = FALSE;
2782 split_domain_account( account_and_domain, &account, &domain );
2783
2784 /* Let the current Unix user id masquerade as first Windows user account */
2785
2786 nameLen = UNLEN + 1;
2787 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2788
2789 if (domain.Buffer)
2790 {
2791 /* check to make sure this account is on this computer */
2792 if (GetComputerNameW( userName, &nameLen ) &&
2793 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2794 {
2795 SetLastError(ERROR_NONE_MAPPED);
2796 ret = FALSE;
2797 }
2798 nameLen = UNLEN + 1;
2799 }
2800
2801 if (GetUserNameW( userName, &nameLen ) &&
2802 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2803 {
2804 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2805 *handled = TRUE;
2806 }
2807 else
2808 {
2809 nameLen = UNLEN + 1;
2810 if (GetComputerNameW( userName, &nameLen ) &&
2811 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2812 {
2813 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2814 *handled = TRUE;
2815 }
2816 }
2817
2818 HeapFree(GetProcessHeap(), 0, userName);
2819 return ret;
2820 }
2821
2822 /******************************************************************************
2823 * LookupAccountNameW [ADVAPI32.@]
2824 */
2825 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2826 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2827 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2828 {
2829 BOOL ret, handled;
2830 LSA_UNICODE_STRING account;
2831
2832 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2833 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2834
2835 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2836 {
2837 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2838 return FALSE;
2839 }
2840
2841 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2842 {
2843 lpAccountName = BUILTIN;
2844 }
2845
2846 RtlInitUnicodeString( &account, lpAccountName );
2847
2848 /* Check well known SIDs first */
2849 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2850 cchReferencedDomainName, peUse, &handled );
2851 if (handled)
2852 return ret;
2853
2854 /* Check user names */
2855 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2856 cchReferencedDomainName, peUse, &handled);
2857 if (handled)
2858 return ret;
2859
2860 SetLastError( ERROR_NONE_MAPPED );
2861 return FALSE;
2862 }
2863
2864 /******************************************************************************
2865 * PrivilegeCheck [ADVAPI32.@]
2866 */
2867 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2868 {
2869 BOOL ret;
2870 BOOLEAN Result;
2871
2872 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2873
2874 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2875 if (ret)
2876 *pfResult = Result;
2877 return ret;
2878 }
2879
2880 /******************************************************************************
2881 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2882 */
2883 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2884 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2885 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2886 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2887 {
2888 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2889 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2890 SecurityDescriptor, DesiredAccess, GenericMapping,
2891 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2892 return TRUE;
2893 }
2894
2895 /******************************************************************************
2896 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2897 */
2898 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2899 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2900 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2901 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2902 {
2903 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2904 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2905 SecurityDescriptor, DesiredAccess, GenericMapping,
2906 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2907 return TRUE;
2908 }
2909
2910 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2911 {
2912 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2913
2914 return TRUE;
2915 }
2916
2917 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2918 {
2919 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2920
2921 return TRUE;
2922 }
2923
2924 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2925 {
2926 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2927
2928 return TRUE;
2929 }
2930
2931 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2932 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2933 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2934 LPBOOL GenerateOnClose)
2935 {
2936 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2937 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2938 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2939 GenerateOnClose);
2940
2941 return TRUE;
2942 }
2943
2944 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2945 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2946 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2947 LPBOOL GenerateOnClose)
2948 {
2949 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2950 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2951 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2952 GenerateOnClose);
2953
2954 return TRUE;
2955 }
2956
2957 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2958 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2959 {
2960 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2961 DesiredAccess, Privileges, AccessGranted);
2962
2963 return TRUE;
2964 }
2965
2966 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2967 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2968 {
2969 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2970 DesiredAccess, Privileges, AccessGranted);
2971
2972 return TRUE;
2973 }
2974
2975 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2976 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2977 {
2978 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2979 ClientToken, Privileges, AccessGranted);
2980
2981 return TRUE;
2982 }
2983
2984 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2985 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2986 {
2987 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2988 ClientToken, Privileges, AccessGranted);
2989
2990 return TRUE;
2991 }
2992
2993 /******************************************************************************
2994 * GetSecurityInfo [ADVAPI32.@]
2995 *
2996 * Retrieves a copy of the security descriptor associated with an object.
2997 *
2998 * PARAMS
2999 * hObject [I] A handle for the object.
3000 * ObjectType [I] The type of object.
3001 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3002 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3003 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3004 * ppDacl [O] If non-null, receives a pointer to the DACL.
3005 * ppSacl [O] If non-null, receives a pointer to the SACL.
3006 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3007 * which must be freed with LocalFree.
3008 *
3009 * RETURNS
3010 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3011 */
3012 DWORD WINAPI GetSecurityInfo(
3013 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3014 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3015 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3016 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3017 )
3018 {
3019 PSECURITY_DESCRIPTOR sd;
3020 NTSTATUS status;
3021 ULONG n1, n2;
3022 BOOL present, defaulted;
3023
3024 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3025 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3026 return RtlNtStatusToDosError(status);
3027
3028 sd = LocalAlloc(0, n1);
3029 if (!sd)
3030 return ERROR_NOT_ENOUGH_MEMORY;
3031
3032 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3033 if (status != STATUS_SUCCESS)
3034 {
3035 LocalFree(sd);
3036 return RtlNtStatusToDosError(status);
3037 }
3038
3039 if (ppsidOwner)
3040 {
3041 *ppsidOwner = NULL;
3042 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3043 }
3044 if (ppsidGroup)
3045 {
3046 *ppsidGroup = NULL;
3047 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3048 }
3049 if (ppDacl)
3050 {
3051 *ppDacl = NULL;
3052 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3053 }
3054 if (ppSacl)
3055 {
3056 *ppSacl = NULL;
3057 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3058 }
3059 if (ppSecurityDescriptor)
3060 *ppSecurityDescriptor = sd;
3061
3062 return ERROR_SUCCESS;
3063 }
3064
3065 /******************************************************************************
3066 * GetSecurityInfoExA [ADVAPI32.@]
3067 */
3068 DWORD WINAPI GetSecurityInfoExA(
3069 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3070 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3071 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3072 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3073 )
3074 {
3075 FIXME("stub!\n");
3076 return ERROR_BAD_PROVIDER;
3077 }
3078
3079 /******************************************************************************
3080 * GetSecurityInfoExW [ADVAPI32.@]
3081 */
3082 DWORD WINAPI GetSecurityInfoExW(
3083 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3084 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3085 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3086 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3087 )
3088 {
3089 FIXME("stub!\n");
3090 return ERROR_BAD_PROVIDER;
3091 }
3092
3093 /******************************************************************************
3094 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3095 */
3096 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3097 LPSTR pTrusteeName, DWORD AccessPermissions,
3098 ACCESS_MODE AccessMode, DWORD Inheritance )
3099 {
3100 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3101 AccessPermissions, AccessMode, Inheritance);
3102
3103 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3104 pExplicitAccess->grfAccessMode = AccessMode;
3105 pExplicitAccess->grfInheritance = Inheritance;
3106
3107 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3108 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3109 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3110 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3111 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3112 }
3113
3114 /******************************************************************************
3115 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3116 */
3117 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3118 LPWSTR pTrusteeName, DWORD AccessPermissions,
3119 ACCESS_MODE AccessMode, DWORD Inheritance )
3120 {
3121 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3122 AccessPermissions, AccessMode, Inheritance);
3123
3124 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3125 pExplicitAccess->grfAccessMode = AccessMode;
3126 pExplicitAccess->grfInheritance = Inheritance;
3127
3128 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3129 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3130 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3131 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3132 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3133 }
3134
3135 /******************************************************************************
3136 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3137 */
3138 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3139 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3140 LPSTR InheritedObjectTypeName, LPSTR Name )
3141 {
3142 DWORD ObjectsPresent = 0;
3143
3144 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3145 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3146
3147 /* Fill the OBJECTS_AND_NAME structure */
3148 pObjName->ObjectType = ObjectType;
3149 if (ObjectTypeName != NULL)
3150 {
3151 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3152 }
3153
3154 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3155 if (InheritedObjectTypeName != NULL)
3156 {
3157 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3158 }
3159
3160 pObjName->ObjectsPresent = ObjectsPresent;
3161 pObjName->ptstrName = Name;
3162
3163 /* Fill the TRUSTEE structure */
3164 pTrustee->pMultipleTrustee = NULL;
3165 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3166 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3167 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3168 pTrustee->ptstrName = (LPSTR)pObjName;
3169 }
3170
3171 /******************************************************************************
3172 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3173 */
3174 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3175 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3176 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3177 {
3178 DWORD ObjectsPresent = 0;
3179
3180 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3181 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3182
3183 /* Fill the OBJECTS_AND_NAME structure */
3184 pObjName->ObjectType = ObjectType;
3185 if (ObjectTypeName !=