Assorted typos fixes.
[wine.git] / dlls / advapi32 / security.c
blobac0a9413de86be99429cd482651b51e180d06ac3
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("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
615 PreviousState, ReturnLength);
617 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
618 NewState, BufferLength, PreviousState,
619 ReturnLength);
620 SetLastError( RtlNtStatusToDosError( status ));
621 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
622 return TRUE;
623 else
624 return FALSE;
627 /******************************************************************************
628 * CheckTokenMembership [ADVAPI32.@]
630 * Determine if an access token is a member of a SID.
632 * PARAMS
633 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
634 * SidToCheck [I] SID that possibly contains the token
635 * IsMember [O] Destination for result.
637 * RETURNS
638 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
639 * Failure: FALSE.
641 BOOL WINAPI
642 CheckTokenMembership( HANDLE token, PSID sid_to_check,
643 PBOOL is_member )
645 PTOKEN_GROUPS token_groups = NULL;
646 HANDLE thread_token = NULL;
647 DWORD size, i;
648 BOOL ret;
650 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
652 *is_member = FALSE;
654 if (!token)
656 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
658 HANDLE process_token;
659 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
660 if (!ret)
661 goto exit;
662 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
663 NULL, SecurityImpersonation, TokenImpersonation,
664 &thread_token);
665 CloseHandle(process_token);
666 if (!ret)
667 goto exit;
669 token = thread_token;
671 else
673 TOKEN_TYPE type;
675 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
676 if (!ret) goto exit;
678 if (type == TokenPrimary)
680 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
681 return FALSE;
685 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
686 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
687 goto exit;
689 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
690 if (!token_groups)
692 ret = FALSE;
693 goto exit;
696 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
697 if (!ret)
698 goto exit;
700 for (i = 0; i < token_groups->GroupCount; i++)
702 TRACE("Groups[%d]: {0x%x, %s}\n", i,
703 token_groups->Groups[i].Attributes,
704 debugstr_sid(token_groups->Groups[i].Sid));
705 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
706 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
708 *is_member = TRUE;
709 TRACE("sid enabled and found in token\n");
710 break;
714 exit:
715 HeapFree(GetProcessHeap(), 0, token_groups);
716 if (thread_token != NULL) CloseHandle(thread_token);
718 return ret;
721 /******************************************************************************
722 * GetTokenInformation [ADVAPI32.@]
724 * Get a type of information about an access token.
726 * PARAMS
727 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
728 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
729 * tokeninfo [O] Destination for token information
730 * tokeninfolength [I] Length of tokeninfo
731 * retlen [O] Destination for returned token information length
733 * RETURNS
734 * Success: TRUE. tokeninfo contains retlen bytes of token information
735 * Failure: FALSE.
737 * NOTES
738 * See NtQueryInformationToken.
740 BOOL WINAPI
741 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
742 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
744 TRACE("(%p, %s, %p, %d, %p):\n",
745 token,
746 (tokeninfoclass == TokenUser) ? "TokenUser" :
747 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
748 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
749 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
750 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
751 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
752 (tokeninfoclass == TokenSource) ? "TokenSource" :
753 (tokeninfoclass == TokenType) ? "TokenType" :
754 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
755 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
756 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
757 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
758 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
759 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
760 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
761 "Unknown",
762 tokeninfo, tokeninfolength, retlen);
763 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
764 tokeninfolength, retlen));
767 /******************************************************************************
768 * SetTokenInformation [ADVAPI32.@]
770 * Set information for an access token.
772 * PARAMS
773 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
774 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
775 * tokeninfo [I] Token information to set
776 * tokeninfolength [I] Length of tokeninfo
778 * RETURNS
779 * Success: TRUE. The information for the token is set to tokeninfo.
780 * Failure: FALSE.
782 BOOL WINAPI
783 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
784 LPVOID tokeninfo, DWORD tokeninfolength )
786 TRACE("(%p, %s, %p, %d): stub\n",
787 token,
788 (tokeninfoclass == TokenUser) ? "TokenUser" :
789 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
790 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
791 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
792 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
793 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
794 (tokeninfoclass == TokenSource) ? "TokenSource" :
795 (tokeninfoclass == TokenType) ? "TokenType" :
796 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
797 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
798 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
799 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
800 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
801 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
802 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
803 "Unknown",
804 tokeninfo, tokeninfolength);
806 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
809 /*************************************************************************
810 * SetThreadToken [ADVAPI32.@]
812 * Assigns an 'impersonation token' to a thread so it can assume the
813 * security privileges of another thread or process. Can also remove
814 * a previously assigned token.
816 * PARAMS
817 * thread [O] Handle to thread to set the token for
818 * token [I] Token to set
820 * RETURNS
821 * Success: TRUE. The threads access token is set to token
822 * Failure: FALSE.
824 * NOTES
825 * Only supported on NT or higher. On Win9X this function does nothing.
826 * See SetTokenInformation.
828 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
830 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
831 ThreadImpersonationToken, &token, sizeof token ));
834 /*************************************************************************
835 * CreateRestrictedToken [ADVAPI32.@]
837 * Create a new more restricted token from an existing token.
839 * PARAMS
840 * baseToken [I] Token to base the new restricted token on
841 * flags [I] Options
842 * nDisableSids [I] Length of disableSids array
843 * disableSids [I] Array of SIDs to disable in the new token
844 * nDeletePrivs [I] Length of deletePrivs array
845 * deletePrivs [I] Array of privileges to delete in the new token
846 * nRestrictSids [I] Length of restrictSids array
847 * restrictSids [I] Array of SIDs to restrict in the new token
848 * newToken [O] Address where the new token is stored
850 * RETURNS
851 * Success: TRUE
852 * Failure: FALSE
854 BOOL WINAPI CreateRestrictedToken(
855 HANDLE baseToken,
856 DWORD flags,
857 DWORD nDisableSids,
858 PSID_AND_ATTRIBUTES disableSids,
859 DWORD nDeletePrivs,
860 PLUID_AND_ATTRIBUTES deletePrivs,
861 DWORD nRestrictSids,
862 PSID_AND_ATTRIBUTES restrictSids,
863 PHANDLE newToken)
865 TOKEN_TYPE type;
866 SECURITY_IMPERSONATION_LEVEL level = TokenImpersonationLevel;
867 DWORD size;
869 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
870 baseToken, flags, nDisableSids, disableSids,
871 nDeletePrivs, deletePrivs,
872 nRestrictSids, restrictSids,
873 newToken);
875 size = sizeof(type);
876 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
877 if (type == TokenImpersonation)
879 size = sizeof(level);
880 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
881 return FALSE;
883 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
886 /* ##############################
887 ###### SID FUNCTIONS ######
888 ##############################
891 /******************************************************************************
892 * AllocateAndInitializeSid [ADVAPI32.@]
894 * PARAMS
895 * pIdentifierAuthority []
896 * nSubAuthorityCount []
897 * nSubAuthority0 []
898 * nSubAuthority1 []
899 * nSubAuthority2 []
900 * nSubAuthority3 []
901 * nSubAuthority4 []
902 * nSubAuthority5 []
903 * nSubAuthority6 []
904 * nSubAuthority7 []
905 * pSid []
907 BOOL WINAPI
908 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
909 BYTE nSubAuthorityCount,
910 DWORD nSubAuthority0, DWORD nSubAuthority1,
911 DWORD nSubAuthority2, DWORD nSubAuthority3,
912 DWORD nSubAuthority4, DWORD nSubAuthority5,
913 DWORD nSubAuthority6, DWORD nSubAuthority7,
914 PSID *pSid )
916 return set_ntstatus( RtlAllocateAndInitializeSid(
917 pIdentifierAuthority, nSubAuthorityCount,
918 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
919 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
920 pSid ));
923 /******************************************************************************
924 * FreeSid [ADVAPI32.@]
926 * PARAMS
927 * pSid []
929 PVOID WINAPI
930 FreeSid( PSID pSid )
932 RtlFreeSid(pSid);
933 return NULL; /* is documented like this */
936 /******************************************************************************
937 * CopySid [ADVAPI32.@]
939 * PARAMS
940 * nDestinationSidLength []
941 * pDestinationSid []
942 * pSourceSid []
944 BOOL WINAPI
945 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
947 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
950 /******************************************************************************
951 * CreateWellKnownSid [ADVAPI32.@]
953 BOOL WINAPI
954 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
955 PSID DomainSid,
956 PSID pSid,
957 DWORD* cbSid)
959 unsigned int i;
960 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
962 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
964 SetLastError(ERROR_INVALID_PARAMETER);
965 return FALSE;
968 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
969 if (WellKnownSids[i].Type == WellKnownSidType) {
970 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
972 if (*cbSid < length)
974 *cbSid = length;
975 SetLastError(ERROR_INSUFFICIENT_BUFFER);
976 return FALSE;
978 if (!pSid)
980 SetLastError(ERROR_INVALID_PARAMETER);
981 return FALSE;
983 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
984 *cbSid = length;
985 return TRUE;
989 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
991 SetLastError(ERROR_INVALID_PARAMETER);
992 return FALSE;
995 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
996 if (WellKnownRids[i].Type == WellKnownSidType) {
997 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
998 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
999 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
1001 if (*cbSid < output_sid_length)
1003 *cbSid = output_sid_length;
1004 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1005 return FALSE;
1007 if (!pSid)
1009 SetLastError(ERROR_INVALID_PARAMETER);
1010 return FALSE;
1012 CopyMemory(pSid, DomainSid, domain_sid_length);
1013 (*GetSidSubAuthorityCount(pSid))++;
1014 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1015 *cbSid = output_sid_length;
1016 return TRUE;
1019 SetLastError(ERROR_INVALID_PARAMETER);
1020 return FALSE;
1023 /******************************************************************************
1024 * IsWellKnownSid [ADVAPI32.@]
1026 BOOL WINAPI
1027 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1029 unsigned int i;
1030 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1032 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
1033 if (WellKnownSids[i].Type == WellKnownSidType)
1034 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1035 return TRUE;
1037 return FALSE;
1040 BOOL WINAPI
1041 IsTokenRestricted( HANDLE TokenHandle )
1043 TOKEN_GROUPS *groups;
1044 DWORD size;
1045 NTSTATUS status;
1046 BOOL restricted;
1048 TRACE("(%p)\n", TokenHandle);
1050 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1051 if (status != STATUS_BUFFER_TOO_SMALL)
1052 return FALSE;
1054 groups = HeapAlloc(GetProcessHeap(), 0, size);
1055 if (!groups)
1057 SetLastError(ERROR_OUTOFMEMORY);
1058 return FALSE;
1061 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1062 if (status != STATUS_SUCCESS)
1064 HeapFree(GetProcessHeap(), 0, groups);
1065 return set_ntstatus(status);
1068 if (groups->GroupCount)
1069 restricted = TRUE;
1070 else
1071 restricted = FALSE;
1073 HeapFree(GetProcessHeap(), 0, groups);
1075 return restricted;
1078 /******************************************************************************
1079 * IsValidSid [ADVAPI32.@]
1081 * PARAMS
1082 * pSid []
1084 BOOL WINAPI
1085 IsValidSid( PSID pSid )
1087 return RtlValidSid( pSid );
1090 /******************************************************************************
1091 * EqualSid [ADVAPI32.@]
1093 * PARAMS
1094 * pSid1 []
1095 * pSid2 []
1097 BOOL WINAPI
1098 EqualSid( PSID pSid1, PSID pSid2 )
1100 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1101 SetLastError(ERROR_SUCCESS);
1102 return ret;
1105 /******************************************************************************
1106 * EqualPrefixSid [ADVAPI32.@]
1108 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1110 return RtlEqualPrefixSid(pSid1, pSid2);
1113 /******************************************************************************
1114 * GetSidLengthRequired [ADVAPI32.@]
1116 * PARAMS
1117 * nSubAuthorityCount []
1119 DWORD WINAPI
1120 GetSidLengthRequired( BYTE nSubAuthorityCount )
1122 return RtlLengthRequiredSid(nSubAuthorityCount);
1125 /******************************************************************************
1126 * InitializeSid [ADVAPI32.@]
1128 * PARAMS
1129 * pIdentifierAuthority []
1131 BOOL WINAPI
1132 InitializeSid (
1133 PSID pSid,
1134 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1135 BYTE nSubAuthorityCount)
1137 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1140 DWORD WINAPI
1141 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1143 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1145 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1146 return 0;
1149 DWORD WINAPI
1150 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1152 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1154 return 1;
1157 /******************************************************************************
1158 * GetSidIdentifierAuthority [ADVAPI32.@]
1160 * PARAMS
1161 * pSid []
1163 PSID_IDENTIFIER_AUTHORITY WINAPI
1164 GetSidIdentifierAuthority( PSID pSid )
1166 return RtlIdentifierAuthoritySid(pSid);
1169 /******************************************************************************
1170 * GetSidSubAuthority [ADVAPI32.@]
1172 * PARAMS
1173 * pSid []
1174 * nSubAuthority []
1176 PDWORD WINAPI
1177 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1179 SetLastError(ERROR_SUCCESS);
1180 return RtlSubAuthoritySid(pSid, nSubAuthority);
1183 /******************************************************************************
1184 * GetSidSubAuthorityCount [ADVAPI32.@]
1186 * PARAMS
1187 * pSid []
1189 PUCHAR WINAPI
1190 GetSidSubAuthorityCount (PSID pSid)
1192 SetLastError(ERROR_SUCCESS);
1193 return RtlSubAuthorityCountSid(pSid);
1196 /******************************************************************************
1197 * GetLengthSid [ADVAPI32.@]
1199 * PARAMS
1200 * pSid []
1202 DWORD WINAPI
1203 GetLengthSid (PSID pSid)
1205 return RtlLengthSid(pSid);
1208 /* ##############################################
1209 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1210 ##############################################
1213 /******************************************************************************
1214 * BuildSecurityDescriptorA [ADVAPI32.@]
1216 * Builds a SD from
1218 * PARAMS
1219 * pOwner [I]
1220 * pGroup [I]
1221 * cCountOfAccessEntries [I]
1222 * pListOfAccessEntries [I]
1223 * cCountOfAuditEntries [I]
1224 * pListofAuditEntries [I]
1225 * pOldSD [I]
1226 * lpdwBufferLength [I/O]
1227 * pNewSD [O]
1229 * RETURNS
1230 * Success: ERROR_SUCCESS
1231 * Failure: nonzero error code from Winerror.h
1233 DWORD WINAPI BuildSecurityDescriptorA(
1234 IN PTRUSTEEA pOwner,
1235 IN PTRUSTEEA pGroup,
1236 IN ULONG cCountOfAccessEntries,
1237 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1238 IN ULONG cCountOfAuditEntries,
1239 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1240 IN PSECURITY_DESCRIPTOR pOldSD,
1241 IN OUT PULONG lpdwBufferLength,
1242 OUT PSECURITY_DESCRIPTOR* pNewSD)
1244 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1245 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1246 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1248 return ERROR_CALL_NOT_IMPLEMENTED;
1251 /******************************************************************************
1252 * BuildSecurityDescriptorW [ADVAPI32.@]
1254 * See BuildSecurityDescriptorA.
1256 DWORD WINAPI BuildSecurityDescriptorW(
1257 IN PTRUSTEEW pOwner,
1258 IN PTRUSTEEW pGroup,
1259 IN ULONG cCountOfAccessEntries,
1260 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1261 IN ULONG cCountOfAuditEntries,
1262 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1263 IN PSECURITY_DESCRIPTOR pOldSD,
1264 IN OUT PULONG lpdwBufferLength,
1265 OUT PSECURITY_DESCRIPTOR* pNewSD)
1267 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1268 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1269 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1271 return ERROR_CALL_NOT_IMPLEMENTED;
1274 /******************************************************************************
1275 * InitializeSecurityDescriptor [ADVAPI32.@]
1277 * PARAMS
1278 * pDescr []
1279 * revision []
1281 BOOL WINAPI
1282 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1284 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1288 /******************************************************************************
1289 * MakeAbsoluteSD [ADVAPI32.@]
1291 BOOL WINAPI MakeAbsoluteSD (
1292 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1293 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1294 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1295 OUT PACL pDacl,
1296 OUT LPDWORD lpdwDaclSize,
1297 OUT PACL pSacl,
1298 OUT LPDWORD lpdwSaclSize,
1299 OUT PSID pOwner,
1300 OUT LPDWORD lpdwOwnerSize,
1301 OUT PSID pPrimaryGroup,
1302 OUT LPDWORD lpdwPrimaryGroupSize)
1304 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1305 pAbsoluteSecurityDescriptor,
1306 lpdwAbsoluteSecurityDescriptorSize,
1307 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1308 pOwner, lpdwOwnerSize,
1309 pPrimaryGroup, lpdwPrimaryGroupSize));
1312 /******************************************************************************
1313 * GetKernelObjectSecurity [ADVAPI32.@]
1315 BOOL WINAPI GetKernelObjectSecurity(
1316 HANDLE Handle,
1317 SECURITY_INFORMATION RequestedInformation,
1318 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1319 DWORD nLength,
1320 LPDWORD lpnLengthNeeded )
1322 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1323 pSecurityDescriptor, nLength, lpnLengthNeeded);
1325 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1326 nLength, lpnLengthNeeded ));
1329 /******************************************************************************
1330 * GetPrivateObjectSecurity [ADVAPI32.@]
1332 BOOL WINAPI GetPrivateObjectSecurity(
1333 PSECURITY_DESCRIPTOR ObjectDescriptor,
1334 SECURITY_INFORMATION SecurityInformation,
1335 PSECURITY_DESCRIPTOR ResultantDescriptor,
1336 DWORD DescriptorLength,
1337 PDWORD ReturnLength )
1339 SECURITY_DESCRIPTOR desc;
1340 BOOL defaulted, present;
1341 PACL pacl;
1342 PSID psid;
1344 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1345 ResultantDescriptor, DescriptorLength, ReturnLength);
1347 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1348 return FALSE;
1350 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1352 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1353 return FALSE;
1354 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1357 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1359 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1360 return FALSE;
1361 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1364 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1366 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1367 return FALSE;
1368 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1371 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1373 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1374 return FALSE;
1375 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1378 *ReturnLength = DescriptorLength;
1379 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1382 /******************************************************************************
1383 * GetSecurityDescriptorLength [ADVAPI32.@]
1385 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1387 return RtlLengthSecurityDescriptor(pDescr);
1390 /******************************************************************************
1391 * GetSecurityDescriptorOwner [ADVAPI32.@]
1393 * PARAMS
1394 * pOwner []
1395 * lpbOwnerDefaulted []
1397 BOOL WINAPI
1398 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1399 LPBOOL lpbOwnerDefaulted )
1401 BOOLEAN defaulted;
1402 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1403 *lpbOwnerDefaulted = defaulted;
1404 return ret;
1407 /******************************************************************************
1408 * SetSecurityDescriptorOwner [ADVAPI32.@]
1410 * PARAMS
1412 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1413 PSID pOwner, BOOL bOwnerDefaulted)
1415 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1417 /******************************************************************************
1418 * GetSecurityDescriptorGroup [ADVAPI32.@]
1420 BOOL WINAPI GetSecurityDescriptorGroup(
1421 PSECURITY_DESCRIPTOR SecurityDescriptor,
1422 PSID *Group,
1423 LPBOOL GroupDefaulted)
1425 BOOLEAN defaulted;
1426 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1427 *GroupDefaulted = defaulted;
1428 return ret;
1430 /******************************************************************************
1431 * SetSecurityDescriptorGroup [ADVAPI32.@]
1433 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1434 PSID Group, BOOL GroupDefaulted)
1436 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1439 /******************************************************************************
1440 * IsValidSecurityDescriptor [ADVAPI32.@]
1442 * PARAMS
1443 * lpsecdesc []
1445 BOOL WINAPI
1446 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1448 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1451 /******************************************************************************
1452 * GetSecurityDescriptorDacl [ADVAPI32.@]
1454 BOOL WINAPI GetSecurityDescriptorDacl(
1455 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1456 OUT LPBOOL lpbDaclPresent,
1457 OUT PACL *pDacl,
1458 OUT LPBOOL lpbDaclDefaulted)
1460 BOOLEAN present, defaulted;
1461 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1462 *lpbDaclPresent = present;
1463 *lpbDaclDefaulted = defaulted;
1464 return ret;
1467 /******************************************************************************
1468 * SetSecurityDescriptorDacl [ADVAPI32.@]
1470 BOOL WINAPI
1471 SetSecurityDescriptorDacl (
1472 PSECURITY_DESCRIPTOR lpsd,
1473 BOOL daclpresent,
1474 PACL dacl,
1475 BOOL dacldefaulted )
1477 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1479 /******************************************************************************
1480 * GetSecurityDescriptorSacl [ADVAPI32.@]
1482 BOOL WINAPI GetSecurityDescriptorSacl(
1483 IN PSECURITY_DESCRIPTOR lpsd,
1484 OUT LPBOOL lpbSaclPresent,
1485 OUT PACL *pSacl,
1486 OUT LPBOOL lpbSaclDefaulted)
1488 BOOLEAN present, defaulted;
1489 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1490 *lpbSaclPresent = present;
1491 *lpbSaclDefaulted = defaulted;
1492 return ret;
1495 /**************************************************************************
1496 * SetSecurityDescriptorSacl [ADVAPI32.@]
1498 BOOL WINAPI SetSecurityDescriptorSacl (
1499 PSECURITY_DESCRIPTOR lpsd,
1500 BOOL saclpresent,
1501 PACL lpsacl,
1502 BOOL sacldefaulted)
1504 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1506 /******************************************************************************
1507 * MakeSelfRelativeSD [ADVAPI32.@]
1509 * PARAMS
1510 * lpabssecdesc []
1511 * lpselfsecdesc []
1512 * lpbuflen []
1514 BOOL WINAPI
1515 MakeSelfRelativeSD(
1516 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1517 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1518 IN OUT LPDWORD lpdwBufferLength)
1520 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1521 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1524 /******************************************************************************
1525 * GetSecurityDescriptorControl [ADVAPI32.@]
1528 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1529 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1531 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1534 /******************************************************************************
1535 * SetSecurityDescriptorControl [ADVAPI32.@]
1537 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1538 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1539 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1541 return set_ntstatus( RtlSetControlSecurityDescriptor(
1542 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1545 /* ##############################
1546 ###### ACL FUNCTIONS ######
1547 ##############################
1550 /*************************************************************************
1551 * InitializeAcl [ADVAPI32.@]
1553 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1555 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1558 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1560 IO_STATUS_BLOCK io_block;
1562 TRACE("(%p)\n", hNamedPipe);
1564 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1565 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1568 /******************************************************************************
1569 * AddAccessAllowedAce [ADVAPI32.@]
1571 BOOL WINAPI AddAccessAllowedAce(
1572 IN OUT PACL pAcl,
1573 IN DWORD dwAceRevision,
1574 IN DWORD AccessMask,
1575 IN PSID pSid)
1577 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1580 /******************************************************************************
1581 * AddAccessAllowedAceEx [ADVAPI32.@]
1583 BOOL WINAPI AddAccessAllowedAceEx(
1584 IN OUT PACL pAcl,
1585 IN DWORD dwAceRevision,
1586 IN DWORD AceFlags,
1587 IN DWORD AccessMask,
1588 IN PSID pSid)
1590 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1593 /******************************************************************************
1594 * AddAccessDeniedAce [ADVAPI32.@]
1596 BOOL WINAPI AddAccessDeniedAce(
1597 IN OUT PACL pAcl,
1598 IN DWORD dwAceRevision,
1599 IN DWORD AccessMask,
1600 IN PSID pSid)
1602 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1605 /******************************************************************************
1606 * AddAccessDeniedAceEx [ADVAPI32.@]
1608 BOOL WINAPI AddAccessDeniedAceEx(
1609 IN OUT PACL pAcl,
1610 IN DWORD dwAceRevision,
1611 IN DWORD AceFlags,
1612 IN DWORD AccessMask,
1613 IN PSID pSid)
1615 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1618 /******************************************************************************
1619 * AddAce [ADVAPI32.@]
1621 BOOL WINAPI AddAce(
1622 IN OUT PACL pAcl,
1623 IN DWORD dwAceRevision,
1624 IN DWORD dwStartingAceIndex,
1625 LPVOID pAceList,
1626 DWORD nAceListLength)
1628 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1631 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1633 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1634 return FALSE;
1637 /******************************************************************************
1638 * DeleteAce [ADVAPI32.@]
1640 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1642 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1645 /******************************************************************************
1646 * FindFirstFreeAce [ADVAPI32.@]
1648 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1650 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1653 /******************************************************************************
1654 * GetAce [ADVAPI32.@]
1656 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1658 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1661 /******************************************************************************
1662 * GetAclInformation [ADVAPI32.@]
1664 BOOL WINAPI GetAclInformation(
1665 PACL pAcl,
1666 LPVOID pAclInformation,
1667 DWORD nAclInformationLength,
1668 ACL_INFORMATION_CLASS dwAclInformationClass)
1670 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1671 nAclInformationLength, dwAclInformationClass));
1674 /******************************************************************************
1675 * IsValidAcl [ADVAPI32.@]
1677 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1679 return RtlValidAcl(pAcl);
1682 /* ##############################
1683 ###### MISC FUNCTIONS ######
1684 ##############################
1687 /******************************************************************************
1688 * AllocateLocallyUniqueId [ADVAPI32.@]
1690 * PARAMS
1691 * lpLuid []
1693 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1695 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1698 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1699 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1700 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1701 { '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 };
1702 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1703 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1704 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1705 { '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 };
1706 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1707 { '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 };
1708 static const WCHAR SE_TCB_NAME_W[] =
1709 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1710 static const WCHAR SE_SECURITY_NAME_W[] =
1711 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1712 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1713 { '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 };
1714 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1715 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1716 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1717 { '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 };
1718 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1719 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1720 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1721 { '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 };
1722 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1723 { '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 };
1724 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1725 { '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 };
1726 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1727 { '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 };
1728 static const WCHAR SE_BACKUP_NAME_W[] =
1729 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1730 static const WCHAR SE_RESTORE_NAME_W[] =
1731 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1732 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1733 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1734 static const WCHAR SE_DEBUG_NAME_W[] =
1735 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1736 static const WCHAR SE_AUDIT_NAME_W[] =
1737 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1738 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1739 { '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 };
1740 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1741 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1742 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1743 { '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 };
1744 static const WCHAR SE_UNDOCK_NAME_W[] =
1745 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1746 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1747 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1748 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1749 { '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 };
1750 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1751 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1752 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1753 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1754 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1755 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1757 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1759 NULL,
1760 NULL,
1761 SE_CREATE_TOKEN_NAME_W,
1762 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1763 SE_LOCK_MEMORY_NAME_W,
1764 SE_INCREASE_QUOTA_NAME_W,
1765 SE_MACHINE_ACCOUNT_NAME_W,
1766 SE_TCB_NAME_W,
1767 SE_SECURITY_NAME_W,
1768 SE_TAKE_OWNERSHIP_NAME_W,
1769 SE_LOAD_DRIVER_NAME_W,
1770 SE_SYSTEM_PROFILE_NAME_W,
1771 SE_SYSTEMTIME_NAME_W,
1772 SE_PROF_SINGLE_PROCESS_NAME_W,
1773 SE_INC_BASE_PRIORITY_NAME_W,
1774 SE_CREATE_PAGEFILE_NAME_W,
1775 SE_CREATE_PERMANENT_NAME_W,
1776 SE_BACKUP_NAME_W,
1777 SE_RESTORE_NAME_W,
1778 SE_SHUTDOWN_NAME_W,
1779 SE_DEBUG_NAME_W,
1780 SE_AUDIT_NAME_W,
1781 SE_SYSTEM_ENVIRONMENT_NAME_W,
1782 SE_CHANGE_NOTIFY_NAME_W,
1783 SE_REMOTE_SHUTDOWN_NAME_W,
1784 SE_UNDOCK_NAME_W,
1785 SE_SYNC_AGENT_NAME_W,
1786 SE_ENABLE_DELEGATION_NAME_W,
1787 SE_MANAGE_VOLUME_NAME_W,
1788 SE_IMPERSONATE_NAME_W,
1789 SE_CREATE_GLOBAL_NAME_W,
1792 /******************************************************************************
1793 * LookupPrivilegeValueW [ADVAPI32.@]
1795 * See LookupPrivilegeValueA.
1797 BOOL WINAPI
1798 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1800 UINT i;
1802 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1804 if (!ADVAPI_IsLocalComputer(lpSystemName))
1806 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1807 return FALSE;
1809 if (!lpName)
1811 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1812 return FALSE;
1814 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1816 if( !WellKnownPrivNames[i] )
1817 continue;
1818 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1819 continue;
1820 lpLuid->LowPart = i;
1821 lpLuid->HighPart = 0;
1822 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1823 lpLuid->HighPart, lpLuid->LowPart );
1824 return TRUE;
1826 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1827 return FALSE;
1830 /******************************************************************************
1831 * LookupPrivilegeValueA [ADVAPI32.@]
1833 * Retrieves LUID used on a system to represent the privilege name.
1835 * PARAMS
1836 * lpSystemName [I] Name of the system
1837 * lpName [I] Name of the privilege
1838 * lpLuid [O] Destination for the resulting LUID
1840 * RETURNS
1841 * Success: TRUE. lpLuid contains the requested LUID.
1842 * Failure: FALSE.
1844 BOOL WINAPI
1845 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1847 UNICODE_STRING lpSystemNameW;
1848 UNICODE_STRING lpNameW;
1849 BOOL ret;
1851 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1852 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1853 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1854 RtlFreeUnicodeString(&lpNameW);
1855 RtlFreeUnicodeString(&lpSystemNameW);
1856 return ret;
1859 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1860 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1862 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1863 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1865 return FALSE;
1868 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1869 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1871 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1872 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1874 return FALSE;
1877 /******************************************************************************
1878 * LookupPrivilegeNameA [ADVAPI32.@]
1880 * See LookupPrivilegeNameW.
1882 BOOL WINAPI
1883 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1884 LPDWORD cchName)
1886 UNICODE_STRING lpSystemNameW;
1887 BOOL ret;
1888 DWORD wLen = 0;
1890 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1892 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1893 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1894 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1896 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1898 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1899 &wLen);
1900 if (ret)
1902 /* Windows crashes if cchName is NULL, so will I */
1903 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1904 *cchName, NULL, NULL);
1906 if (len == 0)
1908 /* WideCharToMultiByte failed */
1909 ret = FALSE;
1911 else if (len > *cchName)
1913 *cchName = len;
1914 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1915 ret = FALSE;
1917 else
1919 /* WideCharToMultiByte succeeded, output length needs to be
1920 * length not including NULL terminator
1922 *cchName = len - 1;
1925 HeapFree(GetProcessHeap(), 0, lpNameW);
1927 RtlFreeUnicodeString(&lpSystemNameW);
1928 return ret;
1931 /******************************************************************************
1932 * LookupPrivilegeNameW [ADVAPI32.@]
1934 * Retrieves the privilege name referred to by the LUID lpLuid.
1936 * PARAMS
1937 * lpSystemName [I] Name of the system
1938 * lpLuid [I] Privilege value
1939 * lpName [O] Name of the privilege
1940 * cchName [I/O] Number of characters in lpName.
1942 * RETURNS
1943 * Success: TRUE. lpName contains the name of the privilege whose value is
1944 * *lpLuid.
1945 * Failure: FALSE.
1947 * REMARKS
1948 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1949 * using this function.
1950 * If the length of lpName is too small, on return *cchName will contain the
1951 * number of WCHARs needed to contain the privilege, including the NULL
1952 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1953 * On success, *cchName will contain the number of characters stored in
1954 * lpName, NOT including the NULL terminator.
1956 BOOL WINAPI
1957 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1958 LPDWORD cchName)
1960 size_t privNameLen;
1962 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1964 if (!ADVAPI_IsLocalComputer(lpSystemName))
1966 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1967 return FALSE;
1969 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1970 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1972 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1973 return FALSE;
1975 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1976 /* Windows crashes if cchName is NULL, so will I */
1977 if (*cchName <= privNameLen)
1979 *cchName = privNameLen + 1;
1980 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1981 return FALSE;
1983 else
1985 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1986 *cchName = privNameLen;
1987 return TRUE;
1991 /******************************************************************************
1992 * GetFileSecurityA [ADVAPI32.@]
1994 * Obtains Specified information about the security of a file or directory.
1996 * PARAMS
1997 * lpFileName [I] Name of the file to get info for
1998 * RequestedInformation [I] SE_ flags from "winnt.h"
1999 * pSecurityDescriptor [O] Destination for security information
2000 * nLength [I] Length of pSecurityDescriptor
2001 * lpnLengthNeeded [O] Destination for length of returned security information
2003 * RETURNS
2004 * Success: TRUE. pSecurityDescriptor contains the requested information.
2005 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2007 * NOTES
2008 * The information returned is constrained by the callers access rights and
2009 * privileges.
2011 BOOL WINAPI
2012 GetFileSecurityA( LPCSTR lpFileName,
2013 SECURITY_INFORMATION RequestedInformation,
2014 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2015 DWORD nLength, LPDWORD lpnLengthNeeded )
2017 BOOL r;
2018 LPWSTR name;
2020 name = SERV_dup(lpFileName);
2021 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2022 nLength, lpnLengthNeeded );
2023 HeapFree( GetProcessHeap(), 0, name );
2025 return r;
2028 /******************************************************************************
2029 * GetFileSecurityW [ADVAPI32.@]
2031 * See GetFileSecurityA.
2033 BOOL WINAPI
2034 GetFileSecurityW( LPCWSTR lpFileName,
2035 SECURITY_INFORMATION RequestedInformation,
2036 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2037 DWORD nLength, LPDWORD lpnLengthNeeded )
2039 HANDLE hfile;
2040 NTSTATUS status;
2041 DWORD access = 0;
2043 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2044 RequestedInformation, pSecurityDescriptor,
2045 nLength, lpnLengthNeeded);
2047 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2048 DACL_SECURITY_INFORMATION))
2049 access |= READ_CONTROL;
2050 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2051 access |= ACCESS_SYSTEM_SECURITY;
2053 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2054 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2055 if ( hfile == INVALID_HANDLE_VALUE )
2056 return FALSE;
2058 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2059 nLength, lpnLengthNeeded );
2060 CloseHandle( hfile );
2061 return set_ntstatus( status );
2065 /******************************************************************************
2066 * LookupAccountSidA [ADVAPI32.@]
2068 BOOL WINAPI
2069 LookupAccountSidA(
2070 IN LPCSTR system,
2071 IN PSID sid,
2072 OUT LPSTR account,
2073 IN OUT LPDWORD accountSize,
2074 OUT LPSTR domain,
2075 IN OUT LPDWORD domainSize,
2076 OUT PSID_NAME_USE name_use )
2078 DWORD len;
2079 BOOL r;
2080 LPWSTR systemW;
2081 LPWSTR accountW = NULL;
2082 LPWSTR domainW = NULL;
2083 DWORD accountSizeW = *accountSize;
2084 DWORD domainSizeW = *domainSize;
2086 systemW = SERV_dup(system);
2087 if (account)
2088 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2089 if (domain)
2090 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2092 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2094 if (r) {
2095 if (accountW && *accountSize) {
2096 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2097 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2098 *accountSize = len;
2099 } else
2100 *accountSize = accountSizeW + 1;
2102 if (domainW && *domainSize) {
2103 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2104 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2105 *domainSize = len;
2106 } else
2107 *domainSize = domainSizeW + 1;
2109 else
2111 *accountSize = accountSizeW + 1;
2112 *domainSize = domainSizeW + 1;
2115 HeapFree( GetProcessHeap(), 0, systemW );
2116 HeapFree( GetProcessHeap(), 0, accountW );
2117 HeapFree( GetProcessHeap(), 0, domainW );
2119 return r;
2122 /******************************************************************************
2123 * LookupAccountSidW [ADVAPI32.@]
2125 * PARAMS
2126 * system []
2127 * sid []
2128 * account []
2129 * accountSize []
2130 * domain []
2131 * domainSize []
2132 * name_use []
2135 BOOL WINAPI
2136 LookupAccountSidW(
2137 IN LPCWSTR system,
2138 IN PSID sid,
2139 OUT LPWSTR account,
2140 IN OUT LPDWORD accountSize,
2141 OUT LPWSTR domain,
2142 IN OUT LPDWORD domainSize,
2143 OUT PSID_NAME_USE name_use )
2145 unsigned int i, j;
2146 const WCHAR * ac = NULL;
2147 const WCHAR * dm = NULL;
2148 SID_NAME_USE use = 0;
2149 LPWSTR computer_name = NULL;
2150 LPWSTR account_name = NULL;
2152 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2153 debugstr_w(system),debugstr_sid(sid),
2154 account,accountSize,accountSize?*accountSize:0,
2155 domain,domainSize,domainSize?*domainSize:0,
2156 name_use);
2158 if (!ADVAPI_IsLocalComputer(system)) {
2159 FIXME("Only local computer supported!\n");
2160 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2161 return FALSE;
2164 /* check the well known SIDs first */
2165 for (i = 0; i <= 60; i++) {
2166 if (IsWellKnownSid(sid, i)) {
2167 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2168 if (ACCOUNT_SIDS[j].type == i) {
2169 ac = ACCOUNT_SIDS[j].account;
2170 dm = ACCOUNT_SIDS[j].domain;
2171 use = ACCOUNT_SIDS[j].name_use;
2174 break;
2178 if (dm == NULL) {
2179 MAX_SID local;
2181 /* check for the local computer next */
2182 if (ADVAPI_GetComputerSid(&local)) {
2183 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2184 BOOL result;
2186 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2187 result = GetComputerNameW(computer_name, &size);
2189 if (result) {
2190 if (EqualSid(sid, &local)) {
2191 dm = computer_name;
2192 ac = Blank;
2193 use = 3;
2194 } else {
2195 local.SubAuthorityCount++;
2197 if (EqualPrefixSid(sid, &local)) {
2198 dm = computer_name;
2199 use = 1;
2200 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2201 case DOMAIN_USER_RID_ADMIN:
2202 ac = Administrator;
2203 break;
2204 case DOMAIN_USER_RID_GUEST:
2205 ac = Guest;
2206 break;
2207 case DOMAIN_GROUP_RID_ADMINS:
2208 ac = Domain_Admins;
2209 break;
2210 case DOMAIN_GROUP_RID_USERS:
2211 ac = Domain_Users;
2212 break;
2213 case DOMAIN_GROUP_RID_GUESTS:
2214 ac = Domain_Guests;
2215 break;
2216 case DOMAIN_GROUP_RID_COMPUTERS:
2217 ac = Domain_Computers;
2218 break;
2219 case DOMAIN_GROUP_RID_CONTROLLERS:
2220 ac = Domain_Controllers;
2221 break;
2222 case DOMAIN_GROUP_RID_CERT_ADMINS:
2223 ac = Cert_Publishers;
2224 break;
2225 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2226 ac = Schema_Admins;
2227 break;
2228 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2229 ac = Enterprise_Admins;
2230 break;
2231 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2232 ac = Group_Policy_Creator_Owners;
2233 break;
2234 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2235 ac = RAS_and_IAS_Servers;
2236 break;
2237 case 1000: /* first user account */
2238 size = UNLEN + 1;
2239 account_name = HeapAlloc(
2240 GetProcessHeap(), 0, size * sizeof(WCHAR));
2241 if (GetUserNameW(account_name, &size))
2242 ac = account_name;
2243 else
2244 dm = NULL;
2246 break;
2247 default:
2248 dm = NULL;
2249 break;
2257 if (dm) {
2258 DWORD ac_len = lstrlenW(ac);
2259 DWORD dm_len = lstrlenW(dm);
2260 BOOL status = TRUE;
2262 if (*accountSize > ac_len) {
2263 if (account)
2264 lstrcpyW(account, ac);
2266 if (*domainSize > dm_len) {
2267 if (domain)
2268 lstrcpyW(domain, dm);
2270 if ((*accountSize && *accountSize < ac_len) ||
2271 (!account && !*accountSize && ac_len) ||
2272 (*domainSize && *domainSize < dm_len) ||
2273 (!domain && !*domainSize && dm_len))
2275 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2276 status = FALSE;
2278 if (*domainSize)
2279 *domainSize = dm_len;
2280 else
2281 *domainSize = dm_len + 1;
2282 if (*accountSize)
2283 *accountSize = ac_len;
2284 else
2285 *accountSize = ac_len + 1;
2287 HeapFree(GetProcessHeap(), 0, account_name);
2288 HeapFree(GetProcessHeap(), 0, computer_name);
2289 if (status) *name_use = use;
2290 return status;
2293 HeapFree(GetProcessHeap(), 0, account_name);
2294 HeapFree(GetProcessHeap(), 0, computer_name);
2295 SetLastError(ERROR_NONE_MAPPED);
2296 return FALSE;
2299 /******************************************************************************
2300 * SetFileSecurityA [ADVAPI32.@]
2302 * See SetFileSecurityW.
2304 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2305 SECURITY_INFORMATION RequestedInformation,
2306 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2308 BOOL r;
2309 LPWSTR name;
2311 name = SERV_dup(lpFileName);
2312 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2313 HeapFree( GetProcessHeap(), 0, name );
2315 return r;
2318 /******************************************************************************
2319 * SetFileSecurityW [ADVAPI32.@]
2321 * Sets the security of a file or directory.
2323 * PARAMS
2324 * lpFileName []
2325 * RequestedInformation []
2326 * pSecurityDescriptor []
2328 * RETURNS
2329 * Success: TRUE.
2330 * Failure: FALSE.
2332 BOOL WINAPI
2333 SetFileSecurityW( LPCWSTR lpFileName,
2334 SECURITY_INFORMATION RequestedInformation,
2335 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2337 HANDLE file;
2338 DWORD access = 0;
2339 NTSTATUS status;
2341 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2342 pSecurityDescriptor );
2344 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2345 RequestedInformation & GROUP_SECURITY_INFORMATION)
2346 access |= WRITE_OWNER;
2347 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2348 access |= ACCESS_SYSTEM_SECURITY;
2349 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2350 access |= WRITE_DAC;
2352 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2353 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2354 if (file == INVALID_HANDLE_VALUE)
2355 return FALSE;
2357 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2358 CloseHandle( file );
2359 return set_ntstatus( status );
2362 /******************************************************************************
2363 * QueryWindows31FilesMigration [ADVAPI32.@]
2365 * PARAMS
2366 * x1 []
2368 BOOL WINAPI
2369 QueryWindows31FilesMigration( DWORD x1 )
2371 FIXME("(%d):stub\n",x1);
2372 return TRUE;
2375 /******************************************************************************
2376 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2378 * PARAMS
2379 * x1 []
2380 * x2 []
2381 * x3 []
2382 * x4 []
2384 BOOL WINAPI
2385 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2386 DWORD x4 )
2388 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2389 return TRUE;
2392 /******************************************************************************
2393 * NotifyBootConfigStatus [ADVAPI32.@]
2395 * PARAMS
2396 * x1 []
2398 BOOL WINAPI
2399 NotifyBootConfigStatus( BOOL x1 )
2401 FIXME("(0x%08d):stub\n",x1);
2402 return 1;
2405 /******************************************************************************
2406 * RevertToSelf [ADVAPI32.@]
2408 * Ends the impersonation of a user.
2410 * PARAMS
2411 * void []
2413 * RETURNS
2414 * Success: TRUE.
2415 * Failure: FALSE.
2417 BOOL WINAPI
2418 RevertToSelf( void )
2420 HANDLE Token = NULL;
2421 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2422 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2425 /******************************************************************************
2426 * ImpersonateSelf [ADVAPI32.@]
2428 * Makes an impersonation token that represents the process user and assigns
2429 * to the current thread.
2431 * PARAMS
2432 * ImpersonationLevel [I] Level at which to impersonate.
2434 * RETURNS
2435 * Success: TRUE.
2436 * Failure: FALSE.
2438 BOOL WINAPI
2439 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2441 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2444 /******************************************************************************
2445 * ImpersonateLoggedOnUser [ADVAPI32.@]
2447 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2449 DWORD size;
2450 NTSTATUS Status;
2451 HANDLE ImpersonationToken;
2452 TOKEN_TYPE Type;
2453 static BOOL warn = TRUE;
2455 if (warn)
2457 FIXME( "(%p)\n", hToken );
2458 warn = FALSE;
2460 if (!GetTokenInformation( hToken, TokenType, &Type,
2461 sizeof(TOKEN_TYPE), &size ))
2462 return FALSE;
2464 if (Type == TokenPrimary)
2466 OBJECT_ATTRIBUTES ObjectAttributes;
2468 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2470 Status = NtDuplicateToken( hToken,
2471 TOKEN_IMPERSONATE | TOKEN_QUERY,
2472 &ObjectAttributes,
2473 SecurityImpersonation,
2474 TokenImpersonation,
2475 &ImpersonationToken );
2476 if (Status != STATUS_SUCCESS)
2478 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2479 SetLastError( RtlNtStatusToDosError( Status ) );
2480 return FALSE;
2483 else
2484 ImpersonationToken = hToken;
2486 Status = NtSetInformationThread( GetCurrentThread(),
2487 ThreadImpersonationToken,
2488 &ImpersonationToken,
2489 sizeof(ImpersonationToken) );
2491 if (Type == TokenPrimary)
2492 NtClose( ImpersonationToken );
2494 if (Status != STATUS_SUCCESS)
2496 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2497 SetLastError( RtlNtStatusToDosError( Status ) );
2498 return FALSE;
2501 return TRUE;
2504 /******************************************************************************
2505 * AccessCheck [ADVAPI32.@]
2507 BOOL WINAPI
2508 AccessCheck(
2509 PSECURITY_DESCRIPTOR SecurityDescriptor,
2510 HANDLE ClientToken,
2511 DWORD DesiredAccess,
2512 PGENERIC_MAPPING GenericMapping,
2513 PPRIVILEGE_SET PrivilegeSet,
2514 LPDWORD PrivilegeSetLength,
2515 LPDWORD GrantedAccess,
2516 LPBOOL AccessStatus)
2518 NTSTATUS access_status;
2519 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2520 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2521 GrantedAccess, &access_status) );
2522 if (ret) *AccessStatus = set_ntstatus( access_status );
2523 return ret;
2527 /******************************************************************************
2528 * AccessCheckByType [ADVAPI32.@]
2530 BOOL WINAPI AccessCheckByType(
2531 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2532 PSID PrincipalSelfSid,
2533 HANDLE ClientToken,
2534 DWORD DesiredAccess,
2535 POBJECT_TYPE_LIST ObjectTypeList,
2536 DWORD ObjectTypeListLength,
2537 PGENERIC_MAPPING GenericMapping,
2538 PPRIVILEGE_SET PrivilegeSet,
2539 LPDWORD PrivilegeSetLength,
2540 LPDWORD GrantedAccess,
2541 LPBOOL AccessStatus)
2543 FIXME("stub\n");
2545 *AccessStatus = TRUE;
2547 return !*AccessStatus;
2550 /******************************************************************************
2551 * MapGenericMask [ADVAPI32.@]
2553 * Maps generic access rights into specific access rights according to the
2554 * supplied mapping.
2556 * PARAMS
2557 * AccessMask [I/O] Access rights.
2558 * GenericMapping [I] The mapping between generic and specific rights.
2560 * RETURNS
2561 * Nothing.
2563 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2565 RtlMapGenericMask( AccessMask, GenericMapping );
2568 /*************************************************************************
2569 * SetKernelObjectSecurity [ADVAPI32.@]
2571 BOOL WINAPI SetKernelObjectSecurity (
2572 IN HANDLE Handle,
2573 IN SECURITY_INFORMATION SecurityInformation,
2574 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2576 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2580 /******************************************************************************
2581 * AddAuditAccessAce [ADVAPI32.@]
2583 BOOL WINAPI AddAuditAccessAce(
2584 IN OUT PACL pAcl,
2585 IN DWORD dwAceRevision,
2586 IN DWORD dwAccessMask,
2587 IN PSID pSid,
2588 IN BOOL bAuditSuccess,
2589 IN BOOL bAuditFailure)
2591 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2592 bAuditSuccess, bAuditFailure) );
2595 /******************************************************************************
2596 * AddAuditAccessAce [ADVAPI32.@]
2598 BOOL WINAPI AddAuditAccessAceEx(
2599 IN OUT PACL pAcl,
2600 IN DWORD dwAceRevision,
2601 IN DWORD dwAceFlags,
2602 IN DWORD dwAccessMask,
2603 IN PSID pSid,
2604 IN BOOL bAuditSuccess,
2605 IN BOOL bAuditFailure)
2607 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2608 bAuditSuccess, bAuditFailure) );
2611 /******************************************************************************
2612 * LookupAccountNameA [ADVAPI32.@]
2614 BOOL WINAPI
2615 LookupAccountNameA(
2616 IN LPCSTR system,
2617 IN LPCSTR account,
2618 OUT PSID sid,
2619 OUT LPDWORD cbSid,
2620 LPSTR ReferencedDomainName,
2621 IN OUT LPDWORD cbReferencedDomainName,
2622 OUT PSID_NAME_USE name_use )
2624 BOOL ret;
2625 UNICODE_STRING lpSystemW;
2626 UNICODE_STRING lpAccountW;
2627 LPWSTR lpReferencedDomainNameW = NULL;
2629 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2630 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2632 if (ReferencedDomainName)
2633 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2635 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2636 cbReferencedDomainName, name_use);
2638 if (ret && lpReferencedDomainNameW)
2640 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2641 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2644 RtlFreeUnicodeString(&lpSystemW);
2645 RtlFreeUnicodeString(&lpAccountW);
2646 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2648 return ret;
2651 /******************************************************************************
2652 * lookup_user_account_name
2654 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2655 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2657 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2658 DWORD len = sizeof(buffer);
2659 HANDLE token;
2660 BOOL ret;
2661 PSID pSid;
2662 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2663 DWORD nameLen;
2665 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2667 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2668 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2671 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2672 CloseHandle( token );
2674 if (!ret) return FALSE;
2676 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2678 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2679 CopySid(*cbSid, Sid, pSid);
2680 if (*cbSid < GetLengthSid(pSid))
2682 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2683 ret = FALSE;
2685 *cbSid = GetLengthSid(pSid);
2687 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2688 if (!GetComputerNameW(domainName, &nameLen))
2690 domainName[0] = 0;
2691 nameLen = 0;
2693 if (*cchReferencedDomainName <= nameLen || !ret)
2695 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2696 nameLen += 1;
2697 ret = FALSE;
2699 else if (ReferencedDomainName)
2700 strcpyW(ReferencedDomainName, domainName);
2702 *cchReferencedDomainName = nameLen;
2704 if (ret)
2705 *peUse = SidTypeUser;
2707 return ret;
2710 /******************************************************************************
2711 * lookup_computer_account_name
2713 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2714 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2716 MAX_SID local;
2717 BOOL ret;
2718 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2719 DWORD nameLen;
2721 if ((ret = ADVAPI_GetComputerSid(&local)))
2723 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2724 CopySid(*cbSid, Sid, &local);
2725 if (*cbSid < GetLengthSid(&local))
2727 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2728 ret = FALSE;
2730 *cbSid = GetLengthSid(&local);
2733 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2734 if (!GetComputerNameW(domainName, &nameLen))
2736 domainName[0] = 0;
2737 nameLen = 0;
2739 if (*cchReferencedDomainName <= nameLen || !ret)
2741 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2742 nameLen += 1;
2743 ret = FALSE;
2745 else if (ReferencedDomainName)
2746 strcpyW(ReferencedDomainName, domainName);
2748 *cchReferencedDomainName = nameLen;
2750 if (ret)
2751 *peUse = SidTypeDomain;
2753 return ret;
2756 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2757 LSA_UNICODE_STRING *domain )
2759 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2761 while (p > str->Buffer && *p != '\\') p--;
2763 if (*p == '\\')
2765 domain->Buffer = str->Buffer;
2766 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2768 account->Buffer = p + 1;
2769 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2771 else
2773 domain->Buffer = NULL;
2774 domain->Length = 0;
2776 account->Buffer = str->Buffer;
2777 account->Length = str->Length;
2781 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2783 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2785 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2786 return TRUE;
2788 return FALSE;
2791 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2793 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2795 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2796 return TRUE;
2798 if (ACCOUNT_SIDS[idx].alias)
2800 len = strlenW( ACCOUNT_SIDS[idx].alias );
2801 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2802 return TRUE;
2804 return FALSE;
2808 * Helper function for LookupAccountNameW
2810 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2811 PSID Sid, LPDWORD cbSid,
2812 LPWSTR ReferencedDomainName,
2813 LPDWORD cchReferencedDomainName,
2814 PSID_NAME_USE peUse, BOOL *handled )
2816 PSID pSid;
2817 LSA_UNICODE_STRING account, domain;
2818 BOOL ret = TRUE;
2819 ULONG i;
2821 *handled = FALSE;
2822 split_domain_account( account_and_domain, &account, &domain );
2824 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2826 /* check domain first */
2827 if (domain.Buffer && !match_domain( i, &domain )) continue;
2829 if (match_account( i, &account ))
2831 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2833 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2835 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2837 if (*cbSid < sidLen)
2839 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2840 ret = FALSE;
2842 else if (Sid)
2844 CopySid(*cbSid, Sid, pSid);
2846 *cbSid = sidLen;
2849 len = strlenW( ACCOUNT_SIDS[i].domain );
2850 if (*cchReferencedDomainName <= len || !ret)
2852 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2853 len++;
2854 ret = FALSE;
2856 else if (ReferencedDomainName)
2858 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2861 *cchReferencedDomainName = len;
2862 if (ret)
2863 *peUse = ACCOUNT_SIDS[i].name_use;
2865 HeapFree(GetProcessHeap(), 0, pSid);
2866 *handled = TRUE;
2867 return ret;
2870 return ret;
2873 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2874 PSID Sid, LPDWORD cbSid,
2875 LPWSTR ReferencedDomainName,
2876 LPDWORD cchReferencedDomainName,
2877 PSID_NAME_USE peUse, BOOL *handled )
2879 DWORD nameLen;
2880 LPWSTR userName = NULL;
2881 LSA_UNICODE_STRING account, domain;
2882 BOOL ret = TRUE;
2884 *handled = FALSE;
2885 split_domain_account( account_and_domain, &account, &domain );
2887 /* Let the current Unix user id masquerade as first Windows user account */
2889 nameLen = UNLEN + 1;
2890 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2892 if (domain.Buffer)
2894 /* check to make sure this account is on this computer */
2895 if (GetComputerNameW( userName, &nameLen ) &&
2896 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2898 SetLastError(ERROR_NONE_MAPPED);
2899 ret = FALSE;
2901 nameLen = UNLEN + 1;
2904 if (GetUserNameW( userName, &nameLen ) &&
2905 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2907 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2908 *handled = TRUE;
2910 else
2912 nameLen = UNLEN + 1;
2913 if (GetComputerNameW( userName, &nameLen ) &&
2914 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2916 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2917 *handled = TRUE;
2921 HeapFree(GetProcessHeap(), 0, userName);
2922 return ret;
2925 /******************************************************************************
2926 * LookupAccountNameW [ADVAPI32.@]
2928 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2929 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2930 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2932 BOOL ret, handled;
2933 LSA_UNICODE_STRING account;
2935 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2936 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2938 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2940 FIXME("remote computer not supported\n");
2941 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2942 return FALSE;
2945 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2947 lpAccountName = BUILTIN;
2950 RtlInitUnicodeString( &account, lpAccountName );
2952 /* Check well known SIDs first */
2953 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2954 cchReferencedDomainName, peUse, &handled );
2955 if (handled)
2956 return ret;
2958 /* Check user names */
2959 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2960 cchReferencedDomainName, peUse, &handled);
2961 if (handled)
2962 return ret;
2964 SetLastError( ERROR_NONE_MAPPED );
2965 return FALSE;
2968 /******************************************************************************
2969 * PrivilegeCheck [ADVAPI32.@]
2971 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2973 BOOL ret;
2974 BOOLEAN Result;
2976 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2978 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2979 if (ret)
2980 *pfResult = Result;
2981 return ret;
2984 /******************************************************************************
2985 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2987 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2988 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2989 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2990 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2992 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2993 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2994 SecurityDescriptor, DesiredAccess, GenericMapping,
2995 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2996 return TRUE;
2999 /******************************************************************************
3000 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3002 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3003 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3004 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3005 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3007 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3008 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3009 SecurityDescriptor, DesiredAccess, GenericMapping,
3010 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3011 return TRUE;
3014 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3016 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3018 return TRUE;
3021 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3023 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3025 return TRUE;
3028 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3030 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3032 return TRUE;
3035 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3036 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3037 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3038 LPBOOL GenerateOnClose)
3040 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3041 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3042 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3043 GenerateOnClose);
3045 return TRUE;
3048 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3049 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3050 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3051 LPBOOL GenerateOnClose)
3053 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3054 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3055 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3056 GenerateOnClose);
3058 return TRUE;
3061 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3062 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3064 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3065 DesiredAccess, Privileges, AccessGranted);
3067 return TRUE;
3070 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3071 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3073 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3074 DesiredAccess, Privileges, AccessGranted);
3076 return TRUE;
3079 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3080 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3082 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3083 ClientToken, Privileges, AccessGranted);
3085 return TRUE;
3088 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3089 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3091 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3092 ClientToken, Privileges, AccessGranted);
3094 return TRUE;
3097 /******************************************************************************
3098 * GetSecurityInfo [ADVAPI32.@]
3100 * Retrieves a copy of the security descriptor associated with an object.
3102 * PARAMS
3103 * hObject [I] A handle for the object.
3104 * ObjectType [I] The type of object.
3105 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3106 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3107 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3108 * ppDacl [O] If non-null, receives a pointer to the DACL.
3109 * ppSacl [O] If non-null, receives a pointer to the SACL.
3110 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3111 * which must be freed with LocalFree.
3113 * RETURNS
3114 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3116 DWORD WINAPI GetSecurityInfo(
3117 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3118 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3119 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3120 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3123 PSECURITY_DESCRIPTOR sd;
3124 NTSTATUS status;
3125 ULONG n1, n2;
3126 BOOL present, defaulted;
3128 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3129 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3131 /* If no descriptor, we have to check that there's a pointer for the requested information */
3132 if( !ppSecurityDescriptor && (
3133 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3134 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3135 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3136 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3137 return ERROR_INVALID_PARAMETER;
3139 switch (ObjectType)
3141 case SE_SERVICE:
3142 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3143 break;
3144 default:
3145 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3146 break;
3148 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3149 return RtlNtStatusToDosError(status);
3151 sd = LocalAlloc(0, n1);
3152 if (!sd)
3153 return ERROR_NOT_ENOUGH_MEMORY;
3155 switch (ObjectType)
3157 case SE_SERVICE:
3158 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3159 break;
3160 default:
3161 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3162 break;
3164 if (status != STATUS_SUCCESS)
3166 LocalFree(sd);
3167 return RtlNtStatusToDosError(status);
3170 if (ppsidOwner)
3172 *ppsidOwner = NULL;
3173 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3175 if (ppsidGroup)
3177 *ppsidGroup = NULL;
3178 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3180 if (ppDacl)
3182 *ppDacl = NULL;
3183 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3185 if (ppSacl)
3187 *ppSacl = NULL;
3188 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3190 if (ppSecurityDescriptor)
3191 *ppSecurityDescriptor = sd;
3193 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3194 * NULL, because native happily returns the SIDs and ACLs that are requested
3195 * in this case.
3198 return ERROR_SUCCESS;
3201 /******************************************************************************
3202 * GetSecurityInfoExA [ADVAPI32.@]
3204 DWORD WINAPI GetSecurityInfoExA(
3205 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3206 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3207 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3208 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3211 FIXME("stub!\n");
3212 return ERROR_BAD_PROVIDER;
3215 /******************************************************************************
3216 * GetSecurityInfoExW [ADVAPI32.@]
3218 DWORD WINAPI GetSecurityInfoExW(
3219 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3220 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3221 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3222 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3225 FIXME("stub!\n");
3226 return ERROR_BAD_PROVIDER;
3229 /******************************************************************************
3230 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3232 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3233 LPSTR pTrusteeName, DWORD AccessPermissions,
3234 ACCESS_MODE AccessMode, DWORD Inheritance )
3236 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3237 AccessPermissions, AccessMode, Inheritance);
3239 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3240 pExplicitAccess->grfAccessMode = AccessMode;
3241 pExplicitAccess->grfInheritance = Inheritance;
3243 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3244 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3245 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3246 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3247 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3250 /******************************************************************************
3251 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3253 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3254 LPWSTR pTrusteeName, DWORD AccessPermissions,
3255 ACCESS_MODE AccessMode, DWORD Inheritance )
3257 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3258 AccessPermissions, AccessMode, Inheritance);
3260 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3261 pExplicitAccess->grfAccessMode = AccessMode;
3262 pExplicitAccess->grfInheritance = Inheritance;
3264 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3265 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3266 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3267 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3268 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3271 /******************************************************************************
3272 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3274 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3275 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3276 LPSTR InheritedObjectTypeName, LPSTR Name )
3278 DWORD ObjectsPresent = 0;
3280 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3281 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3283 /* Fill the OBJECTS_AND_NAME structure */
3284 pObjName->ObjectType = ObjectType;
3285 if (ObjectTypeName != NULL)
3287 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3290 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3291 if (InheritedObjectTypeName != NULL)
3293 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3296 pObjName->ObjectsPresent = ObjectsPresent;
3297 pObjName->ptstrName = Name;
3299 /* Fill the TRUSTEE structure */
3300 pTrustee->pMultipleTrustee = NULL;
3301 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3302 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3303 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3304 pTrustee->ptstrName = (LPSTR)pObjName;
3307 /******************************************************************************
3308 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3310 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3311 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3312 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3314 DWORD ObjectsPresent = 0;
3316 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3317 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3319 /* Fill the OBJECTS_AND_NAME structure */
3320 pObjName->ObjectType = ObjectType;
3321 if (ObjectTypeName != NULL)
3323 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3326 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3327 if (InheritedObjectTypeName != NULL)
3329 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3332 pObjName->ObjectsPresent = ObjectsPresent;
3333 pObjName->ptstrName = Name;
3335 /* Fill the TRUSTEE structure */
3336 pTrustee->pMultipleTrustee = NULL;
3337 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3338 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3339 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3340 pTrustee->ptstrName = (LPWSTR)pObjName;
3343 /******************************************************************************
3344 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3346 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3347 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3349 DWORD ObjectsPresent = 0;
3351 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3353 /* Fill the OBJECTS_AND_SID structure */
3354 if (pObjectGuid != NULL)
3356 pObjSid->ObjectTypeGuid = *pObjectGuid;
3357 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3359 else
3361 ZeroMemory(&pObjSid->ObjectTypeGuid,
3362 sizeof(GUID));
3365 if (pInheritedObjectGuid != NULL)
3367 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3368 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3370 else
3372 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3373 sizeof(GUID));
3376 pObjSid->ObjectsPresent = ObjectsPresent;
3377 pObjSid->pSid = pSid;
3379 /* Fill the TRUSTEE structure */
3380 pTrustee->pMultipleTrustee = NULL;
3381 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3382 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3383 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3384 pTrustee->ptstrName = (LPSTR) pObjSid;
3387 /******************************************************************************
3388 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3390 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3391 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3393 DWORD ObjectsPresent = 0;
3395 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3397 /* Fill the OBJECTS_AND_SID structure */
3398 if (pObjectGuid != NULL)
3400 pObjSid->ObjectTypeGuid = *pObjectGuid;
3401 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3403 else
3405 ZeroMemory(&pObjSid->ObjectTypeGuid,
3406 sizeof(GUID));
3409 if (pInheritedObjectGuid != NULL)
3411 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3412 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3414 else
3416 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3417 sizeof(GUID));
3420 pObjSid->ObjectsPresent = ObjectsPresent;
3421 pObjSid->pSid = pSid;
3423 /* Fill the TRUSTEE structure */
3424 pTrustee->pMultipleTrustee = NULL;
3425 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3426 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3427 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3428 pTrustee->ptstrName = (LPWSTR) pObjSid;
3431 /******************************************************************************
3432 * BuildTrusteeWithSidA [ADVAPI32.@]
3434 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3436 TRACE("%p %p\n", pTrustee, pSid);
3438 pTrustee->pMultipleTrustee = NULL;
3439 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3440 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3441 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3442 pTrustee->ptstrName = pSid;
3445 /******************************************************************************
3446 * BuildTrusteeWithSidW [ADVAPI32.@]
3448 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3450 TRACE("%p %p\n", pTrustee, pSid);
3452 pTrustee->pMultipleTrustee = NULL;
3453 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3454 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3455 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3456 pTrustee->ptstrName = pSid;
3459 /******************************************************************************
3460 * BuildTrusteeWithNameA [ADVAPI32.@]
3462 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3464 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3466 pTrustee->pMultipleTrustee = NULL;
3467 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3468 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3469 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3470 pTrustee->ptstrName = name;
3473 /******************************************************************************
3474 * BuildTrusteeWithNameW [ADVAPI32.@]
3476 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3478 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3480 pTrustee->pMultipleTrustee = NULL;
3481 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3482 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3483 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3484 pTrustee->ptstrName = name;
3487 /******************************************************************************
3488 * GetTrusteeFormA [ADVAPI32.@]
3490 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3492 TRACE("(%p)\n", pTrustee);
3494 if (!pTrustee)
3495 return TRUSTEE_BAD_FORM;
3497 return pTrustee->TrusteeForm;
3500 /******************************************************************************
3501 * GetTrusteeFormW [ADVAPI32.@]
3503 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3505 TRACE("(%p)\n", pTrustee);
3507 if (!pTrustee)
3508 return TRUSTEE_BAD_FORM;
3510 return pTrustee->TrusteeForm;
3513 /******************************************************************************
3514 * GetTrusteeNameA [ADVAPI32.@]
3516 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3518 TRACE("(%p)\n", pTrustee);
3520 if (!pTrustee)
3521 return NULL;
3523 return pTrustee->ptstrName;
3526 /******************************************************************************
3527 * GetTrusteeNameW [ADVAPI32.@]
3529 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3531 TRACE("(%p)\n", pTrustee);
3533 if (!pTrustee)
3534 return NULL;
3536 return pTrustee->ptstrName;
3539 /******************************************************************************
3540 * GetTrusteeTypeA [ADVAPI32.@]
3542 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3544 TRACE("(%p)\n", pTrustee);
3546 if (!pTrustee)
3547 return TRUSTEE_IS_UNKNOWN;
3549 return pTrustee->TrusteeType;
3552 /******************************************************************************
3553 * GetTrusteeTypeW [ADVAPI32.@]
3555 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3557 TRACE("(%p)\n", pTrustee);
3559 if (!pTrustee)
3560 return TRUSTEE_IS_UNKNOWN;
3562 return pTrustee->TrusteeType;
3565 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3566 DWORD nAclInformationLength,
3567 ACL_INFORMATION_CLASS dwAclInformationClass )
3569 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3570 nAclInformationLength, dwAclInformationClass);
3572 return TRUE;
3575 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3577 switch (form)
3579 case TRUSTEE_IS_NAME:
3581 *ptrustee_nameW = SERV_dup(trustee_nameA);
3582 return ERROR_SUCCESS;
3584 case TRUSTEE_IS_OBJECTS_AND_NAME:
3586 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3587 OBJECTS_AND_NAME_W *objW = NULL;
3589 if (objA)
3591 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3592 return ERROR_NOT_ENOUGH_MEMORY;
3594 objW->ObjectsPresent = objA->ObjectsPresent;
3595 objW->ObjectType = objA->ObjectType;
3596 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3597 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3598 objW->ptstrName = SERV_dup(objA->ptstrName);
3601 *ptrustee_nameW = (WCHAR *)objW;
3602 return ERROR_SUCCESS;
3604 /* These forms do not require conversion. */
3605 case TRUSTEE_IS_SID:
3606 case TRUSTEE_IS_OBJECTS_AND_SID:
3607 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3608 return ERROR_SUCCESS;
3609 default:
3610 return ERROR_INVALID_PARAMETER;
3614 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3616 switch (form)
3618 case TRUSTEE_IS_NAME:
3619 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3620 break;
3621 case TRUSTEE_IS_OBJECTS_AND_NAME:
3623 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3625 if (objW)
3627 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3628 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3629 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3630 HeapFree( GetProcessHeap(), 0, objW );
3633 break;
3635 /* Other forms did not require allocation, so no freeing is necessary. */
3636 default:
3637 break;
3641 /******************************************************************************
3642 * SetEntriesInAclA [ADVAPI32.@]
3644 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3645 PACL OldAcl, PACL* NewAcl )
3647 DWORD err = ERROR_SUCCESS;
3648 EXPLICIT_ACCESSW *pEntriesW;
3649 UINT alloc_index, free_index;
3651 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3653 if (NewAcl)
3654 *NewAcl = NULL;
3656 if (!count && !OldAcl)
3657 return ERROR_SUCCESS;
3659 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3660 if (!pEntriesW)
3661 return ERROR_NOT_ENOUGH_MEMORY;
3663 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3665 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3666 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3667 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3668 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3669 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3670 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3671 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3673 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3674 pEntries[alloc_index].Trustee.ptstrName,
3675 &pEntriesW[alloc_index].Trustee.ptstrName );
3676 if (err != ERROR_SUCCESS)
3678 if (err == ERROR_INVALID_PARAMETER)
3679 WARN("bad trustee form %d for trustee %d\n",
3680 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3682 goto cleanup;
3686 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3688 cleanup:
3689 /* Free any previously allocated trustee name buffers, taking into account
3690 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3691 * list. */
3692 for (free_index = 0; free_index < alloc_index; ++free_index)
3693 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3695 HeapFree( GetProcessHeap(), 0, pEntriesW );
3696 return err;
3699 /******************************************************************************
3700 * SetEntriesInAclW [ADVAPI32.@]
3702 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3703 PACL OldAcl, PACL* NewAcl )
3705 ULONG i;
3706 PSID *ppsid;
3707 DWORD ret = ERROR_SUCCESS;
3708 DWORD acl_size = sizeof(ACL);
3709 NTSTATUS status;
3711 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3713 if (NewAcl)
3714 *NewAcl = NULL;
3716 if (!count && !OldAcl)
3717 return ERROR_SUCCESS;
3719 /* allocate array of maximum sized sids allowed */
3720 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3721 if (!ppsid)
3722 return ERROR_OUTOFMEMORY;
3724 for (i = 0; i < count; i++)
3726 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3728 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3729 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3730 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3731 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3732 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3733 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3734 pEntries[i].Trustee.ptstrName);
3736 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3738 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3739 ret = ERROR_INVALID_PARAMETER;
3740 goto exit;
3743 switch (pEntries[i].Trustee.TrusteeForm)
3745 case TRUSTEE_IS_SID:
3746 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3747 ppsid[i], pEntries[i].Trustee.ptstrName))
3749 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3750 ret = ERROR_INVALID_PARAMETER;
3751 goto exit;
3753 break;
3754 case TRUSTEE_IS_NAME:
3756 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3757 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3758 SID_NAME_USE use;
3759 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3761 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3763 ret = GetLastError();
3764 goto exit;
3767 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3769 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3770 ret = ERROR_INVALID_PARAMETER;
3771 goto exit;
3773 break;
3775 case TRUSTEE_IS_OBJECTS_AND_SID:
3776 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3777 break;
3778 case TRUSTEE_IS_OBJECTS_AND_NAME:
3779 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3780 break;
3781 default:
3782 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3783 ret = ERROR_INVALID_PARAMETER;
3784 goto exit;
3787 /* Note: we overestimate the ACL size here as a tradeoff between
3788 * instructions (simplicity) and memory */
3789 switch (pEntries[i].grfAccessMode)
3791 case GRANT_ACCESS:
3792 case SET_ACCESS:
3793 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3794 break;
3795 case DENY_ACCESS:
3796 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3797 break;
3798 case SET_AUDIT_SUCCESS:
3799 case SET_AUDIT_FAILURE:
3800 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3801 break;
3802 case REVOKE_ACCESS:
3803 break;
3804 default:
3805 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3806 ret = ERROR_INVALID_PARAMETER;
3807 goto exit;
3811 if (OldAcl)
3813 ACL_SIZE_INFORMATION size_info;
3815 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3816 if (status != STATUS_SUCCESS)
3818 ret = RtlNtStatusToDosError(status);
3819 goto exit;
3821 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3824 *NewAcl = LocalAlloc(0, acl_size);
3825 if (!*NewAcl)
3827 ret = ERROR_OUTOFMEMORY;
3828 goto exit;
3831 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3832 if (status != STATUS_SUCCESS)
3834 ret = RtlNtStatusToDosError(status);
3835 goto exit;
3838 for (i = 0; i < count; i++)
3840 switch (pEntries[i].grfAccessMode)
3842 case GRANT_ACCESS:
3843 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3844 pEntries[i].grfInheritance,
3845 pEntries[i].grfAccessPermissions,
3846 ppsid[i]);
3847 break;
3848 case SET_ACCESS:
3850 ULONG j;
3851 BOOL add = TRUE;
3852 if (OldAcl)
3854 for (j = 0; ; j++)
3856 const ACE_HEADER *existing_ace_header;
3857 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3858 if (status != STATUS_SUCCESS)
3859 break;
3860 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3861 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3862 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3864 add = FALSE;
3865 break;
3869 if (add)
3870 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3871 pEntries[i].grfInheritance,
3872 pEntries[i].grfAccessPermissions,
3873 ppsid[i]);
3874 break;
3876 case DENY_ACCESS:
3877 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3878 pEntries[i].grfInheritance,
3879 pEntries[i].grfAccessPermissions,
3880 ppsid[i]);
3881 break;
3882 case SET_AUDIT_SUCCESS:
3883 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3884 pEntries[i].grfInheritance,
3885 pEntries[i].grfAccessPermissions,
3886 ppsid[i], TRUE, FALSE);
3887 break;
3888 case SET_AUDIT_FAILURE:
3889 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3890 pEntries[i].grfInheritance,
3891 pEntries[i].grfAccessPermissions,
3892 ppsid[i], FALSE, TRUE);
3893 break;
3894 default:
3895 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3899 if (OldAcl)
3901 for (i = 0; ; i++)
3903 BOOL add = TRUE;
3904 ULONG j;
3905 const ACE_HEADER *old_ace_header;
3906 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3907 if (status != STATUS_SUCCESS) break;
3908 for (j = 0; j < count; j++)
3910 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3911 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3912 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3914 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3915 add = FALSE;
3916 break;
3918 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3920 switch (old_ace_header->AceType)
3922 case ACCESS_ALLOWED_ACE_TYPE:
3923 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3924 add = FALSE;
3925 break;
3926 case ACCESS_DENIED_ACE_TYPE:
3927 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3928 add = FALSE;
3929 break;
3930 case SYSTEM_AUDIT_ACE_TYPE:
3931 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3932 add = FALSE;
3933 break;
3934 case SYSTEM_ALARM_ACE_TYPE:
3935 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3936 add = FALSE;
3937 break;
3938 default:
3939 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3942 if (!add)
3943 break;
3946 if (add)
3947 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3948 if (status != STATUS_SUCCESS)
3950 WARN("RtlAddAce failed with error 0x%08x\n", status);
3951 ret = RtlNtStatusToDosError(status);
3952 break;
3957 exit:
3958 HeapFree(GetProcessHeap(), 0, ppsid);
3959 return ret;
3962 /******************************************************************************
3963 * SetNamedSecurityInfoA [ADVAPI32.@]
3965 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3966 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3967 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3969 LPWSTR wstr;
3970 DWORD r;
3972 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3973 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3975 wstr = SERV_dup(pObjectName);
3976 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3977 psidGroup, pDacl, pSacl );
3979 HeapFree( GetProcessHeap(), 0, wstr );
3981 return r;
3984 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3985 PSECURITY_DESCRIPTOR ModificationDescriptor,
3986 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3987 PGENERIC_MAPPING GenericMapping,
3988 HANDLE Token )
3990 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3991 ObjectsSecurityDescriptor, GenericMapping, Token);
3993 return TRUE;
3996 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3998 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4001 /******************************************************************************
4002 * AreAnyAccessesGranted [ADVAPI32.@]
4004 * Determines whether or not any of a set of specified access permissions have
4005 * been granted or not.
4007 * PARAMS
4008 * GrantedAccess [I] The permissions that have been granted.
4009 * DesiredAccess [I] The permissions that you want to have.
4011 * RETURNS
4012 * Nonzero if any of the permissions have been granted, zero if none of the
4013 * permissions have been granted.
4016 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4018 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4021 /******************************************************************************
4022 * SetNamedSecurityInfoW [ADVAPI32.@]
4024 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4025 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4026 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4028 DWORD access = 0;
4029 HANDLE handle;
4030 DWORD err;
4032 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4033 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4035 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4037 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4038 access |= WRITE_OWNER;
4039 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4040 access |= WRITE_DAC;
4041 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4042 access |= ACCESS_SYSTEM_SECURITY;
4044 switch (ObjectType)
4046 case SE_SERVICE:
4047 if (!(err = get_security_service( pObjectName, access, &handle )))
4049 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4050 CloseServiceHandle( handle );
4052 break;
4053 case SE_REGISTRY_KEY:
4054 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4056 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4057 RegCloseKey( handle );
4059 break;
4060 case SE_FILE_OBJECT:
4061 if (!(err = get_security_file( pObjectName, access, &handle )))
4063 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4064 CloseHandle( handle );
4066 break;
4067 default:
4068 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4069 return ERROR_SUCCESS;
4071 return err;
4074 /******************************************************************************
4075 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4077 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4078 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4080 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4081 return ERROR_CALL_NOT_IMPLEMENTED;
4084 /******************************************************************************
4085 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4087 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4088 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4090 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4091 return ERROR_CALL_NOT_IMPLEMENTED;
4094 /******************************************************************************
4095 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4097 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4098 PACCESS_MASK pFailedAuditRights)
4100 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4101 return ERROR_CALL_NOT_IMPLEMENTED;
4105 /******************************************************************************
4106 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4108 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4109 PACCESS_MASK pFailedAuditRights)
4111 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4112 return ERROR_CALL_NOT_IMPLEMENTED;
4116 /******************************************************************************
4117 * ParseAclStringFlags
4119 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4121 DWORD flags = 0;
4122 LPCWSTR szAcl = *StringAcl;
4124 while (*szAcl != '(')
4126 if (*szAcl == 'P')
4128 flags |= SE_DACL_PROTECTED;
4130 else if (*szAcl == 'A')
4132 szAcl++;
4133 if (*szAcl == 'R')
4134 flags |= SE_DACL_AUTO_INHERIT_REQ;
4135 else if (*szAcl == 'I')
4136 flags |= SE_DACL_AUTO_INHERITED;
4138 szAcl++;
4141 *StringAcl = szAcl;
4142 return flags;
4145 /******************************************************************************
4146 * ParseAceStringType
4148 static const ACEFLAG AceType[] =
4150 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4151 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4152 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4153 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4155 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4156 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4157 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4158 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4160 { NULL, 0 },
4163 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4165 UINT len = 0;
4166 LPCWSTR szAcl = *StringAcl;
4167 const ACEFLAG *lpaf = AceType;
4169 while (*szAcl == ' ')
4170 szAcl++;
4172 while (lpaf->wstr &&
4173 (len = strlenW(lpaf->wstr)) &&
4174 strncmpW(lpaf->wstr, szAcl, len))
4175 lpaf++;
4177 if (!lpaf->wstr)
4178 return 0;
4180 *StringAcl = szAcl + len;
4181 return lpaf->value;
4185 /******************************************************************************
4186 * ParseAceStringFlags
4188 static const ACEFLAG AceFlags[] =
4190 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4191 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4192 { SDDL_INHERITED, INHERITED_ACE },
4193 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4194 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4195 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4196 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4197 { NULL, 0 },
4200 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4202 UINT len = 0;
4203 BYTE flags = 0;
4204 LPCWSTR szAcl = *StringAcl;
4206 while (*szAcl == ' ')
4207 szAcl++;
4209 while (*szAcl != ';')
4211 const ACEFLAG *lpaf = AceFlags;
4213 while (lpaf->wstr &&
4214 (len = strlenW(lpaf->wstr)) &&
4215 strncmpW(lpaf->wstr, szAcl, len))
4216 lpaf++;
4218 if (!lpaf->wstr)
4219 return 0;
4221 flags |= lpaf->value;
4222 szAcl += len;
4225 *StringAcl = szAcl;
4226 return flags;
4230 /******************************************************************************
4231 * ParseAceStringRights
4233 static const ACEFLAG AceRights[] =
4235 { SDDL_GENERIC_ALL, GENERIC_ALL },
4236 { SDDL_GENERIC_READ, GENERIC_READ },
4237 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4238 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4240 { SDDL_READ_CONTROL, READ_CONTROL },
4241 { SDDL_STANDARD_DELETE, DELETE },
4242 { SDDL_WRITE_DAC, WRITE_DAC },
4243 { SDDL_WRITE_OWNER, WRITE_OWNER },
4245 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4246 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4247 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4248 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4249 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4250 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4251 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4252 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4253 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4255 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4256 { SDDL_FILE_READ, FILE_GENERIC_READ },
4257 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4258 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4260 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4261 { SDDL_KEY_READ, KEY_READ },
4262 { SDDL_KEY_WRITE, KEY_WRITE },
4263 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4264 { NULL, 0 },
4267 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4269 UINT len = 0;
4270 DWORD rights = 0;
4271 LPCWSTR szAcl = *StringAcl;
4273 while (*szAcl == ' ')
4274 szAcl++;
4276 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4278 LPCWSTR p = szAcl;
4280 while (*p && *p != ';')
4281 p++;
4283 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4285 rights = strtoulW(szAcl, NULL, 16);
4286 szAcl = p;
4288 else
4289 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4291 else
4293 while (*szAcl != ';')
4295 const ACEFLAG *lpaf = AceRights;
4297 while (lpaf->wstr &&
4298 (len = strlenW(lpaf->wstr)) &&
4299 strncmpW(lpaf->wstr, szAcl, len))
4301 lpaf++;
4304 if (!lpaf->wstr)
4305 return 0;
4307 rights |= lpaf->value;
4308 szAcl += len;
4312 *StringAcl = szAcl;
4313 return rights;
4317 /******************************************************************************
4318 * ParseStringAclToAcl
4320 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4322 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4323 PACL pAcl, LPDWORD cBytes)
4325 DWORD val;
4326 DWORD sidlen;
4327 DWORD length = sizeof(ACL);
4328 DWORD acesize = 0;
4329 DWORD acecount = 0;
4330 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4331 DWORD error = ERROR_INVALID_ACL;
4333 TRACE("%s\n", debugstr_w(StringAcl));
4335 if (!StringAcl)
4336 return FALSE;
4338 if (pAcl) /* pAce is only useful if we're setting values */
4339 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4341 /* Parse ACL flags */
4342 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4344 /* Parse ACE */
4345 while (*StringAcl == '(')
4347 StringAcl++;
4349 /* Parse ACE type */
4350 val = ParseAceStringType(&StringAcl);
4351 if (pAce)
4352 pAce->Header.AceType = (BYTE) val;
4353 if (*StringAcl != ';')
4355 error = RPC_S_INVALID_STRING_UUID;
4356 goto lerr;
4358 StringAcl++;
4360 /* Parse ACE flags */
4361 val = ParseAceStringFlags(&StringAcl);
4362 if (pAce)
4363 pAce->Header.AceFlags = (BYTE) val;
4364 if (*StringAcl != ';')
4365 goto lerr;
4366 StringAcl++;
4368 /* Parse ACE rights */
4369 val = ParseAceStringRights(&StringAcl);
4370 if (pAce)
4371 pAce->Mask = val;
4372 if (*StringAcl != ';')
4373 goto lerr;
4374 StringAcl++;
4376 /* Parse ACE object guid */
4377 while (*StringAcl == ' ')
4378 StringAcl++;
4379 if (*StringAcl != ';')
4381 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4382 goto lerr;
4384 StringAcl++;
4386 /* Parse ACE inherit object guid */
4387 while (*StringAcl == ' ')
4388 StringAcl++;
4389 if (*StringAcl != ';')
4391 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4392 goto lerr;
4394 StringAcl++;
4396 /* Parse ACE account sid */
4397 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4399 while (*StringAcl && *StringAcl != ')')
4400 StringAcl++;
4403 if (*StringAcl != ')')
4404 goto lerr;
4405 StringAcl++;
4407 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4408 length += acesize;
4409 if (pAce)
4411 pAce->Header.AceSize = acesize;
4412 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4414 acecount++;
4417 *cBytes = length;
4419 if (length > 0xffff)
4421 ERR("ACL too large\n");
4422 goto lerr;
4425 if (pAcl)
4427 pAcl->AclRevision = ACL_REVISION;
4428 pAcl->Sbz1 = 0;
4429 pAcl->AclSize = length;
4430 pAcl->AceCount = acecount++;
4431 pAcl->Sbz2 = 0;
4433 return TRUE;
4435 lerr:
4436 SetLastError(error);
4437 WARN("Invalid ACE string format\n");
4438 return FALSE;
4442 /******************************************************************************
4443 * ParseStringSecurityDescriptorToSecurityDescriptor
4445 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4446 LPCWSTR StringSecurityDescriptor,
4447 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4448 LPDWORD cBytes)
4450 BOOL bret = FALSE;
4451 WCHAR toktype;
4452 WCHAR tok[MAX_PATH];
4453 LPCWSTR lptoken;
4454 LPBYTE lpNext = NULL;
4455 DWORD len;
4457 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4459 if (SecurityDescriptor)
4460 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4462 while (*StringSecurityDescriptor == ' ')
4463 StringSecurityDescriptor++;
4465 while (*StringSecurityDescriptor)
4467 toktype = *StringSecurityDescriptor;
4469 /* Expect char identifier followed by ':' */
4470 StringSecurityDescriptor++;
4471 if (*StringSecurityDescriptor != ':')
4473 SetLastError(ERROR_INVALID_PARAMETER);
4474 goto lend;
4476 StringSecurityDescriptor++;
4478 /* Extract token */
4479 lptoken = StringSecurityDescriptor;
4480 while (*lptoken && *lptoken != ':')
4481 lptoken++;
4483 if (*lptoken)
4484 lptoken--;
4486 len = lptoken - StringSecurityDescriptor;
4487 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4488 tok[len] = 0;
4490 switch (toktype)
4492 case 'O':
4494 DWORD bytes;
4496 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4497 goto lend;
4499 if (SecurityDescriptor)
4501 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4502 lpNext += bytes; /* Advance to next token */
4505 *cBytes += bytes;
4507 break;
4510 case 'G':
4512 DWORD bytes;
4514 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4515 goto lend;
4517 if (SecurityDescriptor)
4519 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4520 lpNext += bytes; /* Advance to next token */
4523 *cBytes += bytes;
4525 break;
4528 case 'D':
4530 DWORD flags;
4531 DWORD bytes;
4533 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4534 goto lend;
4536 if (SecurityDescriptor)
4538 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4539 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4540 lpNext += bytes; /* Advance to next token */
4543 *cBytes += bytes;
4545 break;
4548 case 'S':
4550 DWORD flags;
4551 DWORD bytes;
4553 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4554 goto lend;
4556 if (SecurityDescriptor)
4558 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4559 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4560 lpNext += bytes; /* Advance to next token */
4563 *cBytes += bytes;
4565 break;
4568 default:
4569 FIXME("Unknown token\n");
4570 SetLastError(ERROR_INVALID_PARAMETER);
4571 goto lend;
4574 StringSecurityDescriptor = lptoken;
4577 bret = TRUE;
4579 lend:
4580 return bret;
4583 /******************************************************************************
4584 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4586 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4587 LPCSTR StringSecurityDescriptor,
4588 DWORD StringSDRevision,
4589 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4590 PULONG SecurityDescriptorSize)
4592 BOOL ret;
4593 LPWSTR StringSecurityDescriptorW;
4595 if(!StringSecurityDescriptor)
4596 return FALSE;
4598 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4599 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4600 StringSDRevision, SecurityDescriptor,
4601 SecurityDescriptorSize);
4602 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4604 return ret;
4607 /******************************************************************************
4608 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4610 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4611 LPCWSTR StringSecurityDescriptor,
4612 DWORD StringSDRevision,
4613 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4614 PULONG SecurityDescriptorSize)
4616 DWORD cBytes;
4617 SECURITY_DESCRIPTOR* psd;
4618 BOOL bret = FALSE;
4620 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4622 if (GetVersion() & 0x80000000)
4624 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4625 goto lend;
4627 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4629 SetLastError(ERROR_INVALID_PARAMETER);
4630 goto lend;
4632 else if (StringSDRevision != SID_REVISION)
4634 SetLastError(ERROR_UNKNOWN_REVISION);
4635 goto lend;
4638 /* Compute security descriptor length */
4639 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4640 NULL, &cBytes))
4641 goto lend;
4643 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4644 if (!psd) goto lend;
4646 psd->Revision = SID_REVISION;
4647 psd->Control |= SE_SELF_RELATIVE;
4649 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4650 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4652 LocalFree(psd);
4653 goto lend;
4656 if (SecurityDescriptorSize)
4657 *SecurityDescriptorSize = cBytes;
4659 bret = TRUE;
4661 lend:
4662 TRACE(" ret=%d\n", bret);
4663 return bret;
4666 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4668 if (cch == -1)
4669 cch = strlenW(string);
4671 if (plen)
4672 *plen += cch;
4674 if (pwptr)
4676 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4677 *pwptr += cch;
4681 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4683 DWORD i;
4684 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4685 WCHAR subauthfmt[] = { '-','%','u',0 };
4686 WCHAR buf[26];
4687 SID *pisid = psid;
4689 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4691 SetLastError(ERROR_INVALID_SID);
4692 return FALSE;
4695 if (pisid->IdentifierAuthority.Value[0] ||
4696 pisid->IdentifierAuthority.Value[1])
4698 FIXME("not matching MS' bugs\n");
4699 SetLastError(ERROR_INVALID_SID);
4700 return FALSE;
4703 sprintfW( buf, fmt, pisid->Revision,
4704 MAKELONG(
4705 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4706 pisid->IdentifierAuthority.Value[4] ),
4707 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4708 pisid->IdentifierAuthority.Value[2] )
4709 ) );
4710 DumpString(buf, -1, pwptr, plen);
4712 for( i=0; i<pisid->SubAuthorityCount; i++ )
4714 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4715 DumpString(buf, -1, pwptr, plen);
4717 return TRUE;
4720 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4722 size_t i;
4723 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4725 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4727 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4728 return TRUE;
4732 return DumpSidNumeric(psid, pwptr, plen);
4735 static const LPCWSTR AceRightBitNames[32] = {
4736 SDDL_CREATE_CHILD, /* 0 */
4737 SDDL_DELETE_CHILD,
4738 SDDL_LIST_CHILDREN,
4739 SDDL_SELF_WRITE,
4740 SDDL_READ_PROPERTY, /* 4 */
4741 SDDL_WRITE_PROPERTY,
4742 SDDL_DELETE_TREE,
4743 SDDL_LIST_OBJECT,
4744 SDDL_CONTROL_ACCESS, /* 8 */
4745 NULL,
4746 NULL,
4747 NULL,
4748 NULL, /* 12 */
4749 NULL,
4750 NULL,
4751 NULL,
4752 SDDL_STANDARD_DELETE, /* 16 */
4753 SDDL_READ_CONTROL,
4754 SDDL_WRITE_DAC,
4755 SDDL_WRITE_OWNER,
4756 NULL, /* 20 */
4757 NULL,
4758 NULL,
4759 NULL,
4760 NULL, /* 24 */
4761 NULL,
4762 NULL,
4763 NULL,
4764 SDDL_GENERIC_ALL, /* 28 */
4765 SDDL_GENERIC_EXECUTE,
4766 SDDL_GENERIC_WRITE,
4767 SDDL_GENERIC_READ
4770 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4772 static const WCHAR fmtW[] = {'0','x','%','x',0};
4773 WCHAR buf[15];
4774 size_t i;
4776 if (mask == 0)
4777 return;
4779 /* first check if the right have name */
4780 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4782 if (AceRights[i].wstr == NULL)
4783 break;
4784 if (mask == AceRights[i].value)
4786 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4787 return;
4791 /* then check if it can be built from bit names */
4792 for (i = 0; i < 32; i++)
4794 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4796 /* can't be built from bit names */
4797 sprintfW(buf, fmtW, mask);
4798 DumpString(buf, -1, pwptr, plen);
4799 return;
4803 /* build from bit names */
4804 for (i = 0; i < 32; i++)
4805 if (mask & (1 << i))
4806 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4809 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4811 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4812 static const WCHAR openbr = '(';
4813 static const WCHAR closebr = ')';
4814 static const WCHAR semicolon = ';';
4816 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4818 SetLastError(ERROR_INVALID_ACL);
4819 return FALSE;
4822 piace = pace;
4823 DumpString(&openbr, 1, pwptr, plen);
4824 switch (piace->Header.AceType)
4826 case ACCESS_ALLOWED_ACE_TYPE:
4827 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4828 break;
4829 case ACCESS_DENIED_ACE_TYPE:
4830 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4831 break;
4832 case SYSTEM_AUDIT_ACE_TYPE:
4833 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4834 break;
4835 case SYSTEM_ALARM_ACE_TYPE:
4836 DumpString(SDDL_ALARM, -1, pwptr, plen);
4837 break;
4839 DumpString(&semicolon, 1, pwptr, plen);
4841 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4842 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4843 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4844 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4845 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4846 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4847 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4848 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4849 if (piace->Header.AceFlags & INHERITED_ACE)
4850 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4851 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4852 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4853 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4854 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4855 DumpString(&semicolon, 1, pwptr, plen);
4856 DumpRights(piace->Mask, pwptr, plen);
4857 DumpString(&semicolon, 1, pwptr, plen);
4858 /* objects not supported */
4859 DumpString(&semicolon, 1, pwptr, plen);
4860 /* objects not supported */
4861 DumpString(&semicolon, 1, pwptr, plen);
4862 if (!DumpSid(&piace->SidStart, pwptr, plen))
4863 return FALSE;
4864 DumpString(&closebr, 1, pwptr, plen);
4865 return TRUE;
4868 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4870 WORD count;
4871 UINT i;
4873 if (protected)
4874 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4875 if (autoInheritReq)
4876 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4877 if (autoInherited)
4878 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4880 if (pacl == NULL)
4881 return TRUE;
4883 if (!IsValidAcl(pacl))
4884 return FALSE;
4886 count = pacl->AceCount;
4887 for (i = 0; i < count; i++)
4889 LPVOID ace;
4890 if (!GetAce(pacl, i, &ace))
4891 return FALSE;
4892 if (!DumpAce(ace, pwptr, plen))
4893 return FALSE;
4896 return TRUE;
4899 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4901 static const WCHAR prefix[] = {'O',':',0};
4902 BOOL bDefaulted;
4903 PSID psid;
4905 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4906 return FALSE;
4908 if (psid == NULL)
4909 return TRUE;
4911 DumpString(prefix, -1, pwptr, plen);
4912 if (!DumpSid(psid, pwptr, plen))
4913 return FALSE;
4914 return TRUE;
4917 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4919 static const WCHAR prefix[] = {'G',':',0};
4920 BOOL bDefaulted;
4921 PSID psid;
4923 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4924 return FALSE;
4926 if (psid == NULL)
4927 return TRUE;
4929 DumpString(prefix, -1, pwptr, plen);
4930 if (!DumpSid(psid, pwptr, plen))
4931 return FALSE;
4932 return TRUE;
4935 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4937 static const WCHAR dacl[] = {'D',':',0};
4938 SECURITY_DESCRIPTOR_CONTROL control;
4939 BOOL present, defaulted;
4940 DWORD revision;
4941 PACL pacl;
4943 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4944 return FALSE;
4946 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4947 return FALSE;
4949 if (!present)
4950 return TRUE;
4952 DumpString(dacl, 2, pwptr, plen);
4953 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4954 return FALSE;
4955 return TRUE;
4958 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4960 static const WCHAR sacl[] = {'S',':',0};
4961 SECURITY_DESCRIPTOR_CONTROL control;
4962 BOOL present, defaulted;
4963 DWORD revision;
4964 PACL pacl;
4966 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4967 return FALSE;
4969 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4970 return FALSE;
4972 if (!present)
4973 return TRUE;
4975 DumpString(sacl, 2, pwptr, plen);
4976 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4977 return FALSE;
4978 return TRUE;
4981 /******************************************************************************
4982 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4984 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4986 ULONG len;
4987 WCHAR *wptr, *wstr;
4989 if (SDRevision != SDDL_REVISION_1)
4991 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
4992 SetLastError(ERROR_UNKNOWN_REVISION);
4993 return FALSE;
4996 len = 0;
4997 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4998 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4999 return FALSE;
5000 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5001 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5002 return FALSE;
5003 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5004 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5005 return FALSE;
5006 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5007 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5008 return FALSE;
5010 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5011 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5012 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5013 LocalFree (wstr);
5014 return FALSE;
5016 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5017 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5018 LocalFree (wstr);
5019 return FALSE;
5021 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5022 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5023 LocalFree (wstr);
5024 return FALSE;
5026 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5027 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5028 LocalFree (wstr);
5029 return FALSE;
5031 *wptr = 0;
5033 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5034 *OutputString = wstr;
5035 if (OutputLen)
5036 *OutputLen = strlenW(*OutputString)+1;
5037 return TRUE;
5040 /******************************************************************************
5041 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5043 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5045 LPWSTR wstr;
5046 ULONG len;
5047 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5049 int lenA;
5051 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5052 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
5053 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5054 LocalFree(wstr);
5056 if (OutputLen != NULL)
5057 *OutputLen = lenA;
5058 return TRUE;
5060 else
5062 *OutputString = NULL;
5063 if (OutputLen)
5064 *OutputLen = 0;
5065 return FALSE;
5069 /******************************************************************************
5070 * ConvertStringSidToSidW [ADVAPI32.@]
5072 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5074 BOOL bret = FALSE;
5075 DWORD cBytes;
5077 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5078 if (GetVersion() & 0x80000000)
5079 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5080 else if (!StringSid || !Sid)
5081 SetLastError(ERROR_INVALID_PARAMETER);
5082 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5084 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5086 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5087 if (!bret)
5088 LocalFree(*Sid);
5090 return bret;
5093 /******************************************************************************
5094 * ConvertStringSidToSidA [ADVAPI32.@]
5096 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5098 BOOL bret = FALSE;
5100 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5101 if (GetVersion() & 0x80000000)
5102 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5103 else if (!StringSid || !Sid)
5104 SetLastError(ERROR_INVALID_PARAMETER);
5105 else
5107 WCHAR *wStringSid = SERV_dup(StringSid);
5108 bret = ConvertStringSidToSidW(wStringSid, Sid);
5109 HeapFree(GetProcessHeap(), 0, wStringSid);
5111 return bret;
5114 /******************************************************************************
5115 * ConvertSidToStringSidW [ADVAPI32.@]
5117 * format of SID string is:
5118 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5119 * where
5120 * <rev> is the revision of the SID encoded as decimal
5121 * <auth> is the identifier authority encoded as hex
5122 * <subauthN> is the subauthority id encoded as decimal
5124 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5126 DWORD len = 0;
5127 LPWSTR wstr, wptr;
5129 TRACE("%p %p\n", pSid, pstr );
5131 len = 0;
5132 if (!DumpSidNumeric(pSid, NULL, &len))
5133 return FALSE;
5134 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5135 DumpSidNumeric(pSid, &wptr, NULL);
5136 *wptr = 0;
5138 *pstr = wstr;
5139 return TRUE;
5142 /******************************************************************************
5143 * ConvertSidToStringSidA [ADVAPI32.@]
5145 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5147 LPWSTR wstr = NULL;
5148 LPSTR str;
5149 UINT len;
5151 TRACE("%p %p\n", pSid, pstr );
5153 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5154 return FALSE;
5156 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5157 str = LocalAlloc( 0, len );
5158 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5159 LocalFree( wstr );
5161 *pstr = str;
5163 return TRUE;
5166 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5167 PSECURITY_DESCRIPTOR pdesc,
5168 PSECURITY_DESCRIPTOR cdesc,
5169 PSECURITY_DESCRIPTOR* ndesc,
5170 GUID* objtype,
5171 BOOL isdir,
5172 PGENERIC_MAPPING genmap )
5174 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5176 return FALSE;
5179 BOOL WINAPI CreatePrivateObjectSecurity(
5180 PSECURITY_DESCRIPTOR ParentDescriptor,
5181 PSECURITY_DESCRIPTOR CreatorDescriptor,
5182 PSECURITY_DESCRIPTOR* NewDescriptor,
5183 BOOL IsDirectoryObject,
5184 HANDLE Token,
5185 PGENERIC_MAPPING GenericMapping )
5187 SECURITY_DESCRIPTOR_RELATIVE *relative;
5188 DWORD needed, offset;
5189 BYTE *buffer;
5191 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5192 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5194 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5195 needed += sizeof(sidWorld);
5196 needed += sizeof(sidWorld);
5197 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5198 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5200 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, needed ))) return FALSE;
5201 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5202 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5204 HeapFree( GetProcessHeap(), 0, buffer );
5205 return FALSE;
5207 relative->Control |= SE_SELF_RELATIVE;
5208 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5210 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5211 relative->Owner = offset;
5212 offset += sizeof(sidWorld);
5214 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5215 relative->Group = offset;
5216 offset += sizeof(sidWorld);
5218 GetWorldAccessACL( (ACL *)(buffer + offset) );
5219 relative->Dacl = offset;
5220 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5222 GetWorldAccessACL( (ACL *)(buffer + offset) );
5223 relative->Sacl = offset;
5225 *NewDescriptor = relative;
5226 return TRUE;
5229 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5231 FIXME("%p - stub\n", ObjectDescriptor);
5233 HeapFree( GetProcessHeap(), 0, *ObjectDescriptor );
5234 return TRUE;
5237 BOOL WINAPI CreateProcessAsUserA(
5238 HANDLE hToken,
5239 LPCSTR lpApplicationName,
5240 LPSTR lpCommandLine,
5241 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5242 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5243 BOOL bInheritHandles,
5244 DWORD dwCreationFlags,
5245 LPVOID lpEnvironment,
5246 LPCSTR lpCurrentDirectory,
5247 LPSTARTUPINFOA lpStartupInfo,
5248 LPPROCESS_INFORMATION lpProcessInformation )
5250 BOOL ret;
5251 WCHAR *appW, *cmdlnW, *cwdW;
5252 STARTUPINFOW sinfo;
5254 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5255 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5256 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5258 appW = SERV_dup(lpApplicationName);
5259 cmdlnW = SERV_dup(lpCommandLine);
5260 cwdW = SERV_dup(lpCurrentDirectory);
5261 sinfo.cb = sizeof(sinfo);
5262 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5263 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5264 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5265 sinfo.dwX = lpStartupInfo->dwX;
5266 sinfo.dwY = lpStartupInfo->dwY;
5267 sinfo.dwXSize = lpStartupInfo->dwXSize;
5268 sinfo.dwYSize = lpStartupInfo->dwYSize;
5269 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5270 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5271 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5272 sinfo.dwFlags = lpStartupInfo->dwFlags;
5273 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5274 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5275 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5276 sinfo.hStdInput = lpStartupInfo->hStdInput;
5277 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5278 sinfo.hStdError = lpStartupInfo->hStdError;
5279 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5280 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5281 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5282 HeapFree(GetProcessHeap(), 0, appW);
5283 HeapFree(GetProcessHeap(), 0, cmdlnW);
5284 HeapFree(GetProcessHeap(), 0, cwdW);
5285 HeapFree(GetProcessHeap(), 0, sinfo.lpReserved);
5286 HeapFree(GetProcessHeap(), 0, sinfo.lpDesktop);
5287 HeapFree(GetProcessHeap(), 0, sinfo.lpTitle);
5289 return ret;
5292 BOOL WINAPI CreateProcessAsUserW(
5293 HANDLE hToken,
5294 LPCWSTR lpApplicationName,
5295 LPWSTR lpCommandLine,
5296 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5297 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5298 BOOL bInheritHandles,
5299 DWORD dwCreationFlags,
5300 LPVOID lpEnvironment,
5301 LPCWSTR lpCurrentDirectory,
5302 LPSTARTUPINFOW lpStartupInfo,
5303 LPPROCESS_INFORMATION lpProcessInformation )
5305 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5306 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5307 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5308 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5310 /* We should create the process with a suspended main thread */
5311 if (!CreateProcessW (lpApplicationName,
5312 lpCommandLine,
5313 lpProcessAttributes,
5314 lpThreadAttributes,
5315 bInheritHandles,
5316 dwCreationFlags, /* CREATE_SUSPENDED */
5317 lpEnvironment,
5318 lpCurrentDirectory,
5319 lpStartupInfo,
5320 lpProcessInformation))
5322 return FALSE;
5325 return TRUE;
5328 /******************************************************************************
5329 * CreateProcessWithLogonW
5331 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5332 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5333 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5335 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5336 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5337 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5338 lpStartupInfo, lpProcessInformation);
5340 return FALSE;
5343 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5344 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5345 PROCESS_INFORMATION *process_information )
5347 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5348 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5349 creation_flags, environment, debugstr_w(current_directory),
5350 startup_info, process_information);
5352 /* FIXME: check if handles should be inherited */
5353 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5354 current_directory, startup_info, process_information );
5357 /******************************************************************************
5358 * DuplicateTokenEx [ADVAPI32.@]
5360 BOOL WINAPI DuplicateTokenEx(
5361 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5362 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5363 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5364 TOKEN_TYPE TokenType,
5365 PHANDLE DuplicateTokenHandle )
5367 OBJECT_ATTRIBUTES ObjectAttributes;
5369 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5370 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5372 InitializeObjectAttributes(
5373 &ObjectAttributes,
5374 NULL,
5375 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5376 NULL,
5377 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5379 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5380 dwDesiredAccess,
5381 &ObjectAttributes,
5382 ImpersonationLevel,
5383 TokenType,
5384 DuplicateTokenHandle ) );
5387 BOOL WINAPI DuplicateToken(
5388 HANDLE ExistingTokenHandle,
5389 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5390 PHANDLE DuplicateTokenHandle )
5392 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5393 NULL, ImpersonationLevel, TokenImpersonation,
5394 DuplicateTokenHandle );
5397 /******************************************************************************
5398 * ComputeStringSidSize
5400 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5402 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5404 int ctok = 0;
5405 while (*StringSid)
5407 if (*StringSid == '-')
5408 ctok++;
5409 StringSid++;
5412 if (ctok >= 3)
5413 return GetSidLengthRequired(ctok - 2);
5415 else /* String constant format - Only available in winxp and above */
5417 unsigned int i;
5419 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5420 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5421 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5423 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5424 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5426 MAX_SID local;
5427 ADVAPI_GetComputerSid(&local);
5428 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5433 return GetSidLengthRequired(0);
5436 /******************************************************************************
5437 * ParseStringSidToSid
5439 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5441 BOOL bret = FALSE;
5442 SID* pisid=pSid;
5444 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5445 if (!StringSid)
5447 SetLastError(ERROR_INVALID_PARAMETER);
5448 TRACE("StringSid is NULL, returning FALSE\n");
5449 return FALSE;
5452 while (*StringSid == ' ')
5453 StringSid++;
5455 *cBytes = ComputeStringSidSize(StringSid);
5456 if (!pisid) /* Simply compute the size */
5458 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5459 return TRUE;
5462 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5464 DWORD i = 0, identAuth;
5465 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5467 StringSid += 2; /* Advance to Revision */
5468 pisid->Revision = atoiW(StringSid);
5470 if (pisid->Revision != SDDL_REVISION)
5472 TRACE("Revision %d is unknown\n", pisid->Revision);
5473 goto lend; /* ERROR_INVALID_SID */
5475 if (csubauth == 0)
5477 TRACE("SubAuthorityCount is 0\n");
5478 goto lend; /* ERROR_INVALID_SID */
5481 pisid->SubAuthorityCount = csubauth;
5483 /* Advance to identifier authority */
5484 while (*StringSid && *StringSid != '-')
5485 StringSid++;
5486 if (*StringSid == '-')
5487 StringSid++;
5489 /* MS' implementation can't handle values greater than 2^32 - 1, so
5490 * we don't either; assume most significant bytes are always 0
5492 pisid->IdentifierAuthority.Value[0] = 0;
5493 pisid->IdentifierAuthority.Value[1] = 0;
5494 identAuth = atoiW(StringSid);
5495 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5496 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5497 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5498 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5500 /* Advance to first sub authority */
5501 while (*StringSid && *StringSid != '-')
5502 StringSid++;
5503 if (*StringSid == '-')
5504 StringSid++;
5506 while (*StringSid)
5508 pisid->SubAuthority[i++] = atoiW(StringSid);
5510 while (*StringSid && *StringSid != '-')
5511 StringSid++;
5512 if (*StringSid == '-')
5513 StringSid++;
5516 if (i != pisid->SubAuthorityCount)
5517 goto lend; /* ERROR_INVALID_SID */
5519 bret = TRUE;
5521 else /* String constant format - Only available in winxp and above */
5523 unsigned int i;
5524 pisid->Revision = SDDL_REVISION;
5526 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5527 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5529 DWORD j;
5530 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5531 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5532 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5533 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5534 bret = TRUE;
5537 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5538 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5540 ADVAPI_GetComputerSid(pisid);
5541 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5542 pisid->SubAuthorityCount++;
5543 bret = TRUE;
5546 if (!bret)
5547 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5550 lend:
5551 if (!bret)
5552 SetLastError(ERROR_INVALID_SID);
5554 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5555 return bret;
5558 /******************************************************************************
5559 * GetNamedSecurityInfoA [ADVAPI32.@]
5561 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5562 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5563 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5564 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5566 LPWSTR wstr;
5567 DWORD r;
5569 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5570 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5572 wstr = SERV_dup(pObjectName);
5573 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5574 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5576 HeapFree( GetProcessHeap(), 0, wstr );
5578 return r;
5581 /******************************************************************************
5582 * GetNamedSecurityInfoW [ADVAPI32.@]
5584 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5585 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5586 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5588 DWORD access = 0;
5589 HANDLE handle;
5590 DWORD err;
5592 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5593 group, dacl, sacl, descriptor );
5595 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5596 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5598 /* If no descriptor, we have to check that there's a pointer for the requested information */
5599 if( !descriptor && (
5600 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5601 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5602 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5603 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5604 return ERROR_INVALID_PARAMETER;
5606 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5607 access |= READ_CONTROL;
5608 if (info & SACL_SECURITY_INFORMATION)
5609 access |= ACCESS_SYSTEM_SECURITY;
5611 switch (type)
5613 case SE_SERVICE:
5614 if (!(err = get_security_service( name, access, &handle )))
5616 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5617 CloseServiceHandle( handle );
5619 break;
5620 case SE_REGISTRY_KEY:
5621 if (!(err = get_security_regkey( name, access, &handle )))
5623 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5624 RegCloseKey( handle );
5626 break;
5627 case SE_FILE_OBJECT:
5628 if (!(err = get_security_file( name, access, &handle )))
5630 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5631 CloseHandle( handle );
5633 break;
5634 default:
5635 FIXME( "Object type %d is not currently supported.\n", type );
5636 if (owner) *owner = NULL;
5637 if (group) *group = NULL;
5638 if (dacl) *dacl = NULL;
5639 if (sacl) *sacl = NULL;
5640 if (descriptor) *descriptor = NULL;
5641 return ERROR_SUCCESS;
5643 return err;
5646 /******************************************************************************
5647 * GetNamedSecurityInfoExW [ADVAPI32.@]
5649 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5650 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5651 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5653 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5654 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5655 return ERROR_CALL_NOT_IMPLEMENTED;
5658 /******************************************************************************
5659 * GetNamedSecurityInfoExA [ADVAPI32.@]
5661 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5662 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5663 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5665 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5666 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5667 return ERROR_CALL_NOT_IMPLEMENTED;
5670 /******************************************************************************
5671 * DecryptFileW [ADVAPI32.@]
5673 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5675 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5676 return TRUE;
5679 /******************************************************************************
5680 * DecryptFileA [ADVAPI32.@]
5682 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5684 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5685 return TRUE;
5688 /******************************************************************************
5689 * EncryptFileW [ADVAPI32.@]
5691 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5693 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5694 return TRUE;
5697 /******************************************************************************
5698 * EncryptFileA [ADVAPI32.@]
5700 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5702 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5703 return TRUE;
5706 /******************************************************************************
5707 * FileEncryptionStatusW [ADVAPI32.@]
5709 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5711 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5712 if (!lpStatus)
5713 return FALSE;
5714 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5715 return TRUE;
5718 /******************************************************************************
5719 * FileEncryptionStatusA [ADVAPI32.@]
5721 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5723 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5724 if (!lpStatus)
5725 return FALSE;
5726 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5727 return TRUE;
5730 /******************************************************************************
5731 * SetSecurityInfo [ADVAPI32.@]
5733 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5734 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5735 PSID psidGroup, PACL pDacl, PACL pSacl)
5737 SECURITY_DESCRIPTOR sd;
5738 NTSTATUS status;
5740 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5741 return ERROR_INVALID_SECURITY_DESCR;
5743 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5744 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5745 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5746 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5747 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5748 SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
5749 if (SecurityInfo & SACL_SECURITY_INFORMATION)
5750 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
5752 switch (ObjectType)
5754 case SE_SERVICE:
5755 FIXME("stub: Service objects are not supported at this time.\n");
5756 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
5757 break;
5758 default:
5759 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
5760 break;
5762 return RtlNtStatusToDosError(status);
5765 /******************************************************************************
5766 * SaferCreateLevel [ADVAPI32.@]
5768 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5769 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5771 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5773 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5774 return TRUE;
5777 /******************************************************************************
5778 * SaferComputeTokenFromLevel [ADVAPI32.@]
5780 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5781 DWORD flags, LPVOID reserved)
5783 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5785 *access_token = (HANDLE)0xdeadbeef;
5786 return TRUE;
5789 /******************************************************************************
5790 * SaferCloseLevel [ADVAPI32.@]
5792 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5794 FIXME("(%p) stub\n", handle);
5795 return TRUE;
5798 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5799 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5800 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5801 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5802 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5804 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
5805 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5806 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5808 return ERROR_SUCCESS;
5811 /******************************************************************************
5812 * SaferGetPolicyInformation [ADVAPI32.@]
5814 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5815 PVOID buffer, PDWORD required, LPVOID lpReserved)
5817 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5818 return FALSE;
5821 /******************************************************************************
5822 * SaferSetLevelInformation [ADVAPI32.@]
5824 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5825 LPVOID buffer, DWORD size)
5827 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5828 return FALSE;