ntdll: Do not report non-reserved memory areas as free since we don't know what's...
[wine/multimedia.git] / dlls / advapi32 / security.c
blobf57136dcfafde60017b7642a3e29ed7625092787
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 "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.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* 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 } } },
134 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
135 typedef struct WELLKNOWNRID
137 WELL_KNOWN_SID_TYPE Type;
138 DWORD Rid;
139 } WELLKNOWNRID;
141 static const WELLKNOWNRID WellKnownRids[] = {
142 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
143 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
144 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
145 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
146 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
147 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
148 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
149 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
150 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
151 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
152 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
153 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
154 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
158 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
160 typedef struct _AccountSid {
161 WELL_KNOWN_SID_TYPE type;
162 LPCWSTR account;
163 LPCWSTR domain;
164 SID_NAME_USE name_use;
165 } AccountSid;
167 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
168 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
169 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
170 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
171 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
172 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
173 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
174 static const WCHAR Blank[] = { 0 };
175 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
176 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
177 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
178 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 };
179 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
180 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 };
181 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
182 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 };
183 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
184 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
185 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
186 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
187 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
188 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
189 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
190 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 };
191 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
192 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 };
193 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
194 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
195 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
196 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
197 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
198 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
199 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 };
200 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
201 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
202 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
203 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
204 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
205 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
206 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 };
207 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 };
208 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
209 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 };
210 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
211 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
212 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
213 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 };
214 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 };
215 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
216 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
217 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 };
218 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
219 static const WCHAR SELF[] = { 'S','E','L','F',0 };
220 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
221 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
222 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
223 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 };
224 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
225 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
227 static const AccountSid ACCOUNT_SIDS[] = {
228 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
229 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
230 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
231 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
232 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
233 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
234 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
235 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
236 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
253 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
254 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
255 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
256 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
257 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
261 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
262 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
263 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
265 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
270 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
271 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
274 * ACE access rights
276 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
277 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
278 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
279 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
281 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
282 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
283 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
284 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
285 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
286 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
287 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
288 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
289 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
291 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
292 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
293 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
294 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
296 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
297 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
298 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
299 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
301 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
302 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
303 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
304 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
307 * ACL flags
309 static const WCHAR SDDL_PROTECTED[] = {'P',0};
310 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
311 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
314 * ACE types
316 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
317 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
319 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
320 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
321 static const WCHAR SDDL_ALARM[] = {'A','L',0};
322 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
323 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
326 * ACE flags
328 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
329 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
330 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
331 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
332 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
333 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
334 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
336 const char * debugstr_sid(PSID sid)
338 int auth = 0;
339 SID * psid = (SID *)sid;
341 if (psid == NULL)
342 return "(null)";
344 auth = psid->IdentifierAuthority.Value[5] +
345 (psid->IdentifierAuthority.Value[4] << 8) +
346 (psid->IdentifierAuthority.Value[3] << 16) +
347 (psid->IdentifierAuthority.Value[2] << 24);
349 switch (psid->SubAuthorityCount) {
350 case 0:
351 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
352 case 1:
353 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
354 psid->SubAuthority[0]);
355 case 2:
356 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
357 psid->SubAuthority[0], psid->SubAuthority[1]);
358 case 3:
359 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
360 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
361 case 4:
362 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
363 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
364 psid->SubAuthority[3]);
365 case 5:
366 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
367 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
368 psid->SubAuthority[3], psid->SubAuthority[4]);
369 case 6:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
373 case 7:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
377 psid->SubAuthority[6]);
378 case 8:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
382 psid->SubAuthority[6], psid->SubAuthority[7]);
384 return "(too-big)";
387 /* set last error code from NT status and get the proper boolean return value */
388 /* used for functions that are a simple wrapper around the corresponding ntdll API */
389 static inline BOOL set_ntstatus( NTSTATUS status )
391 if (status) SetLastError( RtlNtStatusToDosError( status ));
392 return !status;
395 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
397 static void GetWorldAccessACL(PACL pACL)
399 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
401 pACL->AclRevision = ACL_REVISION;
402 pACL->Sbz1 = 0;
403 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
404 pACL->AceCount = 1;
405 pACL->Sbz2 = 0;
407 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
408 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
409 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
410 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
411 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
414 /************************************************************
415 * ADVAPI_IsLocalComputer
417 * Checks whether the server name indicates local machine.
419 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
421 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
422 BOOL Result;
423 LPWSTR buf;
425 if (!ServerName || !ServerName[0])
426 return TRUE;
428 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
429 Result = GetComputerNameW(buf, &dwSize);
430 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
431 ServerName += 2;
432 Result = Result && !lstrcmpW(ServerName, buf);
433 HeapFree(GetProcessHeap(), 0, buf);
435 return Result;
438 /************************************************************
439 * ADVAPI_GetComputerSid
441 * Reads the computer SID from the registry.
443 BOOL ADVAPI_GetComputerSid(PSID sid)
445 HKEY key;
446 LONG ret;
447 BOOL retval = FALSE;
448 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
449 static const WCHAR V[] = { 'V',0 };
451 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
452 KEY_READ, &key)) == ERROR_SUCCESS)
454 DWORD size = 0;
455 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
456 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
458 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
459 if (data)
461 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
462 data, &size)) == ERROR_SUCCESS)
464 /* the SID is in the last 24 bytes of the binary data */
465 CopyMemory(sid, &data[size-24], 24);
466 retval = TRUE;
468 HeapFree(GetProcessHeap(), 0, data);
471 RegCloseKey(key);
474 if(retval == TRUE) return retval;
476 /* create a new random SID */
477 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
478 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
480 PSID new_sid;
481 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
482 DWORD id[3];
484 if (RtlGenRandom(id, sizeof(id)))
486 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
488 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
489 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
491 FreeSid(new_sid);
494 RegCloseKey(key);
497 return retval;
500 /* ##############################
501 ###### TOKEN FUNCTIONS ######
502 ##############################
505 /******************************************************************************
506 * OpenProcessToken [ADVAPI32.@]
507 * Opens the access token associated with a process handle.
509 * PARAMS
510 * ProcessHandle [I] Handle to process
511 * DesiredAccess [I] Desired access to process
512 * TokenHandle [O] Pointer to handle of open access token
514 * RETURNS
515 * Success: TRUE. TokenHandle contains the access token.
516 * Failure: FALSE.
518 * NOTES
519 * See NtOpenProcessToken.
521 BOOL WINAPI
522 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
523 HANDLE *TokenHandle )
525 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
528 /******************************************************************************
529 * OpenThreadToken [ADVAPI32.@]
531 * Opens the access token associated with a thread handle.
533 * PARAMS
534 * ThreadHandle [I] Handle to process
535 * DesiredAccess [I] Desired access to the thread
536 * OpenAsSelf [I] ???
537 * TokenHandle [O] Destination for the token handle
539 * RETURNS
540 * Success: TRUE. TokenHandle contains the access token.
541 * Failure: FALSE.
543 * NOTES
544 * See NtOpenThreadToken.
546 BOOL WINAPI
547 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
548 BOOL OpenAsSelf, HANDLE *TokenHandle)
550 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
553 BOOL WINAPI
554 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
555 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
557 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
558 PreviousState, ReturnLength));
561 /******************************************************************************
562 * AdjustTokenPrivileges [ADVAPI32.@]
564 * Adjust the privileges of an open token handle.
566 * PARAMS
567 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
568 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
569 * NewState [I] Desired new privileges of the token
570 * BufferLength [I] Length of NewState
571 * PreviousState [O] Destination for the previous state
572 * ReturnLength [I/O] Size of PreviousState
575 * RETURNS
576 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
577 * Failure: FALSE.
579 * NOTES
580 * See NtAdjustPrivilegesToken.
582 BOOL WINAPI
583 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
584 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
585 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
587 NTSTATUS status;
589 TRACE("\n");
591 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
592 NewState, BufferLength, PreviousState,
593 ReturnLength);
594 SetLastError( RtlNtStatusToDosError( status ));
595 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
596 return TRUE;
597 else
598 return FALSE;
601 /******************************************************************************
602 * CheckTokenMembership [ADVAPI32.@]
604 * Determine if an access token is a member of a SID.
606 * PARAMS
607 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
608 * SidToCheck [I] SID that possibly contains the token
609 * IsMember [O] Destination for result.
611 * RETURNS
612 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
613 * Failure: FALSE.
615 BOOL WINAPI
616 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
617 PBOOL IsMember )
619 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
621 *IsMember = TRUE;
622 return(TRUE);
625 /******************************************************************************
626 * GetTokenInformation [ADVAPI32.@]
628 * Get a type of information about an access token.
630 * PARAMS
631 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
632 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
633 * tokeninfo [O] Destination for token information
634 * tokeninfolength [I] Length of tokeninfo
635 * retlen [O] Destination for returned token information length
637 * RETURNS
638 * Success: TRUE. tokeninfo contains retlen bytes of token information
639 * Failure: FALSE.
641 * NOTES
642 * See NtQueryInformationToken.
644 BOOL WINAPI
645 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
646 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
648 TRACE("(%p, %s, %p, %d, %p):\n",
649 token,
650 (tokeninfoclass == TokenUser) ? "TokenUser" :
651 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
652 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
653 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
654 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
655 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
656 (tokeninfoclass == TokenSource) ? "TokenSource" :
657 (tokeninfoclass == TokenType) ? "TokenType" :
658 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
659 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
660 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
661 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
662 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
663 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
664 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
665 "Unknown",
666 tokeninfo, tokeninfolength, retlen);
667 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
668 tokeninfolength, retlen));
671 /******************************************************************************
672 * SetTokenInformation [ADVAPI32.@]
674 * Set information for an access token.
676 * PARAMS
677 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
678 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
679 * tokeninfo [I] Token information to set
680 * tokeninfolength [I] Length of tokeninfo
682 * RETURNS
683 * Success: TRUE. The information for the token is set to tokeninfo.
684 * Failure: FALSE.
686 BOOL WINAPI
687 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
688 LPVOID tokeninfo, DWORD tokeninfolength )
690 TRACE("(%p, %s, %p, %d): stub\n",
691 token,
692 (tokeninfoclass == TokenUser) ? "TokenUser" :
693 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
694 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
695 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
696 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
697 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
698 (tokeninfoclass == TokenSource) ? "TokenSource" :
699 (tokeninfoclass == TokenType) ? "TokenType" :
700 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
701 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
702 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
703 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
704 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
705 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
706 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
707 "Unknown",
708 tokeninfo, tokeninfolength);
710 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
713 /*************************************************************************
714 * SetThreadToken [ADVAPI32.@]
716 * Assigns an 'impersonation token' to a thread so it can assume the
717 * security privileges of another thread or process. Can also remove
718 * a previously assigned token.
720 * PARAMS
721 * thread [O] Handle to thread to set the token for
722 * token [I] Token to set
724 * RETURNS
725 * Success: TRUE. The threads access token is set to token
726 * Failure: FALSE.
728 * NOTES
729 * Only supported on NT or higher. On Win9X this function does nothing.
730 * See SetTokenInformation.
732 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
734 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
735 ThreadImpersonationToken, &token, sizeof token ));
738 /*************************************************************************
739 * CreateRestrictedToken [ADVAPI32.@]
741 * Create a new more restricted token from an existing token.
743 * PARAMS
744 * baseToken [I] Token to base the new restricted token on
745 * flags [I] Options
746 * nDisableSids [I] Length of disableSids array
747 * disableSids [I] Array of SIDs to disable in the new token
748 * nDeletePrivs [I] Length of deletePrivs array
749 * deletePrivs [I] Array of privileges to delete in the new token
750 * nRestrictSids [I] Length of restrictSids array
751 * restrictSids [I] Array of SIDs to restrict in the new token
752 * newToken [O] Address where the new token is stored
754 * RETURNS
755 * Success: TRUE
756 * Failure: FALSE
758 BOOL WINAPI CreateRestrictedToken(
759 HANDLE baseToken,
760 DWORD flags,
761 DWORD nDisableSids,
762 PSID_AND_ATTRIBUTES disableSids,
763 DWORD nDeletePrivs,
764 PLUID_AND_ATTRIBUTES deletePrivs,
765 DWORD nRestrictSids,
766 PSID_AND_ATTRIBUTES restrictSids,
767 PHANDLE newToken)
769 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
770 baseToken, flags, nDisableSids, disableSids,
771 nDeletePrivs, deletePrivs,
772 nRestrictSids, restrictSids,
773 newToken);
774 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
775 return FALSE;
778 /* ##############################
779 ###### SID FUNCTIONS ######
780 ##############################
783 /******************************************************************************
784 * AllocateAndInitializeSid [ADVAPI32.@]
786 * PARAMS
787 * pIdentifierAuthority []
788 * nSubAuthorityCount []
789 * nSubAuthority0 []
790 * nSubAuthority1 []
791 * nSubAuthority2 []
792 * nSubAuthority3 []
793 * nSubAuthority4 []
794 * nSubAuthority5 []
795 * nSubAuthority6 []
796 * nSubAuthority7 []
797 * pSid []
799 BOOL WINAPI
800 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
801 BYTE nSubAuthorityCount,
802 DWORD nSubAuthority0, DWORD nSubAuthority1,
803 DWORD nSubAuthority2, DWORD nSubAuthority3,
804 DWORD nSubAuthority4, DWORD nSubAuthority5,
805 DWORD nSubAuthority6, DWORD nSubAuthority7,
806 PSID *pSid )
808 return set_ntstatus( RtlAllocateAndInitializeSid(
809 pIdentifierAuthority, nSubAuthorityCount,
810 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
811 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
812 pSid ));
815 /******************************************************************************
816 * FreeSid [ADVAPI32.@]
818 * PARAMS
819 * pSid []
821 PVOID WINAPI
822 FreeSid( PSID pSid )
824 RtlFreeSid(pSid);
825 return NULL; /* is documented like this */
828 /******************************************************************************
829 * CopySid [ADVAPI32.@]
831 * PARAMS
832 * nDestinationSidLength []
833 * pDestinationSid []
834 * pSourceSid []
836 BOOL WINAPI
837 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
839 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
842 /******************************************************************************
843 * CreateWellKnownSid [ADVAPI32.@]
845 BOOL WINAPI
846 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
847 PSID DomainSid,
848 PSID pSid,
849 DWORD* cbSid)
851 unsigned int i;
852 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
854 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
855 SetLastError(ERROR_INVALID_PARAMETER);
856 return FALSE;
859 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
860 if (WellKnownSids[i].Type == WellKnownSidType) {
861 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
863 if (*cbSid < length) {
864 SetLastError(ERROR_INSUFFICIENT_BUFFER);
865 return FALSE;
868 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
869 *cbSid = length;
870 return TRUE;
874 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
876 SetLastError(ERROR_INVALID_PARAMETER);
877 return FALSE;
880 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
881 if (WellKnownRids[i].Type == WellKnownSidType) {
882 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
883 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
884 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
886 if (*cbSid < output_sid_length) {
887 SetLastError(ERROR_INSUFFICIENT_BUFFER);
888 return FALSE;
891 CopyMemory(pSid, DomainSid, domain_sid_length);
892 (*GetSidSubAuthorityCount(pSid))++;
893 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
894 *cbSid = output_sid_length;
895 return TRUE;
898 SetLastError(ERROR_INVALID_PARAMETER);
899 return FALSE;
902 /******************************************************************************
903 * IsWellKnownSid [ADVAPI32.@]
905 BOOL WINAPI
906 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
908 unsigned int i;
909 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
911 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
912 if (WellKnownSids[i].Type == WellKnownSidType)
913 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
914 return TRUE;
916 return FALSE;
919 BOOL WINAPI
920 IsTokenRestricted( HANDLE TokenHandle )
922 TOKEN_GROUPS *groups;
923 DWORD size;
924 NTSTATUS status;
925 BOOL restricted;
927 TRACE("(%p)\n", TokenHandle);
929 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
930 if (status != STATUS_BUFFER_TOO_SMALL)
931 return FALSE;
933 groups = HeapAlloc(GetProcessHeap(), 0, size);
934 if (!groups)
936 SetLastError(ERROR_OUTOFMEMORY);
937 return FALSE;
940 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
941 if (status != STATUS_SUCCESS)
943 HeapFree(GetProcessHeap(), 0, groups);
944 return set_ntstatus(status);
947 if (groups->GroupCount)
948 restricted = TRUE;
949 else
950 restricted = FALSE;
952 HeapFree(GetProcessHeap(), 0, groups);
954 return restricted;
957 /******************************************************************************
958 * IsValidSid [ADVAPI32.@]
960 * PARAMS
961 * pSid []
963 BOOL WINAPI
964 IsValidSid( PSID pSid )
966 return RtlValidSid( pSid );
969 /******************************************************************************
970 * EqualSid [ADVAPI32.@]
972 * PARAMS
973 * pSid1 []
974 * pSid2 []
976 BOOL WINAPI
977 EqualSid( PSID pSid1, PSID pSid2 )
979 return RtlEqualSid( pSid1, pSid2 );
982 /******************************************************************************
983 * EqualPrefixSid [ADVAPI32.@]
985 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
987 return RtlEqualPrefixSid(pSid1, pSid2);
990 /******************************************************************************
991 * GetSidLengthRequired [ADVAPI32.@]
993 * PARAMS
994 * nSubAuthorityCount []
996 DWORD WINAPI
997 GetSidLengthRequired( BYTE nSubAuthorityCount )
999 return RtlLengthRequiredSid(nSubAuthorityCount);
1002 /******************************************************************************
1003 * InitializeSid [ADVAPI32.@]
1005 * PARAMS
1006 * pIdentifierAuthority []
1008 BOOL WINAPI
1009 InitializeSid (
1010 PSID pSid,
1011 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1012 BYTE nSubAuthorityCount)
1014 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1017 DWORD WINAPI
1018 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1020 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1022 return 1;
1025 DWORD WINAPI
1026 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1028 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1030 return 1;
1033 /******************************************************************************
1034 * GetSidIdentifierAuthority [ADVAPI32.@]
1036 * PARAMS
1037 * pSid []
1039 PSID_IDENTIFIER_AUTHORITY WINAPI
1040 GetSidIdentifierAuthority( PSID pSid )
1042 return RtlIdentifierAuthoritySid(pSid);
1045 /******************************************************************************
1046 * GetSidSubAuthority [ADVAPI32.@]
1048 * PARAMS
1049 * pSid []
1050 * nSubAuthority []
1052 PDWORD WINAPI
1053 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1055 return RtlSubAuthoritySid(pSid, nSubAuthority);
1058 /******************************************************************************
1059 * GetSidSubAuthorityCount [ADVAPI32.@]
1061 * PARAMS
1062 * pSid []
1064 PUCHAR WINAPI
1065 GetSidSubAuthorityCount (PSID pSid)
1067 return RtlSubAuthorityCountSid(pSid);
1070 /******************************************************************************
1071 * GetLengthSid [ADVAPI32.@]
1073 * PARAMS
1074 * pSid []
1076 DWORD WINAPI
1077 GetLengthSid (PSID pSid)
1079 return RtlLengthSid(pSid);
1082 /* ##############################################
1083 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1084 ##############################################
1087 /******************************************************************************
1088 * BuildSecurityDescriptorA [ADVAPI32.@]
1090 * Builds a SD from
1092 * PARAMS
1093 * pOwner [I]
1094 * pGroup [I]
1095 * cCountOfAccessEntries [I]
1096 * pListOfAccessEntries [I]
1097 * cCountOfAuditEntries [I]
1098 * pListofAuditEntries [I]
1099 * pOldSD [I]
1100 * lpdwBufferLength [I/O]
1101 * pNewSD [O]
1103 * RETURNS
1104 * Success: ERROR_SUCCESS
1105 * Failure: nonzero error code from Winerror.h
1107 DWORD WINAPI BuildSecurityDescriptorA(
1108 IN PTRUSTEEA pOwner,
1109 IN PTRUSTEEA pGroup,
1110 IN ULONG cCountOfAccessEntries,
1111 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1112 IN ULONG cCountOfAuditEntries,
1113 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1114 IN PSECURITY_DESCRIPTOR pOldSD,
1115 IN OUT PULONG lpdwBufferLength,
1116 OUT PSECURITY_DESCRIPTOR* pNewSD)
1118 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1119 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1120 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1122 return ERROR_CALL_NOT_IMPLEMENTED;
1125 /******************************************************************************
1126 * BuildSecurityDescriptorW [ADVAPI32.@]
1128 * See BuildSecurityDescriptorA.
1130 DWORD WINAPI BuildSecurityDescriptorW(
1131 IN PTRUSTEEW pOwner,
1132 IN PTRUSTEEW pGroup,
1133 IN ULONG cCountOfAccessEntries,
1134 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1135 IN ULONG cCountOfAuditEntries,
1136 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1137 IN PSECURITY_DESCRIPTOR pOldSD,
1138 IN OUT PULONG lpdwBufferLength,
1139 OUT PSECURITY_DESCRIPTOR* pNewSD)
1141 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1142 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1143 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145 return ERROR_CALL_NOT_IMPLEMENTED;
1148 /******************************************************************************
1149 * InitializeSecurityDescriptor [ADVAPI32.@]
1151 * PARAMS
1152 * pDescr []
1153 * revision []
1155 BOOL WINAPI
1156 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1158 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1162 /******************************************************************************
1163 * MakeAbsoluteSD [ADVAPI32.@]
1165 BOOL WINAPI MakeAbsoluteSD (
1166 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1167 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1168 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1169 OUT PACL pDacl,
1170 OUT LPDWORD lpdwDaclSize,
1171 OUT PACL pSacl,
1172 OUT LPDWORD lpdwSaclSize,
1173 OUT PSID pOwner,
1174 OUT LPDWORD lpdwOwnerSize,
1175 OUT PSID pPrimaryGroup,
1176 OUT LPDWORD lpdwPrimaryGroupSize)
1178 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1179 pAbsoluteSecurityDescriptor,
1180 lpdwAbsoluteSecurityDescriptorSize,
1181 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1182 pOwner, lpdwOwnerSize,
1183 pPrimaryGroup, lpdwPrimaryGroupSize));
1186 /******************************************************************************
1187 * GetKernelObjectSecurity [ADVAPI32.@]
1189 BOOL WINAPI GetKernelObjectSecurity(
1190 HANDLE Handle,
1191 SECURITY_INFORMATION RequestedInformation,
1192 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1193 DWORD nLength,
1194 LPDWORD lpnLengthNeeded )
1196 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1197 pSecurityDescriptor, nLength, lpnLengthNeeded);
1199 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1200 nLength, lpnLengthNeeded ));
1203 /******************************************************************************
1204 * GetPrivateObjectSecurity [ADVAPI32.@]
1206 BOOL WINAPI GetPrivateObjectSecurity(
1207 PSECURITY_DESCRIPTOR ObjectDescriptor,
1208 SECURITY_INFORMATION SecurityInformation,
1209 PSECURITY_DESCRIPTOR ResultantDescriptor,
1210 DWORD DescriptorLength,
1211 PDWORD ReturnLength )
1213 SECURITY_DESCRIPTOR desc;
1214 BOOL defaulted, present;
1215 PACL pacl;
1216 PSID psid;
1218 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1219 ResultantDescriptor, DescriptorLength, ReturnLength);
1221 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1222 return FALSE;
1224 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1226 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1227 return FALSE;
1228 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1231 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1233 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1234 return FALSE;
1235 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1238 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1240 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1241 return FALSE;
1242 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1245 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1247 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1248 return FALSE;
1249 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1252 *ReturnLength = DescriptorLength;
1253 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1256 /******************************************************************************
1257 * GetSecurityDescriptorLength [ADVAPI32.@]
1259 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1261 return RtlLengthSecurityDescriptor(pDescr);
1264 /******************************************************************************
1265 * GetSecurityDescriptorOwner [ADVAPI32.@]
1267 * PARAMS
1268 * pOwner []
1269 * lpbOwnerDefaulted []
1271 BOOL WINAPI
1272 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1273 LPBOOL lpbOwnerDefaulted )
1275 BOOLEAN defaulted;
1276 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1277 *lpbOwnerDefaulted = defaulted;
1278 return ret;
1281 /******************************************************************************
1282 * SetSecurityDescriptorOwner [ADVAPI32.@]
1284 * PARAMS
1286 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1287 PSID pOwner, BOOL bOwnerDefaulted)
1289 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1291 /******************************************************************************
1292 * GetSecurityDescriptorGroup [ADVAPI32.@]
1294 BOOL WINAPI GetSecurityDescriptorGroup(
1295 PSECURITY_DESCRIPTOR SecurityDescriptor,
1296 PSID *Group,
1297 LPBOOL GroupDefaulted)
1299 BOOLEAN defaulted;
1300 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1301 *GroupDefaulted = defaulted;
1302 return ret;
1304 /******************************************************************************
1305 * SetSecurityDescriptorGroup [ADVAPI32.@]
1307 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1308 PSID Group, BOOL GroupDefaulted)
1310 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1313 /******************************************************************************
1314 * IsValidSecurityDescriptor [ADVAPI32.@]
1316 * PARAMS
1317 * lpsecdesc []
1319 BOOL WINAPI
1320 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1322 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1325 /******************************************************************************
1326 * GetSecurityDescriptorDacl [ADVAPI32.@]
1328 BOOL WINAPI GetSecurityDescriptorDacl(
1329 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1330 OUT LPBOOL lpbDaclPresent,
1331 OUT PACL *pDacl,
1332 OUT LPBOOL lpbDaclDefaulted)
1334 BOOLEAN present, defaulted;
1335 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1336 *lpbDaclPresent = present;
1337 *lpbDaclDefaulted = defaulted;
1338 return ret;
1341 /******************************************************************************
1342 * SetSecurityDescriptorDacl [ADVAPI32.@]
1344 BOOL WINAPI
1345 SetSecurityDescriptorDacl (
1346 PSECURITY_DESCRIPTOR lpsd,
1347 BOOL daclpresent,
1348 PACL dacl,
1349 BOOL dacldefaulted )
1351 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1353 /******************************************************************************
1354 * GetSecurityDescriptorSacl [ADVAPI32.@]
1356 BOOL WINAPI GetSecurityDescriptorSacl(
1357 IN PSECURITY_DESCRIPTOR lpsd,
1358 OUT LPBOOL lpbSaclPresent,
1359 OUT PACL *pSacl,
1360 OUT LPBOOL lpbSaclDefaulted)
1362 BOOLEAN present, defaulted;
1363 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1364 *lpbSaclPresent = present;
1365 *lpbSaclDefaulted = defaulted;
1366 return ret;
1369 /**************************************************************************
1370 * SetSecurityDescriptorSacl [ADVAPI32.@]
1372 BOOL WINAPI SetSecurityDescriptorSacl (
1373 PSECURITY_DESCRIPTOR lpsd,
1374 BOOL saclpresent,
1375 PACL lpsacl,
1376 BOOL sacldefaulted)
1378 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1380 /******************************************************************************
1381 * MakeSelfRelativeSD [ADVAPI32.@]
1383 * PARAMS
1384 * lpabssecdesc []
1385 * lpselfsecdesc []
1386 * lpbuflen []
1388 BOOL WINAPI
1389 MakeSelfRelativeSD(
1390 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1391 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1392 IN OUT LPDWORD lpdwBufferLength)
1394 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1395 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1398 /******************************************************************************
1399 * GetSecurityDescriptorControl [ADVAPI32.@]
1402 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1403 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1405 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1408 /******************************************************************************
1409 * SetSecurityDescriptorControl [ADVAPI32.@]
1411 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1412 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1413 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1415 return set_ntstatus( RtlSetControlSecurityDescriptor(
1416 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1419 /* ##############################
1420 ###### ACL FUNCTIONS ######
1421 ##############################
1424 /*************************************************************************
1425 * InitializeAcl [ADVAPI32.@]
1427 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1429 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1432 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1434 IO_STATUS_BLOCK io_block;
1436 TRACE("(%p)\n", hNamedPipe);
1438 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1439 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1442 /******************************************************************************
1443 * AddAccessAllowedAce [ADVAPI32.@]
1445 BOOL WINAPI AddAccessAllowedAce(
1446 IN OUT PACL pAcl,
1447 IN DWORD dwAceRevision,
1448 IN DWORD AccessMask,
1449 IN PSID pSid)
1451 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1454 /******************************************************************************
1455 * AddAccessAllowedAceEx [ADVAPI32.@]
1457 BOOL WINAPI AddAccessAllowedAceEx(
1458 IN OUT PACL pAcl,
1459 IN DWORD dwAceRevision,
1460 IN DWORD AceFlags,
1461 IN DWORD AccessMask,
1462 IN PSID pSid)
1464 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1467 /******************************************************************************
1468 * AddAccessDeniedAce [ADVAPI32.@]
1470 BOOL WINAPI AddAccessDeniedAce(
1471 IN OUT PACL pAcl,
1472 IN DWORD dwAceRevision,
1473 IN DWORD AccessMask,
1474 IN PSID pSid)
1476 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1479 /******************************************************************************
1480 * AddAccessDeniedAceEx [ADVAPI32.@]
1482 BOOL WINAPI AddAccessDeniedAceEx(
1483 IN OUT PACL pAcl,
1484 IN DWORD dwAceRevision,
1485 IN DWORD AceFlags,
1486 IN DWORD AccessMask,
1487 IN PSID pSid)
1489 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1492 /******************************************************************************
1493 * AddAce [ADVAPI32.@]
1495 BOOL WINAPI AddAce(
1496 IN OUT PACL pAcl,
1497 IN DWORD dwAceRevision,
1498 IN DWORD dwStartingAceIndex,
1499 LPVOID pAceList,
1500 DWORD nAceListLength)
1502 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1505 /******************************************************************************
1506 * DeleteAce [ADVAPI32.@]
1508 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1510 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1513 /******************************************************************************
1514 * FindFirstFreeAce [ADVAPI32.@]
1516 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1518 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1521 /******************************************************************************
1522 * GetAce [ADVAPI32.@]
1524 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1526 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1529 /******************************************************************************
1530 * GetAclInformation [ADVAPI32.@]
1532 BOOL WINAPI GetAclInformation(
1533 PACL pAcl,
1534 LPVOID pAclInformation,
1535 DWORD nAclInformationLength,
1536 ACL_INFORMATION_CLASS dwAclInformationClass)
1538 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1539 nAclInformationLength, dwAclInformationClass));
1542 /******************************************************************************
1543 * IsValidAcl [ADVAPI32.@]
1545 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1547 return RtlValidAcl(pAcl);
1550 /* ##############################
1551 ###### MISC FUNCTIONS ######
1552 ##############################
1555 /******************************************************************************
1556 * AllocateLocallyUniqueId [ADVAPI32.@]
1558 * PARAMS
1559 * lpLuid []
1561 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1563 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1566 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1567 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1568 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1569 { '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 };
1570 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1571 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1572 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1573 { '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 };
1574 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1575 { '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 };
1576 static const WCHAR SE_TCB_NAME_W[] =
1577 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1578 static const WCHAR SE_SECURITY_NAME_W[] =
1579 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1580 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1581 { '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 };
1582 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1583 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1584 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1585 { '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 };
1586 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1587 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1588 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1589 { '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 };
1590 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1591 { '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 };
1592 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1593 { '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 };
1594 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1595 { '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 };
1596 static const WCHAR SE_BACKUP_NAME_W[] =
1597 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1598 static const WCHAR SE_RESTORE_NAME_W[] =
1599 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1600 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1601 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_DEBUG_NAME_W[] =
1603 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_AUDIT_NAME_W[] =
1605 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1606 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1607 { '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 };
1608 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1609 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1610 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1611 { '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 };
1612 static const WCHAR SE_UNDOCK_NAME_W[] =
1613 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1614 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1615 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1616 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1617 { '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 };
1618 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1619 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1620 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1621 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1623 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1627 NULL,
1628 NULL,
1629 SE_CREATE_TOKEN_NAME_W,
1630 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1631 SE_LOCK_MEMORY_NAME_W,
1632 SE_INCREASE_QUOTA_NAME_W,
1633 SE_MACHINE_ACCOUNT_NAME_W,
1634 SE_TCB_NAME_W,
1635 SE_SECURITY_NAME_W,
1636 SE_TAKE_OWNERSHIP_NAME_W,
1637 SE_LOAD_DRIVER_NAME_W,
1638 SE_SYSTEM_PROFILE_NAME_W,
1639 SE_SYSTEMTIME_NAME_W,
1640 SE_PROF_SINGLE_PROCESS_NAME_W,
1641 SE_INC_BASE_PRIORITY_NAME_W,
1642 SE_CREATE_PAGEFILE_NAME_W,
1643 SE_CREATE_PERMANENT_NAME_W,
1644 SE_BACKUP_NAME_W,
1645 SE_RESTORE_NAME_W,
1646 SE_SHUTDOWN_NAME_W,
1647 SE_DEBUG_NAME_W,
1648 SE_AUDIT_NAME_W,
1649 SE_SYSTEM_ENVIRONMENT_NAME_W,
1650 SE_CHANGE_NOTIFY_NAME_W,
1651 SE_REMOTE_SHUTDOWN_NAME_W,
1652 SE_UNDOCK_NAME_W,
1653 SE_SYNC_AGENT_NAME_W,
1654 SE_ENABLE_DELEGATION_NAME_W,
1655 SE_MANAGE_VOLUME_NAME_W,
1656 SE_IMPERSONATE_NAME_W,
1657 SE_CREATE_GLOBAL_NAME_W,
1660 /******************************************************************************
1661 * LookupPrivilegeValueW [ADVAPI32.@]
1663 * See LookupPrivilegeValueA.
1665 BOOL WINAPI
1666 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1668 UINT i;
1670 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1672 if (!ADVAPI_IsLocalComputer(lpSystemName))
1674 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1675 return FALSE;
1677 if (!lpName)
1679 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1680 return FALSE;
1682 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1684 if( !WellKnownPrivNames[i] )
1685 continue;
1686 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1687 continue;
1688 lpLuid->LowPart = i;
1689 lpLuid->HighPart = 0;
1690 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1691 lpLuid->HighPart, lpLuid->LowPart );
1692 return TRUE;
1694 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1695 return FALSE;
1698 /******************************************************************************
1699 * LookupPrivilegeValueA [ADVAPI32.@]
1701 * Retrieves LUID used on a system to represent the privilege name.
1703 * PARAMS
1704 * lpSystemName [I] Name of the system
1705 * lpName [I] Name of the privilege
1706 * lpLuid [O] Destination for the resulting LUID
1708 * RETURNS
1709 * Success: TRUE. lpLuid contains the requested LUID.
1710 * Failure: FALSE.
1712 BOOL WINAPI
1713 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1715 UNICODE_STRING lpSystemNameW;
1716 UNICODE_STRING lpNameW;
1717 BOOL ret;
1719 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1720 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1721 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1722 RtlFreeUnicodeString(&lpNameW);
1723 RtlFreeUnicodeString(&lpSystemNameW);
1724 return ret;
1727 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1728 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1730 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1731 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1733 return FALSE;
1736 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1737 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1739 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1740 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1742 return FALSE;
1745 /******************************************************************************
1746 * LookupPrivilegeNameA [ADVAPI32.@]
1748 * See LookupPrivilegeNameW.
1750 BOOL WINAPI
1751 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1752 LPDWORD cchName)
1754 UNICODE_STRING lpSystemNameW;
1755 BOOL ret;
1756 DWORD wLen = 0;
1758 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1760 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1761 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1762 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1764 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1766 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1767 &wLen);
1768 if (ret)
1770 /* Windows crashes if cchName is NULL, so will I */
1771 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1772 *cchName, NULL, NULL);
1774 if (len == 0)
1776 /* WideCharToMultiByte failed */
1777 ret = FALSE;
1779 else if (len > *cchName)
1781 *cchName = len;
1782 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1783 ret = FALSE;
1785 else
1787 /* WideCharToMultiByte succeeded, output length needs to be
1788 * length not including NULL terminator
1790 *cchName = len - 1;
1793 HeapFree(GetProcessHeap(), 0, lpNameW);
1795 RtlFreeUnicodeString(&lpSystemNameW);
1796 return ret;
1799 /******************************************************************************
1800 * LookupPrivilegeNameW [ADVAPI32.@]
1802 * Retrieves the privilege name referred to by the LUID lpLuid.
1804 * PARAMS
1805 * lpSystemName [I] Name of the system
1806 * lpLuid [I] Privilege value
1807 * lpName [O] Name of the privilege
1808 * cchName [I/O] Number of characters in lpName.
1810 * RETURNS
1811 * Success: TRUE. lpName contains the name of the privilege whose value is
1812 * *lpLuid.
1813 * Failure: FALSE.
1815 * REMARKS
1816 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1817 * using this function.
1818 * If the length of lpName is too small, on return *cchName will contain the
1819 * number of WCHARs needed to contain the privilege, including the NULL
1820 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1821 * On success, *cchName will contain the number of characters stored in
1822 * lpName, NOT including the NULL terminator.
1824 BOOL WINAPI
1825 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1826 LPDWORD cchName)
1828 size_t privNameLen;
1830 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1832 if (!ADVAPI_IsLocalComputer(lpSystemName))
1834 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1835 return FALSE;
1837 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1838 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1840 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1841 return FALSE;
1843 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1844 /* Windows crashes if cchName is NULL, so will I */
1845 if (*cchName <= privNameLen)
1847 *cchName = privNameLen + 1;
1848 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1849 return FALSE;
1851 else
1853 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1854 *cchName = privNameLen;
1855 return TRUE;
1859 /******************************************************************************
1860 * GetFileSecurityA [ADVAPI32.@]
1862 * Obtains Specified information about the security of a file or directory.
1864 * PARAMS
1865 * lpFileName [I] Name of the file to get info for
1866 * RequestedInformation [I] SE_ flags from "winnt.h"
1867 * pSecurityDescriptor [O] Destination for security information
1868 * nLength [I] Length of pSecurityDescriptor
1869 * lpnLengthNeeded [O] Destination for length of returned security information
1871 * RETURNS
1872 * Success: TRUE. pSecurityDescriptor contains the requested information.
1873 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1875 * NOTES
1876 * The information returned is constrained by the callers access rights and
1877 * privileges.
1879 BOOL WINAPI
1880 GetFileSecurityA( LPCSTR lpFileName,
1881 SECURITY_INFORMATION RequestedInformation,
1882 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1883 DWORD nLength, LPDWORD lpnLengthNeeded )
1885 DWORD len;
1886 BOOL r;
1887 LPWSTR name = NULL;
1889 if( lpFileName )
1891 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1892 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1893 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1896 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1897 nLength, lpnLengthNeeded );
1898 HeapFree( GetProcessHeap(), 0, name );
1900 return r;
1903 /******************************************************************************
1904 * GetFileSecurityW [ADVAPI32.@]
1906 * See GetFileSecurityA.
1908 BOOL WINAPI
1909 GetFileSecurityW( LPCWSTR lpFileName,
1910 SECURITY_INFORMATION RequestedInformation,
1911 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1912 DWORD nLength, LPDWORD lpnLengthNeeded )
1914 HANDLE hfile;
1915 NTSTATUS status;
1916 DWORD access = 0;
1918 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1919 DACL_SECURITY_INFORMATION))
1920 access |= READ_CONTROL;
1921 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1922 access |= ACCESS_SYSTEM_SECURITY;
1924 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1925 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1926 if ( hfile == INVALID_HANDLE_VALUE )
1927 return FALSE;
1929 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1930 nLength, lpnLengthNeeded );
1931 CloseHandle( hfile );
1932 return set_ntstatus( status );
1936 /******************************************************************************
1937 * LookupAccountSidA [ADVAPI32.@]
1939 BOOL WINAPI
1940 LookupAccountSidA(
1941 IN LPCSTR system,
1942 IN PSID sid,
1943 OUT LPSTR account,
1944 IN OUT LPDWORD accountSize,
1945 OUT LPSTR domain,
1946 IN OUT LPDWORD domainSize,
1947 OUT PSID_NAME_USE name_use )
1949 DWORD len;
1950 BOOL r;
1951 LPWSTR systemW = NULL;
1952 LPWSTR accountW = NULL;
1953 LPWSTR domainW = NULL;
1954 DWORD accountSizeW = *accountSize;
1955 DWORD domainSizeW = *domainSize;
1957 if (system) {
1958 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1959 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1960 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1962 if (account)
1963 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1964 if (domain)
1965 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1967 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1969 if (r) {
1970 if (accountW && *accountSize) {
1971 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1972 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1973 *accountSize = len;
1974 } else
1975 *accountSize = accountSizeW + 1;
1977 if (domainW && *domainSize) {
1978 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1979 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1980 *domainSize = len;
1981 } else
1982 *domainSize = domainSizeW + 1;
1985 HeapFree( GetProcessHeap(), 0, systemW );
1986 HeapFree( GetProcessHeap(), 0, accountW );
1987 HeapFree( GetProcessHeap(), 0, domainW );
1989 return r;
1992 /******************************************************************************
1993 * LookupAccountSidW [ADVAPI32.@]
1995 * PARAMS
1996 * system []
1997 * sid []
1998 * account []
1999 * accountSize []
2000 * domain []
2001 * domainSize []
2002 * name_use []
2005 BOOL WINAPI
2006 LookupAccountSidW(
2007 IN LPCWSTR system,
2008 IN PSID sid,
2009 OUT LPWSTR account,
2010 IN OUT LPDWORD accountSize,
2011 OUT LPWSTR domain,
2012 IN OUT LPDWORD domainSize,
2013 OUT PSID_NAME_USE name_use )
2015 unsigned int i, j;
2016 const WCHAR * ac = NULL;
2017 const WCHAR * dm = NULL;
2018 SID_NAME_USE use = 0;
2019 LPWSTR computer_name = NULL;
2020 LPWSTR account_name = NULL;
2022 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2023 debugstr_w(system),debugstr_sid(sid),
2024 account,accountSize,accountSize?*accountSize:0,
2025 domain,domainSize,domainSize?*domainSize:0,
2026 name_use);
2028 if (!ADVAPI_IsLocalComputer(system)) {
2029 FIXME("Only local computer supported!\n");
2030 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2031 return FALSE;
2034 /* check the well known SIDs first */
2035 for (i = 0; i <= 60; i++) {
2036 if (IsWellKnownSid(sid, i)) {
2037 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2038 if (ACCOUNT_SIDS[j].type == i) {
2039 ac = ACCOUNT_SIDS[j].account;
2040 dm = ACCOUNT_SIDS[j].domain;
2041 use = ACCOUNT_SIDS[j].name_use;
2044 break;
2048 if (dm == NULL) {
2049 MAX_SID local;
2051 /* check for the local computer next */
2052 if (ADVAPI_GetComputerSid(&local)) {
2053 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2054 BOOL result;
2056 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2057 result = GetComputerNameW(computer_name, &size);
2059 if (result) {
2060 if (EqualSid(sid, &local)) {
2061 dm = computer_name;
2062 ac = Blank;
2063 use = 3;
2064 } else {
2065 local.SubAuthorityCount++;
2067 if (EqualPrefixSid(sid, &local)) {
2068 dm = computer_name;
2069 use = 1;
2070 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2071 case DOMAIN_USER_RID_ADMIN:
2072 ac = Administrator;
2073 break;
2074 case DOMAIN_USER_RID_GUEST:
2075 ac = Guest;
2076 break;
2077 case DOMAIN_GROUP_RID_ADMINS:
2078 ac = Domain_Admins;
2079 break;
2080 case DOMAIN_GROUP_RID_USERS:
2081 ac = Domain_Users;
2082 break;
2083 case DOMAIN_GROUP_RID_GUESTS:
2084 ac = Domain_Guests;
2085 break;
2086 case DOMAIN_GROUP_RID_COMPUTERS:
2087 ac = Domain_Computers;
2088 break;
2089 case DOMAIN_GROUP_RID_CONTROLLERS:
2090 ac = Domain_Controllers;
2091 break;
2092 case DOMAIN_GROUP_RID_CERT_ADMINS:
2093 ac = Cert_Publishers;
2094 break;
2095 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2096 ac = Schema_Admins;
2097 break;
2098 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2099 ac = Enterprise_Admins;
2100 break;
2101 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2102 ac = Group_Policy_Creator_Owners;
2103 break;
2104 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2105 ac = RAS_and_IAS_Servers;
2106 break;
2107 case 1000: /* first user account */
2108 size = UNLEN + 1;
2109 account_name = HeapAlloc(
2110 GetProcessHeap(), 0, size * sizeof(WCHAR));
2111 if (GetUserNameW(account_name, &size))
2112 ac = account_name;
2113 else
2114 dm = NULL;
2116 break;
2117 default:
2118 dm = NULL;
2119 break;
2127 if (dm) {
2128 DWORD ac_len = lstrlenW(ac);
2129 DWORD dm_len = lstrlenW(dm);
2130 BOOL status = TRUE;
2132 if (*accountSize > ac_len) {
2133 if (account)
2134 lstrcpyW(account, ac);
2136 if (*domainSize > dm_len) {
2137 if (domain)
2138 lstrcpyW(domain, dm);
2140 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2141 ((*domainSize != 0) && (*domainSize < dm_len))) {
2142 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2143 status = FALSE;
2145 if (*domainSize)
2146 *domainSize = dm_len;
2147 else
2148 *domainSize = dm_len + 1;
2149 if (*accountSize)
2150 *accountSize = ac_len;
2151 else
2152 *accountSize = ac_len + 1;
2153 *name_use = use;
2154 HeapFree(GetProcessHeap(), 0, account_name);
2155 HeapFree(GetProcessHeap(), 0, computer_name);
2156 return status;
2159 HeapFree(GetProcessHeap(), 0, account_name);
2160 HeapFree(GetProcessHeap(), 0, computer_name);
2161 SetLastError(ERROR_NONE_MAPPED);
2162 return FALSE;
2165 /******************************************************************************
2166 * SetFileSecurityA [ADVAPI32.@]
2168 * See SetFileSecurityW.
2170 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2171 SECURITY_INFORMATION RequestedInformation,
2172 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2174 DWORD len;
2175 BOOL r;
2176 LPWSTR name = NULL;
2178 if( lpFileName )
2180 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2181 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2182 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2185 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2186 HeapFree( GetProcessHeap(), 0, name );
2188 return r;
2191 /******************************************************************************
2192 * SetFileSecurityW [ADVAPI32.@]
2194 * Sets the security of a file or directory.
2196 * PARAMS
2197 * lpFileName []
2198 * RequestedInformation []
2199 * pSecurityDescriptor []
2201 * RETURNS
2202 * Success: TRUE.
2203 * Failure: FALSE.
2205 BOOL WINAPI
2206 SetFileSecurityW( LPCWSTR lpFileName,
2207 SECURITY_INFORMATION RequestedInformation,
2208 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2210 HANDLE file;
2211 DWORD access = 0;
2212 NTSTATUS status;
2214 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2215 pSecurityDescriptor );
2217 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2218 RequestedInformation & GROUP_SECURITY_INFORMATION)
2219 access |= WRITE_OWNER;
2220 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2221 access |= ACCESS_SYSTEM_SECURITY;
2222 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2223 access |= WRITE_DAC;
2225 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2226 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2227 if (file == INVALID_HANDLE_VALUE)
2228 return FALSE;
2230 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2231 CloseHandle( file );
2232 return set_ntstatus( status );
2235 /******************************************************************************
2236 * QueryWindows31FilesMigration [ADVAPI32.@]
2238 * PARAMS
2239 * x1 []
2241 BOOL WINAPI
2242 QueryWindows31FilesMigration( DWORD x1 )
2244 FIXME("(%d):stub\n",x1);
2245 return TRUE;
2248 /******************************************************************************
2249 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2251 * PARAMS
2252 * x1 []
2253 * x2 []
2254 * x3 []
2255 * x4 []
2257 BOOL WINAPI
2258 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2259 DWORD x4 )
2261 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2262 return TRUE;
2265 /******************************************************************************
2266 * NotifyBootConfigStatus [ADVAPI32.@]
2268 * PARAMS
2269 * x1 []
2271 BOOL WINAPI
2272 NotifyBootConfigStatus( BOOL x1 )
2274 FIXME("(0x%08d):stub\n",x1);
2275 return 1;
2278 /******************************************************************************
2279 * RevertToSelf [ADVAPI32.@]
2281 * Ends the impersonation of a user.
2283 * PARAMS
2284 * void []
2286 * RETURNS
2287 * Success: TRUE.
2288 * Failure: FALSE.
2290 BOOL WINAPI
2291 RevertToSelf( void )
2293 HANDLE Token = NULL;
2294 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2295 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2298 /******************************************************************************
2299 * ImpersonateSelf [ADVAPI32.@]
2301 * Makes an impersonation token that represents the process user and assigns
2302 * to the current thread.
2304 * PARAMS
2305 * ImpersonationLevel [I] Level at which to impersonate.
2307 * RETURNS
2308 * Success: TRUE.
2309 * Failure: FALSE.
2311 BOOL WINAPI
2312 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2314 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2317 /******************************************************************************
2318 * ImpersonateLoggedOnUser [ADVAPI32.@]
2320 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2322 DWORD size;
2323 NTSTATUS Status;
2324 HANDLE ImpersonationToken;
2325 TOKEN_TYPE Type;
2326 static BOOL warn = TRUE;
2328 if (warn)
2330 FIXME( "(%p)\n", hToken );
2331 warn = FALSE;
2333 if (!GetTokenInformation( hToken, TokenType, &Type,
2334 sizeof(TOKEN_TYPE), &size ))
2335 return FALSE;
2337 if (Type == TokenPrimary)
2339 OBJECT_ATTRIBUTES ObjectAttributes;
2341 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2343 Status = NtDuplicateToken( hToken,
2344 TOKEN_IMPERSONATE | TOKEN_QUERY,
2345 &ObjectAttributes,
2346 SecurityImpersonation,
2347 TokenImpersonation,
2348 &ImpersonationToken );
2349 if (Status != STATUS_SUCCESS)
2351 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2352 SetLastError( RtlNtStatusToDosError( Status ) );
2353 return FALSE;
2356 else
2357 ImpersonationToken = hToken;
2359 Status = NtSetInformationThread( GetCurrentThread(),
2360 ThreadImpersonationToken,
2361 &ImpersonationToken,
2362 sizeof(ImpersonationToken) );
2364 if (Type == TokenPrimary)
2365 NtClose( ImpersonationToken );
2367 if (Status != STATUS_SUCCESS)
2369 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2370 SetLastError( RtlNtStatusToDosError( Status ) );
2371 return FALSE;
2374 return TRUE;
2377 /******************************************************************************
2378 * AccessCheck [ADVAPI32.@]
2380 BOOL WINAPI
2381 AccessCheck(
2382 PSECURITY_DESCRIPTOR SecurityDescriptor,
2383 HANDLE ClientToken,
2384 DWORD DesiredAccess,
2385 PGENERIC_MAPPING GenericMapping,
2386 PPRIVILEGE_SET PrivilegeSet,
2387 LPDWORD PrivilegeSetLength,
2388 LPDWORD GrantedAccess,
2389 LPBOOL AccessStatus)
2391 NTSTATUS access_status;
2392 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2393 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2394 GrantedAccess, &access_status) );
2395 if (ret) *AccessStatus = set_ntstatus( access_status );
2396 return ret;
2400 /******************************************************************************
2401 * AccessCheckByType [ADVAPI32.@]
2403 BOOL WINAPI AccessCheckByType(
2404 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2405 PSID PrincipalSelfSid,
2406 HANDLE ClientToken,
2407 DWORD DesiredAccess,
2408 POBJECT_TYPE_LIST ObjectTypeList,
2409 DWORD ObjectTypeListLength,
2410 PGENERIC_MAPPING GenericMapping,
2411 PPRIVILEGE_SET PrivilegeSet,
2412 LPDWORD PrivilegeSetLength,
2413 LPDWORD GrantedAccess,
2414 LPBOOL AccessStatus)
2416 FIXME("stub\n");
2418 *AccessStatus = TRUE;
2420 return !*AccessStatus;
2423 /******************************************************************************
2424 * MapGenericMask [ADVAPI32.@]
2426 * Maps generic access rights into specific access rights according to the
2427 * supplied mapping.
2429 * PARAMS
2430 * AccessMask [I/O] Access rights.
2431 * GenericMapping [I] The mapping between generic and specific rights.
2433 * RETURNS
2434 * Nothing.
2436 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2438 RtlMapGenericMask( AccessMask, GenericMapping );
2441 /*************************************************************************
2442 * SetKernelObjectSecurity [ADVAPI32.@]
2444 BOOL WINAPI SetKernelObjectSecurity (
2445 IN HANDLE Handle,
2446 IN SECURITY_INFORMATION SecurityInformation,
2447 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2449 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2453 /******************************************************************************
2454 * AddAuditAccessAce [ADVAPI32.@]
2456 BOOL WINAPI AddAuditAccessAce(
2457 IN OUT PACL pAcl,
2458 IN DWORD dwAceRevision,
2459 IN DWORD dwAccessMask,
2460 IN PSID pSid,
2461 IN BOOL bAuditSuccess,
2462 IN BOOL bAuditFailure)
2464 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2465 bAuditSuccess, bAuditFailure) );
2468 /******************************************************************************
2469 * AddAuditAccessAce [ADVAPI32.@]
2471 BOOL WINAPI AddAuditAccessAceEx(
2472 IN OUT PACL pAcl,
2473 IN DWORD dwAceRevision,
2474 IN DWORD dwAceFlags,
2475 IN DWORD dwAccessMask,
2476 IN PSID pSid,
2477 IN BOOL bAuditSuccess,
2478 IN BOOL bAuditFailure)
2480 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2481 bAuditSuccess, bAuditFailure) );
2484 /******************************************************************************
2485 * LookupAccountNameA [ADVAPI32.@]
2487 BOOL WINAPI
2488 LookupAccountNameA(
2489 IN LPCSTR system,
2490 IN LPCSTR account,
2491 OUT PSID sid,
2492 OUT LPDWORD cbSid,
2493 LPSTR ReferencedDomainName,
2494 IN OUT LPDWORD cbReferencedDomainName,
2495 OUT PSID_NAME_USE name_use )
2497 BOOL ret;
2498 UNICODE_STRING lpSystemW;
2499 UNICODE_STRING lpAccountW;
2500 LPWSTR lpReferencedDomainNameW = NULL;
2502 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2503 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2505 if (ReferencedDomainName)
2506 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2508 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2509 cbReferencedDomainName, name_use);
2511 if (ret && lpReferencedDomainNameW)
2513 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2514 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2517 RtlFreeUnicodeString(&lpSystemW);
2518 RtlFreeUnicodeString(&lpAccountW);
2519 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2521 return ret;
2524 /******************************************************************************
2525 * LookupAccountNameW [ADVAPI32.@]
2527 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2528 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2529 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2531 /* Default implementation: Always return a default SID */
2532 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2533 BOOL ret;
2534 PSID pSid;
2535 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2536 unsigned int i;
2537 DWORD nameLen;
2538 LPWSTR userName = NULL;
2539 LPCWSTR domainName;
2541 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2542 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2544 if (!ADVAPI_IsLocalComputer(lpSystemName))
2546 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2547 return FALSE;
2550 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2552 lpAccountName = BUILTIN;
2555 /* Check well known SIDs first */
2557 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2559 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2561 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2563 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2565 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2567 if (ret)
2569 if (*cbSid < sidLen)
2571 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2572 ret = FALSE;
2574 else if (Sid)
2576 CopySid(*cbSid, Sid, pSid);
2579 *cbSid = sidLen;
2582 domainName = ACCOUNT_SIDS[i].domain;
2583 nameLen = strlenW(domainName);
2585 if (*cchReferencedDomainName <= nameLen || !ret)
2587 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2588 nameLen += 1;
2589 ret = FALSE;
2591 else if (ReferencedDomainName && domainName)
2593 strcpyW(ReferencedDomainName, domainName);
2596 *cchReferencedDomainName = nameLen;
2598 if (ret)
2600 *peUse = ACCOUNT_SIDS[i].name_use;
2603 HeapFree(GetProcessHeap(), 0, pSid);
2605 return ret;
2609 /* Let the current Unix user id masquerade as first Windows user account */
2611 nameLen = UNLEN + 1;
2613 userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2615 ret = GetUserNameW(userName, &nameLen);
2617 if (ret && strcmpW(lpAccountName, userName) != 0)
2619 SetLastError(ERROR_NONE_MAPPED);
2620 ret = FALSE;
2623 HeapFree(GetProcessHeap(), 0, userName);
2625 if (!ret)
2627 return ret;
2630 ret = AllocateAndInitializeSid(&identifierAuthority,
2632 SECURITY_BUILTIN_DOMAIN_RID,
2633 DOMAIN_ALIAS_RID_ADMINS,
2634 0, 0, 0, 0, 0, 0,
2635 &pSid);
2637 if (!ret)
2638 return FALSE;
2640 if (!RtlValidSid(pSid))
2642 FreeSid(pSid);
2643 return FALSE;
2646 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2647 CopySid(*cbSid, Sid, pSid);
2648 if (*cbSid < GetLengthSid(pSid))
2650 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2651 ret = FALSE;
2653 *cbSid = GetLengthSid(pSid);
2655 domainName = dm;
2656 nameLen = strlenW(domainName);
2658 if (*cchReferencedDomainName <= nameLen || !ret)
2660 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2661 nameLen += 1;
2662 ret = FALSE;
2664 else if (ReferencedDomainName)
2666 strcpyW(ReferencedDomainName, domainName);
2669 *cchReferencedDomainName = nameLen;
2671 if (ret)
2673 *peUse = SidTypeUser;
2676 FreeSid(pSid);
2678 return ret;
2681 /******************************************************************************
2682 * PrivilegeCheck [ADVAPI32.@]
2684 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2686 BOOL ret;
2687 BOOLEAN Result;
2689 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2691 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2692 if (ret)
2693 *pfResult = Result;
2694 return ret;
2697 /******************************************************************************
2698 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2700 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2701 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2702 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2703 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2705 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2706 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2707 SecurityDescriptor, DesiredAccess, GenericMapping,
2708 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2709 return TRUE;
2712 /******************************************************************************
2713 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2715 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2716 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2717 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2718 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2720 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2721 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2722 SecurityDescriptor, DesiredAccess, GenericMapping,
2723 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2724 return TRUE;
2727 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2729 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2731 return TRUE;
2734 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2736 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2738 return TRUE;
2741 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2743 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2745 return TRUE;
2748 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2749 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2750 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2751 LPBOOL GenerateOnClose)
2753 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2754 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2755 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2756 GenerateOnClose);
2758 return TRUE;
2761 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2762 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2763 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2764 LPBOOL GenerateOnClose)
2766 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2767 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2768 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2769 GenerateOnClose);
2771 return TRUE;
2774 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2775 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2777 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2778 DesiredAccess, Privileges, AccessGranted);
2780 return TRUE;
2783 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2784 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2786 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2787 DesiredAccess, Privileges, AccessGranted);
2789 return TRUE;
2792 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2793 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2795 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2796 ClientToken, Privileges, AccessGranted);
2798 return TRUE;
2801 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2802 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2804 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2805 ClientToken, Privileges, AccessGranted);
2807 return TRUE;
2810 /******************************************************************************
2811 * GetSecurityInfo [ADVAPI32.@]
2813 * Retrieves a copy of the security descriptor associated with an object.
2815 * PARAMS
2816 * hObject [I] A handle for the object.
2817 * ObjectType [I] The type of object.
2818 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2819 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2820 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2821 * ppDacl [O] If non-null, receives a pointer to the DACL.
2822 * ppSacl [O] If non-null, receives a pointer to the SACL.
2823 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2824 * which must be freed with LocalFree.
2826 * RETURNS
2827 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2829 DWORD WINAPI GetSecurityInfo(
2830 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2831 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2832 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2833 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2836 PSECURITY_DESCRIPTOR sd;
2837 NTSTATUS status;
2838 ULONG n1, n2;
2839 BOOL present, defaulted;
2841 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2842 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2843 return RtlNtStatusToDosError(status);
2845 sd = LocalAlloc(0, n1);
2846 if (!sd)
2847 return ERROR_NOT_ENOUGH_MEMORY;
2849 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2850 if (status != STATUS_SUCCESS)
2852 LocalFree(sd);
2853 return RtlNtStatusToDosError(status);
2856 if (ppsidOwner)
2858 *ppsidOwner = NULL;
2859 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2861 if (ppsidGroup)
2863 *ppsidGroup = NULL;
2864 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2866 if (ppDacl)
2868 *ppDacl = NULL;
2869 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2871 if (ppSacl)
2873 *ppSacl = NULL;
2874 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2876 if (ppSecurityDescriptor)
2877 *ppSecurityDescriptor = sd;
2879 return ERROR_SUCCESS;
2882 /******************************************************************************
2883 * GetSecurityInfoExW [ADVAPI32.@]
2885 DWORD WINAPI GetSecurityInfoExW(
2886 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2887 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2888 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2889 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2892 FIXME("stub!\n");
2893 return ERROR_BAD_PROVIDER;
2896 /******************************************************************************
2897 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2899 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2900 LPSTR pTrusteeName, DWORD AccessPermissions,
2901 ACCESS_MODE AccessMode, DWORD Inheritance )
2903 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2904 AccessPermissions, AccessMode, Inheritance);
2906 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2907 pExplicitAccess->grfAccessMode = AccessMode;
2908 pExplicitAccess->grfInheritance = Inheritance;
2910 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2911 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2912 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2913 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2914 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2917 /******************************************************************************
2918 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2920 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2921 LPWSTR pTrusteeName, DWORD AccessPermissions,
2922 ACCESS_MODE AccessMode, DWORD Inheritance )
2924 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2925 AccessPermissions, AccessMode, Inheritance);
2927 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2928 pExplicitAccess->grfAccessMode = AccessMode;
2929 pExplicitAccess->grfInheritance = Inheritance;
2931 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2932 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2933 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2934 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2935 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2938 /******************************************************************************
2939 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2941 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2942 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2943 LPSTR InheritedObjectTypeName, LPSTR Name )
2945 DWORD ObjectsPresent = 0;
2947 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2948 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2950 /* Fill the OBJECTS_AND_NAME structure */
2951 pObjName->ObjectType = ObjectType;
2952 if (ObjectTypeName != NULL)
2954 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2957 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2958 if (InheritedObjectTypeName != NULL)
2960 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2963 pObjName->ObjectsPresent = ObjectsPresent;
2964 pObjName->ptstrName = Name;
2966 /* Fill the TRUSTEE structure */
2967 pTrustee->pMultipleTrustee = NULL;
2968 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2969 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2970 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2971 pTrustee->ptstrName = (LPSTR)pObjName;
2974 /******************************************************************************
2975 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2977 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2978 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2979 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2981 DWORD ObjectsPresent = 0;
2983 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2984 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2986 /* Fill the OBJECTS_AND_NAME structure */
2987 pObjName->ObjectType = ObjectType;
2988 if (ObjectTypeName != NULL)
2990 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2993 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2994 if (InheritedObjectTypeName != NULL)
2996 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2999 pObjName->ObjectsPresent = ObjectsPresent;
3000 pObjName->ptstrName = Name;
3002 /* Fill the TRUSTEE structure */
3003 pTrustee->pMultipleTrustee = NULL;
3004 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3005 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3006 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3007 pTrustee->ptstrName = (LPWSTR)pObjName;
3010 /******************************************************************************
3011 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3013 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3014 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3016 DWORD ObjectsPresent = 0;
3018 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3020 /* Fill the OBJECTS_AND_SID structure */
3021 if (pObjectGuid != NULL)
3023 pObjSid->ObjectTypeGuid = *pObjectGuid;
3024 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3026 else
3028 ZeroMemory(&pObjSid->ObjectTypeGuid,
3029 sizeof(GUID));
3032 if (pInheritedObjectGuid != NULL)
3034 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3035 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3037 else
3039 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3040 sizeof(GUID));
3043 pObjSid->ObjectsPresent = ObjectsPresent;
3044 pObjSid->pSid = pSid;
3046 /* Fill the TRUSTEE structure */
3047 pTrustee->pMultipleTrustee = NULL;
3048 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3049 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3050 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3051 pTrustee->ptstrName = (LPSTR) pObjSid;
3054 /******************************************************************************
3055 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3057 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3058 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3060 DWORD ObjectsPresent = 0;
3062 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3064 /* Fill the OBJECTS_AND_SID structure */
3065 if (pObjectGuid != NULL)
3067 pObjSid->ObjectTypeGuid = *pObjectGuid;
3068 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3070 else
3072 ZeroMemory(&pObjSid->ObjectTypeGuid,
3073 sizeof(GUID));
3076 if (pInheritedObjectGuid != NULL)
3078 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3079 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3081 else
3083 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3084 sizeof(GUID));
3087 pObjSid->ObjectsPresent = ObjectsPresent;
3088 pObjSid->pSid = pSid;
3090 /* Fill the TRUSTEE structure */
3091 pTrustee->pMultipleTrustee = NULL;
3092 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3093 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3094 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3095 pTrustee->ptstrName = (LPWSTR) pObjSid;
3098 /******************************************************************************
3099 * BuildTrusteeWithSidA [ADVAPI32.@]
3101 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3103 TRACE("%p %p\n", pTrustee, pSid);
3105 pTrustee->pMultipleTrustee = NULL;
3106 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3107 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3108 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3109 pTrustee->ptstrName = (LPSTR) pSid;
3112 /******************************************************************************
3113 * BuildTrusteeWithSidW [ADVAPI32.@]
3115 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3117 TRACE("%p %p\n", pTrustee, pSid);
3119 pTrustee->pMultipleTrustee = NULL;
3120 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3121 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3122 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3123 pTrustee->ptstrName = (LPWSTR) pSid;
3126 /******************************************************************************
3127 * BuildTrusteeWithNameA [ADVAPI32.@]
3129 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3131 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3133 pTrustee->pMultipleTrustee = NULL;
3134 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3135 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3136 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3137 pTrustee->ptstrName = name;
3140 /******************************************************************************
3141 * BuildTrusteeWithNameW [ADVAPI32.@]
3143 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3145 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3147 pTrustee->pMultipleTrustee = NULL;
3148 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3149 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3150 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3151 pTrustee->ptstrName = name;
3154 /******************************************************************************
3155 * GetTrusteeFormA [ADVAPI32.@]
3157 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3159 TRACE("(%p)\n", pTrustee);
3161 if (!pTrustee)
3162 return TRUSTEE_BAD_FORM;
3164 return pTrustee->TrusteeForm;
3167 /******************************************************************************
3168 * GetTrusteeFormW [ADVAPI32.@]
3170 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3172 TRACE("(%p)\n", pTrustee);
3174 if (!pTrustee)
3175 return TRUSTEE_BAD_FORM;
3177 return pTrustee->TrusteeForm;
3180 /******************************************************************************
3181 * GetTrusteeNameA [ADVAPI32.@]
3183 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3185 TRACE("(%p)\n", pTrustee);
3187 if (!pTrustee)
3188 return NULL;
3190 return pTrustee->ptstrName;
3193 /******************************************************************************
3194 * GetTrusteeNameW [ADVAPI32.@]
3196 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3198 TRACE("(%p)\n", pTrustee);
3200 if (!pTrustee)
3201 return NULL;
3203 return pTrustee->ptstrName;
3206 /******************************************************************************
3207 * GetTrusteeTypeA [ADVAPI32.@]
3209 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3211 TRACE("(%p)\n", pTrustee);
3213 if (!pTrustee)
3214 return TRUSTEE_IS_UNKNOWN;
3216 return pTrustee->TrusteeType;
3219 /******************************************************************************
3220 * GetTrusteeTypeW [ADVAPI32.@]
3222 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3224 TRACE("(%p)\n", pTrustee);
3226 if (!pTrustee)
3227 return TRUSTEE_IS_UNKNOWN;
3229 return pTrustee->TrusteeType;
3232 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3233 DWORD nAclInformationLength,
3234 ACL_INFORMATION_CLASS dwAclInformationClass )
3236 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3237 nAclInformationLength, dwAclInformationClass);
3239 return TRUE;
3242 /******************************************************************************
3243 * SetEntriesInAclA [ADVAPI32.@]
3245 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3246 PACL OldAcl, PACL* NewAcl )
3248 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3249 if (NewAcl)
3250 *NewAcl = NULL;
3251 return ERROR_SUCCESS;
3254 /******************************************************************************
3255 * SetEntriesInAclW [ADVAPI32.@]
3257 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3258 PACL OldAcl, PACL* NewAcl )
3260 ULONG i;
3261 PSID *ppsid;
3262 DWORD ret = ERROR_SUCCESS;
3263 DWORD acl_size = sizeof(ACL);
3264 NTSTATUS status;
3266 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3268 *NewAcl = NULL;
3270 if (!count && !OldAcl)
3271 return ERROR_SUCCESS;
3273 /* allocate array of maximum sized sids allowed */
3274 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3275 if (!ppsid)
3276 return ERROR_OUTOFMEMORY;
3278 for (i = 0; i < count; i++)
3280 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3282 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3283 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3284 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3285 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3286 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3287 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3288 pEntries[i].Trustee.ptstrName);
3290 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3292 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3293 ret = ERROR_INVALID_PARAMETER;
3294 goto exit;
3297 switch (pEntries[i].Trustee.TrusteeForm)
3299 case TRUSTEE_IS_SID:
3300 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3301 ppsid[i], pEntries[i].Trustee.ptstrName))
3303 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3304 ret = ERROR_INVALID_PARAMETER;
3305 goto exit;
3307 break;
3308 case TRUSTEE_IS_NAME:
3310 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3311 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3312 SID_NAME_USE use;
3313 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3315 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3316 ret = ERROR_INVALID_PARAMETER;
3317 goto exit;
3319 break;
3321 case TRUSTEE_IS_OBJECTS_AND_SID:
3322 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3323 break;
3324 case TRUSTEE_IS_OBJECTS_AND_NAME:
3325 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3326 break;
3327 default:
3328 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3329 ret = ERROR_INVALID_PARAMETER;
3330 goto exit;
3333 /* Note: we overestimate the ACL size here as a tradeoff between
3334 * instructions (simplicity) and memory */
3335 switch (pEntries[i].grfAccessMode)
3337 case GRANT_ACCESS:
3338 case SET_ACCESS:
3339 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3340 break;
3341 case DENY_ACCESS:
3342 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3343 break;
3344 case SET_AUDIT_SUCCESS:
3345 case SET_AUDIT_FAILURE:
3346 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3347 break;
3348 case REVOKE_ACCESS:
3349 break;
3350 default:
3351 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3352 ret = ERROR_INVALID_PARAMETER;
3353 goto exit;
3357 if (OldAcl)
3359 ACL_SIZE_INFORMATION size_info;
3361 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3362 if (status != STATUS_SUCCESS)
3364 ret = RtlNtStatusToDosError(status);
3365 goto exit;
3367 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3370 *NewAcl = LocalAlloc(0, acl_size);
3371 if (!*NewAcl)
3373 ret = ERROR_OUTOFMEMORY;
3374 goto exit;
3377 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3378 if (status != STATUS_SUCCESS)
3380 ret = RtlNtStatusToDosError(status);
3381 goto exit;
3384 for (i = 0; i < count; i++)
3386 switch (pEntries[i].grfAccessMode)
3388 case GRANT_ACCESS:
3389 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3390 pEntries[i].grfInheritance,
3391 pEntries[i].grfAccessPermissions,
3392 ppsid[i]);
3393 break;
3394 case SET_ACCESS:
3396 ULONG j;
3397 BOOL add = TRUE;
3398 if (OldAcl)
3400 for (j = 0; ; j++)
3402 const ACE_HEADER *existing_ace_header;
3403 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3404 if (status != STATUS_SUCCESS)
3405 break;
3406 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3407 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3408 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3410 add = FALSE;
3411 break;
3415 if (add)
3416 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3417 pEntries[i].grfInheritance,
3418 pEntries[i].grfAccessPermissions,
3419 ppsid[i]);
3420 break;
3422 case DENY_ACCESS:
3423 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3424 pEntries[i].grfInheritance,
3425 pEntries[i].grfAccessPermissions,
3426 ppsid[i]);
3427 break;
3428 case SET_AUDIT_SUCCESS:
3429 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3430 pEntries[i].grfInheritance,
3431 pEntries[i].grfAccessPermissions,
3432 ppsid[i], TRUE, FALSE);
3433 break;
3434 case SET_AUDIT_FAILURE:
3435 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3436 pEntries[i].grfInheritance,
3437 pEntries[i].grfAccessPermissions,
3438 ppsid[i], FALSE, TRUE);
3439 break;
3440 default:
3441 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3445 if (OldAcl)
3447 for (i = 0; ; i++)
3449 BOOL add = TRUE;
3450 ULONG j;
3451 const ACE_HEADER *old_ace_header;
3452 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3453 if (status != STATUS_SUCCESS) break;
3454 for (j = 0; j < count; j++)
3456 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3457 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3458 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3460 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3461 add = FALSE;
3462 break;
3464 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3466 switch (old_ace_header->AceType)
3468 case ACCESS_ALLOWED_ACE_TYPE:
3469 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3470 add = FALSE;
3471 break;
3472 case ACCESS_DENIED_ACE_TYPE:
3473 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3474 add = FALSE;
3475 break;
3476 case SYSTEM_AUDIT_ACE_TYPE:
3477 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3478 add = FALSE;
3479 break;
3480 case SYSTEM_ALARM_ACE_TYPE:
3481 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3482 add = FALSE;
3483 break;
3484 default:
3485 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3488 if (!add)
3489 break;
3492 if (add)
3493 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3494 if (status != STATUS_SUCCESS)
3496 WARN("RtlAddAce failed with error 0x%08x\n", status);
3497 ret = RtlNtStatusToDosError(status);
3498 break;
3503 exit:
3504 HeapFree(GetProcessHeap(), 0, ppsid);
3505 return ret;
3508 /******************************************************************************
3509 * SetNamedSecurityInfoA [ADVAPI32.@]
3511 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3512 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3513 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3515 DWORD len;
3516 LPWSTR wstr = NULL;
3517 DWORD r;
3519 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3520 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3522 if( pObjectName )
3524 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3525 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3526 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3529 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3530 psidGroup, pDacl, pSacl );
3532 HeapFree( GetProcessHeap(), 0, wstr );
3534 return r;
3537 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3538 PSECURITY_DESCRIPTOR ModificationDescriptor,
3539 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3540 PGENERIC_MAPPING GenericMapping,
3541 HANDLE Token )
3543 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3544 ObjectsSecurityDescriptor, GenericMapping, Token);
3546 return TRUE;
3549 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3551 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3554 /******************************************************************************
3555 * AreAnyAccessesGranted [ADVAPI32.@]
3557 * Determines whether or not any of a set of specified access permissions have
3558 * been granted or not.
3560 * PARAMS
3561 * GrantedAccess [I] The permissions that have been granted.
3562 * DesiredAccess [I] The permissions that you want to have.
3564 * RETURNS
3565 * Nonzero if any of the permissions have been granted, zero if none of the
3566 * permissions have been granted.
3569 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3571 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3574 /******************************************************************************
3575 * SetNamedSecurityInfoW [ADVAPI32.@]
3577 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3578 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3579 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3581 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3582 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3583 return ERROR_SUCCESS;
3586 /******************************************************************************
3587 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3589 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3590 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3592 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3593 return ERROR_CALL_NOT_IMPLEMENTED;
3596 /******************************************************************************
3597 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3599 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3600 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3602 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3603 return ERROR_CALL_NOT_IMPLEMENTED;
3606 /******************************************************************************
3607 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3609 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3610 PACCESS_MASK pFailedAuditRights)
3612 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3613 return ERROR_CALL_NOT_IMPLEMENTED;
3617 /******************************************************************************
3618 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3620 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3621 PACCESS_MASK pFailedAuditRights)
3623 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3624 return ERROR_CALL_NOT_IMPLEMENTED;
3628 /******************************************************************************
3629 * ParseAclStringFlags
3631 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3633 DWORD flags = 0;
3634 LPCWSTR szAcl = *StringAcl;
3636 while (*szAcl != '(')
3638 if (*szAcl == 'P')
3640 flags |= SE_DACL_PROTECTED;
3642 else if (*szAcl == 'A')
3644 szAcl++;
3645 if (*szAcl == 'R')
3646 flags |= SE_DACL_AUTO_INHERIT_REQ;
3647 else if (*szAcl == 'I')
3648 flags |= SE_DACL_AUTO_INHERITED;
3650 szAcl++;
3653 *StringAcl = szAcl;
3654 return flags;
3657 /******************************************************************************
3658 * ParseAceStringType
3660 static const ACEFLAG AceType[] =
3662 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3663 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3664 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3665 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3667 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3668 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3669 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3670 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3672 { NULL, 0 },
3675 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3677 UINT len = 0;
3678 LPCWSTR szAcl = *StringAcl;
3679 const ACEFLAG *lpaf = AceType;
3681 while (lpaf->wstr &&
3682 (len = strlenW(lpaf->wstr)) &&
3683 strncmpW(lpaf->wstr, szAcl, len))
3684 lpaf++;
3686 if (!lpaf->wstr)
3687 return 0;
3689 *StringAcl += len;
3690 return lpaf->value;
3694 /******************************************************************************
3695 * ParseAceStringFlags
3697 static const ACEFLAG AceFlags[] =
3699 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3700 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3701 { SDDL_INHERITED, INHERITED_ACE },
3702 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3703 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3704 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3705 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3706 { NULL, 0 },
3709 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3711 UINT len = 0;
3712 BYTE flags = 0;
3713 LPCWSTR szAcl = *StringAcl;
3715 while (*szAcl != ';')
3717 const ACEFLAG *lpaf = AceFlags;
3719 while (lpaf->wstr &&
3720 (len = strlenW(lpaf->wstr)) &&
3721 strncmpW(lpaf->wstr, szAcl, len))
3722 lpaf++;
3724 if (!lpaf->wstr)
3725 return 0;
3727 flags |= lpaf->value;
3728 szAcl += len;
3731 *StringAcl = szAcl;
3732 return flags;
3736 /******************************************************************************
3737 * ParseAceStringRights
3739 static const ACEFLAG AceRights[] =
3741 { SDDL_GENERIC_ALL, GENERIC_ALL },
3742 { SDDL_GENERIC_READ, GENERIC_READ },
3743 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3744 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3746 { SDDL_READ_CONTROL, READ_CONTROL },
3747 { SDDL_STANDARD_DELETE, DELETE },
3748 { SDDL_WRITE_DAC, WRITE_DAC },
3749 { SDDL_WRITE_OWNER, WRITE_OWNER },
3751 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3752 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3753 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3754 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3755 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3756 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3757 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3758 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3759 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3761 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3762 { SDDL_FILE_READ, FILE_GENERIC_READ },
3763 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3764 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3766 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3767 { SDDL_KEY_READ, KEY_READ },
3768 { SDDL_KEY_WRITE, KEY_WRITE },
3769 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3770 { NULL, 0 },
3773 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3775 UINT len = 0;
3776 DWORD rights = 0;
3777 LPCWSTR szAcl = *StringAcl;
3779 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3781 LPCWSTR p = szAcl;
3783 while (*p && *p != ';')
3784 p++;
3786 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3788 rights = strtoulW(szAcl, NULL, 16);
3789 szAcl = p;
3791 else
3792 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3794 else
3796 while (*szAcl != ';')
3798 const ACEFLAG *lpaf = AceRights;
3800 while (lpaf->wstr &&
3801 (len = strlenW(lpaf->wstr)) &&
3802 strncmpW(lpaf->wstr, szAcl, len))
3804 lpaf++;
3807 if (!lpaf->wstr)
3808 return 0;
3810 rights |= lpaf->value;
3811 szAcl += len;
3815 *StringAcl = szAcl;
3816 return rights;
3820 /******************************************************************************
3821 * ParseStringAclToAcl
3823 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3825 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3826 PACL pAcl, LPDWORD cBytes)
3828 DWORD val;
3829 DWORD sidlen;
3830 DWORD length = sizeof(ACL);
3831 DWORD acesize = 0;
3832 DWORD acecount = 0;
3833 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3835 TRACE("%s\n", debugstr_w(StringAcl));
3837 if (!StringAcl)
3838 return FALSE;
3840 if (pAcl) /* pAce is only useful if we're setting values */
3841 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3843 /* Parse ACL flags */
3844 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3846 /* Parse ACE */
3847 while (*StringAcl == '(')
3849 StringAcl++;
3851 /* Parse ACE type */
3852 val = ParseAceStringType(&StringAcl);
3853 if (pAce)
3854 pAce->Header.AceType = (BYTE) val;
3855 if (*StringAcl != ';')
3856 goto lerr;
3857 StringAcl++;
3859 /* Parse ACE flags */
3860 val = ParseAceStringFlags(&StringAcl);
3861 if (pAce)
3862 pAce->Header.AceFlags = (BYTE) val;
3863 if (*StringAcl != ';')
3864 goto lerr;
3865 StringAcl++;
3867 /* Parse ACE rights */
3868 val = ParseAceStringRights(&StringAcl);
3869 if (pAce)
3870 pAce->Mask = val;
3871 if (*StringAcl != ';')
3872 goto lerr;
3873 StringAcl++;
3875 /* Parse ACE object guid */
3876 if (*StringAcl != ';')
3878 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3879 goto lerr;
3881 StringAcl++;
3883 /* Parse ACE inherit object guid */
3884 if (*StringAcl != ';')
3886 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3887 goto lerr;
3889 StringAcl++;
3891 /* Parse ACE account sid */
3892 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3894 while (*StringAcl && *StringAcl != ')')
3895 StringAcl++;
3898 if (*StringAcl != ')')
3899 goto lerr;
3900 StringAcl++;
3902 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3903 length += acesize;
3904 if (pAce)
3906 pAce->Header.AceSize = acesize;
3907 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3909 acecount++;
3912 *cBytes = length;
3914 if (length > 0xffff)
3916 ERR("ACL too large\n");
3917 goto lerr;
3920 if (pAcl)
3922 pAcl->AclRevision = ACL_REVISION;
3923 pAcl->Sbz1 = 0;
3924 pAcl->AclSize = length;
3925 pAcl->AceCount = acecount++;
3926 pAcl->Sbz2 = 0;
3928 return TRUE;
3930 lerr:
3931 SetLastError(ERROR_INVALID_ACL);
3932 WARN("Invalid ACE string format\n");
3933 return FALSE;
3937 /******************************************************************************
3938 * ParseStringSecurityDescriptorToSecurityDescriptor
3940 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3941 LPCWSTR StringSecurityDescriptor,
3942 SECURITY_DESCRIPTOR* SecurityDescriptor,
3943 LPDWORD cBytes)
3945 BOOL bret = FALSE;
3946 WCHAR toktype;
3947 WCHAR tok[MAX_PATH];
3948 LPCWSTR lptoken;
3949 LPBYTE lpNext = NULL;
3950 DWORD len;
3952 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3954 if (SecurityDescriptor)
3955 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3957 while (*StringSecurityDescriptor)
3959 toktype = *StringSecurityDescriptor;
3961 /* Expect char identifier followed by ':' */
3962 StringSecurityDescriptor++;
3963 if (*StringSecurityDescriptor != ':')
3965 SetLastError(ERROR_INVALID_PARAMETER);
3966 goto lend;
3968 StringSecurityDescriptor++;
3970 /* Extract token */
3971 lptoken = StringSecurityDescriptor;
3972 while (*lptoken && *lptoken != ':')
3973 lptoken++;
3975 if (*lptoken)
3976 lptoken--;
3978 len = lptoken - StringSecurityDescriptor;
3979 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3980 tok[len] = 0;
3982 switch (toktype)
3984 case 'O':
3986 DWORD bytes;
3988 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3989 goto lend;
3991 if (SecurityDescriptor)
3993 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3994 lpNext += bytes; /* Advance to next token */
3997 *cBytes += bytes;
3999 break;
4002 case 'G':
4004 DWORD bytes;
4006 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4007 goto lend;
4009 if (SecurityDescriptor)
4011 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4012 lpNext += bytes; /* Advance to next token */
4015 *cBytes += bytes;
4017 break;
4020 case 'D':
4022 DWORD flags;
4023 DWORD bytes;
4025 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4026 goto lend;
4028 if (SecurityDescriptor)
4030 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4031 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4032 lpNext += bytes; /* Advance to next token */
4035 *cBytes += bytes;
4037 break;
4040 case 'S':
4042 DWORD flags;
4043 DWORD bytes;
4045 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4046 goto lend;
4048 if (SecurityDescriptor)
4050 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4051 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4052 lpNext += bytes; /* Advance to next token */
4055 *cBytes += bytes;
4057 break;
4060 default:
4061 FIXME("Unknown token\n");
4062 SetLastError(ERROR_INVALID_PARAMETER);
4063 goto lend;
4066 StringSecurityDescriptor = lptoken;
4069 bret = TRUE;
4071 lend:
4072 return bret;
4075 /******************************************************************************
4076 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4078 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4079 LPCSTR StringSecurityDescriptor,
4080 DWORD StringSDRevision,
4081 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4082 PULONG SecurityDescriptorSize)
4084 UINT len;
4085 BOOL ret = FALSE;
4086 LPWSTR StringSecurityDescriptorW;
4088 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4089 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4091 if (StringSecurityDescriptorW)
4093 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4095 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4096 StringSDRevision, SecurityDescriptor,
4097 SecurityDescriptorSize);
4098 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4101 return ret;
4104 /******************************************************************************
4105 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4107 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4108 LPCWSTR StringSecurityDescriptor,
4109 DWORD StringSDRevision,
4110 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4111 PULONG SecurityDescriptorSize)
4113 DWORD cBytes;
4114 SECURITY_DESCRIPTOR* psd;
4115 BOOL bret = FALSE;
4117 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4119 if (GetVersion() & 0x80000000)
4121 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4122 goto lend;
4124 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4126 SetLastError(ERROR_INVALID_PARAMETER);
4127 goto lend;
4129 else if (StringSDRevision != SID_REVISION)
4131 SetLastError(ERROR_UNKNOWN_REVISION);
4132 goto lend;
4135 /* Compute security descriptor length */
4136 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4137 NULL, &cBytes))
4138 goto lend;
4140 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4141 GMEM_ZEROINIT, cBytes);
4142 if (!psd) goto lend;
4144 psd->Revision = SID_REVISION;
4145 psd->Control |= SE_SELF_RELATIVE;
4147 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4148 psd, &cBytes))
4150 LocalFree(psd);
4151 goto lend;
4154 if (SecurityDescriptorSize)
4155 *SecurityDescriptorSize = cBytes;
4157 bret = TRUE;
4159 lend:
4160 TRACE(" ret=%d\n", bret);
4161 return bret;
4164 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4166 if (cch == -1)
4167 cch = strlenW(string);
4169 if (plen)
4170 *plen += cch;
4172 if (pwptr)
4174 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4175 *pwptr += cch;
4179 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4181 DWORD i;
4182 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4183 WCHAR subauthfmt[] = { '-','%','u',0 };
4184 WCHAR buf[26];
4185 SID *pisid = psid;
4187 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4189 SetLastError(ERROR_INVALID_SID);
4190 return FALSE;
4193 if (pisid->IdentifierAuthority.Value[0] ||
4194 pisid->IdentifierAuthority.Value[1])
4196 FIXME("not matching MS' bugs\n");
4197 SetLastError(ERROR_INVALID_SID);
4198 return FALSE;
4201 sprintfW( buf, fmt, pisid->Revision,
4202 MAKELONG(
4203 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4204 pisid->IdentifierAuthority.Value[4] ),
4205 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4206 pisid->IdentifierAuthority.Value[2] )
4207 ) );
4208 DumpString(buf, -1, pwptr, plen);
4210 for( i=0; i<pisid->SubAuthorityCount; i++ )
4212 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4213 DumpString(buf, -1, pwptr, plen);
4215 return TRUE;
4218 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4220 size_t i;
4221 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4223 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4225 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4226 return TRUE;
4230 return DumpSidNumeric(psid, pwptr, plen);
4233 static const LPCWSTR AceRightBitNames[32] = {
4234 SDDL_CREATE_CHILD, /* 0 */
4235 SDDL_DELETE_CHILD,
4236 SDDL_LIST_CHILDREN,
4237 SDDL_SELF_WRITE,
4238 SDDL_READ_PROPERTY, /* 4 */
4239 SDDL_WRITE_PROPERTY,
4240 SDDL_DELETE_TREE,
4241 SDDL_LIST_OBJECT,
4242 SDDL_CONTROL_ACCESS, /* 8 */
4243 NULL,
4244 NULL,
4245 NULL,
4246 NULL, /* 12 */
4247 NULL,
4248 NULL,
4249 NULL,
4250 SDDL_STANDARD_DELETE, /* 16 */
4251 SDDL_READ_CONTROL,
4252 SDDL_WRITE_DAC,
4253 SDDL_WRITE_OWNER,
4254 NULL, /* 20 */
4255 NULL,
4256 NULL,
4257 NULL,
4258 NULL, /* 24 */
4259 NULL,
4260 NULL,
4261 NULL,
4262 SDDL_GENERIC_ALL, /* 28 */
4263 SDDL_GENERIC_EXECUTE,
4264 SDDL_GENERIC_WRITE,
4265 SDDL_GENERIC_READ
4268 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4270 static const WCHAR fmtW[] = {'0','x','%','x',0};
4271 WCHAR buf[15];
4272 size_t i;
4274 if (mask == 0)
4275 return;
4277 /* first check if the right have name */
4278 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4280 if (AceRights[i].wstr == NULL)
4281 break;
4282 if (mask == AceRights[i].value)
4284 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4285 return;
4289 /* then check if it can be built from bit names */
4290 for (i = 0; i < 32; i++)
4292 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4294 /* can't be built from bit names */
4295 sprintfW(buf, fmtW, mask);
4296 DumpString(buf, -1, pwptr, plen);
4297 return;
4301 /* build from bit names */
4302 for (i = 0; i < 32; i++)
4303 if (mask & (1 << i))
4304 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4307 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4309 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4310 static const WCHAR openbr = '(';
4311 static const WCHAR closebr = ')';
4312 static const WCHAR semicolon = ';';
4314 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4316 SetLastError(ERROR_INVALID_ACL);
4317 return FALSE;
4320 piace = (ACCESS_ALLOWED_ACE *)pace;
4321 DumpString(&openbr, 1, pwptr, plen);
4322 switch (piace->Header.AceType)
4324 case ACCESS_ALLOWED_ACE_TYPE:
4325 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4326 break;
4327 case ACCESS_DENIED_ACE_TYPE:
4328 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4329 break;
4330 case SYSTEM_AUDIT_ACE_TYPE:
4331 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4332 break;
4333 case SYSTEM_ALARM_ACE_TYPE:
4334 DumpString(SDDL_ALARM, -1, pwptr, plen);
4335 break;
4337 DumpString(&semicolon, 1, pwptr, plen);
4339 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4340 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4341 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4342 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4343 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4344 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4345 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4346 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4347 if (piace->Header.AceFlags & INHERITED_ACE)
4348 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4349 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4350 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4351 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4352 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4353 DumpString(&semicolon, 1, pwptr, plen);
4354 DumpRights(piace->Mask, pwptr, plen);
4355 DumpString(&semicolon, 1, pwptr, plen);
4356 /* objects not supported */
4357 DumpString(&semicolon, 1, pwptr, plen);
4358 /* objects not supported */
4359 DumpString(&semicolon, 1, pwptr, plen);
4360 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4361 return FALSE;
4362 DumpString(&closebr, 1, pwptr, plen);
4363 return TRUE;
4366 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4368 WORD count;
4369 int i;
4371 if (protected)
4372 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4373 if (autoInheritReq)
4374 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4375 if (autoInherited)
4376 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4378 if (pacl == NULL)
4379 return TRUE;
4381 if (!IsValidAcl(pacl))
4382 return FALSE;
4384 count = pacl->AceCount;
4385 for (i = 0; i < count; i++)
4387 LPVOID ace;
4388 if (!GetAce(pacl, i, &ace))
4389 return FALSE;
4390 if (!DumpAce(ace, pwptr, plen))
4391 return FALSE;
4394 return TRUE;
4397 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4399 static const WCHAR prefix[] = {'O',':',0};
4400 BOOL bDefaulted;
4401 PSID psid;
4403 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4404 return FALSE;
4406 if (psid == NULL)
4407 return TRUE;
4409 DumpString(prefix, -1, pwptr, plen);
4410 if (!DumpSid(psid, pwptr, plen))
4411 return FALSE;
4412 return TRUE;
4415 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4417 static const WCHAR prefix[] = {'G',':',0};
4418 BOOL bDefaulted;
4419 PSID psid;
4421 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4422 return FALSE;
4424 if (psid == NULL)
4425 return TRUE;
4427 DumpString(prefix, -1, pwptr, plen);
4428 if (!DumpSid(psid, pwptr, plen))
4429 return FALSE;
4430 return TRUE;
4433 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4435 static const WCHAR dacl[] = {'D',':',0};
4436 SECURITY_DESCRIPTOR_CONTROL control;
4437 BOOL present, defaulted;
4438 DWORD revision;
4439 PACL pacl;
4441 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4442 return FALSE;
4444 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4445 return FALSE;
4447 if (!present)
4448 return TRUE;
4450 DumpString(dacl, 2, pwptr, plen);
4451 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4452 return FALSE;
4453 return TRUE;
4456 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4458 static const WCHAR sacl[] = {'S',':',0};
4459 SECURITY_DESCRIPTOR_CONTROL control;
4460 BOOL present, defaulted;
4461 DWORD revision;
4462 PACL pacl;
4464 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4465 return FALSE;
4467 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4468 return FALSE;
4470 if (!present)
4471 return TRUE;
4473 DumpString(sacl, 2, pwptr, plen);
4474 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4475 return FALSE;
4476 return TRUE;
4479 /******************************************************************************
4480 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4482 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4484 ULONG len;
4485 WCHAR *wptr, *wstr;
4487 if (SDRevision != SDDL_REVISION_1)
4489 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4490 SetLastError(ERROR_UNKNOWN_REVISION);
4491 return FALSE;
4494 len = 0;
4495 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4496 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4497 return FALSE;
4498 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4499 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4500 return FALSE;
4501 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4502 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4503 return FALSE;
4504 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4505 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4506 return FALSE;
4508 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4509 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4510 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4511 return FALSE;
4512 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4513 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4514 return FALSE;
4515 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4516 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4517 return FALSE;
4518 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4519 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4520 return FALSE;
4521 *wptr = 0;
4523 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4524 *OutputString = wstr;
4525 if (OutputLen)
4526 *OutputLen = strlenW(*OutputString)+1;
4527 return TRUE;
4530 /******************************************************************************
4531 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4533 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4535 LPWSTR wstr;
4536 ULONG len;
4537 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4539 int lenA;
4541 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4542 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4543 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4544 LocalFree(wstr);
4546 if (OutputLen != NULL)
4547 *OutputLen = lenA;
4548 return TRUE;
4550 else
4552 *OutputString = NULL;
4553 if (OutputLen)
4554 *OutputLen = 0;
4555 return FALSE;
4559 /******************************************************************************
4560 * ConvertStringSidToSidW [ADVAPI32.@]
4562 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4564 BOOL bret = FALSE;
4565 DWORD cBytes;
4567 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4568 if (GetVersion() & 0x80000000)
4569 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4570 else if (!StringSid || !Sid)
4571 SetLastError(ERROR_INVALID_PARAMETER);
4572 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4574 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4576 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4577 if (!bret)
4578 LocalFree(*Sid);
4580 return bret;
4583 /******************************************************************************
4584 * ConvertStringSidToSidA [ADVAPI32.@]
4586 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4588 BOOL bret = FALSE;
4590 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4591 if (GetVersion() & 0x80000000)
4592 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4593 else if (!StringSid || !Sid)
4594 SetLastError(ERROR_INVALID_PARAMETER);
4595 else
4597 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4598 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4599 len * sizeof(WCHAR));
4601 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4602 bret = ConvertStringSidToSidW(wStringSid, Sid);
4603 HeapFree(GetProcessHeap(), 0, wStringSid);
4605 return bret;
4608 /******************************************************************************
4609 * ConvertSidToStringSidW [ADVAPI32.@]
4611 * format of SID string is:
4612 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4613 * where
4614 * <rev> is the revision of the SID encoded as decimal
4615 * <auth> is the identifier authority encoded as hex
4616 * <subauthN> is the subauthority id encoded as decimal
4618 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4620 DWORD len = 0;
4621 LPWSTR wstr, wptr;
4623 TRACE("%p %p\n", pSid, pstr );
4625 len = 0;
4626 if (!DumpSidNumeric(pSid, NULL, &len))
4627 return FALSE;
4628 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4629 DumpSidNumeric(pSid, &wptr, NULL);
4630 *wptr = 0;
4632 *pstr = wstr;
4633 return TRUE;
4636 /******************************************************************************
4637 * ConvertSidToStringSidA [ADVAPI32.@]
4639 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4641 LPWSTR wstr = NULL;
4642 LPSTR str;
4643 UINT len;
4645 TRACE("%p %p\n", pSid, pstr );
4647 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4648 return FALSE;
4650 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4651 str = LocalAlloc( 0, len );
4652 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4653 LocalFree( wstr );
4655 *pstr = str;
4657 return TRUE;
4660 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4661 PSECURITY_DESCRIPTOR pdesc,
4662 PSECURITY_DESCRIPTOR cdesc,
4663 PSECURITY_DESCRIPTOR* ndesc,
4664 GUID* objtype,
4665 BOOL isdir,
4666 PGENERIC_MAPPING genmap )
4668 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4670 return FALSE;
4673 BOOL WINAPI CreatePrivateObjectSecurity(
4674 PSECURITY_DESCRIPTOR ParentDescriptor,
4675 PSECURITY_DESCRIPTOR CreatorDescriptor,
4676 PSECURITY_DESCRIPTOR* NewDescriptor,
4677 BOOL IsDirectoryObject,
4678 HANDLE Token,
4679 PGENERIC_MAPPING GenericMapping )
4681 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4682 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4684 return FALSE;
4687 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4689 FIXME("%p - stub\n", ObjectDescriptor);
4691 return TRUE;
4694 BOOL WINAPI CreateProcessAsUserA(
4695 HANDLE hToken,
4696 LPCSTR lpApplicationName,
4697 LPSTR lpCommandLine,
4698 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4699 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4700 BOOL bInheritHandles,
4701 DWORD dwCreationFlags,
4702 LPVOID lpEnvironment,
4703 LPCSTR lpCurrentDirectory,
4704 LPSTARTUPINFOA lpStartupInfo,
4705 LPPROCESS_INFORMATION lpProcessInformation )
4707 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4708 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4709 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4711 return FALSE;
4714 BOOL WINAPI CreateProcessAsUserW(
4715 HANDLE hToken,
4716 LPCWSTR lpApplicationName,
4717 LPWSTR lpCommandLine,
4718 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4719 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4720 BOOL bInheritHandles,
4721 DWORD dwCreationFlags,
4722 LPVOID lpEnvironment,
4723 LPCWSTR lpCurrentDirectory,
4724 LPSTARTUPINFOW lpStartupInfo,
4725 LPPROCESS_INFORMATION lpProcessInformation )
4727 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4728 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4729 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4730 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4732 /* We should create the process with a suspended main thread */
4733 if (!CreateProcessW (lpApplicationName,
4734 lpCommandLine,
4735 lpProcessAttributes,
4736 lpThreadAttributes,
4737 bInheritHandles,
4738 dwCreationFlags, /* CREATE_SUSPENDED */
4739 lpEnvironment,
4740 lpCurrentDirectory,
4741 lpStartupInfo,
4742 lpProcessInformation))
4744 return FALSE;
4747 return TRUE;
4750 /******************************************************************************
4751 * CreateProcessWithLogonW
4753 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4754 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4755 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4757 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4758 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4759 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4760 lpStartupInfo, lpProcessInformation);
4762 return FALSE;
4765 /******************************************************************************
4766 * DuplicateTokenEx [ADVAPI32.@]
4768 BOOL WINAPI DuplicateTokenEx(
4769 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4770 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4771 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4772 TOKEN_TYPE TokenType,
4773 PHANDLE DuplicateTokenHandle )
4775 OBJECT_ATTRIBUTES ObjectAttributes;
4777 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4778 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4780 InitializeObjectAttributes(
4781 &ObjectAttributes,
4782 NULL,
4783 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4784 NULL,
4785 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4787 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4788 dwDesiredAccess,
4789 &ObjectAttributes,
4790 ImpersonationLevel,
4791 TokenType,
4792 DuplicateTokenHandle ) );
4795 BOOL WINAPI DuplicateToken(
4796 HANDLE ExistingTokenHandle,
4797 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4798 PHANDLE DuplicateTokenHandle )
4800 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4801 NULL, ImpersonationLevel, TokenImpersonation,
4802 DuplicateTokenHandle );
4805 /******************************************************************************
4806 * ComputeStringSidSize
4808 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4810 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4812 int ctok = 0;
4813 while (*StringSid)
4815 if (*StringSid == '-')
4816 ctok++;
4817 StringSid++;
4820 if (ctok >= 3)
4821 return GetSidLengthRequired(ctok - 2);
4823 else /* String constant format - Only available in winxp and above */
4825 unsigned int i;
4827 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4828 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4829 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4832 return GetSidLengthRequired(0);
4835 /******************************************************************************
4836 * ParseStringSidToSid
4838 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4840 BOOL bret = FALSE;
4841 SID* pisid=pSid;
4843 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4844 if (!StringSid)
4846 SetLastError(ERROR_INVALID_PARAMETER);
4847 TRACE("StringSid is NULL, returning FALSE\n");
4848 return FALSE;
4851 *cBytes = ComputeStringSidSize(StringSid);
4852 if (!pisid) /* Simply compute the size */
4854 TRACE("only size requested, returning TRUE\n");
4855 return TRUE;
4858 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4860 DWORD i = 0, identAuth;
4861 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4863 StringSid += 2; /* Advance to Revision */
4864 pisid->Revision = atoiW(StringSid);
4866 if (pisid->Revision != SDDL_REVISION)
4868 TRACE("Revision %d is unknown\n", pisid->Revision);
4869 goto lend; /* ERROR_INVALID_SID */
4871 if (csubauth == 0)
4873 TRACE("SubAuthorityCount is 0\n");
4874 goto lend; /* ERROR_INVALID_SID */
4877 pisid->SubAuthorityCount = csubauth;
4879 /* Advance to identifier authority */
4880 while (*StringSid && *StringSid != '-')
4881 StringSid++;
4882 if (*StringSid == '-')
4883 StringSid++;
4885 /* MS' implementation can't handle values greater than 2^32 - 1, so
4886 * we don't either; assume most significant bytes are always 0
4888 pisid->IdentifierAuthority.Value[0] = 0;
4889 pisid->IdentifierAuthority.Value[1] = 0;
4890 identAuth = atoiW(StringSid);
4891 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4892 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4893 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4894 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4896 /* Advance to first sub authority */
4897 while (*StringSid && *StringSid != '-')
4898 StringSid++;
4899 if (*StringSid == '-')
4900 StringSid++;
4902 while (*StringSid)
4904 pisid->SubAuthority[i++] = atoiW(StringSid);
4906 while (*StringSid && *StringSid != '-')
4907 StringSid++;
4908 if (*StringSid == '-')
4909 StringSid++;
4912 if (i != pisid->SubAuthorityCount)
4913 goto lend; /* ERROR_INVALID_SID */
4915 bret = TRUE;
4917 else /* String constant format - Only available in winxp and above */
4919 unsigned int i;
4920 pisid->Revision = SDDL_REVISION;
4922 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4923 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4925 DWORD j;
4926 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4927 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4928 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4929 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4930 bret = TRUE;
4933 if (!bret)
4934 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4937 lend:
4938 if (!bret)
4939 SetLastError(ERROR_INVALID_SID);
4941 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4942 return bret;
4945 /******************************************************************************
4946 * GetNamedSecurityInfoA [ADVAPI32.@]
4948 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4949 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4950 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4951 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4953 DWORD len;
4954 LPWSTR wstr = NULL;
4955 DWORD r;
4957 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4958 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4960 if( pObjectName )
4962 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4963 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4964 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4967 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4968 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4970 HeapFree( GetProcessHeap(), 0, wstr );
4972 return r;
4975 /******************************************************************************
4976 * GetNamedSecurityInfoW [ADVAPI32.@]
4978 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4979 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4980 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4982 DWORD needed, offset;
4983 SECURITY_DESCRIPTOR_RELATIVE *relative;
4984 BYTE *buffer;
4986 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4987 group, dacl, sacl, descriptor );
4989 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4991 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4992 if (info & OWNER_SECURITY_INFORMATION)
4993 needed += sizeof(sidWorld);
4994 if (info & GROUP_SECURITY_INFORMATION)
4995 needed += sizeof(sidWorld);
4996 if (info & DACL_SECURITY_INFORMATION)
4997 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4998 if (info & SACL_SECURITY_INFORMATION)
4999 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5001 /* must be freed by caller */
5002 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5003 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5005 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5007 HeapFree( GetProcessHeap(), 0, *descriptor );
5008 return ERROR_INVALID_SECURITY_DESCR;
5011 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
5012 relative->Control |= SE_SELF_RELATIVE;
5013 buffer = (BYTE *)relative;
5014 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5016 if (info & OWNER_SECURITY_INFORMATION)
5018 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5019 relative->Owner = offset;
5020 if (owner)
5021 *owner = buffer + offset;
5022 offset += sizeof(sidWorld);
5024 if (info & GROUP_SECURITY_INFORMATION)
5026 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5027 relative->Group = offset;
5028 if (group)
5029 *group = buffer + offset;
5030 offset += sizeof(sidWorld);
5032 if (info & DACL_SECURITY_INFORMATION)
5034 relative->Control |= SE_DACL_PRESENT;
5035 GetWorldAccessACL( (PACL)(buffer + offset) );
5036 relative->Dacl = offset;
5037 if (dacl)
5038 *dacl = (PACL)(buffer + offset);
5039 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5041 if (info & SACL_SECURITY_INFORMATION)
5043 relative->Control |= SE_SACL_PRESENT;
5044 GetWorldAccessACL( (PACL)(buffer + offset) );
5045 relative->Sacl = offset;
5046 if (sacl)
5047 *sacl = (PACL)(buffer + offset);
5049 return ERROR_SUCCESS;
5052 /******************************************************************************
5053 * DecryptFileW [ADVAPI32.@]
5055 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5057 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5058 return TRUE;
5061 /******************************************************************************
5062 * DecryptFileA [ADVAPI32.@]
5064 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5066 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5067 return TRUE;
5070 /******************************************************************************
5071 * EncryptFileW [ADVAPI32.@]
5073 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5075 FIXME("%s\n", debugstr_w(lpFileName));
5076 return TRUE;
5079 /******************************************************************************
5080 * EncryptFileA [ADVAPI32.@]
5082 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5084 FIXME("%s\n", debugstr_a(lpFileName));
5085 return TRUE;
5088 /******************************************************************************
5089 * FileEncryptionStatusW [ADVAPI32.@]
5091 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5093 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5094 if (!lpStatus)
5095 return FALSE;
5096 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5097 return TRUE;
5100 /******************************************************************************
5101 * FileEncryptionStatusA [ADVAPI32.@]
5103 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5105 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5106 if (!lpStatus)
5107 return FALSE;
5108 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5109 return TRUE;
5112 /******************************************************************************
5113 * SetSecurityInfo [ADVAPI32.@]
5115 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5116 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5117 PSID psidGroup, PACL pDacl, PACL pSacl) {
5118 FIXME("stub\n");
5119 return ERROR_SUCCESS;