winemac: Consolidate mouse move handling into -[WineApplicationController handleMouse...
[wine.git] / dlls / advapi32 / security.c
blob359b1e220633c94f3e295b6727e004a7e44e8130
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
41 #include "lmcons.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
49 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
50 PACL pAcl, LPDWORD cBytes);
51 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
52 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
53 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
54 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
55 LPCWSTR StringSecurityDescriptor,
56 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
57 LPDWORD cBytes);
58 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
60 typedef struct _ACEFLAG
62 LPCWSTR wstr;
63 DWORD value;
64 } ACEFLAG, *LPACEFLAG;
66 typedef struct _MAX_SID
68 /* same fields as struct _SID */
69 BYTE Revision;
70 BYTE SubAuthorityCount;
71 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
72 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
73 } MAX_SID;
75 typedef struct WELLKNOWNSID
77 WCHAR wstr[2];
78 WELL_KNOWN_SID_TYPE Type;
79 MAX_SID Sid;
80 } WELLKNOWNSID;
82 static const WELLKNOWNSID WellKnownSids[] =
84 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
85 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
86 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
87 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
88 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
89 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
90 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
91 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
92 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
93 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
94 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
95 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
96 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
97 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
98 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
99 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
100 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
101 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
102 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
103 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
104 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
105 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
106 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
107 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
108 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
109 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
110 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
111 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
112 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
113 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
114 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
115 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
116 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
117 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
118 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
119 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
120 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
121 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
122 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
123 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
124 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
125 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
126 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
127 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
128 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
129 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
130 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
131 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
132 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
133 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
134 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
135 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
138 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
139 typedef struct WELLKNOWNRID
141 WCHAR wstr[2];
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { {0,0}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { {0,0}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { {0,0}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { {0,0}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { {0,0}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { {0,0}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { {0,0}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { {0,0}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { {0,0}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { {0,0}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
216 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
223 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
405 static inline DWORD get_security_file( LPWSTR full_file_name, DWORD access, HANDLE *file )
407 UNICODE_STRING file_nameW;
408 OBJECT_ATTRIBUTES attr;
409 IO_STATUS_BLOCK io;
410 NTSTATUS status;
412 if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
413 return ERROR_PATH_NOT_FOUND;
414 attr.Length = sizeof(attr);
415 attr.RootDirectory = 0;
416 attr.Attributes = OBJ_CASE_INSENSITIVE;
417 attr.ObjectName = &file_nameW;
418 attr.SecurityDescriptor = NULL;
419 status = NtCreateFile( file, access, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
420 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
421 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
422 RtlFreeUnicodeString( &file_nameW );
423 return RtlNtStatusToDosError( status );
426 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
427 static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service )
429 SC_HANDLE manager = 0;
430 DWORD err;
432 err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager );
433 if (err == ERROR_SUCCESS)
434 err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service );
435 CloseServiceHandle( manager );
436 return err;
439 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
440 static inline DWORD get_security_regkey( LPWSTR full_key_name, DWORD access, HANDLE *key )
442 WCHAR classes_rootW[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
443 WCHAR current_userW[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
444 WCHAR machineW[] = {'M','A','C','H','I','N','E',0};
445 WCHAR usersW[] = {'U','S','E','R','S',0};
446 LPWSTR p = strchrW(full_key_name, '\\');
447 int len = p-full_key_name;
448 HKEY hParent;
450 if (!p) return ERROR_INVALID_PARAMETER;
451 if (strncmpW( full_key_name, classes_rootW, len ) == 0)
452 hParent = HKEY_CLASSES_ROOT;
453 else if (strncmpW( full_key_name, current_userW, len ) == 0)
454 hParent = HKEY_CURRENT_USER;
455 else if (strncmpW( full_key_name, machineW, len ) == 0)
456 hParent = HKEY_LOCAL_MACHINE;
457 else if (strncmpW( full_key_name, usersW, len ) == 0)
458 hParent = HKEY_USERS;
459 else
460 return ERROR_INVALID_PARAMETER;
461 return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
464 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
466 static void GetWorldAccessACL(PACL pACL)
468 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
470 pACL->AclRevision = ACL_REVISION;
471 pACL->Sbz1 = 0;
472 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
473 pACL->AceCount = 1;
474 pACL->Sbz2 = 0;
476 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
477 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
478 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
479 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
480 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
483 /************************************************************
484 * ADVAPI_IsLocalComputer
486 * Checks whether the server name indicates local machine.
488 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
490 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
491 BOOL Result;
492 LPWSTR buf;
494 if (!ServerName || !ServerName[0])
495 return TRUE;
497 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
498 Result = GetComputerNameW(buf, &dwSize);
499 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
500 ServerName += 2;
501 Result = Result && !lstrcmpW(ServerName, buf);
502 HeapFree(GetProcessHeap(), 0, buf);
504 return Result;
507 /************************************************************
508 * ADVAPI_GetComputerSid
510 BOOL ADVAPI_GetComputerSid(PSID sid)
512 static const struct /* same fields as struct SID */
514 BYTE Revision;
515 BYTE SubAuthorityCount;
516 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
517 DWORD SubAuthority[4];
518 } computer_sid =
519 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
521 memcpy( sid, &computer_sid, sizeof(computer_sid) );
522 return TRUE;
525 /* ##############################
526 ###### TOKEN FUNCTIONS ######
527 ##############################
530 /******************************************************************************
531 * OpenProcessToken [ADVAPI32.@]
532 * Opens the access token associated with a process handle.
534 * PARAMS
535 * ProcessHandle [I] Handle to process
536 * DesiredAccess [I] Desired access to process
537 * TokenHandle [O] Pointer to handle of open access token
539 * RETURNS
540 * Success: TRUE. TokenHandle contains the access token.
541 * Failure: FALSE.
543 * NOTES
544 * See NtOpenProcessToken.
546 BOOL WINAPI
547 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
548 HANDLE *TokenHandle )
550 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
553 /******************************************************************************
554 * OpenThreadToken [ADVAPI32.@]
556 * Opens the access token associated with a thread handle.
558 * PARAMS
559 * ThreadHandle [I] Handle to process
560 * DesiredAccess [I] Desired access to the thread
561 * OpenAsSelf [I] ???
562 * TokenHandle [O] Destination for the token handle
564 * RETURNS
565 * Success: TRUE. TokenHandle contains the access token.
566 * Failure: FALSE.
568 * NOTES
569 * See NtOpenThreadToken.
571 BOOL WINAPI
572 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
573 BOOL OpenAsSelf, HANDLE *TokenHandle)
575 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
578 BOOL WINAPI
579 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
580 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
582 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
583 PreviousState, ReturnLength));
586 /******************************************************************************
587 * AdjustTokenPrivileges [ADVAPI32.@]
589 * Adjust the privileges of an open token handle.
591 * PARAMS
592 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
593 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
594 * NewState [I] Desired new privileges of the token
595 * BufferLength [I] Length of NewState
596 * PreviousState [O] Destination for the previous state
597 * ReturnLength [I/O] Size of PreviousState
600 * RETURNS
601 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
602 * Failure: FALSE.
604 * NOTES
605 * See NtAdjustPrivilegesToken.
607 BOOL WINAPI
608 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
609 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
610 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
612 NTSTATUS status;
614 TRACE("\n");
616 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
617 NewState, BufferLength, PreviousState,
618 ReturnLength);
619 SetLastError( RtlNtStatusToDosError( status ));
620 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
621 return TRUE;
622 else
623 return FALSE;
626 /******************************************************************************
627 * CheckTokenMembership [ADVAPI32.@]
629 * Determine if an access token is a member of a SID.
631 * PARAMS
632 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
633 * SidToCheck [I] SID that possibly contains the token
634 * IsMember [O] Destination for result.
636 * RETURNS
637 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
638 * Failure: FALSE.
640 BOOL WINAPI
641 CheckTokenMembership( HANDLE token, PSID sid_to_check,
642 PBOOL is_member )
644 PTOKEN_GROUPS token_groups = NULL;
645 HANDLE thread_token = NULL;
646 DWORD size, i;
647 BOOL ret;
649 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
651 *is_member = FALSE;
653 if (!token)
655 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
657 HANDLE process_token;
658 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
659 if (!ret)
660 goto exit;
661 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
662 NULL, SecurityImpersonation, TokenImpersonation,
663 &thread_token);
664 CloseHandle(process_token);
665 if (!ret)
666 goto exit;
668 token = thread_token;
670 else
672 TOKEN_TYPE type;
674 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
675 if (!ret) goto exit;
677 if (type == TokenPrimary)
679 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
680 return FALSE;
684 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
685 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
686 goto exit;
688 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
689 if (!token_groups)
691 ret = FALSE;
692 goto exit;
695 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
696 if (!ret)
697 goto exit;
699 for (i = 0; i < token_groups->GroupCount; i++)
701 TRACE("Groups[%d]: {0x%x, %s}\n", i,
702 token_groups->Groups[i].Attributes,
703 debugstr_sid(token_groups->Groups[i].Sid));
704 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
705 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
707 *is_member = TRUE;
708 TRACE("sid enabled and found in token\n");
709 break;
713 exit:
714 HeapFree(GetProcessHeap(), 0, token_groups);
715 if (thread_token != NULL) CloseHandle(thread_token);
717 return ret;
720 /******************************************************************************
721 * GetTokenInformation [ADVAPI32.@]
723 * Get a type of information about an access token.
725 * PARAMS
726 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
727 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
728 * tokeninfo [O] Destination for token information
729 * tokeninfolength [I] Length of tokeninfo
730 * retlen [O] Destination for returned token information length
732 * RETURNS
733 * Success: TRUE. tokeninfo contains retlen bytes of token information
734 * Failure: FALSE.
736 * NOTES
737 * See NtQueryInformationToken.
739 BOOL WINAPI
740 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
741 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
743 TRACE("(%p, %s, %p, %d, %p):\n",
744 token,
745 (tokeninfoclass == TokenUser) ? "TokenUser" :
746 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
747 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
748 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
749 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
750 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
751 (tokeninfoclass == TokenSource) ? "TokenSource" :
752 (tokeninfoclass == TokenType) ? "TokenType" :
753 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
754 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
755 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
756 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
757 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
758 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
759 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
760 "Unknown",
761 tokeninfo, tokeninfolength, retlen);
762 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
763 tokeninfolength, retlen));
766 /******************************************************************************
767 * SetTokenInformation [ADVAPI32.@]
769 * Set information for an access token.
771 * PARAMS
772 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
773 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
774 * tokeninfo [I] Token information to set
775 * tokeninfolength [I] Length of tokeninfo
777 * RETURNS
778 * Success: TRUE. The information for the token is set to tokeninfo.
779 * Failure: FALSE.
781 BOOL WINAPI
782 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
783 LPVOID tokeninfo, DWORD tokeninfolength )
785 TRACE("(%p, %s, %p, %d): stub\n",
786 token,
787 (tokeninfoclass == TokenUser) ? "TokenUser" :
788 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
789 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
790 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
791 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
792 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
793 (tokeninfoclass == TokenSource) ? "TokenSource" :
794 (tokeninfoclass == TokenType) ? "TokenType" :
795 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
796 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
797 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
798 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
799 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
800 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
801 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
802 "Unknown",
803 tokeninfo, tokeninfolength);
805 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
808 /*************************************************************************
809 * SetThreadToken [ADVAPI32.@]
811 * Assigns an 'impersonation token' to a thread so it can assume the
812 * security privileges of another thread or process. Can also remove
813 * a previously assigned token.
815 * PARAMS
816 * thread [O] Handle to thread to set the token for
817 * token [I] Token to set
819 * RETURNS
820 * Success: TRUE. The threads access token is set to token
821 * Failure: FALSE.
823 * NOTES
824 * Only supported on NT or higher. On Win9X this function does nothing.
825 * See SetTokenInformation.
827 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
829 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
830 ThreadImpersonationToken, &token, sizeof token ));
833 /*************************************************************************
834 * CreateRestrictedToken [ADVAPI32.@]
836 * Create a new more restricted token from an existing token.
838 * PARAMS
839 * baseToken [I] Token to base the new restricted token on
840 * flags [I] Options
841 * nDisableSids [I] Length of disableSids array
842 * disableSids [I] Array of SIDs to disable in the new token
843 * nDeletePrivs [I] Length of deletePrivs array
844 * deletePrivs [I] Array of privileges to delete in the new token
845 * nRestrictSids [I] Length of restrictSids array
846 * restrictSids [I] Array of SIDs to restrict in the new token
847 * newToken [O] Address where the new token is stored
849 * RETURNS
850 * Success: TRUE
851 * Failure: FALSE
853 BOOL WINAPI CreateRestrictedToken(
854 HANDLE baseToken,
855 DWORD flags,
856 DWORD nDisableSids,
857 PSID_AND_ATTRIBUTES disableSids,
858 DWORD nDeletePrivs,
859 PLUID_AND_ATTRIBUTES deletePrivs,
860 DWORD nRestrictSids,
861 PSID_AND_ATTRIBUTES restrictSids,
862 PHANDLE newToken)
864 TOKEN_TYPE type;
865 SECURITY_IMPERSONATION_LEVEL level = TokenImpersonationLevel;
866 DWORD size;
868 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
869 baseToken, flags, nDisableSids, disableSids,
870 nDeletePrivs, deletePrivs,
871 nRestrictSids, restrictSids,
872 newToken);
874 size = sizeof(type);
875 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
876 if (type == TokenImpersonation)
878 size = sizeof(level);
879 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
880 return FALSE;
882 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
885 /* ##############################
886 ###### SID FUNCTIONS ######
887 ##############################
890 /******************************************************************************
891 * AllocateAndInitializeSid [ADVAPI32.@]
893 * PARAMS
894 * pIdentifierAuthority []
895 * nSubAuthorityCount []
896 * nSubAuthority0 []
897 * nSubAuthority1 []
898 * nSubAuthority2 []
899 * nSubAuthority3 []
900 * nSubAuthority4 []
901 * nSubAuthority5 []
902 * nSubAuthority6 []
903 * nSubAuthority7 []
904 * pSid []
906 BOOL WINAPI
907 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
908 BYTE nSubAuthorityCount,
909 DWORD nSubAuthority0, DWORD nSubAuthority1,
910 DWORD nSubAuthority2, DWORD nSubAuthority3,
911 DWORD nSubAuthority4, DWORD nSubAuthority5,
912 DWORD nSubAuthority6, DWORD nSubAuthority7,
913 PSID *pSid )
915 return set_ntstatus( RtlAllocateAndInitializeSid(
916 pIdentifierAuthority, nSubAuthorityCount,
917 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
918 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
919 pSid ));
922 /******************************************************************************
923 * FreeSid [ADVAPI32.@]
925 * PARAMS
926 * pSid []
928 PVOID WINAPI
929 FreeSid( PSID pSid )
931 RtlFreeSid(pSid);
932 return NULL; /* is documented like this */
935 /******************************************************************************
936 * CopySid [ADVAPI32.@]
938 * PARAMS
939 * nDestinationSidLength []
940 * pDestinationSid []
941 * pSourceSid []
943 BOOL WINAPI
944 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
946 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
949 /******************************************************************************
950 * CreateWellKnownSid [ADVAPI32.@]
952 BOOL WINAPI
953 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
954 PSID DomainSid,
955 PSID pSid,
956 DWORD* cbSid)
958 unsigned int i;
959 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
961 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
963 SetLastError(ERROR_INVALID_PARAMETER);
964 return FALSE;
967 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
968 if (WellKnownSids[i].Type == WellKnownSidType) {
969 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
971 if (*cbSid < length)
973 *cbSid = length;
974 SetLastError(ERROR_INSUFFICIENT_BUFFER);
975 return FALSE;
977 if (!pSid)
979 SetLastError(ERROR_INVALID_PARAMETER);
980 return FALSE;
982 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
983 *cbSid = length;
984 return TRUE;
988 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
990 SetLastError(ERROR_INVALID_PARAMETER);
991 return FALSE;
994 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
995 if (WellKnownRids[i].Type == WellKnownSidType) {
996 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
997 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
998 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
1000 if (*cbSid < output_sid_length)
1002 *cbSid = output_sid_length;
1003 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1004 return FALSE;
1006 if (!pSid)
1008 SetLastError(ERROR_INVALID_PARAMETER);
1009 return FALSE;
1011 CopyMemory(pSid, DomainSid, domain_sid_length);
1012 (*GetSidSubAuthorityCount(pSid))++;
1013 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1014 *cbSid = output_sid_length;
1015 return TRUE;
1018 SetLastError(ERROR_INVALID_PARAMETER);
1019 return FALSE;
1022 /******************************************************************************
1023 * IsWellKnownSid [ADVAPI32.@]
1025 BOOL WINAPI
1026 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1028 unsigned int i;
1029 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1031 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
1032 if (WellKnownSids[i].Type == WellKnownSidType)
1033 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1034 return TRUE;
1036 return FALSE;
1039 BOOL WINAPI
1040 IsTokenRestricted( HANDLE TokenHandle )
1042 TOKEN_GROUPS *groups;
1043 DWORD size;
1044 NTSTATUS status;
1045 BOOL restricted;
1047 TRACE("(%p)\n", TokenHandle);
1049 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1050 if (status != STATUS_BUFFER_TOO_SMALL)
1051 return FALSE;
1053 groups = HeapAlloc(GetProcessHeap(), 0, size);
1054 if (!groups)
1056 SetLastError(ERROR_OUTOFMEMORY);
1057 return FALSE;
1060 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1061 if (status != STATUS_SUCCESS)
1063 HeapFree(GetProcessHeap(), 0, groups);
1064 return set_ntstatus(status);
1067 if (groups->GroupCount)
1068 restricted = TRUE;
1069 else
1070 restricted = FALSE;
1072 HeapFree(GetProcessHeap(), 0, groups);
1074 return restricted;
1077 /******************************************************************************
1078 * IsValidSid [ADVAPI32.@]
1080 * PARAMS
1081 * pSid []
1083 BOOL WINAPI
1084 IsValidSid( PSID pSid )
1086 return RtlValidSid( pSid );
1089 /******************************************************************************
1090 * EqualSid [ADVAPI32.@]
1092 * PARAMS
1093 * pSid1 []
1094 * pSid2 []
1096 BOOL WINAPI
1097 EqualSid( PSID pSid1, PSID pSid2 )
1099 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1100 SetLastError(ERROR_SUCCESS);
1101 return ret;
1104 /******************************************************************************
1105 * EqualPrefixSid [ADVAPI32.@]
1107 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1109 return RtlEqualPrefixSid(pSid1, pSid2);
1112 /******************************************************************************
1113 * GetSidLengthRequired [ADVAPI32.@]
1115 * PARAMS
1116 * nSubAuthorityCount []
1118 DWORD WINAPI
1119 GetSidLengthRequired( BYTE nSubAuthorityCount )
1121 return RtlLengthRequiredSid(nSubAuthorityCount);
1124 /******************************************************************************
1125 * InitializeSid [ADVAPI32.@]
1127 * PARAMS
1128 * pIdentifierAuthority []
1130 BOOL WINAPI
1131 InitializeSid (
1132 PSID pSid,
1133 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1134 BYTE nSubAuthorityCount)
1136 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1139 DWORD WINAPI
1140 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1142 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1144 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1145 return 0;
1148 DWORD WINAPI
1149 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1151 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1153 return 1;
1156 /******************************************************************************
1157 * GetSidIdentifierAuthority [ADVAPI32.@]
1159 * PARAMS
1160 * pSid []
1162 PSID_IDENTIFIER_AUTHORITY WINAPI
1163 GetSidIdentifierAuthority( PSID pSid )
1165 return RtlIdentifierAuthoritySid(pSid);
1168 /******************************************************************************
1169 * GetSidSubAuthority [ADVAPI32.@]
1171 * PARAMS
1172 * pSid []
1173 * nSubAuthority []
1175 PDWORD WINAPI
1176 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1178 SetLastError(ERROR_SUCCESS);
1179 return RtlSubAuthoritySid(pSid, nSubAuthority);
1182 /******************************************************************************
1183 * GetSidSubAuthorityCount [ADVAPI32.@]
1185 * PARAMS
1186 * pSid []
1188 PUCHAR WINAPI
1189 GetSidSubAuthorityCount (PSID pSid)
1191 SetLastError(ERROR_SUCCESS);
1192 return RtlSubAuthorityCountSid(pSid);
1195 /******************************************************************************
1196 * GetLengthSid [ADVAPI32.@]
1198 * PARAMS
1199 * pSid []
1201 DWORD WINAPI
1202 GetLengthSid (PSID pSid)
1204 return RtlLengthSid(pSid);
1207 /* ##############################################
1208 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1209 ##############################################
1212 /******************************************************************************
1213 * BuildSecurityDescriptorA [ADVAPI32.@]
1215 * Builds a SD from
1217 * PARAMS
1218 * pOwner [I]
1219 * pGroup [I]
1220 * cCountOfAccessEntries [I]
1221 * pListOfAccessEntries [I]
1222 * cCountOfAuditEntries [I]
1223 * pListofAuditEntries [I]
1224 * pOldSD [I]
1225 * lpdwBufferLength [I/O]
1226 * pNewSD [O]
1228 * RETURNS
1229 * Success: ERROR_SUCCESS
1230 * Failure: nonzero error code from Winerror.h
1232 DWORD WINAPI BuildSecurityDescriptorA(
1233 IN PTRUSTEEA pOwner,
1234 IN PTRUSTEEA pGroup,
1235 IN ULONG cCountOfAccessEntries,
1236 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1237 IN ULONG cCountOfAuditEntries,
1238 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1239 IN PSECURITY_DESCRIPTOR pOldSD,
1240 IN OUT PULONG lpdwBufferLength,
1241 OUT PSECURITY_DESCRIPTOR* pNewSD)
1243 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1244 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1245 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1247 return ERROR_CALL_NOT_IMPLEMENTED;
1250 /******************************************************************************
1251 * BuildSecurityDescriptorW [ADVAPI32.@]
1253 * See BuildSecurityDescriptorA.
1255 DWORD WINAPI BuildSecurityDescriptorW(
1256 IN PTRUSTEEW pOwner,
1257 IN PTRUSTEEW pGroup,
1258 IN ULONG cCountOfAccessEntries,
1259 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1260 IN ULONG cCountOfAuditEntries,
1261 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1262 IN PSECURITY_DESCRIPTOR pOldSD,
1263 IN OUT PULONG lpdwBufferLength,
1264 OUT PSECURITY_DESCRIPTOR* pNewSD)
1266 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1267 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1268 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1270 return ERROR_CALL_NOT_IMPLEMENTED;
1273 /******************************************************************************
1274 * InitializeSecurityDescriptor [ADVAPI32.@]
1276 * PARAMS
1277 * pDescr []
1278 * revision []
1280 BOOL WINAPI
1281 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1283 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1287 /******************************************************************************
1288 * MakeAbsoluteSD [ADVAPI32.@]
1290 BOOL WINAPI MakeAbsoluteSD (
1291 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1292 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1293 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1294 OUT PACL pDacl,
1295 OUT LPDWORD lpdwDaclSize,
1296 OUT PACL pSacl,
1297 OUT LPDWORD lpdwSaclSize,
1298 OUT PSID pOwner,
1299 OUT LPDWORD lpdwOwnerSize,
1300 OUT PSID pPrimaryGroup,
1301 OUT LPDWORD lpdwPrimaryGroupSize)
1303 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1304 pAbsoluteSecurityDescriptor,
1305 lpdwAbsoluteSecurityDescriptorSize,
1306 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1307 pOwner, lpdwOwnerSize,
1308 pPrimaryGroup, lpdwPrimaryGroupSize));
1311 /******************************************************************************
1312 * GetKernelObjectSecurity [ADVAPI32.@]
1314 BOOL WINAPI GetKernelObjectSecurity(
1315 HANDLE Handle,
1316 SECURITY_INFORMATION RequestedInformation,
1317 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1318 DWORD nLength,
1319 LPDWORD lpnLengthNeeded )
1321 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1322 pSecurityDescriptor, nLength, lpnLengthNeeded);
1324 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1325 nLength, lpnLengthNeeded ));
1328 /******************************************************************************
1329 * GetPrivateObjectSecurity [ADVAPI32.@]
1331 BOOL WINAPI GetPrivateObjectSecurity(
1332 PSECURITY_DESCRIPTOR ObjectDescriptor,
1333 SECURITY_INFORMATION SecurityInformation,
1334 PSECURITY_DESCRIPTOR ResultantDescriptor,
1335 DWORD DescriptorLength,
1336 PDWORD ReturnLength )
1338 SECURITY_DESCRIPTOR desc;
1339 BOOL defaulted, present;
1340 PACL pacl;
1341 PSID psid;
1343 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1344 ResultantDescriptor, DescriptorLength, ReturnLength);
1346 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1347 return FALSE;
1349 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1351 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1352 return FALSE;
1353 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1356 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1358 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1359 return FALSE;
1360 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1363 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1365 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1366 return FALSE;
1367 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1370 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1372 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1373 return FALSE;
1374 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1377 *ReturnLength = DescriptorLength;
1378 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1381 /******************************************************************************
1382 * GetSecurityDescriptorLength [ADVAPI32.@]
1384 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1386 return RtlLengthSecurityDescriptor(pDescr);
1389 /******************************************************************************
1390 * GetSecurityDescriptorOwner [ADVAPI32.@]
1392 * PARAMS
1393 * pOwner []
1394 * lpbOwnerDefaulted []
1396 BOOL WINAPI
1397 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1398 LPBOOL lpbOwnerDefaulted )
1400 BOOLEAN defaulted;
1401 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1402 *lpbOwnerDefaulted = defaulted;
1403 return ret;
1406 /******************************************************************************
1407 * SetSecurityDescriptorOwner [ADVAPI32.@]
1409 * PARAMS
1411 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1412 PSID pOwner, BOOL bOwnerDefaulted)
1414 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1416 /******************************************************************************
1417 * GetSecurityDescriptorGroup [ADVAPI32.@]
1419 BOOL WINAPI GetSecurityDescriptorGroup(
1420 PSECURITY_DESCRIPTOR SecurityDescriptor,
1421 PSID *Group,
1422 LPBOOL GroupDefaulted)
1424 BOOLEAN defaulted;
1425 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1426 *GroupDefaulted = defaulted;
1427 return ret;
1429 /******************************************************************************
1430 * SetSecurityDescriptorGroup [ADVAPI32.@]
1432 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1433 PSID Group, BOOL GroupDefaulted)
1435 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1438 /******************************************************************************
1439 * IsValidSecurityDescriptor [ADVAPI32.@]
1441 * PARAMS
1442 * lpsecdesc []
1444 BOOL WINAPI
1445 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1447 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1450 /******************************************************************************
1451 * GetSecurityDescriptorDacl [ADVAPI32.@]
1453 BOOL WINAPI GetSecurityDescriptorDacl(
1454 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1455 OUT LPBOOL lpbDaclPresent,
1456 OUT PACL *pDacl,
1457 OUT LPBOOL lpbDaclDefaulted)
1459 BOOLEAN present, defaulted;
1460 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1461 *lpbDaclPresent = present;
1462 *lpbDaclDefaulted = defaulted;
1463 return ret;
1466 /******************************************************************************
1467 * SetSecurityDescriptorDacl [ADVAPI32.@]
1469 BOOL WINAPI
1470 SetSecurityDescriptorDacl (
1471 PSECURITY_DESCRIPTOR lpsd,
1472 BOOL daclpresent,
1473 PACL dacl,
1474 BOOL dacldefaulted )
1476 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1478 /******************************************************************************
1479 * GetSecurityDescriptorSacl [ADVAPI32.@]
1481 BOOL WINAPI GetSecurityDescriptorSacl(
1482 IN PSECURITY_DESCRIPTOR lpsd,
1483 OUT LPBOOL lpbSaclPresent,
1484 OUT PACL *pSacl,
1485 OUT LPBOOL lpbSaclDefaulted)
1487 BOOLEAN present, defaulted;
1488 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1489 *lpbSaclPresent = present;
1490 *lpbSaclDefaulted = defaulted;
1491 return ret;
1494 /**************************************************************************
1495 * SetSecurityDescriptorSacl [ADVAPI32.@]
1497 BOOL WINAPI SetSecurityDescriptorSacl (
1498 PSECURITY_DESCRIPTOR lpsd,
1499 BOOL saclpresent,
1500 PACL lpsacl,
1501 BOOL sacldefaulted)
1503 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1505 /******************************************************************************
1506 * MakeSelfRelativeSD [ADVAPI32.@]
1508 * PARAMS
1509 * lpabssecdesc []
1510 * lpselfsecdesc []
1511 * lpbuflen []
1513 BOOL WINAPI
1514 MakeSelfRelativeSD(
1515 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1516 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1517 IN OUT LPDWORD lpdwBufferLength)
1519 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1520 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1523 /******************************************************************************
1524 * GetSecurityDescriptorControl [ADVAPI32.@]
1527 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1528 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1530 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1533 /******************************************************************************
1534 * SetSecurityDescriptorControl [ADVAPI32.@]
1536 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1537 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1538 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1540 return set_ntstatus( RtlSetControlSecurityDescriptor(
1541 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1544 /* ##############################
1545 ###### ACL FUNCTIONS ######
1546 ##############################
1549 /*************************************************************************
1550 * InitializeAcl [ADVAPI32.@]
1552 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1554 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1557 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1559 IO_STATUS_BLOCK io_block;
1561 TRACE("(%p)\n", hNamedPipe);
1563 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1564 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1567 /******************************************************************************
1568 * AddAccessAllowedAce [ADVAPI32.@]
1570 BOOL WINAPI AddAccessAllowedAce(
1571 IN OUT PACL pAcl,
1572 IN DWORD dwAceRevision,
1573 IN DWORD AccessMask,
1574 IN PSID pSid)
1576 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1579 /******************************************************************************
1580 * AddAccessAllowedAceEx [ADVAPI32.@]
1582 BOOL WINAPI AddAccessAllowedAceEx(
1583 IN OUT PACL pAcl,
1584 IN DWORD dwAceRevision,
1585 IN DWORD AceFlags,
1586 IN DWORD AccessMask,
1587 IN PSID pSid)
1589 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1592 /******************************************************************************
1593 * AddAccessDeniedAce [ADVAPI32.@]
1595 BOOL WINAPI AddAccessDeniedAce(
1596 IN OUT PACL pAcl,
1597 IN DWORD dwAceRevision,
1598 IN DWORD AccessMask,
1599 IN PSID pSid)
1601 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1604 /******************************************************************************
1605 * AddAccessDeniedAceEx [ADVAPI32.@]
1607 BOOL WINAPI AddAccessDeniedAceEx(
1608 IN OUT PACL pAcl,
1609 IN DWORD dwAceRevision,
1610 IN DWORD AceFlags,
1611 IN DWORD AccessMask,
1612 IN PSID pSid)
1614 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1617 /******************************************************************************
1618 * AddAce [ADVAPI32.@]
1620 BOOL WINAPI AddAce(
1621 IN OUT PACL pAcl,
1622 IN DWORD dwAceRevision,
1623 IN DWORD dwStartingAceIndex,
1624 LPVOID pAceList,
1625 DWORD nAceListLength)
1627 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1630 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1632 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1633 return FALSE;
1636 /******************************************************************************
1637 * DeleteAce [ADVAPI32.@]
1639 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1641 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1644 /******************************************************************************
1645 * FindFirstFreeAce [ADVAPI32.@]
1647 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1649 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1652 /******************************************************************************
1653 * GetAce [ADVAPI32.@]
1655 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1657 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1660 /******************************************************************************
1661 * GetAclInformation [ADVAPI32.@]
1663 BOOL WINAPI GetAclInformation(
1664 PACL pAcl,
1665 LPVOID pAclInformation,
1666 DWORD nAclInformationLength,
1667 ACL_INFORMATION_CLASS dwAclInformationClass)
1669 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1670 nAclInformationLength, dwAclInformationClass));
1673 /******************************************************************************
1674 * IsValidAcl [ADVAPI32.@]
1676 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1678 return RtlValidAcl(pAcl);
1681 /* ##############################
1682 ###### MISC FUNCTIONS ######
1683 ##############################
1686 /******************************************************************************
1687 * AllocateLocallyUniqueId [ADVAPI32.@]
1689 * PARAMS
1690 * lpLuid []
1692 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1694 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1697 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1698 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1699 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1700 { '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 };
1701 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1702 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1703 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1704 { '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 };
1705 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1706 { '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 };
1707 static const WCHAR SE_TCB_NAME_W[] =
1708 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1709 static const WCHAR SE_SECURITY_NAME_W[] =
1710 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1711 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1712 { '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 };
1713 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1714 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1715 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1716 { '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 };
1717 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1718 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1719 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1720 { '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 };
1721 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1722 { '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 };
1723 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1724 { '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 };
1725 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1726 { '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 };
1727 static const WCHAR SE_BACKUP_NAME_W[] =
1728 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1729 static const WCHAR SE_RESTORE_NAME_W[] =
1730 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1731 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1732 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1733 static const WCHAR SE_DEBUG_NAME_W[] =
1734 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1735 static const WCHAR SE_AUDIT_NAME_W[] =
1736 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1737 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1738 { '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 };
1739 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1740 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1741 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1742 { '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 };
1743 static const WCHAR SE_UNDOCK_NAME_W[] =
1744 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1745 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1746 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1747 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1748 { '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 };
1749 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1750 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1751 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1752 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1753 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1754 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1756 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1758 NULL,
1759 NULL,
1760 SE_CREATE_TOKEN_NAME_W,
1761 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1762 SE_LOCK_MEMORY_NAME_W,
1763 SE_INCREASE_QUOTA_NAME_W,
1764 SE_MACHINE_ACCOUNT_NAME_W,
1765 SE_TCB_NAME_W,
1766 SE_SECURITY_NAME_W,
1767 SE_TAKE_OWNERSHIP_NAME_W,
1768 SE_LOAD_DRIVER_NAME_W,
1769 SE_SYSTEM_PROFILE_NAME_W,
1770 SE_SYSTEMTIME_NAME_W,
1771 SE_PROF_SINGLE_PROCESS_NAME_W,
1772 SE_INC_BASE_PRIORITY_NAME_W,
1773 SE_CREATE_PAGEFILE_NAME_W,
1774 SE_CREATE_PERMANENT_NAME_W,
1775 SE_BACKUP_NAME_W,
1776 SE_RESTORE_NAME_W,
1777 SE_SHUTDOWN_NAME_W,
1778 SE_DEBUG_NAME_W,
1779 SE_AUDIT_NAME_W,
1780 SE_SYSTEM_ENVIRONMENT_NAME_W,
1781 SE_CHANGE_NOTIFY_NAME_W,
1782 SE_REMOTE_SHUTDOWN_NAME_W,
1783 SE_UNDOCK_NAME_W,
1784 SE_SYNC_AGENT_NAME_W,
1785 SE_ENABLE_DELEGATION_NAME_W,
1786 SE_MANAGE_VOLUME_NAME_W,
1787 SE_IMPERSONATE_NAME_W,
1788 SE_CREATE_GLOBAL_NAME_W,
1791 /******************************************************************************
1792 * LookupPrivilegeValueW [ADVAPI32.@]
1794 * See LookupPrivilegeValueA.
1796 BOOL WINAPI
1797 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1799 UINT i;
1801 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1803 if (!ADVAPI_IsLocalComputer(lpSystemName))
1805 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1806 return FALSE;
1808 if (!lpName)
1810 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1811 return FALSE;
1813 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1815 if( !WellKnownPrivNames[i] )
1816 continue;
1817 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1818 continue;
1819 lpLuid->LowPart = i;
1820 lpLuid->HighPart = 0;
1821 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1822 lpLuid->HighPart, lpLuid->LowPart );
1823 return TRUE;
1825 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1826 return FALSE;
1829 /******************************************************************************
1830 * LookupPrivilegeValueA [ADVAPI32.@]
1832 * Retrieves LUID used on a system to represent the privilege name.
1834 * PARAMS
1835 * lpSystemName [I] Name of the system
1836 * lpName [I] Name of the privilege
1837 * lpLuid [O] Destination for the resulting LUID
1839 * RETURNS
1840 * Success: TRUE. lpLuid contains the requested LUID.
1841 * Failure: FALSE.
1843 BOOL WINAPI
1844 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1846 UNICODE_STRING lpSystemNameW;
1847 UNICODE_STRING lpNameW;
1848 BOOL ret;
1850 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1851 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1852 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1853 RtlFreeUnicodeString(&lpNameW);
1854 RtlFreeUnicodeString(&lpSystemNameW);
1855 return ret;
1858 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1859 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1861 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1862 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1864 return FALSE;
1867 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1868 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1870 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1871 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1873 return FALSE;
1876 /******************************************************************************
1877 * LookupPrivilegeNameA [ADVAPI32.@]
1879 * See LookupPrivilegeNameW.
1881 BOOL WINAPI
1882 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1883 LPDWORD cchName)
1885 UNICODE_STRING lpSystemNameW;
1886 BOOL ret;
1887 DWORD wLen = 0;
1889 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1891 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1892 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1893 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1895 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1897 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1898 &wLen);
1899 if (ret)
1901 /* Windows crashes if cchName is NULL, so will I */
1902 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1903 *cchName, NULL, NULL);
1905 if (len == 0)
1907 /* WideCharToMultiByte failed */
1908 ret = FALSE;
1910 else if (len > *cchName)
1912 *cchName = len;
1913 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1914 ret = FALSE;
1916 else
1918 /* WideCharToMultiByte succeeded, output length needs to be
1919 * length not including NULL terminator
1921 *cchName = len - 1;
1924 HeapFree(GetProcessHeap(), 0, lpNameW);
1926 RtlFreeUnicodeString(&lpSystemNameW);
1927 return ret;
1930 /******************************************************************************
1931 * LookupPrivilegeNameW [ADVAPI32.@]
1933 * Retrieves the privilege name referred to by the LUID lpLuid.
1935 * PARAMS
1936 * lpSystemName [I] Name of the system
1937 * lpLuid [I] Privilege value
1938 * lpName [O] Name of the privilege
1939 * cchName [I/O] Number of characters in lpName.
1941 * RETURNS
1942 * Success: TRUE. lpName contains the name of the privilege whose value is
1943 * *lpLuid.
1944 * Failure: FALSE.
1946 * REMARKS
1947 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1948 * using this function.
1949 * If the length of lpName is too small, on return *cchName will contain the
1950 * number of WCHARs needed to contain the privilege, including the NULL
1951 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1952 * On success, *cchName will contain the number of characters stored in
1953 * lpName, NOT including the NULL terminator.
1955 BOOL WINAPI
1956 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1957 LPDWORD cchName)
1959 size_t privNameLen;
1961 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1963 if (!ADVAPI_IsLocalComputer(lpSystemName))
1965 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1966 return FALSE;
1968 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1969 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1971 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1972 return FALSE;
1974 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1975 /* Windows crashes if cchName is NULL, so will I */
1976 if (*cchName <= privNameLen)
1978 *cchName = privNameLen + 1;
1979 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1980 return FALSE;
1982 else
1984 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1985 *cchName = privNameLen;
1986 return TRUE;
1990 /******************************************************************************
1991 * GetFileSecurityA [ADVAPI32.@]
1993 * Obtains Specified information about the security of a file or directory.
1995 * PARAMS
1996 * lpFileName [I] Name of the file to get info for
1997 * RequestedInformation [I] SE_ flags from "winnt.h"
1998 * pSecurityDescriptor [O] Destination for security information
1999 * nLength [I] Length of pSecurityDescriptor
2000 * lpnLengthNeeded [O] Destination for length of returned security information
2002 * RETURNS
2003 * Success: TRUE. pSecurityDescriptor contains the requested information.
2004 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2006 * NOTES
2007 * The information returned is constrained by the callers access rights and
2008 * privileges.
2010 BOOL WINAPI
2011 GetFileSecurityA( LPCSTR lpFileName,
2012 SECURITY_INFORMATION RequestedInformation,
2013 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2014 DWORD nLength, LPDWORD lpnLengthNeeded )
2016 BOOL r;
2017 LPWSTR name;
2019 name = SERV_dup(lpFileName);
2020 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2021 nLength, lpnLengthNeeded );
2022 HeapFree( GetProcessHeap(), 0, name );
2024 return r;
2027 /******************************************************************************
2028 * GetFileSecurityW [ADVAPI32.@]
2030 * See GetFileSecurityA.
2032 BOOL WINAPI
2033 GetFileSecurityW( LPCWSTR lpFileName,
2034 SECURITY_INFORMATION RequestedInformation,
2035 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2036 DWORD nLength, LPDWORD lpnLengthNeeded )
2038 HANDLE hfile;
2039 NTSTATUS status;
2040 DWORD access = 0;
2042 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2043 RequestedInformation, pSecurityDescriptor,
2044 nLength, lpnLengthNeeded);
2046 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2047 DACL_SECURITY_INFORMATION))
2048 access |= READ_CONTROL;
2049 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2050 access |= ACCESS_SYSTEM_SECURITY;
2052 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2053 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2054 if ( hfile == INVALID_HANDLE_VALUE )
2055 return FALSE;
2057 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2058 nLength, lpnLengthNeeded );
2059 CloseHandle( hfile );
2060 return set_ntstatus( status );
2064 /******************************************************************************
2065 * LookupAccountSidA [ADVAPI32.@]
2067 BOOL WINAPI
2068 LookupAccountSidA(
2069 IN LPCSTR system,
2070 IN PSID sid,
2071 OUT LPSTR account,
2072 IN OUT LPDWORD accountSize,
2073 OUT LPSTR domain,
2074 IN OUT LPDWORD domainSize,
2075 OUT PSID_NAME_USE name_use )
2077 DWORD len;
2078 BOOL r;
2079 LPWSTR systemW;
2080 LPWSTR accountW = NULL;
2081 LPWSTR domainW = NULL;
2082 DWORD accountSizeW = *accountSize;
2083 DWORD domainSizeW = *domainSize;
2085 systemW = SERV_dup(system);
2086 if (account)
2087 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2088 if (domain)
2089 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2091 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2093 if (r) {
2094 if (accountW && *accountSize) {
2095 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2096 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2097 *accountSize = len;
2098 } else
2099 *accountSize = accountSizeW + 1;
2101 if (domainW && *domainSize) {
2102 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2103 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2104 *domainSize = len;
2105 } else
2106 *domainSize = domainSizeW + 1;
2108 else
2110 *accountSize = accountSizeW + 1;
2111 *domainSize = domainSizeW + 1;
2114 HeapFree( GetProcessHeap(), 0, systemW );
2115 HeapFree( GetProcessHeap(), 0, accountW );
2116 HeapFree( GetProcessHeap(), 0, domainW );
2118 return r;
2121 /******************************************************************************
2122 * LookupAccountSidW [ADVAPI32.@]
2124 * PARAMS
2125 * system []
2126 * sid []
2127 * account []
2128 * accountSize []
2129 * domain []
2130 * domainSize []
2131 * name_use []
2134 BOOL WINAPI
2135 LookupAccountSidW(
2136 IN LPCWSTR system,
2137 IN PSID sid,
2138 OUT LPWSTR account,
2139 IN OUT LPDWORD accountSize,
2140 OUT LPWSTR domain,
2141 IN OUT LPDWORD domainSize,
2142 OUT PSID_NAME_USE name_use )
2144 unsigned int i, j;
2145 const WCHAR * ac = NULL;
2146 const WCHAR * dm = NULL;
2147 SID_NAME_USE use = 0;
2148 LPWSTR computer_name = NULL;
2149 LPWSTR account_name = NULL;
2151 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2152 debugstr_w(system),debugstr_sid(sid),
2153 account,accountSize,accountSize?*accountSize:0,
2154 domain,domainSize,domainSize?*domainSize:0,
2155 name_use);
2157 if (!ADVAPI_IsLocalComputer(system)) {
2158 FIXME("Only local computer supported!\n");
2159 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2160 return FALSE;
2163 /* check the well known SIDs first */
2164 for (i = 0; i <= 60; i++) {
2165 if (IsWellKnownSid(sid, i)) {
2166 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2167 if (ACCOUNT_SIDS[j].type == i) {
2168 ac = ACCOUNT_SIDS[j].account;
2169 dm = ACCOUNT_SIDS[j].domain;
2170 use = ACCOUNT_SIDS[j].name_use;
2173 break;
2177 if (dm == NULL) {
2178 MAX_SID local;
2180 /* check for the local computer next */
2181 if (ADVAPI_GetComputerSid(&local)) {
2182 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2183 BOOL result;
2185 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2186 result = GetComputerNameW(computer_name, &size);
2188 if (result) {
2189 if (EqualSid(sid, &local)) {
2190 dm = computer_name;
2191 ac = Blank;
2192 use = 3;
2193 } else {
2194 local.SubAuthorityCount++;
2196 if (EqualPrefixSid(sid, &local)) {
2197 dm = computer_name;
2198 use = 1;
2199 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2200 case DOMAIN_USER_RID_ADMIN:
2201 ac = Administrator;
2202 break;
2203 case DOMAIN_USER_RID_GUEST:
2204 ac = Guest;
2205 break;
2206 case DOMAIN_GROUP_RID_ADMINS:
2207 ac = Domain_Admins;
2208 break;
2209 case DOMAIN_GROUP_RID_USERS:
2210 ac = Domain_Users;
2211 break;
2212 case DOMAIN_GROUP_RID_GUESTS:
2213 ac = Domain_Guests;
2214 break;
2215 case DOMAIN_GROUP_RID_COMPUTERS:
2216 ac = Domain_Computers;
2217 break;
2218 case DOMAIN_GROUP_RID_CONTROLLERS:
2219 ac = Domain_Controllers;
2220 break;
2221 case DOMAIN_GROUP_RID_CERT_ADMINS:
2222 ac = Cert_Publishers;
2223 break;
2224 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2225 ac = Schema_Admins;
2226 break;
2227 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2228 ac = Enterprise_Admins;
2229 break;
2230 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2231 ac = Group_Policy_Creator_Owners;
2232 break;
2233 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2234 ac = RAS_and_IAS_Servers;
2235 break;
2236 case 1000: /* first user account */
2237 size = UNLEN + 1;
2238 account_name = HeapAlloc(
2239 GetProcessHeap(), 0, size * sizeof(WCHAR));
2240 if (GetUserNameW(account_name, &size))
2241 ac = account_name;
2242 else
2243 dm = NULL;
2245 break;
2246 default:
2247 dm = NULL;
2248 break;
2256 if (dm) {
2257 DWORD ac_len = lstrlenW(ac);
2258 DWORD dm_len = lstrlenW(dm);
2259 BOOL status = TRUE;
2261 if (*accountSize > ac_len) {
2262 if (account)
2263 lstrcpyW(account, ac);
2265 if (*domainSize > dm_len) {
2266 if (domain)
2267 lstrcpyW(domain, dm);
2269 if ((*accountSize && *accountSize < ac_len) ||
2270 (!account && !*accountSize && ac_len) ||
2271 (*domainSize && *domainSize < dm_len) ||
2272 (!domain && !*domainSize && dm_len))
2274 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2275 status = FALSE;
2277 if (*domainSize)
2278 *domainSize = dm_len;
2279 else
2280 *domainSize = dm_len + 1;
2281 if (*accountSize)
2282 *accountSize = ac_len;
2283 else
2284 *accountSize = ac_len + 1;
2286 HeapFree(GetProcessHeap(), 0, account_name);
2287 HeapFree(GetProcessHeap(), 0, computer_name);
2288 if (status) *name_use = use;
2289 return status;
2292 HeapFree(GetProcessHeap(), 0, account_name);
2293 HeapFree(GetProcessHeap(), 0, computer_name);
2294 SetLastError(ERROR_NONE_MAPPED);
2295 return FALSE;
2298 /******************************************************************************
2299 * SetFileSecurityA [ADVAPI32.@]
2301 * See SetFileSecurityW.
2303 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2304 SECURITY_INFORMATION RequestedInformation,
2305 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2307 BOOL r;
2308 LPWSTR name;
2310 name = SERV_dup(lpFileName);
2311 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2312 HeapFree( GetProcessHeap(), 0, name );
2314 return r;
2317 /******************************************************************************
2318 * SetFileSecurityW [ADVAPI32.@]
2320 * Sets the security of a file or directory.
2322 * PARAMS
2323 * lpFileName []
2324 * RequestedInformation []
2325 * pSecurityDescriptor []
2327 * RETURNS
2328 * Success: TRUE.
2329 * Failure: FALSE.
2331 BOOL WINAPI
2332 SetFileSecurityW( LPCWSTR lpFileName,
2333 SECURITY_INFORMATION RequestedInformation,
2334 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2336 HANDLE file;
2337 DWORD access = 0;
2338 NTSTATUS status;
2340 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2341 pSecurityDescriptor );
2343 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2344 RequestedInformation & GROUP_SECURITY_INFORMATION)
2345 access |= WRITE_OWNER;
2346 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2347 access |= ACCESS_SYSTEM_SECURITY;
2348 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2349 access |= WRITE_DAC;
2351 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2352 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2353 if (file == INVALID_HANDLE_VALUE)
2354 return FALSE;
2356 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2357 CloseHandle( file );
2358 return set_ntstatus( status );
2361 /******************************************************************************
2362 * QueryWindows31FilesMigration [ADVAPI32.@]
2364 * PARAMS
2365 * x1 []
2367 BOOL WINAPI
2368 QueryWindows31FilesMigration( DWORD x1 )
2370 FIXME("(%d):stub\n",x1);
2371 return TRUE;
2374 /******************************************************************************
2375 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2377 * PARAMS
2378 * x1 []
2379 * x2 []
2380 * x3 []
2381 * x4 []
2383 BOOL WINAPI
2384 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2385 DWORD x4 )
2387 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2388 return TRUE;
2391 /******************************************************************************
2392 * NotifyBootConfigStatus [ADVAPI32.@]
2394 * PARAMS
2395 * x1 []
2397 BOOL WINAPI
2398 NotifyBootConfigStatus( BOOL x1 )
2400 FIXME("(0x%08d):stub\n",x1);
2401 return 1;
2404 /******************************************************************************
2405 * RevertToSelf [ADVAPI32.@]
2407 * Ends the impersonation of a user.
2409 * PARAMS
2410 * void []
2412 * RETURNS
2413 * Success: TRUE.
2414 * Failure: FALSE.
2416 BOOL WINAPI
2417 RevertToSelf( void )
2419 HANDLE Token = NULL;
2420 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2421 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2424 /******************************************************************************
2425 * ImpersonateSelf [ADVAPI32.@]
2427 * Makes an impersonation token that represents the process user and assigns
2428 * to the current thread.
2430 * PARAMS
2431 * ImpersonationLevel [I] Level at which to impersonate.
2433 * RETURNS
2434 * Success: TRUE.
2435 * Failure: FALSE.
2437 BOOL WINAPI
2438 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2440 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2443 /******************************************************************************
2444 * ImpersonateLoggedOnUser [ADVAPI32.@]
2446 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2448 DWORD size;
2449 NTSTATUS Status;
2450 HANDLE ImpersonationToken;
2451 TOKEN_TYPE Type;
2452 static BOOL warn = TRUE;
2454 if (warn)
2456 FIXME( "(%p)\n", hToken );
2457 warn = FALSE;
2459 if (!GetTokenInformation( hToken, TokenType, &Type,
2460 sizeof(TOKEN_TYPE), &size ))
2461 return FALSE;
2463 if (Type == TokenPrimary)
2465 OBJECT_ATTRIBUTES ObjectAttributes;
2467 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2469 Status = NtDuplicateToken( hToken,
2470 TOKEN_IMPERSONATE | TOKEN_QUERY,
2471 &ObjectAttributes,
2472 SecurityImpersonation,
2473 TokenImpersonation,
2474 &ImpersonationToken );
2475 if (Status != STATUS_SUCCESS)
2477 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2478 SetLastError( RtlNtStatusToDosError( Status ) );
2479 return FALSE;
2482 else
2483 ImpersonationToken = hToken;
2485 Status = NtSetInformationThread( GetCurrentThread(),
2486 ThreadImpersonationToken,
2487 &ImpersonationToken,
2488 sizeof(ImpersonationToken) );
2490 if (Type == TokenPrimary)
2491 NtClose( ImpersonationToken );
2493 if (Status != STATUS_SUCCESS)
2495 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2496 SetLastError( RtlNtStatusToDosError( Status ) );
2497 return FALSE;
2500 return TRUE;
2503 /******************************************************************************
2504 * AccessCheck [ADVAPI32.@]
2506 BOOL WINAPI
2507 AccessCheck(
2508 PSECURITY_DESCRIPTOR SecurityDescriptor,
2509 HANDLE ClientToken,
2510 DWORD DesiredAccess,
2511 PGENERIC_MAPPING GenericMapping,
2512 PPRIVILEGE_SET PrivilegeSet,
2513 LPDWORD PrivilegeSetLength,
2514 LPDWORD GrantedAccess,
2515 LPBOOL AccessStatus)
2517 NTSTATUS access_status;
2518 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2519 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2520 GrantedAccess, &access_status) );
2521 if (ret) *AccessStatus = set_ntstatus( access_status );
2522 return ret;
2526 /******************************************************************************
2527 * AccessCheckByType [ADVAPI32.@]
2529 BOOL WINAPI AccessCheckByType(
2530 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2531 PSID PrincipalSelfSid,
2532 HANDLE ClientToken,
2533 DWORD DesiredAccess,
2534 POBJECT_TYPE_LIST ObjectTypeList,
2535 DWORD ObjectTypeListLength,
2536 PGENERIC_MAPPING GenericMapping,
2537 PPRIVILEGE_SET PrivilegeSet,
2538 LPDWORD PrivilegeSetLength,
2539 LPDWORD GrantedAccess,
2540 LPBOOL AccessStatus)
2542 FIXME("stub\n");
2544 *AccessStatus = TRUE;
2546 return !*AccessStatus;
2549 /******************************************************************************
2550 * MapGenericMask [ADVAPI32.@]
2552 * Maps generic access rights into specific access rights according to the
2553 * supplied mapping.
2555 * PARAMS
2556 * AccessMask [I/O] Access rights.
2557 * GenericMapping [I] The mapping between generic and specific rights.
2559 * RETURNS
2560 * Nothing.
2562 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2564 RtlMapGenericMask( AccessMask, GenericMapping );
2567 /*************************************************************************
2568 * SetKernelObjectSecurity [ADVAPI32.@]
2570 BOOL WINAPI SetKernelObjectSecurity (
2571 IN HANDLE Handle,
2572 IN SECURITY_INFORMATION SecurityInformation,
2573 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2575 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2579 /******************************************************************************
2580 * AddAuditAccessAce [ADVAPI32.@]
2582 BOOL WINAPI AddAuditAccessAce(
2583 IN OUT PACL pAcl,
2584 IN DWORD dwAceRevision,
2585 IN DWORD dwAccessMask,
2586 IN PSID pSid,
2587 IN BOOL bAuditSuccess,
2588 IN BOOL bAuditFailure)
2590 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2591 bAuditSuccess, bAuditFailure) );
2594 /******************************************************************************
2595 * AddAuditAccessAce [ADVAPI32.@]
2597 BOOL WINAPI AddAuditAccessAceEx(
2598 IN OUT PACL pAcl,
2599 IN DWORD dwAceRevision,
2600 IN DWORD dwAceFlags,
2601 IN DWORD dwAccessMask,
2602 IN PSID pSid,
2603 IN BOOL bAuditSuccess,
2604 IN BOOL bAuditFailure)
2606 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2607 bAuditSuccess, bAuditFailure) );
2610 /******************************************************************************
2611 * LookupAccountNameA [ADVAPI32.@]
2613 BOOL WINAPI
2614 LookupAccountNameA(
2615 IN LPCSTR system,
2616 IN LPCSTR account,
2617 OUT PSID sid,
2618 OUT LPDWORD cbSid,
2619 LPSTR ReferencedDomainName,
2620 IN OUT LPDWORD cbReferencedDomainName,
2621 OUT PSID_NAME_USE name_use )
2623 BOOL ret;
2624 UNICODE_STRING lpSystemW;
2625 UNICODE_STRING lpAccountW;
2626 LPWSTR lpReferencedDomainNameW = NULL;
2628 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2629 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2631 if (ReferencedDomainName)
2632 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2634 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2635 cbReferencedDomainName, name_use);
2637 if (ret && lpReferencedDomainNameW)
2639 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2640 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2643 RtlFreeUnicodeString(&lpSystemW);
2644 RtlFreeUnicodeString(&lpAccountW);
2645 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2647 return ret;
2650 /******************************************************************************
2651 * lookup_user_account_name
2653 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2654 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2656 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2657 DWORD len = sizeof(buffer);
2658 HANDLE token;
2659 BOOL ret;
2660 PSID pSid;
2661 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2662 DWORD nameLen;
2664 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2666 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2667 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2670 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2671 CloseHandle( token );
2673 if (!ret) return FALSE;
2675 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2677 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2678 CopySid(*cbSid, Sid, pSid);
2679 if (*cbSid < GetLengthSid(pSid))
2681 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2682 ret = FALSE;
2684 *cbSid = GetLengthSid(pSid);
2686 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2687 if (!GetComputerNameW(domainName, &nameLen))
2689 domainName[0] = 0;
2690 nameLen = 0;
2692 if (*cchReferencedDomainName <= nameLen || !ret)
2694 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2695 nameLen += 1;
2696 ret = FALSE;
2698 else if (ReferencedDomainName)
2699 strcpyW(ReferencedDomainName, domainName);
2701 *cchReferencedDomainName = nameLen;
2703 if (ret)
2704 *peUse = SidTypeUser;
2706 return ret;
2709 /******************************************************************************
2710 * lookup_computer_account_name
2712 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2713 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2715 MAX_SID local;
2716 BOOL ret;
2717 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2718 DWORD nameLen;
2720 if ((ret = ADVAPI_GetComputerSid(&local)))
2722 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2723 CopySid(*cbSid, Sid, &local);
2724 if (*cbSid < GetLengthSid(&local))
2726 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2727 ret = FALSE;
2729 *cbSid = GetLengthSid(&local);
2732 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2733 if (!GetComputerNameW(domainName, &nameLen))
2735 domainName[0] = 0;
2736 nameLen = 0;
2738 if (*cchReferencedDomainName <= nameLen || !ret)
2740 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2741 nameLen += 1;
2742 ret = FALSE;
2744 else if (ReferencedDomainName)
2745 strcpyW(ReferencedDomainName, domainName);
2747 *cchReferencedDomainName = nameLen;
2749 if (ret)
2750 *peUse = SidTypeDomain;
2752 return ret;
2755 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2756 LSA_UNICODE_STRING *domain )
2758 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2760 while (p > str->Buffer && *p != '\\') p--;
2762 if (*p == '\\')
2764 domain->Buffer = str->Buffer;
2765 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2767 account->Buffer = p + 1;
2768 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2770 else
2772 domain->Buffer = NULL;
2773 domain->Length = 0;
2775 account->Buffer = str->Buffer;
2776 account->Length = str->Length;
2780 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2782 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2784 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2785 return TRUE;
2787 return FALSE;
2790 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2792 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2794 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2795 return TRUE;
2797 if (ACCOUNT_SIDS[idx].alias)
2799 len = strlenW( ACCOUNT_SIDS[idx].alias );
2800 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2801 return TRUE;
2803 return FALSE;
2807 * Helper function for LookupAccountNameW
2809 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2810 PSID Sid, LPDWORD cbSid,
2811 LPWSTR ReferencedDomainName,
2812 LPDWORD cchReferencedDomainName,
2813 PSID_NAME_USE peUse, BOOL *handled )
2815 PSID pSid;
2816 LSA_UNICODE_STRING account, domain;
2817 BOOL ret = TRUE;
2818 ULONG i;
2820 *handled = FALSE;
2821 split_domain_account( account_and_domain, &account, &domain );
2823 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2825 /* check domain first */
2826 if (domain.Buffer && !match_domain( i, &domain )) continue;
2828 if (match_account( i, &account ))
2830 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2832 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2834 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2836 if (*cbSid < sidLen)
2838 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2839 ret = FALSE;
2841 else if (Sid)
2843 CopySid(*cbSid, Sid, pSid);
2845 *cbSid = sidLen;
2848 len = strlenW( ACCOUNT_SIDS[i].domain );
2849 if (*cchReferencedDomainName <= len || !ret)
2851 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2852 len++;
2853 ret = FALSE;
2855 else if (ReferencedDomainName)
2857 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2860 *cchReferencedDomainName = len;
2861 if (ret)
2862 *peUse = ACCOUNT_SIDS[i].name_use;
2864 HeapFree(GetProcessHeap(), 0, pSid);
2865 *handled = TRUE;
2866 return ret;
2869 return ret;
2872 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2873 PSID Sid, LPDWORD cbSid,
2874 LPWSTR ReferencedDomainName,
2875 LPDWORD cchReferencedDomainName,
2876 PSID_NAME_USE peUse, BOOL *handled )
2878 DWORD nameLen;
2879 LPWSTR userName = NULL;
2880 LSA_UNICODE_STRING account, domain;
2881 BOOL ret = TRUE;
2883 *handled = FALSE;
2884 split_domain_account( account_and_domain, &account, &domain );
2886 /* Let the current Unix user id masquerade as first Windows user account */
2888 nameLen = UNLEN + 1;
2889 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2891 if (domain.Buffer)
2893 /* check to make sure this account is on this computer */
2894 if (GetComputerNameW( userName, &nameLen ) &&
2895 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2897 SetLastError(ERROR_NONE_MAPPED);
2898 ret = FALSE;
2900 nameLen = UNLEN + 1;
2903 if (GetUserNameW( userName, &nameLen ) &&
2904 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2906 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2907 *handled = TRUE;
2909 else
2911 nameLen = UNLEN + 1;
2912 if (GetComputerNameW( userName, &nameLen ) &&
2913 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2915 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2916 *handled = TRUE;
2920 HeapFree(GetProcessHeap(), 0, userName);
2921 return ret;
2924 /******************************************************************************
2925 * LookupAccountNameW [ADVAPI32.@]
2927 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2928 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2929 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2931 BOOL ret, handled;
2932 LSA_UNICODE_STRING account;
2934 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2935 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2937 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2939 FIXME("remote computer not supported\n");
2940 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2941 return FALSE;
2944 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2946 lpAccountName = BUILTIN;
2949 RtlInitUnicodeString( &account, lpAccountName );
2951 /* Check well known SIDs first */
2952 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2953 cchReferencedDomainName, peUse, &handled );
2954 if (handled)
2955 return ret;
2957 /* Check user names */
2958 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2959 cchReferencedDomainName, peUse, &handled);
2960 if (handled)
2961 return ret;
2963 SetLastError( ERROR_NONE_MAPPED );
2964 return FALSE;
2967 /******************************************************************************
2968 * PrivilegeCheck [ADVAPI32.@]
2970 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2972 BOOL ret;
2973 BOOLEAN Result;
2975 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2977 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2978 if (ret)
2979 *pfResult = Result;
2980 return ret;
2983 /******************************************************************************
2984 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2986 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2987 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2988 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2989 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2991 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2992 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2993 SecurityDescriptor, DesiredAccess, GenericMapping,
2994 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2995 return TRUE;
2998 /******************************************************************************
2999 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3001 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3002 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3003 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3004 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3006 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3007 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3008 SecurityDescriptor, DesiredAccess, GenericMapping,
3009 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3010 return TRUE;
3013 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3015 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3017 return TRUE;
3020 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3022 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3024 return TRUE;
3027 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3029 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3031 return TRUE;
3034 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3035 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3036 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3037 LPBOOL GenerateOnClose)
3039 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3040 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3041 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3042 GenerateOnClose);
3044 return TRUE;
3047 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3048 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3049 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3050 LPBOOL GenerateOnClose)
3052 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3053 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3054 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3055 GenerateOnClose);
3057 return TRUE;
3060 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3061 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3063 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3064 DesiredAccess, Privileges, AccessGranted);
3066 return TRUE;
3069 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3070 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3072 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3073 DesiredAccess, Privileges, AccessGranted);
3075 return TRUE;
3078 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3079 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3081 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3082 ClientToken, Privileges, AccessGranted);
3084 return TRUE;
3087 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3088 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3090 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3091 ClientToken, Privileges, AccessGranted);
3093 return TRUE;
3096 /******************************************************************************
3097 * GetSecurityInfo [ADVAPI32.@]
3099 * Retrieves a copy of the security descriptor associated with an object.
3101 * PARAMS
3102 * hObject [I] A handle for the object.
3103 * ObjectType [I] The type of object.
3104 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3105 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3106 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3107 * ppDacl [O] If non-null, receives a pointer to the DACL.
3108 * ppSacl [O] If non-null, receives a pointer to the SACL.
3109 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3110 * which must be freed with LocalFree.
3112 * RETURNS
3113 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3115 DWORD WINAPI GetSecurityInfo(
3116 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3117 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3118 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3119 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3122 PSECURITY_DESCRIPTOR sd;
3123 NTSTATUS status;
3124 ULONG n1, n2;
3125 BOOL present, defaulted;
3127 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3128 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3130 /* If no descriptor, we have to check that there's a pointer for the requested information */
3131 if( !ppSecurityDescriptor && (
3132 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3133 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3134 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3135 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3136 return ERROR_INVALID_PARAMETER;
3138 switch (ObjectType)
3140 case SE_SERVICE:
3141 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3142 break;
3143 default:
3144 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3145 break;
3147 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3148 return RtlNtStatusToDosError(status);
3150 sd = LocalAlloc(0, n1);
3151 if (!sd)
3152 return ERROR_NOT_ENOUGH_MEMORY;
3154 switch (ObjectType)
3156 case SE_SERVICE:
3157 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3158 break;
3159 default:
3160 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3161 break;
3163 if (status != STATUS_SUCCESS)
3165 LocalFree(sd);
3166 return RtlNtStatusToDosError(status);
3169 if (ppsidOwner)
3171 *ppsidOwner = NULL;
3172 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3174 if (ppsidGroup)
3176 *ppsidGroup = NULL;
3177 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3179 if (ppDacl)
3181 *ppDacl = NULL;
3182 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3184 if (ppSacl)
3186 *ppSacl = NULL;
3187 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3189 if (ppSecurityDescriptor)
3190 *ppSecurityDescriptor = sd;
3192 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3193 * NULL, because native happily returns the SIDs and ACLs that are requested
3194 * in this case.
3197 return ERROR_SUCCESS;
3200 /******************************************************************************
3201 * GetSecurityInfoExA [ADVAPI32.@]
3203 DWORD WINAPI GetSecurityInfoExA(
3204 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3205 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3206 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3207 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3210 FIXME("stub!\n");
3211 return ERROR_BAD_PROVIDER;
3214 /******************************************************************************
3215 * GetSecurityInfoExW [ADVAPI32.@]
3217 DWORD WINAPI GetSecurityInfoExW(
3218 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3219 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3220 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3221 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3224 FIXME("stub!\n");
3225 return ERROR_BAD_PROVIDER;
3228 /******************************************************************************
3229 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3231 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3232 LPSTR pTrusteeName, DWORD AccessPermissions,
3233 ACCESS_MODE AccessMode, DWORD Inheritance )
3235 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3236 AccessPermissions, AccessMode, Inheritance);
3238 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3239 pExplicitAccess->grfAccessMode = AccessMode;
3240 pExplicitAccess->grfInheritance = Inheritance;
3242 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3243 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3244 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3245 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3246 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3249 /******************************************************************************
3250 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3252 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3253 LPWSTR pTrusteeName, DWORD AccessPermissions,
3254 ACCESS_MODE AccessMode, DWORD Inheritance )
3256 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3257 AccessPermissions, AccessMode, Inheritance);
3259 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3260 pExplicitAccess->grfAccessMode = AccessMode;
3261 pExplicitAccess->grfInheritance = Inheritance;
3263 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3264 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3265 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3266 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3267 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3270 /******************************************************************************
3271 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3273 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3274 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3275 LPSTR InheritedObjectTypeName, LPSTR Name )
3277 DWORD ObjectsPresent = 0;
3279 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3280 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3282 /* Fill the OBJECTS_AND_NAME structure */
3283 pObjName->ObjectType = ObjectType;
3284 if (ObjectTypeName != NULL)
3286 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3289 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3290 if (InheritedObjectTypeName != NULL)
3292 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3295 pObjName->ObjectsPresent = ObjectsPresent;
3296 pObjName->ptstrName = Name;
3298 /* Fill the TRUSTEE structure */
3299 pTrustee->pMultipleTrustee = NULL;
3300 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3301 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3302 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3303 pTrustee->ptstrName = (LPSTR)pObjName;
3306 /******************************************************************************
3307 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3309 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3310 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3311 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3313 DWORD ObjectsPresent = 0;
3315 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3316 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3318 /* Fill the OBJECTS_AND_NAME structure */
3319 pObjName->ObjectType = ObjectType;
3320 if (ObjectTypeName != NULL)
3322 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3325 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3326 if (InheritedObjectTypeName != NULL)
3328 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3331 pObjName->ObjectsPresent = ObjectsPresent;
3332 pObjName->ptstrName = Name;
3334 /* Fill the TRUSTEE structure */
3335 pTrustee->pMultipleTrustee = NULL;
3336 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3337 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3338 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3339 pTrustee->ptstrName = (LPWSTR)pObjName;
3342 /******************************************************************************
3343 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3345 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3346 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3348 DWORD ObjectsPresent = 0;
3350 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3352 /* Fill the OBJECTS_AND_SID structure */
3353 if (pObjectGuid != NULL)
3355 pObjSid->ObjectTypeGuid = *pObjectGuid;
3356 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3358 else
3360 ZeroMemory(&pObjSid->ObjectTypeGuid,
3361 sizeof(GUID));
3364 if (pInheritedObjectGuid != NULL)
3366 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3367 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3369 else
3371 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3372 sizeof(GUID));
3375 pObjSid->ObjectsPresent = ObjectsPresent;
3376 pObjSid->pSid = pSid;
3378 /* Fill the TRUSTEE structure */
3379 pTrustee->pMultipleTrustee = NULL;
3380 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3381 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3382 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3383 pTrustee->ptstrName = (LPSTR) pObjSid;
3386 /******************************************************************************
3387 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3389 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3390 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3392 DWORD ObjectsPresent = 0;
3394 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3396 /* Fill the OBJECTS_AND_SID structure */
3397 if (pObjectGuid != NULL)
3399 pObjSid->ObjectTypeGuid = *pObjectGuid;
3400 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3402 else
3404 ZeroMemory(&pObjSid->ObjectTypeGuid,
3405 sizeof(GUID));
3408 if (pInheritedObjectGuid != NULL)
3410 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3411 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3413 else
3415 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3416 sizeof(GUID));
3419 pObjSid->ObjectsPresent = ObjectsPresent;
3420 pObjSid->pSid = pSid;
3422 /* Fill the TRUSTEE structure */
3423 pTrustee->pMultipleTrustee = NULL;
3424 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3425 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3426 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3427 pTrustee->ptstrName = (LPWSTR) pObjSid;
3430 /******************************************************************************
3431 * BuildTrusteeWithSidA [ADVAPI32.@]
3433 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3435 TRACE("%p %p\n", pTrustee, pSid);
3437 pTrustee->pMultipleTrustee = NULL;
3438 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3439 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3440 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3441 pTrustee->ptstrName = pSid;
3444 /******************************************************************************
3445 * BuildTrusteeWithSidW [ADVAPI32.@]
3447 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3449 TRACE("%p %p\n", pTrustee, pSid);
3451 pTrustee->pMultipleTrustee = NULL;
3452 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3453 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3454 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3455 pTrustee->ptstrName = pSid;
3458 /******************************************************************************
3459 * BuildTrusteeWithNameA [ADVAPI32.@]
3461 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3463 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3465 pTrustee->pMultipleTrustee = NULL;
3466 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3467 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3468 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3469 pTrustee->ptstrName = name;
3472 /******************************************************************************
3473 * BuildTrusteeWithNameW [ADVAPI32.@]
3475 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3477 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3479 pTrustee->pMultipleTrustee = NULL;
3480 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3481 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3482 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3483 pTrustee->ptstrName = name;
3486 /******************************************************************************
3487 * GetTrusteeFormA [ADVAPI32.@]
3489 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3491 TRACE("(%p)\n", pTrustee);
3493 if (!pTrustee)
3494 return TRUSTEE_BAD_FORM;
3496 return pTrustee->TrusteeForm;
3499 /******************************************************************************
3500 * GetTrusteeFormW [ADVAPI32.@]
3502 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3504 TRACE("(%p)\n", pTrustee);
3506 if (!pTrustee)
3507 return TRUSTEE_BAD_FORM;
3509 return pTrustee->TrusteeForm;
3512 /******************************************************************************
3513 * GetTrusteeNameA [ADVAPI32.@]
3515 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3517 TRACE("(%p)\n", pTrustee);
3519 if (!pTrustee)
3520 return NULL;
3522 return pTrustee->ptstrName;
3525 /******************************************************************************
3526 * GetTrusteeNameW [ADVAPI32.@]
3528 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3530 TRACE("(%p)\n", pTrustee);
3532 if (!pTrustee)
3533 return NULL;
3535 return pTrustee->ptstrName;
3538 /******************************************************************************
3539 * GetTrusteeTypeA [ADVAPI32.@]
3541 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3543 TRACE("(%p)\n", pTrustee);
3545 if (!pTrustee)
3546 return TRUSTEE_IS_UNKNOWN;
3548 return pTrustee->TrusteeType;
3551 /******************************************************************************
3552 * GetTrusteeTypeW [ADVAPI32.@]
3554 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3556 TRACE("(%p)\n", pTrustee);
3558 if (!pTrustee)
3559 return TRUSTEE_IS_UNKNOWN;
3561 return pTrustee->TrusteeType;
3564 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3565 DWORD nAclInformationLength,
3566 ACL_INFORMATION_CLASS dwAclInformationClass )
3568 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3569 nAclInformationLength, dwAclInformationClass);
3571 return TRUE;
3574 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3576 switch (form)
3578 case TRUSTEE_IS_NAME:
3580 *ptrustee_nameW = SERV_dup(trustee_nameA);
3581 return ERROR_SUCCESS;
3583 case TRUSTEE_IS_OBJECTS_AND_NAME:
3585 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3586 OBJECTS_AND_NAME_W *objW = NULL;
3588 if (objA)
3590 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3591 return ERROR_NOT_ENOUGH_MEMORY;
3593 objW->ObjectsPresent = objA->ObjectsPresent;
3594 objW->ObjectType = objA->ObjectType;
3595 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3596 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3597 objW->ptstrName = SERV_dup(objA->ptstrName);
3600 *ptrustee_nameW = (WCHAR *)objW;
3601 return ERROR_SUCCESS;
3603 /* These forms do not require conversion. */
3604 case TRUSTEE_IS_SID:
3605 case TRUSTEE_IS_OBJECTS_AND_SID:
3606 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3607 return ERROR_SUCCESS;
3608 default:
3609 return ERROR_INVALID_PARAMETER;
3613 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3615 switch (form)
3617 case TRUSTEE_IS_NAME:
3618 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3619 break;
3620 case TRUSTEE_IS_OBJECTS_AND_NAME:
3622 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3624 if (objW)
3626 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3627 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3628 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3629 HeapFree( GetProcessHeap(), 0, objW );
3632 break;
3634 /* Other forms did not require allocation, so no freeing is necessary. */
3635 default:
3636 break;
3640 /******************************************************************************
3641 * SetEntriesInAclA [ADVAPI32.@]
3643 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3644 PACL OldAcl, PACL* NewAcl )
3646 DWORD err = ERROR_SUCCESS;
3647 EXPLICIT_ACCESSW *pEntriesW;
3648 UINT alloc_index, free_index;
3650 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3652 if (NewAcl)
3653 *NewAcl = NULL;
3655 if (!count && !OldAcl)
3656 return ERROR_SUCCESS;
3658 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3659 if (!pEntriesW)
3660 return ERROR_NOT_ENOUGH_MEMORY;
3662 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3664 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3665 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3666 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3667 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3668 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3669 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3670 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3672 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3673 pEntries[alloc_index].Trustee.ptstrName,
3674 &pEntriesW[alloc_index].Trustee.ptstrName );
3675 if (err != ERROR_SUCCESS)
3677 if (err == ERROR_INVALID_PARAMETER)
3678 WARN("bad trustee form %d for trustee %d\n",
3679 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3681 goto cleanup;
3685 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3687 cleanup:
3688 /* Free any previously allocated trustee name buffers, taking into account
3689 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3690 * list. */
3691 for (free_index = 0; free_index < alloc_index; ++free_index)
3692 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3694 HeapFree( GetProcessHeap(), 0, pEntriesW );
3695 return err;
3698 /******************************************************************************
3699 * SetEntriesInAclW [ADVAPI32.@]
3701 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3702 PACL OldAcl, PACL* NewAcl )
3704 ULONG i;
3705 PSID *ppsid;
3706 DWORD ret = ERROR_SUCCESS;
3707 DWORD acl_size = sizeof(ACL);
3708 NTSTATUS status;
3710 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3712 if (NewAcl)
3713 *NewAcl = NULL;
3715 if (!count && !OldAcl)
3716 return ERROR_SUCCESS;
3718 /* allocate array of maximum sized sids allowed */
3719 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3720 if (!ppsid)
3721 return ERROR_OUTOFMEMORY;
3723 for (i = 0; i < count; i++)
3725 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3727 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3728 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3729 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3730 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3731 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3732 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3733 pEntries[i].Trustee.ptstrName);
3735 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3737 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3738 ret = ERROR_INVALID_PARAMETER;
3739 goto exit;
3742 switch (pEntries[i].Trustee.TrusteeForm)
3744 case TRUSTEE_IS_SID:
3745 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3746 ppsid[i], pEntries[i].Trustee.ptstrName))
3748 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3749 ret = ERROR_INVALID_PARAMETER;
3750 goto exit;
3752 break;
3753 case TRUSTEE_IS_NAME:
3755 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3756 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3757 SID_NAME_USE use;
3758 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3760 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3762 ret = GetLastError();
3763 goto exit;
3766 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3768 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3769 ret = ERROR_INVALID_PARAMETER;
3770 goto exit;
3772 break;
3774 case TRUSTEE_IS_OBJECTS_AND_SID:
3775 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3776 break;
3777 case TRUSTEE_IS_OBJECTS_AND_NAME:
3778 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3779 break;
3780 default:
3781 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3782 ret = ERROR_INVALID_PARAMETER;
3783 goto exit;
3786 /* Note: we overestimate the ACL size here as a tradeoff between
3787 * instructions (simplicity) and memory */
3788 switch (pEntries[i].grfAccessMode)
3790 case GRANT_ACCESS:
3791 case SET_ACCESS:
3792 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3793 break;
3794 case DENY_ACCESS:
3795 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3796 break;
3797 case SET_AUDIT_SUCCESS:
3798 case SET_AUDIT_FAILURE:
3799 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3800 break;
3801 case REVOKE_ACCESS:
3802 break;
3803 default:
3804 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3805 ret = ERROR_INVALID_PARAMETER;
3806 goto exit;
3810 if (OldAcl)
3812 ACL_SIZE_INFORMATION size_info;
3814 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3815 if (status != STATUS_SUCCESS)
3817 ret = RtlNtStatusToDosError(status);
3818 goto exit;
3820 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3823 *NewAcl = LocalAlloc(0, acl_size);
3824 if (!*NewAcl)
3826 ret = ERROR_OUTOFMEMORY;
3827 goto exit;
3830 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3831 if (status != STATUS_SUCCESS)
3833 ret = RtlNtStatusToDosError(status);
3834 goto exit;
3837 for (i = 0; i < count; i++)
3839 switch (pEntries[i].grfAccessMode)
3841 case GRANT_ACCESS:
3842 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3843 pEntries[i].grfInheritance,
3844 pEntries[i].grfAccessPermissions,
3845 ppsid[i]);
3846 break;
3847 case SET_ACCESS:
3849 ULONG j;
3850 BOOL add = TRUE;
3851 if (OldAcl)
3853 for (j = 0; ; j++)
3855 const ACE_HEADER *existing_ace_header;
3856 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3857 if (status != STATUS_SUCCESS)
3858 break;
3859 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3860 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3861 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3863 add = FALSE;
3864 break;
3868 if (add)
3869 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3870 pEntries[i].grfInheritance,
3871 pEntries[i].grfAccessPermissions,
3872 ppsid[i]);
3873 break;
3875 case DENY_ACCESS:
3876 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3877 pEntries[i].grfInheritance,
3878 pEntries[i].grfAccessPermissions,
3879 ppsid[i]);
3880 break;
3881 case SET_AUDIT_SUCCESS:
3882 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3883 pEntries[i].grfInheritance,
3884 pEntries[i].grfAccessPermissions,
3885 ppsid[i], TRUE, FALSE);
3886 break;
3887 case SET_AUDIT_FAILURE:
3888 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3889 pEntries[i].grfInheritance,
3890 pEntries[i].grfAccessPermissions,
3891 ppsid[i], FALSE, TRUE);
3892 break;
3893 default:
3894 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3898 if (OldAcl)
3900 for (i = 0; ; i++)
3902 BOOL add = TRUE;
3903 ULONG j;
3904 const ACE_HEADER *old_ace_header;
3905 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3906 if (status != STATUS_SUCCESS) break;
3907 for (j = 0; j < count; j++)
3909 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3910 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3911 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3913 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3914 add = FALSE;
3915 break;
3917 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3919 switch (old_ace_header->AceType)
3921 case ACCESS_ALLOWED_ACE_TYPE:
3922 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3923 add = FALSE;
3924 break;
3925 case ACCESS_DENIED_ACE_TYPE:
3926 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3927 add = FALSE;
3928 break;
3929 case SYSTEM_AUDIT_ACE_TYPE:
3930 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3931 add = FALSE;
3932 break;
3933 case SYSTEM_ALARM_ACE_TYPE:
3934 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3935 add = FALSE;
3936 break;
3937 default:
3938 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3941 if (!add)
3942 break;
3945 if (add)
3946 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3947 if (status != STATUS_SUCCESS)
3949 WARN("RtlAddAce failed with error 0x%08x\n", status);
3950 ret = RtlNtStatusToDosError(status);
3951 break;
3956 exit:
3957 HeapFree(GetProcessHeap(), 0, ppsid);
3958 return ret;
3961 /******************************************************************************
3962 * SetNamedSecurityInfoA [ADVAPI32.@]
3964 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3965 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3966 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3968 LPWSTR wstr;
3969 DWORD r;
3971 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3972 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3974 wstr = SERV_dup(pObjectName);
3975 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3976 psidGroup, pDacl, pSacl );
3978 HeapFree( GetProcessHeap(), 0, wstr );
3980 return r;
3983 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3984 PSECURITY_DESCRIPTOR ModificationDescriptor,
3985 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3986 PGENERIC_MAPPING GenericMapping,
3987 HANDLE Token )
3989 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3990 ObjectsSecurityDescriptor, GenericMapping, Token);
3992 return TRUE;
3995 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3997 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4000 /******************************************************************************
4001 * AreAnyAccessesGranted [ADVAPI32.@]
4003 * Determines whether or not any of a set of specified access permissions have
4004 * been granted or not.
4006 * PARAMS
4007 * GrantedAccess [I] The permissions that have been granted.
4008 * DesiredAccess [I] The permissions that you want to have.
4010 * RETURNS
4011 * Nonzero if any of the permissions have been granted, zero if none of the
4012 * permissions have been granted.
4015 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4017 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4020 /******************************************************************************
4021 * SetNamedSecurityInfoW [ADVAPI32.@]
4023 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4024 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4025 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4027 DWORD access = 0;
4028 HANDLE handle;
4029 DWORD err;
4031 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4032 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4034 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4036 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4037 access |= WRITE_OWNER;
4038 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4039 access |= WRITE_DAC;
4040 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4041 access |= ACCESS_SYSTEM_SECURITY;
4043 switch (ObjectType)
4045 case SE_SERVICE:
4046 if (!(err = get_security_service( pObjectName, access, &handle )))
4048 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4049 CloseServiceHandle( handle );
4051 break;
4052 case SE_REGISTRY_KEY:
4053 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4055 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4056 RegCloseKey( handle );
4058 break;
4059 case SE_FILE_OBJECT:
4060 if (!(err = get_security_file( pObjectName, access, &handle )))
4062 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4063 CloseHandle( handle );
4065 break;
4066 default:
4067 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4068 return ERROR_SUCCESS;
4070 return err;
4073 /******************************************************************************
4074 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4076 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4077 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4079 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4080 return ERROR_CALL_NOT_IMPLEMENTED;
4083 /******************************************************************************
4084 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4086 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4087 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4089 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4090 return ERROR_CALL_NOT_IMPLEMENTED;
4093 /******************************************************************************
4094 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4096 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4097 PACCESS_MASK pFailedAuditRights)
4099 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4100 return ERROR_CALL_NOT_IMPLEMENTED;
4104 /******************************************************************************
4105 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4107 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4108 PACCESS_MASK pFailedAuditRights)
4110 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4111 return ERROR_CALL_NOT_IMPLEMENTED;
4115 /******************************************************************************
4116 * ParseAclStringFlags
4118 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4120 DWORD flags = 0;
4121 LPCWSTR szAcl = *StringAcl;
4123 while (*szAcl != '(')
4125 if (*szAcl == 'P')
4127 flags |= SE_DACL_PROTECTED;
4129 else if (*szAcl == 'A')
4131 szAcl++;
4132 if (*szAcl == 'R')
4133 flags |= SE_DACL_AUTO_INHERIT_REQ;
4134 else if (*szAcl == 'I')
4135 flags |= SE_DACL_AUTO_INHERITED;
4137 szAcl++;
4140 *StringAcl = szAcl;
4141 return flags;
4144 /******************************************************************************
4145 * ParseAceStringType
4147 static const ACEFLAG AceType[] =
4149 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4150 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4151 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4152 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4154 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4155 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4156 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4157 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4159 { NULL, 0 },
4162 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4164 UINT len = 0;
4165 LPCWSTR szAcl = *StringAcl;
4166 const ACEFLAG *lpaf = AceType;
4168 while (*szAcl == ' ')
4169 szAcl++;
4171 while (lpaf->wstr &&
4172 (len = strlenW(lpaf->wstr)) &&
4173 strncmpW(lpaf->wstr, szAcl, len))
4174 lpaf++;
4176 if (!lpaf->wstr)
4177 return 0;
4179 *StringAcl = szAcl + len;
4180 return lpaf->value;
4184 /******************************************************************************
4185 * ParseAceStringFlags
4187 static const ACEFLAG AceFlags[] =
4189 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4190 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4191 { SDDL_INHERITED, INHERITED_ACE },
4192 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4193 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4194 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4195 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4196 { NULL, 0 },
4199 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4201 UINT len = 0;
4202 BYTE flags = 0;
4203 LPCWSTR szAcl = *StringAcl;
4205 while (*szAcl == ' ')
4206 szAcl++;
4208 while (*szAcl != ';')
4210 const ACEFLAG *lpaf = AceFlags;
4212 while (lpaf->wstr &&
4213 (len = strlenW(lpaf->wstr)) &&
4214 strncmpW(lpaf->wstr, szAcl, len))
4215 lpaf++;
4217 if (!lpaf->wstr)
4218 return 0;
4220 flags |= lpaf->value;
4221 szAcl += len;
4224 *StringAcl = szAcl;
4225 return flags;
4229 /******************************************************************************
4230 * ParseAceStringRights
4232 static const ACEFLAG AceRights[] =
4234 { SDDL_GENERIC_ALL, GENERIC_ALL },
4235 { SDDL_GENERIC_READ, GENERIC_READ },
4236 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4237 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4239 { SDDL_READ_CONTROL, READ_CONTROL },
4240 { SDDL_STANDARD_DELETE, DELETE },
4241 { SDDL_WRITE_DAC, WRITE_DAC },
4242 { SDDL_WRITE_OWNER, WRITE_OWNER },
4244 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4245 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4246 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4247 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4248 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4249 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4250 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4251 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4252 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4254 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4255 { SDDL_FILE_READ, FILE_GENERIC_READ },
4256 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4257 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4259 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4260 { SDDL_KEY_READ, KEY_READ },
4261 { SDDL_KEY_WRITE, KEY_WRITE },
4262 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4263 { NULL, 0 },
4266 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4268 UINT len = 0;
4269 DWORD rights = 0;
4270 LPCWSTR szAcl = *StringAcl;
4272 while (*szAcl == ' ')
4273 szAcl++;
4275 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4277 LPCWSTR p = szAcl;
4279 while (*p && *p != ';')
4280 p++;
4282 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4284 rights = strtoulW(szAcl, NULL, 16);
4285 szAcl = p;
4287 else
4288 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4290 else
4292 while (*szAcl != ';')
4294 const ACEFLAG *lpaf = AceRights;
4296 while (lpaf->wstr &&
4297 (len = strlenW(lpaf->wstr)) &&
4298 strncmpW(lpaf->wstr, szAcl, len))
4300 lpaf++;
4303 if (!lpaf->wstr)
4304 return 0;
4306 rights |= lpaf->value;
4307 szAcl += len;
4311 *StringAcl = szAcl;
4312 return rights;
4316 /******************************************************************************
4317 * ParseStringAclToAcl
4319 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4321 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4322 PACL pAcl, LPDWORD cBytes)
4324 DWORD val;
4325 DWORD sidlen;
4326 DWORD length = sizeof(ACL);
4327 DWORD acesize = 0;
4328 DWORD acecount = 0;
4329 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4330 DWORD error = ERROR_INVALID_ACL;
4332 TRACE("%s\n", debugstr_w(StringAcl));
4334 if (!StringAcl)
4335 return FALSE;
4337 if (pAcl) /* pAce is only useful if we're setting values */
4338 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4340 /* Parse ACL flags */
4341 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4343 /* Parse ACE */
4344 while (*StringAcl == '(')
4346 StringAcl++;
4348 /* Parse ACE type */
4349 val = ParseAceStringType(&StringAcl);
4350 if (pAce)
4351 pAce->Header.AceType = (BYTE) val;
4352 if (*StringAcl != ';')
4354 error = RPC_S_INVALID_STRING_UUID;
4355 goto lerr;
4357 StringAcl++;
4359 /* Parse ACE flags */
4360 val = ParseAceStringFlags(&StringAcl);
4361 if (pAce)
4362 pAce->Header.AceFlags = (BYTE) val;
4363 if (*StringAcl != ';')
4364 goto lerr;
4365 StringAcl++;
4367 /* Parse ACE rights */
4368 val = ParseAceStringRights(&StringAcl);
4369 if (pAce)
4370 pAce->Mask = val;
4371 if (*StringAcl != ';')
4372 goto lerr;
4373 StringAcl++;
4375 /* Parse ACE object guid */
4376 while (*StringAcl == ' ')
4377 StringAcl++;
4378 if (*StringAcl != ';')
4380 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4381 goto lerr;
4383 StringAcl++;
4385 /* Parse ACE inherit object guid */
4386 while (*StringAcl == ' ')
4387 StringAcl++;
4388 if (*StringAcl != ';')
4390 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4391 goto lerr;
4393 StringAcl++;
4395 /* Parse ACE account sid */
4396 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4398 while (*StringAcl && *StringAcl != ')')
4399 StringAcl++;
4402 if (*StringAcl != ')')
4403 goto lerr;
4404 StringAcl++;
4406 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4407 length += acesize;
4408 if (pAce)
4410 pAce->Header.AceSize = acesize;
4411 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4413 acecount++;
4416 *cBytes = length;
4418 if (length > 0xffff)
4420 ERR("ACL too large\n");
4421 goto lerr;
4424 if (pAcl)
4426 pAcl->AclRevision = ACL_REVISION;
4427 pAcl->Sbz1 = 0;
4428 pAcl->AclSize = length;
4429 pAcl->AceCount = acecount++;
4430 pAcl->Sbz2 = 0;
4432 return TRUE;
4434 lerr:
4435 SetLastError(error);
4436 WARN("Invalid ACE string format\n");
4437 return FALSE;
4441 /******************************************************************************
4442 * ParseStringSecurityDescriptorToSecurityDescriptor
4444 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4445 LPCWSTR StringSecurityDescriptor,
4446 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4447 LPDWORD cBytes)
4449 BOOL bret = FALSE;
4450 WCHAR toktype;
4451 WCHAR tok[MAX_PATH];
4452 LPCWSTR lptoken;
4453 LPBYTE lpNext = NULL;
4454 DWORD len;
4456 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4458 if (SecurityDescriptor)
4459 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4461 while (*StringSecurityDescriptor == ' ')
4462 StringSecurityDescriptor++;
4464 while (*StringSecurityDescriptor)
4466 toktype = *StringSecurityDescriptor;
4468 /* Expect char identifier followed by ':' */
4469 StringSecurityDescriptor++;
4470 if (*StringSecurityDescriptor != ':')
4472 SetLastError(ERROR_INVALID_PARAMETER);
4473 goto lend;
4475 StringSecurityDescriptor++;
4477 /* Extract token */
4478 lptoken = StringSecurityDescriptor;
4479 while (*lptoken && *lptoken != ':')
4480 lptoken++;
4482 if (*lptoken)
4483 lptoken--;
4485 len = lptoken - StringSecurityDescriptor;
4486 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4487 tok[len] = 0;
4489 switch (toktype)
4491 case 'O':
4493 DWORD bytes;
4495 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4496 goto lend;
4498 if (SecurityDescriptor)
4500 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4501 lpNext += bytes; /* Advance to next token */
4504 *cBytes += bytes;
4506 break;
4509 case 'G':
4511 DWORD bytes;
4513 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4514 goto lend;
4516 if (SecurityDescriptor)
4518 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4519 lpNext += bytes; /* Advance to next token */
4522 *cBytes += bytes;
4524 break;
4527 case 'D':
4529 DWORD flags;
4530 DWORD bytes;
4532 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4533 goto lend;
4535 if (SecurityDescriptor)
4537 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4538 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4539 lpNext += bytes; /* Advance to next token */
4542 *cBytes += bytes;
4544 break;
4547 case 'S':
4549 DWORD flags;
4550 DWORD bytes;
4552 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4553 goto lend;
4555 if (SecurityDescriptor)
4557 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4558 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4559 lpNext += bytes; /* Advance to next token */
4562 *cBytes += bytes;
4564 break;
4567 default:
4568 FIXME("Unknown token\n");
4569 SetLastError(ERROR_INVALID_PARAMETER);
4570 goto lend;
4573 StringSecurityDescriptor = lptoken;
4576 bret = TRUE;
4578 lend:
4579 return bret;
4582 /******************************************************************************
4583 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4585 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4586 LPCSTR StringSecurityDescriptor,
4587 DWORD StringSDRevision,
4588 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4589 PULONG SecurityDescriptorSize)
4591 BOOL ret;
4592 LPWSTR StringSecurityDescriptorW;
4594 if(!StringSecurityDescriptor)
4595 return FALSE;
4597 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4598 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4599 StringSDRevision, SecurityDescriptor,
4600 SecurityDescriptorSize);
4601 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4603 return ret;
4606 /******************************************************************************
4607 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4609 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4610 LPCWSTR StringSecurityDescriptor,
4611 DWORD StringSDRevision,
4612 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4613 PULONG SecurityDescriptorSize)
4615 DWORD cBytes;
4616 SECURITY_DESCRIPTOR* psd;
4617 BOOL bret = FALSE;
4619 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4621 if (GetVersion() & 0x80000000)
4623 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4624 goto lend;
4626 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4628 SetLastError(ERROR_INVALID_PARAMETER);
4629 goto lend;
4631 else if (StringSDRevision != SID_REVISION)
4633 SetLastError(ERROR_UNKNOWN_REVISION);
4634 goto lend;
4637 /* Compute security descriptor length */
4638 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4639 NULL, &cBytes))
4640 goto lend;
4642 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4643 if (!psd) goto lend;
4645 psd->Revision = SID_REVISION;
4646 psd->Control |= SE_SELF_RELATIVE;
4648 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4649 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4651 LocalFree(psd);
4652 goto lend;
4655 if (SecurityDescriptorSize)
4656 *SecurityDescriptorSize = cBytes;
4658 bret = TRUE;
4660 lend:
4661 TRACE(" ret=%d\n", bret);
4662 return bret;
4665 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4667 if (cch == -1)
4668 cch = strlenW(string);
4670 if (plen)
4671 *plen += cch;
4673 if (pwptr)
4675 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4676 *pwptr += cch;
4680 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4682 DWORD i;
4683 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4684 WCHAR subauthfmt[] = { '-','%','u',0 };
4685 WCHAR buf[26];
4686 SID *pisid = psid;
4688 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4690 SetLastError(ERROR_INVALID_SID);
4691 return FALSE;
4694 if (pisid->IdentifierAuthority.Value[0] ||
4695 pisid->IdentifierAuthority.Value[1])
4697 FIXME("not matching MS' bugs\n");
4698 SetLastError(ERROR_INVALID_SID);
4699 return FALSE;
4702 sprintfW( buf, fmt, pisid->Revision,
4703 MAKELONG(
4704 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4705 pisid->IdentifierAuthority.Value[4] ),
4706 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4707 pisid->IdentifierAuthority.Value[2] )
4708 ) );
4709 DumpString(buf, -1, pwptr, plen);
4711 for( i=0; i<pisid->SubAuthorityCount; i++ )
4713 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4714 DumpString(buf, -1, pwptr, plen);
4716 return TRUE;
4719 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4721 size_t i;
4722 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4724 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4726 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4727 return TRUE;
4731 return DumpSidNumeric(psid, pwptr, plen);
4734 static const LPCWSTR AceRightBitNames[32] = {
4735 SDDL_CREATE_CHILD, /* 0 */
4736 SDDL_DELETE_CHILD,
4737 SDDL_LIST_CHILDREN,
4738 SDDL_SELF_WRITE,
4739 SDDL_READ_PROPERTY, /* 4 */
4740 SDDL_WRITE_PROPERTY,
4741 SDDL_DELETE_TREE,
4742 SDDL_LIST_OBJECT,
4743 SDDL_CONTROL_ACCESS, /* 8 */
4744 NULL,
4745 NULL,
4746 NULL,
4747 NULL, /* 12 */
4748 NULL,
4749 NULL,
4750 NULL,
4751 SDDL_STANDARD_DELETE, /* 16 */
4752 SDDL_READ_CONTROL,
4753 SDDL_WRITE_DAC,
4754 SDDL_WRITE_OWNER,
4755 NULL, /* 20 */
4756 NULL,
4757 NULL,
4758 NULL,
4759 NULL, /* 24 */
4760 NULL,
4761 NULL,
4762 NULL,
4763 SDDL_GENERIC_ALL, /* 28 */
4764 SDDL_GENERIC_EXECUTE,
4765 SDDL_GENERIC_WRITE,
4766 SDDL_GENERIC_READ
4769 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4771 static const WCHAR fmtW[] = {'0','x','%','x',0};
4772 WCHAR buf[15];
4773 size_t i;
4775 if (mask == 0)
4776 return;
4778 /* first check if the right have name */
4779 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4781 if (AceRights[i].wstr == NULL)
4782 break;
4783 if (mask == AceRights[i].value)
4785 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4786 return;
4790 /* then check if it can be built from bit names */
4791 for (i = 0; i < 32; i++)
4793 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4795 /* can't be built from bit names */
4796 sprintfW(buf, fmtW, mask);
4797 DumpString(buf, -1, pwptr, plen);
4798 return;
4802 /* build from bit names */
4803 for (i = 0; i < 32; i++)
4804 if (mask & (1 << i))
4805 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4808 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4810 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4811 static const WCHAR openbr = '(';
4812 static const WCHAR closebr = ')';
4813 static const WCHAR semicolon = ';';
4815 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4817 SetLastError(ERROR_INVALID_ACL);
4818 return FALSE;
4821 piace = pace;
4822 DumpString(&openbr, 1, pwptr, plen);
4823 switch (piace->Header.AceType)
4825 case ACCESS_ALLOWED_ACE_TYPE:
4826 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4827 break;
4828 case ACCESS_DENIED_ACE_TYPE:
4829 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4830 break;
4831 case SYSTEM_AUDIT_ACE_TYPE:
4832 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4833 break;
4834 case SYSTEM_ALARM_ACE_TYPE:
4835 DumpString(SDDL_ALARM, -1, pwptr, plen);
4836 break;
4838 DumpString(&semicolon, 1, pwptr, plen);
4840 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4841 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4842 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4843 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4844 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4845 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4846 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4847 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4848 if (piace->Header.AceFlags & INHERITED_ACE)
4849 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4850 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4851 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4852 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4853 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4854 DumpString(&semicolon, 1, pwptr, plen);
4855 DumpRights(piace->Mask, pwptr, plen);
4856 DumpString(&semicolon, 1, pwptr, plen);
4857 /* objects not supported */
4858 DumpString(&semicolon, 1, pwptr, plen);
4859 /* objects not supported */
4860 DumpString(&semicolon, 1, pwptr, plen);
4861 if (!DumpSid(&piace->SidStart, pwptr, plen))
4862 return FALSE;
4863 DumpString(&closebr, 1, pwptr, plen);
4864 return TRUE;
4867 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4869 WORD count;
4870 UINT i;
4872 if (protected)
4873 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4874 if (autoInheritReq)
4875 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4876 if (autoInherited)
4877 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4879 if (pacl == NULL)
4880 return TRUE;
4882 if (!IsValidAcl(pacl))
4883 return FALSE;
4885 count = pacl->AceCount;
4886 for (i = 0; i < count; i++)
4888 LPVOID ace;
4889 if (!GetAce(pacl, i, &ace))
4890 return FALSE;
4891 if (!DumpAce(ace, pwptr, plen))
4892 return FALSE;
4895 return TRUE;
4898 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4900 static const WCHAR prefix[] = {'O',':',0};
4901 BOOL bDefaulted;
4902 PSID psid;
4904 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4905 return FALSE;
4907 if (psid == NULL)
4908 return TRUE;
4910 DumpString(prefix, -1, pwptr, plen);
4911 if (!DumpSid(psid, pwptr, plen))
4912 return FALSE;
4913 return TRUE;
4916 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4918 static const WCHAR prefix[] = {'G',':',0};
4919 BOOL bDefaulted;
4920 PSID psid;
4922 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4923 return FALSE;
4925 if (psid == NULL)
4926 return TRUE;
4928 DumpString(prefix, -1, pwptr, plen);
4929 if (!DumpSid(psid, pwptr, plen))
4930 return FALSE;
4931 return TRUE;
4934 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4936 static const WCHAR dacl[] = {'D',':',0};
4937 SECURITY_DESCRIPTOR_CONTROL control;
4938 BOOL present, defaulted;
4939 DWORD revision;
4940 PACL pacl;
4942 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4943 return FALSE;
4945 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4946 return FALSE;
4948 if (!present)
4949 return TRUE;
4951 DumpString(dacl, 2, pwptr, plen);
4952 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4953 return FALSE;
4954 return TRUE;
4957 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4959 static const WCHAR sacl[] = {'S',':',0};
4960 SECURITY_DESCRIPTOR_CONTROL control;
4961 BOOL present, defaulted;
4962 DWORD revision;
4963 PACL pacl;
4965 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4966 return FALSE;
4968 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4969 return FALSE;
4971 if (!present)
4972 return TRUE;
4974 DumpString(sacl, 2, pwptr, plen);
4975 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4976 return FALSE;
4977 return TRUE;
4980 /******************************************************************************
4981 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4983 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4985 ULONG len;
4986 WCHAR *wptr, *wstr;
4988 if (SDRevision != SDDL_REVISION_1)
4990 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4991 SetLastError(ERROR_UNKNOWN_REVISION);
4992 return FALSE;
4995 len = 0;
4996 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4997 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4998 return FALSE;
4999 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5000 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5001 return FALSE;
5002 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5003 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5004 return FALSE;
5005 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5006 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5007 return FALSE;
5009 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5010 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5011 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5012 LocalFree (wstr);
5013 return FALSE;
5015 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5016 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5017 LocalFree (wstr);
5018 return FALSE;
5020 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5021 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5022 LocalFree (wstr);
5023 return FALSE;
5025 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5026 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5027 LocalFree (wstr);
5028 return FALSE;
5030 *wptr = 0;
5032 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5033 *OutputString = wstr;
5034 if (OutputLen)
5035 *OutputLen = strlenW(*OutputString)+1;
5036 return TRUE;
5039 /******************************************************************************
5040 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5042 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5044 LPWSTR wstr;
5045 ULONG len;
5046 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5048 int lenA;
5050 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5051 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
5052 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5053 LocalFree(wstr);
5055 if (OutputLen != NULL)
5056 *OutputLen = lenA;
5057 return TRUE;
5059 else
5061 *OutputString = NULL;
5062 if (OutputLen)
5063 *OutputLen = 0;
5064 return FALSE;
5068 /******************************************************************************
5069 * ConvertStringSidToSidW [ADVAPI32.@]
5071 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5073 BOOL bret = FALSE;
5074 DWORD cBytes;
5076 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5077 if (GetVersion() & 0x80000000)
5078 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5079 else if (!StringSid || !Sid)
5080 SetLastError(ERROR_INVALID_PARAMETER);
5081 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5083 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5085 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5086 if (!bret)
5087 LocalFree(*Sid);
5089 return bret;
5092 /******************************************************************************
5093 * ConvertStringSidToSidA [ADVAPI32.@]
5095 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5097 BOOL bret = FALSE;
5099 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5100 if (GetVersion() & 0x80000000)
5101 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5102 else if (!StringSid || !Sid)
5103 SetLastError(ERROR_INVALID_PARAMETER);
5104 else
5106 WCHAR *wStringSid = SERV_dup(StringSid);
5107 bret = ConvertStringSidToSidW(wStringSid, Sid);
5108 HeapFree(GetProcessHeap(), 0, wStringSid);
5110 return bret;
5113 /******************************************************************************
5114 * ConvertSidToStringSidW [ADVAPI32.@]
5116 * format of SID string is:
5117 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5118 * where
5119 * <rev> is the revision of the SID encoded as decimal
5120 * <auth> is the identifier authority encoded as hex
5121 * <subauthN> is the subauthority id encoded as decimal
5123 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5125 DWORD len = 0;
5126 LPWSTR wstr, wptr;
5128 TRACE("%p %p\n", pSid, pstr );
5130 len = 0;
5131 if (!DumpSidNumeric(pSid, NULL, &len))
5132 return FALSE;
5133 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5134 DumpSidNumeric(pSid, &wptr, NULL);
5135 *wptr = 0;
5137 *pstr = wstr;
5138 return TRUE;
5141 /******************************************************************************
5142 * ConvertSidToStringSidA [ADVAPI32.@]
5144 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5146 LPWSTR wstr = NULL;
5147 LPSTR str;
5148 UINT len;
5150 TRACE("%p %p\n", pSid, pstr );
5152 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5153 return FALSE;
5155 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5156 str = LocalAlloc( 0, len );
5157 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5158 LocalFree( wstr );
5160 *pstr = str;
5162 return TRUE;
5165 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5166 PSECURITY_DESCRIPTOR pdesc,
5167 PSECURITY_DESCRIPTOR cdesc,
5168 PSECURITY_DESCRIPTOR* ndesc,
5169 GUID* objtype,
5170 BOOL isdir,
5171 PGENERIC_MAPPING genmap )
5173 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5175 return FALSE;
5178 BOOL WINAPI CreatePrivateObjectSecurity(
5179 PSECURITY_DESCRIPTOR ParentDescriptor,
5180 PSECURITY_DESCRIPTOR CreatorDescriptor,
5181 PSECURITY_DESCRIPTOR* NewDescriptor,
5182 BOOL IsDirectoryObject,
5183 HANDLE Token,
5184 PGENERIC_MAPPING GenericMapping )
5186 SECURITY_DESCRIPTOR_RELATIVE *relative;
5187 DWORD needed, offset;
5188 BYTE *buffer;
5190 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5191 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5193 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5194 needed += sizeof(sidWorld);
5195 needed += sizeof(sidWorld);
5196 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5197 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5199 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, needed ))) return FALSE;
5200 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5201 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5203 HeapFree( GetProcessHeap(), 0, buffer );
5204 return FALSE;
5206 relative->Control |= SE_SELF_RELATIVE;
5207 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5209 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5210 relative->Owner = offset;
5211 offset += sizeof(sidWorld);
5213 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5214 relative->Group = offset;
5215 offset += sizeof(sidWorld);
5217 GetWorldAccessACL( (ACL *)(buffer + offset) );
5218 relative->Dacl = offset;
5219 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5221 GetWorldAccessACL( (ACL *)(buffer + offset) );
5222 relative->Sacl = offset;
5224 *NewDescriptor = relative;
5225 return TRUE;
5228 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5230 FIXME("%p - stub\n", ObjectDescriptor);
5232 HeapFree( GetProcessHeap(), 0, *ObjectDescriptor );
5233 return TRUE;
5236 BOOL WINAPI CreateProcessAsUserA(
5237 HANDLE hToken,
5238 LPCSTR lpApplicationName,
5239 LPSTR lpCommandLine,
5240 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5241 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5242 BOOL bInheritHandles,
5243 DWORD dwCreationFlags,
5244 LPVOID lpEnvironment,
5245 LPCSTR lpCurrentDirectory,
5246 LPSTARTUPINFOA lpStartupInfo,
5247 LPPROCESS_INFORMATION lpProcessInformation )
5249 BOOL ret;
5250 WCHAR *appW, *cmdlnW, *cwdW;
5251 STARTUPINFOW sinfo;
5253 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5254 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5255 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5257 appW = SERV_dup(lpApplicationName);
5258 cmdlnW = SERV_dup(lpCommandLine);
5259 cwdW = SERV_dup(lpCurrentDirectory);
5260 sinfo.cb = sizeof(sinfo);
5261 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5262 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5263 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5264 sinfo.dwX = lpStartupInfo->dwX;
5265 sinfo.dwY = lpStartupInfo->dwY;
5266 sinfo.dwXSize = lpStartupInfo->dwXSize;
5267 sinfo.dwYSize = lpStartupInfo->dwYSize;
5268 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5269 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5270 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5271 sinfo.dwFlags = lpStartupInfo->dwFlags;
5272 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5273 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5274 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5275 sinfo.hStdInput = lpStartupInfo->hStdInput;
5276 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5277 sinfo.hStdError = lpStartupInfo->hStdError;
5278 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5279 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5280 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5281 HeapFree(GetProcessHeap(), 0, appW);
5282 HeapFree(GetProcessHeap(), 0, cmdlnW);
5283 HeapFree(GetProcessHeap(), 0, cwdW);
5284 HeapFree(GetProcessHeap(), 0, sinfo.lpReserved);
5285 HeapFree(GetProcessHeap(), 0, sinfo.lpDesktop);
5286 HeapFree(GetProcessHeap(), 0, sinfo.lpTitle);
5288 return ret;
5291 BOOL WINAPI CreateProcessAsUserW(
5292 HANDLE hToken,
5293 LPCWSTR lpApplicationName,
5294 LPWSTR lpCommandLine,
5295 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5296 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5297 BOOL bInheritHandles,
5298 DWORD dwCreationFlags,
5299 LPVOID lpEnvironment,
5300 LPCWSTR lpCurrentDirectory,
5301 LPSTARTUPINFOW lpStartupInfo,
5302 LPPROCESS_INFORMATION lpProcessInformation )
5304 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5305 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5306 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5307 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5309 /* We should create the process with a suspended main thread */
5310 if (!CreateProcessW (lpApplicationName,
5311 lpCommandLine,
5312 lpProcessAttributes,
5313 lpThreadAttributes,
5314 bInheritHandles,
5315 dwCreationFlags, /* CREATE_SUSPENDED */
5316 lpEnvironment,
5317 lpCurrentDirectory,
5318 lpStartupInfo,
5319 lpProcessInformation))
5321 return FALSE;
5324 return TRUE;
5327 /******************************************************************************
5328 * CreateProcessWithLogonW
5330 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5331 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5332 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5334 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5335 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5336 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5337 lpStartupInfo, lpProcessInformation);
5339 return FALSE;
5342 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5343 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5344 PROCESS_INFORMATION *process_information )
5346 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5347 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5348 creation_flags, environment, debugstr_w(current_directory),
5349 startup_info, process_information);
5351 /* FIXME: check if handles should be inherited */
5352 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5353 current_directory, startup_info, process_information );
5356 /******************************************************************************
5357 * DuplicateTokenEx [ADVAPI32.@]
5359 BOOL WINAPI DuplicateTokenEx(
5360 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5361 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5362 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5363 TOKEN_TYPE TokenType,
5364 PHANDLE DuplicateTokenHandle )
5366 OBJECT_ATTRIBUTES ObjectAttributes;
5368 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5369 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5371 InitializeObjectAttributes(
5372 &ObjectAttributes,
5373 NULL,
5374 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5375 NULL,
5376 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5378 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5379 dwDesiredAccess,
5380 &ObjectAttributes,
5381 ImpersonationLevel,
5382 TokenType,
5383 DuplicateTokenHandle ) );
5386 BOOL WINAPI DuplicateToken(
5387 HANDLE ExistingTokenHandle,
5388 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5389 PHANDLE DuplicateTokenHandle )
5391 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5392 NULL, ImpersonationLevel, TokenImpersonation,
5393 DuplicateTokenHandle );
5396 /******************************************************************************
5397 * ComputeStringSidSize
5399 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5401 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5403 int ctok = 0;
5404 while (*StringSid)
5406 if (*StringSid == '-')
5407 ctok++;
5408 StringSid++;
5411 if (ctok >= 3)
5412 return GetSidLengthRequired(ctok - 2);
5414 else /* String constant format - Only available in winxp and above */
5416 unsigned int i;
5418 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5419 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5420 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5422 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5423 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5425 MAX_SID local;
5426 ADVAPI_GetComputerSid(&local);
5427 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5432 return GetSidLengthRequired(0);
5435 /******************************************************************************
5436 * ParseStringSidToSid
5438 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5440 BOOL bret = FALSE;
5441 SID* pisid=pSid;
5443 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5444 if (!StringSid)
5446 SetLastError(ERROR_INVALID_PARAMETER);
5447 TRACE("StringSid is NULL, returning FALSE\n");
5448 return FALSE;
5451 while (*StringSid == ' ')
5452 StringSid++;
5454 *cBytes = ComputeStringSidSize(StringSid);
5455 if (!pisid) /* Simply compute the size */
5457 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5458 return TRUE;
5461 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5463 DWORD i = 0, identAuth;
5464 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5466 StringSid += 2; /* Advance to Revision */
5467 pisid->Revision = atoiW(StringSid);
5469 if (pisid->Revision != SDDL_REVISION)
5471 TRACE("Revision %d is unknown\n", pisid->Revision);
5472 goto lend; /* ERROR_INVALID_SID */
5474 if (csubauth == 0)
5476 TRACE("SubAuthorityCount is 0\n");
5477 goto lend; /* ERROR_INVALID_SID */
5480 pisid->SubAuthorityCount = csubauth;
5482 /* Advance to identifier authority */
5483 while (*StringSid && *StringSid != '-')
5484 StringSid++;
5485 if (*StringSid == '-')
5486 StringSid++;
5488 /* MS' implementation can't handle values greater than 2^32 - 1, so
5489 * we don't either; assume most significant bytes are always 0
5491 pisid->IdentifierAuthority.Value[0] = 0;
5492 pisid->IdentifierAuthority.Value[1] = 0;
5493 identAuth = atoiW(StringSid);
5494 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5495 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5496 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5497 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5499 /* Advance to first sub authority */
5500 while (*StringSid && *StringSid != '-')
5501 StringSid++;
5502 if (*StringSid == '-')
5503 StringSid++;
5505 while (*StringSid)
5507 pisid->SubAuthority[i++] = atoiW(StringSid);
5509 while (*StringSid && *StringSid != '-')
5510 StringSid++;
5511 if (*StringSid == '-')
5512 StringSid++;
5515 if (i != pisid->SubAuthorityCount)
5516 goto lend; /* ERROR_INVALID_SID */
5518 bret = TRUE;
5520 else /* String constant format - Only available in winxp and above */
5522 unsigned int i;
5523 pisid->Revision = SDDL_REVISION;
5525 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5526 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5528 DWORD j;
5529 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5530 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5531 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5532 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5533 bret = TRUE;
5536 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5537 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5539 ADVAPI_GetComputerSid(pisid);
5540 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5541 pisid->SubAuthorityCount++;
5542 bret = TRUE;
5545 if (!bret)
5546 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5549 lend:
5550 if (!bret)
5551 SetLastError(ERROR_INVALID_SID);
5553 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5554 return bret;
5557 /******************************************************************************
5558 * GetNamedSecurityInfoA [ADVAPI32.@]
5560 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5561 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5562 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5563 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5565 LPWSTR wstr;
5566 DWORD r;
5568 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5569 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5571 wstr = SERV_dup(pObjectName);
5572 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5573 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5575 HeapFree( GetProcessHeap(), 0, wstr );
5577 return r;
5580 /******************************************************************************
5581 * GetNamedSecurityInfoW [ADVAPI32.@]
5583 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5584 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5585 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5587 DWORD access = 0;
5588 HANDLE handle;
5589 DWORD err;
5591 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5592 group, dacl, sacl, descriptor );
5594 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5595 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5597 /* If no descriptor, we have to check that there's a pointer for the requested information */
5598 if( !descriptor && (
5599 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5600 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5601 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5602 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5603 return ERROR_INVALID_PARAMETER;
5605 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5606 access |= READ_CONTROL;
5607 if (info & SACL_SECURITY_INFORMATION)
5608 access |= ACCESS_SYSTEM_SECURITY;
5610 switch (type)
5612 case SE_SERVICE:
5613 if (!(err = get_security_service( name, access, &handle )))
5615 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5616 CloseServiceHandle( handle );
5618 break;
5619 case SE_REGISTRY_KEY:
5620 if (!(err = get_security_regkey( name, access, &handle )))
5622 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5623 RegCloseKey( handle );
5625 break;
5626 case SE_FILE_OBJECT:
5627 if (!(err = get_security_file( name, access, &handle )))
5629 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5630 CloseHandle( handle );
5632 break;
5633 default:
5634 FIXME( "Object type %d is not currently supported.\n", type );
5635 if (owner) *owner = NULL;
5636 if (group) *group = NULL;
5637 if (dacl) *dacl = NULL;
5638 if (sacl) *sacl = NULL;
5639 if (descriptor) *descriptor = NULL;
5640 return ERROR_SUCCESS;
5642 return err;
5645 /******************************************************************************
5646 * GetNamedSecurityInfoExW [ADVAPI32.@]
5648 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5649 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5650 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5652 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5653 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5654 return ERROR_CALL_NOT_IMPLEMENTED;
5657 /******************************************************************************
5658 * GetNamedSecurityInfoExA [ADVAPI32.@]
5660 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5661 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5662 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5664 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5665 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5666 return ERROR_CALL_NOT_IMPLEMENTED;
5669 /******************************************************************************
5670 * DecryptFileW [ADVAPI32.@]
5672 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5674 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5675 return TRUE;
5678 /******************************************************************************
5679 * DecryptFileA [ADVAPI32.@]
5681 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5683 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5684 return TRUE;
5687 /******************************************************************************
5688 * EncryptFileW [ADVAPI32.@]
5690 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5692 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5693 return TRUE;
5696 /******************************************************************************
5697 * EncryptFileA [ADVAPI32.@]
5699 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5701 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5702 return TRUE;
5705 /******************************************************************************
5706 * FileEncryptionStatusW [ADVAPI32.@]
5708 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5710 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5711 if (!lpStatus)
5712 return FALSE;
5713 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5714 return TRUE;
5717 /******************************************************************************
5718 * FileEncryptionStatusA [ADVAPI32.@]
5720 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5722 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5723 if (!lpStatus)
5724 return FALSE;
5725 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5726 return TRUE;
5729 /******************************************************************************
5730 * SetSecurityInfo [ADVAPI32.@]
5732 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5733 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5734 PSID psidGroup, PACL pDacl, PACL pSacl)
5736 SECURITY_DESCRIPTOR sd;
5737 NTSTATUS status;
5739 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5740 return ERROR_INVALID_SECURITY_DESCR;
5742 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5743 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5744 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5745 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5746 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5747 SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
5748 if (SecurityInfo & SACL_SECURITY_INFORMATION)
5749 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
5751 switch (ObjectType)
5753 case SE_SERVICE:
5754 FIXME("stub: Service objects are not supported at this time.\n");
5755 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
5756 break;
5757 default:
5758 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
5759 break;
5761 return RtlNtStatusToDosError(status);
5764 /******************************************************************************
5765 * SaferCreateLevel [ADVAPI32.@]
5767 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5768 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5770 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5772 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5773 return TRUE;
5776 /******************************************************************************
5777 * SaferComputeTokenFromLevel [ADVAPI32.@]
5779 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5780 DWORD flags, LPVOID reserved)
5782 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5784 *access_token = (HANDLE)0xdeadbeef;
5785 return TRUE;
5788 /******************************************************************************
5789 * SaferCloseLevel [ADVAPI32.@]
5791 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5793 FIXME("(%p) stub\n", handle);
5794 return TRUE;
5797 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5798 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5799 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5800 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5801 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5803 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5804 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5805 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5807 return ERROR_SUCCESS;
5810 /******************************************************************************
5811 * SaferGetPolicyInformation [ADVAPI32.@]
5813 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5814 PVOID buffer, PDWORD required, LPVOID lpReserved)
5816 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5817 return FALSE;
5820 /******************************************************************************
5821 * SaferSetLevelInformation [ADVAPI32.@]
5823 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5824 LPVOID buffer, DWORD size)
5826 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5827 return FALSE;