push cc8bc80451cc24f4d7cf75168b569f0ebfe19547
[wine/hacks.git] / dlls / advapi32 / security.c
blob773a839104bd3fb58ead5d618734008e7a49cc20
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
188 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 };
189 static const WCHAR DOMAIN[] = {'D','O','M','A','I','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_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
328 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
329 static const WCHAR SDDL_ALARM[] = {'A','L',0};
330 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
331 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
334 * ACE flags
336 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
337 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
338 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
339 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
340 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
341 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
342 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
344 const char * debugstr_sid(PSID sid)
346 int auth = 0;
347 SID * psid = sid;
349 if (psid == NULL)
350 return "(null)";
352 auth = psid->IdentifierAuthority.Value[5] +
353 (psid->IdentifierAuthority.Value[4] << 8) +
354 (psid->IdentifierAuthority.Value[3] << 16) +
355 (psid->IdentifierAuthority.Value[2] << 24);
357 switch (psid->SubAuthorityCount) {
358 case 0:
359 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
360 case 1:
361 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
362 psid->SubAuthority[0]);
363 case 2:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1]);
366 case 3:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
369 case 4:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[3]);
373 case 5:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[3], psid->SubAuthority[4]);
377 case 6:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
381 case 7:
382 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
383 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
384 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
385 psid->SubAuthority[6]);
386 case 8:
387 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
388 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
389 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
390 psid->SubAuthority[6], psid->SubAuthority[7]);
392 return "(too-big)";
395 /* set last error code from NT status and get the proper boolean return value */
396 /* used for functions that are a simple wrapper around the corresponding ntdll API */
397 static inline BOOL set_ntstatus( NTSTATUS status )
399 if (status) SetLastError( RtlNtStatusToDosError( status ));
400 return !status;
403 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405 static void GetWorldAccessACL(PACL pACL)
407 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409 pACL->AclRevision = ACL_REVISION;
410 pACL->Sbz1 = 0;
411 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
412 pACL->AceCount = 1;
413 pACL->Sbz2 = 0;
415 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
416 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
417 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
418 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
419 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
422 /************************************************************
423 * ADVAPI_IsLocalComputer
425 * Checks whether the server name indicates local machine.
427 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
430 BOOL Result;
431 LPWSTR buf;
433 if (!ServerName || !ServerName[0])
434 return TRUE;
436 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
437 Result = GetComputerNameW(buf, &dwSize);
438 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
439 ServerName += 2;
440 Result = Result && !lstrcmpW(ServerName, buf);
441 HeapFree(GetProcessHeap(), 0, buf);
443 return Result;
446 /************************************************************
447 * ADVAPI_GetComputerSid
449 * Reads the computer SID from the registry.
451 BOOL ADVAPI_GetComputerSid(PSID sid)
453 HKEY key;
454 LONG ret;
455 BOOL retval = FALSE;
456 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
457 static const WCHAR V[] = { 'V',0 };
459 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
460 KEY_READ, &key)) == ERROR_SUCCESS)
462 DWORD size = 0;
463 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
464 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
467 if (data)
469 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
470 data, &size)) == ERROR_SUCCESS)
472 /* the SID is in the last 24 bytes of the binary data */
473 CopyMemory(sid, &data[size-24], 24);
474 retval = TRUE;
476 HeapFree(GetProcessHeap(), 0, data);
479 RegCloseKey(key);
482 if(retval == TRUE) return retval;
484 /* create a new random SID */
485 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
486 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488 PSID new_sid;
489 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
490 DWORD id[3];
492 if (RtlGenRandom(id, sizeof(id)))
494 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
497 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499 FreeSid(new_sid);
502 RegCloseKey(key);
505 return retval;
508 /* ##############################
509 ###### TOKEN FUNCTIONS ######
510 ##############################
513 /******************************************************************************
514 * OpenProcessToken [ADVAPI32.@]
515 * Opens the access token associated with a process handle.
517 * PARAMS
518 * ProcessHandle [I] Handle to process
519 * DesiredAccess [I] Desired access to process
520 * TokenHandle [O] Pointer to handle of open access token
522 * RETURNS
523 * Success: TRUE. TokenHandle contains the access token.
524 * Failure: FALSE.
526 * NOTES
527 * See NtOpenProcessToken.
529 BOOL WINAPI
530 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
531 HANDLE *TokenHandle )
533 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
536 /******************************************************************************
537 * OpenThreadToken [ADVAPI32.@]
539 * Opens the access token associated with a thread handle.
541 * PARAMS
542 * ThreadHandle [I] Handle to process
543 * DesiredAccess [I] Desired access to the thread
544 * OpenAsSelf [I] ???
545 * TokenHandle [O] Destination for the token handle
547 * RETURNS
548 * Success: TRUE. TokenHandle contains the access token.
549 * Failure: FALSE.
551 * NOTES
552 * See NtOpenThreadToken.
554 BOOL WINAPI
555 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
556 BOOL OpenAsSelf, HANDLE *TokenHandle)
558 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
561 BOOL WINAPI
562 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
563 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
566 PreviousState, ReturnLength));
569 /******************************************************************************
570 * AdjustTokenPrivileges [ADVAPI32.@]
572 * Adjust the privileges of an open token handle.
574 * PARAMS
575 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
576 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
577 * NewState [I] Desired new privileges of the token
578 * BufferLength [I] Length of NewState
579 * PreviousState [O] Destination for the previous state
580 * ReturnLength [I/O] Size of PreviousState
583 * RETURNS
584 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
585 * Failure: FALSE.
587 * NOTES
588 * See NtAdjustPrivilegesToken.
590 BOOL WINAPI
591 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
592 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
593 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 NTSTATUS status;
597 TRACE("\n");
599 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
600 NewState, BufferLength, PreviousState,
601 ReturnLength);
602 SetLastError( RtlNtStatusToDosError( status ));
603 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
604 return TRUE;
605 else
606 return FALSE;
609 /******************************************************************************
610 * CheckTokenMembership [ADVAPI32.@]
612 * Determine if an access token is a member of a SID.
614 * PARAMS
615 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
616 * SidToCheck [I] SID that possibly contains the token
617 * IsMember [O] Destination for result.
619 * RETURNS
620 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
621 * Failure: FALSE.
623 BOOL WINAPI
624 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
625 PBOOL IsMember )
627 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629 *IsMember = TRUE;
630 return(TRUE);
633 /******************************************************************************
634 * GetTokenInformation [ADVAPI32.@]
636 * Get a type of information about an access token.
638 * PARAMS
639 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
640 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
641 * tokeninfo [O] Destination for token information
642 * tokeninfolength [I] Length of tokeninfo
643 * retlen [O] Destination for returned token information length
645 * RETURNS
646 * Success: TRUE. tokeninfo contains retlen bytes of token information
647 * Failure: FALSE.
649 * NOTES
650 * See NtQueryInformationToken.
652 BOOL WINAPI
653 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
654 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 TRACE("(%p, %s, %p, %d, %p):\n",
657 token,
658 (tokeninfoclass == TokenUser) ? "TokenUser" :
659 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
660 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
661 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
662 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
663 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
664 (tokeninfoclass == TokenSource) ? "TokenSource" :
665 (tokeninfoclass == TokenType) ? "TokenType" :
666 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
667 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
668 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
669 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
670 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
671 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
672 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
673 "Unknown",
674 tokeninfo, tokeninfolength, retlen);
675 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
676 tokeninfolength, retlen));
679 /******************************************************************************
680 * SetTokenInformation [ADVAPI32.@]
682 * Set information for an access token.
684 * PARAMS
685 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
686 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
687 * tokeninfo [I] Token information to set
688 * tokeninfolength [I] Length of tokeninfo
690 * RETURNS
691 * Success: TRUE. The information for the token is set to tokeninfo.
692 * Failure: FALSE.
694 BOOL WINAPI
695 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
696 LPVOID tokeninfo, DWORD tokeninfolength )
698 TRACE("(%p, %s, %p, %d): stub\n",
699 token,
700 (tokeninfoclass == TokenUser) ? "TokenUser" :
701 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
702 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
703 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
704 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
705 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
706 (tokeninfoclass == TokenSource) ? "TokenSource" :
707 (tokeninfoclass == TokenType) ? "TokenType" :
708 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
709 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
710 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
711 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
712 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
713 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
714 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
715 "Unknown",
716 tokeninfo, tokeninfolength);
718 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
721 /*************************************************************************
722 * SetThreadToken [ADVAPI32.@]
724 * Assigns an 'impersonation token' to a thread so it can assume the
725 * security privileges of another thread or process. Can also remove
726 * a previously assigned token.
728 * PARAMS
729 * thread [O] Handle to thread to set the token for
730 * token [I] Token to set
732 * RETURNS
733 * Success: TRUE. The threads access token is set to token
734 * Failure: FALSE.
736 * NOTES
737 * Only supported on NT or higher. On Win9X this function does nothing.
738 * See SetTokenInformation.
740 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
743 ThreadImpersonationToken, &token, sizeof token ));
746 /*************************************************************************
747 * CreateRestrictedToken [ADVAPI32.@]
749 * Create a new more restricted token from an existing token.
751 * PARAMS
752 * baseToken [I] Token to base the new restricted token on
753 * flags [I] Options
754 * nDisableSids [I] Length of disableSids array
755 * disableSids [I] Array of SIDs to disable in the new token
756 * nDeletePrivs [I] Length of deletePrivs array
757 * deletePrivs [I] Array of privileges to delete in the new token
758 * nRestrictSids [I] Length of restrictSids array
759 * restrictSids [I] Array of SIDs to restrict in the new token
760 * newToken [O] Address where the new token is stored
762 * RETURNS
763 * Success: TRUE
764 * Failure: FALSE
766 BOOL WINAPI CreateRestrictedToken(
767 HANDLE baseToken,
768 DWORD flags,
769 DWORD nDisableSids,
770 PSID_AND_ATTRIBUTES disableSids,
771 DWORD nDeletePrivs,
772 PLUID_AND_ATTRIBUTES deletePrivs,
773 DWORD nRestrictSids,
774 PSID_AND_ATTRIBUTES restrictSids,
775 PHANDLE newToken)
777 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
778 baseToken, flags, nDisableSids, disableSids,
779 nDeletePrivs, deletePrivs,
780 nRestrictSids, restrictSids,
781 newToken);
782 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
783 return FALSE;
786 /* ##############################
787 ###### SID FUNCTIONS ######
788 ##############################
791 /******************************************************************************
792 * AllocateAndInitializeSid [ADVAPI32.@]
794 * PARAMS
795 * pIdentifierAuthority []
796 * nSubAuthorityCount []
797 * nSubAuthority0 []
798 * nSubAuthority1 []
799 * nSubAuthority2 []
800 * nSubAuthority3 []
801 * nSubAuthority4 []
802 * nSubAuthority5 []
803 * nSubAuthority6 []
804 * nSubAuthority7 []
805 * pSid []
807 BOOL WINAPI
808 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
809 BYTE nSubAuthorityCount,
810 DWORD nSubAuthority0, DWORD nSubAuthority1,
811 DWORD nSubAuthority2, DWORD nSubAuthority3,
812 DWORD nSubAuthority4, DWORD nSubAuthority5,
813 DWORD nSubAuthority6, DWORD nSubAuthority7,
814 PSID *pSid )
816 return set_ntstatus( RtlAllocateAndInitializeSid(
817 pIdentifierAuthority, nSubAuthorityCount,
818 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
819 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
820 pSid ));
823 /******************************************************************************
824 * FreeSid [ADVAPI32.@]
826 * PARAMS
827 * pSid []
829 PVOID WINAPI
830 FreeSid( PSID pSid )
832 RtlFreeSid(pSid);
833 return NULL; /* is documented like this */
836 /******************************************************************************
837 * CopySid [ADVAPI32.@]
839 * PARAMS
840 * nDestinationSidLength []
841 * pDestinationSid []
842 * pSourceSid []
844 BOOL WINAPI
845 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
850 /******************************************************************************
851 * CreateWellKnownSid [ADVAPI32.@]
853 BOOL WINAPI
854 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
855 PSID DomainSid,
856 PSID pSid,
857 DWORD* cbSid)
859 unsigned int i;
860 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
864 SetLastError(ERROR_INVALID_PARAMETER);
865 return FALSE;
868 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
869 if (WellKnownSids[i].Type == WellKnownSidType) {
870 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
872 if (*cbSid < length)
874 *cbSid = length;
875 SetLastError(ERROR_INSUFFICIENT_BUFFER);
876 return FALSE;
878 if (!pSid)
880 SetLastError(ERROR_INVALID_PARAMETER);
881 return FALSE;
883 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
884 *cbSid = length;
885 return TRUE;
889 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
891 SetLastError(ERROR_INVALID_PARAMETER);
892 return FALSE;
895 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
896 if (WellKnownRids[i].Type == WellKnownSidType) {
897 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
898 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
899 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
901 if (*cbSid < output_sid_length)
903 *cbSid = output_sid_length;
904 SetLastError(ERROR_INSUFFICIENT_BUFFER);
905 return FALSE;
907 if (!pSid)
909 SetLastError(ERROR_INVALID_PARAMETER);
910 return FALSE;
912 CopyMemory(pSid, DomainSid, domain_sid_length);
913 (*GetSidSubAuthorityCount(pSid))++;
914 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
915 *cbSid = output_sid_length;
916 return TRUE;
919 SetLastError(ERROR_INVALID_PARAMETER);
920 return FALSE;
923 /******************************************************************************
924 * IsWellKnownSid [ADVAPI32.@]
926 BOOL WINAPI
927 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
929 unsigned int i;
930 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
932 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
933 if (WellKnownSids[i].Type == WellKnownSidType)
934 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
935 return TRUE;
937 return FALSE;
940 BOOL WINAPI
941 IsTokenRestricted( HANDLE TokenHandle )
943 TOKEN_GROUPS *groups;
944 DWORD size;
945 NTSTATUS status;
946 BOOL restricted;
948 TRACE("(%p)\n", TokenHandle);
950 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
951 if (status != STATUS_BUFFER_TOO_SMALL)
952 return FALSE;
954 groups = HeapAlloc(GetProcessHeap(), 0, size);
955 if (!groups)
957 SetLastError(ERROR_OUTOFMEMORY);
958 return FALSE;
961 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
962 if (status != STATUS_SUCCESS)
964 HeapFree(GetProcessHeap(), 0, groups);
965 return set_ntstatus(status);
968 if (groups->GroupCount)
969 restricted = TRUE;
970 else
971 restricted = FALSE;
973 HeapFree(GetProcessHeap(), 0, groups);
975 return restricted;
978 /******************************************************************************
979 * IsValidSid [ADVAPI32.@]
981 * PARAMS
982 * pSid []
984 BOOL WINAPI
985 IsValidSid( PSID pSid )
987 return RtlValidSid( pSid );
990 /******************************************************************************
991 * EqualSid [ADVAPI32.@]
993 * PARAMS
994 * pSid1 []
995 * pSid2 []
997 BOOL WINAPI
998 EqualSid( PSID pSid1, PSID pSid2 )
1000 return RtlEqualSid( pSid1, pSid2 );
1003 /******************************************************************************
1004 * EqualPrefixSid [ADVAPI32.@]
1006 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1008 return RtlEqualPrefixSid(pSid1, pSid2);
1011 /******************************************************************************
1012 * GetSidLengthRequired [ADVAPI32.@]
1014 * PARAMS
1015 * nSubAuthorityCount []
1017 DWORD WINAPI
1018 GetSidLengthRequired( BYTE nSubAuthorityCount )
1020 return RtlLengthRequiredSid(nSubAuthorityCount);
1023 /******************************************************************************
1024 * InitializeSid [ADVAPI32.@]
1026 * PARAMS
1027 * pIdentifierAuthority []
1029 BOOL WINAPI
1030 InitializeSid (
1031 PSID pSid,
1032 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1033 BYTE nSubAuthorityCount)
1035 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1038 DWORD WINAPI
1039 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1041 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1043 return 1;
1046 DWORD WINAPI
1047 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1049 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1051 return 1;
1054 /******************************************************************************
1055 * GetSidIdentifierAuthority [ADVAPI32.@]
1057 * PARAMS
1058 * pSid []
1060 PSID_IDENTIFIER_AUTHORITY WINAPI
1061 GetSidIdentifierAuthority( PSID pSid )
1063 return RtlIdentifierAuthoritySid(pSid);
1066 /******************************************************************************
1067 * GetSidSubAuthority [ADVAPI32.@]
1069 * PARAMS
1070 * pSid []
1071 * nSubAuthority []
1073 PDWORD WINAPI
1074 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1076 return RtlSubAuthoritySid(pSid, nSubAuthority);
1079 /******************************************************************************
1080 * GetSidSubAuthorityCount [ADVAPI32.@]
1082 * PARAMS
1083 * pSid []
1085 PUCHAR WINAPI
1086 GetSidSubAuthorityCount (PSID pSid)
1088 return RtlSubAuthorityCountSid(pSid);
1091 /******************************************************************************
1092 * GetLengthSid [ADVAPI32.@]
1094 * PARAMS
1095 * pSid []
1097 DWORD WINAPI
1098 GetLengthSid (PSID pSid)
1100 return RtlLengthSid(pSid);
1103 /* ##############################################
1104 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1105 ##############################################
1108 /******************************************************************************
1109 * BuildSecurityDescriptorA [ADVAPI32.@]
1111 * Builds a SD from
1113 * PARAMS
1114 * pOwner [I]
1115 * pGroup [I]
1116 * cCountOfAccessEntries [I]
1117 * pListOfAccessEntries [I]
1118 * cCountOfAuditEntries [I]
1119 * pListofAuditEntries [I]
1120 * pOldSD [I]
1121 * lpdwBufferLength [I/O]
1122 * pNewSD [O]
1124 * RETURNS
1125 * Success: ERROR_SUCCESS
1126 * Failure: nonzero error code from Winerror.h
1128 DWORD WINAPI BuildSecurityDescriptorA(
1129 IN PTRUSTEEA pOwner,
1130 IN PTRUSTEEA pGroup,
1131 IN ULONG cCountOfAccessEntries,
1132 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1133 IN ULONG cCountOfAuditEntries,
1134 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1135 IN PSECURITY_DESCRIPTOR pOldSD,
1136 IN OUT PULONG lpdwBufferLength,
1137 OUT PSECURITY_DESCRIPTOR* pNewSD)
1139 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1140 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1141 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1143 return ERROR_CALL_NOT_IMPLEMENTED;
1146 /******************************************************************************
1147 * BuildSecurityDescriptorW [ADVAPI32.@]
1149 * See BuildSecurityDescriptorA.
1151 DWORD WINAPI BuildSecurityDescriptorW(
1152 IN PTRUSTEEW pOwner,
1153 IN PTRUSTEEW pGroup,
1154 IN ULONG cCountOfAccessEntries,
1155 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1156 IN ULONG cCountOfAuditEntries,
1157 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1158 IN PSECURITY_DESCRIPTOR pOldSD,
1159 IN OUT PULONG lpdwBufferLength,
1160 OUT PSECURITY_DESCRIPTOR* pNewSD)
1162 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1163 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1164 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1166 return ERROR_CALL_NOT_IMPLEMENTED;
1169 /******************************************************************************
1170 * InitializeSecurityDescriptor [ADVAPI32.@]
1172 * PARAMS
1173 * pDescr []
1174 * revision []
1176 BOOL WINAPI
1177 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1179 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1183 /******************************************************************************
1184 * MakeAbsoluteSD [ADVAPI32.@]
1186 BOOL WINAPI MakeAbsoluteSD (
1187 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1188 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1189 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1190 OUT PACL pDacl,
1191 OUT LPDWORD lpdwDaclSize,
1192 OUT PACL pSacl,
1193 OUT LPDWORD lpdwSaclSize,
1194 OUT PSID pOwner,
1195 OUT LPDWORD lpdwOwnerSize,
1196 OUT PSID pPrimaryGroup,
1197 OUT LPDWORD lpdwPrimaryGroupSize)
1199 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1200 pAbsoluteSecurityDescriptor,
1201 lpdwAbsoluteSecurityDescriptorSize,
1202 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1203 pOwner, lpdwOwnerSize,
1204 pPrimaryGroup, lpdwPrimaryGroupSize));
1207 /******************************************************************************
1208 * GetKernelObjectSecurity [ADVAPI32.@]
1210 BOOL WINAPI GetKernelObjectSecurity(
1211 HANDLE Handle,
1212 SECURITY_INFORMATION RequestedInformation,
1213 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1214 DWORD nLength,
1215 LPDWORD lpnLengthNeeded )
1217 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1218 pSecurityDescriptor, nLength, lpnLengthNeeded);
1220 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1221 nLength, lpnLengthNeeded ));
1224 /******************************************************************************
1225 * GetPrivateObjectSecurity [ADVAPI32.@]
1227 BOOL WINAPI GetPrivateObjectSecurity(
1228 PSECURITY_DESCRIPTOR ObjectDescriptor,
1229 SECURITY_INFORMATION SecurityInformation,
1230 PSECURITY_DESCRIPTOR ResultantDescriptor,
1231 DWORD DescriptorLength,
1232 PDWORD ReturnLength )
1234 SECURITY_DESCRIPTOR desc;
1235 BOOL defaulted, present;
1236 PACL pacl;
1237 PSID psid;
1239 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1240 ResultantDescriptor, DescriptorLength, ReturnLength);
1242 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1243 return FALSE;
1245 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1247 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1248 return FALSE;
1249 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1252 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1254 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1255 return FALSE;
1256 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1259 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1261 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1262 return FALSE;
1263 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1266 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1268 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1269 return FALSE;
1270 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1273 *ReturnLength = DescriptorLength;
1274 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1277 /******************************************************************************
1278 * GetSecurityDescriptorLength [ADVAPI32.@]
1280 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1282 return RtlLengthSecurityDescriptor(pDescr);
1285 /******************************************************************************
1286 * GetSecurityDescriptorOwner [ADVAPI32.@]
1288 * PARAMS
1289 * pOwner []
1290 * lpbOwnerDefaulted []
1292 BOOL WINAPI
1293 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1294 LPBOOL lpbOwnerDefaulted )
1296 BOOLEAN defaulted;
1297 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1298 *lpbOwnerDefaulted = defaulted;
1299 return ret;
1302 /******************************************************************************
1303 * SetSecurityDescriptorOwner [ADVAPI32.@]
1305 * PARAMS
1307 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1308 PSID pOwner, BOOL bOwnerDefaulted)
1310 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1312 /******************************************************************************
1313 * GetSecurityDescriptorGroup [ADVAPI32.@]
1315 BOOL WINAPI GetSecurityDescriptorGroup(
1316 PSECURITY_DESCRIPTOR SecurityDescriptor,
1317 PSID *Group,
1318 LPBOOL GroupDefaulted)
1320 BOOLEAN defaulted;
1321 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1322 *GroupDefaulted = defaulted;
1323 return ret;
1325 /******************************************************************************
1326 * SetSecurityDescriptorGroup [ADVAPI32.@]
1328 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1329 PSID Group, BOOL GroupDefaulted)
1331 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1334 /******************************************************************************
1335 * IsValidSecurityDescriptor [ADVAPI32.@]
1337 * PARAMS
1338 * lpsecdesc []
1340 BOOL WINAPI
1341 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1343 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1346 /******************************************************************************
1347 * GetSecurityDescriptorDacl [ADVAPI32.@]
1349 BOOL WINAPI GetSecurityDescriptorDacl(
1350 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1351 OUT LPBOOL lpbDaclPresent,
1352 OUT PACL *pDacl,
1353 OUT LPBOOL lpbDaclDefaulted)
1355 BOOLEAN present, defaulted;
1356 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1357 *lpbDaclPresent = present;
1358 *lpbDaclDefaulted = defaulted;
1359 return ret;
1362 /******************************************************************************
1363 * SetSecurityDescriptorDacl [ADVAPI32.@]
1365 BOOL WINAPI
1366 SetSecurityDescriptorDacl (
1367 PSECURITY_DESCRIPTOR lpsd,
1368 BOOL daclpresent,
1369 PACL dacl,
1370 BOOL dacldefaulted )
1372 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1374 /******************************************************************************
1375 * GetSecurityDescriptorSacl [ADVAPI32.@]
1377 BOOL WINAPI GetSecurityDescriptorSacl(
1378 IN PSECURITY_DESCRIPTOR lpsd,
1379 OUT LPBOOL lpbSaclPresent,
1380 OUT PACL *pSacl,
1381 OUT LPBOOL lpbSaclDefaulted)
1383 BOOLEAN present, defaulted;
1384 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1385 *lpbSaclPresent = present;
1386 *lpbSaclDefaulted = defaulted;
1387 return ret;
1390 /**************************************************************************
1391 * SetSecurityDescriptorSacl [ADVAPI32.@]
1393 BOOL WINAPI SetSecurityDescriptorSacl (
1394 PSECURITY_DESCRIPTOR lpsd,
1395 BOOL saclpresent,
1396 PACL lpsacl,
1397 BOOL sacldefaulted)
1399 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1401 /******************************************************************************
1402 * MakeSelfRelativeSD [ADVAPI32.@]
1404 * PARAMS
1405 * lpabssecdesc []
1406 * lpselfsecdesc []
1407 * lpbuflen []
1409 BOOL WINAPI
1410 MakeSelfRelativeSD(
1411 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1412 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1413 IN OUT LPDWORD lpdwBufferLength)
1415 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1416 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1419 /******************************************************************************
1420 * GetSecurityDescriptorControl [ADVAPI32.@]
1423 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1424 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1426 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1429 /******************************************************************************
1430 * SetSecurityDescriptorControl [ADVAPI32.@]
1432 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1433 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1434 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1436 return set_ntstatus( RtlSetControlSecurityDescriptor(
1437 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1440 /* ##############################
1441 ###### ACL FUNCTIONS ######
1442 ##############################
1445 /*************************************************************************
1446 * InitializeAcl [ADVAPI32.@]
1448 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1450 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1453 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1455 IO_STATUS_BLOCK io_block;
1457 TRACE("(%p)\n", hNamedPipe);
1459 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1460 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1463 /******************************************************************************
1464 * AddAccessAllowedAce [ADVAPI32.@]
1466 BOOL WINAPI AddAccessAllowedAce(
1467 IN OUT PACL pAcl,
1468 IN DWORD dwAceRevision,
1469 IN DWORD AccessMask,
1470 IN PSID pSid)
1472 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1475 /******************************************************************************
1476 * AddAccessAllowedAceEx [ADVAPI32.@]
1478 BOOL WINAPI AddAccessAllowedAceEx(
1479 IN OUT PACL pAcl,
1480 IN DWORD dwAceRevision,
1481 IN DWORD AceFlags,
1482 IN DWORD AccessMask,
1483 IN PSID pSid)
1485 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1488 /******************************************************************************
1489 * AddAccessDeniedAce [ADVAPI32.@]
1491 BOOL WINAPI AddAccessDeniedAce(
1492 IN OUT PACL pAcl,
1493 IN DWORD dwAceRevision,
1494 IN DWORD AccessMask,
1495 IN PSID pSid)
1497 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1500 /******************************************************************************
1501 * AddAccessDeniedAceEx [ADVAPI32.@]
1503 BOOL WINAPI AddAccessDeniedAceEx(
1504 IN OUT PACL pAcl,
1505 IN DWORD dwAceRevision,
1506 IN DWORD AceFlags,
1507 IN DWORD AccessMask,
1508 IN PSID pSid)
1510 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1513 /******************************************************************************
1514 * AddAce [ADVAPI32.@]
1516 BOOL WINAPI AddAce(
1517 IN OUT PACL pAcl,
1518 IN DWORD dwAceRevision,
1519 IN DWORD dwStartingAceIndex,
1520 LPVOID pAceList,
1521 DWORD nAceListLength)
1523 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1526 /******************************************************************************
1527 * DeleteAce [ADVAPI32.@]
1529 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1531 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1534 /******************************************************************************
1535 * FindFirstFreeAce [ADVAPI32.@]
1537 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1539 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1542 /******************************************************************************
1543 * GetAce [ADVAPI32.@]
1545 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1547 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1550 /******************************************************************************
1551 * GetAclInformation [ADVAPI32.@]
1553 BOOL WINAPI GetAclInformation(
1554 PACL pAcl,
1555 LPVOID pAclInformation,
1556 DWORD nAclInformationLength,
1557 ACL_INFORMATION_CLASS dwAclInformationClass)
1559 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1560 nAclInformationLength, dwAclInformationClass));
1563 /******************************************************************************
1564 * IsValidAcl [ADVAPI32.@]
1566 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1568 return RtlValidAcl(pAcl);
1571 /* ##############################
1572 ###### MISC FUNCTIONS ######
1573 ##############################
1576 /******************************************************************************
1577 * AllocateLocallyUniqueId [ADVAPI32.@]
1579 * PARAMS
1580 * lpLuid []
1582 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1584 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1587 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1588 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1592 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1596 { '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 };
1597 static const WCHAR SE_TCB_NAME_W[] =
1598 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_SECURITY_NAME_W[] =
1600 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1602 { '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 };
1603 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1604 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1606 { '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 };
1607 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1608 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1610 { '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 };
1611 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1612 { '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 };
1613 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1614 { '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 };
1615 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_BACKUP_NAME_W[] =
1618 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_RESTORE_NAME_W[] =
1620 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1622 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1623 static const WCHAR SE_DEBUG_NAME_W[] =
1624 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_AUDIT_NAME_W[] =
1626 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1627 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1628 { '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 };
1629 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1630 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1631 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1632 { '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 };
1633 static const WCHAR SE_UNDOCK_NAME_W[] =
1634 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1635 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1636 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1637 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1638 { '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 };
1639 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1640 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1641 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1642 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1643 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1644 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1648 NULL,
1649 NULL,
1650 SE_CREATE_TOKEN_NAME_W,
1651 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1652 SE_LOCK_MEMORY_NAME_W,
1653 SE_INCREASE_QUOTA_NAME_W,
1654 SE_MACHINE_ACCOUNT_NAME_W,
1655 SE_TCB_NAME_W,
1656 SE_SECURITY_NAME_W,
1657 SE_TAKE_OWNERSHIP_NAME_W,
1658 SE_LOAD_DRIVER_NAME_W,
1659 SE_SYSTEM_PROFILE_NAME_W,
1660 SE_SYSTEMTIME_NAME_W,
1661 SE_PROF_SINGLE_PROCESS_NAME_W,
1662 SE_INC_BASE_PRIORITY_NAME_W,
1663 SE_CREATE_PAGEFILE_NAME_W,
1664 SE_CREATE_PERMANENT_NAME_W,
1665 SE_BACKUP_NAME_W,
1666 SE_RESTORE_NAME_W,
1667 SE_SHUTDOWN_NAME_W,
1668 SE_DEBUG_NAME_W,
1669 SE_AUDIT_NAME_W,
1670 SE_SYSTEM_ENVIRONMENT_NAME_W,
1671 SE_CHANGE_NOTIFY_NAME_W,
1672 SE_REMOTE_SHUTDOWN_NAME_W,
1673 SE_UNDOCK_NAME_W,
1674 SE_SYNC_AGENT_NAME_W,
1675 SE_ENABLE_DELEGATION_NAME_W,
1676 SE_MANAGE_VOLUME_NAME_W,
1677 SE_IMPERSONATE_NAME_W,
1678 SE_CREATE_GLOBAL_NAME_W,
1681 /******************************************************************************
1682 * LookupPrivilegeValueW [ADVAPI32.@]
1684 * See LookupPrivilegeValueA.
1686 BOOL WINAPI
1687 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1689 UINT i;
1691 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1693 if (!ADVAPI_IsLocalComputer(lpSystemName))
1695 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1696 return FALSE;
1698 if (!lpName)
1700 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1701 return FALSE;
1703 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1705 if( !WellKnownPrivNames[i] )
1706 continue;
1707 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1708 continue;
1709 lpLuid->LowPart = i;
1710 lpLuid->HighPart = 0;
1711 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1712 lpLuid->HighPart, lpLuid->LowPart );
1713 return TRUE;
1715 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1716 return FALSE;
1719 /******************************************************************************
1720 * LookupPrivilegeValueA [ADVAPI32.@]
1722 * Retrieves LUID used on a system to represent the privilege name.
1724 * PARAMS
1725 * lpSystemName [I] Name of the system
1726 * lpName [I] Name of the privilege
1727 * lpLuid [O] Destination for the resulting LUID
1729 * RETURNS
1730 * Success: TRUE. lpLuid contains the requested LUID.
1731 * Failure: FALSE.
1733 BOOL WINAPI
1734 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1736 UNICODE_STRING lpSystemNameW;
1737 UNICODE_STRING lpNameW;
1738 BOOL ret;
1740 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1741 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1742 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1743 RtlFreeUnicodeString(&lpNameW);
1744 RtlFreeUnicodeString(&lpSystemNameW);
1745 return ret;
1748 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1749 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1751 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1752 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1754 return FALSE;
1757 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1758 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1760 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1761 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1763 return FALSE;
1766 /******************************************************************************
1767 * LookupPrivilegeNameA [ADVAPI32.@]
1769 * See LookupPrivilegeNameW.
1771 BOOL WINAPI
1772 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1773 LPDWORD cchName)
1775 UNICODE_STRING lpSystemNameW;
1776 BOOL ret;
1777 DWORD wLen = 0;
1779 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1781 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1782 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1783 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1785 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1787 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1788 &wLen);
1789 if (ret)
1791 /* Windows crashes if cchName is NULL, so will I */
1792 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1793 *cchName, NULL, NULL);
1795 if (len == 0)
1797 /* WideCharToMultiByte failed */
1798 ret = FALSE;
1800 else if (len > *cchName)
1802 *cchName = len;
1803 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1804 ret = FALSE;
1806 else
1808 /* WideCharToMultiByte succeeded, output length needs to be
1809 * length not including NULL terminator
1811 *cchName = len - 1;
1814 HeapFree(GetProcessHeap(), 0, lpNameW);
1816 RtlFreeUnicodeString(&lpSystemNameW);
1817 return ret;
1820 /******************************************************************************
1821 * LookupPrivilegeNameW [ADVAPI32.@]
1823 * Retrieves the privilege name referred to by the LUID lpLuid.
1825 * PARAMS
1826 * lpSystemName [I] Name of the system
1827 * lpLuid [I] Privilege value
1828 * lpName [O] Name of the privilege
1829 * cchName [I/O] Number of characters in lpName.
1831 * RETURNS
1832 * Success: TRUE. lpName contains the name of the privilege whose value is
1833 * *lpLuid.
1834 * Failure: FALSE.
1836 * REMARKS
1837 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1838 * using this function.
1839 * If the length of lpName is too small, on return *cchName will contain the
1840 * number of WCHARs needed to contain the privilege, including the NULL
1841 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1842 * On success, *cchName will contain the number of characters stored in
1843 * lpName, NOT including the NULL terminator.
1845 BOOL WINAPI
1846 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1847 LPDWORD cchName)
1849 size_t privNameLen;
1851 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1853 if (!ADVAPI_IsLocalComputer(lpSystemName))
1855 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1856 return FALSE;
1858 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1859 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1861 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1862 return FALSE;
1864 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1865 /* Windows crashes if cchName is NULL, so will I */
1866 if (*cchName <= privNameLen)
1868 *cchName = privNameLen + 1;
1869 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1870 return FALSE;
1872 else
1874 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1875 *cchName = privNameLen;
1876 return TRUE;
1880 /******************************************************************************
1881 * GetFileSecurityA [ADVAPI32.@]
1883 * Obtains Specified information about the security of a file or directory.
1885 * PARAMS
1886 * lpFileName [I] Name of the file to get info for
1887 * RequestedInformation [I] SE_ flags from "winnt.h"
1888 * pSecurityDescriptor [O] Destination for security information
1889 * nLength [I] Length of pSecurityDescriptor
1890 * lpnLengthNeeded [O] Destination for length of returned security information
1892 * RETURNS
1893 * Success: TRUE. pSecurityDescriptor contains the requested information.
1894 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1896 * NOTES
1897 * The information returned is constrained by the callers access rights and
1898 * privileges.
1900 BOOL WINAPI
1901 GetFileSecurityA( LPCSTR lpFileName,
1902 SECURITY_INFORMATION RequestedInformation,
1903 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1904 DWORD nLength, LPDWORD lpnLengthNeeded )
1906 DWORD len;
1907 BOOL r;
1908 LPWSTR name = NULL;
1910 if( lpFileName )
1912 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1913 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1914 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1917 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1918 nLength, lpnLengthNeeded );
1919 HeapFree( GetProcessHeap(), 0, name );
1921 return r;
1924 /******************************************************************************
1925 * GetFileSecurityW [ADVAPI32.@]
1927 * See GetFileSecurityA.
1929 BOOL WINAPI
1930 GetFileSecurityW( LPCWSTR lpFileName,
1931 SECURITY_INFORMATION RequestedInformation,
1932 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1933 DWORD nLength, LPDWORD lpnLengthNeeded )
1935 HANDLE hfile;
1936 NTSTATUS status;
1937 DWORD access = 0;
1939 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1940 RequestedInformation, pSecurityDescriptor,
1941 nLength, lpnLengthNeeded);
1943 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1944 DACL_SECURITY_INFORMATION))
1945 access |= READ_CONTROL;
1946 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1947 access |= ACCESS_SYSTEM_SECURITY;
1949 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1950 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1951 if ( hfile == INVALID_HANDLE_VALUE )
1952 return FALSE;
1954 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1955 nLength, lpnLengthNeeded );
1956 CloseHandle( hfile );
1957 return set_ntstatus( status );
1961 /******************************************************************************
1962 * LookupAccountSidA [ADVAPI32.@]
1964 BOOL WINAPI
1965 LookupAccountSidA(
1966 IN LPCSTR system,
1967 IN PSID sid,
1968 OUT LPSTR account,
1969 IN OUT LPDWORD accountSize,
1970 OUT LPSTR domain,
1971 IN OUT LPDWORD domainSize,
1972 OUT PSID_NAME_USE name_use )
1974 DWORD len;
1975 BOOL r;
1976 LPWSTR systemW = NULL;
1977 LPWSTR accountW = NULL;
1978 LPWSTR domainW = NULL;
1979 DWORD accountSizeW = *accountSize;
1980 DWORD domainSizeW = *domainSize;
1982 if (system) {
1983 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1984 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1985 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1987 if (account)
1988 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1989 if (domain)
1990 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1992 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1994 if (r) {
1995 if (accountW && *accountSize) {
1996 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1997 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1998 *accountSize = len;
1999 } else
2000 *accountSize = accountSizeW + 1;
2002 if (domainW && *domainSize) {
2003 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2004 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2005 *domainSize = len;
2006 } else
2007 *domainSize = domainSizeW + 1;
2010 HeapFree( GetProcessHeap(), 0, systemW );
2011 HeapFree( GetProcessHeap(), 0, accountW );
2012 HeapFree( GetProcessHeap(), 0, domainW );
2014 return r;
2017 /******************************************************************************
2018 * LookupAccountSidW [ADVAPI32.@]
2020 * PARAMS
2021 * system []
2022 * sid []
2023 * account []
2024 * accountSize []
2025 * domain []
2026 * domainSize []
2027 * name_use []
2030 BOOL WINAPI
2031 LookupAccountSidW(
2032 IN LPCWSTR system,
2033 IN PSID sid,
2034 OUT LPWSTR account,
2035 IN OUT LPDWORD accountSize,
2036 OUT LPWSTR domain,
2037 IN OUT LPDWORD domainSize,
2038 OUT PSID_NAME_USE name_use )
2040 unsigned int i, j;
2041 const WCHAR * ac = NULL;
2042 const WCHAR * dm = NULL;
2043 SID_NAME_USE use = 0;
2044 LPWSTR computer_name = NULL;
2045 LPWSTR account_name = NULL;
2047 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2048 debugstr_w(system),debugstr_sid(sid),
2049 account,accountSize,accountSize?*accountSize:0,
2050 domain,domainSize,domainSize?*domainSize:0,
2051 name_use);
2053 if (!ADVAPI_IsLocalComputer(system)) {
2054 FIXME("Only local computer supported!\n");
2055 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2056 return FALSE;
2059 /* check the well known SIDs first */
2060 for (i = 0; i <= 60; i++) {
2061 if (IsWellKnownSid(sid, i)) {
2062 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2063 if (ACCOUNT_SIDS[j].type == i) {
2064 ac = ACCOUNT_SIDS[j].account;
2065 dm = ACCOUNT_SIDS[j].domain;
2066 use = ACCOUNT_SIDS[j].name_use;
2069 break;
2073 if (dm == NULL) {
2074 MAX_SID local;
2076 /* check for the local computer next */
2077 if (ADVAPI_GetComputerSid(&local)) {
2078 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2079 BOOL result;
2081 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2082 result = GetComputerNameW(computer_name, &size);
2084 if (result) {
2085 if (EqualSid(sid, &local)) {
2086 dm = computer_name;
2087 ac = Blank;
2088 use = 3;
2089 } else {
2090 local.SubAuthorityCount++;
2092 if (EqualPrefixSid(sid, &local)) {
2093 dm = computer_name;
2094 use = 1;
2095 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2096 case DOMAIN_USER_RID_ADMIN:
2097 ac = Administrator;
2098 break;
2099 case DOMAIN_USER_RID_GUEST:
2100 ac = Guest;
2101 break;
2102 case DOMAIN_GROUP_RID_ADMINS:
2103 ac = Domain_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_USERS:
2106 ac = Domain_Users;
2107 break;
2108 case DOMAIN_GROUP_RID_GUESTS:
2109 ac = Domain_Guests;
2110 break;
2111 case DOMAIN_GROUP_RID_COMPUTERS:
2112 ac = Domain_Computers;
2113 break;
2114 case DOMAIN_GROUP_RID_CONTROLLERS:
2115 ac = Domain_Controllers;
2116 break;
2117 case DOMAIN_GROUP_RID_CERT_ADMINS:
2118 ac = Cert_Publishers;
2119 break;
2120 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2121 ac = Schema_Admins;
2122 break;
2123 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2124 ac = Enterprise_Admins;
2125 break;
2126 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2127 ac = Group_Policy_Creator_Owners;
2128 break;
2129 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2130 ac = RAS_and_IAS_Servers;
2131 break;
2132 case 1000: /* first user account */
2133 size = UNLEN + 1;
2134 account_name = HeapAlloc(
2135 GetProcessHeap(), 0, size * sizeof(WCHAR));
2136 if (GetUserNameW(account_name, &size))
2137 ac = account_name;
2138 else
2139 dm = NULL;
2141 break;
2142 default:
2143 dm = NULL;
2144 break;
2152 if (dm) {
2153 DWORD ac_len = lstrlenW(ac);
2154 DWORD dm_len = lstrlenW(dm);
2155 BOOL status = TRUE;
2157 if (*accountSize > ac_len) {
2158 if (account)
2159 lstrcpyW(account, ac);
2161 if (*domainSize > dm_len) {
2162 if (domain)
2163 lstrcpyW(domain, dm);
2165 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2166 ((*domainSize != 0) && (*domainSize < dm_len))) {
2167 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2168 status = FALSE;
2170 if (*domainSize)
2171 *domainSize = dm_len;
2172 else
2173 *domainSize = dm_len + 1;
2174 if (*accountSize)
2175 *accountSize = ac_len;
2176 else
2177 *accountSize = ac_len + 1;
2178 *name_use = use;
2179 HeapFree(GetProcessHeap(), 0, account_name);
2180 HeapFree(GetProcessHeap(), 0, computer_name);
2181 return status;
2184 HeapFree(GetProcessHeap(), 0, account_name);
2185 HeapFree(GetProcessHeap(), 0, computer_name);
2186 SetLastError(ERROR_NONE_MAPPED);
2187 return FALSE;
2190 /******************************************************************************
2191 * SetFileSecurityA [ADVAPI32.@]
2193 * See SetFileSecurityW.
2195 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2196 SECURITY_INFORMATION RequestedInformation,
2197 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2199 DWORD len;
2200 BOOL r;
2201 LPWSTR name = NULL;
2203 if( lpFileName )
2205 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2206 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2207 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2210 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2211 HeapFree( GetProcessHeap(), 0, name );
2213 return r;
2216 /******************************************************************************
2217 * SetFileSecurityW [ADVAPI32.@]
2219 * Sets the security of a file or directory.
2221 * PARAMS
2222 * lpFileName []
2223 * RequestedInformation []
2224 * pSecurityDescriptor []
2226 * RETURNS
2227 * Success: TRUE.
2228 * Failure: FALSE.
2230 BOOL WINAPI
2231 SetFileSecurityW( LPCWSTR lpFileName,
2232 SECURITY_INFORMATION RequestedInformation,
2233 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2235 HANDLE file;
2236 DWORD access = 0;
2237 NTSTATUS status;
2239 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2240 pSecurityDescriptor );
2242 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2243 RequestedInformation & GROUP_SECURITY_INFORMATION)
2244 access |= WRITE_OWNER;
2245 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2246 access |= ACCESS_SYSTEM_SECURITY;
2247 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2248 access |= WRITE_DAC;
2250 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2251 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2252 if (file == INVALID_HANDLE_VALUE)
2253 return FALSE;
2255 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2256 CloseHandle( file );
2257 return set_ntstatus( status );
2260 /******************************************************************************
2261 * QueryWindows31FilesMigration [ADVAPI32.@]
2263 * PARAMS
2264 * x1 []
2266 BOOL WINAPI
2267 QueryWindows31FilesMigration( DWORD x1 )
2269 FIXME("(%d):stub\n",x1);
2270 return TRUE;
2273 /******************************************************************************
2274 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2276 * PARAMS
2277 * x1 []
2278 * x2 []
2279 * x3 []
2280 * x4 []
2282 BOOL WINAPI
2283 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2284 DWORD x4 )
2286 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2287 return TRUE;
2290 /******************************************************************************
2291 * NotifyBootConfigStatus [ADVAPI32.@]
2293 * PARAMS
2294 * x1 []
2296 BOOL WINAPI
2297 NotifyBootConfigStatus( BOOL x1 )
2299 FIXME("(0x%08d):stub\n",x1);
2300 return 1;
2303 /******************************************************************************
2304 * RevertToSelf [ADVAPI32.@]
2306 * Ends the impersonation of a user.
2308 * PARAMS
2309 * void []
2311 * RETURNS
2312 * Success: TRUE.
2313 * Failure: FALSE.
2315 BOOL WINAPI
2316 RevertToSelf( void )
2318 HANDLE Token = NULL;
2319 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2320 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2323 /******************************************************************************
2324 * ImpersonateSelf [ADVAPI32.@]
2326 * Makes an impersonation token that represents the process user and assigns
2327 * to the current thread.
2329 * PARAMS
2330 * ImpersonationLevel [I] Level at which to impersonate.
2332 * RETURNS
2333 * Success: TRUE.
2334 * Failure: FALSE.
2336 BOOL WINAPI
2337 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2339 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2342 /******************************************************************************
2343 * ImpersonateLoggedOnUser [ADVAPI32.@]
2345 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2347 DWORD size;
2348 NTSTATUS Status;
2349 HANDLE ImpersonationToken;
2350 TOKEN_TYPE Type;
2351 static BOOL warn = TRUE;
2353 if (warn)
2355 FIXME( "(%p)\n", hToken );
2356 warn = FALSE;
2358 if (!GetTokenInformation( hToken, TokenType, &Type,
2359 sizeof(TOKEN_TYPE), &size ))
2360 return FALSE;
2362 if (Type == TokenPrimary)
2364 OBJECT_ATTRIBUTES ObjectAttributes;
2366 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2368 Status = NtDuplicateToken( hToken,
2369 TOKEN_IMPERSONATE | TOKEN_QUERY,
2370 &ObjectAttributes,
2371 SecurityImpersonation,
2372 TokenImpersonation,
2373 &ImpersonationToken );
2374 if (Status != STATUS_SUCCESS)
2376 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2377 SetLastError( RtlNtStatusToDosError( Status ) );
2378 return FALSE;
2381 else
2382 ImpersonationToken = hToken;
2384 Status = NtSetInformationThread( GetCurrentThread(),
2385 ThreadImpersonationToken,
2386 &ImpersonationToken,
2387 sizeof(ImpersonationToken) );
2389 if (Type == TokenPrimary)
2390 NtClose( ImpersonationToken );
2392 if (Status != STATUS_SUCCESS)
2394 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2395 SetLastError( RtlNtStatusToDosError( Status ) );
2396 return FALSE;
2399 return TRUE;
2402 /******************************************************************************
2403 * AccessCheck [ADVAPI32.@]
2405 BOOL WINAPI
2406 AccessCheck(
2407 PSECURITY_DESCRIPTOR SecurityDescriptor,
2408 HANDLE ClientToken,
2409 DWORD DesiredAccess,
2410 PGENERIC_MAPPING GenericMapping,
2411 PPRIVILEGE_SET PrivilegeSet,
2412 LPDWORD PrivilegeSetLength,
2413 LPDWORD GrantedAccess,
2414 LPBOOL AccessStatus)
2416 NTSTATUS access_status;
2417 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2418 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2419 GrantedAccess, &access_status) );
2420 if (ret) *AccessStatus = set_ntstatus( access_status );
2421 return ret;
2425 /******************************************************************************
2426 * AccessCheckByType [ADVAPI32.@]
2428 BOOL WINAPI AccessCheckByType(
2429 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2430 PSID PrincipalSelfSid,
2431 HANDLE ClientToken,
2432 DWORD DesiredAccess,
2433 POBJECT_TYPE_LIST ObjectTypeList,
2434 DWORD ObjectTypeListLength,
2435 PGENERIC_MAPPING GenericMapping,
2436 PPRIVILEGE_SET PrivilegeSet,
2437 LPDWORD PrivilegeSetLength,
2438 LPDWORD GrantedAccess,
2439 LPBOOL AccessStatus)
2441 FIXME("stub\n");
2443 *AccessStatus = TRUE;
2445 return !*AccessStatus;
2448 /******************************************************************************
2449 * MapGenericMask [ADVAPI32.@]
2451 * Maps generic access rights into specific access rights according to the
2452 * supplied mapping.
2454 * PARAMS
2455 * AccessMask [I/O] Access rights.
2456 * GenericMapping [I] The mapping between generic and specific rights.
2458 * RETURNS
2459 * Nothing.
2461 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2463 RtlMapGenericMask( AccessMask, GenericMapping );
2466 /*************************************************************************
2467 * SetKernelObjectSecurity [ADVAPI32.@]
2469 BOOL WINAPI SetKernelObjectSecurity (
2470 IN HANDLE Handle,
2471 IN SECURITY_INFORMATION SecurityInformation,
2472 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2474 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2478 /******************************************************************************
2479 * AddAuditAccessAce [ADVAPI32.@]
2481 BOOL WINAPI AddAuditAccessAce(
2482 IN OUT PACL pAcl,
2483 IN DWORD dwAceRevision,
2484 IN DWORD dwAccessMask,
2485 IN PSID pSid,
2486 IN BOOL bAuditSuccess,
2487 IN BOOL bAuditFailure)
2489 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2490 bAuditSuccess, bAuditFailure) );
2493 /******************************************************************************
2494 * AddAuditAccessAce [ADVAPI32.@]
2496 BOOL WINAPI AddAuditAccessAceEx(
2497 IN OUT PACL pAcl,
2498 IN DWORD dwAceRevision,
2499 IN DWORD dwAceFlags,
2500 IN DWORD dwAccessMask,
2501 IN PSID pSid,
2502 IN BOOL bAuditSuccess,
2503 IN BOOL bAuditFailure)
2505 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2506 bAuditSuccess, bAuditFailure) );
2509 /******************************************************************************
2510 * LookupAccountNameA [ADVAPI32.@]
2512 BOOL WINAPI
2513 LookupAccountNameA(
2514 IN LPCSTR system,
2515 IN LPCSTR account,
2516 OUT PSID sid,
2517 OUT LPDWORD cbSid,
2518 LPSTR ReferencedDomainName,
2519 IN OUT LPDWORD cbReferencedDomainName,
2520 OUT PSID_NAME_USE name_use )
2522 BOOL ret;
2523 UNICODE_STRING lpSystemW;
2524 UNICODE_STRING lpAccountW;
2525 LPWSTR lpReferencedDomainNameW = NULL;
2527 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2528 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2530 if (ReferencedDomainName)
2531 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2533 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2534 cbReferencedDomainName, name_use);
2536 if (ret && lpReferencedDomainNameW)
2538 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2539 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2542 RtlFreeUnicodeString(&lpSystemW);
2543 RtlFreeUnicodeString(&lpAccountW);
2544 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2546 return ret;
2549 /******************************************************************************
2550 * lookup_user_account_name
2552 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2553 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2555 /* Default implementation: Always return a default SID */
2556 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2557 BOOL ret;
2558 PSID pSid;
2559 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2560 DWORD nameLen;
2561 LPCWSTR domainName;
2563 ret = AllocateAndInitializeSid(&identifierAuthority,
2565 SECURITY_BUILTIN_DOMAIN_RID,
2566 DOMAIN_ALIAS_RID_ADMINS,
2567 0, 0, 0, 0, 0, 0,
2568 &pSid);
2570 if (!ret)
2571 return FALSE;
2573 if (!RtlValidSid(pSid))
2575 FreeSid(pSid);
2576 return FALSE;
2579 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2580 CopySid(*cbSid, Sid, pSid);
2581 if (*cbSid < GetLengthSid(pSid))
2583 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2584 ret = FALSE;
2586 *cbSid = GetLengthSid(pSid);
2588 domainName = dm;
2589 nameLen = strlenW(domainName);
2591 if (*cchReferencedDomainName <= nameLen || !ret)
2593 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2594 nameLen += 1;
2595 ret = FALSE;
2597 else if (ReferencedDomainName)
2598 strcpyW(ReferencedDomainName, domainName);
2600 *cchReferencedDomainName = nameLen;
2602 if (ret)
2603 *peUse = SidTypeUser;
2605 FreeSid(pSid);
2607 return ret;
2610 /******************************************************************************
2611 * lookup_computer_account_name
2613 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2614 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2616 MAX_SID local;
2617 BOOL ret;
2618 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2619 DWORD nameLen;
2620 LPCWSTR domainName;
2622 if ((ret = ADVAPI_GetComputerSid(&local)))
2624 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2625 CopySid(*cbSid, Sid, &local);
2626 if (*cbSid < GetLengthSid(&local))
2628 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2629 ret = FALSE;
2631 *cbSid = GetLengthSid(&local);
2634 domainName = dm;
2635 nameLen = strlenW(domainName);
2637 if (*cchReferencedDomainName <= nameLen || !ret)
2639 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2640 nameLen += 1;
2641 ret = FALSE;
2643 else if (ReferencedDomainName)
2644 strcpyW(ReferencedDomainName, domainName);
2646 *cchReferencedDomainName = nameLen;
2648 if (ret)
2649 *peUse = SidTypeDomain;
2651 return ret;
2654 /******************************************************************************
2655 * LookupAccountNameW [ADVAPI32.@]
2657 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2658 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2659 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2661 BOOL ret;
2662 PSID pSid;
2663 unsigned int i;
2664 DWORD nameLen;
2665 LPWSTR userName = NULL;
2666 LPCWSTR domainName;
2667 LPCWSTR lpAccountNamePtr;
2668 LPCWSTR lpDomainNamePtr = NULL;
2670 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2671 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2673 if (!ADVAPI_IsLocalComputer(lpSystemName))
2675 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2676 return FALSE;
2679 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2681 lpAccountName = BUILTIN;
2684 /* Check well known SIDs first */
2685 if ((lpAccountNamePtr = strrchrW(lpAccountName,'\\')))
2687 lpAccountNamePtr++;
2688 lpDomainNamePtr = lpAccountName;
2690 else
2691 lpAccountNamePtr = lpAccountName;
2693 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2695 /* check domain first */
2696 if (lpDomainNamePtr && (strncmpiW(lpDomainNamePtr, ACCOUNT_SIDS[i].domain, strlenW(ACCOUNT_SIDS[i].domain)) || lpDomainNamePtr[strlenW(ACCOUNT_SIDS[i].domain)]!='\\'))
2697 continue;
2699 if (!strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].account) ||
2700 (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].alias)))
2702 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2704 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2706 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2708 if (ret)
2710 if (*cbSid < sidLen)
2712 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2713 ret = FALSE;
2715 else if (Sid)
2717 CopySid(*cbSid, Sid, pSid);
2720 *cbSid = sidLen;
2723 domainName = ACCOUNT_SIDS[i].domain;
2724 nameLen = strlenW(domainName);
2726 if (*cchReferencedDomainName <= nameLen || !ret)
2728 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2729 nameLen += 1;
2730 ret = FALSE;
2732 else if (ReferencedDomainName)
2734 strcpyW(ReferencedDomainName, domainName);
2737 *cchReferencedDomainName = nameLen;
2739 if (ret)
2741 *peUse = ACCOUNT_SIDS[i].name_use;
2744 HeapFree(GetProcessHeap(), 0, pSid);
2746 return ret;
2750 /* Let the current Unix user id masquerade as first Windows user account */
2752 nameLen = UNLEN + 1;
2754 userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2756 if (lpDomainNamePtr)
2758 /* check to make sure this account is on this computer */
2759 if (GetComputerNameW(userName, &nameLen) && strcmpW(lpDomainNamePtr, userName))
2761 SetLastError(ERROR_NONE_MAPPED);
2762 ret = FALSE;
2764 nameLen = UNLEN + 1;
2767 if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2768 ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2769 cchReferencedDomainName, peUse);
2770 else
2772 nameLen = UNLEN + 1;
2773 if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
2774 ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2775 cchReferencedDomainName, peUse);
2776 else
2778 SetLastError(ERROR_NONE_MAPPED);
2779 ret = FALSE;
2783 HeapFree(GetProcessHeap(), 0, userName);
2785 return ret;
2788 /******************************************************************************
2789 * PrivilegeCheck [ADVAPI32.@]
2791 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2793 BOOL ret;
2794 BOOLEAN Result;
2796 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2798 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2799 if (ret)
2800 *pfResult = Result;
2801 return ret;
2804 /******************************************************************************
2805 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2807 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2808 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2809 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2810 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2812 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2813 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2814 SecurityDescriptor, DesiredAccess, GenericMapping,
2815 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2816 return TRUE;
2819 /******************************************************************************
2820 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2822 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2823 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2824 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2825 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2827 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2828 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2829 SecurityDescriptor, DesiredAccess, GenericMapping,
2830 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2831 return TRUE;
2834 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2836 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2838 return TRUE;
2841 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2843 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2845 return TRUE;
2848 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2850 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2852 return TRUE;
2855 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2856 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2857 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2858 LPBOOL GenerateOnClose)
2860 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2861 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2862 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2863 GenerateOnClose);
2865 return TRUE;
2868 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2869 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2870 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2871 LPBOOL GenerateOnClose)
2873 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2874 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2875 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2876 GenerateOnClose);
2878 return TRUE;
2881 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2882 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2884 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2885 DesiredAccess, Privileges, AccessGranted);
2887 return TRUE;
2890 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2891 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2893 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2894 DesiredAccess, Privileges, AccessGranted);
2896 return TRUE;
2899 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2900 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2902 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2903 ClientToken, Privileges, AccessGranted);
2905 return TRUE;
2908 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2909 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2911 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2912 ClientToken, Privileges, AccessGranted);
2914 return TRUE;
2917 /******************************************************************************
2918 * GetSecurityInfo [ADVAPI32.@]
2920 * Retrieves a copy of the security descriptor associated with an object.
2922 * PARAMS
2923 * hObject [I] A handle for the object.
2924 * ObjectType [I] The type of object.
2925 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2926 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2927 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2928 * ppDacl [O] If non-null, receives a pointer to the DACL.
2929 * ppSacl [O] If non-null, receives a pointer to the SACL.
2930 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2931 * which must be freed with LocalFree.
2933 * RETURNS
2934 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2936 DWORD WINAPI GetSecurityInfo(
2937 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2938 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2939 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2940 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2943 PSECURITY_DESCRIPTOR sd;
2944 NTSTATUS status;
2945 ULONG n1, n2;
2946 BOOL present, defaulted;
2948 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2949 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2950 return RtlNtStatusToDosError(status);
2952 sd = LocalAlloc(0, n1);
2953 if (!sd)
2954 return ERROR_NOT_ENOUGH_MEMORY;
2956 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2957 if (status != STATUS_SUCCESS)
2959 LocalFree(sd);
2960 return RtlNtStatusToDosError(status);
2963 if (ppsidOwner)
2965 *ppsidOwner = NULL;
2966 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2968 if (ppsidGroup)
2970 *ppsidGroup = NULL;
2971 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2973 if (ppDacl)
2975 *ppDacl = NULL;
2976 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2978 if (ppSacl)
2980 *ppSacl = NULL;
2981 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2983 if (ppSecurityDescriptor)
2984 *ppSecurityDescriptor = sd;
2986 return ERROR_SUCCESS;
2989 /******************************************************************************
2990 * GetSecurityInfoExA [ADVAPI32.@]
2992 DWORD WINAPI GetSecurityInfoExA(
2993 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2994 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2995 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2996 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2999 FIXME("stub!\n");
3000 return ERROR_BAD_PROVIDER;
3003 /******************************************************************************
3004 * GetSecurityInfoExW [ADVAPI32.@]
3006 DWORD WINAPI GetSecurityInfoExW(
3007 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3008 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3009 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3010 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3013 FIXME("stub!\n");
3014 return ERROR_BAD_PROVIDER;
3017 /******************************************************************************
3018 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3020 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3021 LPSTR pTrusteeName, DWORD AccessPermissions,
3022 ACCESS_MODE AccessMode, DWORD Inheritance )
3024 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3025 AccessPermissions, AccessMode, Inheritance);
3027 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3028 pExplicitAccess->grfAccessMode = AccessMode;
3029 pExplicitAccess->grfInheritance = Inheritance;
3031 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3032 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3033 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3034 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3035 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3038 /******************************************************************************
3039 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3041 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3042 LPWSTR pTrusteeName, DWORD AccessPermissions,
3043 ACCESS_MODE AccessMode, DWORD Inheritance )
3045 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3046 AccessPermissions, AccessMode, Inheritance);
3048 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3049 pExplicitAccess->grfAccessMode = AccessMode;
3050 pExplicitAccess->grfInheritance = Inheritance;
3052 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3053 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3054 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3055 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3056 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3059 /******************************************************************************
3060 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3062 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3063 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3064 LPSTR InheritedObjectTypeName, LPSTR Name )
3066 DWORD ObjectsPresent = 0;
3068 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3069 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3071 /* Fill the OBJECTS_AND_NAME structure */
3072 pObjName->ObjectType = ObjectType;
3073 if (ObjectTypeName != NULL)
3075 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3078 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3079 if (InheritedObjectTypeName != NULL)
3081 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3084 pObjName->ObjectsPresent = ObjectsPresent;
3085 pObjName->ptstrName = Name;
3087 /* Fill the TRUSTEE structure */
3088 pTrustee->pMultipleTrustee = NULL;
3089 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3090 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3091 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3092 pTrustee->ptstrName = (LPSTR)pObjName;
3095 /******************************************************************************
3096 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3098 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3099 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3100 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3102 DWORD ObjectsPresent = 0;
3104 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3105 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3107 /* Fill the OBJECTS_AND_NAME structure */
3108 pObjName->ObjectType = ObjectType;
3109 if (ObjectTypeName != NULL)
3111 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3114 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3115 if (InheritedObjectTypeName != NULL)
3117 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3120 pObjName->ObjectsPresent = ObjectsPresent;
3121 pObjName->ptstrName = Name;
3123 /* Fill the TRUSTEE structure */
3124 pTrustee->pMultipleTrustee = NULL;
3125 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3126 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3127 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3128 pTrustee->ptstrName = (LPWSTR)pObjName;
3131 /******************************************************************************
3132 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3134 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3135 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3137 DWORD ObjectsPresent = 0;
3139 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3141 /* Fill the OBJECTS_AND_SID structure */
3142 if (pObjectGuid != NULL)
3144 pObjSid->ObjectTypeGuid = *pObjectGuid;
3145 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3147 else
3149 ZeroMemory(&pObjSid->ObjectTypeGuid,
3150 sizeof(GUID));
3153 if (pInheritedObjectGuid != NULL)
3155 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3156 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3158 else
3160 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3161 sizeof(GUID));
3164 pObjSid->ObjectsPresent = ObjectsPresent;
3165 pObjSid->pSid = pSid;
3167 /* Fill the TRUSTEE structure */
3168 pTrustee->pMultipleTrustee = NULL;
3169 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3170 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3171 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3172 pTrustee->ptstrName = (LPSTR) pObjSid;
3175 /******************************************************************************
3176 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3178 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3179 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3181 DWORD ObjectsPresent = 0;
3183 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3185 /* Fill the OBJECTS_AND_SID structure */
3186 if (pObjectGuid != NULL)
3188 pObjSid->ObjectTypeGuid = *pObjectGuid;
3189 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3191 else
3193 ZeroMemory(&pObjSid->ObjectTypeGuid,
3194 sizeof(GUID));
3197 if (pInheritedObjectGuid != NULL)
3199 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3200 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3202 else
3204 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3205 sizeof(GUID));
3208 pObjSid->ObjectsPresent = ObjectsPresent;
3209 pObjSid->pSid = pSid;
3211 /* Fill the TRUSTEE structure */
3212 pTrustee->pMultipleTrustee = NULL;
3213 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3214 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3215 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3216 pTrustee->ptstrName = (LPWSTR) pObjSid;
3219 /******************************************************************************
3220 * BuildTrusteeWithSidA [ADVAPI32.@]
3222 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3224 TRACE("%p %p\n", pTrustee, pSid);
3226 pTrustee->pMultipleTrustee = NULL;
3227 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3228 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3229 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3230 pTrustee->ptstrName = pSid;
3233 /******************************************************************************
3234 * BuildTrusteeWithSidW [ADVAPI32.@]
3236 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3238 TRACE("%p %p\n", pTrustee, pSid);
3240 pTrustee->pMultipleTrustee = NULL;
3241 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3242 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3243 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3244 pTrustee->ptstrName = pSid;
3247 /******************************************************************************
3248 * BuildTrusteeWithNameA [ADVAPI32.@]
3250 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3252 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3254 pTrustee->pMultipleTrustee = NULL;
3255 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3256 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3257 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3258 pTrustee->ptstrName = name;
3261 /******************************************************************************
3262 * BuildTrusteeWithNameW [ADVAPI32.@]
3264 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3266 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3268 pTrustee->pMultipleTrustee = NULL;
3269 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3270 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3271 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3272 pTrustee->ptstrName = name;
3275 /******************************************************************************
3276 * GetTrusteeFormA [ADVAPI32.@]
3278 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3280 TRACE("(%p)\n", pTrustee);
3282 if (!pTrustee)
3283 return TRUSTEE_BAD_FORM;
3285 return pTrustee->TrusteeForm;
3288 /******************************************************************************
3289 * GetTrusteeFormW [ADVAPI32.@]
3291 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3293 TRACE("(%p)\n", pTrustee);
3295 if (!pTrustee)
3296 return TRUSTEE_BAD_FORM;
3298 return pTrustee->TrusteeForm;
3301 /******************************************************************************
3302 * GetTrusteeNameA [ADVAPI32.@]
3304 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3306 TRACE("(%p)\n", pTrustee);
3308 if (!pTrustee)
3309 return NULL;
3311 return pTrustee->ptstrName;
3314 /******************************************************************************
3315 * GetTrusteeNameW [ADVAPI32.@]
3317 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3319 TRACE("(%p)\n", pTrustee);
3321 if (!pTrustee)
3322 return NULL;
3324 return pTrustee->ptstrName;
3327 /******************************************************************************
3328 * GetTrusteeTypeA [ADVAPI32.@]
3330 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3332 TRACE("(%p)\n", pTrustee);
3334 if (!pTrustee)
3335 return TRUSTEE_IS_UNKNOWN;
3337 return pTrustee->TrusteeType;
3340 /******************************************************************************
3341 * GetTrusteeTypeW [ADVAPI32.@]
3343 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3345 TRACE("(%p)\n", pTrustee);
3347 if (!pTrustee)
3348 return TRUSTEE_IS_UNKNOWN;
3350 return pTrustee->TrusteeType;
3353 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3354 DWORD nAclInformationLength,
3355 ACL_INFORMATION_CLASS dwAclInformationClass )
3357 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3358 nAclInformationLength, dwAclInformationClass);
3360 return TRUE;
3363 /******************************************************************************
3364 * SetEntriesInAclA [ADVAPI32.@]
3366 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3367 PACL OldAcl, PACL* NewAcl )
3369 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3370 if (NewAcl)
3371 *NewAcl = NULL;
3372 return ERROR_SUCCESS;
3375 /******************************************************************************
3376 * SetEntriesInAclW [ADVAPI32.@]
3378 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3379 PACL OldAcl, PACL* NewAcl )
3381 ULONG i;
3382 PSID *ppsid;
3383 DWORD ret = ERROR_SUCCESS;
3384 DWORD acl_size = sizeof(ACL);
3385 NTSTATUS status;
3387 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3389 *NewAcl = NULL;
3391 if (!count && !OldAcl)
3392 return ERROR_SUCCESS;
3394 /* allocate array of maximum sized sids allowed */
3395 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3396 if (!ppsid)
3397 return ERROR_OUTOFMEMORY;
3399 for (i = 0; i < count; i++)
3401 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3403 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3404 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3405 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3406 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3407 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3408 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3409 pEntries[i].Trustee.ptstrName);
3411 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3413 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3414 ret = ERROR_INVALID_PARAMETER;
3415 goto exit;
3418 switch (pEntries[i].Trustee.TrusteeForm)
3420 case TRUSTEE_IS_SID:
3421 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3422 ppsid[i], pEntries[i].Trustee.ptstrName))
3424 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3425 ret = ERROR_INVALID_PARAMETER;
3426 goto exit;
3428 break;
3429 case TRUSTEE_IS_NAME:
3431 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3432 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3433 SID_NAME_USE use;
3434 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3436 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3437 ret = ERROR_INVALID_PARAMETER;
3438 goto exit;
3440 break;
3442 case TRUSTEE_IS_OBJECTS_AND_SID:
3443 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3444 break;
3445 case TRUSTEE_IS_OBJECTS_AND_NAME:
3446 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3447 break;
3448 default:
3449 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3450 ret = ERROR_INVALID_PARAMETER;
3451 goto exit;
3454 /* Note: we overestimate the ACL size here as a tradeoff between
3455 * instructions (simplicity) and memory */
3456 switch (pEntries[i].grfAccessMode)
3458 case GRANT_ACCESS:
3459 case SET_ACCESS:
3460 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3461 break;
3462 case DENY_ACCESS:
3463 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3464 break;
3465 case SET_AUDIT_SUCCESS:
3466 case SET_AUDIT_FAILURE:
3467 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3468 break;
3469 case REVOKE_ACCESS:
3470 break;
3471 default:
3472 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3473 ret = ERROR_INVALID_PARAMETER;
3474 goto exit;
3478 if (OldAcl)
3480 ACL_SIZE_INFORMATION size_info;
3482 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3483 if (status != STATUS_SUCCESS)
3485 ret = RtlNtStatusToDosError(status);
3486 goto exit;
3488 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3491 *NewAcl = LocalAlloc(0, acl_size);
3492 if (!*NewAcl)
3494 ret = ERROR_OUTOFMEMORY;
3495 goto exit;
3498 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3499 if (status != STATUS_SUCCESS)
3501 ret = RtlNtStatusToDosError(status);
3502 goto exit;
3505 for (i = 0; i < count; i++)
3507 switch (pEntries[i].grfAccessMode)
3509 case GRANT_ACCESS:
3510 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3511 pEntries[i].grfInheritance,
3512 pEntries[i].grfAccessPermissions,
3513 ppsid[i]);
3514 break;
3515 case SET_ACCESS:
3517 ULONG j;
3518 BOOL add = TRUE;
3519 if (OldAcl)
3521 for (j = 0; ; j++)
3523 const ACE_HEADER *existing_ace_header;
3524 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3525 if (status != STATUS_SUCCESS)
3526 break;
3527 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3528 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3529 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3531 add = FALSE;
3532 break;
3536 if (add)
3537 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3538 pEntries[i].grfInheritance,
3539 pEntries[i].grfAccessPermissions,
3540 ppsid[i]);
3541 break;
3543 case DENY_ACCESS:
3544 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3545 pEntries[i].grfInheritance,
3546 pEntries[i].grfAccessPermissions,
3547 ppsid[i]);
3548 break;
3549 case SET_AUDIT_SUCCESS:
3550 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3551 pEntries[i].grfInheritance,
3552 pEntries[i].grfAccessPermissions,
3553 ppsid[i], TRUE, FALSE);
3554 break;
3555 case SET_AUDIT_FAILURE:
3556 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3557 pEntries[i].grfInheritance,
3558 pEntries[i].grfAccessPermissions,
3559 ppsid[i], FALSE, TRUE);
3560 break;
3561 default:
3562 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3566 if (OldAcl)
3568 for (i = 0; ; i++)
3570 BOOL add = TRUE;
3571 ULONG j;
3572 const ACE_HEADER *old_ace_header;
3573 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3574 if (status != STATUS_SUCCESS) break;
3575 for (j = 0; j < count; j++)
3577 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3578 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3579 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3581 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3582 add = FALSE;
3583 break;
3585 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3587 switch (old_ace_header->AceType)
3589 case ACCESS_ALLOWED_ACE_TYPE:
3590 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3591 add = FALSE;
3592 break;
3593 case ACCESS_DENIED_ACE_TYPE:
3594 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3595 add = FALSE;
3596 break;
3597 case SYSTEM_AUDIT_ACE_TYPE:
3598 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3599 add = FALSE;
3600 break;
3601 case SYSTEM_ALARM_ACE_TYPE:
3602 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3603 add = FALSE;
3604 break;
3605 default:
3606 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3609 if (!add)
3610 break;
3613 if (add)
3614 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3615 if (status != STATUS_SUCCESS)
3617 WARN("RtlAddAce failed with error 0x%08x\n", status);
3618 ret = RtlNtStatusToDosError(status);
3619 break;
3624 exit:
3625 HeapFree(GetProcessHeap(), 0, ppsid);
3626 return ret;
3629 /******************************************************************************
3630 * SetNamedSecurityInfoA [ADVAPI32.@]
3632 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3633 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3634 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3636 DWORD len;
3637 LPWSTR wstr = NULL;
3638 DWORD r;
3640 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3641 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3643 if( pObjectName )
3645 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3646 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3647 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3650 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3651 psidGroup, pDacl, pSacl );
3653 HeapFree( GetProcessHeap(), 0, wstr );
3655 return r;
3658 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3659 PSECURITY_DESCRIPTOR ModificationDescriptor,
3660 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3661 PGENERIC_MAPPING GenericMapping,
3662 HANDLE Token )
3664 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3665 ObjectsSecurityDescriptor, GenericMapping, Token);
3667 return TRUE;
3670 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3672 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3675 /******************************************************************************
3676 * AreAnyAccessesGranted [ADVAPI32.@]
3678 * Determines whether or not any of a set of specified access permissions have
3679 * been granted or not.
3681 * PARAMS
3682 * GrantedAccess [I] The permissions that have been granted.
3683 * DesiredAccess [I] The permissions that you want to have.
3685 * RETURNS
3686 * Nonzero if any of the permissions have been granted, zero if none of the
3687 * permissions have been granted.
3690 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3692 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3695 /******************************************************************************
3696 * SetNamedSecurityInfoW [ADVAPI32.@]
3698 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3699 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3700 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3702 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3703 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3704 return ERROR_SUCCESS;
3707 /******************************************************************************
3708 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3710 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3711 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3713 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3714 return ERROR_CALL_NOT_IMPLEMENTED;
3717 /******************************************************************************
3718 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3720 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3721 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3723 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3724 return ERROR_CALL_NOT_IMPLEMENTED;
3727 /******************************************************************************
3728 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3730 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3731 PACCESS_MASK pFailedAuditRights)
3733 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3734 return ERROR_CALL_NOT_IMPLEMENTED;
3738 /******************************************************************************
3739 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3741 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3742 PACCESS_MASK pFailedAuditRights)
3744 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3745 return ERROR_CALL_NOT_IMPLEMENTED;
3749 /******************************************************************************
3750 * ParseAclStringFlags
3752 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3754 DWORD flags = 0;
3755 LPCWSTR szAcl = *StringAcl;
3757 while (*szAcl != '(')
3759 if (*szAcl == 'P')
3761 flags |= SE_DACL_PROTECTED;
3763 else if (*szAcl == 'A')
3765 szAcl++;
3766 if (*szAcl == 'R')
3767 flags |= SE_DACL_AUTO_INHERIT_REQ;
3768 else if (*szAcl == 'I')
3769 flags |= SE_DACL_AUTO_INHERITED;
3771 szAcl++;
3774 *StringAcl = szAcl;
3775 return flags;
3778 /******************************************************************************
3779 * ParseAceStringType
3781 static const ACEFLAG AceType[] =
3783 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3784 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3785 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3786 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3788 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3789 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3790 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3791 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3793 { NULL, 0 },
3796 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3798 UINT len = 0;
3799 LPCWSTR szAcl = *StringAcl;
3800 const ACEFLAG *lpaf = AceType;
3802 while (lpaf->wstr &&
3803 (len = strlenW(lpaf->wstr)) &&
3804 strncmpW(lpaf->wstr, szAcl, len))
3805 lpaf++;
3807 if (!lpaf->wstr)
3808 return 0;
3810 *StringAcl += len;
3811 return lpaf->value;
3815 /******************************************************************************
3816 * ParseAceStringFlags
3818 static const ACEFLAG AceFlags[] =
3820 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3821 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3822 { SDDL_INHERITED, INHERITED_ACE },
3823 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3824 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3825 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3826 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3827 { NULL, 0 },
3830 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3832 UINT len = 0;
3833 BYTE flags = 0;
3834 LPCWSTR szAcl = *StringAcl;
3836 while (*szAcl != ';')
3838 const ACEFLAG *lpaf = AceFlags;
3840 while (lpaf->wstr &&
3841 (len = strlenW(lpaf->wstr)) &&
3842 strncmpW(lpaf->wstr, szAcl, len))
3843 lpaf++;
3845 if (!lpaf->wstr)
3846 return 0;
3848 flags |= lpaf->value;
3849 szAcl += len;
3852 *StringAcl = szAcl;
3853 return flags;
3857 /******************************************************************************
3858 * ParseAceStringRights
3860 static const ACEFLAG AceRights[] =
3862 { SDDL_GENERIC_ALL, GENERIC_ALL },
3863 { SDDL_GENERIC_READ, GENERIC_READ },
3864 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3865 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3867 { SDDL_READ_CONTROL, READ_CONTROL },
3868 { SDDL_STANDARD_DELETE, DELETE },
3869 { SDDL_WRITE_DAC, WRITE_DAC },
3870 { SDDL_WRITE_OWNER, WRITE_OWNER },
3872 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3873 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3874 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3875 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3876 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3877 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3878 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3879 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3880 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3882 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3883 { SDDL_FILE_READ, FILE_GENERIC_READ },
3884 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3885 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3887 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3888 { SDDL_KEY_READ, KEY_READ },
3889 { SDDL_KEY_WRITE, KEY_WRITE },
3890 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3891 { NULL, 0 },
3894 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3896 UINT len = 0;
3897 DWORD rights = 0;
3898 LPCWSTR szAcl = *StringAcl;
3900 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3902 LPCWSTR p = szAcl;
3904 while (*p && *p != ';')
3905 p++;
3907 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3909 rights = strtoulW(szAcl, NULL, 16);
3910 szAcl = p;
3912 else
3913 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3915 else
3917 while (*szAcl != ';')
3919 const ACEFLAG *lpaf = AceRights;
3921 while (lpaf->wstr &&
3922 (len = strlenW(lpaf->wstr)) &&
3923 strncmpW(lpaf->wstr, szAcl, len))
3925 lpaf++;
3928 if (!lpaf->wstr)
3929 return 0;
3931 rights |= lpaf->value;
3932 szAcl += len;
3936 *StringAcl = szAcl;
3937 return rights;
3941 /******************************************************************************
3942 * ParseStringAclToAcl
3944 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3946 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3947 PACL pAcl, LPDWORD cBytes)
3949 DWORD val;
3950 DWORD sidlen;
3951 DWORD length = sizeof(ACL);
3952 DWORD acesize = 0;
3953 DWORD acecount = 0;
3954 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3956 TRACE("%s\n", debugstr_w(StringAcl));
3958 if (!StringAcl)
3959 return FALSE;
3961 if (pAcl) /* pAce is only useful if we're setting values */
3962 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3964 /* Parse ACL flags */
3965 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3967 /* Parse ACE */
3968 while (*StringAcl == '(')
3970 StringAcl++;
3972 /* Parse ACE type */
3973 val = ParseAceStringType(&StringAcl);
3974 if (pAce)
3975 pAce->Header.AceType = (BYTE) val;
3976 if (*StringAcl != ';')
3977 goto lerr;
3978 StringAcl++;
3980 /* Parse ACE flags */
3981 val = ParseAceStringFlags(&StringAcl);
3982 if (pAce)
3983 pAce->Header.AceFlags = (BYTE) val;
3984 if (*StringAcl != ';')
3985 goto lerr;
3986 StringAcl++;
3988 /* Parse ACE rights */
3989 val = ParseAceStringRights(&StringAcl);
3990 if (pAce)
3991 pAce->Mask = val;
3992 if (*StringAcl != ';')
3993 goto lerr;
3994 StringAcl++;
3996 /* Parse ACE object guid */
3997 if (*StringAcl != ';')
3999 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4000 goto lerr;
4002 StringAcl++;
4004 /* Parse ACE inherit object guid */
4005 if (*StringAcl != ';')
4007 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4008 goto lerr;
4010 StringAcl++;
4012 /* Parse ACE account sid */
4013 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4015 while (*StringAcl && *StringAcl != ')')
4016 StringAcl++;
4019 if (*StringAcl != ')')
4020 goto lerr;
4021 StringAcl++;
4023 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4024 length += acesize;
4025 if (pAce)
4027 pAce->Header.AceSize = acesize;
4028 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4030 acecount++;
4033 *cBytes = length;
4035 if (length > 0xffff)
4037 ERR("ACL too large\n");
4038 goto lerr;
4041 if (pAcl)
4043 pAcl->AclRevision = ACL_REVISION;
4044 pAcl->Sbz1 = 0;
4045 pAcl->AclSize = length;
4046 pAcl->AceCount = acecount++;
4047 pAcl->Sbz2 = 0;
4049 return TRUE;
4051 lerr:
4052 SetLastError(ERROR_INVALID_ACL);
4053 WARN("Invalid ACE string format\n");
4054 return FALSE;
4058 /******************************************************************************
4059 * ParseStringSecurityDescriptorToSecurityDescriptor
4061 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4062 LPCWSTR StringSecurityDescriptor,
4063 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4064 LPDWORD cBytes)
4066 BOOL bret = FALSE;
4067 WCHAR toktype;
4068 WCHAR tok[MAX_PATH];
4069 LPCWSTR lptoken;
4070 LPBYTE lpNext = NULL;
4071 DWORD len;
4073 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4075 if (SecurityDescriptor)
4076 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4078 while (*StringSecurityDescriptor)
4080 toktype = *StringSecurityDescriptor;
4082 /* Expect char identifier followed by ':' */
4083 StringSecurityDescriptor++;
4084 if (*StringSecurityDescriptor != ':')
4086 SetLastError(ERROR_INVALID_PARAMETER);
4087 goto lend;
4089 StringSecurityDescriptor++;
4091 /* Extract token */
4092 lptoken = StringSecurityDescriptor;
4093 while (*lptoken && *lptoken != ':')
4094 lptoken++;
4096 if (*lptoken)
4097 lptoken--;
4099 len = lptoken - StringSecurityDescriptor;
4100 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4101 tok[len] = 0;
4103 switch (toktype)
4105 case 'O':
4107 DWORD bytes;
4109 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4110 goto lend;
4112 if (SecurityDescriptor)
4114 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4115 lpNext += bytes; /* Advance to next token */
4118 *cBytes += bytes;
4120 break;
4123 case 'G':
4125 DWORD bytes;
4127 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4128 goto lend;
4130 if (SecurityDescriptor)
4132 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4133 lpNext += bytes; /* Advance to next token */
4136 *cBytes += bytes;
4138 break;
4141 case 'D':
4143 DWORD flags;
4144 DWORD bytes;
4146 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4147 goto lend;
4149 if (SecurityDescriptor)
4151 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4152 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4153 lpNext += bytes; /* Advance to next token */
4156 *cBytes += bytes;
4158 break;
4161 case 'S':
4163 DWORD flags;
4164 DWORD bytes;
4166 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4167 goto lend;
4169 if (SecurityDescriptor)
4171 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4172 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4173 lpNext += bytes; /* Advance to next token */
4176 *cBytes += bytes;
4178 break;
4181 default:
4182 FIXME("Unknown token\n");
4183 SetLastError(ERROR_INVALID_PARAMETER);
4184 goto lend;
4187 StringSecurityDescriptor = lptoken;
4190 bret = TRUE;
4192 lend:
4193 return bret;
4196 /******************************************************************************
4197 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4199 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4200 LPCSTR StringSecurityDescriptor,
4201 DWORD StringSDRevision,
4202 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4203 PULONG SecurityDescriptorSize)
4205 UINT len;
4206 BOOL ret = FALSE;
4207 LPWSTR StringSecurityDescriptorW;
4209 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4210 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4212 if (StringSecurityDescriptorW)
4214 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4216 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4217 StringSDRevision, SecurityDescriptor,
4218 SecurityDescriptorSize);
4219 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4222 return ret;
4225 /******************************************************************************
4226 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4228 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4229 LPCWSTR StringSecurityDescriptor,
4230 DWORD StringSDRevision,
4231 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4232 PULONG SecurityDescriptorSize)
4234 DWORD cBytes;
4235 SECURITY_DESCRIPTOR* psd;
4236 BOOL bret = FALSE;
4238 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4240 if (GetVersion() & 0x80000000)
4242 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4243 goto lend;
4245 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4247 SetLastError(ERROR_INVALID_PARAMETER);
4248 goto lend;
4250 else if (StringSDRevision != SID_REVISION)
4252 SetLastError(ERROR_UNKNOWN_REVISION);
4253 goto lend;
4256 /* Compute security descriptor length */
4257 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4258 NULL, &cBytes))
4259 goto lend;
4261 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4262 if (!psd) goto lend;
4264 psd->Revision = SID_REVISION;
4265 psd->Control |= SE_SELF_RELATIVE;
4267 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4268 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4270 LocalFree(psd);
4271 goto lend;
4274 if (SecurityDescriptorSize)
4275 *SecurityDescriptorSize = cBytes;
4277 bret = TRUE;
4279 lend:
4280 TRACE(" ret=%d\n", bret);
4281 return bret;
4284 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4286 if (cch == -1)
4287 cch = strlenW(string);
4289 if (plen)
4290 *plen += cch;
4292 if (pwptr)
4294 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4295 *pwptr += cch;
4299 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4301 DWORD i;
4302 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4303 WCHAR subauthfmt[] = { '-','%','u',0 };
4304 WCHAR buf[26];
4305 SID *pisid = psid;
4307 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4309 SetLastError(ERROR_INVALID_SID);
4310 return FALSE;
4313 if (pisid->IdentifierAuthority.Value[0] ||
4314 pisid->IdentifierAuthority.Value[1])
4316 FIXME("not matching MS' bugs\n");
4317 SetLastError(ERROR_INVALID_SID);
4318 return FALSE;
4321 sprintfW( buf, fmt, pisid->Revision,
4322 MAKELONG(
4323 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4324 pisid->IdentifierAuthority.Value[4] ),
4325 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4326 pisid->IdentifierAuthority.Value[2] )
4327 ) );
4328 DumpString(buf, -1, pwptr, plen);
4330 for( i=0; i<pisid->SubAuthorityCount; i++ )
4332 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4333 DumpString(buf, -1, pwptr, plen);
4335 return TRUE;
4338 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4340 size_t i;
4341 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4343 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4345 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4346 return TRUE;
4350 return DumpSidNumeric(psid, pwptr, plen);
4353 static const LPCWSTR AceRightBitNames[32] = {
4354 SDDL_CREATE_CHILD, /* 0 */
4355 SDDL_DELETE_CHILD,
4356 SDDL_LIST_CHILDREN,
4357 SDDL_SELF_WRITE,
4358 SDDL_READ_PROPERTY, /* 4 */
4359 SDDL_WRITE_PROPERTY,
4360 SDDL_DELETE_TREE,
4361 SDDL_LIST_OBJECT,
4362 SDDL_CONTROL_ACCESS, /* 8 */
4363 NULL,
4364 NULL,
4365 NULL,
4366 NULL, /* 12 */
4367 NULL,
4368 NULL,
4369 NULL,
4370 SDDL_STANDARD_DELETE, /* 16 */
4371 SDDL_READ_CONTROL,
4372 SDDL_WRITE_DAC,
4373 SDDL_WRITE_OWNER,
4374 NULL, /* 20 */
4375 NULL,
4376 NULL,
4377 NULL,
4378 NULL, /* 24 */
4379 NULL,
4380 NULL,
4381 NULL,
4382 SDDL_GENERIC_ALL, /* 28 */
4383 SDDL_GENERIC_EXECUTE,
4384 SDDL_GENERIC_WRITE,
4385 SDDL_GENERIC_READ
4388 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4390 static const WCHAR fmtW[] = {'0','x','%','x',0};
4391 WCHAR buf[15];
4392 size_t i;
4394 if (mask == 0)
4395 return;
4397 /* first check if the right have name */
4398 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4400 if (AceRights[i].wstr == NULL)
4401 break;
4402 if (mask == AceRights[i].value)
4404 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4405 return;
4409 /* then check if it can be built from bit names */
4410 for (i = 0; i < 32; i++)
4412 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4414 /* can't be built from bit names */
4415 sprintfW(buf, fmtW, mask);
4416 DumpString(buf, -1, pwptr, plen);
4417 return;
4421 /* build from bit names */
4422 for (i = 0; i < 32; i++)
4423 if (mask & (1 << i))
4424 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4427 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4429 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4430 static const WCHAR openbr = '(';
4431 static const WCHAR closebr = ')';
4432 static const WCHAR semicolon = ';';
4434 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4436 SetLastError(ERROR_INVALID_ACL);
4437 return FALSE;
4440 piace = pace;
4441 DumpString(&openbr, 1, pwptr, plen);
4442 switch (piace->Header.AceType)
4444 case ACCESS_ALLOWED_ACE_TYPE:
4445 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4446 break;
4447 case ACCESS_DENIED_ACE_TYPE:
4448 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4449 break;
4450 case SYSTEM_AUDIT_ACE_TYPE:
4451 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4452 break;
4453 case SYSTEM_ALARM_ACE_TYPE:
4454 DumpString(SDDL_ALARM, -1, pwptr, plen);
4455 break;
4457 DumpString(&semicolon, 1, pwptr, plen);
4459 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4460 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4461 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4462 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4463 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4464 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4465 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4466 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4467 if (piace->Header.AceFlags & INHERITED_ACE)
4468 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4469 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4470 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4471 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4472 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4473 DumpString(&semicolon, 1, pwptr, plen);
4474 DumpRights(piace->Mask, pwptr, plen);
4475 DumpString(&semicolon, 1, pwptr, plen);
4476 /* objects not supported */
4477 DumpString(&semicolon, 1, pwptr, plen);
4478 /* objects not supported */
4479 DumpString(&semicolon, 1, pwptr, plen);
4480 if (!DumpSid(&piace->SidStart, pwptr, plen))
4481 return FALSE;
4482 DumpString(&closebr, 1, pwptr, plen);
4483 return TRUE;
4486 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4488 WORD count;
4489 int i;
4491 if (protected)
4492 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4493 if (autoInheritReq)
4494 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4495 if (autoInherited)
4496 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4498 if (pacl == NULL)
4499 return TRUE;
4501 if (!IsValidAcl(pacl))
4502 return FALSE;
4504 count = pacl->AceCount;
4505 for (i = 0; i < count; i++)
4507 LPVOID ace;
4508 if (!GetAce(pacl, i, &ace))
4509 return FALSE;
4510 if (!DumpAce(ace, pwptr, plen))
4511 return FALSE;
4514 return TRUE;
4517 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4519 static const WCHAR prefix[] = {'O',':',0};
4520 BOOL bDefaulted;
4521 PSID psid;
4523 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4524 return FALSE;
4526 if (psid == NULL)
4527 return TRUE;
4529 DumpString(prefix, -1, pwptr, plen);
4530 if (!DumpSid(psid, pwptr, plen))
4531 return FALSE;
4532 return TRUE;
4535 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4537 static const WCHAR prefix[] = {'G',':',0};
4538 BOOL bDefaulted;
4539 PSID psid;
4541 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4542 return FALSE;
4544 if (psid == NULL)
4545 return TRUE;
4547 DumpString(prefix, -1, pwptr, plen);
4548 if (!DumpSid(psid, pwptr, plen))
4549 return FALSE;
4550 return TRUE;
4553 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4555 static const WCHAR dacl[] = {'D',':',0};
4556 SECURITY_DESCRIPTOR_CONTROL control;
4557 BOOL present, defaulted;
4558 DWORD revision;
4559 PACL pacl;
4561 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4562 return FALSE;
4564 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4565 return FALSE;
4567 if (!present)
4568 return TRUE;
4570 DumpString(dacl, 2, pwptr, plen);
4571 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4572 return FALSE;
4573 return TRUE;
4576 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4578 static const WCHAR sacl[] = {'S',':',0};
4579 SECURITY_DESCRIPTOR_CONTROL control;
4580 BOOL present, defaulted;
4581 DWORD revision;
4582 PACL pacl;
4584 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4585 return FALSE;
4587 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4588 return FALSE;
4590 if (!present)
4591 return TRUE;
4593 DumpString(sacl, 2, pwptr, plen);
4594 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4595 return FALSE;
4596 return TRUE;
4599 /******************************************************************************
4600 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4602 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4604 ULONG len;
4605 WCHAR *wptr, *wstr;
4607 if (SDRevision != SDDL_REVISION_1)
4609 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4610 SetLastError(ERROR_UNKNOWN_REVISION);
4611 return FALSE;
4614 len = 0;
4615 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4616 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4617 return FALSE;
4618 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4619 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4620 return FALSE;
4621 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4622 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4623 return FALSE;
4624 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4625 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4626 return FALSE;
4628 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4629 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4630 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4631 return FALSE;
4632 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4633 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4634 return FALSE;
4635 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4636 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4637 return FALSE;
4638 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4639 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4640 return FALSE;
4641 *wptr = 0;
4643 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4644 *OutputString = wstr;
4645 if (OutputLen)
4646 *OutputLen = strlenW(*OutputString)+1;
4647 return TRUE;
4650 /******************************************************************************
4651 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4653 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4655 LPWSTR wstr;
4656 ULONG len;
4657 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4659 int lenA;
4661 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4662 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4663 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4664 LocalFree(wstr);
4666 if (OutputLen != NULL)
4667 *OutputLen = lenA;
4668 return TRUE;
4670 else
4672 *OutputString = NULL;
4673 if (OutputLen)
4674 *OutputLen = 0;
4675 return FALSE;
4679 /******************************************************************************
4680 * ConvertStringSidToSidW [ADVAPI32.@]
4682 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4684 BOOL bret = FALSE;
4685 DWORD cBytes;
4687 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4688 if (GetVersion() & 0x80000000)
4689 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4690 else if (!StringSid || !Sid)
4691 SetLastError(ERROR_INVALID_PARAMETER);
4692 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4694 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4696 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4697 if (!bret)
4698 LocalFree(*Sid);
4700 return bret;
4703 /******************************************************************************
4704 * ConvertStringSidToSidA [ADVAPI32.@]
4706 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4708 BOOL bret = FALSE;
4710 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4711 if (GetVersion() & 0x80000000)
4712 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4713 else if (!StringSid || !Sid)
4714 SetLastError(ERROR_INVALID_PARAMETER);
4715 else
4717 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4718 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4719 len * sizeof(WCHAR));
4721 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4722 bret = ConvertStringSidToSidW(wStringSid, Sid);
4723 HeapFree(GetProcessHeap(), 0, wStringSid);
4725 return bret;
4728 /******************************************************************************
4729 * ConvertSidToStringSidW [ADVAPI32.@]
4731 * format of SID string is:
4732 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4733 * where
4734 * <rev> is the revision of the SID encoded as decimal
4735 * <auth> is the identifier authority encoded as hex
4736 * <subauthN> is the subauthority id encoded as decimal
4738 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4740 DWORD len = 0;
4741 LPWSTR wstr, wptr;
4743 TRACE("%p %p\n", pSid, pstr );
4745 len = 0;
4746 if (!DumpSidNumeric(pSid, NULL, &len))
4747 return FALSE;
4748 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4749 DumpSidNumeric(pSid, &wptr, NULL);
4750 *wptr = 0;
4752 *pstr = wstr;
4753 return TRUE;
4756 /******************************************************************************
4757 * ConvertSidToStringSidA [ADVAPI32.@]
4759 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4761 LPWSTR wstr = NULL;
4762 LPSTR str;
4763 UINT len;
4765 TRACE("%p %p\n", pSid, pstr );
4767 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4768 return FALSE;
4770 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4771 str = LocalAlloc( 0, len );
4772 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4773 LocalFree( wstr );
4775 *pstr = str;
4777 return TRUE;
4780 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4781 PSECURITY_DESCRIPTOR pdesc,
4782 PSECURITY_DESCRIPTOR cdesc,
4783 PSECURITY_DESCRIPTOR* ndesc,
4784 GUID* objtype,
4785 BOOL isdir,
4786 PGENERIC_MAPPING genmap )
4788 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4790 return FALSE;
4793 BOOL WINAPI CreatePrivateObjectSecurity(
4794 PSECURITY_DESCRIPTOR ParentDescriptor,
4795 PSECURITY_DESCRIPTOR CreatorDescriptor,
4796 PSECURITY_DESCRIPTOR* NewDescriptor,
4797 BOOL IsDirectoryObject,
4798 HANDLE Token,
4799 PGENERIC_MAPPING GenericMapping )
4801 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4802 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4804 return FALSE;
4807 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4809 FIXME("%p - stub\n", ObjectDescriptor);
4811 return TRUE;
4814 BOOL WINAPI CreateProcessAsUserA(
4815 HANDLE hToken,
4816 LPCSTR lpApplicationName,
4817 LPSTR lpCommandLine,
4818 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4819 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4820 BOOL bInheritHandles,
4821 DWORD dwCreationFlags,
4822 LPVOID lpEnvironment,
4823 LPCSTR lpCurrentDirectory,
4824 LPSTARTUPINFOA lpStartupInfo,
4825 LPPROCESS_INFORMATION lpProcessInformation )
4827 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4828 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4829 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4831 return FALSE;
4834 BOOL WINAPI CreateProcessAsUserW(
4835 HANDLE hToken,
4836 LPCWSTR lpApplicationName,
4837 LPWSTR lpCommandLine,
4838 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4839 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4840 BOOL bInheritHandles,
4841 DWORD dwCreationFlags,
4842 LPVOID lpEnvironment,
4843 LPCWSTR lpCurrentDirectory,
4844 LPSTARTUPINFOW lpStartupInfo,
4845 LPPROCESS_INFORMATION lpProcessInformation )
4847 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4848 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4849 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4850 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4852 /* We should create the process with a suspended main thread */
4853 if (!CreateProcessW (lpApplicationName,
4854 lpCommandLine,
4855 lpProcessAttributes,
4856 lpThreadAttributes,
4857 bInheritHandles,
4858 dwCreationFlags, /* CREATE_SUSPENDED */
4859 lpEnvironment,
4860 lpCurrentDirectory,
4861 lpStartupInfo,
4862 lpProcessInformation))
4864 return FALSE;
4867 return TRUE;
4870 /******************************************************************************
4871 * CreateProcessWithLogonW
4873 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4874 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4875 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4877 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4878 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4879 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4880 lpStartupInfo, lpProcessInformation);
4882 return FALSE;
4885 /******************************************************************************
4886 * DuplicateTokenEx [ADVAPI32.@]
4888 BOOL WINAPI DuplicateTokenEx(
4889 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4890 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4891 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4892 TOKEN_TYPE TokenType,
4893 PHANDLE DuplicateTokenHandle )
4895 OBJECT_ATTRIBUTES ObjectAttributes;
4897 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4898 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4900 InitializeObjectAttributes(
4901 &ObjectAttributes,
4902 NULL,
4903 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4904 NULL,
4905 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4907 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4908 dwDesiredAccess,
4909 &ObjectAttributes,
4910 ImpersonationLevel,
4911 TokenType,
4912 DuplicateTokenHandle ) );
4915 BOOL WINAPI DuplicateToken(
4916 HANDLE ExistingTokenHandle,
4917 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4918 PHANDLE DuplicateTokenHandle )
4920 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4921 NULL, ImpersonationLevel, TokenImpersonation,
4922 DuplicateTokenHandle );
4925 /******************************************************************************
4926 * ComputeStringSidSize
4928 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4930 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4932 int ctok = 0;
4933 while (*StringSid)
4935 if (*StringSid == '-')
4936 ctok++;
4937 StringSid++;
4940 if (ctok >= 3)
4941 return GetSidLengthRequired(ctok - 2);
4943 else /* String constant format - Only available in winxp and above */
4945 unsigned int i;
4947 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4948 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4949 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4952 return GetSidLengthRequired(0);
4955 /******************************************************************************
4956 * ParseStringSidToSid
4958 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4960 BOOL bret = FALSE;
4961 SID* pisid=pSid;
4963 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4964 if (!StringSid)
4966 SetLastError(ERROR_INVALID_PARAMETER);
4967 TRACE("StringSid is NULL, returning FALSE\n");
4968 return FALSE;
4971 *cBytes = ComputeStringSidSize(StringSid);
4972 if (!pisid) /* Simply compute the size */
4974 TRACE("only size requested, returning TRUE\n");
4975 return TRUE;
4978 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4980 DWORD i = 0, identAuth;
4981 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4983 StringSid += 2; /* Advance to Revision */
4984 pisid->Revision = atoiW(StringSid);
4986 if (pisid->Revision != SDDL_REVISION)
4988 TRACE("Revision %d is unknown\n", pisid->Revision);
4989 goto lend; /* ERROR_INVALID_SID */
4991 if (csubauth == 0)
4993 TRACE("SubAuthorityCount is 0\n");
4994 goto lend; /* ERROR_INVALID_SID */
4997 pisid->SubAuthorityCount = csubauth;
4999 /* Advance to identifier authority */
5000 while (*StringSid && *StringSid != '-')
5001 StringSid++;
5002 if (*StringSid == '-')
5003 StringSid++;
5005 /* MS' implementation can't handle values greater than 2^32 - 1, so
5006 * we don't either; assume most significant bytes are always 0
5008 pisid->IdentifierAuthority.Value[0] = 0;
5009 pisid->IdentifierAuthority.Value[1] = 0;
5010 identAuth = atoiW(StringSid);
5011 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5012 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5013 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5014 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5016 /* Advance to first sub authority */
5017 while (*StringSid && *StringSid != '-')
5018 StringSid++;
5019 if (*StringSid == '-')
5020 StringSid++;
5022 while (*StringSid)
5024 pisid->SubAuthority[i++] = atoiW(StringSid);
5026 while (*StringSid && *StringSid != '-')
5027 StringSid++;
5028 if (*StringSid == '-')
5029 StringSid++;
5032 if (i != pisid->SubAuthorityCount)
5033 goto lend; /* ERROR_INVALID_SID */
5035 bret = TRUE;
5037 else /* String constant format - Only available in winxp and above */
5039 unsigned int i;
5040 pisid->Revision = SDDL_REVISION;
5042 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5043 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5045 DWORD j;
5046 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5047 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5048 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5049 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5050 bret = TRUE;
5053 if (!bret)
5054 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5057 lend:
5058 if (!bret)
5059 SetLastError(ERROR_INVALID_SID);
5061 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5062 return bret;
5065 /******************************************************************************
5066 * GetNamedSecurityInfoA [ADVAPI32.@]
5068 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5069 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5070 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5071 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5073 DWORD len;
5074 LPWSTR wstr = NULL;
5075 DWORD r;
5077 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5078 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5080 if( pObjectName )
5082 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5083 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5084 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5087 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5088 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5090 HeapFree( GetProcessHeap(), 0, wstr );
5092 return r;
5095 /******************************************************************************
5096 * GetNamedSecurityInfoW [ADVAPI32.@]
5098 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5099 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5100 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5102 DWORD needed, offset;
5103 SECURITY_DESCRIPTOR_RELATIVE *relative;
5104 BYTE *buffer;
5106 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5107 group, dacl, sacl, descriptor );
5109 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5111 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5112 if (info & OWNER_SECURITY_INFORMATION)
5113 needed += sizeof(sidWorld);
5114 if (info & GROUP_SECURITY_INFORMATION)
5115 needed += sizeof(sidWorld);
5116 if (info & DACL_SECURITY_INFORMATION)
5117 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5118 if (info & SACL_SECURITY_INFORMATION)
5119 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5121 /* must be freed by caller */
5122 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5123 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5125 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5127 HeapFree( GetProcessHeap(), 0, *descriptor );
5128 return ERROR_INVALID_SECURITY_DESCR;
5131 relative = *descriptor;
5132 relative->Control |= SE_SELF_RELATIVE;
5133 buffer = (BYTE *)relative;
5134 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5136 if (info & OWNER_SECURITY_INFORMATION)
5138 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5139 relative->Owner = offset;
5140 if (owner)
5141 *owner = buffer + offset;
5142 offset += sizeof(sidWorld);
5144 if (info & GROUP_SECURITY_INFORMATION)
5146 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5147 relative->Group = offset;
5148 if (group)
5149 *group = buffer + offset;
5150 offset += sizeof(sidWorld);
5152 if (info & DACL_SECURITY_INFORMATION)
5154 relative->Control |= SE_DACL_PRESENT;
5155 GetWorldAccessACL( (PACL)(buffer + offset) );
5156 relative->Dacl = offset;
5157 if (dacl)
5158 *dacl = (PACL)(buffer + offset);
5159 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5161 if (info & SACL_SECURITY_INFORMATION)
5163 relative->Control |= SE_SACL_PRESENT;
5164 GetWorldAccessACL( (PACL)(buffer + offset) );
5165 relative->Sacl = offset;
5166 if (sacl)
5167 *sacl = (PACL)(buffer + offset);
5169 return ERROR_SUCCESS;
5172 /******************************************************************************
5173 * DecryptFileW [ADVAPI32.@]
5175 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5177 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5178 return TRUE;
5181 /******************************************************************************
5182 * DecryptFileA [ADVAPI32.@]
5184 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5186 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5187 return TRUE;
5190 /******************************************************************************
5191 * EncryptFileW [ADVAPI32.@]
5193 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5195 FIXME("%s\n", debugstr_w(lpFileName));
5196 return TRUE;
5199 /******************************************************************************
5200 * EncryptFileA [ADVAPI32.@]
5202 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5204 FIXME("%s\n", debugstr_a(lpFileName));
5205 return TRUE;
5208 /******************************************************************************
5209 * FileEncryptionStatusW [ADVAPI32.@]
5211 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5213 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5214 if (!lpStatus)
5215 return FALSE;
5216 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5217 return TRUE;
5220 /******************************************************************************
5221 * FileEncryptionStatusA [ADVAPI32.@]
5223 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5225 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5226 if (!lpStatus)
5227 return FALSE;
5228 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5229 return TRUE;
5232 /******************************************************************************
5233 * SetSecurityInfo [ADVAPI32.@]
5235 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5236 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5237 PSID psidGroup, PACL pDacl, PACL pSacl) {
5238 FIXME("stub\n");
5239 return ERROR_SUCCESS;
5242 /******************************************************************************
5243 * SaferCreateLevel [ADVAPI32.@]
5245 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5246 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5248 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5249 return FALSE;
5252 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5253 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5254 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5255 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5256 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5258 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5259 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5260 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5262 return ERROR_SUCCESS;