taskmgr: Remove dead code.
[wine/multimedia.git] / dlls / advapi32 / security.c
blob097b0da1b2b4fec98e0384d9f7a2db77ce305327
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 "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
41 #include "lmcons.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
49 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
50 PACL pAcl, LPDWORD cBytes);
51 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
52 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
53 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
54 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
55 LPCWSTR StringSecurityDescriptor,
56 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
57 LPDWORD cBytes);
58 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
60 typedef struct _ACEFLAG
62 LPCWSTR wstr;
63 DWORD value;
64 } ACEFLAG, *LPACEFLAG;
66 typedef struct _MAX_SID
68 /* same fields as struct _SID */
69 BYTE Revision;
70 BYTE SubAuthorityCount;
71 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
72 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
73 } MAX_SID;
75 typedef struct WELLKNOWNSID
77 WCHAR wstr[2];
78 WELL_KNOWN_SID_TYPE Type;
79 MAX_SID Sid;
80 } WELLKNOWNSID;
82 static const WELLKNOWNSID WellKnownSids[] =
84 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
85 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
86 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
87 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
88 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
89 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
90 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
91 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
92 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
93 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
94 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
95 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
96 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
97 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
98 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
99 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
100 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
101 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
102 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
103 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
104 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
105 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
106 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
107 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
108 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
109 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
110 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
111 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
112 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
113 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
114 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
115 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
116 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
117 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
118 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
119 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
120 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
121 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
122 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
123 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
124 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
125 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
126 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
127 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
128 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
129 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
130 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
131 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
132 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
133 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
134 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
135 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
138 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
139 typedef struct WELLKNOWNRID
141 WCHAR wstr[2];
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { {0,0}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { {0,0}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { {0,0}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { {0,0}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { {0,0}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { {0,0}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { {0,0}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { {0,0}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { {0,0}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { {0,0}, 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_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
191 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
192 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
193 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
194 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
195 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
196 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
197 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
198 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
199 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
200 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
201 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
202 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
203 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
205 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
206 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
207 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
208 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
209 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
210 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
211 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
212 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
213 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
214 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
215 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
216 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
218 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
219 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
220 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
221 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
222 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
223 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
224 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
225 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
226 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
227 static const WCHAR SELF[] = { 'S','E','L','F',0 };
228 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
229 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
230 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
231 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
232 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
233 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
235 static const AccountSid ACCOUNT_SIDS[] = {
236 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
237 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
238 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
239 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
240 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
241 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
242 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
244 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
259 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
260 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
261 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
262 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
264 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
265 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
270 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
271 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
272 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
273 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
279 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
282 * ACE access rights
284 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
285 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
286 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
287 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
289 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
290 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
291 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
292 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
293 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
294 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
295 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
296 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
297 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
299 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
300 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
301 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
302 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
304 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
305 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
306 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
307 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
309 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
310 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
311 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
312 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
315 * ACL flags
317 static const WCHAR SDDL_PROTECTED[] = {'P',0};
318 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
319 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
322 * ACE types
324 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
325 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
326 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
327 static const WCHAR SDDL_ALARM[] = {'A','L',0};
330 * ACE flags
332 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
333 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
334 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
335 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
336 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
337 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
338 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
340 const char * debugstr_sid(PSID sid)
342 int auth = 0;
343 SID * psid = sid;
345 if (psid == NULL)
346 return "(null)";
348 auth = psid->IdentifierAuthority.Value[5] +
349 (psid->IdentifierAuthority.Value[4] << 8) +
350 (psid->IdentifierAuthority.Value[3] << 16) +
351 (psid->IdentifierAuthority.Value[2] << 24);
353 switch (psid->SubAuthorityCount) {
354 case 0:
355 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
356 case 1:
357 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
358 psid->SubAuthority[0]);
359 case 2:
360 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
361 psid->SubAuthority[0], psid->SubAuthority[1]);
362 case 3:
363 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
364 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
365 case 4:
366 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
367 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
368 psid->SubAuthority[3]);
369 case 5:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[3], psid->SubAuthority[4]);
373 case 6:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
377 case 7:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
381 psid->SubAuthority[6]);
382 case 8:
383 return wine_dbg_sprintf("S-%d-%d-%u-%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], psid->SubAuthority[7]);
388 return "(too-big)";
391 /* set last error code from NT status and get the proper boolean return value */
392 /* used for functions that are a simple wrapper around the corresponding ntdll API */
393 static inline BOOL set_ntstatus( NTSTATUS status )
395 if (status) SetLastError( RtlNtStatusToDosError( status ));
396 return !status;
399 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
400 static inline DWORD get_security_file( LPWSTR full_file_name, DWORD access, HANDLE *file )
402 UNICODE_STRING file_nameW;
403 OBJECT_ATTRIBUTES attr;
404 IO_STATUS_BLOCK io;
405 NTSTATUS status;
407 if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
408 return ERROR_PATH_NOT_FOUND;
409 attr.Length = sizeof(attr);
410 attr.RootDirectory = 0;
411 attr.Attributes = OBJ_CASE_INSENSITIVE;
412 attr.ObjectName = &file_nameW;
413 attr.SecurityDescriptor = NULL;
414 status = NtCreateFile( file, access, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
415 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
416 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
417 RtlFreeUnicodeString( &file_nameW );
418 return RtlNtStatusToDosError( status );
421 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
422 static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service )
424 SC_HANDLE manager = 0;
425 DWORD err;
427 err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager );
428 if (err == ERROR_SUCCESS)
429 err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service );
430 CloseServiceHandle( manager );
431 return err;
434 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
435 static inline DWORD get_security_regkey( LPWSTR full_key_name, DWORD access, HANDLE *key )
437 WCHAR classes_rootW[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
438 WCHAR current_userW[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
439 WCHAR machineW[] = {'M','A','C','H','I','N','E',0};
440 WCHAR usersW[] = {'U','S','E','R','S',0};
441 LPWSTR p = strchrW(full_key_name, '\\');
442 int len = p-full_key_name;
443 HKEY hParent;
445 if (!p) return ERROR_INVALID_PARAMETER;
446 if (strncmpW( full_key_name, classes_rootW, len ) == 0)
447 hParent = HKEY_CLASSES_ROOT;
448 else if (strncmpW( full_key_name, current_userW, len ) == 0)
449 hParent = HKEY_CURRENT_USER;
450 else if (strncmpW( full_key_name, machineW, len ) == 0)
451 hParent = HKEY_LOCAL_MACHINE;
452 else if (strncmpW( full_key_name, usersW, len ) == 0)
453 hParent = HKEY_USERS;
454 else
455 return ERROR_INVALID_PARAMETER;
456 return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
459 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
461 static void GetWorldAccessACL(PACL pACL)
463 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
465 pACL->AclRevision = ACL_REVISION;
466 pACL->Sbz1 = 0;
467 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
468 pACL->AceCount = 1;
469 pACL->Sbz2 = 0;
471 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
472 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
473 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
474 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
475 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
478 /************************************************************
479 * ADVAPI_IsLocalComputer
481 * Checks whether the server name indicates local machine.
483 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
485 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
486 BOOL Result;
487 LPWSTR buf;
489 if (!ServerName || !ServerName[0])
490 return TRUE;
492 buf = heap_alloc(dwSize * sizeof(WCHAR));
493 Result = GetComputerNameW(buf, &dwSize);
494 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
495 ServerName += 2;
496 Result = Result && !lstrcmpW(ServerName, buf);
497 heap_free(buf);
499 return Result;
502 /************************************************************
503 * ADVAPI_GetComputerSid
505 BOOL ADVAPI_GetComputerSid(PSID sid)
507 static const struct /* same fields as struct SID */
509 BYTE Revision;
510 BYTE SubAuthorityCount;
511 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
512 DWORD SubAuthority[4];
513 } computer_sid =
514 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
516 memcpy( sid, &computer_sid, sizeof(computer_sid) );
517 return TRUE;
520 /* ##############################
521 ###### TOKEN FUNCTIONS ######
522 ##############################
525 /******************************************************************************
526 * OpenProcessToken [ADVAPI32.@]
527 * Opens the access token associated with a process handle.
529 * PARAMS
530 * ProcessHandle [I] Handle to process
531 * DesiredAccess [I] Desired access to process
532 * TokenHandle [O] Pointer to handle of open access token
534 * RETURNS
535 * Success: TRUE. TokenHandle contains the access token.
536 * Failure: FALSE.
538 * NOTES
539 * See NtOpenProcessToken.
541 BOOL WINAPI
542 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
543 HANDLE *TokenHandle )
545 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
548 /******************************************************************************
549 * OpenThreadToken [ADVAPI32.@]
551 * Opens the access token associated with a thread handle.
553 * PARAMS
554 * ThreadHandle [I] Handle to process
555 * DesiredAccess [I] Desired access to the thread
556 * OpenAsSelf [I] ???
557 * TokenHandle [O] Destination for the token handle
559 * RETURNS
560 * Success: TRUE. TokenHandle contains the access token.
561 * Failure: FALSE.
563 * NOTES
564 * See NtOpenThreadToken.
566 BOOL WINAPI
567 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
568 BOOL OpenAsSelf, HANDLE *TokenHandle)
570 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
573 BOOL WINAPI
574 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
575 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
577 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
578 PreviousState, ReturnLength));
581 /******************************************************************************
582 * AdjustTokenPrivileges [ADVAPI32.@]
584 * Adjust the privileges of an open token handle.
586 * PARAMS
587 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
588 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
589 * NewState [I] Desired new privileges of the token
590 * BufferLength [I] Length of NewState
591 * PreviousState [O] Destination for the previous state
592 * ReturnLength [I/O] Size of PreviousState
595 * RETURNS
596 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
597 * Failure: FALSE.
599 * NOTES
600 * See NtAdjustPrivilegesToken.
602 BOOL WINAPI
603 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
604 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
605 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
607 NTSTATUS status;
609 TRACE("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
610 PreviousState, ReturnLength);
612 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
613 NewState, BufferLength, PreviousState,
614 ReturnLength);
615 SetLastError( RtlNtStatusToDosError( status ));
616 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
617 return TRUE;
618 else
619 return FALSE;
622 /******************************************************************************
623 * CheckTokenMembership [ADVAPI32.@]
625 * Determine if an access token is a member of a SID.
627 * PARAMS
628 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
629 * SidToCheck [I] SID that possibly contains the token
630 * IsMember [O] Destination for result.
632 * RETURNS
633 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
634 * Failure: FALSE.
636 BOOL WINAPI
637 CheckTokenMembership( HANDLE token, PSID sid_to_check,
638 PBOOL is_member )
640 PTOKEN_GROUPS token_groups = NULL;
641 HANDLE thread_token = NULL;
642 DWORD size, i;
643 BOOL ret;
645 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
647 *is_member = FALSE;
649 if (!token)
651 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
653 HANDLE process_token;
654 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
655 if (!ret)
656 goto exit;
657 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
658 NULL, SecurityImpersonation, TokenImpersonation,
659 &thread_token);
660 CloseHandle(process_token);
661 if (!ret)
662 goto exit;
664 token = thread_token;
666 else
668 TOKEN_TYPE type;
670 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
671 if (!ret) goto exit;
673 if (type == TokenPrimary)
675 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
676 return FALSE;
680 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
681 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
682 goto exit;
684 token_groups = heap_alloc(size);
685 if (!token_groups)
687 ret = FALSE;
688 goto exit;
691 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
692 if (!ret)
693 goto exit;
695 for (i = 0; i < token_groups->GroupCount; i++)
697 TRACE("Groups[%d]: {0x%x, %s}\n", i,
698 token_groups->Groups[i].Attributes,
699 debugstr_sid(token_groups->Groups[i].Sid));
700 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
701 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
703 *is_member = TRUE;
704 TRACE("sid enabled and found in token\n");
705 break;
709 exit:
710 heap_free(token_groups);
711 if (thread_token != NULL) CloseHandle(thread_token);
713 return ret;
716 /******************************************************************************
717 * GetTokenInformation [ADVAPI32.@]
719 * Get a type of information about an access token.
721 * PARAMS
722 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
723 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
724 * tokeninfo [O] Destination for token information
725 * tokeninfolength [I] Length of tokeninfo
726 * retlen [O] Destination for returned token information length
728 * RETURNS
729 * Success: TRUE. tokeninfo contains retlen bytes of token information
730 * Failure: FALSE.
732 * NOTES
733 * See NtQueryInformationToken.
735 BOOL WINAPI
736 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
737 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
739 TRACE("(%p, %s, %p, %d, %p):\n",
740 token,
741 (tokeninfoclass == TokenUser) ? "TokenUser" :
742 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
743 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
744 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
745 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
746 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
747 (tokeninfoclass == TokenSource) ? "TokenSource" :
748 (tokeninfoclass == TokenType) ? "TokenType" :
749 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
750 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
751 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
752 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
753 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
754 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
755 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
756 "Unknown",
757 tokeninfo, tokeninfolength, retlen);
758 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
759 tokeninfolength, retlen));
762 /******************************************************************************
763 * SetTokenInformation [ADVAPI32.@]
765 * Set information for an access token.
767 * PARAMS
768 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
769 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
770 * tokeninfo [I] Token information to set
771 * tokeninfolength [I] Length of tokeninfo
773 * RETURNS
774 * Success: TRUE. The information for the token is set to tokeninfo.
775 * Failure: FALSE.
777 BOOL WINAPI
778 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
779 LPVOID tokeninfo, DWORD tokeninfolength )
781 TRACE("(%p, %s, %p, %d): stub\n",
782 token,
783 (tokeninfoclass == TokenUser) ? "TokenUser" :
784 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
785 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
786 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
787 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
788 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
789 (tokeninfoclass == TokenSource) ? "TokenSource" :
790 (tokeninfoclass == TokenType) ? "TokenType" :
791 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
792 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
793 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
794 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
795 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
796 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
797 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
798 "Unknown",
799 tokeninfo, tokeninfolength);
801 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
804 /*************************************************************************
805 * SetThreadToken [ADVAPI32.@]
807 * Assigns an 'impersonation token' to a thread so it can assume the
808 * security privileges of another thread or process. Can also remove
809 * a previously assigned token.
811 * PARAMS
812 * thread [O] Handle to thread to set the token for
813 * token [I] Token to set
815 * RETURNS
816 * Success: TRUE. The threads access token is set to token
817 * Failure: FALSE.
819 * NOTES
820 * Only supported on NT or higher. On Win9X this function does nothing.
821 * See SetTokenInformation.
823 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
825 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
826 ThreadImpersonationToken, &token, sizeof token ));
829 /*************************************************************************
830 * CreateRestrictedToken [ADVAPI32.@]
832 * Create a new more restricted token from an existing token.
834 * PARAMS
835 * baseToken [I] Token to base the new restricted token on
836 * flags [I] Options
837 * nDisableSids [I] Length of disableSids array
838 * disableSids [I] Array of SIDs to disable in the new token
839 * nDeletePrivs [I] Length of deletePrivs array
840 * deletePrivs [I] Array of privileges to delete in the new token
841 * nRestrictSids [I] Length of restrictSids array
842 * restrictSids [I] Array of SIDs to restrict in the new token
843 * newToken [O] Address where the new token is stored
845 * RETURNS
846 * Success: TRUE
847 * Failure: FALSE
849 BOOL WINAPI CreateRestrictedToken(
850 HANDLE baseToken,
851 DWORD flags,
852 DWORD nDisableSids,
853 PSID_AND_ATTRIBUTES disableSids,
854 DWORD nDeletePrivs,
855 PLUID_AND_ATTRIBUTES deletePrivs,
856 DWORD nRestrictSids,
857 PSID_AND_ATTRIBUTES restrictSids,
858 PHANDLE newToken)
860 TOKEN_TYPE type;
861 SECURITY_IMPERSONATION_LEVEL level = TokenImpersonationLevel;
862 DWORD size;
864 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
865 baseToken, flags, nDisableSids, disableSids,
866 nDeletePrivs, deletePrivs,
867 nRestrictSids, restrictSids,
868 newToken);
870 size = sizeof(type);
871 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
872 if (type == TokenImpersonation)
874 size = sizeof(level);
875 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
876 return FALSE;
878 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
881 /* ##############################
882 ###### SID FUNCTIONS ######
883 ##############################
886 /******************************************************************************
887 * AllocateAndInitializeSid [ADVAPI32.@]
889 * PARAMS
890 * pIdentifierAuthority []
891 * nSubAuthorityCount []
892 * nSubAuthority0 []
893 * nSubAuthority1 []
894 * nSubAuthority2 []
895 * nSubAuthority3 []
896 * nSubAuthority4 []
897 * nSubAuthority5 []
898 * nSubAuthority6 []
899 * nSubAuthority7 []
900 * pSid []
902 BOOL WINAPI
903 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
904 BYTE nSubAuthorityCount,
905 DWORD nSubAuthority0, DWORD nSubAuthority1,
906 DWORD nSubAuthority2, DWORD nSubAuthority3,
907 DWORD nSubAuthority4, DWORD nSubAuthority5,
908 DWORD nSubAuthority6, DWORD nSubAuthority7,
909 PSID *pSid )
911 return set_ntstatus( RtlAllocateAndInitializeSid(
912 pIdentifierAuthority, nSubAuthorityCount,
913 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
914 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
915 pSid ));
918 /******************************************************************************
919 * FreeSid [ADVAPI32.@]
921 * PARAMS
922 * pSid []
924 PVOID WINAPI
925 FreeSid( PSID pSid )
927 RtlFreeSid(pSid);
928 return NULL; /* is documented like this */
931 /******************************************************************************
932 * CopySid [ADVAPI32.@]
934 * PARAMS
935 * nDestinationSidLength []
936 * pDestinationSid []
937 * pSourceSid []
939 BOOL WINAPI
940 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
942 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
945 /******************************************************************************
946 * CreateWellKnownSid [ADVAPI32.@]
948 BOOL WINAPI
949 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
950 PSID DomainSid,
951 PSID pSid,
952 DWORD* cbSid)
954 unsigned int i;
955 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
957 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
959 SetLastError(ERROR_INVALID_PARAMETER);
960 return FALSE;
963 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
964 if (WellKnownSids[i].Type == WellKnownSidType) {
965 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
967 if (*cbSid < length)
969 *cbSid = length;
970 SetLastError(ERROR_INSUFFICIENT_BUFFER);
971 return FALSE;
973 if (!pSid)
975 SetLastError(ERROR_INVALID_PARAMETER);
976 return FALSE;
978 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
979 *cbSid = length;
980 return TRUE;
984 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
986 SetLastError(ERROR_INVALID_PARAMETER);
987 return FALSE;
990 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
991 if (WellKnownRids[i].Type == WellKnownSidType) {
992 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
993 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
994 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
996 if (*cbSid < output_sid_length)
998 *cbSid = output_sid_length;
999 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1000 return FALSE;
1002 if (!pSid)
1004 SetLastError(ERROR_INVALID_PARAMETER);
1005 return FALSE;
1007 CopyMemory(pSid, DomainSid, domain_sid_length);
1008 (*GetSidSubAuthorityCount(pSid))++;
1009 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1010 *cbSid = output_sid_length;
1011 return TRUE;
1014 SetLastError(ERROR_INVALID_PARAMETER);
1015 return FALSE;
1018 /******************************************************************************
1019 * IsWellKnownSid [ADVAPI32.@]
1021 BOOL WINAPI
1022 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1024 unsigned int i;
1025 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1027 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
1028 if (WellKnownSids[i].Type == WellKnownSidType)
1029 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1030 return TRUE;
1032 return FALSE;
1035 BOOL WINAPI
1036 IsTokenRestricted( HANDLE TokenHandle )
1038 TOKEN_GROUPS *groups;
1039 DWORD size;
1040 NTSTATUS status;
1041 BOOL restricted;
1043 TRACE("(%p)\n", TokenHandle);
1045 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1046 if (status != STATUS_BUFFER_TOO_SMALL)
1047 return FALSE;
1049 groups = heap_alloc(size);
1050 if (!groups)
1052 SetLastError(ERROR_OUTOFMEMORY);
1053 return FALSE;
1056 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1057 if (status != STATUS_SUCCESS)
1059 heap_free(groups);
1060 return set_ntstatus(status);
1063 restricted = groups->GroupCount > 0;
1064 heap_free(groups);
1066 return restricted;
1069 /******************************************************************************
1070 * IsValidSid [ADVAPI32.@]
1072 * PARAMS
1073 * pSid []
1075 BOOL WINAPI
1076 IsValidSid( PSID pSid )
1078 return RtlValidSid( pSid );
1081 /******************************************************************************
1082 * EqualSid [ADVAPI32.@]
1084 * PARAMS
1085 * pSid1 []
1086 * pSid2 []
1088 BOOL WINAPI
1089 EqualSid( PSID pSid1, PSID pSid2 )
1091 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1092 SetLastError(ERROR_SUCCESS);
1093 return ret;
1096 /******************************************************************************
1097 * EqualPrefixSid [ADVAPI32.@]
1099 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1101 return RtlEqualPrefixSid(pSid1, pSid2);
1104 /******************************************************************************
1105 * GetSidLengthRequired [ADVAPI32.@]
1107 * PARAMS
1108 * nSubAuthorityCount []
1110 DWORD WINAPI
1111 GetSidLengthRequired( BYTE nSubAuthorityCount )
1113 return RtlLengthRequiredSid(nSubAuthorityCount);
1116 /******************************************************************************
1117 * InitializeSid [ADVAPI32.@]
1119 * PARAMS
1120 * pIdentifierAuthority []
1122 BOOL WINAPI
1123 InitializeSid (
1124 PSID pSid,
1125 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1126 BYTE nSubAuthorityCount)
1128 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1131 DWORD WINAPI
1132 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1134 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1136 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1137 return 0;
1140 DWORD WINAPI
1141 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1143 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1145 return 1;
1148 /******************************************************************************
1149 * GetSidIdentifierAuthority [ADVAPI32.@]
1151 * PARAMS
1152 * pSid []
1154 PSID_IDENTIFIER_AUTHORITY WINAPI
1155 GetSidIdentifierAuthority( PSID pSid )
1157 return RtlIdentifierAuthoritySid(pSid);
1160 /******************************************************************************
1161 * GetSidSubAuthority [ADVAPI32.@]
1163 * PARAMS
1164 * pSid []
1165 * nSubAuthority []
1167 PDWORD WINAPI
1168 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1170 SetLastError(ERROR_SUCCESS);
1171 return RtlSubAuthoritySid(pSid, nSubAuthority);
1174 /******************************************************************************
1175 * GetSidSubAuthorityCount [ADVAPI32.@]
1177 * PARAMS
1178 * pSid []
1180 PUCHAR WINAPI
1181 GetSidSubAuthorityCount (PSID pSid)
1183 SetLastError(ERROR_SUCCESS);
1184 return RtlSubAuthorityCountSid(pSid);
1187 /******************************************************************************
1188 * GetLengthSid [ADVAPI32.@]
1190 * PARAMS
1191 * pSid []
1193 DWORD WINAPI
1194 GetLengthSid (PSID pSid)
1196 return RtlLengthSid(pSid);
1199 /* ##############################################
1200 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1201 ##############################################
1204 /******************************************************************************
1205 * BuildSecurityDescriptorA [ADVAPI32.@]
1207 * Builds a SD from
1209 * PARAMS
1210 * pOwner [I]
1211 * pGroup [I]
1212 * cCountOfAccessEntries [I]
1213 * pListOfAccessEntries [I]
1214 * cCountOfAuditEntries [I]
1215 * pListofAuditEntries [I]
1216 * pOldSD [I]
1217 * lpdwBufferLength [I/O]
1218 * pNewSD [O]
1220 * RETURNS
1221 * Success: ERROR_SUCCESS
1222 * Failure: nonzero error code from Winerror.h
1224 DWORD WINAPI BuildSecurityDescriptorA(
1225 IN PTRUSTEEA pOwner,
1226 IN PTRUSTEEA pGroup,
1227 IN ULONG cCountOfAccessEntries,
1228 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1229 IN ULONG cCountOfAuditEntries,
1230 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1231 IN PSECURITY_DESCRIPTOR pOldSD,
1232 IN OUT PULONG lpdwBufferLength,
1233 OUT PSECURITY_DESCRIPTOR* pNewSD)
1235 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1236 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1237 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1239 return ERROR_CALL_NOT_IMPLEMENTED;
1242 /******************************************************************************
1243 * BuildSecurityDescriptorW [ADVAPI32.@]
1245 * See BuildSecurityDescriptorA.
1247 DWORD WINAPI BuildSecurityDescriptorW(
1248 IN PTRUSTEEW pOwner,
1249 IN PTRUSTEEW pGroup,
1250 IN ULONG cCountOfAccessEntries,
1251 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1252 IN ULONG cCountOfAuditEntries,
1253 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1254 IN PSECURITY_DESCRIPTOR pOldSD,
1255 IN OUT PULONG lpdwBufferLength,
1256 OUT PSECURITY_DESCRIPTOR* pNewSD)
1258 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1259 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1260 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1262 return ERROR_CALL_NOT_IMPLEMENTED;
1265 /******************************************************************************
1266 * InitializeSecurityDescriptor [ADVAPI32.@]
1268 * PARAMS
1269 * pDescr []
1270 * revision []
1272 BOOL WINAPI
1273 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1275 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1279 /******************************************************************************
1280 * MakeAbsoluteSD [ADVAPI32.@]
1282 BOOL WINAPI MakeAbsoluteSD (
1283 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1284 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1285 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1286 OUT PACL pDacl,
1287 OUT LPDWORD lpdwDaclSize,
1288 OUT PACL pSacl,
1289 OUT LPDWORD lpdwSaclSize,
1290 OUT PSID pOwner,
1291 OUT LPDWORD lpdwOwnerSize,
1292 OUT PSID pPrimaryGroup,
1293 OUT LPDWORD lpdwPrimaryGroupSize)
1295 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1296 pAbsoluteSecurityDescriptor,
1297 lpdwAbsoluteSecurityDescriptorSize,
1298 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1299 pOwner, lpdwOwnerSize,
1300 pPrimaryGroup, lpdwPrimaryGroupSize));
1303 /******************************************************************************
1304 * GetKernelObjectSecurity [ADVAPI32.@]
1306 BOOL WINAPI GetKernelObjectSecurity(
1307 HANDLE Handle,
1308 SECURITY_INFORMATION RequestedInformation,
1309 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1310 DWORD nLength,
1311 LPDWORD lpnLengthNeeded )
1313 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1314 pSecurityDescriptor, nLength, lpnLengthNeeded);
1316 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1317 nLength, lpnLengthNeeded ));
1320 /******************************************************************************
1321 * GetPrivateObjectSecurity [ADVAPI32.@]
1323 BOOL WINAPI GetPrivateObjectSecurity(
1324 PSECURITY_DESCRIPTOR ObjectDescriptor,
1325 SECURITY_INFORMATION SecurityInformation,
1326 PSECURITY_DESCRIPTOR ResultantDescriptor,
1327 DWORD DescriptorLength,
1328 PDWORD ReturnLength )
1330 SECURITY_DESCRIPTOR desc;
1331 BOOL defaulted, present;
1332 PACL pacl;
1333 PSID psid;
1335 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1336 ResultantDescriptor, DescriptorLength, ReturnLength);
1338 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1339 return FALSE;
1341 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1343 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1344 return FALSE;
1345 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1348 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1350 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1351 return FALSE;
1352 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1355 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1357 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1358 return FALSE;
1359 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1362 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1364 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1365 return FALSE;
1366 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1369 *ReturnLength = DescriptorLength;
1370 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1373 /******************************************************************************
1374 * GetSecurityDescriptorLength [ADVAPI32.@]
1376 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1378 return RtlLengthSecurityDescriptor(pDescr);
1381 /******************************************************************************
1382 * GetSecurityDescriptorOwner [ADVAPI32.@]
1384 * PARAMS
1385 * pOwner []
1386 * lpbOwnerDefaulted []
1388 BOOL WINAPI
1389 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1390 LPBOOL lpbOwnerDefaulted )
1392 BOOLEAN defaulted;
1393 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1394 *lpbOwnerDefaulted = defaulted;
1395 return ret;
1398 /******************************************************************************
1399 * SetSecurityDescriptorOwner [ADVAPI32.@]
1401 * PARAMS
1403 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1404 PSID pOwner, BOOL bOwnerDefaulted)
1406 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1408 /******************************************************************************
1409 * GetSecurityDescriptorGroup [ADVAPI32.@]
1411 BOOL WINAPI GetSecurityDescriptorGroup(
1412 PSECURITY_DESCRIPTOR SecurityDescriptor,
1413 PSID *Group,
1414 LPBOOL GroupDefaulted)
1416 BOOLEAN defaulted;
1417 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1418 *GroupDefaulted = defaulted;
1419 return ret;
1421 /******************************************************************************
1422 * SetSecurityDescriptorGroup [ADVAPI32.@]
1424 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1425 PSID Group, BOOL GroupDefaulted)
1427 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1430 /******************************************************************************
1431 * IsValidSecurityDescriptor [ADVAPI32.@]
1433 * PARAMS
1434 * lpsecdesc []
1436 BOOL WINAPI
1437 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1439 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1442 /******************************************************************************
1443 * GetSecurityDescriptorDacl [ADVAPI32.@]
1445 BOOL WINAPI GetSecurityDescriptorDacl(
1446 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1447 OUT LPBOOL lpbDaclPresent,
1448 OUT PACL *pDacl,
1449 OUT LPBOOL lpbDaclDefaulted)
1451 BOOLEAN present, defaulted;
1452 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1453 *lpbDaclPresent = present;
1454 *lpbDaclDefaulted = defaulted;
1455 return ret;
1458 /******************************************************************************
1459 * SetSecurityDescriptorDacl [ADVAPI32.@]
1461 BOOL WINAPI
1462 SetSecurityDescriptorDacl (
1463 PSECURITY_DESCRIPTOR lpsd,
1464 BOOL daclpresent,
1465 PACL dacl,
1466 BOOL dacldefaulted )
1468 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1470 /******************************************************************************
1471 * GetSecurityDescriptorSacl [ADVAPI32.@]
1473 BOOL WINAPI GetSecurityDescriptorSacl(
1474 IN PSECURITY_DESCRIPTOR lpsd,
1475 OUT LPBOOL lpbSaclPresent,
1476 OUT PACL *pSacl,
1477 OUT LPBOOL lpbSaclDefaulted)
1479 BOOLEAN present, defaulted;
1480 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1481 *lpbSaclPresent = present;
1482 *lpbSaclDefaulted = defaulted;
1483 return ret;
1486 /**************************************************************************
1487 * SetSecurityDescriptorSacl [ADVAPI32.@]
1489 BOOL WINAPI SetSecurityDescriptorSacl (
1490 PSECURITY_DESCRIPTOR lpsd,
1491 BOOL saclpresent,
1492 PACL lpsacl,
1493 BOOL sacldefaulted)
1495 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1497 /******************************************************************************
1498 * MakeSelfRelativeSD [ADVAPI32.@]
1500 * PARAMS
1501 * lpabssecdesc []
1502 * lpselfsecdesc []
1503 * lpbuflen []
1505 BOOL WINAPI
1506 MakeSelfRelativeSD(
1507 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1508 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1509 IN OUT LPDWORD lpdwBufferLength)
1511 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1512 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1515 /******************************************************************************
1516 * GetSecurityDescriptorControl [ADVAPI32.@]
1519 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1520 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1522 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1525 /******************************************************************************
1526 * SetSecurityDescriptorControl [ADVAPI32.@]
1528 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1529 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1530 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1532 return set_ntstatus( RtlSetControlSecurityDescriptor(
1533 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1536 /* ##############################
1537 ###### ACL FUNCTIONS ######
1538 ##############################
1541 /*************************************************************************
1542 * InitializeAcl [ADVAPI32.@]
1544 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1546 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1549 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1551 IO_STATUS_BLOCK io_block;
1553 TRACE("(%p)\n", hNamedPipe);
1555 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1556 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1559 /******************************************************************************
1560 * AddAccessAllowedAce [ADVAPI32.@]
1562 BOOL WINAPI AddAccessAllowedAce(
1563 IN OUT PACL pAcl,
1564 IN DWORD dwAceRevision,
1565 IN DWORD AccessMask,
1566 IN PSID pSid)
1568 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1571 /******************************************************************************
1572 * AddAccessAllowedAceEx [ADVAPI32.@]
1574 BOOL WINAPI AddAccessAllowedAceEx(
1575 IN OUT PACL pAcl,
1576 IN DWORD dwAceRevision,
1577 IN DWORD AceFlags,
1578 IN DWORD AccessMask,
1579 IN PSID pSid)
1581 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1584 /******************************************************************************
1585 * AddAccessDeniedAce [ADVAPI32.@]
1587 BOOL WINAPI AddAccessDeniedAce(
1588 IN OUT PACL pAcl,
1589 IN DWORD dwAceRevision,
1590 IN DWORD AccessMask,
1591 IN PSID pSid)
1593 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1596 /******************************************************************************
1597 * AddAccessDeniedAceEx [ADVAPI32.@]
1599 BOOL WINAPI AddAccessDeniedAceEx(
1600 IN OUT PACL pAcl,
1601 IN DWORD dwAceRevision,
1602 IN DWORD AceFlags,
1603 IN DWORD AccessMask,
1604 IN PSID pSid)
1606 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1609 /******************************************************************************
1610 * AddAce [ADVAPI32.@]
1612 BOOL WINAPI AddAce(
1613 IN OUT PACL pAcl,
1614 IN DWORD dwAceRevision,
1615 IN DWORD dwStartingAceIndex,
1616 LPVOID pAceList,
1617 DWORD nAceListLength)
1619 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1622 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1624 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1625 return FALSE;
1628 /******************************************************************************
1629 * DeleteAce [ADVAPI32.@]
1631 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1633 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1636 /******************************************************************************
1637 * FindFirstFreeAce [ADVAPI32.@]
1639 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1641 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1644 /******************************************************************************
1645 * GetAce [ADVAPI32.@]
1647 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1649 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1652 /******************************************************************************
1653 * GetAclInformation [ADVAPI32.@]
1655 BOOL WINAPI GetAclInformation(
1656 PACL pAcl,
1657 LPVOID pAclInformation,
1658 DWORD nAclInformationLength,
1659 ACL_INFORMATION_CLASS dwAclInformationClass)
1661 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1662 nAclInformationLength, dwAclInformationClass));
1665 /******************************************************************************
1666 * IsValidAcl [ADVAPI32.@]
1668 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1670 return RtlValidAcl(pAcl);
1673 /* ##############################
1674 ###### MISC FUNCTIONS ######
1675 ##############################
1678 /******************************************************************************
1679 * AllocateLocallyUniqueId [ADVAPI32.@]
1681 * PARAMS
1682 * lpLuid []
1684 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1686 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1689 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1690 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1691 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1692 { '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 };
1693 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1694 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1695 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1696 { '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 };
1697 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1698 { '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 };
1699 static const WCHAR SE_TCB_NAME_W[] =
1700 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1701 static const WCHAR SE_SECURITY_NAME_W[] =
1702 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1703 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1704 { '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 };
1705 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1706 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1707 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1708 { '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 };
1709 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1710 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1711 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1712 { '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 };
1713 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1714 { '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 };
1715 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1716 { '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 };
1717 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1718 { '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 };
1719 static const WCHAR SE_BACKUP_NAME_W[] =
1720 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1721 static const WCHAR SE_RESTORE_NAME_W[] =
1722 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1723 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1724 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1725 static const WCHAR SE_DEBUG_NAME_W[] =
1726 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1727 static const WCHAR SE_AUDIT_NAME_W[] =
1728 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1729 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1730 { '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 };
1731 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1732 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1733 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1734 { '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 };
1735 static const WCHAR SE_UNDOCK_NAME_W[] =
1736 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1737 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1738 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1739 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1740 { '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 };
1741 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1742 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1743 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1744 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1745 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1746 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1748 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1750 NULL,
1751 NULL,
1752 SE_CREATE_TOKEN_NAME_W,
1753 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1754 SE_LOCK_MEMORY_NAME_W,
1755 SE_INCREASE_QUOTA_NAME_W,
1756 SE_MACHINE_ACCOUNT_NAME_W,
1757 SE_TCB_NAME_W,
1758 SE_SECURITY_NAME_W,
1759 SE_TAKE_OWNERSHIP_NAME_W,
1760 SE_LOAD_DRIVER_NAME_W,
1761 SE_SYSTEM_PROFILE_NAME_W,
1762 SE_SYSTEMTIME_NAME_W,
1763 SE_PROF_SINGLE_PROCESS_NAME_W,
1764 SE_INC_BASE_PRIORITY_NAME_W,
1765 SE_CREATE_PAGEFILE_NAME_W,
1766 SE_CREATE_PERMANENT_NAME_W,
1767 SE_BACKUP_NAME_W,
1768 SE_RESTORE_NAME_W,
1769 SE_SHUTDOWN_NAME_W,
1770 SE_DEBUG_NAME_W,
1771 SE_AUDIT_NAME_W,
1772 SE_SYSTEM_ENVIRONMENT_NAME_W,
1773 SE_CHANGE_NOTIFY_NAME_W,
1774 SE_REMOTE_SHUTDOWN_NAME_W,
1775 SE_UNDOCK_NAME_W,
1776 SE_SYNC_AGENT_NAME_W,
1777 SE_ENABLE_DELEGATION_NAME_W,
1778 SE_MANAGE_VOLUME_NAME_W,
1779 SE_IMPERSONATE_NAME_W,
1780 SE_CREATE_GLOBAL_NAME_W,
1783 /******************************************************************************
1784 * LookupPrivilegeValueW [ADVAPI32.@]
1786 * See LookupPrivilegeValueA.
1788 BOOL WINAPI
1789 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1791 UINT i;
1793 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1795 if (!ADVAPI_IsLocalComputer(lpSystemName))
1797 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1798 return FALSE;
1800 if (!lpName)
1802 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1803 return FALSE;
1805 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1807 if( !WellKnownPrivNames[i] )
1808 continue;
1809 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1810 continue;
1811 lpLuid->LowPart = i;
1812 lpLuid->HighPart = 0;
1813 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1814 lpLuid->HighPart, lpLuid->LowPart );
1815 return TRUE;
1817 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1818 return FALSE;
1821 /******************************************************************************
1822 * LookupPrivilegeValueA [ADVAPI32.@]
1824 * Retrieves LUID used on a system to represent the privilege name.
1826 * PARAMS
1827 * lpSystemName [I] Name of the system
1828 * lpName [I] Name of the privilege
1829 * lpLuid [O] Destination for the resulting LUID
1831 * RETURNS
1832 * Success: TRUE. lpLuid contains the requested LUID.
1833 * Failure: FALSE.
1835 BOOL WINAPI
1836 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1838 UNICODE_STRING lpSystemNameW;
1839 UNICODE_STRING lpNameW;
1840 BOOL ret;
1842 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1843 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1844 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1845 RtlFreeUnicodeString(&lpNameW);
1846 RtlFreeUnicodeString(&lpSystemNameW);
1847 return ret;
1850 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1851 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1853 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1854 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1856 return FALSE;
1859 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1860 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1862 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1863 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1865 return FALSE;
1868 /******************************************************************************
1869 * LookupPrivilegeNameA [ADVAPI32.@]
1871 * See LookupPrivilegeNameW.
1873 BOOL WINAPI
1874 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1875 LPDWORD cchName)
1877 UNICODE_STRING lpSystemNameW;
1878 BOOL ret;
1879 DWORD wLen = 0;
1881 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1883 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1884 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1885 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1887 LPWSTR lpNameW = heap_alloc(wLen * sizeof(WCHAR));
1889 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1890 &wLen);
1891 if (ret)
1893 /* Windows crashes if cchName is NULL, so will I */
1894 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1895 *cchName, NULL, NULL);
1897 if (len == 0)
1899 /* WideCharToMultiByte failed */
1900 ret = FALSE;
1902 else if (len > *cchName)
1904 *cchName = len;
1905 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1906 ret = FALSE;
1908 else
1910 /* WideCharToMultiByte succeeded, output length needs to be
1911 * length not including NULL terminator
1913 *cchName = len - 1;
1916 heap_free(lpNameW);
1918 RtlFreeUnicodeString(&lpSystemNameW);
1919 return ret;
1922 /******************************************************************************
1923 * LookupPrivilegeNameW [ADVAPI32.@]
1925 * Retrieves the privilege name referred to by the LUID lpLuid.
1927 * PARAMS
1928 * lpSystemName [I] Name of the system
1929 * lpLuid [I] Privilege value
1930 * lpName [O] Name of the privilege
1931 * cchName [I/O] Number of characters in lpName.
1933 * RETURNS
1934 * Success: TRUE. lpName contains the name of the privilege whose value is
1935 * *lpLuid.
1936 * Failure: FALSE.
1938 * REMARKS
1939 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1940 * using this function.
1941 * If the length of lpName is too small, on return *cchName will contain the
1942 * number of WCHARs needed to contain the privilege, including the NULL
1943 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1944 * On success, *cchName will contain the number of characters stored in
1945 * lpName, NOT including the NULL terminator.
1947 BOOL WINAPI
1948 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1949 LPDWORD cchName)
1951 size_t privNameLen;
1953 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1955 if (!ADVAPI_IsLocalComputer(lpSystemName))
1957 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1958 return FALSE;
1960 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1961 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1963 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1964 return FALSE;
1966 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1967 /* Windows crashes if cchName is NULL, so will I */
1968 if (*cchName <= privNameLen)
1970 *cchName = privNameLen + 1;
1971 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1972 return FALSE;
1974 else
1976 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1977 *cchName = privNameLen;
1978 return TRUE;
1982 /******************************************************************************
1983 * GetFileSecurityA [ADVAPI32.@]
1985 * Obtains Specified information about the security of a file or directory.
1987 * PARAMS
1988 * lpFileName [I] Name of the file to get info for
1989 * RequestedInformation [I] SE_ flags from "winnt.h"
1990 * pSecurityDescriptor [O] Destination for security information
1991 * nLength [I] Length of pSecurityDescriptor
1992 * lpnLengthNeeded [O] Destination for length of returned security information
1994 * RETURNS
1995 * Success: TRUE. pSecurityDescriptor contains the requested information.
1996 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1998 * NOTES
1999 * The information returned is constrained by the callers access rights and
2000 * privileges.
2002 BOOL WINAPI
2003 GetFileSecurityA( LPCSTR lpFileName,
2004 SECURITY_INFORMATION RequestedInformation,
2005 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2006 DWORD nLength, LPDWORD lpnLengthNeeded )
2008 BOOL r;
2009 LPWSTR name;
2011 name = SERV_dup(lpFileName);
2012 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2013 nLength, lpnLengthNeeded );
2014 heap_free( name );
2016 return r;
2019 /******************************************************************************
2020 * GetFileSecurityW [ADVAPI32.@]
2022 * See GetFileSecurityA.
2024 BOOL WINAPI
2025 GetFileSecurityW( LPCWSTR lpFileName,
2026 SECURITY_INFORMATION RequestedInformation,
2027 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2028 DWORD nLength, LPDWORD lpnLengthNeeded )
2030 HANDLE hfile;
2031 NTSTATUS status;
2032 DWORD access = 0;
2034 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2035 RequestedInformation, pSecurityDescriptor,
2036 nLength, lpnLengthNeeded);
2038 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2039 DACL_SECURITY_INFORMATION))
2040 access |= READ_CONTROL;
2041 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2042 access |= ACCESS_SYSTEM_SECURITY;
2044 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2045 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2046 if ( hfile == INVALID_HANDLE_VALUE )
2047 return FALSE;
2049 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2050 nLength, lpnLengthNeeded );
2051 CloseHandle( hfile );
2052 return set_ntstatus( status );
2056 /******************************************************************************
2057 * LookupAccountSidA [ADVAPI32.@]
2059 BOOL WINAPI
2060 LookupAccountSidA(
2061 IN LPCSTR system,
2062 IN PSID sid,
2063 OUT LPSTR account,
2064 IN OUT LPDWORD accountSize,
2065 OUT LPSTR domain,
2066 IN OUT LPDWORD domainSize,
2067 OUT PSID_NAME_USE name_use )
2069 DWORD len;
2070 BOOL r;
2071 LPWSTR systemW;
2072 LPWSTR accountW = NULL;
2073 LPWSTR domainW = NULL;
2074 DWORD accountSizeW = *accountSize;
2075 DWORD domainSizeW = *domainSize;
2077 systemW = SERV_dup(system);
2078 if (account)
2079 accountW = heap_alloc( accountSizeW * sizeof(WCHAR) );
2080 if (domain)
2081 domainW = heap_alloc( domainSizeW * sizeof(WCHAR) );
2083 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2085 if (r) {
2086 if (accountW && *accountSize) {
2087 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2088 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2089 *accountSize = len;
2090 } else
2091 *accountSize = accountSizeW + 1;
2093 if (domainW && *domainSize) {
2094 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2095 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2096 *domainSize = len;
2097 } else
2098 *domainSize = domainSizeW + 1;
2100 else
2102 *accountSize = accountSizeW + 1;
2103 *domainSize = domainSizeW + 1;
2106 heap_free( systemW );
2107 heap_free( accountW );
2108 heap_free( domainW );
2110 return r;
2113 /******************************************************************************
2114 * LookupAccountSidW [ADVAPI32.@]
2116 * PARAMS
2117 * system []
2118 * sid []
2119 * account []
2120 * accountSize []
2121 * domain []
2122 * domainSize []
2123 * name_use []
2126 BOOL WINAPI
2127 LookupAccountSidW(
2128 IN LPCWSTR system,
2129 IN PSID sid,
2130 OUT LPWSTR account,
2131 IN OUT LPDWORD accountSize,
2132 OUT LPWSTR domain,
2133 IN OUT LPDWORD domainSize,
2134 OUT PSID_NAME_USE name_use )
2136 unsigned int i, j;
2137 const WCHAR * ac = NULL;
2138 const WCHAR * dm = NULL;
2139 SID_NAME_USE use = 0;
2140 LPWSTR computer_name = NULL;
2141 LPWSTR account_name = NULL;
2143 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2144 debugstr_w(system),debugstr_sid(sid),
2145 account,accountSize,accountSize?*accountSize:0,
2146 domain,domainSize,domainSize?*domainSize:0,
2147 name_use);
2149 if (!ADVAPI_IsLocalComputer(system)) {
2150 FIXME("Only local computer supported!\n");
2151 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2152 return FALSE;
2155 /* check the well known SIDs first */
2156 for (i = 0; i <= 60; i++) {
2157 if (IsWellKnownSid(sid, i)) {
2158 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2159 if (ACCOUNT_SIDS[j].type == i) {
2160 ac = ACCOUNT_SIDS[j].account;
2161 dm = ACCOUNT_SIDS[j].domain;
2162 use = ACCOUNT_SIDS[j].name_use;
2165 break;
2169 if (dm == NULL) {
2170 MAX_SID local;
2172 /* check for the local computer next */
2173 if (ADVAPI_GetComputerSid(&local)) {
2174 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2175 BOOL result;
2177 computer_name = heap_alloc(size * sizeof(WCHAR));
2178 result = GetComputerNameW(computer_name, &size);
2180 if (result) {
2181 if (EqualSid(sid, &local)) {
2182 dm = computer_name;
2183 ac = Blank;
2184 use = 3;
2185 } else {
2186 local.SubAuthorityCount++;
2188 if (EqualPrefixSid(sid, &local)) {
2189 dm = computer_name;
2190 use = 1;
2191 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2192 case DOMAIN_USER_RID_ADMIN:
2193 ac = Administrator;
2194 break;
2195 case DOMAIN_USER_RID_GUEST:
2196 ac = Guest;
2197 break;
2198 case DOMAIN_GROUP_RID_ADMINS:
2199 ac = Domain_Admins;
2200 break;
2201 case DOMAIN_GROUP_RID_USERS:
2202 ac = Domain_Users;
2203 break;
2204 case DOMAIN_GROUP_RID_GUESTS:
2205 ac = Domain_Guests;
2206 break;
2207 case DOMAIN_GROUP_RID_COMPUTERS:
2208 ac = Domain_Computers;
2209 break;
2210 case DOMAIN_GROUP_RID_CONTROLLERS:
2211 ac = Domain_Controllers;
2212 break;
2213 case DOMAIN_GROUP_RID_CERT_ADMINS:
2214 ac = Cert_Publishers;
2215 break;
2216 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2217 ac = Schema_Admins;
2218 break;
2219 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2220 ac = Enterprise_Admins;
2221 break;
2222 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2223 ac = Group_Policy_Creator_Owners;
2224 break;
2225 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2226 ac = RAS_and_IAS_Servers;
2227 break;
2228 case 1000: /* first user account */
2229 size = UNLEN + 1;
2230 account_name = heap_alloc(size * sizeof(WCHAR));
2231 if (GetUserNameW(account_name, &size))
2232 ac = account_name;
2233 else
2234 dm = NULL;
2236 break;
2237 default:
2238 dm = NULL;
2239 break;
2247 if (dm) {
2248 DWORD ac_len = lstrlenW(ac);
2249 DWORD dm_len = lstrlenW(dm);
2250 BOOL status = TRUE;
2252 if (*accountSize > ac_len) {
2253 if (account)
2254 lstrcpyW(account, ac);
2256 if (*domainSize > dm_len) {
2257 if (domain)
2258 lstrcpyW(domain, dm);
2260 if ((*accountSize && *accountSize < ac_len) ||
2261 (!account && !*accountSize && ac_len) ||
2262 (*domainSize && *domainSize < dm_len) ||
2263 (!domain && !*domainSize && dm_len))
2265 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2266 status = FALSE;
2268 if (*domainSize)
2269 *domainSize = dm_len;
2270 else
2271 *domainSize = dm_len + 1;
2272 if (*accountSize)
2273 *accountSize = ac_len;
2274 else
2275 *accountSize = ac_len + 1;
2277 heap_free(account_name);
2278 heap_free(computer_name);
2279 if (status) *name_use = use;
2280 return status;
2283 heap_free(account_name);
2284 heap_free(computer_name);
2285 SetLastError(ERROR_NONE_MAPPED);
2286 return FALSE;
2289 /******************************************************************************
2290 * SetFileSecurityA [ADVAPI32.@]
2292 * See SetFileSecurityW.
2294 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2295 SECURITY_INFORMATION RequestedInformation,
2296 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2298 BOOL r;
2299 LPWSTR name;
2301 name = SERV_dup(lpFileName);
2302 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2303 heap_free( name );
2305 return r;
2308 /******************************************************************************
2309 * SetFileSecurityW [ADVAPI32.@]
2311 * Sets the security of a file or directory.
2313 * PARAMS
2314 * lpFileName []
2315 * RequestedInformation []
2316 * pSecurityDescriptor []
2318 * RETURNS
2319 * Success: TRUE.
2320 * Failure: FALSE.
2322 BOOL WINAPI
2323 SetFileSecurityW( LPCWSTR lpFileName,
2324 SECURITY_INFORMATION RequestedInformation,
2325 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2327 HANDLE file;
2328 DWORD access = 0;
2329 NTSTATUS status;
2331 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2332 pSecurityDescriptor );
2334 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2335 RequestedInformation & GROUP_SECURITY_INFORMATION)
2336 access |= WRITE_OWNER;
2337 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2338 access |= ACCESS_SYSTEM_SECURITY;
2339 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2340 access |= WRITE_DAC;
2342 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2343 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2344 if (file == INVALID_HANDLE_VALUE)
2345 return FALSE;
2347 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2348 CloseHandle( file );
2349 return set_ntstatus( status );
2352 /******************************************************************************
2353 * QueryWindows31FilesMigration [ADVAPI32.@]
2355 * PARAMS
2356 * x1 []
2358 BOOL WINAPI
2359 QueryWindows31FilesMigration( DWORD x1 )
2361 FIXME("(%d):stub\n",x1);
2362 return TRUE;
2365 /******************************************************************************
2366 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2368 * PARAMS
2369 * x1 []
2370 * x2 []
2371 * x3 []
2372 * x4 []
2374 BOOL WINAPI
2375 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2376 DWORD x4 )
2378 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2379 return TRUE;
2382 /******************************************************************************
2383 * NotifyBootConfigStatus [ADVAPI32.@]
2385 * PARAMS
2386 * x1 []
2388 BOOL WINAPI
2389 NotifyBootConfigStatus( BOOL x1 )
2391 FIXME("(0x%08d):stub\n",x1);
2392 return TRUE;
2395 /******************************************************************************
2396 * RevertToSelf [ADVAPI32.@]
2398 * Ends the impersonation of a user.
2400 * PARAMS
2401 * void []
2403 * RETURNS
2404 * Success: TRUE.
2405 * Failure: FALSE.
2407 BOOL WINAPI
2408 RevertToSelf( void )
2410 HANDLE Token = NULL;
2411 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2412 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2415 /******************************************************************************
2416 * ImpersonateSelf [ADVAPI32.@]
2418 * Makes an impersonation token that represents the process user and assigns
2419 * to the current thread.
2421 * PARAMS
2422 * ImpersonationLevel [I] Level at which to impersonate.
2424 * RETURNS
2425 * Success: TRUE.
2426 * Failure: FALSE.
2428 BOOL WINAPI
2429 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2431 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2434 /******************************************************************************
2435 * ImpersonateLoggedOnUser [ADVAPI32.@]
2437 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2439 DWORD size;
2440 NTSTATUS Status;
2441 HANDLE ImpersonationToken;
2442 TOKEN_TYPE Type;
2443 static BOOL warn = TRUE;
2445 if (warn)
2447 FIXME( "(%p)\n", hToken );
2448 warn = FALSE;
2450 if (!GetTokenInformation( hToken, TokenType, &Type,
2451 sizeof(TOKEN_TYPE), &size ))
2452 return FALSE;
2454 if (Type == TokenPrimary)
2456 OBJECT_ATTRIBUTES ObjectAttributes;
2458 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2460 Status = NtDuplicateToken( hToken,
2461 TOKEN_IMPERSONATE | TOKEN_QUERY,
2462 &ObjectAttributes,
2463 SecurityImpersonation,
2464 TokenImpersonation,
2465 &ImpersonationToken );
2466 if (Status != STATUS_SUCCESS)
2468 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2469 SetLastError( RtlNtStatusToDosError( Status ) );
2470 return FALSE;
2473 else
2474 ImpersonationToken = hToken;
2476 Status = NtSetInformationThread( GetCurrentThread(),
2477 ThreadImpersonationToken,
2478 &ImpersonationToken,
2479 sizeof(ImpersonationToken) );
2481 if (Type == TokenPrimary)
2482 NtClose( ImpersonationToken );
2484 if (Status != STATUS_SUCCESS)
2486 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2487 SetLastError( RtlNtStatusToDosError( Status ) );
2488 return FALSE;
2491 return TRUE;
2494 /******************************************************************************
2495 * AccessCheck [ADVAPI32.@]
2497 BOOL WINAPI
2498 AccessCheck(
2499 PSECURITY_DESCRIPTOR SecurityDescriptor,
2500 HANDLE ClientToken,
2501 DWORD DesiredAccess,
2502 PGENERIC_MAPPING GenericMapping,
2503 PPRIVILEGE_SET PrivilegeSet,
2504 LPDWORD PrivilegeSetLength,
2505 LPDWORD GrantedAccess,
2506 LPBOOL AccessStatus)
2508 NTSTATUS access_status;
2509 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2510 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2511 GrantedAccess, &access_status) );
2512 if (ret) *AccessStatus = set_ntstatus( access_status );
2513 return ret;
2517 /******************************************************************************
2518 * AccessCheckByType [ADVAPI32.@]
2520 BOOL WINAPI AccessCheckByType(
2521 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2522 PSID PrincipalSelfSid,
2523 HANDLE ClientToken,
2524 DWORD DesiredAccess,
2525 POBJECT_TYPE_LIST ObjectTypeList,
2526 DWORD ObjectTypeListLength,
2527 PGENERIC_MAPPING GenericMapping,
2528 PPRIVILEGE_SET PrivilegeSet,
2529 LPDWORD PrivilegeSetLength,
2530 LPDWORD GrantedAccess,
2531 LPBOOL AccessStatus)
2533 FIXME("stub\n");
2535 *AccessStatus = TRUE;
2537 return !*AccessStatus;
2540 /******************************************************************************
2541 * MapGenericMask [ADVAPI32.@]
2543 * Maps generic access rights into specific access rights according to the
2544 * supplied mapping.
2546 * PARAMS
2547 * AccessMask [I/O] Access rights.
2548 * GenericMapping [I] The mapping between generic and specific rights.
2550 * RETURNS
2551 * Nothing.
2553 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2555 RtlMapGenericMask( AccessMask, GenericMapping );
2558 /*************************************************************************
2559 * SetKernelObjectSecurity [ADVAPI32.@]
2561 BOOL WINAPI SetKernelObjectSecurity (
2562 IN HANDLE Handle,
2563 IN SECURITY_INFORMATION SecurityInformation,
2564 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2566 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2570 /******************************************************************************
2571 * AddAuditAccessAce [ADVAPI32.@]
2573 BOOL WINAPI AddAuditAccessAce(
2574 IN OUT PACL pAcl,
2575 IN DWORD dwAceRevision,
2576 IN DWORD dwAccessMask,
2577 IN PSID pSid,
2578 IN BOOL bAuditSuccess,
2579 IN BOOL bAuditFailure)
2581 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2582 bAuditSuccess, bAuditFailure) );
2585 /******************************************************************************
2586 * AddAuditAccessAce [ADVAPI32.@]
2588 BOOL WINAPI AddAuditAccessAceEx(
2589 IN OUT PACL pAcl,
2590 IN DWORD dwAceRevision,
2591 IN DWORD dwAceFlags,
2592 IN DWORD dwAccessMask,
2593 IN PSID pSid,
2594 IN BOOL bAuditSuccess,
2595 IN BOOL bAuditFailure)
2597 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2598 bAuditSuccess, bAuditFailure) );
2601 /******************************************************************************
2602 * LookupAccountNameA [ADVAPI32.@]
2604 BOOL WINAPI
2605 LookupAccountNameA(
2606 IN LPCSTR system,
2607 IN LPCSTR account,
2608 OUT PSID sid,
2609 OUT LPDWORD cbSid,
2610 LPSTR ReferencedDomainName,
2611 IN OUT LPDWORD cbReferencedDomainName,
2612 OUT PSID_NAME_USE name_use )
2614 BOOL ret;
2615 UNICODE_STRING lpSystemW;
2616 UNICODE_STRING lpAccountW;
2617 LPWSTR lpReferencedDomainNameW = NULL;
2619 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2620 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2622 if (ReferencedDomainName)
2623 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2625 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2626 cbReferencedDomainName, name_use);
2628 if (ret && lpReferencedDomainNameW)
2630 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2631 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2634 RtlFreeUnicodeString(&lpSystemW);
2635 RtlFreeUnicodeString(&lpAccountW);
2636 heap_free(lpReferencedDomainNameW);
2638 return ret;
2641 /******************************************************************************
2642 * lookup_user_account_name
2644 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2645 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2647 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2648 DWORD len = sizeof(buffer);
2649 HANDLE token;
2650 BOOL ret;
2651 PSID pSid;
2652 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2653 DWORD nameLen;
2655 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2657 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2658 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2661 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2662 CloseHandle( token );
2664 if (!ret) return FALSE;
2666 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2668 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2669 CopySid(*cbSid, Sid, pSid);
2670 if (*cbSid < GetLengthSid(pSid))
2672 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2673 ret = FALSE;
2675 *cbSid = GetLengthSid(pSid);
2677 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2678 if (!GetComputerNameW(domainName, &nameLen))
2680 domainName[0] = 0;
2681 nameLen = 0;
2683 if (*cchReferencedDomainName <= nameLen || !ret)
2685 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2686 nameLen += 1;
2687 ret = FALSE;
2689 else if (ReferencedDomainName)
2690 strcpyW(ReferencedDomainName, domainName);
2692 *cchReferencedDomainName = nameLen;
2694 if (ret)
2695 *peUse = SidTypeUser;
2697 return ret;
2700 /******************************************************************************
2701 * lookup_computer_account_name
2703 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2704 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2706 MAX_SID local;
2707 BOOL ret;
2708 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2709 DWORD nameLen;
2711 if ((ret = ADVAPI_GetComputerSid(&local)))
2713 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2714 CopySid(*cbSid, Sid, &local);
2715 if (*cbSid < GetLengthSid(&local))
2717 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2718 ret = FALSE;
2720 *cbSid = GetLengthSid(&local);
2723 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2724 if (!GetComputerNameW(domainName, &nameLen))
2726 domainName[0] = 0;
2727 nameLen = 0;
2729 if (*cchReferencedDomainName <= nameLen || !ret)
2731 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2732 nameLen += 1;
2733 ret = FALSE;
2735 else if (ReferencedDomainName)
2736 strcpyW(ReferencedDomainName, domainName);
2738 *cchReferencedDomainName = nameLen;
2740 if (ret)
2741 *peUse = SidTypeDomain;
2743 return ret;
2746 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2747 LSA_UNICODE_STRING *domain )
2749 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2751 while (p > str->Buffer && *p != '\\') p--;
2753 if (*p == '\\')
2755 domain->Buffer = str->Buffer;
2756 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2758 account->Buffer = p + 1;
2759 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2761 else
2763 domain->Buffer = NULL;
2764 domain->Length = 0;
2766 account->Buffer = str->Buffer;
2767 account->Length = str->Length;
2771 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2773 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2775 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2776 return TRUE;
2778 return FALSE;
2781 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2783 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2785 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2786 return TRUE;
2788 if (ACCOUNT_SIDS[idx].alias)
2790 len = strlenW( ACCOUNT_SIDS[idx].alias );
2791 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2792 return TRUE;
2794 return FALSE;
2798 * Helper function for LookupAccountNameW
2800 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2801 PSID Sid, LPDWORD cbSid,
2802 LPWSTR ReferencedDomainName,
2803 LPDWORD cchReferencedDomainName,
2804 PSID_NAME_USE peUse, BOOL *handled )
2806 PSID pSid;
2807 LSA_UNICODE_STRING account, domain;
2808 BOOL ret = TRUE;
2809 ULONG i;
2811 *handled = FALSE;
2812 split_domain_account( account_and_domain, &account, &domain );
2814 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2816 /* check domain first */
2817 if (domain.Buffer && !match_domain( i, &domain )) continue;
2819 if (match_account( i, &account ))
2821 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2823 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
2825 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2827 if (*cbSid < sidLen)
2829 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2830 ret = FALSE;
2832 else if (Sid)
2834 CopySid(*cbSid, Sid, pSid);
2836 *cbSid = sidLen;
2839 len = strlenW( ACCOUNT_SIDS[i].domain );
2840 if (*cchReferencedDomainName <= len || !ret)
2842 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2843 len++;
2844 ret = FALSE;
2846 else if (ReferencedDomainName)
2848 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2851 *cchReferencedDomainName = len;
2852 if (ret)
2853 *peUse = ACCOUNT_SIDS[i].name_use;
2855 heap_free(pSid);
2856 *handled = TRUE;
2857 return ret;
2860 return ret;
2863 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2864 PSID Sid, LPDWORD cbSid,
2865 LPWSTR ReferencedDomainName,
2866 LPDWORD cchReferencedDomainName,
2867 PSID_NAME_USE peUse, BOOL *handled )
2869 DWORD nameLen;
2870 LPWSTR userName = NULL;
2871 LSA_UNICODE_STRING account, domain;
2872 BOOL ret = TRUE;
2874 *handled = FALSE;
2875 split_domain_account( account_and_domain, &account, &domain );
2877 /* Let the current Unix user id masquerade as first Windows user account */
2879 nameLen = UNLEN + 1;
2880 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
2882 if (domain.Buffer)
2884 /* check to make sure this account is on this computer */
2885 if (GetComputerNameW( userName, &nameLen ) &&
2886 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2888 SetLastError(ERROR_NONE_MAPPED);
2889 ret = FALSE;
2891 nameLen = UNLEN + 1;
2894 if (GetUserNameW( userName, &nameLen ) &&
2895 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2897 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2898 *handled = TRUE;
2900 else
2902 nameLen = UNLEN + 1;
2903 if (GetComputerNameW( userName, &nameLen ) &&
2904 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2906 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2907 *handled = TRUE;
2911 heap_free(userName);
2912 return ret;
2915 /******************************************************************************
2916 * LookupAccountNameW [ADVAPI32.@]
2918 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2919 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2920 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2922 BOOL ret, handled;
2923 LSA_UNICODE_STRING account;
2925 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2926 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2928 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2930 FIXME("remote computer not supported\n");
2931 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2932 return FALSE;
2935 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2937 lpAccountName = BUILTIN;
2940 RtlInitUnicodeString( &account, lpAccountName );
2942 /* Check well known SIDs first */
2943 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2944 cchReferencedDomainName, peUse, &handled );
2945 if (handled)
2946 return ret;
2948 /* Check user names */
2949 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2950 cchReferencedDomainName, peUse, &handled);
2951 if (handled)
2952 return ret;
2954 SetLastError( ERROR_NONE_MAPPED );
2955 return FALSE;
2958 /******************************************************************************
2959 * PrivilegeCheck [ADVAPI32.@]
2961 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2963 BOOL ret;
2964 BOOLEAN Result;
2966 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2968 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2969 if (ret)
2970 *pfResult = Result;
2971 return ret;
2974 /******************************************************************************
2975 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2977 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2978 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2979 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2980 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2982 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2983 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2984 SecurityDescriptor, DesiredAccess, GenericMapping,
2985 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2986 return TRUE;
2989 /******************************************************************************
2990 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2992 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2993 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2994 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2995 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2997 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2998 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2999 SecurityDescriptor, DesiredAccess, GenericMapping,
3000 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3001 return TRUE;
3004 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3006 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3008 return TRUE;
3011 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3013 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3015 return TRUE;
3018 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3020 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3022 return TRUE;
3025 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3026 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3027 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3028 LPBOOL GenerateOnClose)
3030 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3031 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3032 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3033 GenerateOnClose);
3035 return TRUE;
3038 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3039 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3040 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3041 LPBOOL GenerateOnClose)
3043 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3044 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3045 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3046 GenerateOnClose);
3048 return TRUE;
3051 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3052 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3054 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3055 DesiredAccess, Privileges, AccessGranted);
3057 return TRUE;
3060 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3061 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3063 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3064 DesiredAccess, Privileges, AccessGranted);
3066 return TRUE;
3069 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3070 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3072 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3073 ClientToken, Privileges, AccessGranted);
3075 return TRUE;
3078 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3079 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3081 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3082 ClientToken, Privileges, AccessGranted);
3084 return TRUE;
3087 /******************************************************************************
3088 * GetSecurityInfo [ADVAPI32.@]
3090 * Retrieves a copy of the security descriptor associated with an object.
3092 * PARAMS
3093 * hObject [I] A handle for the object.
3094 * ObjectType [I] The type of object.
3095 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3096 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3097 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3098 * ppDacl [O] If non-null, receives a pointer to the DACL.
3099 * ppSacl [O] If non-null, receives a pointer to the SACL.
3100 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3101 * which must be freed with LocalFree.
3103 * RETURNS
3104 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3106 DWORD WINAPI GetSecurityInfo(
3107 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3108 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3109 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3110 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3113 PSECURITY_DESCRIPTOR sd;
3114 NTSTATUS status;
3115 ULONG n1, n2;
3116 BOOL present, defaulted;
3118 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3119 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3121 /* If no descriptor, we have to check that there's a pointer for the requested information */
3122 if( !ppSecurityDescriptor && (
3123 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3124 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3125 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3126 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3127 return ERROR_INVALID_PARAMETER;
3129 switch (ObjectType)
3131 case SE_SERVICE:
3132 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3133 break;
3134 default:
3135 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3136 break;
3138 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3139 return RtlNtStatusToDosError(status);
3141 sd = LocalAlloc(0, n1);
3142 if (!sd)
3143 return ERROR_NOT_ENOUGH_MEMORY;
3145 switch (ObjectType)
3147 case SE_SERVICE:
3148 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3149 break;
3150 default:
3151 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3152 break;
3154 if (status != STATUS_SUCCESS)
3156 LocalFree(sd);
3157 return RtlNtStatusToDosError(status);
3160 if (ppsidOwner)
3162 *ppsidOwner = NULL;
3163 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3165 if (ppsidGroup)
3167 *ppsidGroup = NULL;
3168 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3170 if (ppDacl)
3172 *ppDacl = NULL;
3173 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3175 if (ppSacl)
3177 *ppSacl = NULL;
3178 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3180 if (ppSecurityDescriptor)
3181 *ppSecurityDescriptor = sd;
3183 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3184 * NULL, because native happily returns the SIDs and ACLs that are requested
3185 * in this case.
3188 return ERROR_SUCCESS;
3191 /******************************************************************************
3192 * GetSecurityInfoExA [ADVAPI32.@]
3194 DWORD WINAPI GetSecurityInfoExA(
3195 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3196 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3197 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3198 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3201 FIXME("stub!\n");
3202 return ERROR_BAD_PROVIDER;
3205 /******************************************************************************
3206 * GetSecurityInfoExW [ADVAPI32.@]
3208 DWORD WINAPI GetSecurityInfoExW(
3209 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3210 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3211 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3212 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3215 FIXME("stub!\n");
3216 return ERROR_BAD_PROVIDER;
3219 /******************************************************************************
3220 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3222 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3223 LPSTR pTrusteeName, DWORD AccessPermissions,
3224 ACCESS_MODE AccessMode, DWORD Inheritance )
3226 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3227 AccessPermissions, AccessMode, Inheritance);
3229 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3230 pExplicitAccess->grfAccessMode = AccessMode;
3231 pExplicitAccess->grfInheritance = Inheritance;
3233 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3234 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3235 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3236 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3237 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3240 /******************************************************************************
3241 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3243 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3244 LPWSTR pTrusteeName, DWORD AccessPermissions,
3245 ACCESS_MODE AccessMode, DWORD Inheritance )
3247 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3248 AccessPermissions, AccessMode, Inheritance);
3250 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3251 pExplicitAccess->grfAccessMode = AccessMode;
3252 pExplicitAccess->grfInheritance = Inheritance;
3254 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3255 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3256 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3257 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3258 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3261 /******************************************************************************
3262 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3264 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3265 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3266 LPSTR InheritedObjectTypeName, LPSTR Name )
3268 DWORD ObjectsPresent = 0;
3270 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3271 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3273 /* Fill the OBJECTS_AND_NAME structure */
3274 pObjName->ObjectType = ObjectType;
3275 if (ObjectTypeName != NULL)
3277 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3280 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3281 if (InheritedObjectTypeName != NULL)
3283 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3286 pObjName->ObjectsPresent = ObjectsPresent;
3287 pObjName->ptstrName = Name;
3289 /* Fill the TRUSTEE structure */
3290 pTrustee->pMultipleTrustee = NULL;
3291 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3292 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3293 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3294 pTrustee->ptstrName = (LPSTR)pObjName;
3297 /******************************************************************************
3298 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3300 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3301 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3302 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3304 DWORD ObjectsPresent = 0;
3306 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3307 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3309 /* Fill the OBJECTS_AND_NAME structure */
3310 pObjName->ObjectType = ObjectType;
3311 if (ObjectTypeName != NULL)
3313 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3316 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3317 if (InheritedObjectTypeName != NULL)
3319 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3322 pObjName->ObjectsPresent = ObjectsPresent;
3323 pObjName->ptstrName = Name;
3325 /* Fill the TRUSTEE structure */
3326 pTrustee->pMultipleTrustee = NULL;
3327 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3328 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3329 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3330 pTrustee->ptstrName = (LPWSTR)pObjName;
3333 /******************************************************************************
3334 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3336 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3337 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3339 DWORD ObjectsPresent = 0;
3341 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3343 /* Fill the OBJECTS_AND_SID structure */
3344 if (pObjectGuid != NULL)
3346 pObjSid->ObjectTypeGuid = *pObjectGuid;
3347 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3349 else
3351 ZeroMemory(&pObjSid->ObjectTypeGuid,
3352 sizeof(GUID));
3355 if (pInheritedObjectGuid != NULL)
3357 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3358 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3360 else
3362 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3363 sizeof(GUID));
3366 pObjSid->ObjectsPresent = ObjectsPresent;
3367 pObjSid->pSid = pSid;
3369 /* Fill the TRUSTEE structure */
3370 pTrustee->pMultipleTrustee = NULL;
3371 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3372 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3373 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3374 pTrustee->ptstrName = (LPSTR) pObjSid;
3377 /******************************************************************************
3378 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3380 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3381 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3383 DWORD ObjectsPresent = 0;
3385 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3387 /* Fill the OBJECTS_AND_SID structure */
3388 if (pObjectGuid != NULL)
3390 pObjSid->ObjectTypeGuid = *pObjectGuid;
3391 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3393 else
3395 ZeroMemory(&pObjSid->ObjectTypeGuid,
3396 sizeof(GUID));
3399 if (pInheritedObjectGuid != NULL)
3401 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3402 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3404 else
3406 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3407 sizeof(GUID));
3410 pObjSid->ObjectsPresent = ObjectsPresent;
3411 pObjSid->pSid = pSid;
3413 /* Fill the TRUSTEE structure */
3414 pTrustee->pMultipleTrustee = NULL;
3415 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3416 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3417 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3418 pTrustee->ptstrName = (LPWSTR) pObjSid;
3421 /******************************************************************************
3422 * BuildTrusteeWithSidA [ADVAPI32.@]
3424 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3426 TRACE("%p %p\n", pTrustee, pSid);
3428 pTrustee->pMultipleTrustee = NULL;
3429 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3430 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3431 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3432 pTrustee->ptstrName = pSid;
3435 /******************************************************************************
3436 * BuildTrusteeWithSidW [ADVAPI32.@]
3438 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3440 TRACE("%p %p\n", pTrustee, pSid);
3442 pTrustee->pMultipleTrustee = NULL;
3443 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3444 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3445 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3446 pTrustee->ptstrName = pSid;
3449 /******************************************************************************
3450 * BuildTrusteeWithNameA [ADVAPI32.@]
3452 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3454 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3456 pTrustee->pMultipleTrustee = NULL;
3457 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3458 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3459 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3460 pTrustee->ptstrName = name;
3463 /******************************************************************************
3464 * BuildTrusteeWithNameW [ADVAPI32.@]
3466 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3468 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3470 pTrustee->pMultipleTrustee = NULL;
3471 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3472 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3473 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3474 pTrustee->ptstrName = name;
3477 /******************************************************************************
3478 * GetTrusteeFormA [ADVAPI32.@]
3480 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3482 TRACE("(%p)\n", pTrustee);
3484 if (!pTrustee)
3485 return TRUSTEE_BAD_FORM;
3487 return pTrustee->TrusteeForm;
3490 /******************************************************************************
3491 * GetTrusteeFormW [ADVAPI32.@]
3493 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3495 TRACE("(%p)\n", pTrustee);
3497 if (!pTrustee)
3498 return TRUSTEE_BAD_FORM;
3500 return pTrustee->TrusteeForm;
3503 /******************************************************************************
3504 * GetTrusteeNameA [ADVAPI32.@]
3506 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3508 TRACE("(%p)\n", pTrustee);
3510 if (!pTrustee)
3511 return NULL;
3513 return pTrustee->ptstrName;
3516 /******************************************************************************
3517 * GetTrusteeNameW [ADVAPI32.@]
3519 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3521 TRACE("(%p)\n", pTrustee);
3523 if (!pTrustee)
3524 return NULL;
3526 return pTrustee->ptstrName;
3529 /******************************************************************************
3530 * GetTrusteeTypeA [ADVAPI32.@]
3532 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3534 TRACE("(%p)\n", pTrustee);
3536 if (!pTrustee)
3537 return TRUSTEE_IS_UNKNOWN;
3539 return pTrustee->TrusteeType;
3542 /******************************************************************************
3543 * GetTrusteeTypeW [ADVAPI32.@]
3545 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3547 TRACE("(%p)\n", pTrustee);
3549 if (!pTrustee)
3550 return TRUSTEE_IS_UNKNOWN;
3552 return pTrustee->TrusteeType;
3555 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3556 DWORD nAclInformationLength,
3557 ACL_INFORMATION_CLASS dwAclInformationClass )
3559 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3560 nAclInformationLength, dwAclInformationClass);
3562 return TRUE;
3565 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3567 switch (form)
3569 case TRUSTEE_IS_NAME:
3571 *ptrustee_nameW = SERV_dup(trustee_nameA);
3572 return ERROR_SUCCESS;
3574 case TRUSTEE_IS_OBJECTS_AND_NAME:
3576 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3577 OBJECTS_AND_NAME_W *objW = NULL;
3579 if (objA)
3581 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3582 return ERROR_NOT_ENOUGH_MEMORY;
3584 objW->ObjectsPresent = objA->ObjectsPresent;
3585 objW->ObjectType = objA->ObjectType;
3586 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3587 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3588 objW->ptstrName = SERV_dup(objA->ptstrName);
3591 *ptrustee_nameW = (WCHAR *)objW;
3592 return ERROR_SUCCESS;
3594 /* These forms do not require conversion. */
3595 case TRUSTEE_IS_SID:
3596 case TRUSTEE_IS_OBJECTS_AND_SID:
3597 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3598 return ERROR_SUCCESS;
3599 default:
3600 return ERROR_INVALID_PARAMETER;
3604 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3606 switch (form)
3608 case TRUSTEE_IS_NAME:
3609 heap_free( trustee_nameW );
3610 break;
3611 case TRUSTEE_IS_OBJECTS_AND_NAME:
3613 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3615 if (objW)
3617 heap_free( objW->ptstrName );
3618 heap_free( objW->InheritedObjectTypeName );
3619 heap_free( objW->ObjectTypeName );
3620 heap_free( objW );
3623 break;
3625 /* Other forms did not require allocation, so no freeing is necessary. */
3626 default:
3627 break;
3631 /******************************************************************************
3632 * SetEntriesInAclA [ADVAPI32.@]
3634 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3635 PACL OldAcl, PACL* NewAcl )
3637 DWORD err = ERROR_SUCCESS;
3638 EXPLICIT_ACCESSW *pEntriesW;
3639 UINT alloc_index, free_index;
3641 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3643 if (NewAcl)
3644 *NewAcl = NULL;
3646 if (!count && !OldAcl)
3647 return ERROR_SUCCESS;
3649 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3650 if (!pEntriesW)
3651 return ERROR_NOT_ENOUGH_MEMORY;
3653 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3655 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3656 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3657 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3658 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3659 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3660 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3661 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3663 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3664 pEntries[alloc_index].Trustee.ptstrName,
3665 &pEntriesW[alloc_index].Trustee.ptstrName );
3666 if (err != ERROR_SUCCESS)
3668 if (err == ERROR_INVALID_PARAMETER)
3669 WARN("bad trustee form %d for trustee %d\n",
3670 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3672 goto cleanup;
3676 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3678 cleanup:
3679 /* Free any previously allocated trustee name buffers, taking into account
3680 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3681 * list. */
3682 for (free_index = 0; free_index < alloc_index; ++free_index)
3683 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3685 heap_free( pEntriesW );
3686 return err;
3689 /******************************************************************************
3690 * SetEntriesInAclW [ADVAPI32.@]
3692 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3693 PACL OldAcl, PACL* NewAcl )
3695 ULONG i;
3696 PSID *ppsid;
3697 DWORD ret = ERROR_SUCCESS;
3698 DWORD acl_size = sizeof(ACL);
3699 NTSTATUS status;
3701 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3703 if (NewAcl)
3704 *NewAcl = NULL;
3706 if (!count && !OldAcl)
3707 return ERROR_SUCCESS;
3709 /* allocate array of maximum sized sids allowed */
3710 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3711 if (!ppsid)
3712 return ERROR_OUTOFMEMORY;
3714 for (i = 0; i < count; i++)
3716 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3718 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3719 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3720 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3721 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3722 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3723 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3724 pEntries[i].Trustee.ptstrName);
3726 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3728 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3729 ret = ERROR_INVALID_PARAMETER;
3730 goto exit;
3733 switch (pEntries[i].Trustee.TrusteeForm)
3735 case TRUSTEE_IS_SID:
3736 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3737 ppsid[i], pEntries[i].Trustee.ptstrName))
3739 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3740 ret = ERROR_INVALID_PARAMETER;
3741 goto exit;
3743 break;
3744 case TRUSTEE_IS_NAME:
3746 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3747 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3748 SID_NAME_USE use;
3749 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3751 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3753 ret = GetLastError();
3754 goto exit;
3757 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3759 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3760 ret = ERROR_INVALID_PARAMETER;
3761 goto exit;
3763 break;
3765 case TRUSTEE_IS_OBJECTS_AND_SID:
3766 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3767 break;
3768 case TRUSTEE_IS_OBJECTS_AND_NAME:
3769 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3770 break;
3771 default:
3772 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3773 ret = ERROR_INVALID_PARAMETER;
3774 goto exit;
3777 /* Note: we overestimate the ACL size here as a tradeoff between
3778 * instructions (simplicity) and memory */
3779 switch (pEntries[i].grfAccessMode)
3781 case GRANT_ACCESS:
3782 case SET_ACCESS:
3783 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3784 break;
3785 case DENY_ACCESS:
3786 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3787 break;
3788 case SET_AUDIT_SUCCESS:
3789 case SET_AUDIT_FAILURE:
3790 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3791 break;
3792 case REVOKE_ACCESS:
3793 break;
3794 default:
3795 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3796 ret = ERROR_INVALID_PARAMETER;
3797 goto exit;
3801 if (OldAcl)
3803 ACL_SIZE_INFORMATION size_info;
3805 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3806 if (status != STATUS_SUCCESS)
3808 ret = RtlNtStatusToDosError(status);
3809 goto exit;
3811 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3814 *NewAcl = LocalAlloc(0, acl_size);
3815 if (!*NewAcl)
3817 ret = ERROR_OUTOFMEMORY;
3818 goto exit;
3821 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3822 if (status != STATUS_SUCCESS)
3824 ret = RtlNtStatusToDosError(status);
3825 goto exit;
3828 for (i = 0; i < count; i++)
3830 switch (pEntries[i].grfAccessMode)
3832 case GRANT_ACCESS:
3833 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3834 pEntries[i].grfInheritance,
3835 pEntries[i].grfAccessPermissions,
3836 ppsid[i]);
3837 break;
3838 case SET_ACCESS:
3840 ULONG j;
3841 BOOL add = TRUE;
3842 if (OldAcl)
3844 for (j = 0; ; j++)
3846 const ACE_HEADER *existing_ace_header;
3847 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3848 if (status != STATUS_SUCCESS)
3849 break;
3850 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3851 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3852 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3854 add = FALSE;
3855 break;
3859 if (add)
3860 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3861 pEntries[i].grfInheritance,
3862 pEntries[i].grfAccessPermissions,
3863 ppsid[i]);
3864 break;
3866 case DENY_ACCESS:
3867 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3868 pEntries[i].grfInheritance,
3869 pEntries[i].grfAccessPermissions,
3870 ppsid[i]);
3871 break;
3872 case SET_AUDIT_SUCCESS:
3873 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3874 pEntries[i].grfInheritance,
3875 pEntries[i].grfAccessPermissions,
3876 ppsid[i], TRUE, FALSE);
3877 break;
3878 case SET_AUDIT_FAILURE:
3879 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3880 pEntries[i].grfInheritance,
3881 pEntries[i].grfAccessPermissions,
3882 ppsid[i], FALSE, TRUE);
3883 break;
3884 default:
3885 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3889 if (OldAcl)
3891 for (i = 0; ; i++)
3893 BOOL add = TRUE;
3894 ULONG j;
3895 const ACE_HEADER *old_ace_header;
3896 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3897 if (status != STATUS_SUCCESS) break;
3898 for (j = 0; j < count; j++)
3900 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3901 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3902 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3904 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3905 add = FALSE;
3906 break;
3908 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3910 switch (old_ace_header->AceType)
3912 case ACCESS_ALLOWED_ACE_TYPE:
3913 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3914 add = FALSE;
3915 break;
3916 case ACCESS_DENIED_ACE_TYPE:
3917 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3918 add = FALSE;
3919 break;
3920 case SYSTEM_AUDIT_ACE_TYPE:
3921 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3922 add = FALSE;
3923 break;
3924 case SYSTEM_ALARM_ACE_TYPE:
3925 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3926 add = FALSE;
3927 break;
3928 default:
3929 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3932 if (!add)
3933 break;
3936 if (add)
3937 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3938 if (status != STATUS_SUCCESS)
3940 WARN("RtlAddAce failed with error 0x%08x\n", status);
3941 ret = RtlNtStatusToDosError(status);
3942 break;
3947 exit:
3948 heap_free(ppsid);
3949 return ret;
3952 /******************************************************************************
3953 * SetNamedSecurityInfoA [ADVAPI32.@]
3955 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3956 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3957 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3959 LPWSTR wstr;
3960 DWORD r;
3962 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3963 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3965 wstr = SERV_dup(pObjectName);
3966 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3967 psidGroup, pDacl, pSacl );
3969 heap_free( wstr );
3971 return r;
3974 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3975 PSECURITY_DESCRIPTOR ModificationDescriptor,
3976 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3977 PGENERIC_MAPPING GenericMapping,
3978 HANDLE Token )
3980 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3981 ObjectsSecurityDescriptor, GenericMapping, Token);
3983 return TRUE;
3986 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3988 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3991 /******************************************************************************
3992 * AreAnyAccessesGranted [ADVAPI32.@]
3994 * Determines whether or not any of a set of specified access permissions have
3995 * been granted or not.
3997 * PARAMS
3998 * GrantedAccess [I] The permissions that have been granted.
3999 * DesiredAccess [I] The permissions that you want to have.
4001 * RETURNS
4002 * Nonzero if any of the permissions have been granted, zero if none of the
4003 * permissions have been granted.
4006 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4008 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4011 /******************************************************************************
4012 * SetNamedSecurityInfoW [ADVAPI32.@]
4014 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4015 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4016 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4018 DWORD access = 0;
4019 HANDLE handle;
4020 DWORD err;
4022 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4023 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4025 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4027 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4028 access |= WRITE_OWNER;
4029 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4030 access |= WRITE_DAC;
4031 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4032 access |= ACCESS_SYSTEM_SECURITY;
4034 switch (ObjectType)
4036 case SE_SERVICE:
4037 if (!(err = get_security_service( pObjectName, access, &handle )))
4039 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4040 CloseServiceHandle( handle );
4042 break;
4043 case SE_REGISTRY_KEY:
4044 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4046 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4047 RegCloseKey( handle );
4049 break;
4050 case SE_FILE_OBJECT:
4051 if (!(err = get_security_file( pObjectName, access, &handle )))
4053 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4054 CloseHandle( handle );
4056 break;
4057 default:
4058 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4059 return ERROR_SUCCESS;
4061 return err;
4064 /******************************************************************************
4065 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4067 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4068 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4070 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4071 return ERROR_CALL_NOT_IMPLEMENTED;
4074 /******************************************************************************
4075 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4077 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4078 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4080 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4081 return ERROR_CALL_NOT_IMPLEMENTED;
4084 /******************************************************************************
4085 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4087 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4088 PACCESS_MASK pFailedAuditRights)
4090 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4091 return ERROR_CALL_NOT_IMPLEMENTED;
4095 /******************************************************************************
4096 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4098 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4099 PACCESS_MASK pFailedAuditRights)
4101 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4102 return ERROR_CALL_NOT_IMPLEMENTED;
4106 /******************************************************************************
4107 * ParseAclStringFlags
4109 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4111 DWORD flags = 0;
4112 LPCWSTR szAcl = *StringAcl;
4114 while (*szAcl != '(')
4116 if (*szAcl == 'P')
4118 flags |= SE_DACL_PROTECTED;
4120 else if (*szAcl == 'A')
4122 szAcl++;
4123 if (*szAcl == 'R')
4124 flags |= SE_DACL_AUTO_INHERIT_REQ;
4125 else if (*szAcl == 'I')
4126 flags |= SE_DACL_AUTO_INHERITED;
4128 szAcl++;
4131 *StringAcl = szAcl;
4132 return flags;
4135 /******************************************************************************
4136 * ParseAceStringType
4138 static const ACEFLAG AceType[] =
4140 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4141 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4142 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4143 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4145 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4146 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4147 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4148 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4150 { NULL, 0 },
4153 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4155 UINT len = 0;
4156 LPCWSTR szAcl = *StringAcl;
4157 const ACEFLAG *lpaf = AceType;
4159 while (*szAcl == ' ')
4160 szAcl++;
4162 while (lpaf->wstr &&
4163 (len = strlenW(lpaf->wstr)) &&
4164 strncmpW(lpaf->wstr, szAcl, len))
4165 lpaf++;
4167 if (!lpaf->wstr)
4168 return 0;
4170 *StringAcl = szAcl + len;
4171 return lpaf->value;
4175 /******************************************************************************
4176 * ParseAceStringFlags
4178 static const ACEFLAG AceFlags[] =
4180 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4181 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4182 { SDDL_INHERITED, INHERITED_ACE },
4183 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4184 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4185 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4186 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4187 { NULL, 0 },
4190 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4192 UINT len = 0;
4193 BYTE flags = 0;
4194 LPCWSTR szAcl = *StringAcl;
4196 while (*szAcl == ' ')
4197 szAcl++;
4199 while (*szAcl != ';')
4201 const ACEFLAG *lpaf = AceFlags;
4203 while (lpaf->wstr &&
4204 (len = strlenW(lpaf->wstr)) &&
4205 strncmpW(lpaf->wstr, szAcl, len))
4206 lpaf++;
4208 if (!lpaf->wstr)
4209 return 0;
4211 flags |= lpaf->value;
4212 szAcl += len;
4215 *StringAcl = szAcl;
4216 return flags;
4220 /******************************************************************************
4221 * ParseAceStringRights
4223 static const ACEFLAG AceRights[] =
4225 { SDDL_GENERIC_ALL, GENERIC_ALL },
4226 { SDDL_GENERIC_READ, GENERIC_READ },
4227 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4228 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4230 { SDDL_READ_CONTROL, READ_CONTROL },
4231 { SDDL_STANDARD_DELETE, DELETE },
4232 { SDDL_WRITE_DAC, WRITE_DAC },
4233 { SDDL_WRITE_OWNER, WRITE_OWNER },
4235 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4236 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4237 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4238 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4239 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4240 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4241 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4242 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4243 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4245 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4246 { SDDL_FILE_READ, FILE_GENERIC_READ },
4247 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4248 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4250 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4251 { SDDL_KEY_READ, KEY_READ },
4252 { SDDL_KEY_WRITE, KEY_WRITE },
4253 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4254 { NULL, 0 },
4257 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4259 UINT len = 0;
4260 DWORD rights = 0;
4261 LPCWSTR szAcl = *StringAcl;
4263 while (*szAcl == ' ')
4264 szAcl++;
4266 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4268 LPCWSTR p = szAcl;
4270 while (*p && *p != ';')
4271 p++;
4273 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4275 rights = strtoulW(szAcl, NULL, 16);
4276 szAcl = p;
4278 else
4279 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4281 else
4283 while (*szAcl != ';')
4285 const ACEFLAG *lpaf = AceRights;
4287 while (lpaf->wstr &&
4288 (len = strlenW(lpaf->wstr)) &&
4289 strncmpW(lpaf->wstr, szAcl, len))
4291 lpaf++;
4294 if (!lpaf->wstr)
4295 return 0;
4297 rights |= lpaf->value;
4298 szAcl += len;
4302 *StringAcl = szAcl;
4303 return rights;
4307 /******************************************************************************
4308 * ParseStringAclToAcl
4310 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4312 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4313 PACL pAcl, LPDWORD cBytes)
4315 DWORD val;
4316 DWORD sidlen;
4317 DWORD length = sizeof(ACL);
4318 DWORD acesize = 0;
4319 DWORD acecount = 0;
4320 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4321 DWORD error = ERROR_INVALID_ACL;
4323 TRACE("%s\n", debugstr_w(StringAcl));
4325 if (!StringAcl)
4326 return FALSE;
4328 if (pAcl) /* pAce is only useful if we're setting values */
4329 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4331 /* Parse ACL flags */
4332 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4334 /* Parse ACE */
4335 while (*StringAcl == '(')
4337 StringAcl++;
4339 /* Parse ACE type */
4340 val = ParseAceStringType(&StringAcl);
4341 if (pAce)
4342 pAce->Header.AceType = (BYTE) val;
4343 if (*StringAcl != ';')
4345 error = RPC_S_INVALID_STRING_UUID;
4346 goto lerr;
4348 StringAcl++;
4350 /* Parse ACE flags */
4351 val = ParseAceStringFlags(&StringAcl);
4352 if (pAce)
4353 pAce->Header.AceFlags = (BYTE) val;
4354 if (*StringAcl != ';')
4355 goto lerr;
4356 StringAcl++;
4358 /* Parse ACE rights */
4359 val = ParseAceStringRights(&StringAcl);
4360 if (pAce)
4361 pAce->Mask = val;
4362 if (*StringAcl != ';')
4363 goto lerr;
4364 StringAcl++;
4366 /* Parse ACE object guid */
4367 while (*StringAcl == ' ')
4368 StringAcl++;
4369 if (*StringAcl != ';')
4371 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4372 goto lerr;
4374 StringAcl++;
4376 /* Parse ACE inherit object guid */
4377 while (*StringAcl == ' ')
4378 StringAcl++;
4379 if (*StringAcl != ';')
4381 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4382 goto lerr;
4384 StringAcl++;
4386 /* Parse ACE account sid */
4387 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4389 while (*StringAcl && *StringAcl != ')')
4390 StringAcl++;
4393 if (*StringAcl != ')')
4394 goto lerr;
4395 StringAcl++;
4397 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4398 length += acesize;
4399 if (pAce)
4401 pAce->Header.AceSize = acesize;
4402 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4404 acecount++;
4407 *cBytes = length;
4409 if (length > 0xffff)
4411 ERR("ACL too large\n");
4412 goto lerr;
4415 if (pAcl)
4417 pAcl->AclRevision = ACL_REVISION;
4418 pAcl->Sbz1 = 0;
4419 pAcl->AclSize = length;
4420 pAcl->AceCount = acecount++;
4421 pAcl->Sbz2 = 0;
4423 return TRUE;
4425 lerr:
4426 SetLastError(error);
4427 WARN("Invalid ACE string format\n");
4428 return FALSE;
4432 /******************************************************************************
4433 * ParseStringSecurityDescriptorToSecurityDescriptor
4435 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4436 LPCWSTR StringSecurityDescriptor,
4437 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4438 LPDWORD cBytes)
4440 BOOL bret = FALSE;
4441 WCHAR toktype;
4442 WCHAR tok[MAX_PATH];
4443 LPCWSTR lptoken;
4444 LPBYTE lpNext = NULL;
4445 DWORD len;
4447 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4449 if (SecurityDescriptor)
4450 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4452 while (*StringSecurityDescriptor == ' ')
4453 StringSecurityDescriptor++;
4455 while (*StringSecurityDescriptor)
4457 toktype = *StringSecurityDescriptor;
4459 /* Expect char identifier followed by ':' */
4460 StringSecurityDescriptor++;
4461 if (*StringSecurityDescriptor != ':')
4463 SetLastError(ERROR_INVALID_PARAMETER);
4464 goto lend;
4466 StringSecurityDescriptor++;
4468 /* Extract token */
4469 lptoken = StringSecurityDescriptor;
4470 while (*lptoken && *lptoken != ':')
4471 lptoken++;
4473 if (*lptoken)
4474 lptoken--;
4476 len = lptoken - StringSecurityDescriptor;
4477 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4478 tok[len] = 0;
4480 switch (toktype)
4482 case 'O':
4484 DWORD bytes;
4486 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4487 goto lend;
4489 if (SecurityDescriptor)
4491 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4492 lpNext += bytes; /* Advance to next token */
4495 *cBytes += bytes;
4497 break;
4500 case 'G':
4502 DWORD bytes;
4504 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4505 goto lend;
4507 if (SecurityDescriptor)
4509 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4510 lpNext += bytes; /* Advance to next token */
4513 *cBytes += bytes;
4515 break;
4518 case 'D':
4520 DWORD flags;
4521 DWORD bytes;
4523 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4524 goto lend;
4526 if (SecurityDescriptor)
4528 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4529 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4530 lpNext += bytes; /* Advance to next token */
4533 *cBytes += bytes;
4535 break;
4538 case 'S':
4540 DWORD flags;
4541 DWORD bytes;
4543 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4544 goto lend;
4546 if (SecurityDescriptor)
4548 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4549 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4550 lpNext += bytes; /* Advance to next token */
4553 *cBytes += bytes;
4555 break;
4558 default:
4559 FIXME("Unknown token\n");
4560 SetLastError(ERROR_INVALID_PARAMETER);
4561 goto lend;
4564 StringSecurityDescriptor = lptoken;
4567 bret = TRUE;
4569 lend:
4570 return bret;
4573 /******************************************************************************
4574 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4576 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4577 LPCSTR StringSecurityDescriptor,
4578 DWORD StringSDRevision,
4579 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4580 PULONG SecurityDescriptorSize)
4582 BOOL ret;
4583 LPWSTR StringSecurityDescriptorW;
4585 if(!StringSecurityDescriptor)
4586 return FALSE;
4588 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4589 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4590 StringSDRevision, SecurityDescriptor,
4591 SecurityDescriptorSize);
4592 heap_free(StringSecurityDescriptorW);
4594 return ret;
4597 /******************************************************************************
4598 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4600 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4601 LPCWSTR StringSecurityDescriptor,
4602 DWORD StringSDRevision,
4603 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4604 PULONG SecurityDescriptorSize)
4606 DWORD cBytes;
4607 SECURITY_DESCRIPTOR* psd;
4608 BOOL bret = FALSE;
4610 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4612 if (GetVersion() & 0x80000000)
4614 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4615 goto lend;
4617 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4619 SetLastError(ERROR_INVALID_PARAMETER);
4620 goto lend;
4622 else if (StringSDRevision != SID_REVISION)
4624 SetLastError(ERROR_UNKNOWN_REVISION);
4625 goto lend;
4628 /* Compute security descriptor length */
4629 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4630 NULL, &cBytes))
4631 goto lend;
4633 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4634 if (!psd) goto lend;
4636 psd->Revision = SID_REVISION;
4637 psd->Control |= SE_SELF_RELATIVE;
4639 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4640 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4642 LocalFree(psd);
4643 goto lend;
4646 if (SecurityDescriptorSize)
4647 *SecurityDescriptorSize = cBytes;
4649 bret = TRUE;
4651 lend:
4652 TRACE(" ret=%d\n", bret);
4653 return bret;
4656 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4658 if (cch == -1)
4659 cch = strlenW(string);
4661 if (plen)
4662 *plen += cch;
4664 if (pwptr)
4666 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4667 *pwptr += cch;
4671 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4673 DWORD i;
4674 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4675 WCHAR subauthfmt[] = { '-','%','u',0 };
4676 WCHAR buf[26];
4677 SID *pisid = psid;
4679 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4681 SetLastError(ERROR_INVALID_SID);
4682 return FALSE;
4685 if (pisid->IdentifierAuthority.Value[0] ||
4686 pisid->IdentifierAuthority.Value[1])
4688 FIXME("not matching MS' bugs\n");
4689 SetLastError(ERROR_INVALID_SID);
4690 return FALSE;
4693 sprintfW( buf, fmt, pisid->Revision,
4694 MAKELONG(
4695 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4696 pisid->IdentifierAuthority.Value[4] ),
4697 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4698 pisid->IdentifierAuthority.Value[2] )
4699 ) );
4700 DumpString(buf, -1, pwptr, plen);
4702 for( i=0; i<pisid->SubAuthorityCount; i++ )
4704 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4705 DumpString(buf, -1, pwptr, plen);
4707 return TRUE;
4710 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4712 size_t i;
4713 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4715 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4717 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4718 return TRUE;
4722 return DumpSidNumeric(psid, pwptr, plen);
4725 static const LPCWSTR AceRightBitNames[32] = {
4726 SDDL_CREATE_CHILD, /* 0 */
4727 SDDL_DELETE_CHILD,
4728 SDDL_LIST_CHILDREN,
4729 SDDL_SELF_WRITE,
4730 SDDL_READ_PROPERTY, /* 4 */
4731 SDDL_WRITE_PROPERTY,
4732 SDDL_DELETE_TREE,
4733 SDDL_LIST_OBJECT,
4734 SDDL_CONTROL_ACCESS, /* 8 */
4735 NULL,
4736 NULL,
4737 NULL,
4738 NULL, /* 12 */
4739 NULL,
4740 NULL,
4741 NULL,
4742 SDDL_STANDARD_DELETE, /* 16 */
4743 SDDL_READ_CONTROL,
4744 SDDL_WRITE_DAC,
4745 SDDL_WRITE_OWNER,
4746 NULL, /* 20 */
4747 NULL,
4748 NULL,
4749 NULL,
4750 NULL, /* 24 */
4751 NULL,
4752 NULL,
4753 NULL,
4754 SDDL_GENERIC_ALL, /* 28 */
4755 SDDL_GENERIC_EXECUTE,
4756 SDDL_GENERIC_WRITE,
4757 SDDL_GENERIC_READ
4760 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4762 static const WCHAR fmtW[] = {'0','x','%','x',0};
4763 WCHAR buf[15];
4764 size_t i;
4766 if (mask == 0)
4767 return;
4769 /* first check if the right have name */
4770 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4772 if (AceRights[i].wstr == NULL)
4773 break;
4774 if (mask == AceRights[i].value)
4776 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4777 return;
4781 /* then check if it can be built from bit names */
4782 for (i = 0; i < 32; i++)
4784 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4786 /* can't be built from bit names */
4787 sprintfW(buf, fmtW, mask);
4788 DumpString(buf, -1, pwptr, plen);
4789 return;
4793 /* build from bit names */
4794 for (i = 0; i < 32; i++)
4795 if (mask & (1 << i))
4796 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4799 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4801 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4802 static const WCHAR openbr = '(';
4803 static const WCHAR closebr = ')';
4804 static const WCHAR semicolon = ';';
4806 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4808 SetLastError(ERROR_INVALID_ACL);
4809 return FALSE;
4812 piace = pace;
4813 DumpString(&openbr, 1, pwptr, plen);
4814 switch (piace->Header.AceType)
4816 case ACCESS_ALLOWED_ACE_TYPE:
4817 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4818 break;
4819 case ACCESS_DENIED_ACE_TYPE:
4820 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4821 break;
4822 case SYSTEM_AUDIT_ACE_TYPE:
4823 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4824 break;
4825 case SYSTEM_ALARM_ACE_TYPE:
4826 DumpString(SDDL_ALARM, -1, pwptr, plen);
4827 break;
4829 DumpString(&semicolon, 1, pwptr, plen);
4831 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4832 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4833 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4834 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4835 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4836 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4837 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4838 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4839 if (piace->Header.AceFlags & INHERITED_ACE)
4840 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4841 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4842 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4843 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4844 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4845 DumpString(&semicolon, 1, pwptr, plen);
4846 DumpRights(piace->Mask, pwptr, plen);
4847 DumpString(&semicolon, 1, pwptr, plen);
4848 /* objects not supported */
4849 DumpString(&semicolon, 1, pwptr, plen);
4850 /* objects not supported */
4851 DumpString(&semicolon, 1, pwptr, plen);
4852 if (!DumpSid(&piace->SidStart, pwptr, plen))
4853 return FALSE;
4854 DumpString(&closebr, 1, pwptr, plen);
4855 return TRUE;
4858 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4860 WORD count;
4861 UINT i;
4863 if (protected)
4864 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4865 if (autoInheritReq)
4866 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4867 if (autoInherited)
4868 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4870 if (pacl == NULL)
4871 return TRUE;
4873 if (!IsValidAcl(pacl))
4874 return FALSE;
4876 count = pacl->AceCount;
4877 for (i = 0; i < count; i++)
4879 LPVOID ace;
4880 if (!GetAce(pacl, i, &ace))
4881 return FALSE;
4882 if (!DumpAce(ace, pwptr, plen))
4883 return FALSE;
4886 return TRUE;
4889 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4891 static const WCHAR prefix[] = {'O',':',0};
4892 BOOL bDefaulted;
4893 PSID psid;
4895 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4896 return FALSE;
4898 if (psid == NULL)
4899 return TRUE;
4901 DumpString(prefix, -1, pwptr, plen);
4902 if (!DumpSid(psid, pwptr, plen))
4903 return FALSE;
4904 return TRUE;
4907 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4909 static const WCHAR prefix[] = {'G',':',0};
4910 BOOL bDefaulted;
4911 PSID psid;
4913 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4914 return FALSE;
4916 if (psid == NULL)
4917 return TRUE;
4919 DumpString(prefix, -1, pwptr, plen);
4920 if (!DumpSid(psid, pwptr, plen))
4921 return FALSE;
4922 return TRUE;
4925 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4927 static const WCHAR dacl[] = {'D',':',0};
4928 SECURITY_DESCRIPTOR_CONTROL control;
4929 BOOL present, defaulted;
4930 DWORD revision;
4931 PACL pacl;
4933 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4934 return FALSE;
4936 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4937 return FALSE;
4939 if (!present)
4940 return TRUE;
4942 DumpString(dacl, 2, pwptr, plen);
4943 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4944 return FALSE;
4945 return TRUE;
4948 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4950 static const WCHAR sacl[] = {'S',':',0};
4951 SECURITY_DESCRIPTOR_CONTROL control;
4952 BOOL present, defaulted;
4953 DWORD revision;
4954 PACL pacl;
4956 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4957 return FALSE;
4959 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4960 return FALSE;
4962 if (!present)
4963 return TRUE;
4965 DumpString(sacl, 2, pwptr, plen);
4966 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4967 return FALSE;
4968 return TRUE;
4971 /******************************************************************************
4972 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4974 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4976 ULONG len;
4977 WCHAR *wptr, *wstr;
4979 if (SDRevision != SDDL_REVISION_1)
4981 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
4982 SetLastError(ERROR_UNKNOWN_REVISION);
4983 return FALSE;
4986 len = 0;
4987 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4988 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4989 return FALSE;
4990 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4991 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4992 return FALSE;
4993 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4994 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4995 return FALSE;
4996 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4997 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4998 return FALSE;
5000 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5001 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5002 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5003 LocalFree (wstr);
5004 return FALSE;
5006 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5007 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5008 LocalFree (wstr);
5009 return FALSE;
5011 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5012 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5013 LocalFree (wstr);
5014 return FALSE;
5016 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5017 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5018 LocalFree (wstr);
5019 return FALSE;
5021 *wptr = 0;
5023 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5024 *OutputString = wstr;
5025 if (OutputLen)
5026 *OutputLen = strlenW(*OutputString)+1;
5027 return TRUE;
5030 /******************************************************************************
5031 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5033 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5035 LPWSTR wstr;
5036 ULONG len;
5037 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5039 int lenA;
5041 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5042 *OutputString = heap_alloc(lenA);
5043 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5044 LocalFree(wstr);
5046 if (OutputLen != NULL)
5047 *OutputLen = lenA;
5048 return TRUE;
5050 else
5052 *OutputString = NULL;
5053 if (OutputLen)
5054 *OutputLen = 0;
5055 return FALSE;
5059 /******************************************************************************
5060 * ConvertStringSidToSidW [ADVAPI32.@]
5062 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5064 BOOL bret = FALSE;
5065 DWORD cBytes;
5067 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5068 if (GetVersion() & 0x80000000)
5069 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5070 else if (!StringSid || !Sid)
5071 SetLastError(ERROR_INVALID_PARAMETER);
5072 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5074 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5076 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5077 if (!bret)
5078 LocalFree(*Sid);
5080 return bret;
5083 /******************************************************************************
5084 * ConvertStringSidToSidA [ADVAPI32.@]
5086 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5088 BOOL bret = FALSE;
5090 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5091 if (GetVersion() & 0x80000000)
5092 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5093 else if (!StringSid || !Sid)
5094 SetLastError(ERROR_INVALID_PARAMETER);
5095 else
5097 WCHAR *wStringSid = SERV_dup(StringSid);
5098 bret = ConvertStringSidToSidW(wStringSid, Sid);
5099 heap_free(wStringSid);
5101 return bret;
5104 /******************************************************************************
5105 * ConvertSidToStringSidW [ADVAPI32.@]
5107 * format of SID string is:
5108 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5109 * where
5110 * <rev> is the revision of the SID encoded as decimal
5111 * <auth> is the identifier authority encoded as hex
5112 * <subauthN> is the subauthority id encoded as decimal
5114 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5116 DWORD len = 0;
5117 LPWSTR wstr, wptr;
5119 TRACE("%p %p\n", pSid, pstr );
5121 len = 0;
5122 if (!DumpSidNumeric(pSid, NULL, &len))
5123 return FALSE;
5124 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5125 DumpSidNumeric(pSid, &wptr, NULL);
5126 *wptr = 0;
5128 *pstr = wstr;
5129 return TRUE;
5132 /******************************************************************************
5133 * ConvertSidToStringSidA [ADVAPI32.@]
5135 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5137 LPWSTR wstr = NULL;
5138 LPSTR str;
5139 UINT len;
5141 TRACE("%p %p\n", pSid, pstr );
5143 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5144 return FALSE;
5146 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5147 str = LocalAlloc( 0, len );
5148 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5149 LocalFree( wstr );
5151 *pstr = str;
5153 return TRUE;
5156 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5157 PSECURITY_DESCRIPTOR pdesc,
5158 PSECURITY_DESCRIPTOR cdesc,
5159 PSECURITY_DESCRIPTOR* ndesc,
5160 GUID* objtype,
5161 BOOL isdir,
5162 PGENERIC_MAPPING genmap )
5164 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5166 return FALSE;
5169 BOOL WINAPI CreatePrivateObjectSecurity(
5170 PSECURITY_DESCRIPTOR ParentDescriptor,
5171 PSECURITY_DESCRIPTOR CreatorDescriptor,
5172 PSECURITY_DESCRIPTOR* NewDescriptor,
5173 BOOL IsDirectoryObject,
5174 HANDLE Token,
5175 PGENERIC_MAPPING GenericMapping )
5177 SECURITY_DESCRIPTOR_RELATIVE *relative;
5178 DWORD needed, offset;
5179 BYTE *buffer;
5181 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5182 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5184 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5185 needed += sizeof(sidWorld);
5186 needed += sizeof(sidWorld);
5187 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5188 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5190 if (!(buffer = heap_alloc( needed ))) return FALSE;
5191 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5192 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5194 heap_free( buffer );
5195 return FALSE;
5197 relative->Control |= SE_SELF_RELATIVE;
5198 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5200 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5201 relative->Owner = offset;
5202 offset += sizeof(sidWorld);
5204 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5205 relative->Group = offset;
5206 offset += sizeof(sidWorld);
5208 GetWorldAccessACL( (ACL *)(buffer + offset) );
5209 relative->Dacl = offset;
5210 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5212 GetWorldAccessACL( (ACL *)(buffer + offset) );
5213 relative->Sacl = offset;
5215 *NewDescriptor = relative;
5216 return TRUE;
5219 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5221 FIXME("%p - stub\n", ObjectDescriptor);
5223 heap_free( *ObjectDescriptor );
5224 return TRUE;
5227 BOOL WINAPI CreateProcessAsUserA(
5228 HANDLE hToken,
5229 LPCSTR lpApplicationName,
5230 LPSTR lpCommandLine,
5231 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5232 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5233 BOOL bInheritHandles,
5234 DWORD dwCreationFlags,
5235 LPVOID lpEnvironment,
5236 LPCSTR lpCurrentDirectory,
5237 LPSTARTUPINFOA lpStartupInfo,
5238 LPPROCESS_INFORMATION lpProcessInformation )
5240 BOOL ret;
5241 WCHAR *appW, *cmdlnW, *cwdW;
5242 STARTUPINFOW sinfo;
5244 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5245 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5246 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5248 appW = SERV_dup(lpApplicationName);
5249 cmdlnW = SERV_dup(lpCommandLine);
5250 cwdW = SERV_dup(lpCurrentDirectory);
5251 sinfo.cb = sizeof(sinfo);
5252 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5253 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5254 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5255 sinfo.dwX = lpStartupInfo->dwX;
5256 sinfo.dwY = lpStartupInfo->dwY;
5257 sinfo.dwXSize = lpStartupInfo->dwXSize;
5258 sinfo.dwYSize = lpStartupInfo->dwYSize;
5259 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5260 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5261 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5262 sinfo.dwFlags = lpStartupInfo->dwFlags;
5263 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5264 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5265 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5266 sinfo.hStdInput = lpStartupInfo->hStdInput;
5267 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5268 sinfo.hStdError = lpStartupInfo->hStdError;
5269 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5270 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5271 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5272 heap_free(appW);
5273 heap_free(cmdlnW);
5274 heap_free(cwdW);
5275 heap_free(sinfo.lpReserved);
5276 heap_free(sinfo.lpDesktop);
5277 heap_free(sinfo.lpTitle);
5279 return ret;
5282 BOOL WINAPI CreateProcessAsUserW(
5283 HANDLE hToken,
5284 LPCWSTR lpApplicationName,
5285 LPWSTR lpCommandLine,
5286 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5287 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5288 BOOL bInheritHandles,
5289 DWORD dwCreationFlags,
5290 LPVOID lpEnvironment,
5291 LPCWSTR lpCurrentDirectory,
5292 LPSTARTUPINFOW lpStartupInfo,
5293 LPPROCESS_INFORMATION lpProcessInformation )
5295 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5296 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5297 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5298 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5300 /* We should create the process with a suspended main thread */
5301 if (!CreateProcessW (lpApplicationName,
5302 lpCommandLine,
5303 lpProcessAttributes,
5304 lpThreadAttributes,
5305 bInheritHandles,
5306 dwCreationFlags, /* CREATE_SUSPENDED */
5307 lpEnvironment,
5308 lpCurrentDirectory,
5309 lpStartupInfo,
5310 lpProcessInformation))
5312 return FALSE;
5315 return TRUE;
5318 /******************************************************************************
5319 * CreateProcessWithLogonW
5321 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5322 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5323 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5325 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5326 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5327 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5328 lpStartupInfo, lpProcessInformation);
5330 return FALSE;
5333 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5334 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5335 PROCESS_INFORMATION *process_information )
5337 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5338 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5339 creation_flags, environment, debugstr_w(current_directory),
5340 startup_info, process_information);
5342 /* FIXME: check if handles should be inherited */
5343 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5344 current_directory, startup_info, process_information );
5347 /******************************************************************************
5348 * DuplicateTokenEx [ADVAPI32.@]
5350 BOOL WINAPI DuplicateTokenEx(
5351 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5352 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5353 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5354 TOKEN_TYPE TokenType,
5355 PHANDLE DuplicateTokenHandle )
5357 OBJECT_ATTRIBUTES ObjectAttributes;
5359 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5360 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5362 InitializeObjectAttributes(
5363 &ObjectAttributes,
5364 NULL,
5365 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5366 NULL,
5367 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5369 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5370 dwDesiredAccess,
5371 &ObjectAttributes,
5372 ImpersonationLevel,
5373 TokenType,
5374 DuplicateTokenHandle ) );
5377 BOOL WINAPI DuplicateToken(
5378 HANDLE ExistingTokenHandle,
5379 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5380 PHANDLE DuplicateTokenHandle )
5382 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5383 NULL, ImpersonationLevel, TokenImpersonation,
5384 DuplicateTokenHandle );
5387 /******************************************************************************
5388 * ComputeStringSidSize
5390 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5392 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5394 int ctok = 0;
5395 while (*StringSid)
5397 if (*StringSid == '-')
5398 ctok++;
5399 StringSid++;
5402 if (ctok >= 3)
5403 return GetSidLengthRequired(ctok - 2);
5405 else /* String constant format - Only available in winxp and above */
5407 unsigned int i;
5409 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5410 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5411 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5413 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5414 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5416 MAX_SID local;
5417 ADVAPI_GetComputerSid(&local);
5418 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5423 return GetSidLengthRequired(0);
5426 /******************************************************************************
5427 * ParseStringSidToSid
5429 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5431 BOOL bret = FALSE;
5432 SID* pisid=pSid;
5434 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5435 if (!StringSid)
5437 SetLastError(ERROR_INVALID_PARAMETER);
5438 TRACE("StringSid is NULL, returning FALSE\n");
5439 return FALSE;
5442 while (*StringSid == ' ')
5443 StringSid++;
5445 *cBytes = ComputeStringSidSize(StringSid);
5446 if (!pisid) /* Simply compute the size */
5448 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5449 return TRUE;
5452 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5454 DWORD i = 0, identAuth;
5455 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5457 StringSid += 2; /* Advance to Revision */
5458 pisid->Revision = atoiW(StringSid);
5460 if (pisid->Revision != SDDL_REVISION)
5462 TRACE("Revision %d is unknown\n", pisid->Revision);
5463 goto lend; /* ERROR_INVALID_SID */
5465 if (csubauth == 0)
5467 TRACE("SubAuthorityCount is 0\n");
5468 goto lend; /* ERROR_INVALID_SID */
5471 pisid->SubAuthorityCount = csubauth;
5473 /* Advance to identifier authority */
5474 while (*StringSid && *StringSid != '-')
5475 StringSid++;
5476 if (*StringSid == '-')
5477 StringSid++;
5479 /* MS' implementation can't handle values greater than 2^32 - 1, so
5480 * we don't either; assume most significant bytes are always 0
5482 pisid->IdentifierAuthority.Value[0] = 0;
5483 pisid->IdentifierAuthority.Value[1] = 0;
5484 identAuth = atoiW(StringSid);
5485 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5486 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5487 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5488 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5490 /* Advance to first sub authority */
5491 while (*StringSid && *StringSid != '-')
5492 StringSid++;
5493 if (*StringSid == '-')
5494 StringSid++;
5496 while (*StringSid)
5498 pisid->SubAuthority[i++] = atoiW(StringSid);
5500 while (*StringSid && *StringSid != '-')
5501 StringSid++;
5502 if (*StringSid == '-')
5503 StringSid++;
5506 if (i != pisid->SubAuthorityCount)
5507 goto lend; /* ERROR_INVALID_SID */
5509 bret = TRUE;
5511 else /* String constant format - Only available in winxp and above */
5513 unsigned int i;
5514 pisid->Revision = SDDL_REVISION;
5516 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5517 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5519 DWORD j;
5520 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5521 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5522 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5523 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5524 bret = TRUE;
5527 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5528 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5530 ADVAPI_GetComputerSid(pisid);
5531 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5532 pisid->SubAuthorityCount++;
5533 bret = TRUE;
5536 if (!bret)
5537 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5540 lend:
5541 if (!bret)
5542 SetLastError(ERROR_INVALID_SID);
5544 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5545 return bret;
5548 /******************************************************************************
5549 * GetNamedSecurityInfoA [ADVAPI32.@]
5551 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5552 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5553 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5554 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5556 LPWSTR wstr;
5557 DWORD r;
5559 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5560 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5562 wstr = SERV_dup(pObjectName);
5563 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5564 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5566 heap_free( wstr );
5568 return r;
5571 /******************************************************************************
5572 * GetNamedSecurityInfoW [ADVAPI32.@]
5574 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5575 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5576 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5578 DWORD access = 0;
5579 HANDLE handle;
5580 DWORD err;
5582 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5583 group, dacl, sacl, descriptor );
5585 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5586 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5588 /* If no descriptor, we have to check that there's a pointer for the requested information */
5589 if( !descriptor && (
5590 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5591 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5592 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5593 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5594 return ERROR_INVALID_PARAMETER;
5596 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5597 access |= READ_CONTROL;
5598 if (info & SACL_SECURITY_INFORMATION)
5599 access |= ACCESS_SYSTEM_SECURITY;
5601 switch (type)
5603 case SE_SERVICE:
5604 if (!(err = get_security_service( name, access, &handle )))
5606 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5607 CloseServiceHandle( handle );
5609 break;
5610 case SE_REGISTRY_KEY:
5611 if (!(err = get_security_regkey( name, access, &handle )))
5613 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5614 RegCloseKey( handle );
5616 break;
5617 case SE_FILE_OBJECT:
5618 if (!(err = get_security_file( name, access, &handle )))
5620 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5621 CloseHandle( handle );
5623 break;
5624 default:
5625 FIXME( "Object type %d is not currently supported.\n", type );
5626 if (owner) *owner = NULL;
5627 if (group) *group = NULL;
5628 if (dacl) *dacl = NULL;
5629 if (sacl) *sacl = NULL;
5630 if (descriptor) *descriptor = NULL;
5631 return ERROR_SUCCESS;
5633 return err;
5636 /******************************************************************************
5637 * GetNamedSecurityInfoExW [ADVAPI32.@]
5639 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5640 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5641 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5643 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5644 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5645 return ERROR_CALL_NOT_IMPLEMENTED;
5648 /******************************************************************************
5649 * GetNamedSecurityInfoExA [ADVAPI32.@]
5651 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5652 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5653 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5655 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5656 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5657 return ERROR_CALL_NOT_IMPLEMENTED;
5660 /******************************************************************************
5661 * DecryptFileW [ADVAPI32.@]
5663 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5665 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5666 return TRUE;
5669 /******************************************************************************
5670 * DecryptFileA [ADVAPI32.@]
5672 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5674 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5675 return TRUE;
5678 /******************************************************************************
5679 * EncryptFileW [ADVAPI32.@]
5681 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5683 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5684 return TRUE;
5687 /******************************************************************************
5688 * EncryptFileA [ADVAPI32.@]
5690 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5692 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5693 return TRUE;
5696 /******************************************************************************
5697 * FileEncryptionStatusW [ADVAPI32.@]
5699 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5701 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5702 if (!lpStatus)
5703 return FALSE;
5704 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5705 return TRUE;
5708 /******************************************************************************
5709 * FileEncryptionStatusA [ADVAPI32.@]
5711 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5713 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5714 if (!lpStatus)
5715 return FALSE;
5716 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5717 return TRUE;
5720 /******************************************************************************
5721 * SetSecurityInfo [ADVAPI32.@]
5723 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5724 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5725 PSID psidGroup, PACL pDacl, PACL pSacl)
5727 SECURITY_DESCRIPTOR sd;
5728 NTSTATUS status;
5730 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5731 return ERROR_INVALID_SECURITY_DESCR;
5733 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5734 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5735 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5736 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5737 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5738 SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
5739 if (SecurityInfo & SACL_SECURITY_INFORMATION)
5740 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
5742 switch (ObjectType)
5744 case SE_SERVICE:
5745 FIXME("stub: Service objects are not supported at this time.\n");
5746 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
5747 break;
5748 default:
5749 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
5750 break;
5752 return RtlNtStatusToDosError(status);
5755 /******************************************************************************
5756 * SaferCreateLevel [ADVAPI32.@]
5758 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5759 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5761 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5763 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5764 return TRUE;
5767 /******************************************************************************
5768 * SaferComputeTokenFromLevel [ADVAPI32.@]
5770 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5771 DWORD flags, LPVOID reserved)
5773 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5775 *access_token = (HANDLE)0xdeadbeef;
5776 return TRUE;
5779 /******************************************************************************
5780 * SaferCloseLevel [ADVAPI32.@]
5782 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5784 FIXME("(%p) stub\n", handle);
5785 return TRUE;
5788 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5789 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5790 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5791 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5792 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5794 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
5795 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5796 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5798 return ERROR_SUCCESS;
5801 /******************************************************************************
5802 * SaferGetPolicyInformation [ADVAPI32.@]
5804 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5805 PVOID buffer, PDWORD required, LPVOID lpReserved)
5807 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5808 return FALSE;
5811 /******************************************************************************
5812 * SaferSetLevelInformation [ADVAPI32.@]
5814 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5815 LPVOID buffer, DWORD size)
5817 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5818 return FALSE;