msvcrt: Added _putwc_nolock implementation.
[wine.git] / dlls / advapi32 / security.c
blobcc2003386b86c721317a2968671f5ea5e8c99c93
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 = heap_alloc(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 heap_free(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 = heap_alloc(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 heap_free(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 = heap_alloc(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 heap_free(groups);
1065 return set_ntstatus(status);
1068 restricted = groups->GroupCount > 0;
1069 heap_free(groups);
1071 return restricted;
1074 /******************************************************************************
1075 * IsValidSid [ADVAPI32.@]
1077 * PARAMS
1078 * pSid []
1080 BOOL WINAPI
1081 IsValidSid( PSID pSid )
1083 return RtlValidSid( pSid );
1086 /******************************************************************************
1087 * EqualSid [ADVAPI32.@]
1089 * PARAMS
1090 * pSid1 []
1091 * pSid2 []
1093 BOOL WINAPI
1094 EqualSid( PSID pSid1, PSID pSid2 )
1096 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1097 SetLastError(ERROR_SUCCESS);
1098 return ret;
1101 /******************************************************************************
1102 * EqualPrefixSid [ADVAPI32.@]
1104 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1106 return RtlEqualPrefixSid(pSid1, pSid2);
1109 /******************************************************************************
1110 * GetSidLengthRequired [ADVAPI32.@]
1112 * PARAMS
1113 * nSubAuthorityCount []
1115 DWORD WINAPI
1116 GetSidLengthRequired( BYTE nSubAuthorityCount )
1118 return RtlLengthRequiredSid(nSubAuthorityCount);
1121 /******************************************************************************
1122 * InitializeSid [ADVAPI32.@]
1124 * PARAMS
1125 * pIdentifierAuthority []
1127 BOOL WINAPI
1128 InitializeSid (
1129 PSID pSid,
1130 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1131 BYTE nSubAuthorityCount)
1133 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1136 DWORD WINAPI
1137 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1139 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1141 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1142 return 0;
1145 DWORD WINAPI
1146 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1148 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1150 return 1;
1153 /******************************************************************************
1154 * GetSidIdentifierAuthority [ADVAPI32.@]
1156 * PARAMS
1157 * pSid []
1159 PSID_IDENTIFIER_AUTHORITY WINAPI
1160 GetSidIdentifierAuthority( PSID pSid )
1162 return RtlIdentifierAuthoritySid(pSid);
1165 /******************************************************************************
1166 * GetSidSubAuthority [ADVAPI32.@]
1168 * PARAMS
1169 * pSid []
1170 * nSubAuthority []
1172 PDWORD WINAPI
1173 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1175 SetLastError(ERROR_SUCCESS);
1176 return RtlSubAuthoritySid(pSid, nSubAuthority);
1179 /******************************************************************************
1180 * GetSidSubAuthorityCount [ADVAPI32.@]
1182 * PARAMS
1183 * pSid []
1185 PUCHAR WINAPI
1186 GetSidSubAuthorityCount (PSID pSid)
1188 SetLastError(ERROR_SUCCESS);
1189 return RtlSubAuthorityCountSid(pSid);
1192 /******************************************************************************
1193 * GetLengthSid [ADVAPI32.@]
1195 * PARAMS
1196 * pSid []
1198 DWORD WINAPI
1199 GetLengthSid (PSID pSid)
1201 return RtlLengthSid(pSid);
1204 /* ##############################################
1205 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1206 ##############################################
1209 /******************************************************************************
1210 * BuildSecurityDescriptorA [ADVAPI32.@]
1212 * Builds a SD from
1214 * PARAMS
1215 * pOwner [I]
1216 * pGroup [I]
1217 * cCountOfAccessEntries [I]
1218 * pListOfAccessEntries [I]
1219 * cCountOfAuditEntries [I]
1220 * pListofAuditEntries [I]
1221 * pOldSD [I]
1222 * lpdwBufferLength [I/O]
1223 * pNewSD [O]
1225 * RETURNS
1226 * Success: ERROR_SUCCESS
1227 * Failure: nonzero error code from Winerror.h
1229 DWORD WINAPI BuildSecurityDescriptorA(
1230 IN PTRUSTEEA pOwner,
1231 IN PTRUSTEEA pGroup,
1232 IN ULONG cCountOfAccessEntries,
1233 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1234 IN ULONG cCountOfAuditEntries,
1235 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1236 IN PSECURITY_DESCRIPTOR pOldSD,
1237 IN OUT PULONG lpdwBufferLength,
1238 OUT PSECURITY_DESCRIPTOR* pNewSD)
1240 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1241 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1242 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1244 return ERROR_CALL_NOT_IMPLEMENTED;
1247 /******************************************************************************
1248 * BuildSecurityDescriptorW [ADVAPI32.@]
1250 * See BuildSecurityDescriptorA.
1252 DWORD WINAPI BuildSecurityDescriptorW(
1253 IN PTRUSTEEW pOwner,
1254 IN PTRUSTEEW pGroup,
1255 IN ULONG cCountOfAccessEntries,
1256 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1257 IN ULONG cCountOfAuditEntries,
1258 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1259 IN PSECURITY_DESCRIPTOR pOldSD,
1260 IN OUT PULONG lpdwBufferLength,
1261 OUT PSECURITY_DESCRIPTOR* pNewSD)
1263 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1264 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1265 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1267 return ERROR_CALL_NOT_IMPLEMENTED;
1270 /******************************************************************************
1271 * InitializeSecurityDescriptor [ADVAPI32.@]
1273 * PARAMS
1274 * pDescr []
1275 * revision []
1277 BOOL WINAPI
1278 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1280 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1284 /******************************************************************************
1285 * MakeAbsoluteSD [ADVAPI32.@]
1287 BOOL WINAPI MakeAbsoluteSD (
1288 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1289 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1290 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1291 OUT PACL pDacl,
1292 OUT LPDWORD lpdwDaclSize,
1293 OUT PACL pSacl,
1294 OUT LPDWORD lpdwSaclSize,
1295 OUT PSID pOwner,
1296 OUT LPDWORD lpdwOwnerSize,
1297 OUT PSID pPrimaryGroup,
1298 OUT LPDWORD lpdwPrimaryGroupSize)
1300 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1301 pAbsoluteSecurityDescriptor,
1302 lpdwAbsoluteSecurityDescriptorSize,
1303 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1304 pOwner, lpdwOwnerSize,
1305 pPrimaryGroup, lpdwPrimaryGroupSize));
1308 /******************************************************************************
1309 * GetKernelObjectSecurity [ADVAPI32.@]
1311 BOOL WINAPI GetKernelObjectSecurity(
1312 HANDLE Handle,
1313 SECURITY_INFORMATION RequestedInformation,
1314 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1315 DWORD nLength,
1316 LPDWORD lpnLengthNeeded )
1318 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1319 pSecurityDescriptor, nLength, lpnLengthNeeded);
1321 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1322 nLength, lpnLengthNeeded ));
1325 /******************************************************************************
1326 * GetPrivateObjectSecurity [ADVAPI32.@]
1328 BOOL WINAPI GetPrivateObjectSecurity(
1329 PSECURITY_DESCRIPTOR ObjectDescriptor,
1330 SECURITY_INFORMATION SecurityInformation,
1331 PSECURITY_DESCRIPTOR ResultantDescriptor,
1332 DWORD DescriptorLength,
1333 PDWORD ReturnLength )
1335 SECURITY_DESCRIPTOR desc;
1336 BOOL defaulted, present;
1337 PACL pacl;
1338 PSID psid;
1340 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1341 ResultantDescriptor, DescriptorLength, ReturnLength);
1343 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1344 return FALSE;
1346 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1348 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1349 return FALSE;
1350 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1353 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1355 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1356 return FALSE;
1357 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1360 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1362 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1363 return FALSE;
1364 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1367 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1369 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1370 return FALSE;
1371 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1374 *ReturnLength = DescriptorLength;
1375 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1378 /******************************************************************************
1379 * GetSecurityDescriptorLength [ADVAPI32.@]
1381 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1383 return RtlLengthSecurityDescriptor(pDescr);
1386 /******************************************************************************
1387 * GetSecurityDescriptorOwner [ADVAPI32.@]
1389 * PARAMS
1390 * pOwner []
1391 * lpbOwnerDefaulted []
1393 BOOL WINAPI
1394 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1395 LPBOOL lpbOwnerDefaulted )
1397 BOOLEAN defaulted;
1398 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1399 *lpbOwnerDefaulted = defaulted;
1400 return ret;
1403 /******************************************************************************
1404 * SetSecurityDescriptorOwner [ADVAPI32.@]
1406 * PARAMS
1408 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1409 PSID pOwner, BOOL bOwnerDefaulted)
1411 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1413 /******************************************************************************
1414 * GetSecurityDescriptorGroup [ADVAPI32.@]
1416 BOOL WINAPI GetSecurityDescriptorGroup(
1417 PSECURITY_DESCRIPTOR SecurityDescriptor,
1418 PSID *Group,
1419 LPBOOL GroupDefaulted)
1421 BOOLEAN defaulted;
1422 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1423 *GroupDefaulted = defaulted;
1424 return ret;
1426 /******************************************************************************
1427 * SetSecurityDescriptorGroup [ADVAPI32.@]
1429 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1430 PSID Group, BOOL GroupDefaulted)
1432 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1435 /******************************************************************************
1436 * IsValidSecurityDescriptor [ADVAPI32.@]
1438 * PARAMS
1439 * lpsecdesc []
1441 BOOL WINAPI
1442 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1444 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1447 /******************************************************************************
1448 * GetSecurityDescriptorDacl [ADVAPI32.@]
1450 BOOL WINAPI GetSecurityDescriptorDacl(
1451 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1452 OUT LPBOOL lpbDaclPresent,
1453 OUT PACL *pDacl,
1454 OUT LPBOOL lpbDaclDefaulted)
1456 BOOLEAN present, defaulted;
1457 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1458 *lpbDaclPresent = present;
1459 *lpbDaclDefaulted = defaulted;
1460 return ret;
1463 /******************************************************************************
1464 * SetSecurityDescriptorDacl [ADVAPI32.@]
1466 BOOL WINAPI
1467 SetSecurityDescriptorDacl (
1468 PSECURITY_DESCRIPTOR lpsd,
1469 BOOL daclpresent,
1470 PACL dacl,
1471 BOOL dacldefaulted )
1473 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1475 /******************************************************************************
1476 * GetSecurityDescriptorSacl [ADVAPI32.@]
1478 BOOL WINAPI GetSecurityDescriptorSacl(
1479 IN PSECURITY_DESCRIPTOR lpsd,
1480 OUT LPBOOL lpbSaclPresent,
1481 OUT PACL *pSacl,
1482 OUT LPBOOL lpbSaclDefaulted)
1484 BOOLEAN present, defaulted;
1485 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1486 *lpbSaclPresent = present;
1487 *lpbSaclDefaulted = defaulted;
1488 return ret;
1491 /**************************************************************************
1492 * SetSecurityDescriptorSacl [ADVAPI32.@]
1494 BOOL WINAPI SetSecurityDescriptorSacl (
1495 PSECURITY_DESCRIPTOR lpsd,
1496 BOOL saclpresent,
1497 PACL lpsacl,
1498 BOOL sacldefaulted)
1500 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1502 /******************************************************************************
1503 * MakeSelfRelativeSD [ADVAPI32.@]
1505 * PARAMS
1506 * lpabssecdesc []
1507 * lpselfsecdesc []
1508 * lpbuflen []
1510 BOOL WINAPI
1511 MakeSelfRelativeSD(
1512 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1513 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1514 IN OUT LPDWORD lpdwBufferLength)
1516 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1517 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1520 /******************************************************************************
1521 * GetSecurityDescriptorControl [ADVAPI32.@]
1524 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1525 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1527 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1530 /******************************************************************************
1531 * SetSecurityDescriptorControl [ADVAPI32.@]
1533 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1534 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1535 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1537 return set_ntstatus( RtlSetControlSecurityDescriptor(
1538 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1541 /* ##############################
1542 ###### ACL FUNCTIONS ######
1543 ##############################
1546 /*************************************************************************
1547 * InitializeAcl [ADVAPI32.@]
1549 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1551 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1554 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1556 IO_STATUS_BLOCK io_block;
1558 TRACE("(%p)\n", hNamedPipe);
1560 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1561 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1564 /******************************************************************************
1565 * AddAccessAllowedAce [ADVAPI32.@]
1567 BOOL WINAPI AddAccessAllowedAce(
1568 IN OUT PACL pAcl,
1569 IN DWORD dwAceRevision,
1570 IN DWORD AccessMask,
1571 IN PSID pSid)
1573 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1576 /******************************************************************************
1577 * AddAccessAllowedAceEx [ADVAPI32.@]
1579 BOOL WINAPI AddAccessAllowedAceEx(
1580 IN OUT PACL pAcl,
1581 IN DWORD dwAceRevision,
1582 IN DWORD AceFlags,
1583 IN DWORD AccessMask,
1584 IN PSID pSid)
1586 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1589 /******************************************************************************
1590 * AddAccessDeniedAce [ADVAPI32.@]
1592 BOOL WINAPI AddAccessDeniedAce(
1593 IN OUT PACL pAcl,
1594 IN DWORD dwAceRevision,
1595 IN DWORD AccessMask,
1596 IN PSID pSid)
1598 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1601 /******************************************************************************
1602 * AddAccessDeniedAceEx [ADVAPI32.@]
1604 BOOL WINAPI AddAccessDeniedAceEx(
1605 IN OUT PACL pAcl,
1606 IN DWORD dwAceRevision,
1607 IN DWORD AceFlags,
1608 IN DWORD AccessMask,
1609 IN PSID pSid)
1611 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1614 /******************************************************************************
1615 * AddAce [ADVAPI32.@]
1617 BOOL WINAPI AddAce(
1618 IN OUT PACL pAcl,
1619 IN DWORD dwAceRevision,
1620 IN DWORD dwStartingAceIndex,
1621 LPVOID pAceList,
1622 DWORD nAceListLength)
1624 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1627 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1629 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1630 return FALSE;
1633 /******************************************************************************
1634 * DeleteAce [ADVAPI32.@]
1636 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1638 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1641 /******************************************************************************
1642 * FindFirstFreeAce [ADVAPI32.@]
1644 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1646 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1649 /******************************************************************************
1650 * GetAce [ADVAPI32.@]
1652 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1654 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1657 /******************************************************************************
1658 * GetAclInformation [ADVAPI32.@]
1660 BOOL WINAPI GetAclInformation(
1661 PACL pAcl,
1662 LPVOID pAclInformation,
1663 DWORD nAclInformationLength,
1664 ACL_INFORMATION_CLASS dwAclInformationClass)
1666 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1667 nAclInformationLength, dwAclInformationClass));
1670 /******************************************************************************
1671 * IsValidAcl [ADVAPI32.@]
1673 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1675 return RtlValidAcl(pAcl);
1678 /* ##############################
1679 ###### MISC FUNCTIONS ######
1680 ##############################
1683 /******************************************************************************
1684 * AllocateLocallyUniqueId [ADVAPI32.@]
1686 * PARAMS
1687 * lpLuid []
1689 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1691 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1694 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1695 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1696 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1697 { '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 };
1698 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1699 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1700 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1701 { '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 };
1702 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1703 { '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 };
1704 static const WCHAR SE_TCB_NAME_W[] =
1705 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1706 static const WCHAR SE_SECURITY_NAME_W[] =
1707 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1708 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1709 { '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 };
1710 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1711 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1712 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1713 { '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 };
1714 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1715 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1716 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1717 { '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 };
1718 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1719 { '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 };
1720 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1721 { '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 };
1722 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1723 { '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 };
1724 static const WCHAR SE_BACKUP_NAME_W[] =
1725 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1726 static const WCHAR SE_RESTORE_NAME_W[] =
1727 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1728 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1729 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1730 static const WCHAR SE_DEBUG_NAME_W[] =
1731 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1732 static const WCHAR SE_AUDIT_NAME_W[] =
1733 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1734 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1735 { '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 };
1736 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1737 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1738 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1739 { '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 };
1740 static const WCHAR SE_UNDOCK_NAME_W[] =
1741 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1742 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1743 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1744 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1745 { '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 };
1746 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1747 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1748 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1749 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1750 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1751 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1753 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1755 NULL,
1756 NULL,
1757 SE_CREATE_TOKEN_NAME_W,
1758 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1759 SE_LOCK_MEMORY_NAME_W,
1760 SE_INCREASE_QUOTA_NAME_W,
1761 SE_MACHINE_ACCOUNT_NAME_W,
1762 SE_TCB_NAME_W,
1763 SE_SECURITY_NAME_W,
1764 SE_TAKE_OWNERSHIP_NAME_W,
1765 SE_LOAD_DRIVER_NAME_W,
1766 SE_SYSTEM_PROFILE_NAME_W,
1767 SE_SYSTEMTIME_NAME_W,
1768 SE_PROF_SINGLE_PROCESS_NAME_W,
1769 SE_INC_BASE_PRIORITY_NAME_W,
1770 SE_CREATE_PAGEFILE_NAME_W,
1771 SE_CREATE_PERMANENT_NAME_W,
1772 SE_BACKUP_NAME_W,
1773 SE_RESTORE_NAME_W,
1774 SE_SHUTDOWN_NAME_W,
1775 SE_DEBUG_NAME_W,
1776 SE_AUDIT_NAME_W,
1777 SE_SYSTEM_ENVIRONMENT_NAME_W,
1778 SE_CHANGE_NOTIFY_NAME_W,
1779 SE_REMOTE_SHUTDOWN_NAME_W,
1780 SE_UNDOCK_NAME_W,
1781 SE_SYNC_AGENT_NAME_W,
1782 SE_ENABLE_DELEGATION_NAME_W,
1783 SE_MANAGE_VOLUME_NAME_W,
1784 SE_IMPERSONATE_NAME_W,
1785 SE_CREATE_GLOBAL_NAME_W,
1788 /******************************************************************************
1789 * LookupPrivilegeValueW [ADVAPI32.@]
1791 * See LookupPrivilegeValueA.
1793 BOOL WINAPI
1794 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1796 UINT i;
1798 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1800 if (!ADVAPI_IsLocalComputer(lpSystemName))
1802 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1803 return FALSE;
1805 if (!lpName)
1807 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1808 return FALSE;
1810 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1812 if( !WellKnownPrivNames[i] )
1813 continue;
1814 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1815 continue;
1816 lpLuid->LowPart = i;
1817 lpLuid->HighPart = 0;
1818 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1819 lpLuid->HighPart, lpLuid->LowPart );
1820 return TRUE;
1822 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1823 return FALSE;
1826 /******************************************************************************
1827 * LookupPrivilegeValueA [ADVAPI32.@]
1829 * Retrieves LUID used on a system to represent the privilege name.
1831 * PARAMS
1832 * lpSystemName [I] Name of the system
1833 * lpName [I] Name of the privilege
1834 * lpLuid [O] Destination for the resulting LUID
1836 * RETURNS
1837 * Success: TRUE. lpLuid contains the requested LUID.
1838 * Failure: FALSE.
1840 BOOL WINAPI
1841 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1843 UNICODE_STRING lpSystemNameW;
1844 UNICODE_STRING lpNameW;
1845 BOOL ret;
1847 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1848 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1849 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1850 RtlFreeUnicodeString(&lpNameW);
1851 RtlFreeUnicodeString(&lpSystemNameW);
1852 return ret;
1855 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1856 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1858 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1859 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1861 return FALSE;
1864 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1865 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1867 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1868 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1870 return FALSE;
1873 /******************************************************************************
1874 * LookupPrivilegeNameA [ADVAPI32.@]
1876 * See LookupPrivilegeNameW.
1878 BOOL WINAPI
1879 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1880 LPDWORD cchName)
1882 UNICODE_STRING lpSystemNameW;
1883 BOOL ret;
1884 DWORD wLen = 0;
1886 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1888 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1889 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1890 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1892 LPWSTR lpNameW = heap_alloc(wLen * sizeof(WCHAR));
1894 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1895 &wLen);
1896 if (ret)
1898 /* Windows crashes if cchName is NULL, so will I */
1899 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1900 *cchName, NULL, NULL);
1902 if (len == 0)
1904 /* WideCharToMultiByte failed */
1905 ret = FALSE;
1907 else if (len > *cchName)
1909 *cchName = len;
1910 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1911 ret = FALSE;
1913 else
1915 /* WideCharToMultiByte succeeded, output length needs to be
1916 * length not including NULL terminator
1918 *cchName = len - 1;
1921 heap_free(lpNameW);
1923 RtlFreeUnicodeString(&lpSystemNameW);
1924 return ret;
1927 /******************************************************************************
1928 * LookupPrivilegeNameW [ADVAPI32.@]
1930 * Retrieves the privilege name referred to by the LUID lpLuid.
1932 * PARAMS
1933 * lpSystemName [I] Name of the system
1934 * lpLuid [I] Privilege value
1935 * lpName [O] Name of the privilege
1936 * cchName [I/O] Number of characters in lpName.
1938 * RETURNS
1939 * Success: TRUE. lpName contains the name of the privilege whose value is
1940 * *lpLuid.
1941 * Failure: FALSE.
1943 * REMARKS
1944 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1945 * using this function.
1946 * If the length of lpName is too small, on return *cchName will contain the
1947 * number of WCHARs needed to contain the privilege, including the NULL
1948 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1949 * On success, *cchName will contain the number of characters stored in
1950 * lpName, NOT including the NULL terminator.
1952 BOOL WINAPI
1953 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1954 LPDWORD cchName)
1956 size_t privNameLen;
1958 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1960 if (!ADVAPI_IsLocalComputer(lpSystemName))
1962 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1963 return FALSE;
1965 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1966 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1968 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1969 return FALSE;
1971 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1972 /* Windows crashes if cchName is NULL, so will I */
1973 if (*cchName <= privNameLen)
1975 *cchName = privNameLen + 1;
1976 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1977 return FALSE;
1979 else
1981 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1982 *cchName = privNameLen;
1983 return TRUE;
1987 /******************************************************************************
1988 * GetFileSecurityA [ADVAPI32.@]
1990 * Obtains Specified information about the security of a file or directory.
1992 * PARAMS
1993 * lpFileName [I] Name of the file to get info for
1994 * RequestedInformation [I] SE_ flags from "winnt.h"
1995 * pSecurityDescriptor [O] Destination for security information
1996 * nLength [I] Length of pSecurityDescriptor
1997 * lpnLengthNeeded [O] Destination for length of returned security information
1999 * RETURNS
2000 * Success: TRUE. pSecurityDescriptor contains the requested information.
2001 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2003 * NOTES
2004 * The information returned is constrained by the callers access rights and
2005 * privileges.
2007 BOOL WINAPI
2008 GetFileSecurityA( LPCSTR lpFileName,
2009 SECURITY_INFORMATION RequestedInformation,
2010 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2011 DWORD nLength, LPDWORD lpnLengthNeeded )
2013 BOOL r;
2014 LPWSTR name;
2016 name = SERV_dup(lpFileName);
2017 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2018 nLength, lpnLengthNeeded );
2019 heap_free( name );
2021 return r;
2024 /******************************************************************************
2025 * GetFileSecurityW [ADVAPI32.@]
2027 * See GetFileSecurityA.
2029 BOOL WINAPI
2030 GetFileSecurityW( LPCWSTR lpFileName,
2031 SECURITY_INFORMATION RequestedInformation,
2032 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2033 DWORD nLength, LPDWORD lpnLengthNeeded )
2035 HANDLE hfile;
2036 NTSTATUS status;
2037 DWORD access = 0;
2039 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2040 RequestedInformation, pSecurityDescriptor,
2041 nLength, lpnLengthNeeded);
2043 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2044 DACL_SECURITY_INFORMATION))
2045 access |= READ_CONTROL;
2046 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2047 access |= ACCESS_SYSTEM_SECURITY;
2049 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2050 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2051 if ( hfile == INVALID_HANDLE_VALUE )
2052 return FALSE;
2054 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2055 nLength, lpnLengthNeeded );
2056 CloseHandle( hfile );
2057 return set_ntstatus( status );
2061 /******************************************************************************
2062 * LookupAccountSidA [ADVAPI32.@]
2064 BOOL WINAPI
2065 LookupAccountSidA(
2066 IN LPCSTR system,
2067 IN PSID sid,
2068 OUT LPSTR account,
2069 IN OUT LPDWORD accountSize,
2070 OUT LPSTR domain,
2071 IN OUT LPDWORD domainSize,
2072 OUT PSID_NAME_USE name_use )
2074 DWORD len;
2075 BOOL r;
2076 LPWSTR systemW;
2077 LPWSTR accountW = NULL;
2078 LPWSTR domainW = NULL;
2079 DWORD accountSizeW = *accountSize;
2080 DWORD domainSizeW = *domainSize;
2082 systemW = SERV_dup(system);
2083 if (account)
2084 accountW = heap_alloc( accountSizeW * sizeof(WCHAR) );
2085 if (domain)
2086 domainW = heap_alloc( domainSizeW * sizeof(WCHAR) );
2088 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2090 if (r) {
2091 if (accountW && *accountSize) {
2092 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2093 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2094 *accountSize = len;
2095 } else
2096 *accountSize = accountSizeW + 1;
2098 if (domainW && *domainSize) {
2099 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2100 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2101 *domainSize = len;
2102 } else
2103 *domainSize = domainSizeW + 1;
2105 else
2107 *accountSize = accountSizeW + 1;
2108 *domainSize = domainSizeW + 1;
2111 heap_free( systemW );
2112 heap_free( accountW );
2113 heap_free( domainW );
2115 return r;
2118 /******************************************************************************
2119 * LookupAccountSidW [ADVAPI32.@]
2121 * PARAMS
2122 * system []
2123 * sid []
2124 * account []
2125 * accountSize []
2126 * domain []
2127 * domainSize []
2128 * name_use []
2131 BOOL WINAPI
2132 LookupAccountSidW(
2133 IN LPCWSTR system,
2134 IN PSID sid,
2135 OUT LPWSTR account,
2136 IN OUT LPDWORD accountSize,
2137 OUT LPWSTR domain,
2138 IN OUT LPDWORD domainSize,
2139 OUT PSID_NAME_USE name_use )
2141 unsigned int i, j;
2142 const WCHAR * ac = NULL;
2143 const WCHAR * dm = NULL;
2144 SID_NAME_USE use = 0;
2145 LPWSTR computer_name = NULL;
2146 LPWSTR account_name = NULL;
2148 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2149 debugstr_w(system),debugstr_sid(sid),
2150 account,accountSize,accountSize?*accountSize:0,
2151 domain,domainSize,domainSize?*domainSize:0,
2152 name_use);
2154 if (!ADVAPI_IsLocalComputer(system)) {
2155 FIXME("Only local computer supported!\n");
2156 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2157 return FALSE;
2160 /* check the well known SIDs first */
2161 for (i = 0; i <= 60; i++) {
2162 if (IsWellKnownSid(sid, i)) {
2163 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2164 if (ACCOUNT_SIDS[j].type == i) {
2165 ac = ACCOUNT_SIDS[j].account;
2166 dm = ACCOUNT_SIDS[j].domain;
2167 use = ACCOUNT_SIDS[j].name_use;
2170 break;
2174 if (dm == NULL) {
2175 MAX_SID local;
2177 /* check for the local computer next */
2178 if (ADVAPI_GetComputerSid(&local)) {
2179 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2180 BOOL result;
2182 computer_name = heap_alloc(size * sizeof(WCHAR));
2183 result = GetComputerNameW(computer_name, &size);
2185 if (result) {
2186 if (EqualSid(sid, &local)) {
2187 dm = computer_name;
2188 ac = Blank;
2189 use = 3;
2190 } else {
2191 local.SubAuthorityCount++;
2193 if (EqualPrefixSid(sid, &local)) {
2194 dm = computer_name;
2195 use = 1;
2196 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2197 case DOMAIN_USER_RID_ADMIN:
2198 ac = Administrator;
2199 break;
2200 case DOMAIN_USER_RID_GUEST:
2201 ac = Guest;
2202 break;
2203 case DOMAIN_GROUP_RID_ADMINS:
2204 ac = Domain_Admins;
2205 break;
2206 case DOMAIN_GROUP_RID_USERS:
2207 ac = Domain_Users;
2208 break;
2209 case DOMAIN_GROUP_RID_GUESTS:
2210 ac = Domain_Guests;
2211 break;
2212 case DOMAIN_GROUP_RID_COMPUTERS:
2213 ac = Domain_Computers;
2214 break;
2215 case DOMAIN_GROUP_RID_CONTROLLERS:
2216 ac = Domain_Controllers;
2217 break;
2218 case DOMAIN_GROUP_RID_CERT_ADMINS:
2219 ac = Cert_Publishers;
2220 break;
2221 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2222 ac = Schema_Admins;
2223 break;
2224 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2225 ac = Enterprise_Admins;
2226 break;
2227 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2228 ac = Group_Policy_Creator_Owners;
2229 break;
2230 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2231 ac = RAS_and_IAS_Servers;
2232 break;
2233 case 1000: /* first user account */
2234 size = UNLEN + 1;
2235 account_name = heap_alloc(size * sizeof(WCHAR));
2236 if (GetUserNameW(account_name, &size))
2237 ac = account_name;
2238 else
2239 dm = NULL;
2241 break;
2242 default:
2243 dm = NULL;
2244 break;
2252 if (dm) {
2253 DWORD ac_len = lstrlenW(ac);
2254 DWORD dm_len = lstrlenW(dm);
2255 BOOL status = TRUE;
2257 if (*accountSize > ac_len) {
2258 if (account)
2259 lstrcpyW(account, ac);
2261 if (*domainSize > dm_len) {
2262 if (domain)
2263 lstrcpyW(domain, dm);
2265 if ((*accountSize && *accountSize < ac_len) ||
2266 (!account && !*accountSize && ac_len) ||
2267 (*domainSize && *domainSize < dm_len) ||
2268 (!domain && !*domainSize && dm_len))
2270 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2271 status = FALSE;
2273 if (*domainSize)
2274 *domainSize = dm_len;
2275 else
2276 *domainSize = dm_len + 1;
2277 if (*accountSize)
2278 *accountSize = ac_len;
2279 else
2280 *accountSize = ac_len + 1;
2282 heap_free(account_name);
2283 heap_free(computer_name);
2284 if (status) *name_use = use;
2285 return status;
2288 heap_free(account_name);
2289 heap_free(computer_name);
2290 SetLastError(ERROR_NONE_MAPPED);
2291 return FALSE;
2294 /******************************************************************************
2295 * SetFileSecurityA [ADVAPI32.@]
2297 * See SetFileSecurityW.
2299 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2300 SECURITY_INFORMATION RequestedInformation,
2301 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2303 BOOL r;
2304 LPWSTR name;
2306 name = SERV_dup(lpFileName);
2307 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2308 heap_free( name );
2310 return r;
2313 /******************************************************************************
2314 * SetFileSecurityW [ADVAPI32.@]
2316 * Sets the security of a file or directory.
2318 * PARAMS
2319 * lpFileName []
2320 * RequestedInformation []
2321 * pSecurityDescriptor []
2323 * RETURNS
2324 * Success: TRUE.
2325 * Failure: FALSE.
2327 BOOL WINAPI
2328 SetFileSecurityW( LPCWSTR lpFileName,
2329 SECURITY_INFORMATION RequestedInformation,
2330 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2332 HANDLE file;
2333 DWORD access = 0;
2334 NTSTATUS status;
2336 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2337 pSecurityDescriptor );
2339 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2340 RequestedInformation & GROUP_SECURITY_INFORMATION)
2341 access |= WRITE_OWNER;
2342 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2343 access |= ACCESS_SYSTEM_SECURITY;
2344 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2345 access |= WRITE_DAC;
2347 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2348 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2349 if (file == INVALID_HANDLE_VALUE)
2350 return FALSE;
2352 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2353 CloseHandle( file );
2354 return set_ntstatus( status );
2357 /******************************************************************************
2358 * QueryWindows31FilesMigration [ADVAPI32.@]
2360 * PARAMS
2361 * x1 []
2363 BOOL WINAPI
2364 QueryWindows31FilesMigration( DWORD x1 )
2366 FIXME("(%d):stub\n",x1);
2367 return TRUE;
2370 /******************************************************************************
2371 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2373 * PARAMS
2374 * x1 []
2375 * x2 []
2376 * x3 []
2377 * x4 []
2379 BOOL WINAPI
2380 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2381 DWORD x4 )
2383 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2384 return TRUE;
2387 /******************************************************************************
2388 * NotifyBootConfigStatus [ADVAPI32.@]
2390 * PARAMS
2391 * x1 []
2393 BOOL WINAPI
2394 NotifyBootConfigStatus( BOOL x1 )
2396 FIXME("(0x%08d):stub\n",x1);
2397 return TRUE;
2400 /******************************************************************************
2401 * RevertToSelf [ADVAPI32.@]
2403 * Ends the impersonation of a user.
2405 * PARAMS
2406 * void []
2408 * RETURNS
2409 * Success: TRUE.
2410 * Failure: FALSE.
2412 BOOL WINAPI
2413 RevertToSelf( void )
2415 HANDLE Token = NULL;
2416 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2417 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2420 /******************************************************************************
2421 * ImpersonateSelf [ADVAPI32.@]
2423 * Makes an impersonation token that represents the process user and assigns
2424 * to the current thread.
2426 * PARAMS
2427 * ImpersonationLevel [I] Level at which to impersonate.
2429 * RETURNS
2430 * Success: TRUE.
2431 * Failure: FALSE.
2433 BOOL WINAPI
2434 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2436 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2439 /******************************************************************************
2440 * ImpersonateLoggedOnUser [ADVAPI32.@]
2442 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2444 DWORD size;
2445 NTSTATUS Status;
2446 HANDLE ImpersonationToken;
2447 TOKEN_TYPE Type;
2448 static BOOL warn = TRUE;
2450 if (warn)
2452 FIXME( "(%p)\n", hToken );
2453 warn = FALSE;
2455 if (!GetTokenInformation( hToken, TokenType, &Type,
2456 sizeof(TOKEN_TYPE), &size ))
2457 return FALSE;
2459 if (Type == TokenPrimary)
2461 OBJECT_ATTRIBUTES ObjectAttributes;
2463 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2465 Status = NtDuplicateToken( hToken,
2466 TOKEN_IMPERSONATE | TOKEN_QUERY,
2467 &ObjectAttributes,
2468 SecurityImpersonation,
2469 TokenImpersonation,
2470 &ImpersonationToken );
2471 if (Status != STATUS_SUCCESS)
2473 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2474 SetLastError( RtlNtStatusToDosError( Status ) );
2475 return FALSE;
2478 else
2479 ImpersonationToken = hToken;
2481 Status = NtSetInformationThread( GetCurrentThread(),
2482 ThreadImpersonationToken,
2483 &ImpersonationToken,
2484 sizeof(ImpersonationToken) );
2486 if (Type == TokenPrimary)
2487 NtClose( ImpersonationToken );
2489 if (Status != STATUS_SUCCESS)
2491 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2492 SetLastError( RtlNtStatusToDosError( Status ) );
2493 return FALSE;
2496 return TRUE;
2499 /******************************************************************************
2500 * AccessCheck [ADVAPI32.@]
2502 BOOL WINAPI
2503 AccessCheck(
2504 PSECURITY_DESCRIPTOR SecurityDescriptor,
2505 HANDLE ClientToken,
2506 DWORD DesiredAccess,
2507 PGENERIC_MAPPING GenericMapping,
2508 PPRIVILEGE_SET PrivilegeSet,
2509 LPDWORD PrivilegeSetLength,
2510 LPDWORD GrantedAccess,
2511 LPBOOL AccessStatus)
2513 NTSTATUS access_status;
2514 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2515 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2516 GrantedAccess, &access_status) );
2517 if (ret) *AccessStatus = set_ntstatus( access_status );
2518 return ret;
2522 /******************************************************************************
2523 * AccessCheckByType [ADVAPI32.@]
2525 BOOL WINAPI AccessCheckByType(
2526 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2527 PSID PrincipalSelfSid,
2528 HANDLE ClientToken,
2529 DWORD DesiredAccess,
2530 POBJECT_TYPE_LIST ObjectTypeList,
2531 DWORD ObjectTypeListLength,
2532 PGENERIC_MAPPING GenericMapping,
2533 PPRIVILEGE_SET PrivilegeSet,
2534 LPDWORD PrivilegeSetLength,
2535 LPDWORD GrantedAccess,
2536 LPBOOL AccessStatus)
2538 FIXME("stub\n");
2540 *AccessStatus = TRUE;
2542 return !*AccessStatus;
2545 /******************************************************************************
2546 * MapGenericMask [ADVAPI32.@]
2548 * Maps generic access rights into specific access rights according to the
2549 * supplied mapping.
2551 * PARAMS
2552 * AccessMask [I/O] Access rights.
2553 * GenericMapping [I] The mapping between generic and specific rights.
2555 * RETURNS
2556 * Nothing.
2558 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2560 RtlMapGenericMask( AccessMask, GenericMapping );
2563 /*************************************************************************
2564 * SetKernelObjectSecurity [ADVAPI32.@]
2566 BOOL WINAPI SetKernelObjectSecurity (
2567 IN HANDLE Handle,
2568 IN SECURITY_INFORMATION SecurityInformation,
2569 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2571 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2575 /******************************************************************************
2576 * AddAuditAccessAce [ADVAPI32.@]
2578 BOOL WINAPI AddAuditAccessAce(
2579 IN OUT PACL pAcl,
2580 IN DWORD dwAceRevision,
2581 IN DWORD dwAccessMask,
2582 IN PSID pSid,
2583 IN BOOL bAuditSuccess,
2584 IN BOOL bAuditFailure)
2586 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2587 bAuditSuccess, bAuditFailure) );
2590 /******************************************************************************
2591 * AddAuditAccessAce [ADVAPI32.@]
2593 BOOL WINAPI AddAuditAccessAceEx(
2594 IN OUT PACL pAcl,
2595 IN DWORD dwAceRevision,
2596 IN DWORD dwAceFlags,
2597 IN DWORD dwAccessMask,
2598 IN PSID pSid,
2599 IN BOOL bAuditSuccess,
2600 IN BOOL bAuditFailure)
2602 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2603 bAuditSuccess, bAuditFailure) );
2606 /******************************************************************************
2607 * LookupAccountNameA [ADVAPI32.@]
2609 BOOL WINAPI
2610 LookupAccountNameA(
2611 IN LPCSTR system,
2612 IN LPCSTR account,
2613 OUT PSID sid,
2614 OUT LPDWORD cbSid,
2615 LPSTR ReferencedDomainName,
2616 IN OUT LPDWORD cbReferencedDomainName,
2617 OUT PSID_NAME_USE name_use )
2619 BOOL ret;
2620 UNICODE_STRING lpSystemW;
2621 UNICODE_STRING lpAccountW;
2622 LPWSTR lpReferencedDomainNameW = NULL;
2624 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2625 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2627 if (ReferencedDomainName)
2628 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2630 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2631 cbReferencedDomainName, name_use);
2633 if (ret && lpReferencedDomainNameW)
2635 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2636 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2639 RtlFreeUnicodeString(&lpSystemW);
2640 RtlFreeUnicodeString(&lpAccountW);
2641 heap_free(lpReferencedDomainNameW);
2643 return ret;
2646 /******************************************************************************
2647 * lookup_user_account_name
2649 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2650 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2652 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2653 DWORD len = sizeof(buffer);
2654 HANDLE token;
2655 BOOL ret;
2656 PSID pSid;
2657 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2658 DWORD nameLen;
2660 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2662 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2663 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2666 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2667 CloseHandle( token );
2669 if (!ret) return FALSE;
2671 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2673 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2674 CopySid(*cbSid, Sid, pSid);
2675 if (*cbSid < GetLengthSid(pSid))
2677 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2678 ret = FALSE;
2680 *cbSid = GetLengthSid(pSid);
2682 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2683 if (!GetComputerNameW(domainName, &nameLen))
2685 domainName[0] = 0;
2686 nameLen = 0;
2688 if (*cchReferencedDomainName <= nameLen || !ret)
2690 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2691 nameLen += 1;
2692 ret = FALSE;
2694 else if (ReferencedDomainName)
2695 strcpyW(ReferencedDomainName, domainName);
2697 *cchReferencedDomainName = nameLen;
2699 if (ret)
2700 *peUse = SidTypeUser;
2702 return ret;
2705 /******************************************************************************
2706 * lookup_computer_account_name
2708 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2709 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2711 MAX_SID local;
2712 BOOL ret;
2713 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2714 DWORD nameLen;
2716 if ((ret = ADVAPI_GetComputerSid(&local)))
2718 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2719 CopySid(*cbSid, Sid, &local);
2720 if (*cbSid < GetLengthSid(&local))
2722 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2723 ret = FALSE;
2725 *cbSid = GetLengthSid(&local);
2728 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2729 if (!GetComputerNameW(domainName, &nameLen))
2731 domainName[0] = 0;
2732 nameLen = 0;
2734 if (*cchReferencedDomainName <= nameLen || !ret)
2736 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2737 nameLen += 1;
2738 ret = FALSE;
2740 else if (ReferencedDomainName)
2741 strcpyW(ReferencedDomainName, domainName);
2743 *cchReferencedDomainName = nameLen;
2745 if (ret)
2746 *peUse = SidTypeDomain;
2748 return ret;
2751 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2752 LSA_UNICODE_STRING *domain )
2754 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2756 while (p > str->Buffer && *p != '\\') p--;
2758 if (*p == '\\')
2760 domain->Buffer = str->Buffer;
2761 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2763 account->Buffer = p + 1;
2764 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2766 else
2768 domain->Buffer = NULL;
2769 domain->Length = 0;
2771 account->Buffer = str->Buffer;
2772 account->Length = str->Length;
2776 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2778 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2780 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2781 return TRUE;
2783 return FALSE;
2786 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2788 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2790 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2791 return TRUE;
2793 if (ACCOUNT_SIDS[idx].alias)
2795 len = strlenW( ACCOUNT_SIDS[idx].alias );
2796 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2797 return TRUE;
2799 return FALSE;
2803 * Helper function for LookupAccountNameW
2805 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2806 PSID Sid, LPDWORD cbSid,
2807 LPWSTR ReferencedDomainName,
2808 LPDWORD cchReferencedDomainName,
2809 PSID_NAME_USE peUse, BOOL *handled )
2811 PSID pSid;
2812 LSA_UNICODE_STRING account, domain;
2813 BOOL ret = TRUE;
2814 ULONG i;
2816 *handled = FALSE;
2817 split_domain_account( account_and_domain, &account, &domain );
2819 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2821 /* check domain first */
2822 if (domain.Buffer && !match_domain( i, &domain )) continue;
2824 if (match_account( i, &account ))
2826 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2828 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
2830 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2832 if (*cbSid < sidLen)
2834 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2835 ret = FALSE;
2837 else if (Sid)
2839 CopySid(*cbSid, Sid, pSid);
2841 *cbSid = sidLen;
2844 len = strlenW( ACCOUNT_SIDS[i].domain );
2845 if (*cchReferencedDomainName <= len || !ret)
2847 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2848 len++;
2849 ret = FALSE;
2851 else if (ReferencedDomainName)
2853 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2856 *cchReferencedDomainName = len;
2857 if (ret)
2858 *peUse = ACCOUNT_SIDS[i].name_use;
2860 heap_free(pSid);
2861 *handled = TRUE;
2862 return ret;
2865 return ret;
2868 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2869 PSID Sid, LPDWORD cbSid,
2870 LPWSTR ReferencedDomainName,
2871 LPDWORD cchReferencedDomainName,
2872 PSID_NAME_USE peUse, BOOL *handled )
2874 DWORD nameLen;
2875 LPWSTR userName = NULL;
2876 LSA_UNICODE_STRING account, domain;
2877 BOOL ret = TRUE;
2879 *handled = FALSE;
2880 split_domain_account( account_and_domain, &account, &domain );
2882 /* Let the current Unix user id masquerade as first Windows user account */
2884 nameLen = UNLEN + 1;
2885 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
2887 if (domain.Buffer)
2889 /* check to make sure this account is on this computer */
2890 if (GetComputerNameW( userName, &nameLen ) &&
2891 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2893 SetLastError(ERROR_NONE_MAPPED);
2894 ret = FALSE;
2896 nameLen = UNLEN + 1;
2899 if (GetUserNameW( userName, &nameLen ) &&
2900 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2902 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2903 *handled = TRUE;
2905 else
2907 nameLen = UNLEN + 1;
2908 if (GetComputerNameW( userName, &nameLen ) &&
2909 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2911 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2912 *handled = TRUE;
2916 heap_free(userName);
2917 return ret;
2920 /******************************************************************************
2921 * LookupAccountNameW [ADVAPI32.@]
2923 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2924 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2925 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2927 BOOL ret, handled;
2928 LSA_UNICODE_STRING account;
2930 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2931 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2933 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2935 FIXME("remote computer not supported\n");
2936 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2937 return FALSE;
2940 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2942 lpAccountName = BUILTIN;
2945 RtlInitUnicodeString( &account, lpAccountName );
2947 /* Check well known SIDs first */
2948 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2949 cchReferencedDomainName, peUse, &handled );
2950 if (handled)
2951 return ret;
2953 /* Check user names */
2954 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2955 cchReferencedDomainName, peUse, &handled);
2956 if (handled)
2957 return ret;
2959 SetLastError( ERROR_NONE_MAPPED );
2960 return FALSE;
2963 /******************************************************************************
2964 * PrivilegeCheck [ADVAPI32.@]
2966 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2968 BOOL ret;
2969 BOOLEAN Result;
2971 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2973 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2974 if (ret)
2975 *pfResult = Result;
2976 return ret;
2979 /******************************************************************************
2980 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2982 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2983 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2984 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2985 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2987 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2988 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2989 SecurityDescriptor, DesiredAccess, GenericMapping,
2990 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2991 return TRUE;
2994 /******************************************************************************
2995 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2997 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2998 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2999 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3000 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3002 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3003 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3004 SecurityDescriptor, DesiredAccess, GenericMapping,
3005 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3006 return TRUE;
3009 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3011 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3013 return TRUE;
3016 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3018 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3020 return TRUE;
3023 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3025 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3027 return TRUE;
3030 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3031 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3032 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3033 LPBOOL GenerateOnClose)
3035 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3036 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3037 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3038 GenerateOnClose);
3040 return TRUE;
3043 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3044 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3045 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3046 LPBOOL GenerateOnClose)
3048 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3049 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3050 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3051 GenerateOnClose);
3053 return TRUE;
3056 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3057 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3059 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3060 DesiredAccess, Privileges, AccessGranted);
3062 return TRUE;
3065 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3066 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3068 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3069 DesiredAccess, Privileges, AccessGranted);
3071 return TRUE;
3074 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3075 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3077 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3078 ClientToken, Privileges, AccessGranted);
3080 return TRUE;
3083 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3084 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3086 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3087 ClientToken, Privileges, AccessGranted);
3089 return TRUE;
3092 /******************************************************************************
3093 * GetSecurityInfo [ADVAPI32.@]
3095 * Retrieves a copy of the security descriptor associated with an object.
3097 * PARAMS
3098 * hObject [I] A handle for the object.
3099 * ObjectType [I] The type of object.
3100 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3101 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3102 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3103 * ppDacl [O] If non-null, receives a pointer to the DACL.
3104 * ppSacl [O] If non-null, receives a pointer to the SACL.
3105 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3106 * which must be freed with LocalFree.
3108 * RETURNS
3109 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3111 DWORD WINAPI GetSecurityInfo(
3112 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3113 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3114 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3115 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3118 PSECURITY_DESCRIPTOR sd;
3119 NTSTATUS status;
3120 ULONG n1, n2;
3121 BOOL present, defaulted;
3123 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3124 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3126 /* If no descriptor, we have to check that there's a pointer for the requested information */
3127 if( !ppSecurityDescriptor && (
3128 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3129 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3130 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3131 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3132 return ERROR_INVALID_PARAMETER;
3134 switch (ObjectType)
3136 case SE_SERVICE:
3137 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3138 break;
3139 default:
3140 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3141 break;
3143 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3144 return RtlNtStatusToDosError(status);
3146 sd = LocalAlloc(0, n1);
3147 if (!sd)
3148 return ERROR_NOT_ENOUGH_MEMORY;
3150 switch (ObjectType)
3152 case SE_SERVICE:
3153 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3154 break;
3155 default:
3156 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3157 break;
3159 if (status != STATUS_SUCCESS)
3161 LocalFree(sd);
3162 return RtlNtStatusToDosError(status);
3165 if (ppsidOwner)
3167 *ppsidOwner = NULL;
3168 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3170 if (ppsidGroup)
3172 *ppsidGroup = NULL;
3173 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3175 if (ppDacl)
3177 *ppDacl = NULL;
3178 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3180 if (ppSacl)
3182 *ppSacl = NULL;
3183 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3185 if (ppSecurityDescriptor)
3186 *ppSecurityDescriptor = sd;
3188 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3189 * NULL, because native happily returns the SIDs and ACLs that are requested
3190 * in this case.
3193 return ERROR_SUCCESS;
3196 /******************************************************************************
3197 * GetSecurityInfoExA [ADVAPI32.@]
3199 DWORD WINAPI GetSecurityInfoExA(
3200 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3201 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3202 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3203 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3206 FIXME("stub!\n");
3207 return ERROR_BAD_PROVIDER;
3210 /******************************************************************************
3211 * GetSecurityInfoExW [ADVAPI32.@]
3213 DWORD WINAPI GetSecurityInfoExW(
3214 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3215 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3216 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3217 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3220 FIXME("stub!\n");
3221 return ERROR_BAD_PROVIDER;
3224 /******************************************************************************
3225 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3227 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3228 LPSTR pTrusteeName, DWORD AccessPermissions,
3229 ACCESS_MODE AccessMode, DWORD Inheritance )
3231 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3232 AccessPermissions, AccessMode, Inheritance);
3234 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3235 pExplicitAccess->grfAccessMode = AccessMode;
3236 pExplicitAccess->grfInheritance = Inheritance;
3238 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3239 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3240 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3241 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3242 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3245 /******************************************************************************
3246 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3248 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3249 LPWSTR pTrusteeName, DWORD AccessPermissions,
3250 ACCESS_MODE AccessMode, DWORD Inheritance )
3252 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3253 AccessPermissions, AccessMode, Inheritance);
3255 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3256 pExplicitAccess->grfAccessMode = AccessMode;
3257 pExplicitAccess->grfInheritance = Inheritance;
3259 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3260 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3261 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3262 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3263 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3266 /******************************************************************************
3267 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3269 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3270 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3271 LPSTR InheritedObjectTypeName, LPSTR Name )
3273 DWORD ObjectsPresent = 0;
3275 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3276 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3278 /* Fill the OBJECTS_AND_NAME structure */
3279 pObjName->ObjectType = ObjectType;
3280 if (ObjectTypeName != NULL)
3282 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3285 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3286 if (InheritedObjectTypeName != NULL)
3288 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3291 pObjName->ObjectsPresent = ObjectsPresent;
3292 pObjName->ptstrName = Name;
3294 /* Fill the TRUSTEE structure */
3295 pTrustee->pMultipleTrustee = NULL;
3296 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3297 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3298 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3299 pTrustee->ptstrName = (LPSTR)pObjName;
3302 /******************************************************************************
3303 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3305 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3306 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3307 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3309 DWORD ObjectsPresent = 0;
3311 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3312 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3314 /* Fill the OBJECTS_AND_NAME structure */
3315 pObjName->ObjectType = ObjectType;
3316 if (ObjectTypeName != NULL)
3318 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3321 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3322 if (InheritedObjectTypeName != NULL)
3324 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3327 pObjName->ObjectsPresent = ObjectsPresent;
3328 pObjName->ptstrName = Name;
3330 /* Fill the TRUSTEE structure */
3331 pTrustee->pMultipleTrustee = NULL;
3332 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3333 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3334 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3335 pTrustee->ptstrName = (LPWSTR)pObjName;
3338 /******************************************************************************
3339 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3341 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3342 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3344 DWORD ObjectsPresent = 0;
3346 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3348 /* Fill the OBJECTS_AND_SID structure */
3349 if (pObjectGuid != NULL)
3351 pObjSid->ObjectTypeGuid = *pObjectGuid;
3352 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3354 else
3356 ZeroMemory(&pObjSid->ObjectTypeGuid,
3357 sizeof(GUID));
3360 if (pInheritedObjectGuid != NULL)
3362 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3363 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3365 else
3367 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3368 sizeof(GUID));
3371 pObjSid->ObjectsPresent = ObjectsPresent;
3372 pObjSid->pSid = pSid;
3374 /* Fill the TRUSTEE structure */
3375 pTrustee->pMultipleTrustee = NULL;
3376 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3377 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3378 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3379 pTrustee->ptstrName = (LPSTR) pObjSid;
3382 /******************************************************************************
3383 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3385 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3386 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3388 DWORD ObjectsPresent = 0;
3390 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3392 /* Fill the OBJECTS_AND_SID structure */
3393 if (pObjectGuid != NULL)
3395 pObjSid->ObjectTypeGuid = *pObjectGuid;
3396 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3398 else
3400 ZeroMemory(&pObjSid->ObjectTypeGuid,
3401 sizeof(GUID));
3404 if (pInheritedObjectGuid != NULL)
3406 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3407 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3409 else
3411 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3412 sizeof(GUID));
3415 pObjSid->ObjectsPresent = ObjectsPresent;
3416 pObjSid->pSid = pSid;
3418 /* Fill the TRUSTEE structure */
3419 pTrustee->pMultipleTrustee = NULL;
3420 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3421 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3422 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3423 pTrustee->ptstrName = (LPWSTR) pObjSid;
3426 /******************************************************************************
3427 * BuildTrusteeWithSidA [ADVAPI32.@]
3429 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3431 TRACE("%p %p\n", pTrustee, pSid);
3433 pTrustee->pMultipleTrustee = NULL;
3434 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3435 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3436 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3437 pTrustee->ptstrName = pSid;
3440 /******************************************************************************
3441 * BuildTrusteeWithSidW [ADVAPI32.@]
3443 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3445 TRACE("%p %p\n", pTrustee, pSid);
3447 pTrustee->pMultipleTrustee = NULL;
3448 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3449 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3450 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3451 pTrustee->ptstrName = pSid;
3454 /******************************************************************************
3455 * BuildTrusteeWithNameA [ADVAPI32.@]
3457 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3459 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3461 pTrustee->pMultipleTrustee = NULL;
3462 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3463 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3464 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3465 pTrustee->ptstrName = name;
3468 /******************************************************************************
3469 * BuildTrusteeWithNameW [ADVAPI32.@]
3471 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3473 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3475 pTrustee->pMultipleTrustee = NULL;
3476 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3477 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3478 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3479 pTrustee->ptstrName = name;
3482 /******************************************************************************
3483 * GetTrusteeFormA [ADVAPI32.@]
3485 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3487 TRACE("(%p)\n", pTrustee);
3489 if (!pTrustee)
3490 return TRUSTEE_BAD_FORM;
3492 return pTrustee->TrusteeForm;
3495 /******************************************************************************
3496 * GetTrusteeFormW [ADVAPI32.@]
3498 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3500 TRACE("(%p)\n", pTrustee);
3502 if (!pTrustee)
3503 return TRUSTEE_BAD_FORM;
3505 return pTrustee->TrusteeForm;
3508 /******************************************************************************
3509 * GetTrusteeNameA [ADVAPI32.@]
3511 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3513 TRACE("(%p)\n", pTrustee);
3515 if (!pTrustee)
3516 return NULL;
3518 return pTrustee->ptstrName;
3521 /******************************************************************************
3522 * GetTrusteeNameW [ADVAPI32.@]
3524 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3526 TRACE("(%p)\n", pTrustee);
3528 if (!pTrustee)
3529 return NULL;
3531 return pTrustee->ptstrName;
3534 /******************************************************************************
3535 * GetTrusteeTypeA [ADVAPI32.@]
3537 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3539 TRACE("(%p)\n", pTrustee);
3541 if (!pTrustee)
3542 return TRUSTEE_IS_UNKNOWN;
3544 return pTrustee->TrusteeType;
3547 /******************************************************************************
3548 * GetTrusteeTypeW [ADVAPI32.@]
3550 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3552 TRACE("(%p)\n", pTrustee);
3554 if (!pTrustee)
3555 return TRUSTEE_IS_UNKNOWN;
3557 return pTrustee->TrusteeType;
3560 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3561 DWORD nAclInformationLength,
3562 ACL_INFORMATION_CLASS dwAclInformationClass )
3564 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3565 nAclInformationLength, dwAclInformationClass);
3567 return TRUE;
3570 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3572 switch (form)
3574 case TRUSTEE_IS_NAME:
3576 *ptrustee_nameW = SERV_dup(trustee_nameA);
3577 return ERROR_SUCCESS;
3579 case TRUSTEE_IS_OBJECTS_AND_NAME:
3581 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3582 OBJECTS_AND_NAME_W *objW = NULL;
3584 if (objA)
3586 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3587 return ERROR_NOT_ENOUGH_MEMORY;
3589 objW->ObjectsPresent = objA->ObjectsPresent;
3590 objW->ObjectType = objA->ObjectType;
3591 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3592 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3593 objW->ptstrName = SERV_dup(objA->ptstrName);
3596 *ptrustee_nameW = (WCHAR *)objW;
3597 return ERROR_SUCCESS;
3599 /* These forms do not require conversion. */
3600 case TRUSTEE_IS_SID:
3601 case TRUSTEE_IS_OBJECTS_AND_SID:
3602 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3603 return ERROR_SUCCESS;
3604 default:
3605 return ERROR_INVALID_PARAMETER;
3609 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3611 switch (form)
3613 case TRUSTEE_IS_NAME:
3614 heap_free( trustee_nameW );
3615 break;
3616 case TRUSTEE_IS_OBJECTS_AND_NAME:
3618 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3620 if (objW)
3622 heap_free( objW->ptstrName );
3623 heap_free( objW->InheritedObjectTypeName );
3624 heap_free( objW->ObjectTypeName );
3625 heap_free( objW );
3628 break;
3630 /* Other forms did not require allocation, so no freeing is necessary. */
3631 default:
3632 break;
3636 /******************************************************************************
3637 * SetEntriesInAclA [ADVAPI32.@]
3639 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3640 PACL OldAcl, PACL* NewAcl )
3642 DWORD err = ERROR_SUCCESS;
3643 EXPLICIT_ACCESSW *pEntriesW;
3644 UINT alloc_index, free_index;
3646 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3648 if (NewAcl)
3649 *NewAcl = NULL;
3651 if (!count && !OldAcl)
3652 return ERROR_SUCCESS;
3654 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3655 if (!pEntriesW)
3656 return ERROR_NOT_ENOUGH_MEMORY;
3658 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3660 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3661 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3662 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3663 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3664 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3665 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3666 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3668 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3669 pEntries[alloc_index].Trustee.ptstrName,
3670 &pEntriesW[alloc_index].Trustee.ptstrName );
3671 if (err != ERROR_SUCCESS)
3673 if (err == ERROR_INVALID_PARAMETER)
3674 WARN("bad trustee form %d for trustee %d\n",
3675 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3677 goto cleanup;
3681 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3683 cleanup:
3684 /* Free any previously allocated trustee name buffers, taking into account
3685 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3686 * list. */
3687 for (free_index = 0; free_index < alloc_index; ++free_index)
3688 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3690 heap_free( pEntriesW );
3691 return err;
3694 /******************************************************************************
3695 * SetEntriesInAclW [ADVAPI32.@]
3697 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3698 PACL OldAcl, PACL* NewAcl )
3700 ULONG i;
3701 PSID *ppsid;
3702 DWORD ret = ERROR_SUCCESS;
3703 DWORD acl_size = sizeof(ACL);
3704 NTSTATUS status;
3706 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3708 if (NewAcl)
3709 *NewAcl = NULL;
3711 if (!count && !OldAcl)
3712 return ERROR_SUCCESS;
3714 /* allocate array of maximum sized sids allowed */
3715 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3716 if (!ppsid)
3717 return ERROR_OUTOFMEMORY;
3719 for (i = 0; i < count; i++)
3721 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3723 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3724 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3725 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3726 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3727 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3728 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3729 pEntries[i].Trustee.ptstrName);
3731 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3733 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3734 ret = ERROR_INVALID_PARAMETER;
3735 goto exit;
3738 switch (pEntries[i].Trustee.TrusteeForm)
3740 case TRUSTEE_IS_SID:
3741 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3742 ppsid[i], pEntries[i].Trustee.ptstrName))
3744 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3745 ret = ERROR_INVALID_PARAMETER;
3746 goto exit;
3748 break;
3749 case TRUSTEE_IS_NAME:
3751 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3752 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3753 SID_NAME_USE use;
3754 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3756 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3758 ret = GetLastError();
3759 goto exit;
3762 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3764 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3765 ret = ERROR_INVALID_PARAMETER;
3766 goto exit;
3768 break;
3770 case TRUSTEE_IS_OBJECTS_AND_SID:
3771 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3772 break;
3773 case TRUSTEE_IS_OBJECTS_AND_NAME:
3774 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3775 break;
3776 default:
3777 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3778 ret = ERROR_INVALID_PARAMETER;
3779 goto exit;
3782 /* Note: we overestimate the ACL size here as a tradeoff between
3783 * instructions (simplicity) and memory */
3784 switch (pEntries[i].grfAccessMode)
3786 case GRANT_ACCESS:
3787 case SET_ACCESS:
3788 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3789 break;
3790 case DENY_ACCESS:
3791 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3792 break;
3793 case SET_AUDIT_SUCCESS:
3794 case SET_AUDIT_FAILURE:
3795 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3796 break;
3797 case REVOKE_ACCESS:
3798 break;
3799 default:
3800 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3801 ret = ERROR_INVALID_PARAMETER;
3802 goto exit;
3806 if (OldAcl)
3808 ACL_SIZE_INFORMATION size_info;
3810 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3811 if (status != STATUS_SUCCESS)
3813 ret = RtlNtStatusToDosError(status);
3814 goto exit;
3816 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3819 *NewAcl = LocalAlloc(0, acl_size);
3820 if (!*NewAcl)
3822 ret = ERROR_OUTOFMEMORY;
3823 goto exit;
3826 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3827 if (status != STATUS_SUCCESS)
3829 ret = RtlNtStatusToDosError(status);
3830 goto exit;
3833 for (i = 0; i < count; i++)
3835 switch (pEntries[i].grfAccessMode)
3837 case GRANT_ACCESS:
3838 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3839 pEntries[i].grfInheritance,
3840 pEntries[i].grfAccessPermissions,
3841 ppsid[i]);
3842 break;
3843 case SET_ACCESS:
3845 ULONG j;
3846 BOOL add = TRUE;
3847 if (OldAcl)
3849 for (j = 0; ; j++)
3851 const ACE_HEADER *existing_ace_header;
3852 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3853 if (status != STATUS_SUCCESS)
3854 break;
3855 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3856 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3857 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3859 add = FALSE;
3860 break;
3864 if (add)
3865 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3866 pEntries[i].grfInheritance,
3867 pEntries[i].grfAccessPermissions,
3868 ppsid[i]);
3869 break;
3871 case DENY_ACCESS:
3872 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3873 pEntries[i].grfInheritance,
3874 pEntries[i].grfAccessPermissions,
3875 ppsid[i]);
3876 break;
3877 case SET_AUDIT_SUCCESS:
3878 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3879 pEntries[i].grfInheritance,
3880 pEntries[i].grfAccessPermissions,
3881 ppsid[i], TRUE, FALSE);
3882 break;
3883 case SET_AUDIT_FAILURE:
3884 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3885 pEntries[i].grfInheritance,
3886 pEntries[i].grfAccessPermissions,
3887 ppsid[i], FALSE, TRUE);
3888 break;
3889 default:
3890 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3894 if (OldAcl)
3896 for (i = 0; ; i++)
3898 BOOL add = TRUE;
3899 ULONG j;
3900 const ACE_HEADER *old_ace_header;
3901 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3902 if (status != STATUS_SUCCESS) break;
3903 for (j = 0; j < count; j++)
3905 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3906 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3907 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3909 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3910 add = FALSE;
3911 break;
3913 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3915 switch (old_ace_header->AceType)
3917 case ACCESS_ALLOWED_ACE_TYPE:
3918 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3919 add = FALSE;
3920 break;
3921 case ACCESS_DENIED_ACE_TYPE:
3922 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3923 add = FALSE;
3924 break;
3925 case SYSTEM_AUDIT_ACE_TYPE:
3926 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3927 add = FALSE;
3928 break;
3929 case SYSTEM_ALARM_ACE_TYPE:
3930 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3931 add = FALSE;
3932 break;
3933 default:
3934 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3937 if (!add)
3938 break;
3941 if (add)
3942 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3943 if (status != STATUS_SUCCESS)
3945 WARN("RtlAddAce failed with error 0x%08x\n", status);
3946 ret = RtlNtStatusToDosError(status);
3947 break;
3952 exit:
3953 heap_free(ppsid);
3954 return ret;
3957 /******************************************************************************
3958 * SetNamedSecurityInfoA [ADVAPI32.@]
3960 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3961 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3962 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3964 LPWSTR wstr;
3965 DWORD r;
3967 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3968 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3970 wstr = SERV_dup(pObjectName);
3971 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3972 psidGroup, pDacl, pSacl );
3974 heap_free( wstr );
3976 return r;
3979 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3980 PSECURITY_DESCRIPTOR ModificationDescriptor,
3981 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3982 PGENERIC_MAPPING GenericMapping,
3983 HANDLE Token )
3985 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3986 ObjectsSecurityDescriptor, GenericMapping, Token);
3988 return TRUE;
3991 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3993 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3996 /******************************************************************************
3997 * AreAnyAccessesGranted [ADVAPI32.@]
3999 * Determines whether or not any of a set of specified access permissions have
4000 * been granted or not.
4002 * PARAMS
4003 * GrantedAccess [I] The permissions that have been granted.
4004 * DesiredAccess [I] The permissions that you want to have.
4006 * RETURNS
4007 * Nonzero if any of the permissions have been granted, zero if none of the
4008 * permissions have been granted.
4011 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4013 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4016 /******************************************************************************
4017 * SetNamedSecurityInfoW [ADVAPI32.@]
4019 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4020 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4021 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4023 DWORD access = 0;
4024 HANDLE handle;
4025 DWORD err;
4027 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4028 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4030 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4032 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4033 access |= WRITE_OWNER;
4034 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4035 access |= WRITE_DAC;
4036 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4037 access |= ACCESS_SYSTEM_SECURITY;
4039 switch (ObjectType)
4041 case SE_SERVICE:
4042 if (!(err = get_security_service( pObjectName, access, &handle )))
4044 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4045 CloseServiceHandle( handle );
4047 break;
4048 case SE_REGISTRY_KEY:
4049 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4051 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4052 RegCloseKey( handle );
4054 break;
4055 case SE_FILE_OBJECT:
4056 if (!(err = get_security_file( pObjectName, access, &handle )))
4058 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4059 CloseHandle( handle );
4061 break;
4062 default:
4063 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4064 return ERROR_SUCCESS;
4066 return err;
4069 /******************************************************************************
4070 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4072 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4073 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4075 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4076 return ERROR_CALL_NOT_IMPLEMENTED;
4079 /******************************************************************************
4080 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4082 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4083 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4085 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4086 return ERROR_CALL_NOT_IMPLEMENTED;
4089 /******************************************************************************
4090 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4092 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4093 PACCESS_MASK pFailedAuditRights)
4095 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4096 return ERROR_CALL_NOT_IMPLEMENTED;
4100 /******************************************************************************
4101 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4103 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4104 PACCESS_MASK pFailedAuditRights)
4106 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4107 return ERROR_CALL_NOT_IMPLEMENTED;
4111 /******************************************************************************
4112 * ParseAclStringFlags
4114 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4116 DWORD flags = 0;
4117 LPCWSTR szAcl = *StringAcl;
4119 while (*szAcl != '(')
4121 if (*szAcl == 'P')
4123 flags |= SE_DACL_PROTECTED;
4125 else if (*szAcl == 'A')
4127 szAcl++;
4128 if (*szAcl == 'R')
4129 flags |= SE_DACL_AUTO_INHERIT_REQ;
4130 else if (*szAcl == 'I')
4131 flags |= SE_DACL_AUTO_INHERITED;
4133 szAcl++;
4136 *StringAcl = szAcl;
4137 return flags;
4140 /******************************************************************************
4141 * ParseAceStringType
4143 static const ACEFLAG AceType[] =
4145 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4146 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4147 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4148 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4150 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4151 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4152 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4153 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4155 { NULL, 0 },
4158 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4160 UINT len = 0;
4161 LPCWSTR szAcl = *StringAcl;
4162 const ACEFLAG *lpaf = AceType;
4164 while (*szAcl == ' ')
4165 szAcl++;
4167 while (lpaf->wstr &&
4168 (len = strlenW(lpaf->wstr)) &&
4169 strncmpW(lpaf->wstr, szAcl, len))
4170 lpaf++;
4172 if (!lpaf->wstr)
4173 return 0;
4175 *StringAcl = szAcl + len;
4176 return lpaf->value;
4180 /******************************************************************************
4181 * ParseAceStringFlags
4183 static const ACEFLAG AceFlags[] =
4185 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4186 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4187 { SDDL_INHERITED, INHERITED_ACE },
4188 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4189 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4190 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4191 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4192 { NULL, 0 },
4195 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4197 UINT len = 0;
4198 BYTE flags = 0;
4199 LPCWSTR szAcl = *StringAcl;
4201 while (*szAcl == ' ')
4202 szAcl++;
4204 while (*szAcl != ';')
4206 const ACEFLAG *lpaf = AceFlags;
4208 while (lpaf->wstr &&
4209 (len = strlenW(lpaf->wstr)) &&
4210 strncmpW(lpaf->wstr, szAcl, len))
4211 lpaf++;
4213 if (!lpaf->wstr)
4214 return 0;
4216 flags |= lpaf->value;
4217 szAcl += len;
4220 *StringAcl = szAcl;
4221 return flags;
4225 /******************************************************************************
4226 * ParseAceStringRights
4228 static const ACEFLAG AceRights[] =
4230 { SDDL_GENERIC_ALL, GENERIC_ALL },
4231 { SDDL_GENERIC_READ, GENERIC_READ },
4232 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4233 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4235 { SDDL_READ_CONTROL, READ_CONTROL },
4236 { SDDL_STANDARD_DELETE, DELETE },
4237 { SDDL_WRITE_DAC, WRITE_DAC },
4238 { SDDL_WRITE_OWNER, WRITE_OWNER },
4240 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4241 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4242 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4243 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4244 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4245 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4246 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4247 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4248 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4250 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4251 { SDDL_FILE_READ, FILE_GENERIC_READ },
4252 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4253 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4255 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4256 { SDDL_KEY_READ, KEY_READ },
4257 { SDDL_KEY_WRITE, KEY_WRITE },
4258 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4259 { NULL, 0 },
4262 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4264 UINT len = 0;
4265 DWORD rights = 0;
4266 LPCWSTR szAcl = *StringAcl;
4268 while (*szAcl == ' ')
4269 szAcl++;
4271 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4273 LPCWSTR p = szAcl;
4275 while (*p && *p != ';')
4276 p++;
4278 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4280 rights = strtoulW(szAcl, NULL, 16);
4281 szAcl = p;
4283 else
4284 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4286 else
4288 while (*szAcl != ';')
4290 const ACEFLAG *lpaf = AceRights;
4292 while (lpaf->wstr &&
4293 (len = strlenW(lpaf->wstr)) &&
4294 strncmpW(lpaf->wstr, szAcl, len))
4296 lpaf++;
4299 if (!lpaf->wstr)
4300 return 0;
4302 rights |= lpaf->value;
4303 szAcl += len;
4307 *StringAcl = szAcl;
4308 return rights;
4312 /******************************************************************************
4313 * ParseStringAclToAcl
4315 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4317 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4318 PACL pAcl, LPDWORD cBytes)
4320 DWORD val;
4321 DWORD sidlen;
4322 DWORD length = sizeof(ACL);
4323 DWORD acesize = 0;
4324 DWORD acecount = 0;
4325 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4326 DWORD error = ERROR_INVALID_ACL;
4328 TRACE("%s\n", debugstr_w(StringAcl));
4330 if (!StringAcl)
4331 return FALSE;
4333 if (pAcl) /* pAce is only useful if we're setting values */
4334 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4336 /* Parse ACL flags */
4337 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4339 /* Parse ACE */
4340 while (*StringAcl == '(')
4342 StringAcl++;
4344 /* Parse ACE type */
4345 val = ParseAceStringType(&StringAcl);
4346 if (pAce)
4347 pAce->Header.AceType = (BYTE) val;
4348 if (*StringAcl != ';')
4350 error = RPC_S_INVALID_STRING_UUID;
4351 goto lerr;
4353 StringAcl++;
4355 /* Parse ACE flags */
4356 val = ParseAceStringFlags(&StringAcl);
4357 if (pAce)
4358 pAce->Header.AceFlags = (BYTE) val;
4359 if (*StringAcl != ';')
4360 goto lerr;
4361 StringAcl++;
4363 /* Parse ACE rights */
4364 val = ParseAceStringRights(&StringAcl);
4365 if (pAce)
4366 pAce->Mask = val;
4367 if (*StringAcl != ';')
4368 goto lerr;
4369 StringAcl++;
4371 /* Parse ACE object guid */
4372 while (*StringAcl == ' ')
4373 StringAcl++;
4374 if (*StringAcl != ';')
4376 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4377 goto lerr;
4379 StringAcl++;
4381 /* Parse ACE inherit object guid */
4382 while (*StringAcl == ' ')
4383 StringAcl++;
4384 if (*StringAcl != ';')
4386 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4387 goto lerr;
4389 StringAcl++;
4391 /* Parse ACE account sid */
4392 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4394 while (*StringAcl && *StringAcl != ')')
4395 StringAcl++;
4398 if (*StringAcl != ')')
4399 goto lerr;
4400 StringAcl++;
4402 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4403 length += acesize;
4404 if (pAce)
4406 pAce->Header.AceSize = acesize;
4407 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4409 acecount++;
4412 *cBytes = length;
4414 if (length > 0xffff)
4416 ERR("ACL too large\n");
4417 goto lerr;
4420 if (pAcl)
4422 pAcl->AclRevision = ACL_REVISION;
4423 pAcl->Sbz1 = 0;
4424 pAcl->AclSize = length;
4425 pAcl->AceCount = acecount++;
4426 pAcl->Sbz2 = 0;
4428 return TRUE;
4430 lerr:
4431 SetLastError(error);
4432 WARN("Invalid ACE string format\n");
4433 return FALSE;
4437 /******************************************************************************
4438 * ParseStringSecurityDescriptorToSecurityDescriptor
4440 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4441 LPCWSTR StringSecurityDescriptor,
4442 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4443 LPDWORD cBytes)
4445 BOOL bret = FALSE;
4446 WCHAR toktype;
4447 WCHAR tok[MAX_PATH];
4448 LPCWSTR lptoken;
4449 LPBYTE lpNext = NULL;
4450 DWORD len;
4452 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4454 if (SecurityDescriptor)
4455 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4457 while (*StringSecurityDescriptor == ' ')
4458 StringSecurityDescriptor++;
4460 while (*StringSecurityDescriptor)
4462 toktype = *StringSecurityDescriptor;
4464 /* Expect char identifier followed by ':' */
4465 StringSecurityDescriptor++;
4466 if (*StringSecurityDescriptor != ':')
4468 SetLastError(ERROR_INVALID_PARAMETER);
4469 goto lend;
4471 StringSecurityDescriptor++;
4473 /* Extract token */
4474 lptoken = StringSecurityDescriptor;
4475 while (*lptoken && *lptoken != ':')
4476 lptoken++;
4478 if (*lptoken)
4479 lptoken--;
4481 len = lptoken - StringSecurityDescriptor;
4482 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4483 tok[len] = 0;
4485 switch (toktype)
4487 case 'O':
4489 DWORD bytes;
4491 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4492 goto lend;
4494 if (SecurityDescriptor)
4496 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4497 lpNext += bytes; /* Advance to next token */
4500 *cBytes += bytes;
4502 break;
4505 case 'G':
4507 DWORD bytes;
4509 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4510 goto lend;
4512 if (SecurityDescriptor)
4514 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4515 lpNext += bytes; /* Advance to next token */
4518 *cBytes += bytes;
4520 break;
4523 case 'D':
4525 DWORD flags;
4526 DWORD bytes;
4528 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4529 goto lend;
4531 if (SecurityDescriptor)
4533 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4534 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4535 lpNext += bytes; /* Advance to next token */
4538 *cBytes += bytes;
4540 break;
4543 case 'S':
4545 DWORD flags;
4546 DWORD bytes;
4548 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4549 goto lend;
4551 if (SecurityDescriptor)
4553 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4554 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4555 lpNext += bytes; /* Advance to next token */
4558 *cBytes += bytes;
4560 break;
4563 default:
4564 FIXME("Unknown token\n");
4565 SetLastError(ERROR_INVALID_PARAMETER);
4566 goto lend;
4569 StringSecurityDescriptor = lptoken;
4572 bret = TRUE;
4574 lend:
4575 return bret;
4578 /******************************************************************************
4579 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4581 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4582 LPCSTR StringSecurityDescriptor,
4583 DWORD StringSDRevision,
4584 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4585 PULONG SecurityDescriptorSize)
4587 BOOL ret;
4588 LPWSTR StringSecurityDescriptorW;
4590 if(!StringSecurityDescriptor)
4591 return FALSE;
4593 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4594 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4595 StringSDRevision, SecurityDescriptor,
4596 SecurityDescriptorSize);
4597 heap_free(StringSecurityDescriptorW);
4599 return ret;
4602 /******************************************************************************
4603 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4605 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4606 LPCWSTR StringSecurityDescriptor,
4607 DWORD StringSDRevision,
4608 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4609 PULONG SecurityDescriptorSize)
4611 DWORD cBytes;
4612 SECURITY_DESCRIPTOR* psd;
4613 BOOL bret = FALSE;
4615 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4617 if (GetVersion() & 0x80000000)
4619 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4620 goto lend;
4622 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4624 SetLastError(ERROR_INVALID_PARAMETER);
4625 goto lend;
4627 else if (StringSDRevision != SID_REVISION)
4629 SetLastError(ERROR_UNKNOWN_REVISION);
4630 goto lend;
4633 /* Compute security descriptor length */
4634 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4635 NULL, &cBytes))
4636 goto lend;
4638 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4639 if (!psd) goto lend;
4641 psd->Revision = SID_REVISION;
4642 psd->Control |= SE_SELF_RELATIVE;
4644 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4645 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4647 LocalFree(psd);
4648 goto lend;
4651 if (SecurityDescriptorSize)
4652 *SecurityDescriptorSize = cBytes;
4654 bret = TRUE;
4656 lend:
4657 TRACE(" ret=%d\n", bret);
4658 return bret;
4661 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4663 if (cch == -1)
4664 cch = strlenW(string);
4666 if (plen)
4667 *plen += cch;
4669 if (pwptr)
4671 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4672 *pwptr += cch;
4676 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4678 DWORD i;
4679 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4680 WCHAR subauthfmt[] = { '-','%','u',0 };
4681 WCHAR buf[26];
4682 SID *pisid = psid;
4684 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4686 SetLastError(ERROR_INVALID_SID);
4687 return FALSE;
4690 if (pisid->IdentifierAuthority.Value[0] ||
4691 pisid->IdentifierAuthority.Value[1])
4693 FIXME("not matching MS' bugs\n");
4694 SetLastError(ERROR_INVALID_SID);
4695 return FALSE;
4698 sprintfW( buf, fmt, pisid->Revision,
4699 MAKELONG(
4700 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4701 pisid->IdentifierAuthority.Value[4] ),
4702 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4703 pisid->IdentifierAuthority.Value[2] )
4704 ) );
4705 DumpString(buf, -1, pwptr, plen);
4707 for( i=0; i<pisid->SubAuthorityCount; i++ )
4709 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4710 DumpString(buf, -1, pwptr, plen);
4712 return TRUE;
4715 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4717 size_t i;
4718 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4720 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4722 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4723 return TRUE;
4727 return DumpSidNumeric(psid, pwptr, plen);
4730 static const LPCWSTR AceRightBitNames[32] = {
4731 SDDL_CREATE_CHILD, /* 0 */
4732 SDDL_DELETE_CHILD,
4733 SDDL_LIST_CHILDREN,
4734 SDDL_SELF_WRITE,
4735 SDDL_READ_PROPERTY, /* 4 */
4736 SDDL_WRITE_PROPERTY,
4737 SDDL_DELETE_TREE,
4738 SDDL_LIST_OBJECT,
4739 SDDL_CONTROL_ACCESS, /* 8 */
4740 NULL,
4741 NULL,
4742 NULL,
4743 NULL, /* 12 */
4744 NULL,
4745 NULL,
4746 NULL,
4747 SDDL_STANDARD_DELETE, /* 16 */
4748 SDDL_READ_CONTROL,
4749 SDDL_WRITE_DAC,
4750 SDDL_WRITE_OWNER,
4751 NULL, /* 20 */
4752 NULL,
4753 NULL,
4754 NULL,
4755 NULL, /* 24 */
4756 NULL,
4757 NULL,
4758 NULL,
4759 SDDL_GENERIC_ALL, /* 28 */
4760 SDDL_GENERIC_EXECUTE,
4761 SDDL_GENERIC_WRITE,
4762 SDDL_GENERIC_READ
4765 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4767 static const WCHAR fmtW[] = {'0','x','%','x',0};
4768 WCHAR buf[15];
4769 size_t i;
4771 if (mask == 0)
4772 return;
4774 /* first check if the right have name */
4775 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4777 if (AceRights[i].wstr == NULL)
4778 break;
4779 if (mask == AceRights[i].value)
4781 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4782 return;
4786 /* then check if it can be built from bit names */
4787 for (i = 0; i < 32; i++)
4789 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4791 /* can't be built from bit names */
4792 sprintfW(buf, fmtW, mask);
4793 DumpString(buf, -1, pwptr, plen);
4794 return;
4798 /* build from bit names */
4799 for (i = 0; i < 32; i++)
4800 if (mask & (1 << i))
4801 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4804 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4806 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4807 static const WCHAR openbr = '(';
4808 static const WCHAR closebr = ')';
4809 static const WCHAR semicolon = ';';
4811 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4813 SetLastError(ERROR_INVALID_ACL);
4814 return FALSE;
4817 piace = pace;
4818 DumpString(&openbr, 1, pwptr, plen);
4819 switch (piace->Header.AceType)
4821 case ACCESS_ALLOWED_ACE_TYPE:
4822 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4823 break;
4824 case ACCESS_DENIED_ACE_TYPE:
4825 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4826 break;
4827 case SYSTEM_AUDIT_ACE_TYPE:
4828 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4829 break;
4830 case SYSTEM_ALARM_ACE_TYPE:
4831 DumpString(SDDL_ALARM, -1, pwptr, plen);
4832 break;
4834 DumpString(&semicolon, 1, pwptr, plen);
4836 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4837 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4838 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4839 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4840 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4841 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4842 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4843 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4844 if (piace->Header.AceFlags & INHERITED_ACE)
4845 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4846 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4847 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4848 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4849 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4850 DumpString(&semicolon, 1, pwptr, plen);
4851 DumpRights(piace->Mask, pwptr, plen);
4852 DumpString(&semicolon, 1, pwptr, plen);
4853 /* objects not supported */
4854 DumpString(&semicolon, 1, pwptr, plen);
4855 /* objects not supported */
4856 DumpString(&semicolon, 1, pwptr, plen);
4857 if (!DumpSid(&piace->SidStart, pwptr, plen))
4858 return FALSE;
4859 DumpString(&closebr, 1, pwptr, plen);
4860 return TRUE;
4863 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4865 WORD count;
4866 UINT i;
4868 if (protected)
4869 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4870 if (autoInheritReq)
4871 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4872 if (autoInherited)
4873 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4875 if (pacl == NULL)
4876 return TRUE;
4878 if (!IsValidAcl(pacl))
4879 return FALSE;
4881 count = pacl->AceCount;
4882 for (i = 0; i < count; i++)
4884 LPVOID ace;
4885 if (!GetAce(pacl, i, &ace))
4886 return FALSE;
4887 if (!DumpAce(ace, pwptr, plen))
4888 return FALSE;
4891 return TRUE;
4894 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4896 static const WCHAR prefix[] = {'O',':',0};
4897 BOOL bDefaulted;
4898 PSID psid;
4900 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4901 return FALSE;
4903 if (psid == NULL)
4904 return TRUE;
4906 DumpString(prefix, -1, pwptr, plen);
4907 if (!DumpSid(psid, pwptr, plen))
4908 return FALSE;
4909 return TRUE;
4912 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4914 static const WCHAR prefix[] = {'G',':',0};
4915 BOOL bDefaulted;
4916 PSID psid;
4918 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4919 return FALSE;
4921 if (psid == NULL)
4922 return TRUE;
4924 DumpString(prefix, -1, pwptr, plen);
4925 if (!DumpSid(psid, pwptr, plen))
4926 return FALSE;
4927 return TRUE;
4930 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4932 static const WCHAR dacl[] = {'D',':',0};
4933 SECURITY_DESCRIPTOR_CONTROL control;
4934 BOOL present, defaulted;
4935 DWORD revision;
4936 PACL pacl;
4938 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4939 return FALSE;
4941 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4942 return FALSE;
4944 if (!present)
4945 return TRUE;
4947 DumpString(dacl, 2, pwptr, plen);
4948 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4949 return FALSE;
4950 return TRUE;
4953 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4955 static const WCHAR sacl[] = {'S',':',0};
4956 SECURITY_DESCRIPTOR_CONTROL control;
4957 BOOL present, defaulted;
4958 DWORD revision;
4959 PACL pacl;
4961 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4962 return FALSE;
4964 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4965 return FALSE;
4967 if (!present)
4968 return TRUE;
4970 DumpString(sacl, 2, pwptr, plen);
4971 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4972 return FALSE;
4973 return TRUE;
4976 /******************************************************************************
4977 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4979 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4981 ULONG len;
4982 WCHAR *wptr, *wstr;
4984 if (SDRevision != SDDL_REVISION_1)
4986 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
4987 SetLastError(ERROR_UNKNOWN_REVISION);
4988 return FALSE;
4991 len = 0;
4992 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4993 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4994 return FALSE;
4995 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4996 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4997 return FALSE;
4998 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4999 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5000 return FALSE;
5001 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5002 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5003 return FALSE;
5005 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5006 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5007 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5008 LocalFree (wstr);
5009 return FALSE;
5011 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5012 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5013 LocalFree (wstr);
5014 return FALSE;
5016 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5017 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5018 LocalFree (wstr);
5019 return FALSE;
5021 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5022 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5023 LocalFree (wstr);
5024 return FALSE;
5026 *wptr = 0;
5028 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5029 *OutputString = wstr;
5030 if (OutputLen)
5031 *OutputLen = strlenW(*OutputString)+1;
5032 return TRUE;
5035 /******************************************************************************
5036 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5038 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5040 LPWSTR wstr;
5041 ULONG len;
5042 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5044 int lenA;
5046 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5047 *OutputString = heap_alloc(lenA);
5048 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5049 LocalFree(wstr);
5051 if (OutputLen != NULL)
5052 *OutputLen = lenA;
5053 return TRUE;
5055 else
5057 *OutputString = NULL;
5058 if (OutputLen)
5059 *OutputLen = 0;
5060 return FALSE;
5064 /******************************************************************************
5065 * ConvertStringSidToSidW [ADVAPI32.@]
5067 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5069 BOOL bret = FALSE;
5070 DWORD cBytes;
5072 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5073 if (GetVersion() & 0x80000000)
5074 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5075 else if (!StringSid || !Sid)
5076 SetLastError(ERROR_INVALID_PARAMETER);
5077 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5079 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5081 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5082 if (!bret)
5083 LocalFree(*Sid);
5085 return bret;
5088 /******************************************************************************
5089 * ConvertStringSidToSidA [ADVAPI32.@]
5091 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5093 BOOL bret = FALSE;
5095 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5096 if (GetVersion() & 0x80000000)
5097 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5098 else if (!StringSid || !Sid)
5099 SetLastError(ERROR_INVALID_PARAMETER);
5100 else
5102 WCHAR *wStringSid = SERV_dup(StringSid);
5103 bret = ConvertStringSidToSidW(wStringSid, Sid);
5104 heap_free(wStringSid);
5106 return bret;
5109 /******************************************************************************
5110 * ConvertSidToStringSidW [ADVAPI32.@]
5112 * format of SID string is:
5113 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5114 * where
5115 * <rev> is the revision of the SID encoded as decimal
5116 * <auth> is the identifier authority encoded as hex
5117 * <subauthN> is the subauthority id encoded as decimal
5119 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5121 DWORD len = 0;
5122 LPWSTR wstr, wptr;
5124 TRACE("%p %p\n", pSid, pstr );
5126 len = 0;
5127 if (!DumpSidNumeric(pSid, NULL, &len))
5128 return FALSE;
5129 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5130 DumpSidNumeric(pSid, &wptr, NULL);
5131 *wptr = 0;
5133 *pstr = wstr;
5134 return TRUE;
5137 /******************************************************************************
5138 * ConvertSidToStringSidA [ADVAPI32.@]
5140 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5142 LPWSTR wstr = NULL;
5143 LPSTR str;
5144 UINT len;
5146 TRACE("%p %p\n", pSid, pstr );
5148 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5149 return FALSE;
5151 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5152 str = LocalAlloc( 0, len );
5153 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5154 LocalFree( wstr );
5156 *pstr = str;
5158 return TRUE;
5161 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5162 PSECURITY_DESCRIPTOR pdesc,
5163 PSECURITY_DESCRIPTOR cdesc,
5164 PSECURITY_DESCRIPTOR* ndesc,
5165 GUID* objtype,
5166 BOOL isdir,
5167 PGENERIC_MAPPING genmap )
5169 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5171 return FALSE;
5174 BOOL WINAPI CreatePrivateObjectSecurity(
5175 PSECURITY_DESCRIPTOR ParentDescriptor,
5176 PSECURITY_DESCRIPTOR CreatorDescriptor,
5177 PSECURITY_DESCRIPTOR* NewDescriptor,
5178 BOOL IsDirectoryObject,
5179 HANDLE Token,
5180 PGENERIC_MAPPING GenericMapping )
5182 SECURITY_DESCRIPTOR_RELATIVE *relative;
5183 DWORD needed, offset;
5184 BYTE *buffer;
5186 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5187 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5189 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5190 needed += sizeof(sidWorld);
5191 needed += sizeof(sidWorld);
5192 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5193 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5195 if (!(buffer = heap_alloc( needed ))) return FALSE;
5196 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5197 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5199 heap_free( buffer );
5200 return FALSE;
5202 relative->Control |= SE_SELF_RELATIVE;
5203 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5205 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5206 relative->Owner = offset;
5207 offset += sizeof(sidWorld);
5209 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5210 relative->Group = offset;
5211 offset += sizeof(sidWorld);
5213 GetWorldAccessACL( (ACL *)(buffer + offset) );
5214 relative->Dacl = offset;
5215 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5217 GetWorldAccessACL( (ACL *)(buffer + offset) );
5218 relative->Sacl = offset;
5220 *NewDescriptor = relative;
5221 return TRUE;
5224 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5226 FIXME("%p - stub\n", ObjectDescriptor);
5228 heap_free( *ObjectDescriptor );
5229 return TRUE;
5232 BOOL WINAPI CreateProcessAsUserA(
5233 HANDLE hToken,
5234 LPCSTR lpApplicationName,
5235 LPSTR lpCommandLine,
5236 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5237 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5238 BOOL bInheritHandles,
5239 DWORD dwCreationFlags,
5240 LPVOID lpEnvironment,
5241 LPCSTR lpCurrentDirectory,
5242 LPSTARTUPINFOA lpStartupInfo,
5243 LPPROCESS_INFORMATION lpProcessInformation )
5245 BOOL ret;
5246 WCHAR *appW, *cmdlnW, *cwdW;
5247 STARTUPINFOW sinfo;
5249 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5250 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5251 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5253 appW = SERV_dup(lpApplicationName);
5254 cmdlnW = SERV_dup(lpCommandLine);
5255 cwdW = SERV_dup(lpCurrentDirectory);
5256 sinfo.cb = sizeof(sinfo);
5257 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5258 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5259 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5260 sinfo.dwX = lpStartupInfo->dwX;
5261 sinfo.dwY = lpStartupInfo->dwY;
5262 sinfo.dwXSize = lpStartupInfo->dwXSize;
5263 sinfo.dwYSize = lpStartupInfo->dwYSize;
5264 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5265 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5266 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5267 sinfo.dwFlags = lpStartupInfo->dwFlags;
5268 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5269 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5270 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5271 sinfo.hStdInput = lpStartupInfo->hStdInput;
5272 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5273 sinfo.hStdError = lpStartupInfo->hStdError;
5274 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5275 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5276 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5277 heap_free(appW);
5278 heap_free(cmdlnW);
5279 heap_free(cwdW);
5280 heap_free(sinfo.lpReserved);
5281 heap_free(sinfo.lpDesktop);
5282 heap_free(sinfo.lpTitle);
5284 return ret;
5287 BOOL WINAPI CreateProcessAsUserW(
5288 HANDLE hToken,
5289 LPCWSTR lpApplicationName,
5290 LPWSTR lpCommandLine,
5291 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5292 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5293 BOOL bInheritHandles,
5294 DWORD dwCreationFlags,
5295 LPVOID lpEnvironment,
5296 LPCWSTR lpCurrentDirectory,
5297 LPSTARTUPINFOW lpStartupInfo,
5298 LPPROCESS_INFORMATION lpProcessInformation )
5300 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5301 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5302 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5303 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5305 /* We should create the process with a suspended main thread */
5306 if (!CreateProcessW (lpApplicationName,
5307 lpCommandLine,
5308 lpProcessAttributes,
5309 lpThreadAttributes,
5310 bInheritHandles,
5311 dwCreationFlags, /* CREATE_SUSPENDED */
5312 lpEnvironment,
5313 lpCurrentDirectory,
5314 lpStartupInfo,
5315 lpProcessInformation))
5317 return FALSE;
5320 return TRUE;
5323 /******************************************************************************
5324 * CreateProcessWithLogonW
5326 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5327 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5328 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5330 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5331 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5332 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5333 lpStartupInfo, lpProcessInformation);
5335 return FALSE;
5338 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5339 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5340 PROCESS_INFORMATION *process_information )
5342 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5343 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5344 creation_flags, environment, debugstr_w(current_directory),
5345 startup_info, process_information);
5347 /* FIXME: check if handles should be inherited */
5348 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5349 current_directory, startup_info, process_information );
5352 /******************************************************************************
5353 * DuplicateTokenEx [ADVAPI32.@]
5355 BOOL WINAPI DuplicateTokenEx(
5356 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5357 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5358 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5359 TOKEN_TYPE TokenType,
5360 PHANDLE DuplicateTokenHandle )
5362 OBJECT_ATTRIBUTES ObjectAttributes;
5364 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5365 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5367 InitializeObjectAttributes(
5368 &ObjectAttributes,
5369 NULL,
5370 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5371 NULL,
5372 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5374 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5375 dwDesiredAccess,
5376 &ObjectAttributes,
5377 ImpersonationLevel,
5378 TokenType,
5379 DuplicateTokenHandle ) );
5382 BOOL WINAPI DuplicateToken(
5383 HANDLE ExistingTokenHandle,
5384 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5385 PHANDLE DuplicateTokenHandle )
5387 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5388 NULL, ImpersonationLevel, TokenImpersonation,
5389 DuplicateTokenHandle );
5392 /******************************************************************************
5393 * ComputeStringSidSize
5395 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5397 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5399 int ctok = 0;
5400 while (*StringSid)
5402 if (*StringSid == '-')
5403 ctok++;
5404 StringSid++;
5407 if (ctok >= 3)
5408 return GetSidLengthRequired(ctok - 2);
5410 else /* String constant format - Only available in winxp and above */
5412 unsigned int i;
5414 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5415 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5416 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5418 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5419 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5421 MAX_SID local;
5422 ADVAPI_GetComputerSid(&local);
5423 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5428 return GetSidLengthRequired(0);
5431 /******************************************************************************
5432 * ParseStringSidToSid
5434 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5436 BOOL bret = FALSE;
5437 SID* pisid=pSid;
5439 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5440 if (!StringSid)
5442 SetLastError(ERROR_INVALID_PARAMETER);
5443 TRACE("StringSid is NULL, returning FALSE\n");
5444 return FALSE;
5447 while (*StringSid == ' ')
5448 StringSid++;
5450 *cBytes = ComputeStringSidSize(StringSid);
5451 if (!pisid) /* Simply compute the size */
5453 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5454 return TRUE;
5457 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5459 DWORD i = 0, identAuth;
5460 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5462 StringSid += 2; /* Advance to Revision */
5463 pisid->Revision = atoiW(StringSid);
5465 if (pisid->Revision != SDDL_REVISION)
5467 TRACE("Revision %d is unknown\n", pisid->Revision);
5468 goto lend; /* ERROR_INVALID_SID */
5470 if (csubauth == 0)
5472 TRACE("SubAuthorityCount is 0\n");
5473 goto lend; /* ERROR_INVALID_SID */
5476 pisid->SubAuthorityCount = csubauth;
5478 /* Advance to identifier authority */
5479 while (*StringSid && *StringSid != '-')
5480 StringSid++;
5481 if (*StringSid == '-')
5482 StringSid++;
5484 /* MS' implementation can't handle values greater than 2^32 - 1, so
5485 * we don't either; assume most significant bytes are always 0
5487 pisid->IdentifierAuthority.Value[0] = 0;
5488 pisid->IdentifierAuthority.Value[1] = 0;
5489 identAuth = atoiW(StringSid);
5490 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5491 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5492 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5493 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5495 /* Advance to first sub authority */
5496 while (*StringSid && *StringSid != '-')
5497 StringSid++;
5498 if (*StringSid == '-')
5499 StringSid++;
5501 while (*StringSid)
5503 pisid->SubAuthority[i++] = atoiW(StringSid);
5505 while (*StringSid && *StringSid != '-')
5506 StringSid++;
5507 if (*StringSid == '-')
5508 StringSid++;
5511 if (i != pisid->SubAuthorityCount)
5512 goto lend; /* ERROR_INVALID_SID */
5514 bret = TRUE;
5516 else /* String constant format - Only available in winxp and above */
5518 unsigned int i;
5519 pisid->Revision = SDDL_REVISION;
5521 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5522 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5524 DWORD j;
5525 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5526 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5527 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5528 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5529 bret = TRUE;
5532 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5533 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5535 ADVAPI_GetComputerSid(pisid);
5536 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5537 pisid->SubAuthorityCount++;
5538 bret = TRUE;
5541 if (!bret)
5542 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5545 lend:
5546 if (!bret)
5547 SetLastError(ERROR_INVALID_SID);
5549 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5550 return bret;
5553 /******************************************************************************
5554 * GetNamedSecurityInfoA [ADVAPI32.@]
5556 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5557 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5558 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5559 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5561 LPWSTR wstr;
5562 DWORD r;
5564 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5565 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5567 wstr = SERV_dup(pObjectName);
5568 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5569 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5571 heap_free( wstr );
5573 return r;
5576 /******************************************************************************
5577 * GetNamedSecurityInfoW [ADVAPI32.@]
5579 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5580 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5581 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5583 DWORD access = 0;
5584 HANDLE handle;
5585 DWORD err;
5587 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5588 group, dacl, sacl, descriptor );
5590 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5591 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5593 /* If no descriptor, we have to check that there's a pointer for the requested information */
5594 if( !descriptor && (
5595 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5596 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5597 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5598 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5599 return ERROR_INVALID_PARAMETER;
5601 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5602 access |= READ_CONTROL;
5603 if (info & SACL_SECURITY_INFORMATION)
5604 access |= ACCESS_SYSTEM_SECURITY;
5606 switch (type)
5608 case SE_SERVICE:
5609 if (!(err = get_security_service( name, access, &handle )))
5611 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5612 CloseServiceHandle( handle );
5614 break;
5615 case SE_REGISTRY_KEY:
5616 if (!(err = get_security_regkey( name, access, &handle )))
5618 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5619 RegCloseKey( handle );
5621 break;
5622 case SE_FILE_OBJECT:
5623 if (!(err = get_security_file( name, access, &handle )))
5625 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5626 CloseHandle( handle );
5628 break;
5629 default:
5630 FIXME( "Object type %d is not currently supported.\n", type );
5631 if (owner) *owner = NULL;
5632 if (group) *group = NULL;
5633 if (dacl) *dacl = NULL;
5634 if (sacl) *sacl = NULL;
5635 if (descriptor) *descriptor = NULL;
5636 return ERROR_SUCCESS;
5638 return err;
5641 /******************************************************************************
5642 * GetNamedSecurityInfoExW [ADVAPI32.@]
5644 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5645 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5646 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5648 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5649 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5650 return ERROR_CALL_NOT_IMPLEMENTED;
5653 /******************************************************************************
5654 * GetNamedSecurityInfoExA [ADVAPI32.@]
5656 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5657 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5658 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5660 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5661 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5662 return ERROR_CALL_NOT_IMPLEMENTED;
5665 /******************************************************************************
5666 * DecryptFileW [ADVAPI32.@]
5668 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5670 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5671 return TRUE;
5674 /******************************************************************************
5675 * DecryptFileA [ADVAPI32.@]
5677 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5679 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5680 return TRUE;
5683 /******************************************************************************
5684 * EncryptFileW [ADVAPI32.@]
5686 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5688 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5689 return TRUE;
5692 /******************************************************************************
5693 * EncryptFileA [ADVAPI32.@]
5695 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5697 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5698 return TRUE;
5701 /******************************************************************************
5702 * FileEncryptionStatusW [ADVAPI32.@]
5704 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5706 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5707 if (!lpStatus)
5708 return FALSE;
5709 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5710 return TRUE;
5713 /******************************************************************************
5714 * FileEncryptionStatusA [ADVAPI32.@]
5716 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5718 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5719 if (!lpStatus)
5720 return FALSE;
5721 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5722 return TRUE;
5725 /******************************************************************************
5726 * SetSecurityInfo [ADVAPI32.@]
5728 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5729 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5730 PSID psidGroup, PACL pDacl, PACL pSacl)
5732 SECURITY_DESCRIPTOR sd;
5733 NTSTATUS status;
5735 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5736 return ERROR_INVALID_SECURITY_DESCR;
5738 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5739 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5740 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5741 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5742 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5743 SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
5744 if (SecurityInfo & SACL_SECURITY_INFORMATION)
5745 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
5747 switch (ObjectType)
5749 case SE_SERVICE:
5750 FIXME("stub: Service objects are not supported at this time.\n");
5751 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
5752 break;
5753 default:
5754 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
5755 break;
5757 return RtlNtStatusToDosError(status);
5760 /******************************************************************************
5761 * SaferCreateLevel [ADVAPI32.@]
5763 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5764 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5766 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5768 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5769 return TRUE;
5772 /******************************************************************************
5773 * SaferComputeTokenFromLevel [ADVAPI32.@]
5775 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5776 DWORD flags, LPVOID reserved)
5778 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5780 *access_token = (HANDLE)0xdeadbeef;
5781 return TRUE;
5784 /******************************************************************************
5785 * SaferCloseLevel [ADVAPI32.@]
5787 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5789 FIXME("(%p) stub\n", handle);
5790 return TRUE;
5793 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5794 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5795 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5796 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5797 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5799 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
5800 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5801 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5803 return ERROR_SUCCESS;
5806 /******************************************************************************
5807 * SaferGetPolicyInformation [ADVAPI32.@]
5809 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5810 PVOID buffer, PDWORD required, LPVOID lpReserved)
5812 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5813 return FALSE;
5816 /******************************************************************************
5817 * SaferSetLevelInformation [ADVAPI32.@]
5819 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5820 LPVOID buffer, DWORD size)
5822 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5823 return FALSE;