advapi32: Return a fake security descriptor from CreatePrivateObjectSecurity.
[wine/multimedia.git] / dlls / advapi32 / security.c
blob9df27dbd5fb3e585d4af3a76713c410f6496ad6a
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
216 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
223 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 BOOL ADVAPI_GetComputerSid(PSID sid)
452 static const struct /* same fields as struct SID */
454 BYTE Revision;
455 BYTE SubAuthorityCount;
456 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
457 DWORD SubAuthority[4];
458 } computer_sid =
459 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
461 memcpy( sid, &computer_sid, sizeof(computer_sid) );
462 return TRUE;
465 /* ##############################
466 ###### TOKEN FUNCTIONS ######
467 ##############################
470 /******************************************************************************
471 * OpenProcessToken [ADVAPI32.@]
472 * Opens the access token associated with a process handle.
474 * PARAMS
475 * ProcessHandle [I] Handle to process
476 * DesiredAccess [I] Desired access to process
477 * TokenHandle [O] Pointer to handle of open access token
479 * RETURNS
480 * Success: TRUE. TokenHandle contains the access token.
481 * Failure: FALSE.
483 * NOTES
484 * See NtOpenProcessToken.
486 BOOL WINAPI
487 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
488 HANDLE *TokenHandle )
490 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
493 /******************************************************************************
494 * OpenThreadToken [ADVAPI32.@]
496 * Opens the access token associated with a thread handle.
498 * PARAMS
499 * ThreadHandle [I] Handle to process
500 * DesiredAccess [I] Desired access to the thread
501 * OpenAsSelf [I] ???
502 * TokenHandle [O] Destination for the token handle
504 * RETURNS
505 * Success: TRUE. TokenHandle contains the access token.
506 * Failure: FALSE.
508 * NOTES
509 * See NtOpenThreadToken.
511 BOOL WINAPI
512 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
513 BOOL OpenAsSelf, HANDLE *TokenHandle)
515 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
518 BOOL WINAPI
519 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
520 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
522 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
523 PreviousState, ReturnLength));
526 /******************************************************************************
527 * AdjustTokenPrivileges [ADVAPI32.@]
529 * Adjust the privileges of an open token handle.
531 * PARAMS
532 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
533 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
534 * NewState [I] Desired new privileges of the token
535 * BufferLength [I] Length of NewState
536 * PreviousState [O] Destination for the previous state
537 * ReturnLength [I/O] Size of PreviousState
540 * RETURNS
541 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
542 * Failure: FALSE.
544 * NOTES
545 * See NtAdjustPrivilegesToken.
547 BOOL WINAPI
548 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
549 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
550 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
552 NTSTATUS status;
554 TRACE("\n");
556 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
557 NewState, BufferLength, PreviousState,
558 ReturnLength);
559 SetLastError( RtlNtStatusToDosError( status ));
560 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
561 return TRUE;
562 else
563 return FALSE;
566 /******************************************************************************
567 * CheckTokenMembership [ADVAPI32.@]
569 * Determine if an access token is a member of a SID.
571 * PARAMS
572 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573 * SidToCheck [I] SID that possibly contains the token
574 * IsMember [O] Destination for result.
576 * RETURNS
577 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
578 * Failure: FALSE.
580 BOOL WINAPI
581 CheckTokenMembership( HANDLE token, PSID sid_to_check,
582 PBOOL is_member )
584 PTOKEN_GROUPS token_groups = NULL;
585 HANDLE thread_token = NULL;
586 DWORD size, i;
587 BOOL ret;
589 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
591 *is_member = FALSE;
593 if (!token)
595 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
597 HANDLE process_token;
598 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
599 if (!ret)
600 goto exit;
601 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
602 NULL, SecurityImpersonation, TokenImpersonation,
603 &thread_token);
604 CloseHandle(process_token);
605 if (!ret)
606 goto exit;
608 token = thread_token;
610 else
612 TOKEN_TYPE type;
614 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
615 if (!ret) goto exit;
617 if (type == TokenPrimary)
619 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
620 return FALSE;
624 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
625 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
626 goto exit;
628 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
629 if (!token_groups)
631 ret = FALSE;
632 goto exit;
635 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
636 if (!ret)
637 goto exit;
639 for (i = 0; i < token_groups->GroupCount; i++)
641 TRACE("Groups[%d]: {0x%x, %s}\n", i,
642 token_groups->Groups[i].Attributes,
643 debugstr_sid(token_groups->Groups[i].Sid));
644 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
645 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
647 *is_member = TRUE;
648 TRACE("sid enabled and found in token\n");
649 break;
653 exit:
654 HeapFree(GetProcessHeap(), 0, token_groups);
655 if (thread_token != NULL) CloseHandle(thread_token);
657 return ret;
660 /******************************************************************************
661 * GetTokenInformation [ADVAPI32.@]
663 * Get a type of information about an access token.
665 * PARAMS
666 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
667 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
668 * tokeninfo [O] Destination for token information
669 * tokeninfolength [I] Length of tokeninfo
670 * retlen [O] Destination for returned token information length
672 * RETURNS
673 * Success: TRUE. tokeninfo contains retlen bytes of token information
674 * Failure: FALSE.
676 * NOTES
677 * See NtQueryInformationToken.
679 BOOL WINAPI
680 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
681 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
683 TRACE("(%p, %s, %p, %d, %p):\n",
684 token,
685 (tokeninfoclass == TokenUser) ? "TokenUser" :
686 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
687 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
688 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
689 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
690 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
691 (tokeninfoclass == TokenSource) ? "TokenSource" :
692 (tokeninfoclass == TokenType) ? "TokenType" :
693 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
694 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
695 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
696 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
697 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
698 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
699 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
700 "Unknown",
701 tokeninfo, tokeninfolength, retlen);
702 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
703 tokeninfolength, retlen));
706 /******************************************************************************
707 * SetTokenInformation [ADVAPI32.@]
709 * Set information for an access token.
711 * PARAMS
712 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
713 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
714 * tokeninfo [I] Token information to set
715 * tokeninfolength [I] Length of tokeninfo
717 * RETURNS
718 * Success: TRUE. The information for the token is set to tokeninfo.
719 * Failure: FALSE.
721 BOOL WINAPI
722 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
723 LPVOID tokeninfo, DWORD tokeninfolength )
725 TRACE("(%p, %s, %p, %d): stub\n",
726 token,
727 (tokeninfoclass == TokenUser) ? "TokenUser" :
728 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
729 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
730 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
731 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
732 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
733 (tokeninfoclass == TokenSource) ? "TokenSource" :
734 (tokeninfoclass == TokenType) ? "TokenType" :
735 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
736 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
737 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
738 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
739 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
740 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
741 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
742 "Unknown",
743 tokeninfo, tokeninfolength);
745 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
748 /*************************************************************************
749 * SetThreadToken [ADVAPI32.@]
751 * Assigns an 'impersonation token' to a thread so it can assume the
752 * security privileges of another thread or process. Can also remove
753 * a previously assigned token.
755 * PARAMS
756 * thread [O] Handle to thread to set the token for
757 * token [I] Token to set
759 * RETURNS
760 * Success: TRUE. The threads access token is set to token
761 * Failure: FALSE.
763 * NOTES
764 * Only supported on NT or higher. On Win9X this function does nothing.
765 * See SetTokenInformation.
767 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
769 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
770 ThreadImpersonationToken, &token, sizeof token ));
773 /*************************************************************************
774 * CreateRestrictedToken [ADVAPI32.@]
776 * Create a new more restricted token from an existing token.
778 * PARAMS
779 * baseToken [I] Token to base the new restricted token on
780 * flags [I] Options
781 * nDisableSids [I] Length of disableSids array
782 * disableSids [I] Array of SIDs to disable in the new token
783 * nDeletePrivs [I] Length of deletePrivs array
784 * deletePrivs [I] Array of privileges to delete in the new token
785 * nRestrictSids [I] Length of restrictSids array
786 * restrictSids [I] Array of SIDs to restrict in the new token
787 * newToken [O] Address where the new token is stored
789 * RETURNS
790 * Success: TRUE
791 * Failure: FALSE
793 BOOL WINAPI CreateRestrictedToken(
794 HANDLE baseToken,
795 DWORD flags,
796 DWORD nDisableSids,
797 PSID_AND_ATTRIBUTES disableSids,
798 DWORD nDeletePrivs,
799 PLUID_AND_ATTRIBUTES deletePrivs,
800 DWORD nRestrictSids,
801 PSID_AND_ATTRIBUTES restrictSids,
802 PHANDLE newToken)
804 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
805 baseToken, flags, nDisableSids, disableSids,
806 nDeletePrivs, deletePrivs,
807 nRestrictSids, restrictSids,
808 newToken);
809 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
810 return FALSE;
813 /* ##############################
814 ###### SID FUNCTIONS ######
815 ##############################
818 /******************************************************************************
819 * AllocateAndInitializeSid [ADVAPI32.@]
821 * PARAMS
822 * pIdentifierAuthority []
823 * nSubAuthorityCount []
824 * nSubAuthority0 []
825 * nSubAuthority1 []
826 * nSubAuthority2 []
827 * nSubAuthority3 []
828 * nSubAuthority4 []
829 * nSubAuthority5 []
830 * nSubAuthority6 []
831 * nSubAuthority7 []
832 * pSid []
834 BOOL WINAPI
835 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
836 BYTE nSubAuthorityCount,
837 DWORD nSubAuthority0, DWORD nSubAuthority1,
838 DWORD nSubAuthority2, DWORD nSubAuthority3,
839 DWORD nSubAuthority4, DWORD nSubAuthority5,
840 DWORD nSubAuthority6, DWORD nSubAuthority7,
841 PSID *pSid )
843 return set_ntstatus( RtlAllocateAndInitializeSid(
844 pIdentifierAuthority, nSubAuthorityCount,
845 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
846 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
847 pSid ));
850 /******************************************************************************
851 * FreeSid [ADVAPI32.@]
853 * PARAMS
854 * pSid []
856 PVOID WINAPI
857 FreeSid( PSID pSid )
859 RtlFreeSid(pSid);
860 return NULL; /* is documented like this */
863 /******************************************************************************
864 * CopySid [ADVAPI32.@]
866 * PARAMS
867 * nDestinationSidLength []
868 * pDestinationSid []
869 * pSourceSid []
871 BOOL WINAPI
872 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
874 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
877 /******************************************************************************
878 * CreateWellKnownSid [ADVAPI32.@]
880 BOOL WINAPI
881 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
882 PSID DomainSid,
883 PSID pSid,
884 DWORD* cbSid)
886 unsigned int i;
887 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
889 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
891 SetLastError(ERROR_INVALID_PARAMETER);
892 return FALSE;
895 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
896 if (WellKnownSids[i].Type == WellKnownSidType) {
897 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
899 if (*cbSid < length)
901 *cbSid = length;
902 SetLastError(ERROR_INSUFFICIENT_BUFFER);
903 return FALSE;
905 if (!pSid)
907 SetLastError(ERROR_INVALID_PARAMETER);
908 return FALSE;
910 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
911 *cbSid = length;
912 return TRUE;
916 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
918 SetLastError(ERROR_INVALID_PARAMETER);
919 return FALSE;
922 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
923 if (WellKnownRids[i].Type == WellKnownSidType) {
924 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
925 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
926 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
928 if (*cbSid < output_sid_length)
930 *cbSid = output_sid_length;
931 SetLastError(ERROR_INSUFFICIENT_BUFFER);
932 return FALSE;
934 if (!pSid)
936 SetLastError(ERROR_INVALID_PARAMETER);
937 return FALSE;
939 CopyMemory(pSid, DomainSid, domain_sid_length);
940 (*GetSidSubAuthorityCount(pSid))++;
941 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
942 *cbSid = output_sid_length;
943 return TRUE;
946 SetLastError(ERROR_INVALID_PARAMETER);
947 return FALSE;
950 /******************************************************************************
951 * IsWellKnownSid [ADVAPI32.@]
953 BOOL WINAPI
954 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
956 unsigned int i;
957 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
959 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
960 if (WellKnownSids[i].Type == WellKnownSidType)
961 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
962 return TRUE;
964 return FALSE;
967 BOOL WINAPI
968 IsTokenRestricted( HANDLE TokenHandle )
970 TOKEN_GROUPS *groups;
971 DWORD size;
972 NTSTATUS status;
973 BOOL restricted;
975 TRACE("(%p)\n", TokenHandle);
977 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
978 if (status != STATUS_BUFFER_TOO_SMALL)
979 return FALSE;
981 groups = HeapAlloc(GetProcessHeap(), 0, size);
982 if (!groups)
984 SetLastError(ERROR_OUTOFMEMORY);
985 return FALSE;
988 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
989 if (status != STATUS_SUCCESS)
991 HeapFree(GetProcessHeap(), 0, groups);
992 return set_ntstatus(status);
995 if (groups->GroupCount)
996 restricted = TRUE;
997 else
998 restricted = FALSE;
1000 HeapFree(GetProcessHeap(), 0, groups);
1002 return restricted;
1005 /******************************************************************************
1006 * IsValidSid [ADVAPI32.@]
1008 * PARAMS
1009 * pSid []
1011 BOOL WINAPI
1012 IsValidSid( PSID pSid )
1014 return RtlValidSid( pSid );
1017 /******************************************************************************
1018 * EqualSid [ADVAPI32.@]
1020 * PARAMS
1021 * pSid1 []
1022 * pSid2 []
1024 BOOL WINAPI
1025 EqualSid( PSID pSid1, PSID pSid2 )
1027 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1028 SetLastError(ERROR_SUCCESS);
1029 return ret;
1032 /******************************************************************************
1033 * EqualPrefixSid [ADVAPI32.@]
1035 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1037 return RtlEqualPrefixSid(pSid1, pSid2);
1040 /******************************************************************************
1041 * GetSidLengthRequired [ADVAPI32.@]
1043 * PARAMS
1044 * nSubAuthorityCount []
1046 DWORD WINAPI
1047 GetSidLengthRequired( BYTE nSubAuthorityCount )
1049 return RtlLengthRequiredSid(nSubAuthorityCount);
1052 /******************************************************************************
1053 * InitializeSid [ADVAPI32.@]
1055 * PARAMS
1056 * pIdentifierAuthority []
1058 BOOL WINAPI
1059 InitializeSid (
1060 PSID pSid,
1061 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1062 BYTE nSubAuthorityCount)
1064 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1067 DWORD WINAPI
1068 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1070 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1072 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1073 return 0;
1076 DWORD WINAPI
1077 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1079 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1081 return 1;
1084 /******************************************************************************
1085 * GetSidIdentifierAuthority [ADVAPI32.@]
1087 * PARAMS
1088 * pSid []
1090 PSID_IDENTIFIER_AUTHORITY WINAPI
1091 GetSidIdentifierAuthority( PSID pSid )
1093 return RtlIdentifierAuthoritySid(pSid);
1096 /******************************************************************************
1097 * GetSidSubAuthority [ADVAPI32.@]
1099 * PARAMS
1100 * pSid []
1101 * nSubAuthority []
1103 PDWORD WINAPI
1104 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1106 SetLastError(ERROR_SUCCESS);
1107 return RtlSubAuthoritySid(pSid, nSubAuthority);
1110 /******************************************************************************
1111 * GetSidSubAuthorityCount [ADVAPI32.@]
1113 * PARAMS
1114 * pSid []
1116 PUCHAR WINAPI
1117 GetSidSubAuthorityCount (PSID pSid)
1119 SetLastError(ERROR_SUCCESS);
1120 return RtlSubAuthorityCountSid(pSid);
1123 /******************************************************************************
1124 * GetLengthSid [ADVAPI32.@]
1126 * PARAMS
1127 * pSid []
1129 DWORD WINAPI
1130 GetLengthSid (PSID pSid)
1132 return RtlLengthSid(pSid);
1135 /* ##############################################
1136 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1137 ##############################################
1140 /******************************************************************************
1141 * BuildSecurityDescriptorA [ADVAPI32.@]
1143 * Builds a SD from
1145 * PARAMS
1146 * pOwner [I]
1147 * pGroup [I]
1148 * cCountOfAccessEntries [I]
1149 * pListOfAccessEntries [I]
1150 * cCountOfAuditEntries [I]
1151 * pListofAuditEntries [I]
1152 * pOldSD [I]
1153 * lpdwBufferLength [I/O]
1154 * pNewSD [O]
1156 * RETURNS
1157 * Success: ERROR_SUCCESS
1158 * Failure: nonzero error code from Winerror.h
1160 DWORD WINAPI BuildSecurityDescriptorA(
1161 IN PTRUSTEEA pOwner,
1162 IN PTRUSTEEA pGroup,
1163 IN ULONG cCountOfAccessEntries,
1164 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1165 IN ULONG cCountOfAuditEntries,
1166 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1167 IN PSECURITY_DESCRIPTOR pOldSD,
1168 IN OUT PULONG lpdwBufferLength,
1169 OUT PSECURITY_DESCRIPTOR* pNewSD)
1171 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1172 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1173 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1175 return ERROR_CALL_NOT_IMPLEMENTED;
1178 /******************************************************************************
1179 * BuildSecurityDescriptorW [ADVAPI32.@]
1181 * See BuildSecurityDescriptorA.
1183 DWORD WINAPI BuildSecurityDescriptorW(
1184 IN PTRUSTEEW pOwner,
1185 IN PTRUSTEEW pGroup,
1186 IN ULONG cCountOfAccessEntries,
1187 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1188 IN ULONG cCountOfAuditEntries,
1189 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1190 IN PSECURITY_DESCRIPTOR pOldSD,
1191 IN OUT PULONG lpdwBufferLength,
1192 OUT PSECURITY_DESCRIPTOR* pNewSD)
1194 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1195 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1196 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1198 return ERROR_CALL_NOT_IMPLEMENTED;
1201 /******************************************************************************
1202 * InitializeSecurityDescriptor [ADVAPI32.@]
1204 * PARAMS
1205 * pDescr []
1206 * revision []
1208 BOOL WINAPI
1209 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1211 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1215 /******************************************************************************
1216 * MakeAbsoluteSD [ADVAPI32.@]
1218 BOOL WINAPI MakeAbsoluteSD (
1219 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1220 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1221 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1222 OUT PACL pDacl,
1223 OUT LPDWORD lpdwDaclSize,
1224 OUT PACL pSacl,
1225 OUT LPDWORD lpdwSaclSize,
1226 OUT PSID pOwner,
1227 OUT LPDWORD lpdwOwnerSize,
1228 OUT PSID pPrimaryGroup,
1229 OUT LPDWORD lpdwPrimaryGroupSize)
1231 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1232 pAbsoluteSecurityDescriptor,
1233 lpdwAbsoluteSecurityDescriptorSize,
1234 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1235 pOwner, lpdwOwnerSize,
1236 pPrimaryGroup, lpdwPrimaryGroupSize));
1239 /******************************************************************************
1240 * GetKernelObjectSecurity [ADVAPI32.@]
1242 BOOL WINAPI GetKernelObjectSecurity(
1243 HANDLE Handle,
1244 SECURITY_INFORMATION RequestedInformation,
1245 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1246 DWORD nLength,
1247 LPDWORD lpnLengthNeeded )
1249 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1250 pSecurityDescriptor, nLength, lpnLengthNeeded);
1252 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1253 nLength, lpnLengthNeeded ));
1256 /******************************************************************************
1257 * GetPrivateObjectSecurity [ADVAPI32.@]
1259 BOOL WINAPI GetPrivateObjectSecurity(
1260 PSECURITY_DESCRIPTOR ObjectDescriptor,
1261 SECURITY_INFORMATION SecurityInformation,
1262 PSECURITY_DESCRIPTOR ResultantDescriptor,
1263 DWORD DescriptorLength,
1264 PDWORD ReturnLength )
1266 SECURITY_DESCRIPTOR desc;
1267 BOOL defaulted, present;
1268 PACL pacl;
1269 PSID psid;
1271 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1272 ResultantDescriptor, DescriptorLength, ReturnLength);
1274 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1275 return FALSE;
1277 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1279 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1280 return FALSE;
1281 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1284 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1286 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1287 return FALSE;
1288 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1291 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1293 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1294 return FALSE;
1295 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1298 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1300 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1301 return FALSE;
1302 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1305 *ReturnLength = DescriptorLength;
1306 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1309 /******************************************************************************
1310 * GetSecurityDescriptorLength [ADVAPI32.@]
1312 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1314 return RtlLengthSecurityDescriptor(pDescr);
1317 /******************************************************************************
1318 * GetSecurityDescriptorOwner [ADVAPI32.@]
1320 * PARAMS
1321 * pOwner []
1322 * lpbOwnerDefaulted []
1324 BOOL WINAPI
1325 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1326 LPBOOL lpbOwnerDefaulted )
1328 BOOLEAN defaulted;
1329 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1330 *lpbOwnerDefaulted = defaulted;
1331 return ret;
1334 /******************************************************************************
1335 * SetSecurityDescriptorOwner [ADVAPI32.@]
1337 * PARAMS
1339 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1340 PSID pOwner, BOOL bOwnerDefaulted)
1342 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1344 /******************************************************************************
1345 * GetSecurityDescriptorGroup [ADVAPI32.@]
1347 BOOL WINAPI GetSecurityDescriptorGroup(
1348 PSECURITY_DESCRIPTOR SecurityDescriptor,
1349 PSID *Group,
1350 LPBOOL GroupDefaulted)
1352 BOOLEAN defaulted;
1353 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1354 *GroupDefaulted = defaulted;
1355 return ret;
1357 /******************************************************************************
1358 * SetSecurityDescriptorGroup [ADVAPI32.@]
1360 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1361 PSID Group, BOOL GroupDefaulted)
1363 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1366 /******************************************************************************
1367 * IsValidSecurityDescriptor [ADVAPI32.@]
1369 * PARAMS
1370 * lpsecdesc []
1372 BOOL WINAPI
1373 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1375 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1378 /******************************************************************************
1379 * GetSecurityDescriptorDacl [ADVAPI32.@]
1381 BOOL WINAPI GetSecurityDescriptorDacl(
1382 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1383 OUT LPBOOL lpbDaclPresent,
1384 OUT PACL *pDacl,
1385 OUT LPBOOL lpbDaclDefaulted)
1387 BOOLEAN present, defaulted;
1388 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1389 *lpbDaclPresent = present;
1390 *lpbDaclDefaulted = defaulted;
1391 return ret;
1394 /******************************************************************************
1395 * SetSecurityDescriptorDacl [ADVAPI32.@]
1397 BOOL WINAPI
1398 SetSecurityDescriptorDacl (
1399 PSECURITY_DESCRIPTOR lpsd,
1400 BOOL daclpresent,
1401 PACL dacl,
1402 BOOL dacldefaulted )
1404 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1406 /******************************************************************************
1407 * GetSecurityDescriptorSacl [ADVAPI32.@]
1409 BOOL WINAPI GetSecurityDescriptorSacl(
1410 IN PSECURITY_DESCRIPTOR lpsd,
1411 OUT LPBOOL lpbSaclPresent,
1412 OUT PACL *pSacl,
1413 OUT LPBOOL lpbSaclDefaulted)
1415 BOOLEAN present, defaulted;
1416 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1417 *lpbSaclPresent = present;
1418 *lpbSaclDefaulted = defaulted;
1419 return ret;
1422 /**************************************************************************
1423 * SetSecurityDescriptorSacl [ADVAPI32.@]
1425 BOOL WINAPI SetSecurityDescriptorSacl (
1426 PSECURITY_DESCRIPTOR lpsd,
1427 BOOL saclpresent,
1428 PACL lpsacl,
1429 BOOL sacldefaulted)
1431 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1433 /******************************************************************************
1434 * MakeSelfRelativeSD [ADVAPI32.@]
1436 * PARAMS
1437 * lpabssecdesc []
1438 * lpselfsecdesc []
1439 * lpbuflen []
1441 BOOL WINAPI
1442 MakeSelfRelativeSD(
1443 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1444 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1445 IN OUT LPDWORD lpdwBufferLength)
1447 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1448 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1451 /******************************************************************************
1452 * GetSecurityDescriptorControl [ADVAPI32.@]
1455 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1456 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1458 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1461 /******************************************************************************
1462 * SetSecurityDescriptorControl [ADVAPI32.@]
1464 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1465 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1466 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1468 return set_ntstatus( RtlSetControlSecurityDescriptor(
1469 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1472 /* ##############################
1473 ###### ACL FUNCTIONS ######
1474 ##############################
1477 /*************************************************************************
1478 * InitializeAcl [ADVAPI32.@]
1480 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1482 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1485 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1487 IO_STATUS_BLOCK io_block;
1489 TRACE("(%p)\n", hNamedPipe);
1491 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1492 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1495 /******************************************************************************
1496 * AddAccessAllowedAce [ADVAPI32.@]
1498 BOOL WINAPI AddAccessAllowedAce(
1499 IN OUT PACL pAcl,
1500 IN DWORD dwAceRevision,
1501 IN DWORD AccessMask,
1502 IN PSID pSid)
1504 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1507 /******************************************************************************
1508 * AddAccessAllowedAceEx [ADVAPI32.@]
1510 BOOL WINAPI AddAccessAllowedAceEx(
1511 IN OUT PACL pAcl,
1512 IN DWORD dwAceRevision,
1513 IN DWORD AceFlags,
1514 IN DWORD AccessMask,
1515 IN PSID pSid)
1517 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1520 /******************************************************************************
1521 * AddAccessDeniedAce [ADVAPI32.@]
1523 BOOL WINAPI AddAccessDeniedAce(
1524 IN OUT PACL pAcl,
1525 IN DWORD dwAceRevision,
1526 IN DWORD AccessMask,
1527 IN PSID pSid)
1529 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1532 /******************************************************************************
1533 * AddAccessDeniedAceEx [ADVAPI32.@]
1535 BOOL WINAPI AddAccessDeniedAceEx(
1536 IN OUT PACL pAcl,
1537 IN DWORD dwAceRevision,
1538 IN DWORD AceFlags,
1539 IN DWORD AccessMask,
1540 IN PSID pSid)
1542 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1545 /******************************************************************************
1546 * AddAce [ADVAPI32.@]
1548 BOOL WINAPI AddAce(
1549 IN OUT PACL pAcl,
1550 IN DWORD dwAceRevision,
1551 IN DWORD dwStartingAceIndex,
1552 LPVOID pAceList,
1553 DWORD nAceListLength)
1555 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1558 /******************************************************************************
1559 * DeleteAce [ADVAPI32.@]
1561 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1563 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1566 /******************************************************************************
1567 * FindFirstFreeAce [ADVAPI32.@]
1569 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1571 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1574 /******************************************************************************
1575 * GetAce [ADVAPI32.@]
1577 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1579 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1582 /******************************************************************************
1583 * GetAclInformation [ADVAPI32.@]
1585 BOOL WINAPI GetAclInformation(
1586 PACL pAcl,
1587 LPVOID pAclInformation,
1588 DWORD nAclInformationLength,
1589 ACL_INFORMATION_CLASS dwAclInformationClass)
1591 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1592 nAclInformationLength, dwAclInformationClass));
1595 /******************************************************************************
1596 * IsValidAcl [ADVAPI32.@]
1598 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1600 return RtlValidAcl(pAcl);
1603 /* ##############################
1604 ###### MISC FUNCTIONS ######
1605 ##############################
1608 /******************************************************************************
1609 * AllocateLocallyUniqueId [ADVAPI32.@]
1611 * PARAMS
1612 * lpLuid []
1614 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1616 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1619 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1620 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1622 { '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 };
1623 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1624 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1626 { '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 };
1627 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1628 { '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 };
1629 static const WCHAR SE_TCB_NAME_W[] =
1630 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1631 static const WCHAR SE_SECURITY_NAME_W[] =
1632 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1633 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1634 { '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 };
1635 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1636 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1637 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1638 { '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 };
1639 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1640 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1641 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1642 { '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 };
1643 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1644 { '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 };
1645 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1646 { '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 };
1647 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1648 { '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 };
1649 static const WCHAR SE_BACKUP_NAME_W[] =
1650 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1651 static const WCHAR SE_RESTORE_NAME_W[] =
1652 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1653 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1654 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1655 static const WCHAR SE_DEBUG_NAME_W[] =
1656 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1657 static const WCHAR SE_AUDIT_NAME_W[] =
1658 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1659 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1660 { '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 };
1661 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1662 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1663 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1664 { '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 };
1665 static const WCHAR SE_UNDOCK_NAME_W[] =
1666 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1667 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1668 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1669 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1670 { '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 };
1671 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1672 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1673 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1674 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1675 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1676 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1678 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1680 NULL,
1681 NULL,
1682 SE_CREATE_TOKEN_NAME_W,
1683 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1684 SE_LOCK_MEMORY_NAME_W,
1685 SE_INCREASE_QUOTA_NAME_W,
1686 SE_MACHINE_ACCOUNT_NAME_W,
1687 SE_TCB_NAME_W,
1688 SE_SECURITY_NAME_W,
1689 SE_TAKE_OWNERSHIP_NAME_W,
1690 SE_LOAD_DRIVER_NAME_W,
1691 SE_SYSTEM_PROFILE_NAME_W,
1692 SE_SYSTEMTIME_NAME_W,
1693 SE_PROF_SINGLE_PROCESS_NAME_W,
1694 SE_INC_BASE_PRIORITY_NAME_W,
1695 SE_CREATE_PAGEFILE_NAME_W,
1696 SE_CREATE_PERMANENT_NAME_W,
1697 SE_BACKUP_NAME_W,
1698 SE_RESTORE_NAME_W,
1699 SE_SHUTDOWN_NAME_W,
1700 SE_DEBUG_NAME_W,
1701 SE_AUDIT_NAME_W,
1702 SE_SYSTEM_ENVIRONMENT_NAME_W,
1703 SE_CHANGE_NOTIFY_NAME_W,
1704 SE_REMOTE_SHUTDOWN_NAME_W,
1705 SE_UNDOCK_NAME_W,
1706 SE_SYNC_AGENT_NAME_W,
1707 SE_ENABLE_DELEGATION_NAME_W,
1708 SE_MANAGE_VOLUME_NAME_W,
1709 SE_IMPERSONATE_NAME_W,
1710 SE_CREATE_GLOBAL_NAME_W,
1713 /******************************************************************************
1714 * LookupPrivilegeValueW [ADVAPI32.@]
1716 * See LookupPrivilegeValueA.
1718 BOOL WINAPI
1719 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1721 UINT i;
1723 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1725 if (!ADVAPI_IsLocalComputer(lpSystemName))
1727 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1728 return FALSE;
1730 if (!lpName)
1732 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1733 return FALSE;
1735 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1737 if( !WellKnownPrivNames[i] )
1738 continue;
1739 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1740 continue;
1741 lpLuid->LowPart = i;
1742 lpLuid->HighPart = 0;
1743 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1744 lpLuid->HighPart, lpLuid->LowPart );
1745 return TRUE;
1747 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1748 return FALSE;
1751 /******************************************************************************
1752 * LookupPrivilegeValueA [ADVAPI32.@]
1754 * Retrieves LUID used on a system to represent the privilege name.
1756 * PARAMS
1757 * lpSystemName [I] Name of the system
1758 * lpName [I] Name of the privilege
1759 * lpLuid [O] Destination for the resulting LUID
1761 * RETURNS
1762 * Success: TRUE. lpLuid contains the requested LUID.
1763 * Failure: FALSE.
1765 BOOL WINAPI
1766 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1768 UNICODE_STRING lpSystemNameW;
1769 UNICODE_STRING lpNameW;
1770 BOOL ret;
1772 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1773 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1774 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1775 RtlFreeUnicodeString(&lpNameW);
1776 RtlFreeUnicodeString(&lpSystemNameW);
1777 return ret;
1780 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1781 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1783 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1784 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1786 return FALSE;
1789 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1790 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1792 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1793 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1795 return FALSE;
1798 /******************************************************************************
1799 * LookupPrivilegeNameA [ADVAPI32.@]
1801 * See LookupPrivilegeNameW.
1803 BOOL WINAPI
1804 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1805 LPDWORD cchName)
1807 UNICODE_STRING lpSystemNameW;
1808 BOOL ret;
1809 DWORD wLen = 0;
1811 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1813 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1814 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1815 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1817 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1819 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1820 &wLen);
1821 if (ret)
1823 /* Windows crashes if cchName is NULL, so will I */
1824 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1825 *cchName, NULL, NULL);
1827 if (len == 0)
1829 /* WideCharToMultiByte failed */
1830 ret = FALSE;
1832 else if (len > *cchName)
1834 *cchName = len;
1835 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1836 ret = FALSE;
1838 else
1840 /* WideCharToMultiByte succeeded, output length needs to be
1841 * length not including NULL terminator
1843 *cchName = len - 1;
1846 HeapFree(GetProcessHeap(), 0, lpNameW);
1848 RtlFreeUnicodeString(&lpSystemNameW);
1849 return ret;
1852 /******************************************************************************
1853 * LookupPrivilegeNameW [ADVAPI32.@]
1855 * Retrieves the privilege name referred to by the LUID lpLuid.
1857 * PARAMS
1858 * lpSystemName [I] Name of the system
1859 * lpLuid [I] Privilege value
1860 * lpName [O] Name of the privilege
1861 * cchName [I/O] Number of characters in lpName.
1863 * RETURNS
1864 * Success: TRUE. lpName contains the name of the privilege whose value is
1865 * *lpLuid.
1866 * Failure: FALSE.
1868 * REMARKS
1869 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1870 * using this function.
1871 * If the length of lpName is too small, on return *cchName will contain the
1872 * number of WCHARs needed to contain the privilege, including the NULL
1873 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1874 * On success, *cchName will contain the number of characters stored in
1875 * lpName, NOT including the NULL terminator.
1877 BOOL WINAPI
1878 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1879 LPDWORD cchName)
1881 size_t privNameLen;
1883 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1885 if (!ADVAPI_IsLocalComputer(lpSystemName))
1887 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1888 return FALSE;
1890 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1891 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1893 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1894 return FALSE;
1896 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1897 /* Windows crashes if cchName is NULL, so will I */
1898 if (*cchName <= privNameLen)
1900 *cchName = privNameLen + 1;
1901 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1902 return FALSE;
1904 else
1906 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1907 *cchName = privNameLen;
1908 return TRUE;
1912 /******************************************************************************
1913 * GetFileSecurityA [ADVAPI32.@]
1915 * Obtains Specified information about the security of a file or directory.
1917 * PARAMS
1918 * lpFileName [I] Name of the file to get info for
1919 * RequestedInformation [I] SE_ flags from "winnt.h"
1920 * pSecurityDescriptor [O] Destination for security information
1921 * nLength [I] Length of pSecurityDescriptor
1922 * lpnLengthNeeded [O] Destination for length of returned security information
1924 * RETURNS
1925 * Success: TRUE. pSecurityDescriptor contains the requested information.
1926 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1928 * NOTES
1929 * The information returned is constrained by the callers access rights and
1930 * privileges.
1932 BOOL WINAPI
1933 GetFileSecurityA( LPCSTR lpFileName,
1934 SECURITY_INFORMATION RequestedInformation,
1935 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936 DWORD nLength, LPDWORD lpnLengthNeeded )
1938 DWORD len;
1939 BOOL r;
1940 LPWSTR name = NULL;
1942 if( lpFileName )
1944 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1945 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1946 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1949 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1950 nLength, lpnLengthNeeded );
1951 HeapFree( GetProcessHeap(), 0, name );
1953 return r;
1956 /******************************************************************************
1957 * GetFileSecurityW [ADVAPI32.@]
1959 * See GetFileSecurityA.
1961 BOOL WINAPI
1962 GetFileSecurityW( LPCWSTR lpFileName,
1963 SECURITY_INFORMATION RequestedInformation,
1964 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1965 DWORD nLength, LPDWORD lpnLengthNeeded )
1967 HANDLE hfile;
1968 NTSTATUS status;
1969 DWORD access = 0;
1971 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1972 RequestedInformation, pSecurityDescriptor,
1973 nLength, lpnLengthNeeded);
1975 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1976 DACL_SECURITY_INFORMATION))
1977 access |= READ_CONTROL;
1978 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1979 access |= ACCESS_SYSTEM_SECURITY;
1981 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1982 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1983 if ( hfile == INVALID_HANDLE_VALUE )
1984 return FALSE;
1986 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1987 nLength, lpnLengthNeeded );
1988 CloseHandle( hfile );
1989 return set_ntstatus( status );
1993 /******************************************************************************
1994 * LookupAccountSidA [ADVAPI32.@]
1996 BOOL WINAPI
1997 LookupAccountSidA(
1998 IN LPCSTR system,
1999 IN PSID sid,
2000 OUT LPSTR account,
2001 IN OUT LPDWORD accountSize,
2002 OUT LPSTR domain,
2003 IN OUT LPDWORD domainSize,
2004 OUT PSID_NAME_USE name_use )
2006 DWORD len;
2007 BOOL r;
2008 LPWSTR systemW = NULL;
2009 LPWSTR accountW = NULL;
2010 LPWSTR domainW = NULL;
2011 DWORD accountSizeW = *accountSize;
2012 DWORD domainSizeW = *domainSize;
2014 if (system) {
2015 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2016 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2017 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2019 if (account)
2020 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2021 if (domain)
2022 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2024 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2026 if (r) {
2027 if (accountW && *accountSize) {
2028 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2029 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2030 *accountSize = len;
2031 } else
2032 *accountSize = accountSizeW + 1;
2034 if (domainW && *domainSize) {
2035 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2036 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2037 *domainSize = len;
2038 } else
2039 *domainSize = domainSizeW + 1;
2041 else
2043 *accountSize = accountSizeW + 1;
2044 *domainSize = domainSizeW + 1;
2047 HeapFree( GetProcessHeap(), 0, systemW );
2048 HeapFree( GetProcessHeap(), 0, accountW );
2049 HeapFree( GetProcessHeap(), 0, domainW );
2051 return r;
2054 /******************************************************************************
2055 * LookupAccountSidW [ADVAPI32.@]
2057 * PARAMS
2058 * system []
2059 * sid []
2060 * account []
2061 * accountSize []
2062 * domain []
2063 * domainSize []
2064 * name_use []
2067 BOOL WINAPI
2068 LookupAccountSidW(
2069 IN LPCWSTR system,
2070 IN PSID sid,
2071 OUT LPWSTR account,
2072 IN OUT LPDWORD accountSize,
2073 OUT LPWSTR domain,
2074 IN OUT LPDWORD domainSize,
2075 OUT PSID_NAME_USE name_use )
2077 unsigned int i, j;
2078 const WCHAR * ac = NULL;
2079 const WCHAR * dm = NULL;
2080 SID_NAME_USE use = 0;
2081 LPWSTR computer_name = NULL;
2082 LPWSTR account_name = NULL;
2084 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2085 debugstr_w(system),debugstr_sid(sid),
2086 account,accountSize,accountSize?*accountSize:0,
2087 domain,domainSize,domainSize?*domainSize:0,
2088 name_use);
2090 if (!ADVAPI_IsLocalComputer(system)) {
2091 FIXME("Only local computer supported!\n");
2092 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2093 return FALSE;
2096 /* check the well known SIDs first */
2097 for (i = 0; i <= 60; i++) {
2098 if (IsWellKnownSid(sid, i)) {
2099 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2100 if (ACCOUNT_SIDS[j].type == i) {
2101 ac = ACCOUNT_SIDS[j].account;
2102 dm = ACCOUNT_SIDS[j].domain;
2103 use = ACCOUNT_SIDS[j].name_use;
2106 break;
2110 if (dm == NULL) {
2111 MAX_SID local;
2113 /* check for the local computer next */
2114 if (ADVAPI_GetComputerSid(&local)) {
2115 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2116 BOOL result;
2118 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2119 result = GetComputerNameW(computer_name, &size);
2121 if (result) {
2122 if (EqualSid(sid, &local)) {
2123 dm = computer_name;
2124 ac = Blank;
2125 use = 3;
2126 } else {
2127 local.SubAuthorityCount++;
2129 if (EqualPrefixSid(sid, &local)) {
2130 dm = computer_name;
2131 use = 1;
2132 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2133 case DOMAIN_USER_RID_ADMIN:
2134 ac = Administrator;
2135 break;
2136 case DOMAIN_USER_RID_GUEST:
2137 ac = Guest;
2138 break;
2139 case DOMAIN_GROUP_RID_ADMINS:
2140 ac = Domain_Admins;
2141 break;
2142 case DOMAIN_GROUP_RID_USERS:
2143 ac = Domain_Users;
2144 break;
2145 case DOMAIN_GROUP_RID_GUESTS:
2146 ac = Domain_Guests;
2147 break;
2148 case DOMAIN_GROUP_RID_COMPUTERS:
2149 ac = Domain_Computers;
2150 break;
2151 case DOMAIN_GROUP_RID_CONTROLLERS:
2152 ac = Domain_Controllers;
2153 break;
2154 case DOMAIN_GROUP_RID_CERT_ADMINS:
2155 ac = Cert_Publishers;
2156 break;
2157 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2158 ac = Schema_Admins;
2159 break;
2160 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2161 ac = Enterprise_Admins;
2162 break;
2163 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2164 ac = Group_Policy_Creator_Owners;
2165 break;
2166 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2167 ac = RAS_and_IAS_Servers;
2168 break;
2169 case 1000: /* first user account */
2170 size = UNLEN + 1;
2171 account_name = HeapAlloc(
2172 GetProcessHeap(), 0, size * sizeof(WCHAR));
2173 if (GetUserNameW(account_name, &size))
2174 ac = account_name;
2175 else
2176 dm = NULL;
2178 break;
2179 default:
2180 dm = NULL;
2181 break;
2189 if (dm) {
2190 DWORD ac_len = lstrlenW(ac);
2191 DWORD dm_len = lstrlenW(dm);
2192 BOOL status = TRUE;
2194 if (*accountSize > ac_len) {
2195 if (account)
2196 lstrcpyW(account, ac);
2198 if (*domainSize > dm_len) {
2199 if (domain)
2200 lstrcpyW(domain, dm);
2202 if ((*accountSize && *accountSize < ac_len) ||
2203 (!account && !*accountSize && ac_len) ||
2204 (*domainSize && *domainSize < dm_len) ||
2205 (!domain && !*domainSize && dm_len))
2207 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2208 status = FALSE;
2210 if (*domainSize)
2211 *domainSize = dm_len;
2212 else
2213 *domainSize = dm_len + 1;
2214 if (*accountSize)
2215 *accountSize = ac_len;
2216 else
2217 *accountSize = ac_len + 1;
2219 HeapFree(GetProcessHeap(), 0, account_name);
2220 HeapFree(GetProcessHeap(), 0, computer_name);
2221 if (status) *name_use = use;
2222 return status;
2225 HeapFree(GetProcessHeap(), 0, account_name);
2226 HeapFree(GetProcessHeap(), 0, computer_name);
2227 SetLastError(ERROR_NONE_MAPPED);
2228 return FALSE;
2231 /******************************************************************************
2232 * SetFileSecurityA [ADVAPI32.@]
2234 * See SetFileSecurityW.
2236 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2237 SECURITY_INFORMATION RequestedInformation,
2238 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2240 DWORD len;
2241 BOOL r;
2242 LPWSTR name = NULL;
2244 if( lpFileName )
2246 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2247 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2248 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2251 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2252 HeapFree( GetProcessHeap(), 0, name );
2254 return r;
2257 /******************************************************************************
2258 * SetFileSecurityW [ADVAPI32.@]
2260 * Sets the security of a file or directory.
2262 * PARAMS
2263 * lpFileName []
2264 * RequestedInformation []
2265 * pSecurityDescriptor []
2267 * RETURNS
2268 * Success: TRUE.
2269 * Failure: FALSE.
2271 BOOL WINAPI
2272 SetFileSecurityW( LPCWSTR lpFileName,
2273 SECURITY_INFORMATION RequestedInformation,
2274 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2276 HANDLE file;
2277 DWORD access = 0;
2278 NTSTATUS status;
2280 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2281 pSecurityDescriptor );
2283 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2284 RequestedInformation & GROUP_SECURITY_INFORMATION)
2285 access |= WRITE_OWNER;
2286 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2287 access |= ACCESS_SYSTEM_SECURITY;
2288 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2289 access |= WRITE_DAC;
2291 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2292 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2293 if (file == INVALID_HANDLE_VALUE)
2294 return FALSE;
2296 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2297 CloseHandle( file );
2298 return set_ntstatus( status );
2301 /******************************************************************************
2302 * QueryWindows31FilesMigration [ADVAPI32.@]
2304 * PARAMS
2305 * x1 []
2307 BOOL WINAPI
2308 QueryWindows31FilesMigration( DWORD x1 )
2310 FIXME("(%d):stub\n",x1);
2311 return TRUE;
2314 /******************************************************************************
2315 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2317 * PARAMS
2318 * x1 []
2319 * x2 []
2320 * x3 []
2321 * x4 []
2323 BOOL WINAPI
2324 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2325 DWORD x4 )
2327 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2328 return TRUE;
2331 /******************************************************************************
2332 * NotifyBootConfigStatus [ADVAPI32.@]
2334 * PARAMS
2335 * x1 []
2337 BOOL WINAPI
2338 NotifyBootConfigStatus( BOOL x1 )
2340 FIXME("(0x%08d):stub\n",x1);
2341 return 1;
2344 /******************************************************************************
2345 * RevertToSelf [ADVAPI32.@]
2347 * Ends the impersonation of a user.
2349 * PARAMS
2350 * void []
2352 * RETURNS
2353 * Success: TRUE.
2354 * Failure: FALSE.
2356 BOOL WINAPI
2357 RevertToSelf( void )
2359 HANDLE Token = NULL;
2360 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2361 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2364 /******************************************************************************
2365 * ImpersonateSelf [ADVAPI32.@]
2367 * Makes an impersonation token that represents the process user and assigns
2368 * to the current thread.
2370 * PARAMS
2371 * ImpersonationLevel [I] Level at which to impersonate.
2373 * RETURNS
2374 * Success: TRUE.
2375 * Failure: FALSE.
2377 BOOL WINAPI
2378 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2380 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2383 /******************************************************************************
2384 * ImpersonateLoggedOnUser [ADVAPI32.@]
2386 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2388 DWORD size;
2389 NTSTATUS Status;
2390 HANDLE ImpersonationToken;
2391 TOKEN_TYPE Type;
2392 static BOOL warn = TRUE;
2394 if (warn)
2396 FIXME( "(%p)\n", hToken );
2397 warn = FALSE;
2399 if (!GetTokenInformation( hToken, TokenType, &Type,
2400 sizeof(TOKEN_TYPE), &size ))
2401 return FALSE;
2403 if (Type == TokenPrimary)
2405 OBJECT_ATTRIBUTES ObjectAttributes;
2407 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2409 Status = NtDuplicateToken( hToken,
2410 TOKEN_IMPERSONATE | TOKEN_QUERY,
2411 &ObjectAttributes,
2412 SecurityImpersonation,
2413 TokenImpersonation,
2414 &ImpersonationToken );
2415 if (Status != STATUS_SUCCESS)
2417 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2418 SetLastError( RtlNtStatusToDosError( Status ) );
2419 return FALSE;
2422 else
2423 ImpersonationToken = hToken;
2425 Status = NtSetInformationThread( GetCurrentThread(),
2426 ThreadImpersonationToken,
2427 &ImpersonationToken,
2428 sizeof(ImpersonationToken) );
2430 if (Type == TokenPrimary)
2431 NtClose( ImpersonationToken );
2433 if (Status != STATUS_SUCCESS)
2435 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2436 SetLastError( RtlNtStatusToDosError( Status ) );
2437 return FALSE;
2440 return TRUE;
2443 /******************************************************************************
2444 * AccessCheck [ADVAPI32.@]
2446 BOOL WINAPI
2447 AccessCheck(
2448 PSECURITY_DESCRIPTOR SecurityDescriptor,
2449 HANDLE ClientToken,
2450 DWORD DesiredAccess,
2451 PGENERIC_MAPPING GenericMapping,
2452 PPRIVILEGE_SET PrivilegeSet,
2453 LPDWORD PrivilegeSetLength,
2454 LPDWORD GrantedAccess,
2455 LPBOOL AccessStatus)
2457 NTSTATUS access_status;
2458 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2459 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2460 GrantedAccess, &access_status) );
2461 if (ret) *AccessStatus = set_ntstatus( access_status );
2462 return ret;
2466 /******************************************************************************
2467 * AccessCheckByType [ADVAPI32.@]
2469 BOOL WINAPI AccessCheckByType(
2470 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2471 PSID PrincipalSelfSid,
2472 HANDLE ClientToken,
2473 DWORD DesiredAccess,
2474 POBJECT_TYPE_LIST ObjectTypeList,
2475 DWORD ObjectTypeListLength,
2476 PGENERIC_MAPPING GenericMapping,
2477 PPRIVILEGE_SET PrivilegeSet,
2478 LPDWORD PrivilegeSetLength,
2479 LPDWORD GrantedAccess,
2480 LPBOOL AccessStatus)
2482 FIXME("stub\n");
2484 *AccessStatus = TRUE;
2486 return !*AccessStatus;
2489 /******************************************************************************
2490 * MapGenericMask [ADVAPI32.@]
2492 * Maps generic access rights into specific access rights according to the
2493 * supplied mapping.
2495 * PARAMS
2496 * AccessMask [I/O] Access rights.
2497 * GenericMapping [I] The mapping between generic and specific rights.
2499 * RETURNS
2500 * Nothing.
2502 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2504 RtlMapGenericMask( AccessMask, GenericMapping );
2507 /*************************************************************************
2508 * SetKernelObjectSecurity [ADVAPI32.@]
2510 BOOL WINAPI SetKernelObjectSecurity (
2511 IN HANDLE Handle,
2512 IN SECURITY_INFORMATION SecurityInformation,
2513 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2515 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2519 /******************************************************************************
2520 * AddAuditAccessAce [ADVAPI32.@]
2522 BOOL WINAPI AddAuditAccessAce(
2523 IN OUT PACL pAcl,
2524 IN DWORD dwAceRevision,
2525 IN DWORD dwAccessMask,
2526 IN PSID pSid,
2527 IN BOOL bAuditSuccess,
2528 IN BOOL bAuditFailure)
2530 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2531 bAuditSuccess, bAuditFailure) );
2534 /******************************************************************************
2535 * AddAuditAccessAce [ADVAPI32.@]
2537 BOOL WINAPI AddAuditAccessAceEx(
2538 IN OUT PACL pAcl,
2539 IN DWORD dwAceRevision,
2540 IN DWORD dwAceFlags,
2541 IN DWORD dwAccessMask,
2542 IN PSID pSid,
2543 IN BOOL bAuditSuccess,
2544 IN BOOL bAuditFailure)
2546 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2547 bAuditSuccess, bAuditFailure) );
2550 /******************************************************************************
2551 * LookupAccountNameA [ADVAPI32.@]
2553 BOOL WINAPI
2554 LookupAccountNameA(
2555 IN LPCSTR system,
2556 IN LPCSTR account,
2557 OUT PSID sid,
2558 OUT LPDWORD cbSid,
2559 LPSTR ReferencedDomainName,
2560 IN OUT LPDWORD cbReferencedDomainName,
2561 OUT PSID_NAME_USE name_use )
2563 BOOL ret;
2564 UNICODE_STRING lpSystemW;
2565 UNICODE_STRING lpAccountW;
2566 LPWSTR lpReferencedDomainNameW = NULL;
2568 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2569 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2571 if (ReferencedDomainName)
2572 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2574 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2575 cbReferencedDomainName, name_use);
2577 if (ret && lpReferencedDomainNameW)
2579 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2580 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2583 RtlFreeUnicodeString(&lpSystemW);
2584 RtlFreeUnicodeString(&lpAccountW);
2585 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2587 return ret;
2590 /******************************************************************************
2591 * lookup_user_account_name
2593 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2594 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2596 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2597 DWORD len = sizeof(buffer);
2598 HANDLE token;
2599 BOOL ret;
2600 PSID pSid;
2601 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2602 DWORD nameLen;
2604 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2606 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2607 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2610 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2611 CloseHandle( token );
2613 if (!ret) return FALSE;
2615 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2617 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2618 CopySid(*cbSid, Sid, pSid);
2619 if (*cbSid < GetLengthSid(pSid))
2621 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2622 ret = FALSE;
2624 *cbSid = GetLengthSid(pSid);
2626 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2627 if (!GetComputerNameW(domainName, &nameLen))
2629 domainName[0] = 0;
2630 nameLen = 0;
2632 if (*cchReferencedDomainName <= nameLen || !ret)
2634 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2635 nameLen += 1;
2636 ret = FALSE;
2638 else if (ReferencedDomainName)
2639 strcpyW(ReferencedDomainName, domainName);
2641 *cchReferencedDomainName = nameLen;
2643 if (ret)
2644 *peUse = SidTypeUser;
2646 return ret;
2649 /******************************************************************************
2650 * lookup_computer_account_name
2652 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2653 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2655 MAX_SID local;
2656 BOOL ret;
2657 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2658 DWORD nameLen;
2660 if ((ret = ADVAPI_GetComputerSid(&local)))
2662 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2663 CopySid(*cbSid, Sid, &local);
2664 if (*cbSid < GetLengthSid(&local))
2666 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2667 ret = FALSE;
2669 *cbSid = GetLengthSid(&local);
2672 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2673 if (!GetComputerNameW(domainName, &nameLen))
2675 domainName[0] = 0;
2676 nameLen = 0;
2678 if (*cchReferencedDomainName <= nameLen || !ret)
2680 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2681 nameLen += 1;
2682 ret = FALSE;
2684 else if (ReferencedDomainName)
2685 strcpyW(ReferencedDomainName, domainName);
2687 *cchReferencedDomainName = nameLen;
2689 if (ret)
2690 *peUse = SidTypeDomain;
2692 return ret;
2695 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2696 LSA_UNICODE_STRING *domain )
2698 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2700 while (p > str->Buffer && *p != '\\') p--;
2702 if (*p == '\\')
2704 domain->Buffer = str->Buffer;
2705 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2707 account->Buffer = p + 1;
2708 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2710 else
2712 domain->Buffer = NULL;
2713 domain->Length = 0;
2715 account->Buffer = str->Buffer;
2716 account->Length = str->Length;
2720 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2722 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2724 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2725 return TRUE;
2727 return FALSE;
2730 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2732 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2734 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2735 return TRUE;
2737 if (ACCOUNT_SIDS[idx].alias)
2739 len = strlenW( ACCOUNT_SIDS[idx].alias );
2740 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2741 return TRUE;
2743 return FALSE;
2747 * Helper function for LookupAccountNameW
2749 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2750 PSID Sid, LPDWORD cbSid,
2751 LPWSTR ReferencedDomainName,
2752 LPDWORD cchReferencedDomainName,
2753 PSID_NAME_USE peUse, BOOL *handled )
2755 PSID pSid;
2756 LSA_UNICODE_STRING account, domain;
2757 BOOL ret = TRUE;
2758 ULONG i;
2760 *handled = FALSE;
2761 split_domain_account( account_and_domain, &account, &domain );
2763 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2765 /* check domain first */
2766 if (domain.Buffer && !match_domain( i, &domain )) continue;
2768 if (match_account( i, &account ))
2770 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2772 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2774 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2776 if (*cbSid < sidLen)
2778 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2779 ret = FALSE;
2781 else if (Sid)
2783 CopySid(*cbSid, Sid, pSid);
2785 *cbSid = sidLen;
2788 len = strlenW( ACCOUNT_SIDS[i].domain );
2789 if (*cchReferencedDomainName <= len || !ret)
2791 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2792 len++;
2793 ret = FALSE;
2795 else if (ReferencedDomainName)
2797 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2800 *cchReferencedDomainName = len;
2801 if (ret)
2802 *peUse = ACCOUNT_SIDS[i].name_use;
2804 HeapFree(GetProcessHeap(), 0, pSid);
2805 *handled = TRUE;
2806 return ret;
2809 return ret;
2812 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2813 PSID Sid, LPDWORD cbSid,
2814 LPWSTR ReferencedDomainName,
2815 LPDWORD cchReferencedDomainName,
2816 PSID_NAME_USE peUse, BOOL *handled )
2818 DWORD nameLen;
2819 LPWSTR userName = NULL;
2820 LSA_UNICODE_STRING account, domain;
2821 BOOL ret = TRUE;
2823 *handled = FALSE;
2824 split_domain_account( account_and_domain, &account, &domain );
2826 /* Let the current Unix user id masquerade as first Windows user account */
2828 nameLen = UNLEN + 1;
2829 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2831 if (domain.Buffer)
2833 /* check to make sure this account is on this computer */
2834 if (GetComputerNameW( userName, &nameLen ) &&
2835 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2837 SetLastError(ERROR_NONE_MAPPED);
2838 ret = FALSE;
2840 nameLen = UNLEN + 1;
2843 if (GetUserNameW( userName, &nameLen ) &&
2844 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2846 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2847 *handled = TRUE;
2849 else
2851 nameLen = UNLEN + 1;
2852 if (GetComputerNameW( userName, &nameLen ) &&
2853 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2855 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2856 *handled = TRUE;
2860 HeapFree(GetProcessHeap(), 0, userName);
2861 return ret;
2864 /******************************************************************************
2865 * LookupAccountNameW [ADVAPI32.@]
2867 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2868 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2869 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2871 BOOL ret, handled;
2872 LSA_UNICODE_STRING account;
2874 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2875 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2877 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2879 FIXME("remote computer not supported\n");
2880 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2881 return FALSE;
2884 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2886 lpAccountName = BUILTIN;
2889 RtlInitUnicodeString( &account, lpAccountName );
2891 /* Check well known SIDs first */
2892 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2893 cchReferencedDomainName, peUse, &handled );
2894 if (handled)
2895 return ret;
2897 /* Check user names */
2898 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2899 cchReferencedDomainName, peUse, &handled);
2900 if (handled)
2901 return ret;
2903 SetLastError( ERROR_NONE_MAPPED );
2904 return FALSE;
2907 /******************************************************************************
2908 * PrivilegeCheck [ADVAPI32.@]
2910 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2912 BOOL ret;
2913 BOOLEAN Result;
2915 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2917 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2918 if (ret)
2919 *pfResult = Result;
2920 return ret;
2923 /******************************************************************************
2924 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2926 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2927 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2928 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2929 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2931 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2932 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2933 SecurityDescriptor, DesiredAccess, GenericMapping,
2934 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2935 return TRUE;
2938 /******************************************************************************
2939 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2941 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2942 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2943 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2944 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2946 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2947 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2948 SecurityDescriptor, DesiredAccess, GenericMapping,
2949 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2950 return TRUE;
2953 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2955 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2957 return TRUE;
2960 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2962 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2964 return TRUE;
2967 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2969 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2971 return TRUE;
2974 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2975 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2976 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2977 LPBOOL GenerateOnClose)
2979 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2980 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2981 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2982 GenerateOnClose);
2984 return TRUE;
2987 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2988 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2989 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2990 LPBOOL GenerateOnClose)
2992 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2993 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2994 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2995 GenerateOnClose);
2997 return TRUE;
3000 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3001 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3003 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3004 DesiredAccess, Privileges, AccessGranted);
3006 return TRUE;
3009 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3010 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3012 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3013 DesiredAccess, Privileges, AccessGranted);
3015 return TRUE;
3018 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3019 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3021 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3022 ClientToken, Privileges, AccessGranted);
3024 return TRUE;
3027 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3028 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3030 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3031 ClientToken, Privileges, AccessGranted);
3033 return TRUE;
3036 /******************************************************************************
3037 * GetSecurityInfo [ADVAPI32.@]
3039 * Retrieves a copy of the security descriptor associated with an object.
3041 * PARAMS
3042 * hObject [I] A handle for the object.
3043 * ObjectType [I] The type of object.
3044 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3045 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3046 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3047 * ppDacl [O] If non-null, receives a pointer to the DACL.
3048 * ppSacl [O] If non-null, receives a pointer to the SACL.
3049 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3050 * which must be freed with LocalFree.
3052 * RETURNS
3053 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3055 DWORD WINAPI GetSecurityInfo(
3056 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3057 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3058 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3059 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3062 PSECURITY_DESCRIPTOR sd;
3063 NTSTATUS status;
3064 ULONG n1, n2;
3065 BOOL present, defaulted;
3067 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3068 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3069 return RtlNtStatusToDosError(status);
3071 sd = LocalAlloc(0, n1);
3072 if (!sd)
3073 return ERROR_NOT_ENOUGH_MEMORY;
3075 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3076 if (status != STATUS_SUCCESS)
3078 LocalFree(sd);
3079 return RtlNtStatusToDosError(status);
3082 if (ppsidOwner)
3084 *ppsidOwner = NULL;
3085 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3087 if (ppsidGroup)
3089 *ppsidGroup = NULL;
3090 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3092 if (ppDacl)
3094 *ppDacl = NULL;
3095 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3097 if (ppSacl)
3099 *ppSacl = NULL;
3100 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3102 if (ppSecurityDescriptor)
3103 *ppSecurityDescriptor = sd;
3105 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3106 * NULL, because native happily returns the SIDs and ACLs that are requested
3107 * in this case.
3110 return ERROR_SUCCESS;
3113 /******************************************************************************
3114 * GetSecurityInfoExA [ADVAPI32.@]
3116 DWORD WINAPI GetSecurityInfoExA(
3117 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3118 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3119 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3120 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3123 FIXME("stub!\n");
3124 return ERROR_BAD_PROVIDER;
3127 /******************************************************************************
3128 * GetSecurityInfoExW [ADVAPI32.@]
3130 DWORD WINAPI GetSecurityInfoExW(
3131 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3132 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3133 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3134 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3137 FIXME("stub!\n");
3138 return ERROR_BAD_PROVIDER;
3141 /******************************************************************************
3142 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3144 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3145 LPSTR pTrusteeName, DWORD AccessPermissions,
3146 ACCESS_MODE AccessMode, DWORD Inheritance )
3148 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3149 AccessPermissions, AccessMode, Inheritance);
3151 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3152 pExplicitAccess->grfAccessMode = AccessMode;
3153 pExplicitAccess->grfInheritance = Inheritance;
3155 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3156 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3157 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3158 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3159 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3162 /******************************************************************************
3163 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3165 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3166 LPWSTR pTrusteeName, DWORD AccessPermissions,
3167 ACCESS_MODE AccessMode, DWORD Inheritance )
3169 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3170 AccessPermissions, AccessMode, Inheritance);
3172 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3173 pExplicitAccess->grfAccessMode = AccessMode;
3174 pExplicitAccess->grfInheritance = Inheritance;
3176 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3177 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3178 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3179 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3180 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3183 /******************************************************************************
3184 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3186 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3187 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3188 LPSTR InheritedObjectTypeName, LPSTR Name )
3190 DWORD ObjectsPresent = 0;
3192 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3193 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3195 /* Fill the OBJECTS_AND_NAME structure */
3196 pObjName->ObjectType = ObjectType;
3197 if (ObjectTypeName != NULL)
3199 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3202 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3203 if (InheritedObjectTypeName != NULL)
3205 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3208 pObjName->ObjectsPresent = ObjectsPresent;
3209 pObjName->ptstrName = Name;
3211 /* Fill the TRUSTEE structure */
3212 pTrustee->pMultipleTrustee = NULL;
3213 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3214 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3215 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3216 pTrustee->ptstrName = (LPSTR)pObjName;
3219 /******************************************************************************
3220 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3222 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3223 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3224 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3226 DWORD ObjectsPresent = 0;
3228 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3229 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3231 /* Fill the OBJECTS_AND_NAME structure */
3232 pObjName->ObjectType = ObjectType;
3233 if (ObjectTypeName != NULL)
3235 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3238 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3239 if (InheritedObjectTypeName != NULL)
3241 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3244 pObjName->ObjectsPresent = ObjectsPresent;
3245 pObjName->ptstrName = Name;
3247 /* Fill the TRUSTEE structure */
3248 pTrustee->pMultipleTrustee = NULL;
3249 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3250 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3251 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3252 pTrustee->ptstrName = (LPWSTR)pObjName;
3255 /******************************************************************************
3256 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3258 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3259 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3261 DWORD ObjectsPresent = 0;
3263 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3265 /* Fill the OBJECTS_AND_SID structure */
3266 if (pObjectGuid != NULL)
3268 pObjSid->ObjectTypeGuid = *pObjectGuid;
3269 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3271 else
3273 ZeroMemory(&pObjSid->ObjectTypeGuid,
3274 sizeof(GUID));
3277 if (pInheritedObjectGuid != NULL)
3279 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3280 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3282 else
3284 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3285 sizeof(GUID));
3288 pObjSid->ObjectsPresent = ObjectsPresent;
3289 pObjSid->pSid = pSid;
3291 /* Fill the TRUSTEE structure */
3292 pTrustee->pMultipleTrustee = NULL;
3293 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3294 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3295 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3296 pTrustee->ptstrName = (LPSTR) pObjSid;
3299 /******************************************************************************
3300 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3302 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3303 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3305 DWORD ObjectsPresent = 0;
3307 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3309 /* Fill the OBJECTS_AND_SID structure */
3310 if (pObjectGuid != NULL)
3312 pObjSid->ObjectTypeGuid = *pObjectGuid;
3313 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3315 else
3317 ZeroMemory(&pObjSid->ObjectTypeGuid,
3318 sizeof(GUID));
3321 if (pInheritedObjectGuid != NULL)
3323 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3324 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3326 else
3328 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3329 sizeof(GUID));
3332 pObjSid->ObjectsPresent = ObjectsPresent;
3333 pObjSid->pSid = pSid;
3335 /* Fill the TRUSTEE structure */
3336 pTrustee->pMultipleTrustee = NULL;
3337 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3338 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3339 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3340 pTrustee->ptstrName = (LPWSTR) pObjSid;
3343 /******************************************************************************
3344 * BuildTrusteeWithSidA [ADVAPI32.@]
3346 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3348 TRACE("%p %p\n", pTrustee, pSid);
3350 pTrustee->pMultipleTrustee = NULL;
3351 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3352 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3353 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3354 pTrustee->ptstrName = pSid;
3357 /******************************************************************************
3358 * BuildTrusteeWithSidW [ADVAPI32.@]
3360 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3362 TRACE("%p %p\n", pTrustee, pSid);
3364 pTrustee->pMultipleTrustee = NULL;
3365 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3366 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3367 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3368 pTrustee->ptstrName = pSid;
3371 /******************************************************************************
3372 * BuildTrusteeWithNameA [ADVAPI32.@]
3374 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3376 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3378 pTrustee->pMultipleTrustee = NULL;
3379 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3380 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3381 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3382 pTrustee->ptstrName = name;
3385 /******************************************************************************
3386 * BuildTrusteeWithNameW [ADVAPI32.@]
3388 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3390 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3392 pTrustee->pMultipleTrustee = NULL;
3393 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3394 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3395 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3396 pTrustee->ptstrName = name;
3399 /******************************************************************************
3400 * GetTrusteeFormA [ADVAPI32.@]
3402 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3404 TRACE("(%p)\n", pTrustee);
3406 if (!pTrustee)
3407 return TRUSTEE_BAD_FORM;
3409 return pTrustee->TrusteeForm;
3412 /******************************************************************************
3413 * GetTrusteeFormW [ADVAPI32.@]
3415 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3417 TRACE("(%p)\n", pTrustee);
3419 if (!pTrustee)
3420 return TRUSTEE_BAD_FORM;
3422 return pTrustee->TrusteeForm;
3425 /******************************************************************************
3426 * GetTrusteeNameA [ADVAPI32.@]
3428 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3430 TRACE("(%p)\n", pTrustee);
3432 if (!pTrustee)
3433 return NULL;
3435 return pTrustee->ptstrName;
3438 /******************************************************************************
3439 * GetTrusteeNameW [ADVAPI32.@]
3441 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3443 TRACE("(%p)\n", pTrustee);
3445 if (!pTrustee)
3446 return NULL;
3448 return pTrustee->ptstrName;
3451 /******************************************************************************
3452 * GetTrusteeTypeA [ADVAPI32.@]
3454 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3456 TRACE("(%p)\n", pTrustee);
3458 if (!pTrustee)
3459 return TRUSTEE_IS_UNKNOWN;
3461 return pTrustee->TrusteeType;
3464 /******************************************************************************
3465 * GetTrusteeTypeW [ADVAPI32.@]
3467 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3469 TRACE("(%p)\n", pTrustee);
3471 if (!pTrustee)
3472 return TRUSTEE_IS_UNKNOWN;
3474 return pTrustee->TrusteeType;
3477 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3478 DWORD nAclInformationLength,
3479 ACL_INFORMATION_CLASS dwAclInformationClass )
3481 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3482 nAclInformationLength, dwAclInformationClass);
3484 return TRUE;
3487 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3489 DWORD len;
3491 switch (form)
3493 case TRUSTEE_IS_NAME:
3495 WCHAR *wstr = NULL;
3497 if (trustee_nameA)
3499 len = MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, NULL, 0 );
3500 if (!(wstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3501 return ERROR_NOT_ENOUGH_MEMORY;
3503 MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, wstr, len );
3506 *ptrustee_nameW = wstr;
3507 return ERROR_SUCCESS;
3509 case TRUSTEE_IS_OBJECTS_AND_NAME:
3511 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3512 OBJECTS_AND_NAME_W *objW = NULL;
3514 if (objA)
3516 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3517 return ERROR_NOT_ENOUGH_MEMORY;
3519 objW->ObjectsPresent = objA->ObjectsPresent;
3520 objW->ObjectType = objA->ObjectType;
3521 objW->ObjectTypeName = NULL;
3522 objW->InheritedObjectTypeName = NULL;
3523 objW->ptstrName = NULL;
3525 if (objA->ObjectTypeName)
3527 len = MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, NULL, 0 );
3528 if (!(objW->ObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3529 goto error;
3530 MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, objW->ObjectTypeName, len );
3533 if (objA->InheritedObjectTypeName)
3535 len = MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, NULL, 0 );
3536 if (!(objW->InheritedObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3537 goto error;
3538 MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, objW->InheritedObjectTypeName, len );
3541 if (objA->ptstrName)
3543 len = MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, NULL, 0 );
3544 if (!(objW->ptstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3545 goto error;
3546 MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, objW->ptstrName, len );
3550 *ptrustee_nameW = (WCHAR *)objW;
3551 return ERROR_SUCCESS;
3552 error:
3553 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3554 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3555 HeapFree( GetProcessHeap(), 0, objW );
3556 return ERROR_NOT_ENOUGH_MEMORY;
3558 /* These forms do not require conversion. */
3559 case TRUSTEE_IS_SID:
3560 case TRUSTEE_IS_OBJECTS_AND_SID:
3561 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3562 return ERROR_SUCCESS;
3563 default:
3564 return ERROR_INVALID_PARAMETER;
3568 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3570 switch (form)
3572 case TRUSTEE_IS_NAME:
3573 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3574 break;
3575 case TRUSTEE_IS_OBJECTS_AND_NAME:
3577 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3579 if (objW)
3581 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3582 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3583 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3584 HeapFree( GetProcessHeap(), 0, objW );
3587 break;
3589 /* Other forms did not require allocation, so no freeing is necessary. */
3590 default:
3591 break;
3595 /******************************************************************************
3596 * SetEntriesInAclA [ADVAPI32.@]
3598 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3599 PACL OldAcl, PACL* NewAcl )
3601 DWORD err = ERROR_SUCCESS;
3602 EXPLICIT_ACCESSW *pEntriesW;
3603 UINT alloc_index, free_index;
3605 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3607 if (NewAcl)
3608 *NewAcl = NULL;
3610 if (!count && !OldAcl)
3611 return ERROR_SUCCESS;
3613 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3614 if (!pEntriesW)
3615 return ERROR_NOT_ENOUGH_MEMORY;
3617 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3619 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3620 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3621 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3622 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3623 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3624 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3625 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3627 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3628 pEntries[alloc_index].Trustee.ptstrName,
3629 &pEntriesW[alloc_index].Trustee.ptstrName );
3630 if (err != ERROR_SUCCESS)
3632 if (err == ERROR_INVALID_PARAMETER)
3633 WARN("bad trustee form %d for trustee %d\n",
3634 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3636 goto cleanup;
3640 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3642 cleanup:
3643 /* Free any previously allocated trustee name buffers, taking into account
3644 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3645 * list. */
3646 for (free_index = 0; free_index < alloc_index; ++free_index)
3647 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3649 HeapFree( GetProcessHeap(), 0, pEntriesW );
3650 return err;
3653 /******************************************************************************
3654 * SetEntriesInAclW [ADVAPI32.@]
3656 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3657 PACL OldAcl, PACL* NewAcl )
3659 ULONG i;
3660 PSID *ppsid;
3661 DWORD ret = ERROR_SUCCESS;
3662 DWORD acl_size = sizeof(ACL);
3663 NTSTATUS status;
3665 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3667 if (NewAcl)
3668 *NewAcl = NULL;
3670 if (!count && !OldAcl)
3671 return ERROR_SUCCESS;
3673 /* allocate array of maximum sized sids allowed */
3674 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3675 if (!ppsid)
3676 return ERROR_OUTOFMEMORY;
3678 for (i = 0; i < count; i++)
3680 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3682 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3683 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3684 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3685 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3686 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3687 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3688 pEntries[i].Trustee.ptstrName);
3690 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3692 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3693 ret = ERROR_INVALID_PARAMETER;
3694 goto exit;
3697 switch (pEntries[i].Trustee.TrusteeForm)
3699 case TRUSTEE_IS_SID:
3700 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3701 ppsid[i], pEntries[i].Trustee.ptstrName))
3703 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3704 ret = ERROR_INVALID_PARAMETER;
3705 goto exit;
3707 break;
3708 case TRUSTEE_IS_NAME:
3710 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3711 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3712 SID_NAME_USE use;
3713 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3715 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3717 ret = GetLastError();
3718 goto exit;
3721 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3723 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3724 ret = ERROR_INVALID_PARAMETER;
3725 goto exit;
3727 break;
3729 case TRUSTEE_IS_OBJECTS_AND_SID:
3730 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3731 break;
3732 case TRUSTEE_IS_OBJECTS_AND_NAME:
3733 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3734 break;
3735 default:
3736 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3737 ret = ERROR_INVALID_PARAMETER;
3738 goto exit;
3741 /* Note: we overestimate the ACL size here as a tradeoff between
3742 * instructions (simplicity) and memory */
3743 switch (pEntries[i].grfAccessMode)
3745 case GRANT_ACCESS:
3746 case SET_ACCESS:
3747 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3748 break;
3749 case DENY_ACCESS:
3750 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3751 break;
3752 case SET_AUDIT_SUCCESS:
3753 case SET_AUDIT_FAILURE:
3754 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3755 break;
3756 case REVOKE_ACCESS:
3757 break;
3758 default:
3759 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3760 ret = ERROR_INVALID_PARAMETER;
3761 goto exit;
3765 if (OldAcl)
3767 ACL_SIZE_INFORMATION size_info;
3769 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3770 if (status != STATUS_SUCCESS)
3772 ret = RtlNtStatusToDosError(status);
3773 goto exit;
3775 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3778 *NewAcl = LocalAlloc(0, acl_size);
3779 if (!*NewAcl)
3781 ret = ERROR_OUTOFMEMORY;
3782 goto exit;
3785 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3786 if (status != STATUS_SUCCESS)
3788 ret = RtlNtStatusToDosError(status);
3789 goto exit;
3792 for (i = 0; i < count; i++)
3794 switch (pEntries[i].grfAccessMode)
3796 case GRANT_ACCESS:
3797 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3798 pEntries[i].grfInheritance,
3799 pEntries[i].grfAccessPermissions,
3800 ppsid[i]);
3801 break;
3802 case SET_ACCESS:
3804 ULONG j;
3805 BOOL add = TRUE;
3806 if (OldAcl)
3808 for (j = 0; ; j++)
3810 const ACE_HEADER *existing_ace_header;
3811 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3812 if (status != STATUS_SUCCESS)
3813 break;
3814 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3815 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3816 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3818 add = FALSE;
3819 break;
3823 if (add)
3824 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3825 pEntries[i].grfInheritance,
3826 pEntries[i].grfAccessPermissions,
3827 ppsid[i]);
3828 break;
3830 case DENY_ACCESS:
3831 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3832 pEntries[i].grfInheritance,
3833 pEntries[i].grfAccessPermissions,
3834 ppsid[i]);
3835 break;
3836 case SET_AUDIT_SUCCESS:
3837 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3838 pEntries[i].grfInheritance,
3839 pEntries[i].grfAccessPermissions,
3840 ppsid[i], TRUE, FALSE);
3841 break;
3842 case SET_AUDIT_FAILURE:
3843 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3844 pEntries[i].grfInheritance,
3845 pEntries[i].grfAccessPermissions,
3846 ppsid[i], FALSE, TRUE);
3847 break;
3848 default:
3849 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3853 if (OldAcl)
3855 for (i = 0; ; i++)
3857 BOOL add = TRUE;
3858 ULONG j;
3859 const ACE_HEADER *old_ace_header;
3860 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3861 if (status != STATUS_SUCCESS) break;
3862 for (j = 0; j < count; j++)
3864 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3865 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3866 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3868 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3869 add = FALSE;
3870 break;
3872 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3874 switch (old_ace_header->AceType)
3876 case ACCESS_ALLOWED_ACE_TYPE:
3877 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3878 add = FALSE;
3879 break;
3880 case ACCESS_DENIED_ACE_TYPE:
3881 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3882 add = FALSE;
3883 break;
3884 case SYSTEM_AUDIT_ACE_TYPE:
3885 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3886 add = FALSE;
3887 break;
3888 case SYSTEM_ALARM_ACE_TYPE:
3889 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3890 add = FALSE;
3891 break;
3892 default:
3893 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3896 if (!add)
3897 break;
3900 if (add)
3901 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3902 if (status != STATUS_SUCCESS)
3904 WARN("RtlAddAce failed with error 0x%08x\n", status);
3905 ret = RtlNtStatusToDosError(status);
3906 break;
3911 exit:
3912 HeapFree(GetProcessHeap(), 0, ppsid);
3913 return ret;
3916 /******************************************************************************
3917 * SetNamedSecurityInfoA [ADVAPI32.@]
3919 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3920 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3921 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3923 DWORD len;
3924 LPWSTR wstr = NULL;
3925 DWORD r;
3927 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3928 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3930 if( pObjectName )
3932 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3933 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3934 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3937 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3938 psidGroup, pDacl, pSacl );
3940 HeapFree( GetProcessHeap(), 0, wstr );
3942 return r;
3945 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3946 PSECURITY_DESCRIPTOR ModificationDescriptor,
3947 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3948 PGENERIC_MAPPING GenericMapping,
3949 HANDLE Token )
3951 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3952 ObjectsSecurityDescriptor, GenericMapping, Token);
3954 return TRUE;
3957 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3959 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3962 /******************************************************************************
3963 * AreAnyAccessesGranted [ADVAPI32.@]
3965 * Determines whether or not any of a set of specified access permissions have
3966 * been granted or not.
3968 * PARAMS
3969 * GrantedAccess [I] The permissions that have been granted.
3970 * DesiredAccess [I] The permissions that you want to have.
3972 * RETURNS
3973 * Nonzero if any of the permissions have been granted, zero if none of the
3974 * permissions have been granted.
3977 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3979 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3982 /******************************************************************************
3983 * SetNamedSecurityInfoW [ADVAPI32.@]
3985 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3986 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3987 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3989 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3990 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3991 return ERROR_SUCCESS;
3994 /******************************************************************************
3995 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3997 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3998 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4000 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4001 return ERROR_CALL_NOT_IMPLEMENTED;
4004 /******************************************************************************
4005 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4007 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4008 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4010 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4011 return ERROR_CALL_NOT_IMPLEMENTED;
4014 /******************************************************************************
4015 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4017 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4018 PACCESS_MASK pFailedAuditRights)
4020 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4021 return ERROR_CALL_NOT_IMPLEMENTED;
4025 /******************************************************************************
4026 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4028 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4029 PACCESS_MASK pFailedAuditRights)
4031 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4032 return ERROR_CALL_NOT_IMPLEMENTED;
4036 /******************************************************************************
4037 * ParseAclStringFlags
4039 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4041 DWORD flags = 0;
4042 LPCWSTR szAcl = *StringAcl;
4044 while (*szAcl != '(')
4046 if (*szAcl == 'P')
4048 flags |= SE_DACL_PROTECTED;
4050 else if (*szAcl == 'A')
4052 szAcl++;
4053 if (*szAcl == 'R')
4054 flags |= SE_DACL_AUTO_INHERIT_REQ;
4055 else if (*szAcl == 'I')
4056 flags |= SE_DACL_AUTO_INHERITED;
4058 szAcl++;
4061 *StringAcl = szAcl;
4062 return flags;
4065 /******************************************************************************
4066 * ParseAceStringType
4068 static const ACEFLAG AceType[] =
4070 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4071 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4072 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4073 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4075 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4076 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4077 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4078 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4080 { NULL, 0 },
4083 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4085 UINT len = 0;
4086 LPCWSTR szAcl = *StringAcl;
4087 const ACEFLAG *lpaf = AceType;
4089 while (*szAcl == ' ')
4090 szAcl++;
4092 while (lpaf->wstr &&
4093 (len = strlenW(lpaf->wstr)) &&
4094 strncmpW(lpaf->wstr, szAcl, len))
4095 lpaf++;
4097 if (!lpaf->wstr)
4098 return 0;
4100 *StringAcl = szAcl + len;
4101 return lpaf->value;
4105 /******************************************************************************
4106 * ParseAceStringFlags
4108 static const ACEFLAG AceFlags[] =
4110 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4111 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4112 { SDDL_INHERITED, INHERITED_ACE },
4113 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4114 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4115 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4116 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4117 { NULL, 0 },
4120 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4122 UINT len = 0;
4123 BYTE flags = 0;
4124 LPCWSTR szAcl = *StringAcl;
4126 while (*szAcl == ' ')
4127 szAcl++;
4129 while (*szAcl != ';')
4131 const ACEFLAG *lpaf = AceFlags;
4133 while (lpaf->wstr &&
4134 (len = strlenW(lpaf->wstr)) &&
4135 strncmpW(lpaf->wstr, szAcl, len))
4136 lpaf++;
4138 if (!lpaf->wstr)
4139 return 0;
4141 flags |= lpaf->value;
4142 szAcl += len;
4145 *StringAcl = szAcl;
4146 return flags;
4150 /******************************************************************************
4151 * ParseAceStringRights
4153 static const ACEFLAG AceRights[] =
4155 { SDDL_GENERIC_ALL, GENERIC_ALL },
4156 { SDDL_GENERIC_READ, GENERIC_READ },
4157 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4158 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4160 { SDDL_READ_CONTROL, READ_CONTROL },
4161 { SDDL_STANDARD_DELETE, DELETE },
4162 { SDDL_WRITE_DAC, WRITE_DAC },
4163 { SDDL_WRITE_OWNER, WRITE_OWNER },
4165 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4166 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4167 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4168 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4169 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4170 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4171 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4172 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4173 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4175 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4176 { SDDL_FILE_READ, FILE_GENERIC_READ },
4177 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4178 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4180 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4181 { SDDL_KEY_READ, KEY_READ },
4182 { SDDL_KEY_WRITE, KEY_WRITE },
4183 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4184 { NULL, 0 },
4187 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4189 UINT len = 0;
4190 DWORD rights = 0;
4191 LPCWSTR szAcl = *StringAcl;
4193 while (*szAcl == ' ')
4194 szAcl++;
4196 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4198 LPCWSTR p = szAcl;
4200 while (*p && *p != ';')
4201 p++;
4203 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4205 rights = strtoulW(szAcl, NULL, 16);
4206 szAcl = p;
4208 else
4209 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4211 else
4213 while (*szAcl != ';')
4215 const ACEFLAG *lpaf = AceRights;
4217 while (lpaf->wstr &&
4218 (len = strlenW(lpaf->wstr)) &&
4219 strncmpW(lpaf->wstr, szAcl, len))
4221 lpaf++;
4224 if (!lpaf->wstr)
4225 return 0;
4227 rights |= lpaf->value;
4228 szAcl += len;
4232 *StringAcl = szAcl;
4233 return rights;
4237 /******************************************************************************
4238 * ParseStringAclToAcl
4240 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4242 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4243 PACL pAcl, LPDWORD cBytes)
4245 DWORD val;
4246 DWORD sidlen;
4247 DWORD length = sizeof(ACL);
4248 DWORD acesize = 0;
4249 DWORD acecount = 0;
4250 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4251 DWORD error = ERROR_INVALID_ACL;
4253 TRACE("%s\n", debugstr_w(StringAcl));
4255 if (!StringAcl)
4256 return FALSE;
4258 if (pAcl) /* pAce is only useful if we're setting values */
4259 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4261 /* Parse ACL flags */
4262 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4264 /* Parse ACE */
4265 while (*StringAcl == '(')
4267 StringAcl++;
4269 /* Parse ACE type */
4270 val = ParseAceStringType(&StringAcl);
4271 if (pAce)
4272 pAce->Header.AceType = (BYTE) val;
4273 if (*StringAcl != ';')
4275 error = RPC_S_INVALID_STRING_UUID;
4276 goto lerr;
4278 StringAcl++;
4280 /* Parse ACE flags */
4281 val = ParseAceStringFlags(&StringAcl);
4282 if (pAce)
4283 pAce->Header.AceFlags = (BYTE) val;
4284 if (*StringAcl != ';')
4285 goto lerr;
4286 StringAcl++;
4288 /* Parse ACE rights */
4289 val = ParseAceStringRights(&StringAcl);
4290 if (pAce)
4291 pAce->Mask = val;
4292 if (*StringAcl != ';')
4293 goto lerr;
4294 StringAcl++;
4296 /* Parse ACE object guid */
4297 while (*StringAcl == ' ')
4298 StringAcl++;
4299 if (*StringAcl != ';')
4301 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4302 goto lerr;
4304 StringAcl++;
4306 /* Parse ACE inherit object guid */
4307 while (*StringAcl == ' ')
4308 StringAcl++;
4309 if (*StringAcl != ';')
4311 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4312 goto lerr;
4314 StringAcl++;
4316 /* Parse ACE account sid */
4317 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4319 while (*StringAcl && *StringAcl != ')')
4320 StringAcl++;
4323 if (*StringAcl != ')')
4324 goto lerr;
4325 StringAcl++;
4327 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4328 length += acesize;
4329 if (pAce)
4331 pAce->Header.AceSize = acesize;
4332 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4334 acecount++;
4337 *cBytes = length;
4339 if (length > 0xffff)
4341 ERR("ACL too large\n");
4342 goto lerr;
4345 if (pAcl)
4347 pAcl->AclRevision = ACL_REVISION;
4348 pAcl->Sbz1 = 0;
4349 pAcl->AclSize = length;
4350 pAcl->AceCount = acecount++;
4351 pAcl->Sbz2 = 0;
4353 return TRUE;
4355 lerr:
4356 SetLastError(error);
4357 WARN("Invalid ACE string format\n");
4358 return FALSE;
4362 /******************************************************************************
4363 * ParseStringSecurityDescriptorToSecurityDescriptor
4365 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4366 LPCWSTR StringSecurityDescriptor,
4367 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4368 LPDWORD cBytes)
4370 BOOL bret = FALSE;
4371 WCHAR toktype;
4372 WCHAR tok[MAX_PATH];
4373 LPCWSTR lptoken;
4374 LPBYTE lpNext = NULL;
4375 DWORD len;
4377 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4379 if (SecurityDescriptor)
4380 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4382 while (*StringSecurityDescriptor == ' ')
4383 StringSecurityDescriptor++;
4385 while (*StringSecurityDescriptor)
4387 toktype = *StringSecurityDescriptor;
4389 /* Expect char identifier followed by ':' */
4390 StringSecurityDescriptor++;
4391 if (*StringSecurityDescriptor != ':')
4393 SetLastError(ERROR_INVALID_PARAMETER);
4394 goto lend;
4396 StringSecurityDescriptor++;
4398 /* Extract token */
4399 lptoken = StringSecurityDescriptor;
4400 while (*lptoken && *lptoken != ':')
4401 lptoken++;
4403 if (*lptoken)
4404 lptoken--;
4406 len = lptoken - StringSecurityDescriptor;
4407 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4408 tok[len] = 0;
4410 switch (toktype)
4412 case 'O':
4414 DWORD bytes;
4416 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4417 goto lend;
4419 if (SecurityDescriptor)
4421 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4422 lpNext += bytes; /* Advance to next token */
4425 *cBytes += bytes;
4427 break;
4430 case 'G':
4432 DWORD bytes;
4434 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4435 goto lend;
4437 if (SecurityDescriptor)
4439 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4440 lpNext += bytes; /* Advance to next token */
4443 *cBytes += bytes;
4445 break;
4448 case 'D':
4450 DWORD flags;
4451 DWORD bytes;
4453 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4454 goto lend;
4456 if (SecurityDescriptor)
4458 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4459 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4460 lpNext += bytes; /* Advance to next token */
4463 *cBytes += bytes;
4465 break;
4468 case 'S':
4470 DWORD flags;
4471 DWORD bytes;
4473 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4474 goto lend;
4476 if (SecurityDescriptor)
4478 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4479 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4480 lpNext += bytes; /* Advance to next token */
4483 *cBytes += bytes;
4485 break;
4488 default:
4489 FIXME("Unknown token\n");
4490 SetLastError(ERROR_INVALID_PARAMETER);
4491 goto lend;
4494 StringSecurityDescriptor = lptoken;
4497 bret = TRUE;
4499 lend:
4500 return bret;
4503 /******************************************************************************
4504 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4506 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4507 LPCSTR StringSecurityDescriptor,
4508 DWORD StringSDRevision,
4509 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4510 PULONG SecurityDescriptorSize)
4512 UINT len;
4513 BOOL ret = FALSE;
4514 LPWSTR StringSecurityDescriptorW;
4516 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4517 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4519 if (StringSecurityDescriptorW)
4521 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4523 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4524 StringSDRevision, SecurityDescriptor,
4525 SecurityDescriptorSize);
4526 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4529 return ret;
4532 /******************************************************************************
4533 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4535 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4536 LPCWSTR StringSecurityDescriptor,
4537 DWORD StringSDRevision,
4538 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4539 PULONG SecurityDescriptorSize)
4541 DWORD cBytes;
4542 SECURITY_DESCRIPTOR* psd;
4543 BOOL bret = FALSE;
4545 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4547 if (GetVersion() & 0x80000000)
4549 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4550 goto lend;
4552 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4554 SetLastError(ERROR_INVALID_PARAMETER);
4555 goto lend;
4557 else if (StringSDRevision != SID_REVISION)
4559 SetLastError(ERROR_UNKNOWN_REVISION);
4560 goto lend;
4563 /* Compute security descriptor length */
4564 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4565 NULL, &cBytes))
4566 goto lend;
4568 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4569 if (!psd) goto lend;
4571 psd->Revision = SID_REVISION;
4572 psd->Control |= SE_SELF_RELATIVE;
4574 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4575 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4577 LocalFree(psd);
4578 goto lend;
4581 if (SecurityDescriptorSize)
4582 *SecurityDescriptorSize = cBytes;
4584 bret = TRUE;
4586 lend:
4587 TRACE(" ret=%d\n", bret);
4588 return bret;
4591 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4593 if (cch == -1)
4594 cch = strlenW(string);
4596 if (plen)
4597 *plen += cch;
4599 if (pwptr)
4601 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4602 *pwptr += cch;
4606 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4608 DWORD i;
4609 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4610 WCHAR subauthfmt[] = { '-','%','u',0 };
4611 WCHAR buf[26];
4612 SID *pisid = psid;
4614 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4616 SetLastError(ERROR_INVALID_SID);
4617 return FALSE;
4620 if (pisid->IdentifierAuthority.Value[0] ||
4621 pisid->IdentifierAuthority.Value[1])
4623 FIXME("not matching MS' bugs\n");
4624 SetLastError(ERROR_INVALID_SID);
4625 return FALSE;
4628 sprintfW( buf, fmt, pisid->Revision,
4629 MAKELONG(
4630 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4631 pisid->IdentifierAuthority.Value[4] ),
4632 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4633 pisid->IdentifierAuthority.Value[2] )
4634 ) );
4635 DumpString(buf, -1, pwptr, plen);
4637 for( i=0; i<pisid->SubAuthorityCount; i++ )
4639 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4640 DumpString(buf, -1, pwptr, plen);
4642 return TRUE;
4645 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4647 size_t i;
4648 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4650 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4652 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4653 return TRUE;
4657 return DumpSidNumeric(psid, pwptr, plen);
4660 static const LPCWSTR AceRightBitNames[32] = {
4661 SDDL_CREATE_CHILD, /* 0 */
4662 SDDL_DELETE_CHILD,
4663 SDDL_LIST_CHILDREN,
4664 SDDL_SELF_WRITE,
4665 SDDL_READ_PROPERTY, /* 4 */
4666 SDDL_WRITE_PROPERTY,
4667 SDDL_DELETE_TREE,
4668 SDDL_LIST_OBJECT,
4669 SDDL_CONTROL_ACCESS, /* 8 */
4670 NULL,
4671 NULL,
4672 NULL,
4673 NULL, /* 12 */
4674 NULL,
4675 NULL,
4676 NULL,
4677 SDDL_STANDARD_DELETE, /* 16 */
4678 SDDL_READ_CONTROL,
4679 SDDL_WRITE_DAC,
4680 SDDL_WRITE_OWNER,
4681 NULL, /* 20 */
4682 NULL,
4683 NULL,
4684 NULL,
4685 NULL, /* 24 */
4686 NULL,
4687 NULL,
4688 NULL,
4689 SDDL_GENERIC_ALL, /* 28 */
4690 SDDL_GENERIC_EXECUTE,
4691 SDDL_GENERIC_WRITE,
4692 SDDL_GENERIC_READ
4695 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4697 static const WCHAR fmtW[] = {'0','x','%','x',0};
4698 WCHAR buf[15];
4699 size_t i;
4701 if (mask == 0)
4702 return;
4704 /* first check if the right have name */
4705 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4707 if (AceRights[i].wstr == NULL)
4708 break;
4709 if (mask == AceRights[i].value)
4711 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4712 return;
4716 /* then check if it can be built from bit names */
4717 for (i = 0; i < 32; i++)
4719 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4721 /* can't be built from bit names */
4722 sprintfW(buf, fmtW, mask);
4723 DumpString(buf, -1, pwptr, plen);
4724 return;
4728 /* build from bit names */
4729 for (i = 0; i < 32; i++)
4730 if (mask & (1 << i))
4731 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4734 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4736 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4737 static const WCHAR openbr = '(';
4738 static const WCHAR closebr = ')';
4739 static const WCHAR semicolon = ';';
4741 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4743 SetLastError(ERROR_INVALID_ACL);
4744 return FALSE;
4747 piace = pace;
4748 DumpString(&openbr, 1, pwptr, plen);
4749 switch (piace->Header.AceType)
4751 case ACCESS_ALLOWED_ACE_TYPE:
4752 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4753 break;
4754 case ACCESS_DENIED_ACE_TYPE:
4755 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4756 break;
4757 case SYSTEM_AUDIT_ACE_TYPE:
4758 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4759 break;
4760 case SYSTEM_ALARM_ACE_TYPE:
4761 DumpString(SDDL_ALARM, -1, pwptr, plen);
4762 break;
4764 DumpString(&semicolon, 1, pwptr, plen);
4766 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4767 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4768 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4769 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4770 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4771 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4772 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4773 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4774 if (piace->Header.AceFlags & INHERITED_ACE)
4775 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4776 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4777 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4778 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4779 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4780 DumpString(&semicolon, 1, pwptr, plen);
4781 DumpRights(piace->Mask, pwptr, plen);
4782 DumpString(&semicolon, 1, pwptr, plen);
4783 /* objects not supported */
4784 DumpString(&semicolon, 1, pwptr, plen);
4785 /* objects not supported */
4786 DumpString(&semicolon, 1, pwptr, plen);
4787 if (!DumpSid(&piace->SidStart, pwptr, plen))
4788 return FALSE;
4789 DumpString(&closebr, 1, pwptr, plen);
4790 return TRUE;
4793 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4795 WORD count;
4796 int i;
4798 if (protected)
4799 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4800 if (autoInheritReq)
4801 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4802 if (autoInherited)
4803 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4805 if (pacl == NULL)
4806 return TRUE;
4808 if (!IsValidAcl(pacl))
4809 return FALSE;
4811 count = pacl->AceCount;
4812 for (i = 0; i < count; i++)
4814 LPVOID ace;
4815 if (!GetAce(pacl, i, &ace))
4816 return FALSE;
4817 if (!DumpAce(ace, pwptr, plen))
4818 return FALSE;
4821 return TRUE;
4824 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4826 static const WCHAR prefix[] = {'O',':',0};
4827 BOOL bDefaulted;
4828 PSID psid;
4830 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4831 return FALSE;
4833 if (psid == NULL)
4834 return TRUE;
4836 DumpString(prefix, -1, pwptr, plen);
4837 if (!DumpSid(psid, pwptr, plen))
4838 return FALSE;
4839 return TRUE;
4842 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4844 static const WCHAR prefix[] = {'G',':',0};
4845 BOOL bDefaulted;
4846 PSID psid;
4848 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4849 return FALSE;
4851 if (psid == NULL)
4852 return TRUE;
4854 DumpString(prefix, -1, pwptr, plen);
4855 if (!DumpSid(psid, pwptr, plen))
4856 return FALSE;
4857 return TRUE;
4860 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4862 static const WCHAR dacl[] = {'D',':',0};
4863 SECURITY_DESCRIPTOR_CONTROL control;
4864 BOOL present, defaulted;
4865 DWORD revision;
4866 PACL pacl;
4868 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4869 return FALSE;
4871 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4872 return FALSE;
4874 if (!present)
4875 return TRUE;
4877 DumpString(dacl, 2, pwptr, plen);
4878 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4879 return FALSE;
4880 return TRUE;
4883 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4885 static const WCHAR sacl[] = {'S',':',0};
4886 SECURITY_DESCRIPTOR_CONTROL control;
4887 BOOL present, defaulted;
4888 DWORD revision;
4889 PACL pacl;
4891 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4892 return FALSE;
4894 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4895 return FALSE;
4897 if (!present)
4898 return TRUE;
4900 DumpString(sacl, 2, pwptr, plen);
4901 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4902 return FALSE;
4903 return TRUE;
4906 /******************************************************************************
4907 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4909 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4911 ULONG len;
4912 WCHAR *wptr, *wstr;
4914 if (SDRevision != SDDL_REVISION_1)
4916 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4917 SetLastError(ERROR_UNKNOWN_REVISION);
4918 return FALSE;
4921 len = 0;
4922 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4923 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4924 return FALSE;
4925 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4926 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4927 return FALSE;
4928 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4929 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4930 return FALSE;
4931 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4932 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4933 return FALSE;
4935 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4936 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4937 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4938 return FALSE;
4939 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4940 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4941 return FALSE;
4942 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4943 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4944 return FALSE;
4945 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4946 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4947 return FALSE;
4948 *wptr = 0;
4950 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4951 *OutputString = wstr;
4952 if (OutputLen)
4953 *OutputLen = strlenW(*OutputString)+1;
4954 return TRUE;
4957 /******************************************************************************
4958 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4960 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4962 LPWSTR wstr;
4963 ULONG len;
4964 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4966 int lenA;
4968 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4969 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4970 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4971 LocalFree(wstr);
4973 if (OutputLen != NULL)
4974 *OutputLen = lenA;
4975 return TRUE;
4977 else
4979 *OutputString = NULL;
4980 if (OutputLen)
4981 *OutputLen = 0;
4982 return FALSE;
4986 /******************************************************************************
4987 * ConvertStringSidToSidW [ADVAPI32.@]
4989 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4991 BOOL bret = FALSE;
4992 DWORD cBytes;
4994 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4995 if (GetVersion() & 0x80000000)
4996 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4997 else if (!StringSid || !Sid)
4998 SetLastError(ERROR_INVALID_PARAMETER);
4999 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5001 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5003 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5004 if (!bret)
5005 LocalFree(*Sid);
5007 return bret;
5010 /******************************************************************************
5011 * ConvertStringSidToSidA [ADVAPI32.@]
5013 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5015 BOOL bret = FALSE;
5017 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5018 if (GetVersion() & 0x80000000)
5019 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5020 else if (!StringSid || !Sid)
5021 SetLastError(ERROR_INVALID_PARAMETER);
5022 else
5024 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
5025 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
5026 len * sizeof(WCHAR));
5028 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
5029 bret = ConvertStringSidToSidW(wStringSid, Sid);
5030 HeapFree(GetProcessHeap(), 0, wStringSid);
5032 return bret;
5035 /******************************************************************************
5036 * ConvertSidToStringSidW [ADVAPI32.@]
5038 * format of SID string is:
5039 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5040 * where
5041 * <rev> is the revision of the SID encoded as decimal
5042 * <auth> is the identifier authority encoded as hex
5043 * <subauthN> is the subauthority id encoded as decimal
5045 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5047 DWORD len = 0;
5048 LPWSTR wstr, wptr;
5050 TRACE("%p %p\n", pSid, pstr );
5052 len = 0;
5053 if (!DumpSidNumeric(pSid, NULL, &len))
5054 return FALSE;
5055 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5056 DumpSidNumeric(pSid, &wptr, NULL);
5057 *wptr = 0;
5059 *pstr = wstr;
5060 return TRUE;
5063 /******************************************************************************
5064 * ConvertSidToStringSidA [ADVAPI32.@]
5066 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5068 LPWSTR wstr = NULL;
5069 LPSTR str;
5070 UINT len;
5072 TRACE("%p %p\n", pSid, pstr );
5074 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5075 return FALSE;
5077 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5078 str = LocalAlloc( 0, len );
5079 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5080 LocalFree( wstr );
5082 *pstr = str;
5084 return TRUE;
5087 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5088 PSECURITY_DESCRIPTOR pdesc,
5089 PSECURITY_DESCRIPTOR cdesc,
5090 PSECURITY_DESCRIPTOR* ndesc,
5091 GUID* objtype,
5092 BOOL isdir,
5093 PGENERIC_MAPPING genmap )
5095 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5097 return FALSE;
5100 BOOL WINAPI CreatePrivateObjectSecurity(
5101 PSECURITY_DESCRIPTOR ParentDescriptor,
5102 PSECURITY_DESCRIPTOR CreatorDescriptor,
5103 PSECURITY_DESCRIPTOR* NewDescriptor,
5104 BOOL IsDirectoryObject,
5105 HANDLE Token,
5106 PGENERIC_MAPPING GenericMapping )
5108 SECURITY_DESCRIPTOR_RELATIVE *relative;
5109 DWORD needed, offset;
5110 BYTE *buffer;
5112 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5113 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5115 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5116 needed += sizeof(sidWorld);
5117 needed += sizeof(sidWorld);
5118 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5119 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5121 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, needed ))) return FALSE;
5122 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5123 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5125 HeapFree( GetProcessHeap(), 0, buffer );
5126 return FALSE;
5128 relative->Control |= SE_SELF_RELATIVE;
5129 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5131 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5132 relative->Owner = offset;
5133 offset += sizeof(sidWorld);
5135 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5136 relative->Group = offset;
5137 offset += sizeof(sidWorld);
5139 GetWorldAccessACL( (ACL *)(buffer + offset) );
5140 relative->Dacl = offset;
5141 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5143 GetWorldAccessACL( (ACL *)(buffer + offset) );
5144 relative->Sacl = offset;
5146 *NewDescriptor = relative;
5147 return TRUE;
5150 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5152 FIXME("%p - stub\n", ObjectDescriptor);
5154 HeapFree( GetProcessHeap(), 0, *ObjectDescriptor );
5155 return TRUE;
5158 BOOL WINAPI CreateProcessAsUserA(
5159 HANDLE hToken,
5160 LPCSTR lpApplicationName,
5161 LPSTR lpCommandLine,
5162 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5163 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5164 BOOL bInheritHandles,
5165 DWORD dwCreationFlags,
5166 LPVOID lpEnvironment,
5167 LPCSTR lpCurrentDirectory,
5168 LPSTARTUPINFOA lpStartupInfo,
5169 LPPROCESS_INFORMATION lpProcessInformation )
5171 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
5172 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5173 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5175 return FALSE;
5178 BOOL WINAPI CreateProcessAsUserW(
5179 HANDLE hToken,
5180 LPCWSTR lpApplicationName,
5181 LPWSTR lpCommandLine,
5182 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5183 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5184 BOOL bInheritHandles,
5185 DWORD dwCreationFlags,
5186 LPVOID lpEnvironment,
5187 LPCWSTR lpCurrentDirectory,
5188 LPSTARTUPINFOW lpStartupInfo,
5189 LPPROCESS_INFORMATION lpProcessInformation )
5191 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5192 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5193 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5194 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5196 /* We should create the process with a suspended main thread */
5197 if (!CreateProcessW (lpApplicationName,
5198 lpCommandLine,
5199 lpProcessAttributes,
5200 lpThreadAttributes,
5201 bInheritHandles,
5202 dwCreationFlags, /* CREATE_SUSPENDED */
5203 lpEnvironment,
5204 lpCurrentDirectory,
5205 lpStartupInfo,
5206 lpProcessInformation))
5208 return FALSE;
5211 return TRUE;
5214 /******************************************************************************
5215 * CreateProcessWithLogonW
5217 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5218 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5219 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5221 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5222 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5223 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5224 lpStartupInfo, lpProcessInformation);
5226 return FALSE;
5229 /******************************************************************************
5230 * DuplicateTokenEx [ADVAPI32.@]
5232 BOOL WINAPI DuplicateTokenEx(
5233 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5234 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5235 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5236 TOKEN_TYPE TokenType,
5237 PHANDLE DuplicateTokenHandle )
5239 OBJECT_ATTRIBUTES ObjectAttributes;
5241 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5242 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5244 InitializeObjectAttributes(
5245 &ObjectAttributes,
5246 NULL,
5247 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5248 NULL,
5249 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5251 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5252 dwDesiredAccess,
5253 &ObjectAttributes,
5254 ImpersonationLevel,
5255 TokenType,
5256 DuplicateTokenHandle ) );
5259 BOOL WINAPI DuplicateToken(
5260 HANDLE ExistingTokenHandle,
5261 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5262 PHANDLE DuplicateTokenHandle )
5264 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5265 NULL, ImpersonationLevel, TokenImpersonation,
5266 DuplicateTokenHandle );
5269 /******************************************************************************
5270 * ComputeStringSidSize
5272 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5274 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5276 int ctok = 0;
5277 while (*StringSid)
5279 if (*StringSid == '-')
5280 ctok++;
5281 StringSid++;
5284 if (ctok >= 3)
5285 return GetSidLengthRequired(ctok - 2);
5287 else /* String constant format - Only available in winxp and above */
5289 unsigned int i;
5291 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5292 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5293 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5296 return GetSidLengthRequired(0);
5299 /******************************************************************************
5300 * ParseStringSidToSid
5302 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5304 BOOL bret = FALSE;
5305 SID* pisid=pSid;
5307 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5308 if (!StringSid)
5310 SetLastError(ERROR_INVALID_PARAMETER);
5311 TRACE("StringSid is NULL, returning FALSE\n");
5312 return FALSE;
5315 while (*StringSid == ' ')
5316 StringSid++;
5318 *cBytes = ComputeStringSidSize(StringSid);
5319 if (!pisid) /* Simply compute the size */
5321 TRACE("only size requested, returning TRUE\n");
5322 return TRUE;
5325 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5327 DWORD i = 0, identAuth;
5328 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5330 StringSid += 2; /* Advance to Revision */
5331 pisid->Revision = atoiW(StringSid);
5333 if (pisid->Revision != SDDL_REVISION)
5335 TRACE("Revision %d is unknown\n", pisid->Revision);
5336 goto lend; /* ERROR_INVALID_SID */
5338 if (csubauth == 0)
5340 TRACE("SubAuthorityCount is 0\n");
5341 goto lend; /* ERROR_INVALID_SID */
5344 pisid->SubAuthorityCount = csubauth;
5346 /* Advance to identifier authority */
5347 while (*StringSid && *StringSid != '-')
5348 StringSid++;
5349 if (*StringSid == '-')
5350 StringSid++;
5352 /* MS' implementation can't handle values greater than 2^32 - 1, so
5353 * we don't either; assume most significant bytes are always 0
5355 pisid->IdentifierAuthority.Value[0] = 0;
5356 pisid->IdentifierAuthority.Value[1] = 0;
5357 identAuth = atoiW(StringSid);
5358 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5359 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5360 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5361 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5363 /* Advance to first sub authority */
5364 while (*StringSid && *StringSid != '-')
5365 StringSid++;
5366 if (*StringSid == '-')
5367 StringSid++;
5369 while (*StringSid)
5371 pisid->SubAuthority[i++] = atoiW(StringSid);
5373 while (*StringSid && *StringSid != '-')
5374 StringSid++;
5375 if (*StringSid == '-')
5376 StringSid++;
5379 if (i != pisid->SubAuthorityCount)
5380 goto lend; /* ERROR_INVALID_SID */
5382 bret = TRUE;
5384 else /* String constant format - Only available in winxp and above */
5386 unsigned int i;
5387 pisid->Revision = SDDL_REVISION;
5389 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5390 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5392 DWORD j;
5393 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5394 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5395 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5396 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5397 bret = TRUE;
5400 if (!bret)
5401 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5404 lend:
5405 if (!bret)
5406 SetLastError(ERROR_INVALID_SID);
5408 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5409 return bret;
5412 /******************************************************************************
5413 * GetNamedSecurityInfoA [ADVAPI32.@]
5415 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5416 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5417 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5418 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5420 DWORD len;
5421 LPWSTR wstr = NULL;
5422 DWORD r;
5424 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5425 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5427 if( pObjectName )
5429 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5430 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5431 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5434 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5435 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5437 HeapFree( GetProcessHeap(), 0, wstr );
5439 return r;
5442 /******************************************************************************
5443 * GetNamedSecurityInfoW [ADVAPI32.@]
5445 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5446 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5447 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5449 DWORD needed, offset;
5450 SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
5451 BYTE *buffer;
5453 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5454 group, dacl, sacl, descriptor );
5456 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5457 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5459 /* If no descriptor, we have to check that there's a pointer for the requested information */
5460 if( !descriptor && (
5461 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5462 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5463 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5464 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5465 return ERROR_INVALID_PARAMETER;
5467 needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5468 if (info & OWNER_SECURITY_INFORMATION)
5469 needed += sizeof(sidWorld);
5470 if (info & GROUP_SECURITY_INFORMATION)
5471 needed += sizeof(sidWorld);
5472 if (info & DACL_SECURITY_INFORMATION)
5473 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5474 if (info & SACL_SECURITY_INFORMATION)
5475 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5477 if(descriptor)
5479 /* must be freed by caller */
5480 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5481 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5483 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5485 HeapFree( GetProcessHeap(), 0, *descriptor );
5486 return ERROR_INVALID_SECURITY_DESCR;
5489 relative = *descriptor;
5490 relative->Control |= SE_SELF_RELATIVE;
5492 buffer = (BYTE *)relative;
5493 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5495 else
5497 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
5498 if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
5499 offset = 0;
5502 if (info & OWNER_SECURITY_INFORMATION)
5504 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5505 if(relative)
5506 relative->Owner = offset;
5507 if (owner)
5508 *owner = buffer + offset;
5509 offset += sizeof(sidWorld);
5511 if (info & GROUP_SECURITY_INFORMATION)
5513 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5514 if(relative)
5515 relative->Group = offset;
5516 if (group)
5517 *group = buffer + offset;
5518 offset += sizeof(sidWorld);
5520 if (info & DACL_SECURITY_INFORMATION)
5522 GetWorldAccessACL( (PACL)(buffer + offset) );
5523 if(relative)
5525 relative->Control |= SE_DACL_PRESENT;
5526 relative->Dacl = offset;
5528 if (dacl)
5529 *dacl = (PACL)(buffer + offset);
5530 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5532 if (info & SACL_SECURITY_INFORMATION)
5534 GetWorldAccessACL( (PACL)(buffer + offset) );
5535 if(relative)
5537 relative->Control |= SE_SACL_PRESENT;
5538 relative->Sacl = offset;
5540 if (sacl)
5541 *sacl = (PACL)(buffer + offset);
5544 return ERROR_SUCCESS;
5547 /******************************************************************************
5548 * GetNamedSecurityInfoExW [ADVAPI32.@]
5550 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5551 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5552 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5554 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5555 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5556 return ERROR_CALL_NOT_IMPLEMENTED;
5559 /******************************************************************************
5560 * GetNamedSecurityInfoExA [ADVAPI32.@]
5562 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5563 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5564 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5566 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5567 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5568 return ERROR_CALL_NOT_IMPLEMENTED;
5571 /******************************************************************************
5572 * DecryptFileW [ADVAPI32.@]
5574 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5576 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5577 return TRUE;
5580 /******************************************************************************
5581 * DecryptFileA [ADVAPI32.@]
5583 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5585 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5586 return TRUE;
5589 /******************************************************************************
5590 * EncryptFileW [ADVAPI32.@]
5592 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5594 FIXME("%s\n", debugstr_w(lpFileName));
5595 return TRUE;
5598 /******************************************************************************
5599 * EncryptFileA [ADVAPI32.@]
5601 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5603 FIXME("%s\n", debugstr_a(lpFileName));
5604 return TRUE;
5607 /******************************************************************************
5608 * FileEncryptionStatusW [ADVAPI32.@]
5610 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5612 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5613 if (!lpStatus)
5614 return FALSE;
5615 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5616 return TRUE;
5619 /******************************************************************************
5620 * FileEncryptionStatusA [ADVAPI32.@]
5622 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5624 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5625 if (!lpStatus)
5626 return FALSE;
5627 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5628 return TRUE;
5631 /******************************************************************************
5632 * SetSecurityInfo [ADVAPI32.@]
5634 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5635 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5636 PSID psidGroup, PACL pDacl, PACL pSacl) {
5637 FIXME("stub\n");
5638 return ERROR_SUCCESS;
5641 /******************************************************************************
5642 * SaferCreateLevel [ADVAPI32.@]
5644 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5645 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5647 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5649 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5650 return TRUE;
5653 /******************************************************************************
5654 * SaferComputeTokenFromLevel [ADVAPI32.@]
5656 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5657 DWORD flags, LPVOID reserved)
5659 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5661 *access_token = (HANDLE)0xdeadbeef;
5662 return TRUE;
5665 /******************************************************************************
5666 * SaferCloseLevel [ADVAPI32.@]
5668 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5670 FIXME("(%p) stub\n", handle);
5671 return TRUE;
5674 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5675 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5676 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5677 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5678 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5680 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5681 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5682 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5684 return ERROR_SUCCESS;
5687 /******************************************************************************
5688 * SaferGetPolicyInformation [ADVAPI32.@]
5690 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5691 PVOID buffer, PDWORD required, LPVOID lpReserved)
5693 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5694 return FALSE;
5697 /******************************************************************************
5698 * SaferSetLevelInformation [ADVAPI32.@]
5700 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5701 LPVOID buffer, DWORD size)
5703 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5704 return FALSE;