advapi32: Add AddMandatoryAce stub.
[wine.git] / dlls / advapi32 / security.c
blob8e2f39c4e607e86be57afbf523122849aa1f0f37
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 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 BOOL ADVAPI_GetComputerSid(PSID sid)
452 static const struct /* same fields as struct SID */
454 BYTE Revision;
455 BYTE SubAuthorityCount;
456 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
457 DWORD SubAuthority[4];
458 } computer_sid =
459 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
461 memcpy( sid, &computer_sid, sizeof(computer_sid) );
462 return TRUE;
465 /* ##############################
466 ###### TOKEN FUNCTIONS ######
467 ##############################
470 /******************************************************************************
471 * OpenProcessToken [ADVAPI32.@]
472 * Opens the access token associated with a process handle.
474 * PARAMS
475 * ProcessHandle [I] Handle to process
476 * DesiredAccess [I] Desired access to process
477 * TokenHandle [O] Pointer to handle of open access token
479 * RETURNS
480 * Success: TRUE. TokenHandle contains the access token.
481 * Failure: FALSE.
483 * NOTES
484 * See NtOpenProcessToken.
486 BOOL WINAPI
487 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
488 HANDLE *TokenHandle )
490 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
493 /******************************************************************************
494 * OpenThreadToken [ADVAPI32.@]
496 * Opens the access token associated with a thread handle.
498 * PARAMS
499 * ThreadHandle [I] Handle to process
500 * DesiredAccess [I] Desired access to the thread
501 * OpenAsSelf [I] ???
502 * TokenHandle [O] Destination for the token handle
504 * RETURNS
505 * Success: TRUE. TokenHandle contains the access token.
506 * Failure: FALSE.
508 * NOTES
509 * See NtOpenThreadToken.
511 BOOL WINAPI
512 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
513 BOOL OpenAsSelf, HANDLE *TokenHandle)
515 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
518 BOOL WINAPI
519 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
520 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
522 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
523 PreviousState, ReturnLength));
526 /******************************************************************************
527 * AdjustTokenPrivileges [ADVAPI32.@]
529 * Adjust the privileges of an open token handle.
531 * PARAMS
532 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
533 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
534 * NewState [I] Desired new privileges of the token
535 * BufferLength [I] Length of NewState
536 * PreviousState [O] Destination for the previous state
537 * ReturnLength [I/O] Size of PreviousState
540 * RETURNS
541 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
542 * Failure: FALSE.
544 * NOTES
545 * See NtAdjustPrivilegesToken.
547 BOOL WINAPI
548 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
549 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
550 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
552 NTSTATUS status;
554 TRACE("\n");
556 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
557 NewState, BufferLength, PreviousState,
558 ReturnLength);
559 SetLastError( RtlNtStatusToDosError( status ));
560 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
561 return TRUE;
562 else
563 return FALSE;
566 /******************************************************************************
567 * CheckTokenMembership [ADVAPI32.@]
569 * Determine if an access token is a member of a SID.
571 * PARAMS
572 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573 * SidToCheck [I] SID that possibly contains the token
574 * IsMember [O] Destination for result.
576 * RETURNS
577 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
578 * Failure: FALSE.
580 BOOL WINAPI
581 CheckTokenMembership( HANDLE token, PSID sid_to_check,
582 PBOOL is_member )
584 PTOKEN_GROUPS token_groups = NULL;
585 HANDLE thread_token = NULL;
586 DWORD size, i;
587 BOOL ret;
589 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
591 *is_member = FALSE;
593 if (!token)
595 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
597 HANDLE process_token;
598 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
599 if (!ret)
600 goto exit;
601 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
602 NULL, SecurityImpersonation, TokenImpersonation,
603 &thread_token);
604 CloseHandle(process_token);
605 if (!ret)
606 goto exit;
608 token = thread_token;
610 else
612 TOKEN_TYPE type;
614 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
615 if (!ret) goto exit;
617 if (type == TokenPrimary)
619 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
620 return FALSE;
624 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
625 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
626 goto exit;
628 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
629 if (!token_groups)
631 ret = FALSE;
632 goto exit;
635 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
636 if (!ret)
637 goto exit;
639 for (i = 0; i < token_groups->GroupCount; i++)
641 TRACE("Groups[%d]: {0x%x, %s}\n", i,
642 token_groups->Groups[i].Attributes,
643 debugstr_sid(token_groups->Groups[i].Sid));
644 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
645 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
647 *is_member = TRUE;
648 TRACE("sid enabled and found in token\n");
649 break;
653 exit:
654 HeapFree(GetProcessHeap(), 0, token_groups);
655 if (thread_token != NULL) CloseHandle(thread_token);
657 return ret;
660 /******************************************************************************
661 * GetTokenInformation [ADVAPI32.@]
663 * Get a type of information about an access token.
665 * PARAMS
666 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
667 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
668 * tokeninfo [O] Destination for token information
669 * tokeninfolength [I] Length of tokeninfo
670 * retlen [O] Destination for returned token information length
672 * RETURNS
673 * Success: TRUE. tokeninfo contains retlen bytes of token information
674 * Failure: FALSE.
676 * NOTES
677 * See NtQueryInformationToken.
679 BOOL WINAPI
680 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
681 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
683 TRACE("(%p, %s, %p, %d, %p):\n",
684 token,
685 (tokeninfoclass == TokenUser) ? "TokenUser" :
686 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
687 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
688 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
689 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
690 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
691 (tokeninfoclass == TokenSource) ? "TokenSource" :
692 (tokeninfoclass == TokenType) ? "TokenType" :
693 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
694 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
695 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
696 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
697 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
698 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
699 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
700 "Unknown",
701 tokeninfo, tokeninfolength, retlen);
702 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
703 tokeninfolength, retlen));
706 /******************************************************************************
707 * SetTokenInformation [ADVAPI32.@]
709 * Set information for an access token.
711 * PARAMS
712 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
713 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
714 * tokeninfo [I] Token information to set
715 * tokeninfolength [I] Length of tokeninfo
717 * RETURNS
718 * Success: TRUE. The information for the token is set to tokeninfo.
719 * Failure: FALSE.
721 BOOL WINAPI
722 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
723 LPVOID tokeninfo, DWORD tokeninfolength )
725 TRACE("(%p, %s, %p, %d): stub\n",
726 token,
727 (tokeninfoclass == TokenUser) ? "TokenUser" :
728 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
729 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
730 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
731 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
732 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
733 (tokeninfoclass == TokenSource) ? "TokenSource" :
734 (tokeninfoclass == TokenType) ? "TokenType" :
735 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
736 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
737 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
738 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
739 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
740 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
741 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
742 "Unknown",
743 tokeninfo, tokeninfolength);
745 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
748 /*************************************************************************
749 * SetThreadToken [ADVAPI32.@]
751 * Assigns an 'impersonation token' to a thread so it can assume the
752 * security privileges of another thread or process. Can also remove
753 * a previously assigned token.
755 * PARAMS
756 * thread [O] Handle to thread to set the token for
757 * token [I] Token to set
759 * RETURNS
760 * Success: TRUE. The threads access token is set to token
761 * Failure: FALSE.
763 * NOTES
764 * Only supported on NT or higher. On Win9X this function does nothing.
765 * See SetTokenInformation.
767 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
769 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
770 ThreadImpersonationToken, &token, sizeof token ));
773 /*************************************************************************
774 * CreateRestrictedToken [ADVAPI32.@]
776 * Create a new more restricted token from an existing token.
778 * PARAMS
779 * baseToken [I] Token to base the new restricted token on
780 * flags [I] Options
781 * nDisableSids [I] Length of disableSids array
782 * disableSids [I] Array of SIDs to disable in the new token
783 * nDeletePrivs [I] Length of deletePrivs array
784 * deletePrivs [I] Array of privileges to delete in the new token
785 * nRestrictSids [I] Length of restrictSids array
786 * restrictSids [I] Array of SIDs to restrict in the new token
787 * newToken [O] Address where the new token is stored
789 * RETURNS
790 * Success: TRUE
791 * Failure: FALSE
793 BOOL WINAPI CreateRestrictedToken(
794 HANDLE baseToken,
795 DWORD flags,
796 DWORD nDisableSids,
797 PSID_AND_ATTRIBUTES disableSids,
798 DWORD nDeletePrivs,
799 PLUID_AND_ATTRIBUTES deletePrivs,
800 DWORD nRestrictSids,
801 PSID_AND_ATTRIBUTES restrictSids,
802 PHANDLE newToken)
804 TOKEN_TYPE type;
805 SECURITY_IMPERSONATION_LEVEL level = TokenImpersonationLevel;
806 DWORD size;
808 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
809 baseToken, flags, nDisableSids, disableSids,
810 nDeletePrivs, deletePrivs,
811 nRestrictSids, restrictSids,
812 newToken);
814 size = sizeof(type);
815 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
816 if (type == TokenImpersonation)
818 size = sizeof(level);
819 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
820 return FALSE;
822 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
825 /* ##############################
826 ###### SID FUNCTIONS ######
827 ##############################
830 /******************************************************************************
831 * AllocateAndInitializeSid [ADVAPI32.@]
833 * PARAMS
834 * pIdentifierAuthority []
835 * nSubAuthorityCount []
836 * nSubAuthority0 []
837 * nSubAuthority1 []
838 * nSubAuthority2 []
839 * nSubAuthority3 []
840 * nSubAuthority4 []
841 * nSubAuthority5 []
842 * nSubAuthority6 []
843 * nSubAuthority7 []
844 * pSid []
846 BOOL WINAPI
847 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
848 BYTE nSubAuthorityCount,
849 DWORD nSubAuthority0, DWORD nSubAuthority1,
850 DWORD nSubAuthority2, DWORD nSubAuthority3,
851 DWORD nSubAuthority4, DWORD nSubAuthority5,
852 DWORD nSubAuthority6, DWORD nSubAuthority7,
853 PSID *pSid )
855 return set_ntstatus( RtlAllocateAndInitializeSid(
856 pIdentifierAuthority, nSubAuthorityCount,
857 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
858 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
859 pSid ));
862 /******************************************************************************
863 * FreeSid [ADVAPI32.@]
865 * PARAMS
866 * pSid []
868 PVOID WINAPI
869 FreeSid( PSID pSid )
871 RtlFreeSid(pSid);
872 return NULL; /* is documented like this */
875 /******************************************************************************
876 * CopySid [ADVAPI32.@]
878 * PARAMS
879 * nDestinationSidLength []
880 * pDestinationSid []
881 * pSourceSid []
883 BOOL WINAPI
884 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
886 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
889 /******************************************************************************
890 * CreateWellKnownSid [ADVAPI32.@]
892 BOOL WINAPI
893 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
894 PSID DomainSid,
895 PSID pSid,
896 DWORD* cbSid)
898 unsigned int i;
899 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
901 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
903 SetLastError(ERROR_INVALID_PARAMETER);
904 return FALSE;
907 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
908 if (WellKnownSids[i].Type == WellKnownSidType) {
909 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
911 if (*cbSid < length)
913 *cbSid = length;
914 SetLastError(ERROR_INSUFFICIENT_BUFFER);
915 return FALSE;
917 if (!pSid)
919 SetLastError(ERROR_INVALID_PARAMETER);
920 return FALSE;
922 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
923 *cbSid = length;
924 return TRUE;
928 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
930 SetLastError(ERROR_INVALID_PARAMETER);
931 return FALSE;
934 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
935 if (WellKnownRids[i].Type == WellKnownSidType) {
936 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
937 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
938 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
940 if (*cbSid < output_sid_length)
942 *cbSid = output_sid_length;
943 SetLastError(ERROR_INSUFFICIENT_BUFFER);
944 return FALSE;
946 if (!pSid)
948 SetLastError(ERROR_INVALID_PARAMETER);
949 return FALSE;
951 CopyMemory(pSid, DomainSid, domain_sid_length);
952 (*GetSidSubAuthorityCount(pSid))++;
953 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
954 *cbSid = output_sid_length;
955 return TRUE;
958 SetLastError(ERROR_INVALID_PARAMETER);
959 return FALSE;
962 /******************************************************************************
963 * IsWellKnownSid [ADVAPI32.@]
965 BOOL WINAPI
966 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
968 unsigned int i;
969 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
971 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
972 if (WellKnownSids[i].Type == WellKnownSidType)
973 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
974 return TRUE;
976 return FALSE;
979 BOOL WINAPI
980 IsTokenRestricted( HANDLE TokenHandle )
982 TOKEN_GROUPS *groups;
983 DWORD size;
984 NTSTATUS status;
985 BOOL restricted;
987 TRACE("(%p)\n", TokenHandle);
989 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
990 if (status != STATUS_BUFFER_TOO_SMALL)
991 return FALSE;
993 groups = HeapAlloc(GetProcessHeap(), 0, size);
994 if (!groups)
996 SetLastError(ERROR_OUTOFMEMORY);
997 return FALSE;
1000 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1001 if (status != STATUS_SUCCESS)
1003 HeapFree(GetProcessHeap(), 0, groups);
1004 return set_ntstatus(status);
1007 if (groups->GroupCount)
1008 restricted = TRUE;
1009 else
1010 restricted = FALSE;
1012 HeapFree(GetProcessHeap(), 0, groups);
1014 return restricted;
1017 /******************************************************************************
1018 * IsValidSid [ADVAPI32.@]
1020 * PARAMS
1021 * pSid []
1023 BOOL WINAPI
1024 IsValidSid( PSID pSid )
1026 return RtlValidSid( pSid );
1029 /******************************************************************************
1030 * EqualSid [ADVAPI32.@]
1032 * PARAMS
1033 * pSid1 []
1034 * pSid2 []
1036 BOOL WINAPI
1037 EqualSid( PSID pSid1, PSID pSid2 )
1039 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1040 SetLastError(ERROR_SUCCESS);
1041 return ret;
1044 /******************************************************************************
1045 * EqualPrefixSid [ADVAPI32.@]
1047 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1049 return RtlEqualPrefixSid(pSid1, pSid2);
1052 /******************************************************************************
1053 * GetSidLengthRequired [ADVAPI32.@]
1055 * PARAMS
1056 * nSubAuthorityCount []
1058 DWORD WINAPI
1059 GetSidLengthRequired( BYTE nSubAuthorityCount )
1061 return RtlLengthRequiredSid(nSubAuthorityCount);
1064 /******************************************************************************
1065 * InitializeSid [ADVAPI32.@]
1067 * PARAMS
1068 * pIdentifierAuthority []
1070 BOOL WINAPI
1071 InitializeSid (
1072 PSID pSid,
1073 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1074 BYTE nSubAuthorityCount)
1076 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1079 DWORD WINAPI
1080 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1082 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1084 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1085 return 0;
1088 DWORD WINAPI
1089 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1091 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1093 return 1;
1096 /******************************************************************************
1097 * GetSidIdentifierAuthority [ADVAPI32.@]
1099 * PARAMS
1100 * pSid []
1102 PSID_IDENTIFIER_AUTHORITY WINAPI
1103 GetSidIdentifierAuthority( PSID pSid )
1105 return RtlIdentifierAuthoritySid(pSid);
1108 /******************************************************************************
1109 * GetSidSubAuthority [ADVAPI32.@]
1111 * PARAMS
1112 * pSid []
1113 * nSubAuthority []
1115 PDWORD WINAPI
1116 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1118 SetLastError(ERROR_SUCCESS);
1119 return RtlSubAuthoritySid(pSid, nSubAuthority);
1122 /******************************************************************************
1123 * GetSidSubAuthorityCount [ADVAPI32.@]
1125 * PARAMS
1126 * pSid []
1128 PUCHAR WINAPI
1129 GetSidSubAuthorityCount (PSID pSid)
1131 SetLastError(ERROR_SUCCESS);
1132 return RtlSubAuthorityCountSid(pSid);
1135 /******************************************************************************
1136 * GetLengthSid [ADVAPI32.@]
1138 * PARAMS
1139 * pSid []
1141 DWORD WINAPI
1142 GetLengthSid (PSID pSid)
1144 return RtlLengthSid(pSid);
1147 /* ##############################################
1148 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1149 ##############################################
1152 /******************************************************************************
1153 * BuildSecurityDescriptorA [ADVAPI32.@]
1155 * Builds a SD from
1157 * PARAMS
1158 * pOwner [I]
1159 * pGroup [I]
1160 * cCountOfAccessEntries [I]
1161 * pListOfAccessEntries [I]
1162 * cCountOfAuditEntries [I]
1163 * pListofAuditEntries [I]
1164 * pOldSD [I]
1165 * lpdwBufferLength [I/O]
1166 * pNewSD [O]
1168 * RETURNS
1169 * Success: ERROR_SUCCESS
1170 * Failure: nonzero error code from Winerror.h
1172 DWORD WINAPI BuildSecurityDescriptorA(
1173 IN PTRUSTEEA pOwner,
1174 IN PTRUSTEEA pGroup,
1175 IN ULONG cCountOfAccessEntries,
1176 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1177 IN ULONG cCountOfAuditEntries,
1178 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1179 IN PSECURITY_DESCRIPTOR pOldSD,
1180 IN OUT PULONG lpdwBufferLength,
1181 OUT PSECURITY_DESCRIPTOR* pNewSD)
1183 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1184 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1185 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1187 return ERROR_CALL_NOT_IMPLEMENTED;
1190 /******************************************************************************
1191 * BuildSecurityDescriptorW [ADVAPI32.@]
1193 * See BuildSecurityDescriptorA.
1195 DWORD WINAPI BuildSecurityDescriptorW(
1196 IN PTRUSTEEW pOwner,
1197 IN PTRUSTEEW pGroup,
1198 IN ULONG cCountOfAccessEntries,
1199 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1200 IN ULONG cCountOfAuditEntries,
1201 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1202 IN PSECURITY_DESCRIPTOR pOldSD,
1203 IN OUT PULONG lpdwBufferLength,
1204 OUT PSECURITY_DESCRIPTOR* pNewSD)
1206 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1207 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1208 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1210 return ERROR_CALL_NOT_IMPLEMENTED;
1213 /******************************************************************************
1214 * InitializeSecurityDescriptor [ADVAPI32.@]
1216 * PARAMS
1217 * pDescr []
1218 * revision []
1220 BOOL WINAPI
1221 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1223 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1227 /******************************************************************************
1228 * MakeAbsoluteSD [ADVAPI32.@]
1230 BOOL WINAPI MakeAbsoluteSD (
1231 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1232 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1233 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1234 OUT PACL pDacl,
1235 OUT LPDWORD lpdwDaclSize,
1236 OUT PACL pSacl,
1237 OUT LPDWORD lpdwSaclSize,
1238 OUT PSID pOwner,
1239 OUT LPDWORD lpdwOwnerSize,
1240 OUT PSID pPrimaryGroup,
1241 OUT LPDWORD lpdwPrimaryGroupSize)
1243 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1244 pAbsoluteSecurityDescriptor,
1245 lpdwAbsoluteSecurityDescriptorSize,
1246 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1247 pOwner, lpdwOwnerSize,
1248 pPrimaryGroup, lpdwPrimaryGroupSize));
1251 /******************************************************************************
1252 * GetKernelObjectSecurity [ADVAPI32.@]
1254 BOOL WINAPI GetKernelObjectSecurity(
1255 HANDLE Handle,
1256 SECURITY_INFORMATION RequestedInformation,
1257 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1258 DWORD nLength,
1259 LPDWORD lpnLengthNeeded )
1261 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1262 pSecurityDescriptor, nLength, lpnLengthNeeded);
1264 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1265 nLength, lpnLengthNeeded ));
1268 /******************************************************************************
1269 * GetPrivateObjectSecurity [ADVAPI32.@]
1271 BOOL WINAPI GetPrivateObjectSecurity(
1272 PSECURITY_DESCRIPTOR ObjectDescriptor,
1273 SECURITY_INFORMATION SecurityInformation,
1274 PSECURITY_DESCRIPTOR ResultantDescriptor,
1275 DWORD DescriptorLength,
1276 PDWORD ReturnLength )
1278 SECURITY_DESCRIPTOR desc;
1279 BOOL defaulted, present;
1280 PACL pacl;
1281 PSID psid;
1283 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1284 ResultantDescriptor, DescriptorLength, ReturnLength);
1286 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1287 return FALSE;
1289 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1291 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1292 return FALSE;
1293 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1296 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1298 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1299 return FALSE;
1300 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1303 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1305 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1306 return FALSE;
1307 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1310 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1312 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1313 return FALSE;
1314 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1317 *ReturnLength = DescriptorLength;
1318 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1321 /******************************************************************************
1322 * GetSecurityDescriptorLength [ADVAPI32.@]
1324 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1326 return RtlLengthSecurityDescriptor(pDescr);
1329 /******************************************************************************
1330 * GetSecurityDescriptorOwner [ADVAPI32.@]
1332 * PARAMS
1333 * pOwner []
1334 * lpbOwnerDefaulted []
1336 BOOL WINAPI
1337 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1338 LPBOOL lpbOwnerDefaulted )
1340 BOOLEAN defaulted;
1341 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1342 *lpbOwnerDefaulted = defaulted;
1343 return ret;
1346 /******************************************************************************
1347 * SetSecurityDescriptorOwner [ADVAPI32.@]
1349 * PARAMS
1351 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1352 PSID pOwner, BOOL bOwnerDefaulted)
1354 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1356 /******************************************************************************
1357 * GetSecurityDescriptorGroup [ADVAPI32.@]
1359 BOOL WINAPI GetSecurityDescriptorGroup(
1360 PSECURITY_DESCRIPTOR SecurityDescriptor,
1361 PSID *Group,
1362 LPBOOL GroupDefaulted)
1364 BOOLEAN defaulted;
1365 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1366 *GroupDefaulted = defaulted;
1367 return ret;
1369 /******************************************************************************
1370 * SetSecurityDescriptorGroup [ADVAPI32.@]
1372 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1373 PSID Group, BOOL GroupDefaulted)
1375 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1378 /******************************************************************************
1379 * IsValidSecurityDescriptor [ADVAPI32.@]
1381 * PARAMS
1382 * lpsecdesc []
1384 BOOL WINAPI
1385 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1387 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1390 /******************************************************************************
1391 * GetSecurityDescriptorDacl [ADVAPI32.@]
1393 BOOL WINAPI GetSecurityDescriptorDacl(
1394 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1395 OUT LPBOOL lpbDaclPresent,
1396 OUT PACL *pDacl,
1397 OUT LPBOOL lpbDaclDefaulted)
1399 BOOLEAN present, defaulted;
1400 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1401 *lpbDaclPresent = present;
1402 *lpbDaclDefaulted = defaulted;
1403 return ret;
1406 /******************************************************************************
1407 * SetSecurityDescriptorDacl [ADVAPI32.@]
1409 BOOL WINAPI
1410 SetSecurityDescriptorDacl (
1411 PSECURITY_DESCRIPTOR lpsd,
1412 BOOL daclpresent,
1413 PACL dacl,
1414 BOOL dacldefaulted )
1416 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1418 /******************************************************************************
1419 * GetSecurityDescriptorSacl [ADVAPI32.@]
1421 BOOL WINAPI GetSecurityDescriptorSacl(
1422 IN PSECURITY_DESCRIPTOR lpsd,
1423 OUT LPBOOL lpbSaclPresent,
1424 OUT PACL *pSacl,
1425 OUT LPBOOL lpbSaclDefaulted)
1427 BOOLEAN present, defaulted;
1428 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1429 *lpbSaclPresent = present;
1430 *lpbSaclDefaulted = defaulted;
1431 return ret;
1434 /**************************************************************************
1435 * SetSecurityDescriptorSacl [ADVAPI32.@]
1437 BOOL WINAPI SetSecurityDescriptorSacl (
1438 PSECURITY_DESCRIPTOR lpsd,
1439 BOOL saclpresent,
1440 PACL lpsacl,
1441 BOOL sacldefaulted)
1443 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1445 /******************************************************************************
1446 * MakeSelfRelativeSD [ADVAPI32.@]
1448 * PARAMS
1449 * lpabssecdesc []
1450 * lpselfsecdesc []
1451 * lpbuflen []
1453 BOOL WINAPI
1454 MakeSelfRelativeSD(
1455 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1456 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1457 IN OUT LPDWORD lpdwBufferLength)
1459 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1460 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1463 /******************************************************************************
1464 * GetSecurityDescriptorControl [ADVAPI32.@]
1467 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1468 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1470 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1473 /******************************************************************************
1474 * SetSecurityDescriptorControl [ADVAPI32.@]
1476 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1477 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1478 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1480 return set_ntstatus( RtlSetControlSecurityDescriptor(
1481 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1484 /* ##############################
1485 ###### ACL FUNCTIONS ######
1486 ##############################
1489 /*************************************************************************
1490 * InitializeAcl [ADVAPI32.@]
1492 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1494 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1497 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1499 IO_STATUS_BLOCK io_block;
1501 TRACE("(%p)\n", hNamedPipe);
1503 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1504 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1507 /******************************************************************************
1508 * AddAccessAllowedAce [ADVAPI32.@]
1510 BOOL WINAPI AddAccessAllowedAce(
1511 IN OUT PACL pAcl,
1512 IN DWORD dwAceRevision,
1513 IN DWORD AccessMask,
1514 IN PSID pSid)
1516 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1519 /******************************************************************************
1520 * AddAccessAllowedAceEx [ADVAPI32.@]
1522 BOOL WINAPI AddAccessAllowedAceEx(
1523 IN OUT PACL pAcl,
1524 IN DWORD dwAceRevision,
1525 IN DWORD AceFlags,
1526 IN DWORD AccessMask,
1527 IN PSID pSid)
1529 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1532 /******************************************************************************
1533 * AddAccessDeniedAce [ADVAPI32.@]
1535 BOOL WINAPI AddAccessDeniedAce(
1536 IN OUT PACL pAcl,
1537 IN DWORD dwAceRevision,
1538 IN DWORD AccessMask,
1539 IN PSID pSid)
1541 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1544 /******************************************************************************
1545 * AddAccessDeniedAceEx [ADVAPI32.@]
1547 BOOL WINAPI AddAccessDeniedAceEx(
1548 IN OUT PACL pAcl,
1549 IN DWORD dwAceRevision,
1550 IN DWORD AceFlags,
1551 IN DWORD AccessMask,
1552 IN PSID pSid)
1554 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1557 /******************************************************************************
1558 * AddAce [ADVAPI32.@]
1560 BOOL WINAPI AddAce(
1561 IN OUT PACL pAcl,
1562 IN DWORD dwAceRevision,
1563 IN DWORD dwStartingAceIndex,
1564 LPVOID pAceList,
1565 DWORD nAceListLength)
1567 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1570 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1572 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1573 return FALSE;
1576 /******************************************************************************
1577 * DeleteAce [ADVAPI32.@]
1579 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1581 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1584 /******************************************************************************
1585 * FindFirstFreeAce [ADVAPI32.@]
1587 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1589 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1592 /******************************************************************************
1593 * GetAce [ADVAPI32.@]
1595 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1597 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1600 /******************************************************************************
1601 * GetAclInformation [ADVAPI32.@]
1603 BOOL WINAPI GetAclInformation(
1604 PACL pAcl,
1605 LPVOID pAclInformation,
1606 DWORD nAclInformationLength,
1607 ACL_INFORMATION_CLASS dwAclInformationClass)
1609 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1610 nAclInformationLength, dwAclInformationClass));
1613 /******************************************************************************
1614 * IsValidAcl [ADVAPI32.@]
1616 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1618 return RtlValidAcl(pAcl);
1621 /* ##############################
1622 ###### MISC FUNCTIONS ######
1623 ##############################
1626 /******************************************************************************
1627 * AllocateLocallyUniqueId [ADVAPI32.@]
1629 * PARAMS
1630 * lpLuid []
1632 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1634 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1637 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1638 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1639 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1640 { '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 };
1641 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1642 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1643 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1644 { '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 };
1645 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1646 { '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 };
1647 static const WCHAR SE_TCB_NAME_W[] =
1648 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1649 static const WCHAR SE_SECURITY_NAME_W[] =
1650 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1651 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1652 { '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 };
1653 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1654 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1655 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1656 { '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 };
1657 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1658 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1659 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1660 { '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 };
1661 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1662 { '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 };
1663 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1664 { '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 };
1665 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1666 { '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 };
1667 static const WCHAR SE_BACKUP_NAME_W[] =
1668 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1669 static const WCHAR SE_RESTORE_NAME_W[] =
1670 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1671 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1672 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1673 static const WCHAR SE_DEBUG_NAME_W[] =
1674 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1675 static const WCHAR SE_AUDIT_NAME_W[] =
1676 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1677 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1678 { '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 };
1679 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1680 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1681 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1682 { '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 };
1683 static const WCHAR SE_UNDOCK_NAME_W[] =
1684 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1685 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1686 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1687 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1688 { '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 };
1689 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1690 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1691 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1692 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1693 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1694 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1696 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1698 NULL,
1699 NULL,
1700 SE_CREATE_TOKEN_NAME_W,
1701 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1702 SE_LOCK_MEMORY_NAME_W,
1703 SE_INCREASE_QUOTA_NAME_W,
1704 SE_MACHINE_ACCOUNT_NAME_W,
1705 SE_TCB_NAME_W,
1706 SE_SECURITY_NAME_W,
1707 SE_TAKE_OWNERSHIP_NAME_W,
1708 SE_LOAD_DRIVER_NAME_W,
1709 SE_SYSTEM_PROFILE_NAME_W,
1710 SE_SYSTEMTIME_NAME_W,
1711 SE_PROF_SINGLE_PROCESS_NAME_W,
1712 SE_INC_BASE_PRIORITY_NAME_W,
1713 SE_CREATE_PAGEFILE_NAME_W,
1714 SE_CREATE_PERMANENT_NAME_W,
1715 SE_BACKUP_NAME_W,
1716 SE_RESTORE_NAME_W,
1717 SE_SHUTDOWN_NAME_W,
1718 SE_DEBUG_NAME_W,
1719 SE_AUDIT_NAME_W,
1720 SE_SYSTEM_ENVIRONMENT_NAME_W,
1721 SE_CHANGE_NOTIFY_NAME_W,
1722 SE_REMOTE_SHUTDOWN_NAME_W,
1723 SE_UNDOCK_NAME_W,
1724 SE_SYNC_AGENT_NAME_W,
1725 SE_ENABLE_DELEGATION_NAME_W,
1726 SE_MANAGE_VOLUME_NAME_W,
1727 SE_IMPERSONATE_NAME_W,
1728 SE_CREATE_GLOBAL_NAME_W,
1731 /******************************************************************************
1732 * LookupPrivilegeValueW [ADVAPI32.@]
1734 * See LookupPrivilegeValueA.
1736 BOOL WINAPI
1737 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1739 UINT i;
1741 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1743 if (!ADVAPI_IsLocalComputer(lpSystemName))
1745 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1746 return FALSE;
1748 if (!lpName)
1750 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1751 return FALSE;
1753 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1755 if( !WellKnownPrivNames[i] )
1756 continue;
1757 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1758 continue;
1759 lpLuid->LowPart = i;
1760 lpLuid->HighPart = 0;
1761 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1762 lpLuid->HighPart, lpLuid->LowPart );
1763 return TRUE;
1765 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1766 return FALSE;
1769 /******************************************************************************
1770 * LookupPrivilegeValueA [ADVAPI32.@]
1772 * Retrieves LUID used on a system to represent the privilege name.
1774 * PARAMS
1775 * lpSystemName [I] Name of the system
1776 * lpName [I] Name of the privilege
1777 * lpLuid [O] Destination for the resulting LUID
1779 * RETURNS
1780 * Success: TRUE. lpLuid contains the requested LUID.
1781 * Failure: FALSE.
1783 BOOL WINAPI
1784 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1786 UNICODE_STRING lpSystemNameW;
1787 UNICODE_STRING lpNameW;
1788 BOOL ret;
1790 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1791 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1792 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1793 RtlFreeUnicodeString(&lpNameW);
1794 RtlFreeUnicodeString(&lpSystemNameW);
1795 return ret;
1798 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1799 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1801 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1802 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1804 return FALSE;
1807 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1808 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1810 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1811 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1813 return FALSE;
1816 /******************************************************************************
1817 * LookupPrivilegeNameA [ADVAPI32.@]
1819 * See LookupPrivilegeNameW.
1821 BOOL WINAPI
1822 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1823 LPDWORD cchName)
1825 UNICODE_STRING lpSystemNameW;
1826 BOOL ret;
1827 DWORD wLen = 0;
1829 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1831 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1832 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1833 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1835 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1837 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1838 &wLen);
1839 if (ret)
1841 /* Windows crashes if cchName is NULL, so will I */
1842 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1843 *cchName, NULL, NULL);
1845 if (len == 0)
1847 /* WideCharToMultiByte failed */
1848 ret = FALSE;
1850 else if (len > *cchName)
1852 *cchName = len;
1853 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1854 ret = FALSE;
1856 else
1858 /* WideCharToMultiByte succeeded, output length needs to be
1859 * length not including NULL terminator
1861 *cchName = len - 1;
1864 HeapFree(GetProcessHeap(), 0, lpNameW);
1866 RtlFreeUnicodeString(&lpSystemNameW);
1867 return ret;
1870 /******************************************************************************
1871 * LookupPrivilegeNameW [ADVAPI32.@]
1873 * Retrieves the privilege name referred to by the LUID lpLuid.
1875 * PARAMS
1876 * lpSystemName [I] Name of the system
1877 * lpLuid [I] Privilege value
1878 * lpName [O] Name of the privilege
1879 * cchName [I/O] Number of characters in lpName.
1881 * RETURNS
1882 * Success: TRUE. lpName contains the name of the privilege whose value is
1883 * *lpLuid.
1884 * Failure: FALSE.
1886 * REMARKS
1887 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1888 * using this function.
1889 * If the length of lpName is too small, on return *cchName will contain the
1890 * number of WCHARs needed to contain the privilege, including the NULL
1891 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1892 * On success, *cchName will contain the number of characters stored in
1893 * lpName, NOT including the NULL terminator.
1895 BOOL WINAPI
1896 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1897 LPDWORD cchName)
1899 size_t privNameLen;
1901 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1903 if (!ADVAPI_IsLocalComputer(lpSystemName))
1905 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1906 return FALSE;
1908 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1909 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1911 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1912 return FALSE;
1914 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1915 /* Windows crashes if cchName is NULL, so will I */
1916 if (*cchName <= privNameLen)
1918 *cchName = privNameLen + 1;
1919 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1920 return FALSE;
1922 else
1924 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1925 *cchName = privNameLen;
1926 return TRUE;
1930 /******************************************************************************
1931 * GetFileSecurityA [ADVAPI32.@]
1933 * Obtains Specified information about the security of a file or directory.
1935 * PARAMS
1936 * lpFileName [I] Name of the file to get info for
1937 * RequestedInformation [I] SE_ flags from "winnt.h"
1938 * pSecurityDescriptor [O] Destination for security information
1939 * nLength [I] Length of pSecurityDescriptor
1940 * lpnLengthNeeded [O] Destination for length of returned security information
1942 * RETURNS
1943 * Success: TRUE. pSecurityDescriptor contains the requested information.
1944 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1946 * NOTES
1947 * The information returned is constrained by the callers access rights and
1948 * privileges.
1950 BOOL WINAPI
1951 GetFileSecurityA( LPCSTR lpFileName,
1952 SECURITY_INFORMATION RequestedInformation,
1953 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1954 DWORD nLength, LPDWORD lpnLengthNeeded )
1956 BOOL r;
1957 LPWSTR name;
1959 name = SERV_dup(lpFileName);
1960 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1961 nLength, lpnLengthNeeded );
1962 HeapFree( GetProcessHeap(), 0, name );
1964 return r;
1967 /******************************************************************************
1968 * GetFileSecurityW [ADVAPI32.@]
1970 * See GetFileSecurityA.
1972 BOOL WINAPI
1973 GetFileSecurityW( LPCWSTR lpFileName,
1974 SECURITY_INFORMATION RequestedInformation,
1975 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1976 DWORD nLength, LPDWORD lpnLengthNeeded )
1978 HANDLE hfile;
1979 NTSTATUS status;
1980 DWORD access = 0;
1982 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1983 RequestedInformation, pSecurityDescriptor,
1984 nLength, lpnLengthNeeded);
1986 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1987 DACL_SECURITY_INFORMATION))
1988 access |= READ_CONTROL;
1989 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1990 access |= ACCESS_SYSTEM_SECURITY;
1992 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1993 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1994 if ( hfile == INVALID_HANDLE_VALUE )
1995 return FALSE;
1997 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1998 nLength, lpnLengthNeeded );
1999 CloseHandle( hfile );
2000 return set_ntstatus( status );
2004 /******************************************************************************
2005 * LookupAccountSidA [ADVAPI32.@]
2007 BOOL WINAPI
2008 LookupAccountSidA(
2009 IN LPCSTR system,
2010 IN PSID sid,
2011 OUT LPSTR account,
2012 IN OUT LPDWORD accountSize,
2013 OUT LPSTR domain,
2014 IN OUT LPDWORD domainSize,
2015 OUT PSID_NAME_USE name_use )
2017 DWORD len;
2018 BOOL r;
2019 LPWSTR systemW;
2020 LPWSTR accountW = NULL;
2021 LPWSTR domainW = NULL;
2022 DWORD accountSizeW = *accountSize;
2023 DWORD domainSizeW = *domainSize;
2025 systemW = SERV_dup(system);
2026 if (account)
2027 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2028 if (domain)
2029 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2031 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2033 if (r) {
2034 if (accountW && *accountSize) {
2035 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2036 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2037 *accountSize = len;
2038 } else
2039 *accountSize = accountSizeW + 1;
2041 if (domainW && *domainSize) {
2042 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2043 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2044 *domainSize = len;
2045 } else
2046 *domainSize = domainSizeW + 1;
2048 else
2050 *accountSize = accountSizeW + 1;
2051 *domainSize = domainSizeW + 1;
2054 HeapFree( GetProcessHeap(), 0, systemW );
2055 HeapFree( GetProcessHeap(), 0, accountW );
2056 HeapFree( GetProcessHeap(), 0, domainW );
2058 return r;
2061 /******************************************************************************
2062 * LookupAccountSidW [ADVAPI32.@]
2064 * PARAMS
2065 * system []
2066 * sid []
2067 * account []
2068 * accountSize []
2069 * domain []
2070 * domainSize []
2071 * name_use []
2074 BOOL WINAPI
2075 LookupAccountSidW(
2076 IN LPCWSTR system,
2077 IN PSID sid,
2078 OUT LPWSTR account,
2079 IN OUT LPDWORD accountSize,
2080 OUT LPWSTR domain,
2081 IN OUT LPDWORD domainSize,
2082 OUT PSID_NAME_USE name_use )
2084 unsigned int i, j;
2085 const WCHAR * ac = NULL;
2086 const WCHAR * dm = NULL;
2087 SID_NAME_USE use = 0;
2088 LPWSTR computer_name = NULL;
2089 LPWSTR account_name = NULL;
2091 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2092 debugstr_w(system),debugstr_sid(sid),
2093 account,accountSize,accountSize?*accountSize:0,
2094 domain,domainSize,domainSize?*domainSize:0,
2095 name_use);
2097 if (!ADVAPI_IsLocalComputer(system)) {
2098 FIXME("Only local computer supported!\n");
2099 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2100 return FALSE;
2103 /* check the well known SIDs first */
2104 for (i = 0; i <= 60; i++) {
2105 if (IsWellKnownSid(sid, i)) {
2106 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2107 if (ACCOUNT_SIDS[j].type == i) {
2108 ac = ACCOUNT_SIDS[j].account;
2109 dm = ACCOUNT_SIDS[j].domain;
2110 use = ACCOUNT_SIDS[j].name_use;
2113 break;
2117 if (dm == NULL) {
2118 MAX_SID local;
2120 /* check for the local computer next */
2121 if (ADVAPI_GetComputerSid(&local)) {
2122 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2123 BOOL result;
2125 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2126 result = GetComputerNameW(computer_name, &size);
2128 if (result) {
2129 if (EqualSid(sid, &local)) {
2130 dm = computer_name;
2131 ac = Blank;
2132 use = 3;
2133 } else {
2134 local.SubAuthorityCount++;
2136 if (EqualPrefixSid(sid, &local)) {
2137 dm = computer_name;
2138 use = 1;
2139 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2140 case DOMAIN_USER_RID_ADMIN:
2141 ac = Administrator;
2142 break;
2143 case DOMAIN_USER_RID_GUEST:
2144 ac = Guest;
2145 break;
2146 case DOMAIN_GROUP_RID_ADMINS:
2147 ac = Domain_Admins;
2148 break;
2149 case DOMAIN_GROUP_RID_USERS:
2150 ac = Domain_Users;
2151 break;
2152 case DOMAIN_GROUP_RID_GUESTS:
2153 ac = Domain_Guests;
2154 break;
2155 case DOMAIN_GROUP_RID_COMPUTERS:
2156 ac = Domain_Computers;
2157 break;
2158 case DOMAIN_GROUP_RID_CONTROLLERS:
2159 ac = Domain_Controllers;
2160 break;
2161 case DOMAIN_GROUP_RID_CERT_ADMINS:
2162 ac = Cert_Publishers;
2163 break;
2164 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2165 ac = Schema_Admins;
2166 break;
2167 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2168 ac = Enterprise_Admins;
2169 break;
2170 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2171 ac = Group_Policy_Creator_Owners;
2172 break;
2173 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2174 ac = RAS_and_IAS_Servers;
2175 break;
2176 case 1000: /* first user account */
2177 size = UNLEN + 1;
2178 account_name = HeapAlloc(
2179 GetProcessHeap(), 0, size * sizeof(WCHAR));
2180 if (GetUserNameW(account_name, &size))
2181 ac = account_name;
2182 else
2183 dm = NULL;
2185 break;
2186 default:
2187 dm = NULL;
2188 break;
2196 if (dm) {
2197 DWORD ac_len = lstrlenW(ac);
2198 DWORD dm_len = lstrlenW(dm);
2199 BOOL status = TRUE;
2201 if (*accountSize > ac_len) {
2202 if (account)
2203 lstrcpyW(account, ac);
2205 if (*domainSize > dm_len) {
2206 if (domain)
2207 lstrcpyW(domain, dm);
2209 if ((*accountSize && *accountSize < ac_len) ||
2210 (!account && !*accountSize && ac_len) ||
2211 (*domainSize && *domainSize < dm_len) ||
2212 (!domain && !*domainSize && dm_len))
2214 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2215 status = FALSE;
2217 if (*domainSize)
2218 *domainSize = dm_len;
2219 else
2220 *domainSize = dm_len + 1;
2221 if (*accountSize)
2222 *accountSize = ac_len;
2223 else
2224 *accountSize = ac_len + 1;
2226 HeapFree(GetProcessHeap(), 0, account_name);
2227 HeapFree(GetProcessHeap(), 0, computer_name);
2228 if (status) *name_use = use;
2229 return status;
2232 HeapFree(GetProcessHeap(), 0, account_name);
2233 HeapFree(GetProcessHeap(), 0, computer_name);
2234 SetLastError(ERROR_NONE_MAPPED);
2235 return FALSE;
2238 /******************************************************************************
2239 * SetFileSecurityA [ADVAPI32.@]
2241 * See SetFileSecurityW.
2243 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2244 SECURITY_INFORMATION RequestedInformation,
2245 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2247 BOOL r;
2248 LPWSTR name;
2250 name = SERV_dup(lpFileName);
2251 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2252 HeapFree( GetProcessHeap(), 0, name );
2254 return r;
2257 /******************************************************************************
2258 * SetFileSecurityW [ADVAPI32.@]
2260 * Sets the security of a file or directory.
2262 * PARAMS
2263 * lpFileName []
2264 * RequestedInformation []
2265 * pSecurityDescriptor []
2267 * RETURNS
2268 * Success: TRUE.
2269 * Failure: FALSE.
2271 BOOL WINAPI
2272 SetFileSecurityW( LPCWSTR lpFileName,
2273 SECURITY_INFORMATION RequestedInformation,
2274 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2276 HANDLE file;
2277 DWORD access = 0;
2278 NTSTATUS status;
2280 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2281 pSecurityDescriptor );
2283 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2284 RequestedInformation & GROUP_SECURITY_INFORMATION)
2285 access |= WRITE_OWNER;
2286 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2287 access |= ACCESS_SYSTEM_SECURITY;
2288 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2289 access |= WRITE_DAC;
2291 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2292 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2293 if (file == INVALID_HANDLE_VALUE)
2294 return FALSE;
2296 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2297 CloseHandle( file );
2298 return set_ntstatus( status );
2301 /******************************************************************************
2302 * QueryWindows31FilesMigration [ADVAPI32.@]
2304 * PARAMS
2305 * x1 []
2307 BOOL WINAPI
2308 QueryWindows31FilesMigration( DWORD x1 )
2310 FIXME("(%d):stub\n",x1);
2311 return TRUE;
2314 /******************************************************************************
2315 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2317 * PARAMS
2318 * x1 []
2319 * x2 []
2320 * x3 []
2321 * x4 []
2323 BOOL WINAPI
2324 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2325 DWORD x4 )
2327 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2328 return TRUE;
2331 /******************************************************************************
2332 * NotifyBootConfigStatus [ADVAPI32.@]
2334 * PARAMS
2335 * x1 []
2337 BOOL WINAPI
2338 NotifyBootConfigStatus( BOOL x1 )
2340 FIXME("(0x%08d):stub\n",x1);
2341 return 1;
2344 /******************************************************************************
2345 * RevertToSelf [ADVAPI32.@]
2347 * Ends the impersonation of a user.
2349 * PARAMS
2350 * void []
2352 * RETURNS
2353 * Success: TRUE.
2354 * Failure: FALSE.
2356 BOOL WINAPI
2357 RevertToSelf( void )
2359 HANDLE Token = NULL;
2360 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2361 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2364 /******************************************************************************
2365 * ImpersonateSelf [ADVAPI32.@]
2367 * Makes an impersonation token that represents the process user and assigns
2368 * to the current thread.
2370 * PARAMS
2371 * ImpersonationLevel [I] Level at which to impersonate.
2373 * RETURNS
2374 * Success: TRUE.
2375 * Failure: FALSE.
2377 BOOL WINAPI
2378 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2380 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2383 /******************************************************************************
2384 * ImpersonateLoggedOnUser [ADVAPI32.@]
2386 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2388 DWORD size;
2389 NTSTATUS Status;
2390 HANDLE ImpersonationToken;
2391 TOKEN_TYPE Type;
2392 static BOOL warn = TRUE;
2394 if (warn)
2396 FIXME( "(%p)\n", hToken );
2397 warn = FALSE;
2399 if (!GetTokenInformation( hToken, TokenType, &Type,
2400 sizeof(TOKEN_TYPE), &size ))
2401 return FALSE;
2403 if (Type == TokenPrimary)
2405 OBJECT_ATTRIBUTES ObjectAttributes;
2407 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2409 Status = NtDuplicateToken( hToken,
2410 TOKEN_IMPERSONATE | TOKEN_QUERY,
2411 &ObjectAttributes,
2412 SecurityImpersonation,
2413 TokenImpersonation,
2414 &ImpersonationToken );
2415 if (Status != STATUS_SUCCESS)
2417 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2418 SetLastError( RtlNtStatusToDosError( Status ) );
2419 return FALSE;
2422 else
2423 ImpersonationToken = hToken;
2425 Status = NtSetInformationThread( GetCurrentThread(),
2426 ThreadImpersonationToken,
2427 &ImpersonationToken,
2428 sizeof(ImpersonationToken) );
2430 if (Type == TokenPrimary)
2431 NtClose( ImpersonationToken );
2433 if (Status != STATUS_SUCCESS)
2435 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2436 SetLastError( RtlNtStatusToDosError( Status ) );
2437 return FALSE;
2440 return TRUE;
2443 /******************************************************************************
2444 * AccessCheck [ADVAPI32.@]
2446 BOOL WINAPI
2447 AccessCheck(
2448 PSECURITY_DESCRIPTOR SecurityDescriptor,
2449 HANDLE ClientToken,
2450 DWORD DesiredAccess,
2451 PGENERIC_MAPPING GenericMapping,
2452 PPRIVILEGE_SET PrivilegeSet,
2453 LPDWORD PrivilegeSetLength,
2454 LPDWORD GrantedAccess,
2455 LPBOOL AccessStatus)
2457 NTSTATUS access_status;
2458 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2459 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2460 GrantedAccess, &access_status) );
2461 if (ret) *AccessStatus = set_ntstatus( access_status );
2462 return ret;
2466 /******************************************************************************
2467 * AccessCheckByType [ADVAPI32.@]
2469 BOOL WINAPI AccessCheckByType(
2470 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2471 PSID PrincipalSelfSid,
2472 HANDLE ClientToken,
2473 DWORD DesiredAccess,
2474 POBJECT_TYPE_LIST ObjectTypeList,
2475 DWORD ObjectTypeListLength,
2476 PGENERIC_MAPPING GenericMapping,
2477 PPRIVILEGE_SET PrivilegeSet,
2478 LPDWORD PrivilegeSetLength,
2479 LPDWORD GrantedAccess,
2480 LPBOOL AccessStatus)
2482 FIXME("stub\n");
2484 *AccessStatus = TRUE;
2486 return !*AccessStatus;
2489 /******************************************************************************
2490 * MapGenericMask [ADVAPI32.@]
2492 * Maps generic access rights into specific access rights according to the
2493 * supplied mapping.
2495 * PARAMS
2496 * AccessMask [I/O] Access rights.
2497 * GenericMapping [I] The mapping between generic and specific rights.
2499 * RETURNS
2500 * Nothing.
2502 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2504 RtlMapGenericMask( AccessMask, GenericMapping );
2507 /*************************************************************************
2508 * SetKernelObjectSecurity [ADVAPI32.@]
2510 BOOL WINAPI SetKernelObjectSecurity (
2511 IN HANDLE Handle,
2512 IN SECURITY_INFORMATION SecurityInformation,
2513 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2515 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2519 /******************************************************************************
2520 * AddAuditAccessAce [ADVAPI32.@]
2522 BOOL WINAPI AddAuditAccessAce(
2523 IN OUT PACL pAcl,
2524 IN DWORD dwAceRevision,
2525 IN DWORD dwAccessMask,
2526 IN PSID pSid,
2527 IN BOOL bAuditSuccess,
2528 IN BOOL bAuditFailure)
2530 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2531 bAuditSuccess, bAuditFailure) );
2534 /******************************************************************************
2535 * AddAuditAccessAce [ADVAPI32.@]
2537 BOOL WINAPI AddAuditAccessAceEx(
2538 IN OUT PACL pAcl,
2539 IN DWORD dwAceRevision,
2540 IN DWORD dwAceFlags,
2541 IN DWORD dwAccessMask,
2542 IN PSID pSid,
2543 IN BOOL bAuditSuccess,
2544 IN BOOL bAuditFailure)
2546 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2547 bAuditSuccess, bAuditFailure) );
2550 /******************************************************************************
2551 * LookupAccountNameA [ADVAPI32.@]
2553 BOOL WINAPI
2554 LookupAccountNameA(
2555 IN LPCSTR system,
2556 IN LPCSTR account,
2557 OUT PSID sid,
2558 OUT LPDWORD cbSid,
2559 LPSTR ReferencedDomainName,
2560 IN OUT LPDWORD cbReferencedDomainName,
2561 OUT PSID_NAME_USE name_use )
2563 BOOL ret;
2564 UNICODE_STRING lpSystemW;
2565 UNICODE_STRING lpAccountW;
2566 LPWSTR lpReferencedDomainNameW = NULL;
2568 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2569 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2571 if (ReferencedDomainName)
2572 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2574 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2575 cbReferencedDomainName, name_use);
2577 if (ret && lpReferencedDomainNameW)
2579 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2580 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2583 RtlFreeUnicodeString(&lpSystemW);
2584 RtlFreeUnicodeString(&lpAccountW);
2585 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2587 return ret;
2590 /******************************************************************************
2591 * lookup_user_account_name
2593 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2594 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2596 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2597 DWORD len = sizeof(buffer);
2598 HANDLE token;
2599 BOOL ret;
2600 PSID pSid;
2601 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2602 DWORD nameLen;
2604 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2606 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2607 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2610 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2611 CloseHandle( token );
2613 if (!ret) return FALSE;
2615 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2617 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2618 CopySid(*cbSid, Sid, pSid);
2619 if (*cbSid < GetLengthSid(pSid))
2621 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2622 ret = FALSE;
2624 *cbSid = GetLengthSid(pSid);
2626 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2627 if (!GetComputerNameW(domainName, &nameLen))
2629 domainName[0] = 0;
2630 nameLen = 0;
2632 if (*cchReferencedDomainName <= nameLen || !ret)
2634 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2635 nameLen += 1;
2636 ret = FALSE;
2638 else if (ReferencedDomainName)
2639 strcpyW(ReferencedDomainName, domainName);
2641 *cchReferencedDomainName = nameLen;
2643 if (ret)
2644 *peUse = SidTypeUser;
2646 return ret;
2649 /******************************************************************************
2650 * lookup_computer_account_name
2652 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2653 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2655 MAX_SID local;
2656 BOOL ret;
2657 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2658 DWORD nameLen;
2660 if ((ret = ADVAPI_GetComputerSid(&local)))
2662 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2663 CopySid(*cbSid, Sid, &local);
2664 if (*cbSid < GetLengthSid(&local))
2666 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2667 ret = FALSE;
2669 *cbSid = GetLengthSid(&local);
2672 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2673 if (!GetComputerNameW(domainName, &nameLen))
2675 domainName[0] = 0;
2676 nameLen = 0;
2678 if (*cchReferencedDomainName <= nameLen || !ret)
2680 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2681 nameLen += 1;
2682 ret = FALSE;
2684 else if (ReferencedDomainName)
2685 strcpyW(ReferencedDomainName, domainName);
2687 *cchReferencedDomainName = nameLen;
2689 if (ret)
2690 *peUse = SidTypeDomain;
2692 return ret;
2695 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2696 LSA_UNICODE_STRING *domain )
2698 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2700 while (p > str->Buffer && *p != '\\') p--;
2702 if (*p == '\\')
2704 domain->Buffer = str->Buffer;
2705 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2707 account->Buffer = p + 1;
2708 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2710 else
2712 domain->Buffer = NULL;
2713 domain->Length = 0;
2715 account->Buffer = str->Buffer;
2716 account->Length = str->Length;
2720 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2722 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2724 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2725 return TRUE;
2727 return FALSE;
2730 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2732 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2734 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2735 return TRUE;
2737 if (ACCOUNT_SIDS[idx].alias)
2739 len = strlenW( ACCOUNT_SIDS[idx].alias );
2740 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2741 return TRUE;
2743 return FALSE;
2747 * Helper function for LookupAccountNameW
2749 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2750 PSID Sid, LPDWORD cbSid,
2751 LPWSTR ReferencedDomainName,
2752 LPDWORD cchReferencedDomainName,
2753 PSID_NAME_USE peUse, BOOL *handled )
2755 PSID pSid;
2756 LSA_UNICODE_STRING account, domain;
2757 BOOL ret = TRUE;
2758 ULONG i;
2760 *handled = FALSE;
2761 split_domain_account( account_and_domain, &account, &domain );
2763 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2765 /* check domain first */
2766 if (domain.Buffer && !match_domain( i, &domain )) continue;
2768 if (match_account( i, &account ))
2770 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2772 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2774 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2776 if (*cbSid < sidLen)
2778 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2779 ret = FALSE;
2781 else if (Sid)
2783 CopySid(*cbSid, Sid, pSid);
2785 *cbSid = sidLen;
2788 len = strlenW( ACCOUNT_SIDS[i].domain );
2789 if (*cchReferencedDomainName <= len || !ret)
2791 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2792 len++;
2793 ret = FALSE;
2795 else if (ReferencedDomainName)
2797 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2800 *cchReferencedDomainName = len;
2801 if (ret)
2802 *peUse = ACCOUNT_SIDS[i].name_use;
2804 HeapFree(GetProcessHeap(), 0, pSid);
2805 *handled = TRUE;
2806 return ret;
2809 return ret;
2812 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2813 PSID Sid, LPDWORD cbSid,
2814 LPWSTR ReferencedDomainName,
2815 LPDWORD cchReferencedDomainName,
2816 PSID_NAME_USE peUse, BOOL *handled )
2818 DWORD nameLen;
2819 LPWSTR userName = NULL;
2820 LSA_UNICODE_STRING account, domain;
2821 BOOL ret = TRUE;
2823 *handled = FALSE;
2824 split_domain_account( account_and_domain, &account, &domain );
2826 /* Let the current Unix user id masquerade as first Windows user account */
2828 nameLen = UNLEN + 1;
2829 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2831 if (domain.Buffer)
2833 /* check to make sure this account is on this computer */
2834 if (GetComputerNameW( userName, &nameLen ) &&
2835 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2837 SetLastError(ERROR_NONE_MAPPED);
2838 ret = FALSE;
2840 nameLen = UNLEN + 1;
2843 if (GetUserNameW( userName, &nameLen ) &&
2844 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2846 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2847 *handled = TRUE;
2849 else
2851 nameLen = UNLEN + 1;
2852 if (GetComputerNameW( userName, &nameLen ) &&
2853 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2855 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2856 *handled = TRUE;
2860 HeapFree(GetProcessHeap(), 0, userName);
2861 return ret;
2864 /******************************************************************************
2865 * LookupAccountNameW [ADVAPI32.@]
2867 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2868 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2869 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2871 BOOL ret, handled;
2872 LSA_UNICODE_STRING account;
2874 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2875 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2877 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2879 FIXME("remote computer not supported\n");
2880 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2881 return FALSE;
2884 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2886 lpAccountName = BUILTIN;
2889 RtlInitUnicodeString( &account, lpAccountName );
2891 /* Check well known SIDs first */
2892 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2893 cchReferencedDomainName, peUse, &handled );
2894 if (handled)
2895 return ret;
2897 /* Check user names */
2898 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2899 cchReferencedDomainName, peUse, &handled);
2900 if (handled)
2901 return ret;
2903 SetLastError( ERROR_NONE_MAPPED );
2904 return FALSE;
2907 /******************************************************************************
2908 * PrivilegeCheck [ADVAPI32.@]
2910 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2912 BOOL ret;
2913 BOOLEAN Result;
2915 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2917 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2918 if (ret)
2919 *pfResult = Result;
2920 return ret;
2923 /******************************************************************************
2924 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2926 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2927 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2928 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2929 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2931 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2932 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2933 SecurityDescriptor, DesiredAccess, GenericMapping,
2934 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2935 return TRUE;
2938 /******************************************************************************
2939 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2941 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2942 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2943 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2944 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2946 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2947 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2948 SecurityDescriptor, DesiredAccess, GenericMapping,
2949 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2950 return TRUE;
2953 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2955 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2957 return TRUE;
2960 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2962 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2964 return TRUE;
2967 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2969 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2971 return TRUE;
2974 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2975 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2976 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2977 LPBOOL GenerateOnClose)
2979 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2980 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2981 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2982 GenerateOnClose);
2984 return TRUE;
2987 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2988 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2989 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2990 LPBOOL GenerateOnClose)
2992 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2993 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2994 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2995 GenerateOnClose);
2997 return TRUE;
3000 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3001 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3003 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3004 DesiredAccess, Privileges, AccessGranted);
3006 return TRUE;
3009 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3010 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3012 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3013 DesiredAccess, Privileges, AccessGranted);
3015 return TRUE;
3018 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3019 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3021 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3022 ClientToken, Privileges, AccessGranted);
3024 return TRUE;
3027 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3028 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3030 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3031 ClientToken, Privileges, AccessGranted);
3033 return TRUE;
3036 /******************************************************************************
3037 * GetSecurityInfo [ADVAPI32.@]
3039 * Retrieves a copy of the security descriptor associated with an object.
3041 * PARAMS
3042 * hObject [I] A handle for the object.
3043 * ObjectType [I] The type of object.
3044 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3045 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3046 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3047 * ppDacl [O] If non-null, receives a pointer to the DACL.
3048 * ppSacl [O] If non-null, receives a pointer to the SACL.
3049 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3050 * which must be freed with LocalFree.
3052 * RETURNS
3053 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3055 DWORD WINAPI GetSecurityInfo(
3056 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3057 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3058 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3059 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3062 PSECURITY_DESCRIPTOR sd;
3063 NTSTATUS status;
3064 ULONG n1, n2;
3065 BOOL present, defaulted;
3067 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3068 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3070 /* If no descriptor, we have to check that there's a pointer for the requested information */
3071 if( !ppSecurityDescriptor && (
3072 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3073 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3074 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3075 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3076 return ERROR_INVALID_PARAMETER;
3078 switch (ObjectType)
3080 case SE_SERVICE:
3081 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3082 break;
3083 default:
3084 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3085 break;
3087 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3088 return RtlNtStatusToDosError(status);
3090 sd = LocalAlloc(0, n1);
3091 if (!sd)
3092 return ERROR_NOT_ENOUGH_MEMORY;
3094 switch (ObjectType)
3096 case SE_SERVICE:
3097 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3098 break;
3099 default:
3100 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3101 break;
3103 if (status != STATUS_SUCCESS)
3105 LocalFree(sd);
3106 return RtlNtStatusToDosError(status);
3109 if (ppsidOwner)
3111 *ppsidOwner = NULL;
3112 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3114 if (ppsidGroup)
3116 *ppsidGroup = NULL;
3117 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3119 if (ppDacl)
3121 *ppDacl = NULL;
3122 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3124 if (ppSacl)
3126 *ppSacl = NULL;
3127 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3129 if (ppSecurityDescriptor)
3130 *ppSecurityDescriptor = sd;
3132 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3133 * NULL, because native happily returns the SIDs and ACLs that are requested
3134 * in this case.
3137 return ERROR_SUCCESS;
3140 /******************************************************************************
3141 * GetSecurityInfoExA [ADVAPI32.@]
3143 DWORD WINAPI GetSecurityInfoExA(
3144 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3145 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3146 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3147 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3150 FIXME("stub!\n");
3151 return ERROR_BAD_PROVIDER;
3154 /******************************************************************************
3155 * GetSecurityInfoExW [ADVAPI32.@]
3157 DWORD WINAPI GetSecurityInfoExW(
3158 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3159 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3160 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3161 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3164 FIXME("stub!\n");
3165 return ERROR_BAD_PROVIDER;
3168 /******************************************************************************
3169 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3171 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3172 LPSTR pTrusteeName, DWORD AccessPermissions,
3173 ACCESS_MODE AccessMode, DWORD Inheritance )
3175 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3176 AccessPermissions, AccessMode, Inheritance);
3178 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3179 pExplicitAccess->grfAccessMode = AccessMode;
3180 pExplicitAccess->grfInheritance = Inheritance;
3182 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3183 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3184 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3185 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3186 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3189 /******************************************************************************
3190 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3192 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3193 LPWSTR pTrusteeName, DWORD AccessPermissions,
3194 ACCESS_MODE AccessMode, DWORD Inheritance )
3196 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3197 AccessPermissions, AccessMode, Inheritance);
3199 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3200 pExplicitAccess->grfAccessMode = AccessMode;
3201 pExplicitAccess->grfInheritance = Inheritance;
3203 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3204 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3205 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3206 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3207 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3210 /******************************************************************************
3211 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3213 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3214 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3215 LPSTR InheritedObjectTypeName, LPSTR Name )
3217 DWORD ObjectsPresent = 0;
3219 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3220 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3222 /* Fill the OBJECTS_AND_NAME structure */
3223 pObjName->ObjectType = ObjectType;
3224 if (ObjectTypeName != NULL)
3226 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3229 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3230 if (InheritedObjectTypeName != NULL)
3232 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3235 pObjName->ObjectsPresent = ObjectsPresent;
3236 pObjName->ptstrName = Name;
3238 /* Fill the TRUSTEE structure */
3239 pTrustee->pMultipleTrustee = NULL;
3240 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3241 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3242 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3243 pTrustee->ptstrName = (LPSTR)pObjName;
3246 /******************************************************************************
3247 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3249 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3250 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3251 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3253 DWORD ObjectsPresent = 0;
3255 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3256 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3258 /* Fill the OBJECTS_AND_NAME structure */
3259 pObjName->ObjectType = ObjectType;
3260 if (ObjectTypeName != NULL)
3262 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3265 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3266 if (InheritedObjectTypeName != NULL)
3268 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3271 pObjName->ObjectsPresent = ObjectsPresent;
3272 pObjName->ptstrName = Name;
3274 /* Fill the TRUSTEE structure */
3275 pTrustee->pMultipleTrustee = NULL;
3276 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3277 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3278 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3279 pTrustee->ptstrName = (LPWSTR)pObjName;
3282 /******************************************************************************
3283 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3285 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3286 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3288 DWORD ObjectsPresent = 0;
3290 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3292 /* Fill the OBJECTS_AND_SID structure */
3293 if (pObjectGuid != NULL)
3295 pObjSid->ObjectTypeGuid = *pObjectGuid;
3296 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3298 else
3300 ZeroMemory(&pObjSid->ObjectTypeGuid,
3301 sizeof(GUID));
3304 if (pInheritedObjectGuid != NULL)
3306 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3307 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3309 else
3311 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3312 sizeof(GUID));
3315 pObjSid->ObjectsPresent = ObjectsPresent;
3316 pObjSid->pSid = pSid;
3318 /* Fill the TRUSTEE structure */
3319 pTrustee->pMultipleTrustee = NULL;
3320 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3321 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3322 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3323 pTrustee->ptstrName = (LPSTR) pObjSid;
3326 /******************************************************************************
3327 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3329 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3330 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3332 DWORD ObjectsPresent = 0;
3334 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3336 /* Fill the OBJECTS_AND_SID structure */
3337 if (pObjectGuid != NULL)
3339 pObjSid->ObjectTypeGuid = *pObjectGuid;
3340 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3342 else
3344 ZeroMemory(&pObjSid->ObjectTypeGuid,
3345 sizeof(GUID));
3348 if (pInheritedObjectGuid != NULL)
3350 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3351 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3353 else
3355 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3356 sizeof(GUID));
3359 pObjSid->ObjectsPresent = ObjectsPresent;
3360 pObjSid->pSid = pSid;
3362 /* Fill the TRUSTEE structure */
3363 pTrustee->pMultipleTrustee = NULL;
3364 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3365 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3366 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3367 pTrustee->ptstrName = (LPWSTR) pObjSid;
3370 /******************************************************************************
3371 * BuildTrusteeWithSidA [ADVAPI32.@]
3373 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3375 TRACE("%p %p\n", pTrustee, pSid);
3377 pTrustee->pMultipleTrustee = NULL;
3378 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3379 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3380 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3381 pTrustee->ptstrName = pSid;
3384 /******************************************************************************
3385 * BuildTrusteeWithSidW [ADVAPI32.@]
3387 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3389 TRACE("%p %p\n", pTrustee, pSid);
3391 pTrustee->pMultipleTrustee = NULL;
3392 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3393 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3394 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3395 pTrustee->ptstrName = pSid;
3398 /******************************************************************************
3399 * BuildTrusteeWithNameA [ADVAPI32.@]
3401 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3403 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3405 pTrustee->pMultipleTrustee = NULL;
3406 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3407 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3408 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3409 pTrustee->ptstrName = name;
3412 /******************************************************************************
3413 * BuildTrusteeWithNameW [ADVAPI32.@]
3415 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3417 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3419 pTrustee->pMultipleTrustee = NULL;
3420 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3421 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3422 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3423 pTrustee->ptstrName = name;
3426 /******************************************************************************
3427 * GetTrusteeFormA [ADVAPI32.@]
3429 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3431 TRACE("(%p)\n", pTrustee);
3433 if (!pTrustee)
3434 return TRUSTEE_BAD_FORM;
3436 return pTrustee->TrusteeForm;
3439 /******************************************************************************
3440 * GetTrusteeFormW [ADVAPI32.@]
3442 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3444 TRACE("(%p)\n", pTrustee);
3446 if (!pTrustee)
3447 return TRUSTEE_BAD_FORM;
3449 return pTrustee->TrusteeForm;
3452 /******************************************************************************
3453 * GetTrusteeNameA [ADVAPI32.@]
3455 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3457 TRACE("(%p)\n", pTrustee);
3459 if (!pTrustee)
3460 return NULL;
3462 return pTrustee->ptstrName;
3465 /******************************************************************************
3466 * GetTrusteeNameW [ADVAPI32.@]
3468 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3470 TRACE("(%p)\n", pTrustee);
3472 if (!pTrustee)
3473 return NULL;
3475 return pTrustee->ptstrName;
3478 /******************************************************************************
3479 * GetTrusteeTypeA [ADVAPI32.@]
3481 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3483 TRACE("(%p)\n", pTrustee);
3485 if (!pTrustee)
3486 return TRUSTEE_IS_UNKNOWN;
3488 return pTrustee->TrusteeType;
3491 /******************************************************************************
3492 * GetTrusteeTypeW [ADVAPI32.@]
3494 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3496 TRACE("(%p)\n", pTrustee);
3498 if (!pTrustee)
3499 return TRUSTEE_IS_UNKNOWN;
3501 return pTrustee->TrusteeType;
3504 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3505 DWORD nAclInformationLength,
3506 ACL_INFORMATION_CLASS dwAclInformationClass )
3508 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3509 nAclInformationLength, dwAclInformationClass);
3511 return TRUE;
3514 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3516 switch (form)
3518 case TRUSTEE_IS_NAME:
3520 *ptrustee_nameW = SERV_dup(trustee_nameA);
3521 return ERROR_SUCCESS;
3523 case TRUSTEE_IS_OBJECTS_AND_NAME:
3525 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3526 OBJECTS_AND_NAME_W *objW = NULL;
3528 if (objA)
3530 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3531 return ERROR_NOT_ENOUGH_MEMORY;
3533 objW->ObjectsPresent = objA->ObjectsPresent;
3534 objW->ObjectType = objA->ObjectType;
3535 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3536 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3537 objW->ptstrName = SERV_dup(objA->ptstrName);
3540 *ptrustee_nameW = (WCHAR *)objW;
3541 return ERROR_SUCCESS;
3543 /* These forms do not require conversion. */
3544 case TRUSTEE_IS_SID:
3545 case TRUSTEE_IS_OBJECTS_AND_SID:
3546 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3547 return ERROR_SUCCESS;
3548 default:
3549 return ERROR_INVALID_PARAMETER;
3553 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3555 switch (form)
3557 case TRUSTEE_IS_NAME:
3558 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3559 break;
3560 case TRUSTEE_IS_OBJECTS_AND_NAME:
3562 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3564 if (objW)
3566 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3567 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3568 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3569 HeapFree( GetProcessHeap(), 0, objW );
3572 break;
3574 /* Other forms did not require allocation, so no freeing is necessary. */
3575 default:
3576 break;
3580 /******************************************************************************
3581 * SetEntriesInAclA [ADVAPI32.@]
3583 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3584 PACL OldAcl, PACL* NewAcl )
3586 DWORD err = ERROR_SUCCESS;
3587 EXPLICIT_ACCESSW *pEntriesW;
3588 UINT alloc_index, free_index;
3590 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3592 if (NewAcl)
3593 *NewAcl = NULL;
3595 if (!count && !OldAcl)
3596 return ERROR_SUCCESS;
3598 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3599 if (!pEntriesW)
3600 return ERROR_NOT_ENOUGH_MEMORY;
3602 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3604 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3605 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3606 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3607 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3608 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3609 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3610 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3612 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3613 pEntries[alloc_index].Trustee.ptstrName,
3614 &pEntriesW[alloc_index].Trustee.ptstrName );
3615 if (err != ERROR_SUCCESS)
3617 if (err == ERROR_INVALID_PARAMETER)
3618 WARN("bad trustee form %d for trustee %d\n",
3619 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3621 goto cleanup;
3625 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3627 cleanup:
3628 /* Free any previously allocated trustee name buffers, taking into account
3629 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3630 * list. */
3631 for (free_index = 0; free_index < alloc_index; ++free_index)
3632 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3634 HeapFree( GetProcessHeap(), 0, pEntriesW );
3635 return err;
3638 /******************************************************************************
3639 * SetEntriesInAclW [ADVAPI32.@]
3641 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3642 PACL OldAcl, PACL* NewAcl )
3644 ULONG i;
3645 PSID *ppsid;
3646 DWORD ret = ERROR_SUCCESS;
3647 DWORD acl_size = sizeof(ACL);
3648 NTSTATUS status;
3650 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3652 if (NewAcl)
3653 *NewAcl = NULL;
3655 if (!count && !OldAcl)
3656 return ERROR_SUCCESS;
3658 /* allocate array of maximum sized sids allowed */
3659 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3660 if (!ppsid)
3661 return ERROR_OUTOFMEMORY;
3663 for (i = 0; i < count; i++)
3665 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3667 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3668 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3669 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3670 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3671 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3672 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3673 pEntries[i].Trustee.ptstrName);
3675 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3677 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3678 ret = ERROR_INVALID_PARAMETER;
3679 goto exit;
3682 switch (pEntries[i].Trustee.TrusteeForm)
3684 case TRUSTEE_IS_SID:
3685 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3686 ppsid[i], pEntries[i].Trustee.ptstrName))
3688 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3689 ret = ERROR_INVALID_PARAMETER;
3690 goto exit;
3692 break;
3693 case TRUSTEE_IS_NAME:
3695 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3696 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3697 SID_NAME_USE use;
3698 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3700 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3702 ret = GetLastError();
3703 goto exit;
3706 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3708 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3709 ret = ERROR_INVALID_PARAMETER;
3710 goto exit;
3712 break;
3714 case TRUSTEE_IS_OBJECTS_AND_SID:
3715 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3716 break;
3717 case TRUSTEE_IS_OBJECTS_AND_NAME:
3718 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3719 break;
3720 default:
3721 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3722 ret = ERROR_INVALID_PARAMETER;
3723 goto exit;
3726 /* Note: we overestimate the ACL size here as a tradeoff between
3727 * instructions (simplicity) and memory */
3728 switch (pEntries[i].grfAccessMode)
3730 case GRANT_ACCESS:
3731 case SET_ACCESS:
3732 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3733 break;
3734 case DENY_ACCESS:
3735 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3736 break;
3737 case SET_AUDIT_SUCCESS:
3738 case SET_AUDIT_FAILURE:
3739 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3740 break;
3741 case REVOKE_ACCESS:
3742 break;
3743 default:
3744 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3745 ret = ERROR_INVALID_PARAMETER;
3746 goto exit;
3750 if (OldAcl)
3752 ACL_SIZE_INFORMATION size_info;
3754 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3755 if (status != STATUS_SUCCESS)
3757 ret = RtlNtStatusToDosError(status);
3758 goto exit;
3760 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3763 *NewAcl = LocalAlloc(0, acl_size);
3764 if (!*NewAcl)
3766 ret = ERROR_OUTOFMEMORY;
3767 goto exit;
3770 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3771 if (status != STATUS_SUCCESS)
3773 ret = RtlNtStatusToDosError(status);
3774 goto exit;
3777 for (i = 0; i < count; i++)
3779 switch (pEntries[i].grfAccessMode)
3781 case GRANT_ACCESS:
3782 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3783 pEntries[i].grfInheritance,
3784 pEntries[i].grfAccessPermissions,
3785 ppsid[i]);
3786 break;
3787 case SET_ACCESS:
3789 ULONG j;
3790 BOOL add = TRUE;
3791 if (OldAcl)
3793 for (j = 0; ; j++)
3795 const ACE_HEADER *existing_ace_header;
3796 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3797 if (status != STATUS_SUCCESS)
3798 break;
3799 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3800 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3801 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3803 add = FALSE;
3804 break;
3808 if (add)
3809 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3810 pEntries[i].grfInheritance,
3811 pEntries[i].grfAccessPermissions,
3812 ppsid[i]);
3813 break;
3815 case DENY_ACCESS:
3816 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3817 pEntries[i].grfInheritance,
3818 pEntries[i].grfAccessPermissions,
3819 ppsid[i]);
3820 break;
3821 case SET_AUDIT_SUCCESS:
3822 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3823 pEntries[i].grfInheritance,
3824 pEntries[i].grfAccessPermissions,
3825 ppsid[i], TRUE, FALSE);
3826 break;
3827 case SET_AUDIT_FAILURE:
3828 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3829 pEntries[i].grfInheritance,
3830 pEntries[i].grfAccessPermissions,
3831 ppsid[i], FALSE, TRUE);
3832 break;
3833 default:
3834 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3838 if (OldAcl)
3840 for (i = 0; ; i++)
3842 BOOL add = TRUE;
3843 ULONG j;
3844 const ACE_HEADER *old_ace_header;
3845 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3846 if (status != STATUS_SUCCESS) break;
3847 for (j = 0; j < count; j++)
3849 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3850 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3851 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3853 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3854 add = FALSE;
3855 break;
3857 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3859 switch (old_ace_header->AceType)
3861 case ACCESS_ALLOWED_ACE_TYPE:
3862 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3863 add = FALSE;
3864 break;
3865 case ACCESS_DENIED_ACE_TYPE:
3866 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3867 add = FALSE;
3868 break;
3869 case SYSTEM_AUDIT_ACE_TYPE:
3870 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3871 add = FALSE;
3872 break;
3873 case SYSTEM_ALARM_ACE_TYPE:
3874 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3875 add = FALSE;
3876 break;
3877 default:
3878 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3881 if (!add)
3882 break;
3885 if (add)
3886 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3887 if (status != STATUS_SUCCESS)
3889 WARN("RtlAddAce failed with error 0x%08x\n", status);
3890 ret = RtlNtStatusToDosError(status);
3891 break;
3896 exit:
3897 HeapFree(GetProcessHeap(), 0, ppsid);
3898 return ret;
3901 /******************************************************************************
3902 * SetNamedSecurityInfoA [ADVAPI32.@]
3904 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3905 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3906 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3908 LPWSTR wstr;
3909 DWORD r;
3911 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3912 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3914 wstr = SERV_dup(pObjectName);
3915 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3916 psidGroup, pDacl, pSacl );
3918 HeapFree( GetProcessHeap(), 0, wstr );
3920 return r;
3923 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3924 PSECURITY_DESCRIPTOR ModificationDescriptor,
3925 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3926 PGENERIC_MAPPING GenericMapping,
3927 HANDLE Token )
3929 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3930 ObjectsSecurityDescriptor, GenericMapping, Token);
3932 return TRUE;
3935 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3937 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3940 /******************************************************************************
3941 * AreAnyAccessesGranted [ADVAPI32.@]
3943 * Determines whether or not any of a set of specified access permissions have
3944 * been granted or not.
3946 * PARAMS
3947 * GrantedAccess [I] The permissions that have been granted.
3948 * DesiredAccess [I] The permissions that you want to have.
3950 * RETURNS
3951 * Nonzero if any of the permissions have been granted, zero if none of the
3952 * permissions have been granted.
3955 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3957 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3960 /******************************************************************************
3961 * SetNamedSecurityInfoW [ADVAPI32.@]
3963 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3964 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3965 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3967 OBJECT_ATTRIBUTES attr;
3968 UNICODE_STRING nameW;
3969 IO_STATUS_BLOCK io;
3970 DWORD access = 0;
3971 HANDLE hFile;
3972 DWORD status;
3974 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3975 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3976 if (ObjectType != SE_FILE_OBJECT)
3978 FIXME( "Object type %d is not currently supported.\n", ObjectType );
3979 return ERROR_SUCCESS;
3982 if (!pObjectName) return ERROR_INVALID_PARAMETER;
3983 if (!RtlDosPathNameToNtPathName_U( pObjectName, &nameW, NULL, NULL ))
3984 return ERROR_PATH_NOT_FOUND;
3986 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
3987 access |= WRITE_OWNER;
3988 if (SecurityInfo & DACL_SECURITY_INFORMATION)
3989 access |= WRITE_DAC;
3990 if (SecurityInfo & SACL_SECURITY_INFORMATION)
3991 access |= ACCESS_SYSTEM_SECURITY;
3992 attr.Length = sizeof(attr);
3993 attr.RootDirectory = 0;
3994 attr.Attributes = OBJ_CASE_INSENSITIVE;
3995 attr.ObjectName = &nameW;
3996 attr.SecurityDescriptor = NULL;
3998 status = NtCreateFile( &hFile, access, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
3999 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4000 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
4001 RtlFreeUnicodeString( &nameW );
4002 if (status != STATUS_SUCCESS)
4003 return RtlNtStatusToDosError( status );
4004 status = SetSecurityInfo( hFile, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4005 CloseHandle( hFile );
4006 return status;
4009 /******************************************************************************
4010 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4012 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4013 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4015 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4016 return ERROR_CALL_NOT_IMPLEMENTED;
4019 /******************************************************************************
4020 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4022 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4023 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4025 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4026 return ERROR_CALL_NOT_IMPLEMENTED;
4029 /******************************************************************************
4030 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4032 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4033 PACCESS_MASK pFailedAuditRights)
4035 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4036 return ERROR_CALL_NOT_IMPLEMENTED;
4040 /******************************************************************************
4041 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4043 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4044 PACCESS_MASK pFailedAuditRights)
4046 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4047 return ERROR_CALL_NOT_IMPLEMENTED;
4051 /******************************************************************************
4052 * ParseAclStringFlags
4054 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4056 DWORD flags = 0;
4057 LPCWSTR szAcl = *StringAcl;
4059 while (*szAcl != '(')
4061 if (*szAcl == 'P')
4063 flags |= SE_DACL_PROTECTED;
4065 else if (*szAcl == 'A')
4067 szAcl++;
4068 if (*szAcl == 'R')
4069 flags |= SE_DACL_AUTO_INHERIT_REQ;
4070 else if (*szAcl == 'I')
4071 flags |= SE_DACL_AUTO_INHERITED;
4073 szAcl++;
4076 *StringAcl = szAcl;
4077 return flags;
4080 /******************************************************************************
4081 * ParseAceStringType
4083 static const ACEFLAG AceType[] =
4085 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4086 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4087 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4088 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4090 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4091 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4092 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4093 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4095 { NULL, 0 },
4098 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4100 UINT len = 0;
4101 LPCWSTR szAcl = *StringAcl;
4102 const ACEFLAG *lpaf = AceType;
4104 while (*szAcl == ' ')
4105 szAcl++;
4107 while (lpaf->wstr &&
4108 (len = strlenW(lpaf->wstr)) &&
4109 strncmpW(lpaf->wstr, szAcl, len))
4110 lpaf++;
4112 if (!lpaf->wstr)
4113 return 0;
4115 *StringAcl = szAcl + len;
4116 return lpaf->value;
4120 /******************************************************************************
4121 * ParseAceStringFlags
4123 static const ACEFLAG AceFlags[] =
4125 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4126 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4127 { SDDL_INHERITED, INHERITED_ACE },
4128 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4129 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4130 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4131 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4132 { NULL, 0 },
4135 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4137 UINT len = 0;
4138 BYTE flags = 0;
4139 LPCWSTR szAcl = *StringAcl;
4141 while (*szAcl == ' ')
4142 szAcl++;
4144 while (*szAcl != ';')
4146 const ACEFLAG *lpaf = AceFlags;
4148 while (lpaf->wstr &&
4149 (len = strlenW(lpaf->wstr)) &&
4150 strncmpW(lpaf->wstr, szAcl, len))
4151 lpaf++;
4153 if (!lpaf->wstr)
4154 return 0;
4156 flags |= lpaf->value;
4157 szAcl += len;
4160 *StringAcl = szAcl;
4161 return flags;
4165 /******************************************************************************
4166 * ParseAceStringRights
4168 static const ACEFLAG AceRights[] =
4170 { SDDL_GENERIC_ALL, GENERIC_ALL },
4171 { SDDL_GENERIC_READ, GENERIC_READ },
4172 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4173 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4175 { SDDL_READ_CONTROL, READ_CONTROL },
4176 { SDDL_STANDARD_DELETE, DELETE },
4177 { SDDL_WRITE_DAC, WRITE_DAC },
4178 { SDDL_WRITE_OWNER, WRITE_OWNER },
4180 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4181 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4182 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4183 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4184 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4185 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4186 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4187 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4188 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4190 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4191 { SDDL_FILE_READ, FILE_GENERIC_READ },
4192 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4193 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4195 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4196 { SDDL_KEY_READ, KEY_READ },
4197 { SDDL_KEY_WRITE, KEY_WRITE },
4198 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4199 { NULL, 0 },
4202 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4204 UINT len = 0;
4205 DWORD rights = 0;
4206 LPCWSTR szAcl = *StringAcl;
4208 while (*szAcl == ' ')
4209 szAcl++;
4211 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4213 LPCWSTR p = szAcl;
4215 while (*p && *p != ';')
4216 p++;
4218 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4220 rights = strtoulW(szAcl, NULL, 16);
4221 szAcl = p;
4223 else
4224 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4226 else
4228 while (*szAcl != ';')
4230 const ACEFLAG *lpaf = AceRights;
4232 while (lpaf->wstr &&
4233 (len = strlenW(lpaf->wstr)) &&
4234 strncmpW(lpaf->wstr, szAcl, len))
4236 lpaf++;
4239 if (!lpaf->wstr)
4240 return 0;
4242 rights |= lpaf->value;
4243 szAcl += len;
4247 *StringAcl = szAcl;
4248 return rights;
4252 /******************************************************************************
4253 * ParseStringAclToAcl
4255 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4257 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4258 PACL pAcl, LPDWORD cBytes)
4260 DWORD val;
4261 DWORD sidlen;
4262 DWORD length = sizeof(ACL);
4263 DWORD acesize = 0;
4264 DWORD acecount = 0;
4265 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4266 DWORD error = ERROR_INVALID_ACL;
4268 TRACE("%s\n", debugstr_w(StringAcl));
4270 if (!StringAcl)
4271 return FALSE;
4273 if (pAcl) /* pAce is only useful if we're setting values */
4274 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4276 /* Parse ACL flags */
4277 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4279 /* Parse ACE */
4280 while (*StringAcl == '(')
4282 StringAcl++;
4284 /* Parse ACE type */
4285 val = ParseAceStringType(&StringAcl);
4286 if (pAce)
4287 pAce->Header.AceType = (BYTE) val;
4288 if (*StringAcl != ';')
4290 error = RPC_S_INVALID_STRING_UUID;
4291 goto lerr;
4293 StringAcl++;
4295 /* Parse ACE flags */
4296 val = ParseAceStringFlags(&StringAcl);
4297 if (pAce)
4298 pAce->Header.AceFlags = (BYTE) val;
4299 if (*StringAcl != ';')
4300 goto lerr;
4301 StringAcl++;
4303 /* Parse ACE rights */
4304 val = ParseAceStringRights(&StringAcl);
4305 if (pAce)
4306 pAce->Mask = val;
4307 if (*StringAcl != ';')
4308 goto lerr;
4309 StringAcl++;
4311 /* Parse ACE object guid */
4312 while (*StringAcl == ' ')
4313 StringAcl++;
4314 if (*StringAcl != ';')
4316 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4317 goto lerr;
4319 StringAcl++;
4321 /* Parse ACE inherit object guid */
4322 while (*StringAcl == ' ')
4323 StringAcl++;
4324 if (*StringAcl != ';')
4326 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4327 goto lerr;
4329 StringAcl++;
4331 /* Parse ACE account sid */
4332 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4334 while (*StringAcl && *StringAcl != ')')
4335 StringAcl++;
4338 if (*StringAcl != ')')
4339 goto lerr;
4340 StringAcl++;
4342 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4343 length += acesize;
4344 if (pAce)
4346 pAce->Header.AceSize = acesize;
4347 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4349 acecount++;
4352 *cBytes = length;
4354 if (length > 0xffff)
4356 ERR("ACL too large\n");
4357 goto lerr;
4360 if (pAcl)
4362 pAcl->AclRevision = ACL_REVISION;
4363 pAcl->Sbz1 = 0;
4364 pAcl->AclSize = length;
4365 pAcl->AceCount = acecount++;
4366 pAcl->Sbz2 = 0;
4368 return TRUE;
4370 lerr:
4371 SetLastError(error);
4372 WARN("Invalid ACE string format\n");
4373 return FALSE;
4377 /******************************************************************************
4378 * ParseStringSecurityDescriptorToSecurityDescriptor
4380 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4381 LPCWSTR StringSecurityDescriptor,
4382 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4383 LPDWORD cBytes)
4385 BOOL bret = FALSE;
4386 WCHAR toktype;
4387 WCHAR tok[MAX_PATH];
4388 LPCWSTR lptoken;
4389 LPBYTE lpNext = NULL;
4390 DWORD len;
4392 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4394 if (SecurityDescriptor)
4395 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4397 while (*StringSecurityDescriptor == ' ')
4398 StringSecurityDescriptor++;
4400 while (*StringSecurityDescriptor)
4402 toktype = *StringSecurityDescriptor;
4404 /* Expect char identifier followed by ':' */
4405 StringSecurityDescriptor++;
4406 if (*StringSecurityDescriptor != ':')
4408 SetLastError(ERROR_INVALID_PARAMETER);
4409 goto lend;
4411 StringSecurityDescriptor++;
4413 /* Extract token */
4414 lptoken = StringSecurityDescriptor;
4415 while (*lptoken && *lptoken != ':')
4416 lptoken++;
4418 if (*lptoken)
4419 lptoken--;
4421 len = lptoken - StringSecurityDescriptor;
4422 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4423 tok[len] = 0;
4425 switch (toktype)
4427 case 'O':
4429 DWORD bytes;
4431 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4432 goto lend;
4434 if (SecurityDescriptor)
4436 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4437 lpNext += bytes; /* Advance to next token */
4440 *cBytes += bytes;
4442 break;
4445 case 'G':
4447 DWORD bytes;
4449 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4450 goto lend;
4452 if (SecurityDescriptor)
4454 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4455 lpNext += bytes; /* Advance to next token */
4458 *cBytes += bytes;
4460 break;
4463 case 'D':
4465 DWORD flags;
4466 DWORD bytes;
4468 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4469 goto lend;
4471 if (SecurityDescriptor)
4473 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4474 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4475 lpNext += bytes; /* Advance to next token */
4478 *cBytes += bytes;
4480 break;
4483 case 'S':
4485 DWORD flags;
4486 DWORD bytes;
4488 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4489 goto lend;
4491 if (SecurityDescriptor)
4493 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4494 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4495 lpNext += bytes; /* Advance to next token */
4498 *cBytes += bytes;
4500 break;
4503 default:
4504 FIXME("Unknown token\n");
4505 SetLastError(ERROR_INVALID_PARAMETER);
4506 goto lend;
4509 StringSecurityDescriptor = lptoken;
4512 bret = TRUE;
4514 lend:
4515 return bret;
4518 /******************************************************************************
4519 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4521 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4522 LPCSTR StringSecurityDescriptor,
4523 DWORD StringSDRevision,
4524 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4525 PULONG SecurityDescriptorSize)
4527 BOOL ret;
4528 LPWSTR StringSecurityDescriptorW;
4530 if(!StringSecurityDescriptor)
4531 return FALSE;
4533 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4534 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4535 StringSDRevision, SecurityDescriptor,
4536 SecurityDescriptorSize);
4537 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4539 return ret;
4542 /******************************************************************************
4543 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4545 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4546 LPCWSTR StringSecurityDescriptor,
4547 DWORD StringSDRevision,
4548 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4549 PULONG SecurityDescriptorSize)
4551 DWORD cBytes;
4552 SECURITY_DESCRIPTOR* psd;
4553 BOOL bret = FALSE;
4555 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4557 if (GetVersion() & 0x80000000)
4559 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4560 goto lend;
4562 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4564 SetLastError(ERROR_INVALID_PARAMETER);
4565 goto lend;
4567 else if (StringSDRevision != SID_REVISION)
4569 SetLastError(ERROR_UNKNOWN_REVISION);
4570 goto lend;
4573 /* Compute security descriptor length */
4574 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4575 NULL, &cBytes))
4576 goto lend;
4578 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4579 if (!psd) goto lend;
4581 psd->Revision = SID_REVISION;
4582 psd->Control |= SE_SELF_RELATIVE;
4584 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4585 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4587 LocalFree(psd);
4588 goto lend;
4591 if (SecurityDescriptorSize)
4592 *SecurityDescriptorSize = cBytes;
4594 bret = TRUE;
4596 lend:
4597 TRACE(" ret=%d\n", bret);
4598 return bret;
4601 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4603 if (cch == -1)
4604 cch = strlenW(string);
4606 if (plen)
4607 *plen += cch;
4609 if (pwptr)
4611 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4612 *pwptr += cch;
4616 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4618 DWORD i;
4619 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4620 WCHAR subauthfmt[] = { '-','%','u',0 };
4621 WCHAR buf[26];
4622 SID *pisid = psid;
4624 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4626 SetLastError(ERROR_INVALID_SID);
4627 return FALSE;
4630 if (pisid->IdentifierAuthority.Value[0] ||
4631 pisid->IdentifierAuthority.Value[1])
4633 FIXME("not matching MS' bugs\n");
4634 SetLastError(ERROR_INVALID_SID);
4635 return FALSE;
4638 sprintfW( buf, fmt, pisid->Revision,
4639 MAKELONG(
4640 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4641 pisid->IdentifierAuthority.Value[4] ),
4642 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4643 pisid->IdentifierAuthority.Value[2] )
4644 ) );
4645 DumpString(buf, -1, pwptr, plen);
4647 for( i=0; i<pisid->SubAuthorityCount; i++ )
4649 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4650 DumpString(buf, -1, pwptr, plen);
4652 return TRUE;
4655 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4657 size_t i;
4658 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4660 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4662 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4663 return TRUE;
4667 return DumpSidNumeric(psid, pwptr, plen);
4670 static const LPCWSTR AceRightBitNames[32] = {
4671 SDDL_CREATE_CHILD, /* 0 */
4672 SDDL_DELETE_CHILD,
4673 SDDL_LIST_CHILDREN,
4674 SDDL_SELF_WRITE,
4675 SDDL_READ_PROPERTY, /* 4 */
4676 SDDL_WRITE_PROPERTY,
4677 SDDL_DELETE_TREE,
4678 SDDL_LIST_OBJECT,
4679 SDDL_CONTROL_ACCESS, /* 8 */
4680 NULL,
4681 NULL,
4682 NULL,
4683 NULL, /* 12 */
4684 NULL,
4685 NULL,
4686 NULL,
4687 SDDL_STANDARD_DELETE, /* 16 */
4688 SDDL_READ_CONTROL,
4689 SDDL_WRITE_DAC,
4690 SDDL_WRITE_OWNER,
4691 NULL, /* 20 */
4692 NULL,
4693 NULL,
4694 NULL,
4695 NULL, /* 24 */
4696 NULL,
4697 NULL,
4698 NULL,
4699 SDDL_GENERIC_ALL, /* 28 */
4700 SDDL_GENERIC_EXECUTE,
4701 SDDL_GENERIC_WRITE,
4702 SDDL_GENERIC_READ
4705 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4707 static const WCHAR fmtW[] = {'0','x','%','x',0};
4708 WCHAR buf[15];
4709 size_t i;
4711 if (mask == 0)
4712 return;
4714 /* first check if the right have name */
4715 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4717 if (AceRights[i].wstr == NULL)
4718 break;
4719 if (mask == AceRights[i].value)
4721 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4722 return;
4726 /* then check if it can be built from bit names */
4727 for (i = 0; i < 32; i++)
4729 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4731 /* can't be built from bit names */
4732 sprintfW(buf, fmtW, mask);
4733 DumpString(buf, -1, pwptr, plen);
4734 return;
4738 /* build from bit names */
4739 for (i = 0; i < 32; i++)
4740 if (mask & (1 << i))
4741 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4744 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4746 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4747 static const WCHAR openbr = '(';
4748 static const WCHAR closebr = ')';
4749 static const WCHAR semicolon = ';';
4751 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4753 SetLastError(ERROR_INVALID_ACL);
4754 return FALSE;
4757 piace = pace;
4758 DumpString(&openbr, 1, pwptr, plen);
4759 switch (piace->Header.AceType)
4761 case ACCESS_ALLOWED_ACE_TYPE:
4762 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4763 break;
4764 case ACCESS_DENIED_ACE_TYPE:
4765 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4766 break;
4767 case SYSTEM_AUDIT_ACE_TYPE:
4768 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4769 break;
4770 case SYSTEM_ALARM_ACE_TYPE:
4771 DumpString(SDDL_ALARM, -1, pwptr, plen);
4772 break;
4774 DumpString(&semicolon, 1, pwptr, plen);
4776 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4777 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4778 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4779 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4780 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4781 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4782 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4783 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4784 if (piace->Header.AceFlags & INHERITED_ACE)
4785 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4786 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4787 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4788 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4789 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4790 DumpString(&semicolon, 1, pwptr, plen);
4791 DumpRights(piace->Mask, pwptr, plen);
4792 DumpString(&semicolon, 1, pwptr, plen);
4793 /* objects not supported */
4794 DumpString(&semicolon, 1, pwptr, plen);
4795 /* objects not supported */
4796 DumpString(&semicolon, 1, pwptr, plen);
4797 if (!DumpSid(&piace->SidStart, pwptr, plen))
4798 return FALSE;
4799 DumpString(&closebr, 1, pwptr, plen);
4800 return TRUE;
4803 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4805 WORD count;
4806 UINT i;
4808 if (protected)
4809 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4810 if (autoInheritReq)
4811 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4812 if (autoInherited)
4813 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4815 if (pacl == NULL)
4816 return TRUE;
4818 if (!IsValidAcl(pacl))
4819 return FALSE;
4821 count = pacl->AceCount;
4822 for (i = 0; i < count; i++)
4824 LPVOID ace;
4825 if (!GetAce(pacl, i, &ace))
4826 return FALSE;
4827 if (!DumpAce(ace, pwptr, plen))
4828 return FALSE;
4831 return TRUE;
4834 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4836 static const WCHAR prefix[] = {'O',':',0};
4837 BOOL bDefaulted;
4838 PSID psid;
4840 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4841 return FALSE;
4843 if (psid == NULL)
4844 return TRUE;
4846 DumpString(prefix, -1, pwptr, plen);
4847 if (!DumpSid(psid, pwptr, plen))
4848 return FALSE;
4849 return TRUE;
4852 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4854 static const WCHAR prefix[] = {'G',':',0};
4855 BOOL bDefaulted;
4856 PSID psid;
4858 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4859 return FALSE;
4861 if (psid == NULL)
4862 return TRUE;
4864 DumpString(prefix, -1, pwptr, plen);
4865 if (!DumpSid(psid, pwptr, plen))
4866 return FALSE;
4867 return TRUE;
4870 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4872 static const WCHAR dacl[] = {'D',':',0};
4873 SECURITY_DESCRIPTOR_CONTROL control;
4874 BOOL present, defaulted;
4875 DWORD revision;
4876 PACL pacl;
4878 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4879 return FALSE;
4881 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4882 return FALSE;
4884 if (!present)
4885 return TRUE;
4887 DumpString(dacl, 2, pwptr, plen);
4888 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4889 return FALSE;
4890 return TRUE;
4893 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4895 static const WCHAR sacl[] = {'S',':',0};
4896 SECURITY_DESCRIPTOR_CONTROL control;
4897 BOOL present, defaulted;
4898 DWORD revision;
4899 PACL pacl;
4901 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4902 return FALSE;
4904 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4905 return FALSE;
4907 if (!present)
4908 return TRUE;
4910 DumpString(sacl, 2, pwptr, plen);
4911 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4912 return FALSE;
4913 return TRUE;
4916 /******************************************************************************
4917 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4919 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4921 ULONG len;
4922 WCHAR *wptr, *wstr;
4924 if (SDRevision != SDDL_REVISION_1)
4926 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4927 SetLastError(ERROR_UNKNOWN_REVISION);
4928 return FALSE;
4931 len = 0;
4932 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4933 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4934 return FALSE;
4935 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4936 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4937 return FALSE;
4938 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4939 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4940 return FALSE;
4941 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4942 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4943 return FALSE;
4945 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4946 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4947 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
4948 LocalFree (wstr);
4949 return FALSE;
4951 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4952 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
4953 LocalFree (wstr);
4954 return FALSE;
4956 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4957 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
4958 LocalFree (wstr);
4959 return FALSE;
4961 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4962 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
4963 LocalFree (wstr);
4964 return FALSE;
4966 *wptr = 0;
4968 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4969 *OutputString = wstr;
4970 if (OutputLen)
4971 *OutputLen = strlenW(*OutputString)+1;
4972 return TRUE;
4975 /******************************************************************************
4976 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4978 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4980 LPWSTR wstr;
4981 ULONG len;
4982 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4984 int lenA;
4986 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4987 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4988 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4989 LocalFree(wstr);
4991 if (OutputLen != NULL)
4992 *OutputLen = lenA;
4993 return TRUE;
4995 else
4997 *OutputString = NULL;
4998 if (OutputLen)
4999 *OutputLen = 0;
5000 return FALSE;
5004 /******************************************************************************
5005 * ConvertStringSidToSidW [ADVAPI32.@]
5007 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5009 BOOL bret = FALSE;
5010 DWORD cBytes;
5012 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5013 if (GetVersion() & 0x80000000)
5014 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5015 else if (!StringSid || !Sid)
5016 SetLastError(ERROR_INVALID_PARAMETER);
5017 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5019 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5021 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5022 if (!bret)
5023 LocalFree(*Sid);
5025 return bret;
5028 /******************************************************************************
5029 * ConvertStringSidToSidA [ADVAPI32.@]
5031 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5033 BOOL bret = FALSE;
5035 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5036 if (GetVersion() & 0x80000000)
5037 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5038 else if (!StringSid || !Sid)
5039 SetLastError(ERROR_INVALID_PARAMETER);
5040 else
5042 WCHAR *wStringSid = SERV_dup(StringSid);
5043 bret = ConvertStringSidToSidW(wStringSid, Sid);
5044 HeapFree(GetProcessHeap(), 0, wStringSid);
5046 return bret;
5049 /******************************************************************************
5050 * ConvertSidToStringSidW [ADVAPI32.@]
5052 * format of SID string is:
5053 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5054 * where
5055 * <rev> is the revision of the SID encoded as decimal
5056 * <auth> is the identifier authority encoded as hex
5057 * <subauthN> is the subauthority id encoded as decimal
5059 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5061 DWORD len = 0;
5062 LPWSTR wstr, wptr;
5064 TRACE("%p %p\n", pSid, pstr );
5066 len = 0;
5067 if (!DumpSidNumeric(pSid, NULL, &len))
5068 return FALSE;
5069 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5070 DumpSidNumeric(pSid, &wptr, NULL);
5071 *wptr = 0;
5073 *pstr = wstr;
5074 return TRUE;
5077 /******************************************************************************
5078 * ConvertSidToStringSidA [ADVAPI32.@]
5080 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5082 LPWSTR wstr = NULL;
5083 LPSTR str;
5084 UINT len;
5086 TRACE("%p %p\n", pSid, pstr );
5088 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5089 return FALSE;
5091 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5092 str = LocalAlloc( 0, len );
5093 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5094 LocalFree( wstr );
5096 *pstr = str;
5098 return TRUE;
5101 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5102 PSECURITY_DESCRIPTOR pdesc,
5103 PSECURITY_DESCRIPTOR cdesc,
5104 PSECURITY_DESCRIPTOR* ndesc,
5105 GUID* objtype,
5106 BOOL isdir,
5107 PGENERIC_MAPPING genmap )
5109 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5111 return FALSE;
5114 BOOL WINAPI CreatePrivateObjectSecurity(
5115 PSECURITY_DESCRIPTOR ParentDescriptor,
5116 PSECURITY_DESCRIPTOR CreatorDescriptor,
5117 PSECURITY_DESCRIPTOR* NewDescriptor,
5118 BOOL IsDirectoryObject,
5119 HANDLE Token,
5120 PGENERIC_MAPPING GenericMapping )
5122 SECURITY_DESCRIPTOR_RELATIVE *relative;
5123 DWORD needed, offset;
5124 BYTE *buffer;
5126 FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5127 CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5129 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5130 needed += sizeof(sidWorld);
5131 needed += sizeof(sidWorld);
5132 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5133 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5135 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, needed ))) return FALSE;
5136 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5137 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5139 HeapFree( GetProcessHeap(), 0, buffer );
5140 return FALSE;
5142 relative->Control |= SE_SELF_RELATIVE;
5143 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5145 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5146 relative->Owner = offset;
5147 offset += sizeof(sidWorld);
5149 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5150 relative->Group = offset;
5151 offset += sizeof(sidWorld);
5153 GetWorldAccessACL( (ACL *)(buffer + offset) );
5154 relative->Dacl = offset;
5155 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5157 GetWorldAccessACL( (ACL *)(buffer + offset) );
5158 relative->Sacl = offset;
5160 *NewDescriptor = relative;
5161 return TRUE;
5164 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5166 FIXME("%p - stub\n", ObjectDescriptor);
5168 HeapFree( GetProcessHeap(), 0, *ObjectDescriptor );
5169 return TRUE;
5172 BOOL WINAPI CreateProcessAsUserA(
5173 HANDLE hToken,
5174 LPCSTR lpApplicationName,
5175 LPSTR lpCommandLine,
5176 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5177 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5178 BOOL bInheritHandles,
5179 DWORD dwCreationFlags,
5180 LPVOID lpEnvironment,
5181 LPCSTR lpCurrentDirectory,
5182 LPSTARTUPINFOA lpStartupInfo,
5183 LPPROCESS_INFORMATION lpProcessInformation )
5185 BOOL ret;
5186 WCHAR *appW, *cmdlnW, *cwdW;
5187 STARTUPINFOW sinfo;
5189 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5190 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5191 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5193 appW = SERV_dup(lpApplicationName);
5194 cmdlnW = SERV_dup(lpCommandLine);
5195 cwdW = SERV_dup(lpCurrentDirectory);
5196 sinfo.cb = sizeof(sinfo);
5197 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5198 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5199 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5200 sinfo.dwX = lpStartupInfo->dwX;
5201 sinfo.dwY = lpStartupInfo->dwY;
5202 sinfo.dwXSize = lpStartupInfo->dwXSize;
5203 sinfo.dwYSize = lpStartupInfo->dwYSize;
5204 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5205 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5206 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5207 sinfo.dwFlags = lpStartupInfo->dwFlags;
5208 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5209 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5210 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5211 sinfo.hStdInput = lpStartupInfo->hStdInput;
5212 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5213 sinfo.hStdError = lpStartupInfo->hStdError;
5214 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5215 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5216 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5217 HeapFree(GetProcessHeap(), 0, appW);
5218 HeapFree(GetProcessHeap(), 0, cmdlnW);
5219 HeapFree(GetProcessHeap(), 0, cwdW);
5220 HeapFree(GetProcessHeap(), 0, sinfo.lpReserved);
5221 HeapFree(GetProcessHeap(), 0, sinfo.lpDesktop);
5222 HeapFree(GetProcessHeap(), 0, sinfo.lpTitle);
5224 return ret;
5227 BOOL WINAPI CreateProcessAsUserW(
5228 HANDLE hToken,
5229 LPCWSTR lpApplicationName,
5230 LPWSTR lpCommandLine,
5231 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5232 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5233 BOOL bInheritHandles,
5234 DWORD dwCreationFlags,
5235 LPVOID lpEnvironment,
5236 LPCWSTR lpCurrentDirectory,
5237 LPSTARTUPINFOW lpStartupInfo,
5238 LPPROCESS_INFORMATION lpProcessInformation )
5240 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5241 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5242 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5243 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5245 /* We should create the process with a suspended main thread */
5246 if (!CreateProcessW (lpApplicationName,
5247 lpCommandLine,
5248 lpProcessAttributes,
5249 lpThreadAttributes,
5250 bInheritHandles,
5251 dwCreationFlags, /* CREATE_SUSPENDED */
5252 lpEnvironment,
5253 lpCurrentDirectory,
5254 lpStartupInfo,
5255 lpProcessInformation))
5257 return FALSE;
5260 return TRUE;
5263 /******************************************************************************
5264 * CreateProcessWithLogonW
5266 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5267 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5268 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5270 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5271 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5272 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5273 lpStartupInfo, lpProcessInformation);
5275 return FALSE;
5278 /******************************************************************************
5279 * DuplicateTokenEx [ADVAPI32.@]
5281 BOOL WINAPI DuplicateTokenEx(
5282 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5283 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5284 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5285 TOKEN_TYPE TokenType,
5286 PHANDLE DuplicateTokenHandle )
5288 OBJECT_ATTRIBUTES ObjectAttributes;
5290 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5291 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5293 InitializeObjectAttributes(
5294 &ObjectAttributes,
5295 NULL,
5296 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5297 NULL,
5298 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5300 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5301 dwDesiredAccess,
5302 &ObjectAttributes,
5303 ImpersonationLevel,
5304 TokenType,
5305 DuplicateTokenHandle ) );
5308 BOOL WINAPI DuplicateToken(
5309 HANDLE ExistingTokenHandle,
5310 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5311 PHANDLE DuplicateTokenHandle )
5313 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5314 NULL, ImpersonationLevel, TokenImpersonation,
5315 DuplicateTokenHandle );
5318 /******************************************************************************
5319 * ComputeStringSidSize
5321 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5323 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5325 int ctok = 0;
5326 while (*StringSid)
5328 if (*StringSid == '-')
5329 ctok++;
5330 StringSid++;
5333 if (ctok >= 3)
5334 return GetSidLengthRequired(ctok - 2);
5336 else /* String constant format - Only available in winxp and above */
5338 unsigned int i;
5340 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5341 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5342 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5344 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5345 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5347 MAX_SID local;
5348 ADVAPI_GetComputerSid(&local);
5349 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5354 return GetSidLengthRequired(0);
5357 /******************************************************************************
5358 * ParseStringSidToSid
5360 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5362 BOOL bret = FALSE;
5363 SID* pisid=pSid;
5365 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5366 if (!StringSid)
5368 SetLastError(ERROR_INVALID_PARAMETER);
5369 TRACE("StringSid is NULL, returning FALSE\n");
5370 return FALSE;
5373 while (*StringSid == ' ')
5374 StringSid++;
5376 *cBytes = ComputeStringSidSize(StringSid);
5377 if (!pisid) /* Simply compute the size */
5379 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5380 return TRUE;
5383 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5385 DWORD i = 0, identAuth;
5386 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5388 StringSid += 2; /* Advance to Revision */
5389 pisid->Revision = atoiW(StringSid);
5391 if (pisid->Revision != SDDL_REVISION)
5393 TRACE("Revision %d is unknown\n", pisid->Revision);
5394 goto lend; /* ERROR_INVALID_SID */
5396 if (csubauth == 0)
5398 TRACE("SubAuthorityCount is 0\n");
5399 goto lend; /* ERROR_INVALID_SID */
5402 pisid->SubAuthorityCount = csubauth;
5404 /* Advance to identifier authority */
5405 while (*StringSid && *StringSid != '-')
5406 StringSid++;
5407 if (*StringSid == '-')
5408 StringSid++;
5410 /* MS' implementation can't handle values greater than 2^32 - 1, so
5411 * we don't either; assume most significant bytes are always 0
5413 pisid->IdentifierAuthority.Value[0] = 0;
5414 pisid->IdentifierAuthority.Value[1] = 0;
5415 identAuth = atoiW(StringSid);
5416 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5417 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5418 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5419 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5421 /* Advance to first sub authority */
5422 while (*StringSid && *StringSid != '-')
5423 StringSid++;
5424 if (*StringSid == '-')
5425 StringSid++;
5427 while (*StringSid)
5429 pisid->SubAuthority[i++] = atoiW(StringSid);
5431 while (*StringSid && *StringSid != '-')
5432 StringSid++;
5433 if (*StringSid == '-')
5434 StringSid++;
5437 if (i != pisid->SubAuthorityCount)
5438 goto lend; /* ERROR_INVALID_SID */
5440 bret = TRUE;
5442 else /* String constant format - Only available in winxp and above */
5444 unsigned int i;
5445 pisid->Revision = SDDL_REVISION;
5447 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5448 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5450 DWORD j;
5451 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5452 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5453 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5454 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5455 bret = TRUE;
5458 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5459 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5461 ADVAPI_GetComputerSid(pisid);
5462 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5463 pisid->SubAuthorityCount++;
5464 bret = TRUE;
5467 if (!bret)
5468 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5471 lend:
5472 if (!bret)
5473 SetLastError(ERROR_INVALID_SID);
5475 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5476 return bret;
5479 /******************************************************************************
5480 * GetNamedSecurityInfoA [ADVAPI32.@]
5482 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5483 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5484 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5485 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5487 LPWSTR wstr;
5488 DWORD r;
5490 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5491 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5493 wstr = SERV_dup(pObjectName);
5494 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5495 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5497 HeapFree( GetProcessHeap(), 0, wstr );
5499 return r;
5502 /******************************************************************************
5503 * GetNamedSecurityInfoW [ADVAPI32.@]
5505 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5506 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5507 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5509 OBJECT_ATTRIBUTES attr;
5510 UNICODE_STRING nameW;
5511 IO_STATUS_BLOCK io;
5512 DWORD access = 0;
5513 HANDLE hFile;
5514 DWORD status;
5516 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5517 group, dacl, sacl, descriptor );
5518 if (type != SE_FILE_OBJECT)
5520 FIXME( "Object type %d is not currently supported.\n", type );
5521 if (owner) *owner = NULL;
5522 if (group) *group = NULL;
5523 if (dacl) *dacl = NULL;
5524 if (sacl) *sacl = NULL;
5525 if (descriptor) *descriptor = NULL;
5526 return ERROR_SUCCESS;
5529 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5530 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5532 /* If no descriptor, we have to check that there's a pointer for the requested information */
5533 if( !descriptor && (
5534 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5535 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5536 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5537 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5538 return ERROR_INVALID_PARAMETER;
5539 if (!RtlDosPathNameToNtPathName_U( name, &nameW, NULL, NULL ))
5540 return ERROR_PATH_NOT_FOUND;
5542 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5543 access |= READ_CONTROL;
5544 if (info & SACL_SECURITY_INFORMATION)
5545 access |= ACCESS_SYSTEM_SECURITY;
5546 attr.Length = sizeof(attr);
5547 attr.RootDirectory = 0;
5548 attr.Attributes = OBJ_CASE_INSENSITIVE;
5549 attr.ObjectName = &nameW;
5550 attr.SecurityDescriptor = NULL;
5552 status = NtCreateFile( &hFile, access, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
5553 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
5554 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
5555 RtlFreeUnicodeString( &nameW );
5556 if (status != STATUS_SUCCESS)
5557 return RtlNtStatusToDosError( status );
5558 status = GetSecurityInfo( hFile, type, info, owner, group, dacl, sacl, descriptor );
5559 CloseHandle( hFile );
5560 return status;
5563 /******************************************************************************
5564 * GetNamedSecurityInfoExW [ADVAPI32.@]
5566 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5567 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5568 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5570 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5571 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5572 return ERROR_CALL_NOT_IMPLEMENTED;
5575 /******************************************************************************
5576 * GetNamedSecurityInfoExA [ADVAPI32.@]
5578 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5579 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5580 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5582 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5583 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5584 return ERROR_CALL_NOT_IMPLEMENTED;
5587 /******************************************************************************
5588 * DecryptFileW [ADVAPI32.@]
5590 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5592 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5593 return TRUE;
5596 /******************************************************************************
5597 * DecryptFileA [ADVAPI32.@]
5599 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5601 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5602 return TRUE;
5605 /******************************************************************************
5606 * EncryptFileW [ADVAPI32.@]
5608 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5610 FIXME("%s\n", debugstr_w(lpFileName));
5611 return TRUE;
5614 /******************************************************************************
5615 * EncryptFileA [ADVAPI32.@]
5617 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5619 FIXME("%s\n", debugstr_a(lpFileName));
5620 return TRUE;
5623 /******************************************************************************
5624 * FileEncryptionStatusW [ADVAPI32.@]
5626 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5628 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5629 if (!lpStatus)
5630 return FALSE;
5631 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5632 return TRUE;
5635 /******************************************************************************
5636 * FileEncryptionStatusA [ADVAPI32.@]
5638 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5640 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5641 if (!lpStatus)
5642 return FALSE;
5643 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5644 return TRUE;
5647 /******************************************************************************
5648 * SetSecurityInfo [ADVAPI32.@]
5650 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5651 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5652 PSID psidGroup, PACL pDacl, PACL pSacl)
5654 SECURITY_DESCRIPTOR sd;
5655 NTSTATUS status;
5657 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5658 return ERROR_INVALID_SECURITY_DESCR;
5660 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5661 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5662 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5663 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5664 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5665 SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
5666 if (SecurityInfo & SACL_SECURITY_INFORMATION)
5667 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
5669 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
5670 return RtlNtStatusToDosError(status);
5673 /******************************************************************************
5674 * SaferCreateLevel [ADVAPI32.@]
5676 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5677 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5679 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5681 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5682 return TRUE;
5685 /******************************************************************************
5686 * SaferComputeTokenFromLevel [ADVAPI32.@]
5688 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5689 DWORD flags, LPVOID reserved)
5691 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5693 *access_token = (HANDLE)0xdeadbeef;
5694 return TRUE;
5697 /******************************************************************************
5698 * SaferCloseLevel [ADVAPI32.@]
5700 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5702 FIXME("(%p) stub\n", handle);
5703 return TRUE;
5706 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5707 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5708 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5709 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5710 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5712 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5713 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5714 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5716 return ERROR_SUCCESS;
5719 /******************************************************************************
5720 * SaferGetPolicyInformation [ADVAPI32.@]
5722 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5723 PVOID buffer, PDWORD required, LPVOID lpReserved)
5725 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5726 return FALSE;
5729 /******************************************************************************
5730 * SaferSetLevelInformation [ADVAPI32.@]
5732 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5733 LPVOID buffer, DWORD size)
5735 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5736 return FALSE;