push dc8503392987ce7578c917abaade55b30873eb34
[wine/hacks.git] / dlls / advapi32 / security.c
blob559291c6f27ac6fa10fe8312a21bdeed177f93d2
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"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
47 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
48 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
49 PACL pAcl, LPDWORD cBytes);
50 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
51 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
52 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
53 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
54 LPCWSTR StringSecurityDescriptor,
55 SECURITY_DESCRIPTOR* SecurityDescriptor,
56 LPDWORD cBytes);
57 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
59 typedef struct _ACEFLAG
61 LPCWSTR wstr;
62 DWORD value;
63 } ACEFLAG, *LPACEFLAG;
65 typedef struct _MAX_SID
67 /* same fields as struct _SID */
68 BYTE Revision;
69 BYTE SubAuthorityCount;
70 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } MAX_SID;
74 typedef struct WELLKNOWNSID
76 WCHAR wstr[2];
77 WELL_KNOWN_SID_TYPE Type;
78 MAX_SID Sid;
79 } WELLKNOWNSID;
81 static const WELLKNOWNSID WellKnownSids[] =
83 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
84 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
85 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
86 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
87 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
88 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
89 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
90 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
91 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
92 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
93 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
94 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
95 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
96 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
97 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
98 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
99 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
100 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
101 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
102 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
103 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
104 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
105 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
106 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
107 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
108 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
109 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
110 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
111 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
112 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
113 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
114 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
115 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
116 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
117 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
118 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
119 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
121 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
122 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
123 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
124 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
125 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
126 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
129 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
131 typedef struct _AccountSid {
132 WELL_KNOWN_SID_TYPE type;
133 LPCWSTR account;
134 LPCWSTR domain;
135 SID_NAME_USE name_use;
136 } AccountSid;
138 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
139 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
140 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
141 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
142 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
143 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
144 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
145 static const WCHAR Blank[] = { 0 };
146 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
147 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
148 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
149 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 };
150 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
151 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 };
152 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
153 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 };
154 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
155 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
156 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
157 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
158 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
159 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
160 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
161 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 };
162 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
163 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 };
164 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
165 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
166 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
167 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
168 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
169 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
170 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 };
171 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
172 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
173 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
174 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
175 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
176 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
177 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 };
178 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 };
179 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
180 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 };
181 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
182 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
183 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
184 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 };
185 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 };
186 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
187 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
188 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 };
189 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
190 static const WCHAR SELF[] = { 'S','E','L','F',0 };
191 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
192 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
193 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
194 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 };
195 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
196 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
198 static const AccountSid ACCOUNT_SIDS[] = {
199 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
200 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
201 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
202 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
203 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
204 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
205 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
206 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
207 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
208 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
209 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
210 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
211 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
212 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
213 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
214 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
215 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
216 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
217 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
218 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
219 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
220 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
221 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
222 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
223 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
224 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
225 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
226 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
227 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
228 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
229 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
230 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
231 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
232 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
233 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
234 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
235 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
236 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
242 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
245 * ACE access rights
247 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
248 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
249 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
250 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
252 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
253 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
254 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
255 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
256 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
257 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
258 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
259 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
260 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
262 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
263 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
264 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
265 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
267 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
268 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
269 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
270 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
272 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
273 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
274 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
275 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
278 * ACL flags
280 static const WCHAR SDDL_PROTECTED[] = {'P',0};
281 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
282 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
285 * ACE types
287 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
288 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
289 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
290 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
291 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
292 static const WCHAR SDDL_ALARM[] = {'A','L',0};
293 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
294 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
297 * ACE flags
299 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
300 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
301 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
302 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
303 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
304 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
305 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
307 const char * debugstr_sid(PSID sid)
309 int auth = 0;
310 SID * psid = (SID *)sid;
312 if (psid == NULL)
313 return "(null)";
315 auth = psid->IdentifierAuthority.Value[5] +
316 (psid->IdentifierAuthority.Value[4] << 8) +
317 (psid->IdentifierAuthority.Value[3] << 16) +
318 (psid->IdentifierAuthority.Value[2] << 24);
320 switch (psid->SubAuthorityCount) {
321 case 0:
322 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
323 case 1:
324 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
325 psid->SubAuthority[0]);
326 case 2:
327 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
328 psid->SubAuthority[0], psid->SubAuthority[1]);
329 case 3:
330 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
331 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
332 case 4:
333 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
334 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
335 psid->SubAuthority[3]);
336 case 5:
337 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
338 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
339 psid->SubAuthority[3], psid->SubAuthority[4]);
340 case 6:
341 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
342 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
343 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
344 case 7:
345 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
346 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
347 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
348 psid->SubAuthority[6]);
349 case 8:
350 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
351 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
352 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
353 psid->SubAuthority[6], psid->SubAuthority[7]);
355 return "(too-big)";
358 /* set last error code from NT status and get the proper boolean return value */
359 /* used for functions that are a simple wrapper around the corresponding ntdll API */
360 static inline BOOL set_ntstatus( NTSTATUS status )
362 if (status) SetLastError( RtlNtStatusToDosError( status ));
363 return !status;
366 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
368 static void GetWorldAccessACL(PACL pACL)
370 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
372 pACL->AclRevision = ACL_REVISION;
373 pACL->Sbz1 = 0;
374 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
375 pACL->AceCount = 1;
376 pACL->Sbz2 = 0;
378 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
379 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
380 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
381 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
382 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
385 /************************************************************
386 * ADVAPI_IsLocalComputer
388 * Checks whether the server name indicates local machine.
390 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
392 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
393 BOOL Result;
394 LPWSTR buf;
396 if (!ServerName || !ServerName[0])
397 return TRUE;
399 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
400 Result = GetComputerNameW(buf, &dwSize);
401 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
402 ServerName += 2;
403 Result = Result && !lstrcmpW(ServerName, buf);
404 HeapFree(GetProcessHeap(), 0, buf);
406 return Result;
409 /************************************************************
410 * ADVAPI_GetComputerSid
412 * Reads the computer SID from the registry.
414 BOOL ADVAPI_GetComputerSid(PSID sid)
416 HKEY key;
417 LONG ret;
418 BOOL retval = FALSE;
419 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 };
420 static const WCHAR V[] = { 'V',0 };
422 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
423 KEY_READ, &key)) == ERROR_SUCCESS)
425 DWORD size = 0;
426 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
427 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
429 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
430 if (data)
432 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
433 data, &size)) == ERROR_SUCCESS)
435 /* the SID is in the last 24 bytes of the binary data */
436 CopyMemory(sid, &data[size-24], 24);
437 retval = TRUE;
439 HeapFree(GetProcessHeap(), 0, data);
442 RegCloseKey(key);
445 if(retval == TRUE) return retval;
447 /* create a new random SID */
448 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
449 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
451 PSID new_sid;
452 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
453 DWORD id[3];
455 if (RtlGenRandom(&id, sizeof(id)))
457 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
459 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
460 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
462 FreeSid(new_sid);
465 RegCloseKey(key);
468 return retval;
471 /* ##############################
472 ###### TOKEN FUNCTIONS ######
473 ##############################
476 /******************************************************************************
477 * OpenProcessToken [ADVAPI32.@]
478 * Opens the access token associated with a process handle.
480 * PARAMS
481 * ProcessHandle [I] Handle to process
482 * DesiredAccess [I] Desired access to process
483 * TokenHandle [O] Pointer to handle of open access token
485 * RETURNS
486 * Success: TRUE. TokenHandle contains the access token.
487 * Failure: FALSE.
489 * NOTES
490 * See NtOpenProcessToken.
492 BOOL WINAPI
493 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
494 HANDLE *TokenHandle )
496 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
499 /******************************************************************************
500 * OpenThreadToken [ADVAPI32.@]
502 * Opens the access token associated with a thread handle.
504 * PARAMS
505 * ThreadHandle [I] Handle to process
506 * DesiredAccess [I] Desired access to the thread
507 * OpenAsSelf [I] ???
508 * TokenHandle [O] Destination for the token handle
510 * RETURNS
511 * Success: TRUE. TokenHandle contains the access token.
512 * Failure: FALSE.
514 * NOTES
515 * See NtOpenThreadToken.
517 BOOL WINAPI
518 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
519 BOOL OpenAsSelf, HANDLE *TokenHandle)
521 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
524 BOOL WINAPI
525 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
526 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
528 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
529 PreviousState, ReturnLength));
532 /******************************************************************************
533 * AdjustTokenPrivileges [ADVAPI32.@]
535 * Adjust the privileges of an open token handle.
537 * PARAMS
538 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
539 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
540 * NewState [I] Desired new privileges of the token
541 * BufferLength [I] Length of NewState
542 * PreviousState [O] Destination for the previous state
543 * ReturnLength [I/O] Size of PreviousState
546 * RETURNS
547 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
548 * Failure: FALSE.
550 * NOTES
551 * See NtAdjustPrivilegesToken.
553 BOOL WINAPI
554 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
555 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
556 PTOKEN_PRIVILEGES PreviousState, LPDWORD ReturnLength )
558 NTSTATUS status;
560 TRACE("\n");
562 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
563 NewState, BufferLength, PreviousState,
564 ReturnLength);
565 SetLastError( RtlNtStatusToDosError( status ));
566 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
567 return TRUE;
568 else
569 return FALSE;
572 /******************************************************************************
573 * CheckTokenMembership [ADVAPI32.@]
575 * Determine if an access token is a member of a SID.
577 * PARAMS
578 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
579 * SidToCheck [I] SID that possibly contains the token
580 * IsMember [O] Destination for result.
582 * RETURNS
583 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
584 * Failure: FALSE.
586 BOOL WINAPI
587 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
588 PBOOL IsMember )
590 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
592 *IsMember = TRUE;
593 return(TRUE);
596 /******************************************************************************
597 * GetTokenInformation [ADVAPI32.@]
599 * Get a type of information about an access token.
601 * PARAMS
602 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
603 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
604 * tokeninfo [O] Destination for token information
605 * tokeninfolength [I] Length of tokeninfo
606 * retlen [O] Destination for returned token information length
608 * RETURNS
609 * Success: TRUE. tokeninfo contains retlen bytes of token information
610 * Failure: FALSE.
612 * NOTES
613 * See NtQueryInformationToken.
615 BOOL WINAPI
616 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
617 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
619 TRACE("(%p, %s, %p, %d, %p):\n",
620 token,
621 (tokeninfoclass == TokenUser) ? "TokenUser" :
622 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
623 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
624 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
625 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
626 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
627 (tokeninfoclass == TokenSource) ? "TokenSource" :
628 (tokeninfoclass == TokenType) ? "TokenType" :
629 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
630 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
631 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
632 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
633 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
634 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
635 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
636 "Unknown",
637 tokeninfo, tokeninfolength, retlen);
638 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
639 tokeninfolength, retlen));
642 /******************************************************************************
643 * SetTokenInformation [ADVAPI32.@]
645 * Set information for an access token.
647 * PARAMS
648 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
649 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
650 * tokeninfo [I] Token information to set
651 * tokeninfolength [I] Length of tokeninfo
653 * RETURNS
654 * Success: TRUE. The information for the token is set to tokeninfo.
655 * Failure: FALSE.
657 BOOL WINAPI
658 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
659 LPVOID tokeninfo, DWORD tokeninfolength )
661 TRACE("(%p, %s, %p, %d): stub\n",
662 token,
663 (tokeninfoclass == TokenUser) ? "TokenUser" :
664 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
665 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
666 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
667 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
668 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
669 (tokeninfoclass == TokenSource) ? "TokenSource" :
670 (tokeninfoclass == TokenType) ? "TokenType" :
671 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
672 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
673 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
674 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
675 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
676 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
677 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
678 "Unknown",
679 tokeninfo, tokeninfolength);
681 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
684 /*************************************************************************
685 * SetThreadToken [ADVAPI32.@]
687 * Assigns an 'impersonation token' to a thread so it can assume the
688 * security privileges of another thread or process. Can also remove
689 * a previously assigned token.
691 * PARAMS
692 * thread [O] Handle to thread to set the token for
693 * token [I] Token to set
695 * RETURNS
696 * Success: TRUE. The threads access token is set to token
697 * Failure: FALSE.
699 * NOTES
700 * Only supported on NT or higher. On Win9X this function does nothing.
701 * See SetTokenInformation.
703 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
705 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
706 ThreadImpersonationToken, &token, sizeof token ));
709 /* ##############################
710 ###### SID FUNCTIONS ######
711 ##############################
714 /******************************************************************************
715 * AllocateAndInitializeSid [ADVAPI32.@]
717 * PARAMS
718 * pIdentifierAuthority []
719 * nSubAuthorityCount []
720 * nSubAuthority0 []
721 * nSubAuthority1 []
722 * nSubAuthority2 []
723 * nSubAuthority3 []
724 * nSubAuthority4 []
725 * nSubAuthority5 []
726 * nSubAuthority6 []
727 * nSubAuthority7 []
728 * pSid []
730 BOOL WINAPI
731 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
732 BYTE nSubAuthorityCount,
733 DWORD nSubAuthority0, DWORD nSubAuthority1,
734 DWORD nSubAuthority2, DWORD nSubAuthority3,
735 DWORD nSubAuthority4, DWORD nSubAuthority5,
736 DWORD nSubAuthority6, DWORD nSubAuthority7,
737 PSID *pSid )
739 return set_ntstatus( RtlAllocateAndInitializeSid(
740 pIdentifierAuthority, nSubAuthorityCount,
741 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
742 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
743 pSid ));
746 /******************************************************************************
747 * FreeSid [ADVAPI32.@]
749 * PARAMS
750 * pSid []
752 PVOID WINAPI
753 FreeSid( PSID pSid )
755 RtlFreeSid(pSid);
756 return NULL; /* is documented like this */
759 /******************************************************************************
760 * CopySid [ADVAPI32.@]
762 * PARAMS
763 * nDestinationSidLength []
764 * pDestinationSid []
765 * pSourceSid []
767 BOOL WINAPI
768 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
770 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
773 /******************************************************************************
774 * CreateWellKnownSid [ADVAPI32.@]
776 BOOL WINAPI
777 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
778 PSID DomainSid,
779 PSID pSid,
780 DWORD* cbSid)
782 unsigned int i;
783 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
785 if (DomainSid != NULL) {
786 FIXME("Only local computer supported!\n");
787 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME */
788 return FALSE;
791 if (cbSid == NULL || pSid == NULL) {
792 SetLastError(ERROR_INVALID_PARAMETER);
793 return FALSE;
796 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
797 if (WellKnownSids[i].Type == WellKnownSidType) {
798 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
800 if (*cbSid < length) {
801 SetLastError(ERROR_INSUFFICIENT_BUFFER);
802 return FALSE;
805 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
806 *cbSid = length;
807 return TRUE;
811 SetLastError(ERROR_INVALID_PARAMETER);
812 return FALSE;
815 /******************************************************************************
816 * IsWellKnownSid [ADVAPI32.@]
818 BOOL WINAPI
819 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
821 unsigned int i;
822 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
824 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
825 if (WellKnownSids[i].Type == WellKnownSidType)
826 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
827 return TRUE;
829 return FALSE;
832 BOOL WINAPI
833 IsTokenRestricted( HANDLE TokenHandle )
835 TOKEN_GROUPS *groups;
836 DWORD size;
837 NTSTATUS status;
838 BOOL restricted;
840 TRACE("(%p)\n", TokenHandle);
842 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
843 if (status != STATUS_BUFFER_TOO_SMALL)
844 return FALSE;
846 groups = HeapAlloc(GetProcessHeap(), 0, size);
847 if (!groups)
849 SetLastError(ERROR_OUTOFMEMORY);
850 return FALSE;
853 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
854 if (status != STATUS_SUCCESS)
856 HeapFree(GetProcessHeap(), 0, groups);
857 return set_ntstatus(status);
860 if (groups->GroupCount)
861 restricted = TRUE;
862 else
863 restricted = FALSE;
865 HeapFree(GetProcessHeap(), 0, groups);
867 return restricted;
870 /******************************************************************************
871 * IsValidSid [ADVAPI32.@]
873 * PARAMS
874 * pSid []
876 BOOL WINAPI
877 IsValidSid( PSID pSid )
879 return RtlValidSid( pSid );
882 /******************************************************************************
883 * EqualSid [ADVAPI32.@]
885 * PARAMS
886 * pSid1 []
887 * pSid2 []
889 BOOL WINAPI
890 EqualSid( PSID pSid1, PSID pSid2 )
892 return RtlEqualSid( pSid1, pSid2 );
895 /******************************************************************************
896 * EqualPrefixSid [ADVAPI32.@]
898 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
900 return RtlEqualPrefixSid(pSid1, pSid2);
903 /******************************************************************************
904 * GetSidLengthRequired [ADVAPI32.@]
906 * PARAMS
907 * nSubAuthorityCount []
909 DWORD WINAPI
910 GetSidLengthRequired( BYTE nSubAuthorityCount )
912 return RtlLengthRequiredSid(nSubAuthorityCount);
915 /******************************************************************************
916 * InitializeSid [ADVAPI32.@]
918 * PARAMS
919 * pIdentifierAuthority []
921 BOOL WINAPI
922 InitializeSid (
923 PSID pSid,
924 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
925 BYTE nSubAuthorityCount)
927 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
930 DWORD WINAPI
931 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
933 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
935 return 1;
938 DWORD WINAPI
939 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
941 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
943 return 1;
946 /******************************************************************************
947 * GetSidIdentifierAuthority [ADVAPI32.@]
949 * PARAMS
950 * pSid []
952 PSID_IDENTIFIER_AUTHORITY WINAPI
953 GetSidIdentifierAuthority( PSID pSid )
955 return RtlIdentifierAuthoritySid(pSid);
958 /******************************************************************************
959 * GetSidSubAuthority [ADVAPI32.@]
961 * PARAMS
962 * pSid []
963 * nSubAuthority []
965 PDWORD WINAPI
966 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
968 return RtlSubAuthoritySid(pSid, nSubAuthority);
971 /******************************************************************************
972 * GetSidSubAuthorityCount [ADVAPI32.@]
974 * PARAMS
975 * pSid []
977 PUCHAR WINAPI
978 GetSidSubAuthorityCount (PSID pSid)
980 return RtlSubAuthorityCountSid(pSid);
983 /******************************************************************************
984 * GetLengthSid [ADVAPI32.@]
986 * PARAMS
987 * pSid []
989 DWORD WINAPI
990 GetLengthSid (PSID pSid)
992 return RtlLengthSid(pSid);
995 /* ##############################################
996 ###### SECURITY DESCRIPTOR FUNCTIONS ######
997 ##############################################
1000 /******************************************************************************
1001 * BuildSecurityDescriptorA [ADVAPI32.@]
1003 * Builds a SD from
1005 * PARAMS
1006 * pOwner [I]
1007 * pGroup [I]
1008 * cCountOfAccessEntries [I]
1009 * pListOfAccessEntries [I]
1010 * cCountOfAuditEntries [I]
1011 * pListofAuditEntries [I]
1012 * pOldSD [I]
1013 * lpdwBufferLength [I/O]
1014 * pNewSD [O]
1016 * RETURNS
1017 * Success: ERROR_SUCCESS
1018 * Failure: nonzero error code from Winerror.h
1020 DWORD WINAPI BuildSecurityDescriptorA(
1021 IN PTRUSTEEA pOwner,
1022 IN PTRUSTEEA pGroup,
1023 IN ULONG cCountOfAccessEntries,
1024 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1025 IN ULONG cCountOfAuditEntries,
1026 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1027 IN PSECURITY_DESCRIPTOR pOldSD,
1028 IN OUT PULONG lpdwBufferLength,
1029 OUT PSECURITY_DESCRIPTOR* pNewSD)
1031 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1032 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1033 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1035 return ERROR_CALL_NOT_IMPLEMENTED;
1038 /******************************************************************************
1039 * BuildSecurityDescriptorW [ADVAPI32.@]
1041 * See BuildSecurityDescriptorA.
1043 DWORD WINAPI BuildSecurityDescriptorW(
1044 IN PTRUSTEEW pOwner,
1045 IN PTRUSTEEW pGroup,
1046 IN ULONG cCountOfAccessEntries,
1047 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1048 IN ULONG cCountOfAuditEntries,
1049 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1050 IN PSECURITY_DESCRIPTOR pOldSD,
1051 IN OUT PULONG lpdwBufferLength,
1052 OUT PSECURITY_DESCRIPTOR* pNewSD)
1054 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1055 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1056 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1058 return ERROR_CALL_NOT_IMPLEMENTED;
1061 /******************************************************************************
1062 * InitializeSecurityDescriptor [ADVAPI32.@]
1064 * PARAMS
1065 * pDescr []
1066 * revision []
1068 BOOL WINAPI
1069 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1071 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1075 /******************************************************************************
1076 * MakeAbsoluteSD [ADVAPI32.@]
1078 BOOL WINAPI MakeAbsoluteSD (
1079 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1080 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1081 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1082 OUT PACL pDacl,
1083 OUT LPDWORD lpdwDaclSize,
1084 OUT PACL pSacl,
1085 OUT LPDWORD lpdwSaclSize,
1086 OUT PSID pOwner,
1087 OUT LPDWORD lpdwOwnerSize,
1088 OUT PSID pPrimaryGroup,
1089 OUT LPDWORD lpdwPrimaryGroupSize)
1091 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1092 pAbsoluteSecurityDescriptor,
1093 lpdwAbsoluteSecurityDescriptorSize,
1094 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1095 pOwner, lpdwOwnerSize,
1096 pPrimaryGroup, lpdwPrimaryGroupSize));
1099 /******************************************************************************
1100 * GetKernelObjectSecurity [ADVAPI32.@]
1102 BOOL WINAPI GetKernelObjectSecurity(
1103 HANDLE Handle,
1104 SECURITY_INFORMATION RequestedInformation,
1105 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1106 DWORD nLength,
1107 LPDWORD lpnLengthNeeded )
1109 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1110 pSecurityDescriptor, nLength, lpnLengthNeeded);
1112 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1113 nLength, lpnLengthNeeded ));
1116 /******************************************************************************
1117 * GetPrivateObjectSecurity [ADVAPI32.@]
1119 BOOL WINAPI GetPrivateObjectSecurity(
1120 PSECURITY_DESCRIPTOR ObjectDescriptor,
1121 SECURITY_INFORMATION SecurityInformation,
1122 PSECURITY_DESCRIPTOR ResultantDescriptor,
1123 DWORD DescriptorLength,
1124 PDWORD ReturnLength )
1126 SECURITY_DESCRIPTOR desc;
1127 BOOL defaulted, present;
1128 PACL pacl;
1129 PSID psid;
1131 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1132 ResultantDescriptor, DescriptorLength, ReturnLength);
1134 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1135 return FALSE;
1137 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1139 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1140 return FALSE;
1141 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1144 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1146 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1147 return FALSE;
1148 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1151 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1153 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1154 return FALSE;
1155 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1158 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1160 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1161 return FALSE;
1162 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1165 *ReturnLength = DescriptorLength;
1166 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1169 /******************************************************************************
1170 * GetSecurityDescriptorLength [ADVAPI32.@]
1172 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1174 return RtlLengthSecurityDescriptor(pDescr);
1177 /******************************************************************************
1178 * GetSecurityDescriptorOwner [ADVAPI32.@]
1180 * PARAMS
1181 * pOwner []
1182 * lpbOwnerDefaulted []
1184 BOOL WINAPI
1185 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1186 LPBOOL lpbOwnerDefaulted )
1188 BOOLEAN defaulted;
1189 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1190 *lpbOwnerDefaulted = defaulted;
1191 return ret;
1194 /******************************************************************************
1195 * SetSecurityDescriptorOwner [ADVAPI32.@]
1197 * PARAMS
1199 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1200 PSID pOwner, BOOL bOwnerDefaulted)
1202 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1204 /******************************************************************************
1205 * GetSecurityDescriptorGroup [ADVAPI32.@]
1207 BOOL WINAPI GetSecurityDescriptorGroup(
1208 PSECURITY_DESCRIPTOR SecurityDescriptor,
1209 PSID *Group,
1210 LPBOOL GroupDefaulted)
1212 BOOLEAN defaulted;
1213 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1214 *GroupDefaulted = defaulted;
1215 return ret;
1217 /******************************************************************************
1218 * SetSecurityDescriptorGroup [ADVAPI32.@]
1220 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1221 PSID Group, BOOL GroupDefaulted)
1223 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1226 /******************************************************************************
1227 * IsValidSecurityDescriptor [ADVAPI32.@]
1229 * PARAMS
1230 * lpsecdesc []
1232 BOOL WINAPI
1233 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1235 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1238 /******************************************************************************
1239 * GetSecurityDescriptorDacl [ADVAPI32.@]
1241 BOOL WINAPI GetSecurityDescriptorDacl(
1242 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1243 OUT LPBOOL lpbDaclPresent,
1244 OUT PACL *pDacl,
1245 OUT LPBOOL lpbDaclDefaulted)
1247 BOOLEAN present, defaulted;
1248 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1249 *lpbDaclPresent = present;
1250 *lpbDaclDefaulted = defaulted;
1251 return ret;
1254 /******************************************************************************
1255 * SetSecurityDescriptorDacl [ADVAPI32.@]
1257 BOOL WINAPI
1258 SetSecurityDescriptorDacl (
1259 PSECURITY_DESCRIPTOR lpsd,
1260 BOOL daclpresent,
1261 PACL dacl,
1262 BOOL dacldefaulted )
1264 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1266 /******************************************************************************
1267 * GetSecurityDescriptorSacl [ADVAPI32.@]
1269 BOOL WINAPI GetSecurityDescriptorSacl(
1270 IN PSECURITY_DESCRIPTOR lpsd,
1271 OUT LPBOOL lpbSaclPresent,
1272 OUT PACL *pSacl,
1273 OUT LPBOOL lpbSaclDefaulted)
1275 BOOLEAN present, defaulted;
1276 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1277 *lpbSaclPresent = present;
1278 *lpbSaclDefaulted = defaulted;
1279 return ret;
1282 /**************************************************************************
1283 * SetSecurityDescriptorSacl [ADVAPI32.@]
1285 BOOL WINAPI SetSecurityDescriptorSacl (
1286 PSECURITY_DESCRIPTOR lpsd,
1287 BOOL saclpresent,
1288 PACL lpsacl,
1289 BOOL sacldefaulted)
1291 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1293 /******************************************************************************
1294 * MakeSelfRelativeSD [ADVAPI32.@]
1296 * PARAMS
1297 * lpabssecdesc []
1298 * lpselfsecdesc []
1299 * lpbuflen []
1301 BOOL WINAPI
1302 MakeSelfRelativeSD(
1303 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1304 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1305 IN OUT LPDWORD lpdwBufferLength)
1307 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1308 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1311 /******************************************************************************
1312 * GetSecurityDescriptorControl [ADVAPI32.@]
1315 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1316 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1318 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1321 /* ##############################
1322 ###### ACL FUNCTIONS ######
1323 ##############################
1326 /*************************************************************************
1327 * InitializeAcl [ADVAPI32.@]
1329 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1331 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1334 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1336 IO_STATUS_BLOCK io_block;
1338 TRACE("(%p)\n", hNamedPipe);
1340 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1341 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1344 /******************************************************************************
1345 * AddAccessAllowedAce [ADVAPI32.@]
1347 BOOL WINAPI AddAccessAllowedAce(
1348 IN OUT PACL pAcl,
1349 IN DWORD dwAceRevision,
1350 IN DWORD AccessMask,
1351 IN PSID pSid)
1353 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1356 /******************************************************************************
1357 * AddAccessAllowedAceEx [ADVAPI32.@]
1359 BOOL WINAPI AddAccessAllowedAceEx(
1360 IN OUT PACL pAcl,
1361 IN DWORD dwAceRevision,
1362 IN DWORD AceFlags,
1363 IN DWORD AccessMask,
1364 IN PSID pSid)
1366 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1369 /******************************************************************************
1370 * AddAccessDeniedAce [ADVAPI32.@]
1372 BOOL WINAPI AddAccessDeniedAce(
1373 IN OUT PACL pAcl,
1374 IN DWORD dwAceRevision,
1375 IN DWORD AccessMask,
1376 IN PSID pSid)
1378 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1381 /******************************************************************************
1382 * AddAccessDeniedAceEx [ADVAPI32.@]
1384 BOOL WINAPI AddAccessDeniedAceEx(
1385 IN OUT PACL pAcl,
1386 IN DWORD dwAceRevision,
1387 IN DWORD AceFlags,
1388 IN DWORD AccessMask,
1389 IN PSID pSid)
1391 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1394 /******************************************************************************
1395 * AddAce [ADVAPI32.@]
1397 BOOL WINAPI AddAce(
1398 IN OUT PACL pAcl,
1399 IN DWORD dwAceRevision,
1400 IN DWORD dwStartingAceIndex,
1401 LPVOID pAceList,
1402 DWORD nAceListLength)
1404 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1407 /******************************************************************************
1408 * DeleteAce [ADVAPI32.@]
1410 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1412 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1415 /******************************************************************************
1416 * FindFirstFreeAce [ADVAPI32.@]
1418 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1420 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1423 /******************************************************************************
1424 * GetAce [ADVAPI32.@]
1426 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1428 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1431 /******************************************************************************
1432 * GetAclInformation [ADVAPI32.@]
1434 BOOL WINAPI GetAclInformation(
1435 PACL pAcl,
1436 LPVOID pAclInformation,
1437 DWORD nAclInformationLength,
1438 ACL_INFORMATION_CLASS dwAclInformationClass)
1440 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1441 nAclInformationLength, dwAclInformationClass));
1444 /******************************************************************************
1445 * IsValidAcl [ADVAPI32.@]
1447 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1449 return RtlValidAcl(pAcl);
1452 /* ##############################
1453 ###### MISC FUNCTIONS ######
1454 ##############################
1457 /******************************************************************************
1458 * AllocateLocallyUniqueId [ADVAPI32.@]
1460 * PARAMS
1461 * lpLuid []
1463 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1465 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1468 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1469 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1470 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1471 { '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 };
1472 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1473 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1474 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1475 { '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 };
1476 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1477 { '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 };
1478 static const WCHAR SE_TCB_NAME_W[] =
1479 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1480 static const WCHAR SE_SECURITY_NAME_W[] =
1481 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1482 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1483 { '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 };
1484 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1485 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1486 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1487 { '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 };
1488 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1489 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1490 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1491 { '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 };
1492 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1493 { '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 };
1494 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1495 { '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 };
1496 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1497 { '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 };
1498 static const WCHAR SE_BACKUP_NAME_W[] =
1499 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1500 static const WCHAR SE_RESTORE_NAME_W[] =
1501 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1502 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1503 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1504 static const WCHAR SE_DEBUG_NAME_W[] =
1505 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1506 static const WCHAR SE_AUDIT_NAME_W[] =
1507 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1508 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1509 { '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 };
1510 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1511 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1512 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1513 { '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 };
1514 static const WCHAR SE_UNDOCK_NAME_W[] =
1515 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1516 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1517 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1518 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1519 { '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 };
1520 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1521 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1522 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1523 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1524 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1525 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1527 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1529 NULL,
1530 NULL,
1531 SE_CREATE_TOKEN_NAME_W,
1532 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1533 SE_LOCK_MEMORY_NAME_W,
1534 SE_INCREASE_QUOTA_NAME_W,
1535 SE_MACHINE_ACCOUNT_NAME_W,
1536 SE_TCB_NAME_W,
1537 SE_SECURITY_NAME_W,
1538 SE_TAKE_OWNERSHIP_NAME_W,
1539 SE_LOAD_DRIVER_NAME_W,
1540 SE_SYSTEM_PROFILE_NAME_W,
1541 SE_SYSTEMTIME_NAME_W,
1542 SE_PROF_SINGLE_PROCESS_NAME_W,
1543 SE_INC_BASE_PRIORITY_NAME_W,
1544 SE_CREATE_PAGEFILE_NAME_W,
1545 SE_CREATE_PERMANENT_NAME_W,
1546 SE_BACKUP_NAME_W,
1547 SE_RESTORE_NAME_W,
1548 SE_SHUTDOWN_NAME_W,
1549 SE_DEBUG_NAME_W,
1550 SE_AUDIT_NAME_W,
1551 SE_SYSTEM_ENVIRONMENT_NAME_W,
1552 SE_CHANGE_NOTIFY_NAME_W,
1553 SE_REMOTE_SHUTDOWN_NAME_W,
1554 SE_UNDOCK_NAME_W,
1555 SE_SYNC_AGENT_NAME_W,
1556 SE_ENABLE_DELEGATION_NAME_W,
1557 SE_MANAGE_VOLUME_NAME_W,
1558 SE_IMPERSONATE_NAME_W,
1559 SE_CREATE_GLOBAL_NAME_W,
1562 /******************************************************************************
1563 * LookupPrivilegeValueW [ADVAPI32.@]
1565 * See LookupPrivilegeValueA.
1567 BOOL WINAPI
1568 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1570 UINT i;
1572 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1574 if (!ADVAPI_IsLocalComputer(lpSystemName))
1576 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1577 return FALSE;
1579 if (!lpName)
1581 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1582 return FALSE;
1584 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1586 if( !WellKnownPrivNames[i] )
1587 continue;
1588 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1589 continue;
1590 lpLuid->LowPart = i;
1591 lpLuid->HighPart = 0;
1592 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1593 lpLuid->HighPart, lpLuid->LowPart );
1594 return TRUE;
1596 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1597 return FALSE;
1600 /******************************************************************************
1601 * LookupPrivilegeValueA [ADVAPI32.@]
1603 * Retrieves LUID used on a system to represent the privilege name.
1605 * PARAMS
1606 * lpSystemName [I] Name of the system
1607 * lpName [I] Name of the privilege
1608 * lpLuid [O] Destination for the resulting LUID
1610 * RETURNS
1611 * Success: TRUE. lpLuid contains the requested LUID.
1612 * Failure: FALSE.
1614 BOOL WINAPI
1615 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1617 UNICODE_STRING lpSystemNameW;
1618 UNICODE_STRING lpNameW;
1619 BOOL ret;
1621 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1622 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1623 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1624 RtlFreeUnicodeString(&lpNameW);
1625 RtlFreeUnicodeString(&lpSystemNameW);
1626 return ret;
1629 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1630 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1632 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1633 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1635 return FALSE;
1638 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1639 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1641 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1642 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1644 return FALSE;
1647 /******************************************************************************
1648 * LookupPrivilegeNameA [ADVAPI32.@]
1650 * See LookupPrivilegeNameW.
1652 BOOL WINAPI
1653 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1654 LPDWORD cchName)
1656 UNICODE_STRING lpSystemNameW;
1657 BOOL ret;
1658 DWORD wLen = 0;
1660 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1662 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1663 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1664 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1666 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1668 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1669 &wLen);
1670 if (ret)
1672 /* Windows crashes if cchName is NULL, so will I */
1673 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1674 *cchName, NULL, NULL);
1676 if (len == 0)
1678 /* WideCharToMultiByte failed */
1679 ret = FALSE;
1681 else if (len > *cchName)
1683 *cchName = len;
1684 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1685 ret = FALSE;
1687 else
1689 /* WideCharToMultiByte succeeded, output length needs to be
1690 * length not including NULL terminator
1692 *cchName = len - 1;
1695 HeapFree(GetProcessHeap(), 0, lpNameW);
1697 RtlFreeUnicodeString(&lpSystemNameW);
1698 return ret;
1701 /******************************************************************************
1702 * LookupPrivilegeNameW [ADVAPI32.@]
1704 * Retrieves the privilege name referred to by the LUID lpLuid.
1706 * PARAMS
1707 * lpSystemName [I] Name of the system
1708 * lpLuid [I] Privilege value
1709 * lpName [O] Name of the privilege
1710 * cchName [I/O] Number of characters in lpName.
1712 * RETURNS
1713 * Success: TRUE. lpName contains the name of the privilege whose value is
1714 * *lpLuid.
1715 * Failure: FALSE.
1717 * REMARKS
1718 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1719 * using this function.
1720 * If the length of lpName is too small, on return *cchName will contain the
1721 * number of WCHARs needed to contain the privilege, including the NULL
1722 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1723 * On success, *cchName will contain the number of characters stored in
1724 * lpName, NOT including the NULL terminator.
1726 BOOL WINAPI
1727 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1728 LPDWORD cchName)
1730 size_t privNameLen;
1732 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1734 if (!ADVAPI_IsLocalComputer(lpSystemName))
1736 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1737 return FALSE;
1739 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1740 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1742 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1743 return FALSE;
1745 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1746 /* Windows crashes if cchName is NULL, so will I */
1747 if (*cchName <= privNameLen)
1749 *cchName = privNameLen + 1;
1750 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1751 return FALSE;
1753 else
1755 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1756 *cchName = privNameLen;
1757 return TRUE;
1761 /******************************************************************************
1762 * GetFileSecurityA [ADVAPI32.@]
1764 * Obtains Specified information about the security of a file or directory.
1766 * PARAMS
1767 * lpFileName [I] Name of the file to get info for
1768 * RequestedInformation [I] SE_ flags from "winnt.h"
1769 * pSecurityDescriptor [O] Destination for security information
1770 * nLength [I] Length of pSecurityDescriptor
1771 * lpnLengthNeeded [O] Destination for length of returned security information
1773 * RETURNS
1774 * Success: TRUE. pSecurityDescriptor contains the requested information.
1775 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1777 * NOTES
1778 * The information returned is constrained by the callers access rights and
1779 * privileges.
1781 BOOL WINAPI
1782 GetFileSecurityA( LPCSTR lpFileName,
1783 SECURITY_INFORMATION RequestedInformation,
1784 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1785 DWORD nLength, LPDWORD lpnLengthNeeded )
1787 DWORD len;
1788 BOOL r;
1789 LPWSTR name = NULL;
1791 if( lpFileName )
1793 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1794 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1795 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1798 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1799 nLength, lpnLengthNeeded );
1800 HeapFree( GetProcessHeap(), 0, name );
1802 return r;
1805 /******************************************************************************
1806 * GetFileSecurityW [ADVAPI32.@]
1808 * See GetFileSecurityA.
1810 BOOL WINAPI
1811 GetFileSecurityW( LPCWSTR lpFileName,
1812 SECURITY_INFORMATION RequestedInformation,
1813 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1814 DWORD nLength, LPDWORD lpnLengthNeeded )
1816 HANDLE hfile;
1817 NTSTATUS status;
1818 DWORD access = 0;
1820 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1821 DACL_SECURITY_INFORMATION))
1822 access |= READ_CONTROL;
1823 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1824 access |= ACCESS_SYSTEM_SECURITY;
1826 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1827 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1828 if ( hfile == INVALID_HANDLE_VALUE )
1829 return FALSE;
1831 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1832 nLength, lpnLengthNeeded );
1833 CloseHandle( hfile );
1834 return set_ntstatus( status );
1838 /******************************************************************************
1839 * LookupAccountSidA [ADVAPI32.@]
1841 BOOL WINAPI
1842 LookupAccountSidA(
1843 IN LPCSTR system,
1844 IN PSID sid,
1845 OUT LPSTR account,
1846 IN OUT LPDWORD accountSize,
1847 OUT LPSTR domain,
1848 IN OUT LPDWORD domainSize,
1849 OUT PSID_NAME_USE name_use )
1851 DWORD len;
1852 BOOL r;
1853 LPWSTR systemW = NULL;
1854 LPWSTR accountW = NULL;
1855 LPWSTR domainW = NULL;
1856 DWORD accountSizeW = *accountSize;
1857 DWORD domainSizeW = *domainSize;
1859 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1860 debugstr_a(system),debugstr_sid(sid),
1861 account,accountSize,accountSize?*accountSize:0,
1862 domain,domainSize,domainSize?*domainSize:0,
1863 name_use);
1865 if (system) {
1866 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1867 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1868 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1870 if (account)
1871 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1872 if (domain)
1873 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1875 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1877 if (r) {
1878 if (accountW && *accountSize) {
1879 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1880 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1881 *accountSize = len;
1882 } else
1883 *accountSize = accountSizeW + 1;
1885 if (domainW && *domainSize) {
1886 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1887 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1888 *domainSize = len;
1889 } else
1890 *domainSize = domainSizeW + 1;
1893 HeapFree( GetProcessHeap(), 0, systemW );
1894 HeapFree( GetProcessHeap(), 0, accountW );
1895 HeapFree( GetProcessHeap(), 0, domainW );
1897 return r;
1900 /******************************************************************************
1901 * LookupAccountSidW [ADVAPI32.@]
1903 * PARAMS
1904 * system []
1905 * sid []
1906 * account []
1907 * accountSize []
1908 * domain []
1909 * domainSize []
1910 * name_use []
1913 BOOL WINAPI
1914 LookupAccountSidW(
1915 IN LPCWSTR system,
1916 IN PSID sid,
1917 OUT LPWSTR account,
1918 IN OUT LPDWORD accountSize,
1919 OUT LPWSTR domain,
1920 IN OUT LPDWORD domainSize,
1921 OUT PSID_NAME_USE name_use )
1923 unsigned int i, j;
1924 const WCHAR * ac = NULL;
1925 const WCHAR * dm = NULL;
1926 SID_NAME_USE use = 0;
1927 LPWSTR computer_name = NULL;
1929 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1930 debugstr_w(system),debugstr_sid(sid),
1931 account,accountSize,accountSize?*accountSize:0,
1932 domain,domainSize,domainSize?*domainSize:0,
1933 name_use);
1935 if (!ADVAPI_IsLocalComputer(system)) {
1936 FIXME("Only local computer supported!\n");
1937 SetLastError(ERROR_NONE_MAPPED);
1938 return FALSE;
1941 /* check the well known SIDs first */
1942 for (i = 0; i <= 60; i++) {
1943 if (IsWellKnownSid(sid, i)) {
1944 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1945 if (ACCOUNT_SIDS[j].type == i) {
1946 ac = ACCOUNT_SIDS[j].account;
1947 dm = ACCOUNT_SIDS[j].domain;
1948 use = ACCOUNT_SIDS[j].name_use;
1951 break;
1955 if (dm == NULL) {
1956 MAX_SID local;
1958 /* check for the local computer next */
1959 if (ADVAPI_GetComputerSid(&local)) {
1960 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1961 BOOL result;
1963 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1964 result = GetComputerNameW(computer_name, &size);
1966 if (result) {
1967 if (EqualSid(sid, &local)) {
1968 dm = computer_name;
1969 ac = Blank;
1970 use = 3;
1971 } else {
1972 local.SubAuthorityCount++;
1974 if (EqualPrefixSid(sid, &local)) {
1975 dm = computer_name;
1976 use = 1;
1977 switch (((MAX_SID *)sid)->SubAuthority[4]) {
1978 case DOMAIN_USER_RID_ADMIN:
1979 ac = Administrator;
1980 break;
1981 case DOMAIN_USER_RID_GUEST:
1982 ac = Guest;
1983 break;
1984 case DOMAIN_GROUP_RID_ADMINS:
1985 ac = Domain_Admins;
1986 break;
1987 case DOMAIN_GROUP_RID_USERS:
1988 ac = Domain_Users;
1989 break;
1990 case DOMAIN_GROUP_RID_GUESTS:
1991 ac = Domain_Guests;
1992 break;
1993 case DOMAIN_GROUP_RID_COMPUTERS:
1994 ac = Domain_Computers;
1995 break;
1996 case DOMAIN_GROUP_RID_CONTROLLERS:
1997 ac = Domain_Controllers;
1998 break;
1999 case DOMAIN_GROUP_RID_CERT_ADMINS:
2000 ac = Cert_Publishers;
2001 break;
2002 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2003 ac = Schema_Admins;
2004 break;
2005 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2006 ac = Enterprise_Admins;
2007 break;
2008 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2009 ac = Group_Policy_Creator_Owners;
2010 break;
2011 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2012 ac = RAS_and_IAS_Servers;
2013 break;
2014 default:
2015 dm = NULL;
2016 break;
2024 if (dm) {
2025 BOOL status = TRUE;
2026 if (*accountSize > lstrlenW(ac)) {
2027 if (account)
2028 lstrcpyW(account, ac);
2030 if (*domainSize > lstrlenW(dm)) {
2031 if (domain)
2032 lstrcpyW(domain, dm);
2034 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2035 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2036 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2037 status = FALSE;
2039 if (*domainSize)
2040 *domainSize = strlenW(dm);
2041 else
2042 *domainSize = strlenW(dm) + 1;
2043 if (*accountSize)
2044 *accountSize = strlenW(ac);
2045 else
2046 *accountSize = strlenW(ac) + 1;
2047 *name_use = use;
2048 HeapFree(GetProcessHeap(), 0, computer_name);
2049 return status;
2052 HeapFree(GetProcessHeap(), 0, computer_name);
2053 SetLastError(ERROR_NONE_MAPPED);
2054 return FALSE;
2057 /******************************************************************************
2058 * SetFileSecurityA [ADVAPI32.@]
2060 * See SetFileSecurityW.
2062 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2063 SECURITY_INFORMATION RequestedInformation,
2064 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2066 DWORD len;
2067 BOOL r;
2068 LPWSTR name = NULL;
2070 if( lpFileName )
2072 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2073 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2074 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2077 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2078 HeapFree( GetProcessHeap(), 0, name );
2080 return r;
2083 /******************************************************************************
2084 * SetFileSecurityW [ADVAPI32.@]
2086 * Sets the security of a file or directory.
2088 * PARAMS
2089 * lpFileName []
2090 * RequestedInformation []
2091 * pSecurityDescriptor []
2093 * RETURNS
2094 * Success: TRUE.
2095 * Failure: FALSE.
2097 BOOL WINAPI
2098 SetFileSecurityW( LPCWSTR lpFileName,
2099 SECURITY_INFORMATION RequestedInformation,
2100 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2102 HANDLE file;
2103 DWORD access = 0;
2104 NTSTATUS status;
2106 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2107 pSecurityDescriptor );
2109 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2110 RequestedInformation & GROUP_SECURITY_INFORMATION)
2111 access |= WRITE_OWNER;
2112 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2113 access |= ACCESS_SYSTEM_SECURITY;
2114 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2115 access |= WRITE_DAC;
2117 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2118 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2119 if (file == INVALID_HANDLE_VALUE)
2120 return FALSE;
2122 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2123 CloseHandle( file );
2124 return set_ntstatus( status );
2127 /******************************************************************************
2128 * QueryWindows31FilesMigration [ADVAPI32.@]
2130 * PARAMS
2131 * x1 []
2133 BOOL WINAPI
2134 QueryWindows31FilesMigration( DWORD x1 )
2136 FIXME("(%d):stub\n",x1);
2137 return TRUE;
2140 /******************************************************************************
2141 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2143 * PARAMS
2144 * x1 []
2145 * x2 []
2146 * x3 []
2147 * x4 []
2149 BOOL WINAPI
2150 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2151 DWORD x4 )
2153 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2154 return TRUE;
2157 /******************************************************************************
2158 * NotifyBootConfigStatus [ADVAPI32.@]
2160 * PARAMS
2161 * x1 []
2163 BOOL WINAPI
2164 NotifyBootConfigStatus( BOOL x1 )
2166 FIXME("(0x%08d):stub\n",x1);
2167 return 1;
2170 /******************************************************************************
2171 * RevertToSelf [ADVAPI32.@]
2173 * Ends the impersonation of a user.
2175 * PARAMS
2176 * void []
2178 * RETURNS
2179 * Success: TRUE.
2180 * Failure: FALSE.
2182 BOOL WINAPI
2183 RevertToSelf( void )
2185 HANDLE Token = NULL;
2186 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2187 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2190 /******************************************************************************
2191 * ImpersonateSelf [ADVAPI32.@]
2193 * Makes an impersonation token that represents the process user and assigns
2194 * to the current thread.
2196 * PARAMS
2197 * ImpersonationLevel [I] Level at which to impersonate.
2199 * RETURNS
2200 * Success: TRUE.
2201 * Failure: FALSE.
2203 BOOL WINAPI
2204 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2206 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2209 /******************************************************************************
2210 * ImpersonateLoggedOnUser [ADVAPI32.@]
2212 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2214 DWORD size;
2215 NTSTATUS Status;
2216 HANDLE ImpersonationToken;
2217 TOKEN_TYPE Type;
2219 FIXME( "(%p)\n", hToken );
2221 if (!GetTokenInformation( hToken, TokenType, &Type,
2222 sizeof(TOKEN_TYPE), &size ))
2223 return FALSE;
2225 if (Type == TokenPrimary)
2227 OBJECT_ATTRIBUTES ObjectAttributes;
2229 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2231 Status = NtDuplicateToken( hToken,
2232 TOKEN_IMPERSONATE | TOKEN_QUERY,
2233 &ObjectAttributes,
2234 SecurityImpersonation,
2235 TokenImpersonation,
2236 &ImpersonationToken );
2237 if (Status != STATUS_SUCCESS)
2239 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2240 SetLastError( RtlNtStatusToDosError( Status ) );
2241 return FALSE;
2244 else
2245 ImpersonationToken = hToken;
2247 Status = NtSetInformationThread( GetCurrentThread(),
2248 ThreadImpersonationToken,
2249 &ImpersonationToken,
2250 sizeof(ImpersonationToken) );
2252 if (Type == TokenPrimary)
2253 NtClose( ImpersonationToken );
2255 if (Status != STATUS_SUCCESS)
2257 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2258 SetLastError( RtlNtStatusToDosError( Status ) );
2259 return FALSE;
2262 return TRUE;
2265 /******************************************************************************
2266 * AccessCheck [ADVAPI32.@]
2268 BOOL WINAPI
2269 AccessCheck(
2270 PSECURITY_DESCRIPTOR SecurityDescriptor,
2271 HANDLE ClientToken,
2272 DWORD DesiredAccess,
2273 PGENERIC_MAPPING GenericMapping,
2274 PPRIVILEGE_SET PrivilegeSet,
2275 LPDWORD PrivilegeSetLength,
2276 LPDWORD GrantedAccess,
2277 LPBOOL AccessStatus)
2279 NTSTATUS access_status;
2280 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2281 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2282 GrantedAccess, &access_status) );
2283 if (ret) *AccessStatus = set_ntstatus( access_status );
2284 return ret;
2288 /******************************************************************************
2289 * AccessCheckByType [ADVAPI32.@]
2291 BOOL WINAPI AccessCheckByType(
2292 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2293 PSID PrincipalSelfSid,
2294 HANDLE ClientToken,
2295 DWORD DesiredAccess,
2296 POBJECT_TYPE_LIST ObjectTypeList,
2297 DWORD ObjectTypeListLength,
2298 PGENERIC_MAPPING GenericMapping,
2299 PPRIVILEGE_SET PrivilegeSet,
2300 LPDWORD PrivilegeSetLength,
2301 LPDWORD GrantedAccess,
2302 LPBOOL AccessStatus)
2304 FIXME("stub\n");
2306 *AccessStatus = TRUE;
2308 return !*AccessStatus;
2311 /******************************************************************************
2312 * MapGenericMask [ADVAPI32.@]
2314 * Maps generic access rights into specific access rights according to the
2315 * supplied mapping.
2317 * PARAMS
2318 * AccessMask [I/O] Access rights.
2319 * GenericMapping [I] The mapping between generic and specific rights.
2321 * RETURNS
2322 * Nothing.
2324 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2326 RtlMapGenericMask( AccessMask, GenericMapping );
2329 /*************************************************************************
2330 * SetKernelObjectSecurity [ADVAPI32.@]
2332 BOOL WINAPI SetKernelObjectSecurity (
2333 IN HANDLE Handle,
2334 IN SECURITY_INFORMATION SecurityInformation,
2335 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2337 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2341 /******************************************************************************
2342 * AddAuditAccessAce [ADVAPI32.@]
2344 BOOL WINAPI AddAuditAccessAce(
2345 IN OUT PACL pAcl,
2346 IN DWORD dwAceRevision,
2347 IN DWORD dwAccessMask,
2348 IN PSID pSid,
2349 IN BOOL bAuditSuccess,
2350 IN BOOL bAuditFailure)
2352 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2353 bAuditSuccess, bAuditFailure) );
2356 /******************************************************************************
2357 * AddAuditAccessAce [ADVAPI32.@]
2359 BOOL WINAPI AddAuditAccessAceEx(
2360 IN OUT PACL pAcl,
2361 IN DWORD dwAceRevision,
2362 IN DWORD dwAceFlags,
2363 IN DWORD dwAccessMask,
2364 IN PSID pSid,
2365 IN BOOL bAuditSuccess,
2366 IN BOOL bAuditFailure)
2368 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2369 bAuditSuccess, bAuditFailure) );
2372 /******************************************************************************
2373 * LookupAccountNameA [ADVAPI32.@]
2375 BOOL WINAPI
2376 LookupAccountNameA(
2377 IN LPCSTR system,
2378 IN LPCSTR account,
2379 OUT PSID sid,
2380 OUT LPDWORD cbSid,
2381 LPSTR ReferencedDomainName,
2382 IN OUT LPDWORD cbReferencedDomainName,
2383 OUT PSID_NAME_USE name_use )
2385 BOOL ret;
2386 UNICODE_STRING lpSystemW;
2387 UNICODE_STRING lpAccountW;
2388 LPWSTR lpReferencedDomainNameW = NULL;
2390 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2391 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2393 if (ReferencedDomainName)
2394 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2396 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2397 cbReferencedDomainName, name_use);
2399 if (ret && lpReferencedDomainNameW)
2401 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2402 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2405 RtlFreeUnicodeString(&lpSystemW);
2406 RtlFreeUnicodeString(&lpAccountW);
2407 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2409 return ret;
2412 /******************************************************************************
2413 * LookupAccountNameW [ADVAPI32.@]
2415 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2416 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2417 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2419 /* Default implementation: Always return a default SID */
2420 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2421 BOOL ret;
2422 PSID pSid;
2423 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2425 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2426 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2428 ret = AllocateAndInitializeSid(&identifierAuthority,
2430 SECURITY_BUILTIN_DOMAIN_RID,
2431 DOMAIN_ALIAS_RID_ADMINS,
2432 0, 0, 0, 0, 0, 0,
2433 &pSid);
2435 if (!ret)
2436 return FALSE;
2438 if (!RtlValidSid(pSid))
2440 FreeSid(pSid);
2441 return FALSE;
2444 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2445 CopySid(*cbSid, Sid, pSid);
2446 if (*cbSid < GetLengthSid(pSid))
2448 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2449 ret = FALSE;
2451 *cbSid = GetLengthSid(pSid);
2453 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2454 strcpyW(ReferencedDomainName, dm);
2456 if (*cchReferencedDomainName <= strlenW(dm))
2458 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2459 ret = FALSE;
2462 *cchReferencedDomainName = strlenW(dm)+1;
2464 FreeSid(pSid);
2466 return ret;
2469 /******************************************************************************
2470 * PrivilegeCheck [ADVAPI32.@]
2472 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2474 BOOL ret;
2475 BOOLEAN Result;
2477 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2479 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2480 if (ret)
2481 *pfResult = Result;
2482 return ret;
2485 /******************************************************************************
2486 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2488 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2489 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2490 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2491 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2493 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2494 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2495 SecurityDescriptor, DesiredAccess, GenericMapping,
2496 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2497 return TRUE;
2500 /******************************************************************************
2501 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2503 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2504 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2505 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2506 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2508 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2509 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2510 SecurityDescriptor, DesiredAccess, GenericMapping,
2511 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2512 return TRUE;
2515 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2517 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2519 return TRUE;
2522 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2524 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2526 return TRUE;
2529 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2531 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2533 return TRUE;
2536 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2537 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2538 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2539 LPBOOL GenerateOnClose)
2541 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2542 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2543 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2544 GenerateOnClose);
2546 return TRUE;
2549 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2550 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2551 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2552 LPBOOL GenerateOnClose)
2554 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2555 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2556 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2557 GenerateOnClose);
2559 return TRUE;
2562 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2563 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2565 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2566 DesiredAccess, Privileges, AccessGranted);
2568 return TRUE;
2571 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2572 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2574 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2575 DesiredAccess, Privileges, AccessGranted);
2577 return TRUE;
2580 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2581 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2583 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2584 ClientToken, Privileges, AccessGranted);
2586 return TRUE;
2589 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2590 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2592 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2593 ClientToken, Privileges, AccessGranted);
2595 return TRUE;
2598 /******************************************************************************
2599 * GetSecurityInfo [ADVAPI32.@]
2601 DWORD WINAPI GetSecurityInfo(
2602 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2603 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2604 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2605 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2608 FIXME("stub!\n");
2609 return ERROR_BAD_PROVIDER;
2612 /******************************************************************************
2613 * GetSecurityInfoExW [ADVAPI32.@]
2615 DWORD WINAPI GetSecurityInfoExW(
2616 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2617 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2618 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2619 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2622 FIXME("stub!\n");
2623 return ERROR_BAD_PROVIDER;
2626 /******************************************************************************
2627 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2629 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2630 LPSTR pTrusteeName, DWORD AccessPermissions,
2631 ACCESS_MODE AccessMode, DWORD Inheritance )
2633 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2634 AccessPermissions, AccessMode, Inheritance);
2636 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2637 pExplicitAccess->grfAccessMode = AccessMode;
2638 pExplicitAccess->grfInheritance = Inheritance;
2640 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2641 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2642 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2643 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2644 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2647 /******************************************************************************
2648 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2650 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2651 LPWSTR pTrusteeName, DWORD AccessPermissions,
2652 ACCESS_MODE AccessMode, DWORD Inheritance )
2654 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2655 AccessPermissions, AccessMode, Inheritance);
2657 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2658 pExplicitAccess->grfAccessMode = AccessMode;
2659 pExplicitAccess->grfInheritance = Inheritance;
2661 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2662 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2663 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2664 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2665 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2668 /******************************************************************************
2669 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2671 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2672 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2673 LPSTR InheritedObjectTypeName, LPSTR Name )
2675 DWORD ObjectsPresent = 0;
2677 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2678 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2680 /* Fill the OBJECTS_AND_NAME structure */
2681 pObjName->ObjectType = ObjectType;
2682 if (ObjectTypeName != NULL)
2684 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2687 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2688 if (InheritedObjectTypeName != NULL)
2690 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2693 pObjName->ObjectsPresent = ObjectsPresent;
2694 pObjName->ptstrName = Name;
2696 /* Fill the TRUSTEE structure */
2697 pTrustee->pMultipleTrustee = NULL;
2698 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2699 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2700 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2701 pTrustee->ptstrName = (LPSTR)pObjName;
2704 /******************************************************************************
2705 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2707 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2708 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2709 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2711 DWORD ObjectsPresent = 0;
2713 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2714 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2716 /* Fill the OBJECTS_AND_NAME structure */
2717 pObjName->ObjectType = ObjectType;
2718 if (ObjectTypeName != NULL)
2720 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2723 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2724 if (InheritedObjectTypeName != NULL)
2726 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2729 pObjName->ObjectsPresent = ObjectsPresent;
2730 pObjName->ptstrName = Name;
2732 /* Fill the TRUSTEE structure */
2733 pTrustee->pMultipleTrustee = NULL;
2734 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2735 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2736 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2737 pTrustee->ptstrName = (LPWSTR)pObjName;
2740 /******************************************************************************
2741 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2743 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2744 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2746 DWORD ObjectsPresent = 0;
2748 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2750 /* Fill the OBJECTS_AND_SID structure */
2751 if (pObjectGuid != NULL)
2753 pObjSid->ObjectTypeGuid = *pObjectGuid;
2754 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2756 else
2758 ZeroMemory(&pObjSid->ObjectTypeGuid,
2759 sizeof(GUID));
2762 if (pInheritedObjectGuid != NULL)
2764 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2765 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2767 else
2769 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2770 sizeof(GUID));
2773 pObjSid->ObjectsPresent = ObjectsPresent;
2774 pObjSid->pSid = pSid;
2776 /* Fill the TRUSTEE structure */
2777 pTrustee->pMultipleTrustee = NULL;
2778 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2779 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2780 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2781 pTrustee->ptstrName = (LPSTR) pObjSid;
2784 /******************************************************************************
2785 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2787 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2788 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2790 DWORD ObjectsPresent = 0;
2792 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2794 /* Fill the OBJECTS_AND_SID structure */
2795 if (pObjectGuid != NULL)
2797 pObjSid->ObjectTypeGuid = *pObjectGuid;
2798 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2800 else
2802 ZeroMemory(&pObjSid->ObjectTypeGuid,
2803 sizeof(GUID));
2806 if (pInheritedObjectGuid != NULL)
2808 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2809 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2811 else
2813 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2814 sizeof(GUID));
2817 pObjSid->ObjectsPresent = ObjectsPresent;
2818 pObjSid->pSid = pSid;
2820 /* Fill the TRUSTEE structure */
2821 pTrustee->pMultipleTrustee = NULL;
2822 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2823 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2824 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2825 pTrustee->ptstrName = (LPWSTR) pObjSid;
2828 /******************************************************************************
2829 * BuildTrusteeWithSidA [ADVAPI32.@]
2831 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2833 TRACE("%p %p\n", pTrustee, pSid);
2835 pTrustee->pMultipleTrustee = NULL;
2836 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2837 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2838 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2839 pTrustee->ptstrName = (LPSTR) pSid;
2842 /******************************************************************************
2843 * BuildTrusteeWithSidW [ADVAPI32.@]
2845 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2847 TRACE("%p %p\n", pTrustee, pSid);
2849 pTrustee->pMultipleTrustee = NULL;
2850 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2851 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2852 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2853 pTrustee->ptstrName = (LPWSTR) pSid;
2856 /******************************************************************************
2857 * BuildTrusteeWithNameA [ADVAPI32.@]
2859 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2861 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2863 pTrustee->pMultipleTrustee = NULL;
2864 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2865 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2866 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2867 pTrustee->ptstrName = name;
2870 /******************************************************************************
2871 * BuildTrusteeWithNameW [ADVAPI32.@]
2873 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2875 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2877 pTrustee->pMultipleTrustee = NULL;
2878 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2879 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2880 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2881 pTrustee->ptstrName = name;
2884 /******************************************************************************
2885 * GetTrusteeFormA [ADVAPI32.@]
2887 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2889 TRACE("(%p)\n", pTrustee);
2891 if (!pTrustee)
2892 return TRUSTEE_BAD_FORM;
2894 return pTrustee->TrusteeForm;
2897 /******************************************************************************
2898 * GetTrusteeFormW [ADVAPI32.@]
2900 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2902 TRACE("(%p)\n", pTrustee);
2904 if (!pTrustee)
2905 return TRUSTEE_BAD_FORM;
2907 return pTrustee->TrusteeForm;
2910 /******************************************************************************
2911 * GetTrusteeNameA [ADVAPI32.@]
2913 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2915 TRACE("(%p)\n", pTrustee);
2917 if (!pTrustee)
2918 return NULL;
2920 return pTrustee->ptstrName;
2923 /******************************************************************************
2924 * GetTrusteeNameW [ADVAPI32.@]
2926 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2928 TRACE("(%p)\n", pTrustee);
2930 if (!pTrustee)
2931 return NULL;
2933 return pTrustee->ptstrName;
2936 /******************************************************************************
2937 * GetTrusteeTypeA [ADVAPI32.@]
2939 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2941 TRACE("(%p)\n", pTrustee);
2943 if (!pTrustee)
2944 return TRUSTEE_IS_UNKNOWN;
2946 return pTrustee->TrusteeType;
2949 /******************************************************************************
2950 * GetTrusteeTypeW [ADVAPI32.@]
2952 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
2954 TRACE("(%p)\n", pTrustee);
2956 if (!pTrustee)
2957 return TRUSTEE_IS_UNKNOWN;
2959 return pTrustee->TrusteeType;
2962 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2963 DWORD nAclInformationLength,
2964 ACL_INFORMATION_CLASS dwAclInformationClass )
2966 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
2967 nAclInformationLength, dwAclInformationClass);
2969 return TRUE;
2972 /******************************************************************************
2973 * SetEntriesInAclA [ADVAPI32.@]
2975 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2976 PACL OldAcl, PACL* NewAcl )
2978 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2979 *NewAcl = NULL;
2980 return ERROR_SUCCESS;
2983 /******************************************************************************
2984 * SetEntriesInAclW [ADVAPI32.@]
2986 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2987 PACL OldAcl, PACL* NewAcl )
2989 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2990 *NewAcl = NULL;
2991 return ERROR_SUCCESS;
2994 /******************************************************************************
2995 * SetNamedSecurityInfoA [ADVAPI32.@]
2997 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2998 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2999 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3001 DWORD len;
3002 LPWSTR wstr = NULL;
3003 DWORD r;
3005 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3006 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3008 if( pObjectName )
3010 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3011 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3012 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3015 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3016 psidGroup, pDacl, pSacl );
3018 HeapFree( GetProcessHeap(), 0, wstr );
3020 return r;
3023 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3024 PSECURITY_DESCRIPTOR ModificationDescriptor,
3025 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3026 PGENERIC_MAPPING GenericMapping,
3027 HANDLE Token )
3029 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3030 ObjectsSecurityDescriptor, GenericMapping, Token);
3032 return TRUE;
3035 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
3036 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
3037 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
3039 FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
3040 ControlBitsToSet);
3042 return TRUE;
3045 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3047 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3050 /******************************************************************************
3051 * AreAnyAccessesGranted [ADVAPI32.@]
3053 * Determines whether or not any of a set of specified access permissions have
3054 * been granted or not.
3056 * PARAMS
3057 * GrantedAccess [I] The permissions that have been granted.
3058 * DesiredAccess [I] The permissions that you want to have.
3060 * RETURNS
3061 * Nonzero if any of the permissions have been granted, zero if none of the
3062 * permissions have been granted.
3065 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3067 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3070 /******************************************************************************
3071 * SetNamedSecurityInfoW [ADVAPI32.@]
3073 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3074 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3075 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3077 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3078 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3079 return ERROR_SUCCESS;
3082 /******************************************************************************
3083 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3085 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3086 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3088 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3089 return ERROR_CALL_NOT_IMPLEMENTED;
3092 /******************************************************************************
3093 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3095 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3096 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3098 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3099 return ERROR_CALL_NOT_IMPLEMENTED;
3103 /******************************************************************************
3104 * ParseAclStringFlags
3106 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3108 DWORD flags = 0;
3109 LPCWSTR szAcl = *StringAcl;
3111 while (*szAcl != '(')
3113 if (*szAcl == 'P')
3115 flags |= SE_DACL_PROTECTED;
3117 else if (*szAcl == 'A')
3119 szAcl++;
3120 if (*szAcl == 'R')
3121 flags |= SE_DACL_AUTO_INHERIT_REQ;
3122 else if (*szAcl == 'I')
3123 flags |= SE_DACL_AUTO_INHERITED;
3125 szAcl++;
3128 *StringAcl = szAcl;
3129 return flags;
3132 /******************************************************************************
3133 * ParseAceStringType
3135 static const ACEFLAG AceType[] =
3137 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3138 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3139 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3140 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3142 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3143 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3144 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3145 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3147 { NULL, 0 },
3150 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3152 UINT len = 0;
3153 LPCWSTR szAcl = *StringAcl;
3154 const ACEFLAG *lpaf = AceType;
3156 while (lpaf->wstr &&
3157 (len = strlenW(lpaf->wstr)) &&
3158 strncmpW(lpaf->wstr, szAcl, len))
3159 lpaf++;
3161 if (!lpaf->wstr)
3162 return 0;
3164 *StringAcl += len;
3165 return lpaf->value;
3169 /******************************************************************************
3170 * ParseAceStringFlags
3172 static const ACEFLAG AceFlags[] =
3174 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3175 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3176 { SDDL_INHERITED, INHERITED_ACE },
3177 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3178 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3179 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3180 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3181 { NULL, 0 },
3184 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3186 UINT len = 0;
3187 BYTE flags = 0;
3188 LPCWSTR szAcl = *StringAcl;
3190 while (*szAcl != ';')
3192 const ACEFLAG *lpaf = AceFlags;
3194 while (lpaf->wstr &&
3195 (len = strlenW(lpaf->wstr)) &&
3196 strncmpW(lpaf->wstr, szAcl, len))
3197 lpaf++;
3199 if (!lpaf->wstr)
3200 return 0;
3202 flags |= lpaf->value;
3203 szAcl += len;
3206 *StringAcl = szAcl;
3207 return flags;
3211 /******************************************************************************
3212 * ParseAceStringRights
3214 static const ACEFLAG AceRights[] =
3216 { SDDL_GENERIC_ALL, GENERIC_ALL },
3217 { SDDL_GENERIC_READ, GENERIC_READ },
3218 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3219 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3221 { SDDL_READ_CONTROL, READ_CONTROL },
3222 { SDDL_STANDARD_DELETE, DELETE },
3223 { SDDL_WRITE_DAC, WRITE_DAC },
3224 { SDDL_WRITE_OWNER, WRITE_OWNER },
3226 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3227 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3228 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3229 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3230 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3231 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3232 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3233 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3234 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3236 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3237 { SDDL_FILE_READ, FILE_GENERIC_READ },
3238 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3239 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3241 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3242 { SDDL_KEY_READ, KEY_READ },
3243 { SDDL_KEY_WRITE, KEY_WRITE },
3244 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3245 { NULL, 0 },
3248 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3250 UINT len = 0;
3251 DWORD rights = 0;
3252 LPCWSTR szAcl = *StringAcl;
3254 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3256 LPCWSTR p = szAcl;
3258 while (*p && *p != ';')
3259 p++;
3261 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3263 rights = strtoulW(szAcl, NULL, 16);
3264 szAcl = p;
3266 else
3267 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3269 else
3271 while (*szAcl != ';')
3273 const ACEFLAG *lpaf = AceRights;
3275 while (lpaf->wstr &&
3276 (len = strlenW(lpaf->wstr)) &&
3277 strncmpW(lpaf->wstr, szAcl, len))
3279 lpaf++;
3282 if (!lpaf->wstr)
3283 return 0;
3285 rights |= lpaf->value;
3286 szAcl += len;
3290 *StringAcl = szAcl;
3291 return rights;
3295 /******************************************************************************
3296 * ParseStringAclToAcl
3298 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3300 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3301 PACL pAcl, LPDWORD cBytes)
3303 DWORD val;
3304 DWORD sidlen;
3305 DWORD length = sizeof(ACL);
3306 DWORD acesize = 0;
3307 DWORD acecount = 0;
3308 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3310 TRACE("%s\n", debugstr_w(StringAcl));
3312 if (!StringAcl)
3313 return FALSE;
3315 if (pAcl) /* pAce is only useful if we're setting values */
3316 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3318 /* Parse ACL flags */
3319 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3321 /* Parse ACE */
3322 while (*StringAcl == '(')
3324 StringAcl++;
3326 /* Parse ACE type */
3327 val = ParseAceStringType(&StringAcl);
3328 if (pAce)
3329 pAce->Header.AceType = (BYTE) val;
3330 if (*StringAcl != ';')
3331 goto lerr;
3332 StringAcl++;
3334 /* Parse ACE flags */
3335 val = ParseAceStringFlags(&StringAcl);
3336 if (pAce)
3337 pAce->Header.AceFlags = (BYTE) val;
3338 if (*StringAcl != ';')
3339 goto lerr;
3340 StringAcl++;
3342 /* Parse ACE rights */
3343 val = ParseAceStringRights(&StringAcl);
3344 if (pAce)
3345 pAce->Mask = val;
3346 if (*StringAcl != ';')
3347 goto lerr;
3348 StringAcl++;
3350 /* Parse ACE object guid */
3351 if (*StringAcl != ';')
3353 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3354 goto lerr;
3356 StringAcl++;
3358 /* Parse ACE inherit object guid */
3359 if (*StringAcl != ';')
3361 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3362 goto lerr;
3364 StringAcl++;
3366 /* Parse ACE account sid */
3367 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3369 while (*StringAcl && *StringAcl != ')')
3370 StringAcl++;
3373 if (*StringAcl != ')')
3374 goto lerr;
3375 StringAcl++;
3377 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3378 length += acesize;
3379 if (pAce)
3381 pAce->Header.AceSize = acesize;
3382 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3384 acecount++;
3387 *cBytes = length;
3389 if (length > 0xffff)
3391 ERR("ACL too large\n");
3392 goto lerr;
3395 if (pAcl)
3397 pAcl->AclRevision = ACL_REVISION;
3398 pAcl->Sbz1 = 0;
3399 pAcl->AclSize = length;
3400 pAcl->AceCount = acecount++;
3401 pAcl->Sbz2 = 0;
3403 return TRUE;
3405 lerr:
3406 WARN("Invalid ACE string format\n");
3407 return FALSE;
3411 /******************************************************************************
3412 * ParseStringSecurityDescriptorToSecurityDescriptor
3414 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3415 LPCWSTR StringSecurityDescriptor,
3416 SECURITY_DESCRIPTOR* SecurityDescriptor,
3417 LPDWORD cBytes)
3419 BOOL bret = FALSE;
3420 WCHAR toktype;
3421 WCHAR tok[MAX_PATH];
3422 LPCWSTR lptoken;
3423 LPBYTE lpNext = NULL;
3424 DWORD len;
3426 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3428 if (SecurityDescriptor)
3429 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3431 while (*StringSecurityDescriptor)
3433 toktype = *StringSecurityDescriptor;
3435 /* Expect char identifier followed by ':' */
3436 StringSecurityDescriptor++;
3437 if (*StringSecurityDescriptor != ':')
3439 SetLastError(ERROR_INVALID_PARAMETER);
3440 goto lend;
3442 StringSecurityDescriptor++;
3444 /* Extract token */
3445 lptoken = StringSecurityDescriptor;
3446 while (*lptoken && *lptoken != ':')
3447 lptoken++;
3449 if (*lptoken)
3450 lptoken--;
3452 len = lptoken - StringSecurityDescriptor;
3453 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3454 tok[len] = 0;
3456 switch (toktype)
3458 case 'O':
3460 DWORD bytes;
3462 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3463 goto lend;
3465 if (SecurityDescriptor)
3467 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3468 lpNext += bytes; /* Advance to next token */
3471 *cBytes += bytes;
3473 break;
3476 case 'G':
3478 DWORD bytes;
3480 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3481 goto lend;
3483 if (SecurityDescriptor)
3485 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3486 lpNext += bytes; /* Advance to next token */
3489 *cBytes += bytes;
3491 break;
3494 case 'D':
3496 DWORD flags;
3497 DWORD bytes;
3499 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3500 goto lend;
3502 if (SecurityDescriptor)
3504 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3505 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3506 lpNext += bytes; /* Advance to next token */
3509 *cBytes += bytes;
3511 break;
3514 case 'S':
3516 DWORD flags;
3517 DWORD bytes;
3519 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3520 goto lend;
3522 if (SecurityDescriptor)
3524 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3525 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3526 lpNext += bytes; /* Advance to next token */
3529 *cBytes += bytes;
3531 break;
3534 default:
3535 FIXME("Unknown token\n");
3536 SetLastError(ERROR_INVALID_PARAMETER);
3537 goto lend;
3540 StringSecurityDescriptor = lptoken;
3543 bret = TRUE;
3545 lend:
3546 return bret;
3549 /******************************************************************************
3550 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3552 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3553 LPCSTR StringSecurityDescriptor,
3554 DWORD StringSDRevision,
3555 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3556 PULONG SecurityDescriptorSize)
3558 UINT len;
3559 BOOL ret = FALSE;
3560 LPWSTR StringSecurityDescriptorW;
3562 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3563 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3565 if (StringSecurityDescriptorW)
3567 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3569 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3570 StringSDRevision, SecurityDescriptor,
3571 SecurityDescriptorSize);
3572 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3575 return ret;
3578 /******************************************************************************
3579 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3581 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3582 LPCWSTR StringSecurityDescriptor,
3583 DWORD StringSDRevision,
3584 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3585 PULONG SecurityDescriptorSize)
3587 DWORD cBytes;
3588 SECURITY_DESCRIPTOR* psd;
3589 BOOL bret = FALSE;
3591 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3593 if (GetVersion() & 0x80000000)
3595 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3596 goto lend;
3598 else if (StringSDRevision != SID_REVISION)
3600 SetLastError(ERROR_UNKNOWN_REVISION);
3601 goto lend;
3604 /* Compute security descriptor length */
3605 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3606 NULL, &cBytes))
3607 goto lend;
3609 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3610 GMEM_ZEROINIT, cBytes);
3611 if (!psd) goto lend;
3613 psd->Revision = SID_REVISION;
3614 psd->Control |= SE_SELF_RELATIVE;
3616 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3617 psd, &cBytes))
3619 LocalFree(psd);
3620 goto lend;
3623 if (SecurityDescriptorSize)
3624 *SecurityDescriptorSize = cBytes;
3626 bret = TRUE;
3628 lend:
3629 TRACE(" ret=%d\n", bret);
3630 return bret;
3633 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3635 if (cch == -1)
3636 cch = strlenW(string);
3638 if (plen)
3639 *plen += cch;
3641 if (pwptr)
3643 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3644 *pwptr += cch;
3648 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3650 DWORD i;
3651 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3652 WCHAR subauthfmt[] = { '-','%','u',0 };
3653 WCHAR buf[26];
3654 SID *pisid = psid;
3656 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3658 SetLastError(ERROR_INVALID_SID);
3659 return FALSE;
3662 if (pisid->IdentifierAuthority.Value[0] ||
3663 pisid->IdentifierAuthority.Value[1])
3665 FIXME("not matching MS' bugs\n");
3666 SetLastError(ERROR_INVALID_SID);
3667 return FALSE;
3670 sprintfW( buf, fmt, pisid->Revision,
3671 MAKELONG(
3672 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3673 pisid->IdentifierAuthority.Value[4] ),
3674 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3675 pisid->IdentifierAuthority.Value[2] )
3676 ) );
3677 DumpString(buf, -1, pwptr, plen);
3679 for( i=0; i<pisid->SubAuthorityCount; i++ )
3681 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3682 DumpString(buf, -1, pwptr, plen);
3684 return TRUE;
3687 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3689 int i;
3690 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3692 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3694 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3695 return TRUE;
3699 return DumpSidNumeric(psid, pwptr, plen);
3702 static const LPCWSTR AceRightBitNames[32] = {
3703 SDDL_CREATE_CHILD, /* 0 */
3704 SDDL_DELETE_CHILD,
3705 SDDL_LIST_CHILDREN,
3706 SDDL_SELF_WRITE,
3707 SDDL_READ_PROPERTY, /* 4 */
3708 SDDL_WRITE_PROPERTY,
3709 SDDL_DELETE_TREE,
3710 SDDL_LIST_OBJECT,
3711 SDDL_CONTROL_ACCESS, /* 8 */
3712 NULL,
3713 NULL,
3714 NULL,
3715 NULL, /* 12 */
3716 NULL,
3717 NULL,
3718 NULL,
3719 SDDL_STANDARD_DELETE, /* 16 */
3720 SDDL_READ_CONTROL,
3721 SDDL_WRITE_DAC,
3722 SDDL_WRITE_OWNER,
3723 NULL, /* 20 */
3724 NULL,
3725 NULL,
3726 NULL,
3727 NULL, /* 24 */
3728 NULL,
3729 NULL,
3730 NULL,
3731 SDDL_GENERIC_ALL, /* 28 */
3732 SDDL_GENERIC_EXECUTE,
3733 SDDL_GENERIC_WRITE,
3734 SDDL_GENERIC_READ
3737 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
3739 static const WCHAR fmtW[] = {'0','x','%','x',0};
3740 WCHAR buf[15];
3741 int i;
3743 if (mask == 0)
3744 return;
3746 /* first check if the right have name */
3747 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
3749 if (AceRights[i].wstr == NULL)
3750 break;
3751 if (mask == AceRights[i].value)
3753 DumpString(AceRights[i].wstr, -1, pwptr, plen);
3754 return;
3758 /* then check if it can be built from bit names */
3759 for (i = 0; i < 32; i++)
3761 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
3763 /* can't be built from bit names */
3764 sprintfW(buf, fmtW, mask);
3765 DumpString(buf, -1, pwptr, plen);
3766 return;
3770 /* build from bit names */
3771 for (i = 0; i < 32; i++)
3772 if (mask & (1 << i))
3773 DumpString(AceRightBitNames[i], -1, pwptr, plen);
3776 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
3778 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
3779 static const WCHAR openbr = '(';
3780 static const WCHAR closebr = ')';
3781 static const WCHAR semicolon = ';';
3783 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
3785 SetLastError(ERROR_INVALID_ACL);
3786 return FALSE;
3789 piace = (ACCESS_ALLOWED_ACE *)pace;
3790 DumpString(&openbr, 1, pwptr, plen);
3791 switch (piace->Header.AceType)
3793 case ACCESS_ALLOWED_ACE_TYPE:
3794 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
3795 break;
3796 case ACCESS_DENIED_ACE_TYPE:
3797 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
3798 break;
3799 case SYSTEM_AUDIT_ACE_TYPE:
3800 DumpString(SDDL_AUDIT, -1, pwptr, plen);
3801 break;
3802 case SYSTEM_ALARM_ACE_TYPE:
3803 DumpString(SDDL_ALARM, -1, pwptr, plen);
3804 break;
3806 DumpString(&semicolon, 1, pwptr, plen);
3808 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
3809 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
3810 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
3811 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
3812 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
3813 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
3814 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
3815 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
3816 if (piace->Header.AceFlags & INHERITED_ACE)
3817 DumpString(SDDL_INHERITED, -1, pwptr, plen);
3818 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
3819 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
3820 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
3821 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
3822 DumpString(&semicolon, 1, pwptr, plen);
3823 DumpRights(piace->Mask, pwptr, plen);
3824 DumpString(&semicolon, 1, pwptr, plen);
3825 /* objects not supported */
3826 DumpString(&semicolon, 1, pwptr, plen);
3827 /* objects not supported */
3828 DumpString(&semicolon, 1, pwptr, plen);
3829 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
3830 return FALSE;
3831 DumpString(&closebr, 1, pwptr, plen);
3832 return TRUE;
3835 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
3837 WORD count;
3838 int i;
3840 if (protected)
3841 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
3842 if (autoInheritReq)
3843 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3844 if (autoInherited)
3845 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3847 if (pacl == NULL)
3848 return TRUE;
3850 if (!IsValidAcl(pacl))
3851 return FALSE;
3853 count = pacl->AceCount;
3854 for (i = 0; i < count; i++)
3856 LPVOID ace;
3857 if (!GetAce(pacl, i, &ace))
3858 return FALSE;
3859 if (!DumpAce(ace, pwptr, plen))
3860 return FALSE;
3863 return TRUE;
3866 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3868 static const WCHAR prefix[] = {'O',':',0};
3869 BOOL bDefaulted;
3870 PSID psid;
3872 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3873 return FALSE;
3875 if (psid == NULL)
3876 return TRUE;
3878 DumpString(prefix, -1, pwptr, plen);
3879 if (!DumpSid(psid, pwptr, plen))
3880 return FALSE;
3881 return TRUE;
3884 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3886 static const WCHAR prefix[] = {'G',':',0};
3887 BOOL bDefaulted;
3888 PSID psid;
3890 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3891 return FALSE;
3893 if (psid == NULL)
3894 return TRUE;
3896 DumpString(prefix, -1, pwptr, plen);
3897 if (!DumpSid(psid, pwptr, plen))
3898 return FALSE;
3899 return TRUE;
3902 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3904 static const WCHAR dacl[] = {'D',':',0};
3905 SECURITY_DESCRIPTOR_CONTROL control;
3906 BOOL present, defaulted;
3907 DWORD revision;
3908 PACL pacl;
3910 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3911 return FALSE;
3913 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3914 return FALSE;
3916 if (!present)
3917 return TRUE;
3919 DumpString(dacl, 2, pwptr, plen);
3920 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3921 return FALSE;
3922 return TRUE;
3925 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3927 static const WCHAR sacl[] = {'S',':',0};
3928 SECURITY_DESCRIPTOR_CONTROL control;
3929 BOOL present, defaulted;
3930 DWORD revision;
3931 PACL pacl;
3933 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3934 return FALSE;
3936 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3937 return FALSE;
3939 if (!present)
3940 return TRUE;
3942 DumpString(sacl, 2, pwptr, plen);
3943 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3944 return FALSE;
3945 return TRUE;
3948 /******************************************************************************
3949 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3951 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
3953 ULONG len;
3954 WCHAR *wptr, *wstr;
3956 if (SDRevision != SDDL_REVISION_1)
3958 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
3959 SetLastError(ERROR_UNKNOWN_REVISION);
3960 return FALSE;
3963 len = 0;
3964 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3965 if (!DumpOwner(SecurityDescriptor, NULL, &len))
3966 return FALSE;
3967 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3968 if (!DumpGroup(SecurityDescriptor, NULL, &len))
3969 return FALSE;
3970 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3971 if (!DumpDacl(SecurityDescriptor, NULL, &len))
3972 return FALSE;
3973 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3974 if (!DumpSacl(SecurityDescriptor, NULL, &len))
3975 return FALSE;
3977 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
3978 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3979 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
3980 return FALSE;
3981 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3982 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
3983 return FALSE;
3984 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3985 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
3986 return FALSE;
3987 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3988 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
3989 return FALSE;
3990 *wptr = 0;
3992 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
3993 *OutputString = wstr;
3994 if (OutputLen)
3995 *OutputLen = strlenW(*OutputString)+1;
3996 return TRUE;
3999 /******************************************************************************
4000 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4002 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4004 LPWSTR wstr;
4005 ULONG len;
4006 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4008 int lenA;
4010 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4011 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4012 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4013 LocalFree(wstr);
4015 if (OutputLen != NULL)
4016 *OutputLen = lenA;
4017 return TRUE;
4019 else
4021 *OutputString = NULL;
4022 if (OutputLen)
4023 *OutputLen = 0;
4024 return FALSE;
4028 /******************************************************************************
4029 * ConvertStringSidToSidW [ADVAPI32.@]
4031 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4033 BOOL bret = FALSE;
4034 DWORD cBytes;
4036 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4037 if (GetVersion() & 0x80000000)
4038 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4039 else if (!StringSid || !Sid)
4040 SetLastError(ERROR_INVALID_PARAMETER);
4041 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4043 PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
4045 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4046 if (!bret)
4047 LocalFree(*Sid);
4049 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4050 return bret;
4053 /******************************************************************************
4054 * ConvertStringSidToSidA [ADVAPI32.@]
4056 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4058 BOOL bret = FALSE;
4060 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4061 if (GetVersion() & 0x80000000)
4062 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4063 else if (!StringSid || !Sid)
4064 SetLastError(ERROR_INVALID_PARAMETER);
4065 else
4067 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4068 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4069 len * sizeof(WCHAR));
4071 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4072 bret = ConvertStringSidToSidW(wStringSid, Sid);
4073 HeapFree(GetProcessHeap(), 0, wStringSid);
4075 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4076 return bret;
4079 /******************************************************************************
4080 * ConvertSidToStringSidW [ADVAPI32.@]
4082 * format of SID string is:
4083 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4084 * where
4085 * <rev> is the revision of the SID encoded as decimal
4086 * <auth> is the identifier authority encoded as hex
4087 * <subauthN> is the subauthority id encoded as decimal
4089 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4091 DWORD len = 0;
4092 LPWSTR wstr, wptr;
4094 TRACE("%p %p\n", pSid, pstr );
4096 len = 0;
4097 if (!DumpSidNumeric(pSid, NULL, &len))
4098 return FALSE;
4099 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4100 DumpSidNumeric(pSid, &wptr, NULL);
4101 *wptr = 0;
4103 *pstr = wstr;
4104 return TRUE;
4107 /******************************************************************************
4108 * ConvertSidToStringSidA [ADVAPI32.@]
4110 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4112 LPWSTR wstr = NULL;
4113 LPSTR str;
4114 UINT len;
4116 TRACE("%p %p\n", pSid, pstr );
4118 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4119 return FALSE;
4121 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4122 str = LocalAlloc( 0, len );
4123 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4124 LocalFree( wstr );
4126 *pstr = str;
4128 return TRUE;
4131 BOOL WINAPI CreatePrivateObjectSecurity(
4132 PSECURITY_DESCRIPTOR ParentDescriptor,
4133 PSECURITY_DESCRIPTOR CreatorDescriptor,
4134 PSECURITY_DESCRIPTOR* NewDescriptor,
4135 BOOL IsDirectoryObject,
4136 HANDLE Token,
4137 PGENERIC_MAPPING GenericMapping )
4139 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4140 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4142 return FALSE;
4145 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4147 FIXME("%p - stub\n", ObjectDescriptor);
4149 return TRUE;
4152 BOOL WINAPI CreateProcessAsUserA(
4153 HANDLE hToken,
4154 LPCSTR lpApplicationName,
4155 LPSTR lpCommandLine,
4156 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4157 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4158 BOOL bInheritHandles,
4159 DWORD dwCreationFlags,
4160 LPVOID lpEnvironment,
4161 LPCSTR lpCurrentDirectory,
4162 LPSTARTUPINFOA lpStartupInfo,
4163 LPPROCESS_INFORMATION lpProcessInformation )
4165 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4166 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4167 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4169 return FALSE;
4172 BOOL WINAPI CreateProcessAsUserW(
4173 HANDLE hToken,
4174 LPCWSTR lpApplicationName,
4175 LPWSTR lpCommandLine,
4176 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4177 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4178 BOOL bInheritHandles,
4179 DWORD dwCreationFlags,
4180 LPVOID lpEnvironment,
4181 LPCWSTR lpCurrentDirectory,
4182 LPSTARTUPINFOW lpStartupInfo,
4183 LPPROCESS_INFORMATION lpProcessInformation )
4185 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4186 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4187 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4188 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4190 /* We should create the process with a suspended main thread */
4191 if (!CreateProcessW (lpApplicationName,
4192 lpCommandLine,
4193 lpProcessAttributes,
4194 lpThreadAttributes,
4195 bInheritHandles,
4196 dwCreationFlags, /* CREATE_SUSPENDED */
4197 lpEnvironment,
4198 lpCurrentDirectory,
4199 lpStartupInfo,
4200 lpProcessInformation))
4202 return FALSE;
4205 return TRUE;
4208 /******************************************************************************
4209 * DuplicateTokenEx [ADVAPI32.@]
4211 BOOL WINAPI DuplicateTokenEx(
4212 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4213 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4214 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4215 TOKEN_TYPE TokenType,
4216 PHANDLE DuplicateTokenHandle )
4218 OBJECT_ATTRIBUTES ObjectAttributes;
4220 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4221 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4223 InitializeObjectAttributes(
4224 &ObjectAttributes,
4225 NULL,
4226 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4227 NULL,
4228 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4230 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4231 dwDesiredAccess,
4232 &ObjectAttributes,
4233 ImpersonationLevel,
4234 TokenType,
4235 DuplicateTokenHandle ) );
4238 BOOL WINAPI DuplicateToken(
4239 HANDLE ExistingTokenHandle,
4240 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4241 PHANDLE DuplicateTokenHandle )
4243 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4244 NULL, ImpersonationLevel, TokenImpersonation,
4245 DuplicateTokenHandle );
4248 BOOL WINAPI EnumDependentServicesA(
4249 SC_HANDLE hService,
4250 DWORD dwServiceState,
4251 LPENUM_SERVICE_STATUSA lpServices,
4252 DWORD cbBufSize,
4253 LPDWORD pcbBytesNeeded,
4254 LPDWORD lpServicesReturned )
4256 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4257 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4259 return FALSE;
4262 BOOL WINAPI EnumDependentServicesW(
4263 SC_HANDLE hService,
4264 DWORD dwServiceState,
4265 LPENUM_SERVICE_STATUSW lpServices,
4266 DWORD cbBufSize,
4267 LPDWORD pcbBytesNeeded,
4268 LPDWORD lpServicesReturned )
4270 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4271 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4273 return FALSE;
4276 /******************************************************************************
4277 * ComputeStringSidSize
4279 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4281 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4283 int ctok = 0;
4284 while (*StringSid)
4286 if (*StringSid == '-')
4287 ctok++;
4288 StringSid++;
4291 if (ctok >= 3)
4292 return GetSidLengthRequired(ctok - 2);
4294 else /* String constant format - Only available in winxp and above */
4296 unsigned int i;
4298 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4299 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4300 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4303 return GetSidLengthRequired(0);
4306 /******************************************************************************
4307 * ParseStringSidToSid
4309 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4311 BOOL bret = FALSE;
4312 SID* pisid=pSid;
4314 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4315 if (!StringSid)
4317 SetLastError(ERROR_INVALID_PARAMETER);
4318 TRACE("StringSid is NULL, returning FALSE\n");
4319 return FALSE;
4322 *cBytes = ComputeStringSidSize(StringSid);
4323 if (!pisid) /* Simply compute the size */
4325 TRACE("only size requested, returning TRUE\n");
4326 return TRUE;
4329 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4331 DWORD i = 0, identAuth;
4332 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4334 StringSid += 2; /* Advance to Revision */
4335 pisid->Revision = atoiW(StringSid);
4337 if (pisid->Revision != SDDL_REVISION)
4339 TRACE("Revision %d is unknown\n", pisid->Revision);
4340 goto lend; /* ERROR_INVALID_SID */
4342 if (csubauth == 0)
4344 TRACE("SubAuthorityCount is 0\n");
4345 goto lend; /* ERROR_INVALID_SID */
4348 pisid->SubAuthorityCount = csubauth;
4350 /* Advance to identifier authority */
4351 while (*StringSid && *StringSid != '-')
4352 StringSid++;
4353 if (*StringSid == '-')
4354 StringSid++;
4356 /* MS' implementation can't handle values greater than 2^32 - 1, so
4357 * we don't either; assume most significant bytes are always 0
4359 pisid->IdentifierAuthority.Value[0] = 0;
4360 pisid->IdentifierAuthority.Value[1] = 0;
4361 identAuth = atoiW(StringSid);
4362 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4363 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4364 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4365 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4367 /* Advance to first sub authority */
4368 while (*StringSid && *StringSid != '-')
4369 StringSid++;
4370 if (*StringSid == '-')
4371 StringSid++;
4373 while (*StringSid)
4375 pisid->SubAuthority[i++] = atoiW(StringSid);
4377 while (*StringSid && *StringSid != '-')
4378 StringSid++;
4379 if (*StringSid == '-')
4380 StringSid++;
4383 if (i != pisid->SubAuthorityCount)
4384 goto lend; /* ERROR_INVALID_SID */
4386 bret = TRUE;
4388 else /* String constant format - Only available in winxp and above */
4390 unsigned int i;
4391 pisid->Revision = SDDL_REVISION;
4393 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4394 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4396 DWORD j;
4397 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4398 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4399 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4400 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4401 bret = TRUE;
4404 if (!bret)
4405 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4408 lend:
4409 if (!bret)
4410 SetLastError(ERROR_INVALID_SID);
4412 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4413 return bret;
4416 /******************************************************************************
4417 * GetNamedSecurityInfoA [ADVAPI32.@]
4419 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4420 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4421 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4422 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4424 DWORD len;
4425 LPWSTR wstr = NULL;
4426 DWORD r;
4428 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4429 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4431 if( pObjectName )
4433 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4434 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4435 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4438 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4439 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4441 HeapFree( GetProcessHeap(), 0, wstr );
4443 return r;
4446 /******************************************************************************
4447 * GetNamedSecurityInfoW [ADVAPI32.@]
4449 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4450 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4451 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4453 DWORD needed, offset;
4454 SECURITY_DESCRIPTOR_RELATIVE *relative;
4455 BYTE *buffer;
4457 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4458 group, dacl, sacl, descriptor );
4460 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4462 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4463 if (info & OWNER_SECURITY_INFORMATION)
4464 needed += sizeof(sidWorld);
4465 if (info & GROUP_SECURITY_INFORMATION)
4466 needed += sizeof(sidWorld);
4467 if (info & DACL_SECURITY_INFORMATION)
4468 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4469 if (info & SACL_SECURITY_INFORMATION)
4470 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4472 /* must be freed by caller */
4473 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4474 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4476 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4478 HeapFree( GetProcessHeap(), 0, *descriptor );
4479 return ERROR_INVALID_SECURITY_DESCR;
4482 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4483 relative->Control |= SE_SELF_RELATIVE;
4484 buffer = (BYTE *)relative;
4485 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4487 if (info & OWNER_SECURITY_INFORMATION)
4489 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4490 relative->Owner = offset;
4491 if (owner)
4492 *owner = buffer + offset;
4493 offset += sizeof(sidWorld);
4495 if (info & GROUP_SECURITY_INFORMATION)
4497 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4498 relative->Group = offset;
4499 if (group)
4500 *group = buffer + offset;
4501 offset += sizeof(sidWorld);
4503 if (info & DACL_SECURITY_INFORMATION)
4505 relative->Control |= SE_DACL_PRESENT;
4506 GetWorldAccessACL( (PACL)(buffer + offset) );
4507 relative->Dacl = offset;
4508 if (dacl)
4509 *dacl = (PACL)(buffer + offset);
4510 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4512 if (info & SACL_SECURITY_INFORMATION)
4514 relative->Control |= SE_SACL_PRESENT;
4515 GetWorldAccessACL( (PACL)(buffer + offset) );
4516 relative->Sacl = offset;
4517 if (sacl)
4518 *sacl = (PACL)(buffer + offset);
4520 return ERROR_SUCCESS;
4523 /******************************************************************************
4524 * DecryptFileW [ADVAPI32.@]
4526 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4528 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4529 return TRUE;
4532 /******************************************************************************
4533 * DecryptFileA [ADVAPI32.@]
4535 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4537 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4538 return TRUE;
4541 /******************************************************************************
4542 * EncryptFileW [ADVAPI32.@]
4544 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4546 FIXME("%s\n", debugstr_w(lpFileName));
4547 return TRUE;
4550 /******************************************************************************
4551 * EncryptFileA [ADVAPI32.@]
4553 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4555 FIXME("%s\n", debugstr_a(lpFileName));
4556 return TRUE;
4559 /******************************************************************************
4560 * FileEncryptionStatusW [ADVAPI32.@]
4562 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4564 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4565 if (!lpStatus)
4566 return FALSE;
4567 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4568 return TRUE;
4571 /******************************************************************************
4572 * FileEncryptionStatusA [ADVAPI32.@]
4574 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4576 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4577 if (!lpStatus)
4578 return FALSE;
4579 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4580 return TRUE;
4583 /******************************************************************************
4584 * SetSecurityInfo [ADVAPI32.@]
4586 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4587 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4588 PSID psidGroup, PACL pDacl, PACL pSacl) {
4589 FIXME("stub\n");
4590 return ERROR_SUCCESS;