push 449d6a3aabb36101ab68dc5159ee54c4adc03034
[wine/hacks.git] / dlls / advapi32 / security.c
blob31ee263bdd029e9384cd20c6cd0c35fc3d9859a8
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 LPVOID NewState, DWORD BufferLength,
556 LPVOID 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 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1127 ResultantDescriptor, DescriptorLength, ReturnLength);
1129 return set_ntstatus( NtQuerySecurityObject(ObjectDescriptor, SecurityInformation,
1130 ResultantDescriptor, DescriptorLength, ReturnLength ));
1133 /******************************************************************************
1134 * GetSecurityDescriptorLength [ADVAPI32.@]
1136 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1138 return RtlLengthSecurityDescriptor(pDescr);
1141 /******************************************************************************
1142 * GetSecurityDescriptorOwner [ADVAPI32.@]
1144 * PARAMS
1145 * pOwner []
1146 * lpbOwnerDefaulted []
1148 BOOL WINAPI
1149 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1150 LPBOOL lpbOwnerDefaulted )
1152 BOOLEAN defaulted;
1153 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1154 *lpbOwnerDefaulted = defaulted;
1155 return ret;
1158 /******************************************************************************
1159 * SetSecurityDescriptorOwner [ADVAPI32.@]
1161 * PARAMS
1163 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1164 PSID pOwner, BOOL bOwnerDefaulted)
1166 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1168 /******************************************************************************
1169 * GetSecurityDescriptorGroup [ADVAPI32.@]
1171 BOOL WINAPI GetSecurityDescriptorGroup(
1172 PSECURITY_DESCRIPTOR SecurityDescriptor,
1173 PSID *Group,
1174 LPBOOL GroupDefaulted)
1176 BOOLEAN defaulted;
1177 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1178 *GroupDefaulted = defaulted;
1179 return ret;
1181 /******************************************************************************
1182 * SetSecurityDescriptorGroup [ADVAPI32.@]
1184 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1185 PSID Group, BOOL GroupDefaulted)
1187 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1190 /******************************************************************************
1191 * IsValidSecurityDescriptor [ADVAPI32.@]
1193 * PARAMS
1194 * lpsecdesc []
1196 BOOL WINAPI
1197 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1199 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1202 /******************************************************************************
1203 * GetSecurityDescriptorDacl [ADVAPI32.@]
1205 BOOL WINAPI GetSecurityDescriptorDacl(
1206 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1207 OUT LPBOOL lpbDaclPresent,
1208 OUT PACL *pDacl,
1209 OUT LPBOOL lpbDaclDefaulted)
1211 BOOLEAN present, defaulted;
1212 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1213 *lpbDaclPresent = present;
1214 *lpbDaclDefaulted = defaulted;
1215 return ret;
1218 /******************************************************************************
1219 * SetSecurityDescriptorDacl [ADVAPI32.@]
1221 BOOL WINAPI
1222 SetSecurityDescriptorDacl (
1223 PSECURITY_DESCRIPTOR lpsd,
1224 BOOL daclpresent,
1225 PACL dacl,
1226 BOOL dacldefaulted )
1228 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1230 /******************************************************************************
1231 * GetSecurityDescriptorSacl [ADVAPI32.@]
1233 BOOL WINAPI GetSecurityDescriptorSacl(
1234 IN PSECURITY_DESCRIPTOR lpsd,
1235 OUT LPBOOL lpbSaclPresent,
1236 OUT PACL *pSacl,
1237 OUT LPBOOL lpbSaclDefaulted)
1239 BOOLEAN present, defaulted;
1240 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1241 *lpbSaclPresent = present;
1242 *lpbSaclDefaulted = defaulted;
1243 return ret;
1246 /**************************************************************************
1247 * SetSecurityDescriptorSacl [ADVAPI32.@]
1249 BOOL WINAPI SetSecurityDescriptorSacl (
1250 PSECURITY_DESCRIPTOR lpsd,
1251 BOOL saclpresent,
1252 PACL lpsacl,
1253 BOOL sacldefaulted)
1255 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1257 /******************************************************************************
1258 * MakeSelfRelativeSD [ADVAPI32.@]
1260 * PARAMS
1261 * lpabssecdesc []
1262 * lpselfsecdesc []
1263 * lpbuflen []
1265 BOOL WINAPI
1266 MakeSelfRelativeSD(
1267 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1268 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1269 IN OUT LPDWORD lpdwBufferLength)
1271 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1272 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1275 /******************************************************************************
1276 * GetSecurityDescriptorControl [ADVAPI32.@]
1279 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1280 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1282 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1285 /* ##############################
1286 ###### ACL FUNCTIONS ######
1287 ##############################
1290 /*************************************************************************
1291 * InitializeAcl [ADVAPI32.@]
1293 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1295 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1298 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1300 IO_STATUS_BLOCK io_block;
1302 TRACE("(%p)\n", hNamedPipe);
1304 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1305 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1308 /******************************************************************************
1309 * AddAccessAllowedAce [ADVAPI32.@]
1311 BOOL WINAPI AddAccessAllowedAce(
1312 IN OUT PACL pAcl,
1313 IN DWORD dwAceRevision,
1314 IN DWORD AccessMask,
1315 IN PSID pSid)
1317 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1320 /******************************************************************************
1321 * AddAccessAllowedAceEx [ADVAPI32.@]
1323 BOOL WINAPI AddAccessAllowedAceEx(
1324 IN OUT PACL pAcl,
1325 IN DWORD dwAceRevision,
1326 IN DWORD AceFlags,
1327 IN DWORD AccessMask,
1328 IN PSID pSid)
1330 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1333 /******************************************************************************
1334 * AddAccessDeniedAce [ADVAPI32.@]
1336 BOOL WINAPI AddAccessDeniedAce(
1337 IN OUT PACL pAcl,
1338 IN DWORD dwAceRevision,
1339 IN DWORD AccessMask,
1340 IN PSID pSid)
1342 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1345 /******************************************************************************
1346 * AddAccessDeniedAceEx [ADVAPI32.@]
1348 BOOL WINAPI AddAccessDeniedAceEx(
1349 IN OUT PACL pAcl,
1350 IN DWORD dwAceRevision,
1351 IN DWORD AceFlags,
1352 IN DWORD AccessMask,
1353 IN PSID pSid)
1355 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1358 /******************************************************************************
1359 * AddAce [ADVAPI32.@]
1361 BOOL WINAPI AddAce(
1362 IN OUT PACL pAcl,
1363 IN DWORD dwAceRevision,
1364 IN DWORD dwStartingAceIndex,
1365 LPVOID pAceList,
1366 DWORD nAceListLength)
1368 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1371 /******************************************************************************
1372 * DeleteAce [ADVAPI32.@]
1374 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1376 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1379 /******************************************************************************
1380 * FindFirstFreeAce [ADVAPI32.@]
1382 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1384 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1387 /******************************************************************************
1388 * GetAce [ADVAPI32.@]
1390 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1392 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1395 /******************************************************************************
1396 * GetAclInformation [ADVAPI32.@]
1398 BOOL WINAPI GetAclInformation(
1399 PACL pAcl,
1400 LPVOID pAclInformation,
1401 DWORD nAclInformationLength,
1402 ACL_INFORMATION_CLASS dwAclInformationClass)
1404 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1405 nAclInformationLength, dwAclInformationClass));
1408 /******************************************************************************
1409 * IsValidAcl [ADVAPI32.@]
1411 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1413 return RtlValidAcl(pAcl);
1416 /* ##############################
1417 ###### MISC FUNCTIONS ######
1418 ##############################
1421 /******************************************************************************
1422 * AllocateLocallyUniqueId [ADVAPI32.@]
1424 * PARAMS
1425 * lpLuid []
1427 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1429 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1432 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1433 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1434 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1435 { '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 };
1436 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1437 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1438 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1439 { '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 };
1440 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1441 { '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 };
1442 static const WCHAR SE_TCB_NAME_W[] =
1443 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1444 static const WCHAR SE_SECURITY_NAME_W[] =
1445 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1446 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1447 { '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 };
1448 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1449 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1450 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1451 { '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 };
1452 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1453 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1454 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1455 { '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 };
1456 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1457 { '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 };
1458 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1459 { '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 };
1460 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1461 { '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 };
1462 static const WCHAR SE_BACKUP_NAME_W[] =
1463 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1464 static const WCHAR SE_RESTORE_NAME_W[] =
1465 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1466 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1467 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1468 static const WCHAR SE_DEBUG_NAME_W[] =
1469 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1470 static const WCHAR SE_AUDIT_NAME_W[] =
1471 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1472 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1473 { '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 };
1474 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1475 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1476 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1477 { '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 };
1478 static const WCHAR SE_UNDOCK_NAME_W[] =
1479 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1480 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1481 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1482 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1483 { '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 };
1484 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1485 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1486 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1487 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1488 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1489 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1491 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1493 NULL,
1494 NULL,
1495 SE_CREATE_TOKEN_NAME_W,
1496 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1497 SE_LOCK_MEMORY_NAME_W,
1498 SE_INCREASE_QUOTA_NAME_W,
1499 SE_MACHINE_ACCOUNT_NAME_W,
1500 SE_TCB_NAME_W,
1501 SE_SECURITY_NAME_W,
1502 SE_TAKE_OWNERSHIP_NAME_W,
1503 SE_LOAD_DRIVER_NAME_W,
1504 SE_SYSTEM_PROFILE_NAME_W,
1505 SE_SYSTEMTIME_NAME_W,
1506 SE_PROF_SINGLE_PROCESS_NAME_W,
1507 SE_INC_BASE_PRIORITY_NAME_W,
1508 SE_CREATE_PAGEFILE_NAME_W,
1509 SE_CREATE_PERMANENT_NAME_W,
1510 SE_BACKUP_NAME_W,
1511 SE_RESTORE_NAME_W,
1512 SE_SHUTDOWN_NAME_W,
1513 SE_DEBUG_NAME_W,
1514 SE_AUDIT_NAME_W,
1515 SE_SYSTEM_ENVIRONMENT_NAME_W,
1516 SE_CHANGE_NOTIFY_NAME_W,
1517 SE_REMOTE_SHUTDOWN_NAME_W,
1518 SE_UNDOCK_NAME_W,
1519 SE_SYNC_AGENT_NAME_W,
1520 SE_ENABLE_DELEGATION_NAME_W,
1521 SE_MANAGE_VOLUME_NAME_W,
1522 SE_IMPERSONATE_NAME_W,
1523 SE_CREATE_GLOBAL_NAME_W,
1526 /******************************************************************************
1527 * LookupPrivilegeValueW [ADVAPI32.@]
1529 * See LookupPrivilegeValueA.
1531 BOOL WINAPI
1532 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1534 UINT i;
1536 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1538 if (!ADVAPI_IsLocalComputer(lpSystemName))
1540 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1541 return FALSE;
1543 if (!lpName)
1545 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1546 return FALSE;
1548 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1550 if( !WellKnownPrivNames[i] )
1551 continue;
1552 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1553 continue;
1554 lpLuid->LowPart = i;
1555 lpLuid->HighPart = 0;
1556 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1557 lpLuid->HighPart, lpLuid->LowPart );
1558 return TRUE;
1560 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1561 return FALSE;
1564 /******************************************************************************
1565 * LookupPrivilegeValueA [ADVAPI32.@]
1567 * Retrieves LUID used on a system to represent the privilege name.
1569 * PARAMS
1570 * lpSystemName [I] Name of the system
1571 * lpName [I] Name of the privilege
1572 * lpLuid [O] Destination for the resulting LUID
1574 * RETURNS
1575 * Success: TRUE. lpLuid contains the requested LUID.
1576 * Failure: FALSE.
1578 BOOL WINAPI
1579 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1581 UNICODE_STRING lpSystemNameW;
1582 UNICODE_STRING lpNameW;
1583 BOOL ret;
1585 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1586 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1587 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1588 RtlFreeUnicodeString(&lpNameW);
1589 RtlFreeUnicodeString(&lpSystemNameW);
1590 return ret;
1593 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1594 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1596 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1597 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1599 return FALSE;
1602 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1603 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1605 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1606 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1608 return FALSE;
1611 /******************************************************************************
1612 * LookupPrivilegeNameA [ADVAPI32.@]
1614 * See LookupPrivilegeNameW.
1616 BOOL WINAPI
1617 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1618 LPDWORD cchName)
1620 UNICODE_STRING lpSystemNameW;
1621 BOOL ret;
1622 DWORD wLen = 0;
1624 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1626 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1627 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1628 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1630 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1632 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1633 &wLen);
1634 if (ret)
1636 /* Windows crashes if cchName is NULL, so will I */
1637 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1638 *cchName, NULL, NULL);
1640 if (len == 0)
1642 /* WideCharToMultiByte failed */
1643 ret = FALSE;
1645 else if (len > *cchName)
1647 *cchName = len;
1648 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1649 ret = FALSE;
1651 else
1653 /* WideCharToMultiByte succeeded, output length needs to be
1654 * length not including NULL terminator
1656 *cchName = len - 1;
1659 HeapFree(GetProcessHeap(), 0, lpNameW);
1661 RtlFreeUnicodeString(&lpSystemNameW);
1662 return ret;
1665 /******************************************************************************
1666 * LookupPrivilegeNameW [ADVAPI32.@]
1668 * Retrieves the privilege name referred to by the LUID lpLuid.
1670 * PARAMS
1671 * lpSystemName [I] Name of the system
1672 * lpLuid [I] Privilege value
1673 * lpName [O] Name of the privilege
1674 * cchName [I/O] Number of characters in lpName.
1676 * RETURNS
1677 * Success: TRUE. lpName contains the name of the privilege whose value is
1678 * *lpLuid.
1679 * Failure: FALSE.
1681 * REMARKS
1682 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1683 * using this function.
1684 * If the length of lpName is too small, on return *cchName will contain the
1685 * number of WCHARs needed to contain the privilege, including the NULL
1686 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1687 * On success, *cchName will contain the number of characters stored in
1688 * lpName, NOT including the NULL terminator.
1690 BOOL WINAPI
1691 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1692 LPDWORD cchName)
1694 size_t privNameLen;
1696 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1698 if (!ADVAPI_IsLocalComputer(lpSystemName))
1700 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1701 return FALSE;
1703 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1704 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1706 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1707 return FALSE;
1709 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1710 /* Windows crashes if cchName is NULL, so will I */
1711 if (*cchName <= privNameLen)
1713 *cchName = privNameLen + 1;
1714 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1715 return FALSE;
1717 else
1719 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1720 *cchName = privNameLen;
1721 return TRUE;
1725 /******************************************************************************
1726 * GetFileSecurityA [ADVAPI32.@]
1728 * Obtains Specified information about the security of a file or directory.
1730 * PARAMS
1731 * lpFileName [I] Name of the file to get info for
1732 * RequestedInformation [I] SE_ flags from "winnt.h"
1733 * pSecurityDescriptor [O] Destination for security information
1734 * nLength [I] Length of pSecurityDescriptor
1735 * lpnLengthNeeded [O] Destination for length of returned security information
1737 * RETURNS
1738 * Success: TRUE. pSecurityDescriptor contains the requested information.
1739 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1741 * NOTES
1742 * The information returned is constrained by the callers access rights and
1743 * privileges.
1745 BOOL WINAPI
1746 GetFileSecurityA( LPCSTR lpFileName,
1747 SECURITY_INFORMATION RequestedInformation,
1748 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1749 DWORD nLength, LPDWORD lpnLengthNeeded )
1751 DWORD len;
1752 BOOL r;
1753 LPWSTR name = NULL;
1755 if( lpFileName )
1757 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1758 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1759 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1762 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1763 nLength, lpnLengthNeeded );
1764 HeapFree( GetProcessHeap(), 0, name );
1766 return r;
1769 /******************************************************************************
1770 * GetFileSecurityW [ADVAPI32.@]
1772 * See GetFileSecurityA.
1774 BOOL WINAPI
1775 GetFileSecurityW( LPCWSTR lpFileName,
1776 SECURITY_INFORMATION RequestedInformation,
1777 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1778 DWORD nLength, LPDWORD lpnLengthNeeded )
1780 HANDLE hfile;
1781 NTSTATUS status;
1783 hfile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ,
1784 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1785 if ( hfile == INVALID_HANDLE_VALUE )
1786 return FALSE;
1788 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1789 nLength, lpnLengthNeeded );
1790 CloseHandle( hfile );
1791 return set_ntstatus( status );
1795 /******************************************************************************
1796 * LookupAccountSidA [ADVAPI32.@]
1798 BOOL WINAPI
1799 LookupAccountSidA(
1800 IN LPCSTR system,
1801 IN PSID sid,
1802 OUT LPSTR account,
1803 IN OUT LPDWORD accountSize,
1804 OUT LPSTR domain,
1805 IN OUT LPDWORD domainSize,
1806 OUT PSID_NAME_USE name_use )
1808 DWORD len;
1809 BOOL r;
1810 LPWSTR systemW = NULL;
1811 LPWSTR accountW = NULL;
1812 LPWSTR domainW = NULL;
1813 DWORD accountSizeW = *accountSize;
1814 DWORD domainSizeW = *domainSize;
1816 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1817 debugstr_a(system),debugstr_sid(sid),
1818 account,accountSize,accountSize?*accountSize:0,
1819 domain,domainSize,domainSize?*domainSize:0,
1820 name_use);
1822 if (system) {
1823 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1824 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1825 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1827 if (account)
1828 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1829 if (domain)
1830 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1832 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1834 if (r) {
1835 if (accountW && *accountSize) {
1836 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1837 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1838 *accountSize = len;
1839 } else
1840 *accountSize = accountSizeW + 1;
1842 if (domainW && *domainSize) {
1843 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1844 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1845 *domainSize = len;
1846 } else
1847 *domainSize = domainSizeW + 1;
1850 HeapFree( GetProcessHeap(), 0, systemW );
1851 HeapFree( GetProcessHeap(), 0, accountW );
1852 HeapFree( GetProcessHeap(), 0, domainW );
1854 return r;
1857 /******************************************************************************
1858 * LookupAccountSidW [ADVAPI32.@]
1860 * PARAMS
1861 * system []
1862 * sid []
1863 * account []
1864 * accountSize []
1865 * domain []
1866 * domainSize []
1867 * name_use []
1870 BOOL WINAPI
1871 LookupAccountSidW(
1872 IN LPCWSTR system,
1873 IN PSID sid,
1874 OUT LPWSTR account,
1875 IN OUT LPDWORD accountSize,
1876 OUT LPWSTR domain,
1877 IN OUT LPDWORD domainSize,
1878 OUT PSID_NAME_USE name_use )
1880 unsigned int i, j;
1881 const WCHAR * ac = NULL;
1882 const WCHAR * dm = NULL;
1883 SID_NAME_USE use = 0;
1884 LPWSTR computer_name = NULL;
1886 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1887 debugstr_w(system),debugstr_sid(sid),
1888 account,accountSize,accountSize?*accountSize:0,
1889 domain,domainSize,domainSize?*domainSize:0,
1890 name_use);
1892 if (!ADVAPI_IsLocalComputer(system)) {
1893 FIXME("Only local computer supported!\n");
1894 SetLastError(ERROR_NONE_MAPPED);
1895 return FALSE;
1898 /* check the well known SIDs first */
1899 for (i = 0; i <= 60; i++) {
1900 if (IsWellKnownSid(sid, i)) {
1901 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1902 if (ACCOUNT_SIDS[j].type == i) {
1903 ac = ACCOUNT_SIDS[j].account;
1904 dm = ACCOUNT_SIDS[j].domain;
1905 use = ACCOUNT_SIDS[j].name_use;
1908 break;
1912 if (dm == NULL) {
1913 MAX_SID local;
1915 /* check for the local computer next */
1916 if (ADVAPI_GetComputerSid(&local)) {
1917 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1918 BOOL result;
1920 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1921 result = GetComputerNameW(computer_name, &size);
1923 if (result) {
1924 if (EqualSid(sid, &local)) {
1925 dm = computer_name;
1926 ac = Blank;
1927 use = 3;
1928 } else {
1929 local.SubAuthorityCount++;
1931 if (EqualPrefixSid(sid, &local)) {
1932 dm = computer_name;
1933 use = 1;
1934 switch (((MAX_SID *)sid)->SubAuthority[4]) {
1935 case DOMAIN_USER_RID_ADMIN:
1936 ac = Administrator;
1937 break;
1938 case DOMAIN_USER_RID_GUEST:
1939 ac = Guest;
1940 break;
1941 case DOMAIN_GROUP_RID_ADMINS:
1942 ac = Domain_Admins;
1943 break;
1944 case DOMAIN_GROUP_RID_USERS:
1945 ac = Domain_Users;
1946 break;
1947 case DOMAIN_GROUP_RID_GUESTS:
1948 ac = Domain_Guests;
1949 break;
1950 case DOMAIN_GROUP_RID_COMPUTERS:
1951 ac = Domain_Computers;
1952 break;
1953 case DOMAIN_GROUP_RID_CONTROLLERS:
1954 ac = Domain_Controllers;
1955 break;
1956 case DOMAIN_GROUP_RID_CERT_ADMINS:
1957 ac = Cert_Publishers;
1958 break;
1959 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
1960 ac = Schema_Admins;
1961 break;
1962 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
1963 ac = Enterprise_Admins;
1964 break;
1965 case DOMAIN_GROUP_RID_POLICY_ADMINS:
1966 ac = Group_Policy_Creator_Owners;
1967 break;
1968 case DOMAIN_ALIAS_RID_RAS_SERVERS:
1969 ac = RAS_and_IAS_Servers;
1970 break;
1971 default:
1972 dm = NULL;
1973 break;
1981 if (dm) {
1982 BOOL status = TRUE;
1983 if (*accountSize > lstrlenW(ac)) {
1984 if (account)
1985 lstrcpyW(account, ac);
1987 if (*domainSize > lstrlenW(dm)) {
1988 if (domain)
1989 lstrcpyW(domain, dm);
1991 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
1992 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
1993 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1994 status = FALSE;
1996 if (*domainSize)
1997 *domainSize = strlenW(dm);
1998 else
1999 *domainSize = strlenW(dm) + 1;
2000 if (*accountSize)
2001 *accountSize = strlenW(ac);
2002 else
2003 *accountSize = strlenW(ac) + 1;
2004 *name_use = use;
2005 HeapFree(GetProcessHeap(), 0, computer_name);
2006 return status;
2009 HeapFree(GetProcessHeap(), 0, computer_name);
2010 SetLastError(ERROR_NONE_MAPPED);
2011 return FALSE;
2014 /******************************************************************************
2015 * SetFileSecurityA [ADVAPI32.@]
2017 * See SetFileSecurityW.
2019 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2020 SECURITY_INFORMATION RequestedInformation,
2021 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2023 DWORD len;
2024 BOOL r;
2025 LPWSTR name = NULL;
2027 if( lpFileName )
2029 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2030 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2031 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2034 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2035 HeapFree( GetProcessHeap(), 0, name );
2037 return r;
2040 /******************************************************************************
2041 * SetFileSecurityW [ADVAPI32.@]
2043 * Sets the security of a file or directory.
2045 * PARAMS
2046 * lpFileName []
2047 * RequestedInformation []
2048 * pSecurityDescriptor []
2050 * RETURNS
2051 * Success: TRUE.
2052 * Failure: FALSE.
2054 BOOL WINAPI
2055 SetFileSecurityW( LPCWSTR lpFileName,
2056 SECURITY_INFORMATION RequestedInformation,
2057 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2059 FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
2060 return TRUE;
2063 /******************************************************************************
2064 * QueryWindows31FilesMigration [ADVAPI32.@]
2066 * PARAMS
2067 * x1 []
2069 BOOL WINAPI
2070 QueryWindows31FilesMigration( DWORD x1 )
2072 FIXME("(%d):stub\n",x1);
2073 return TRUE;
2076 /******************************************************************************
2077 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2079 * PARAMS
2080 * x1 []
2081 * x2 []
2082 * x3 []
2083 * x4 []
2085 BOOL WINAPI
2086 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2087 DWORD x4 )
2089 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2090 return TRUE;
2093 /******************************************************************************
2094 * NotifyBootConfigStatus [ADVAPI32.@]
2096 * PARAMS
2097 * x1 []
2099 BOOL WINAPI
2100 NotifyBootConfigStatus( BOOL x1 )
2102 FIXME("(0x%08d):stub\n",x1);
2103 return 1;
2106 /******************************************************************************
2107 * RevertToSelf [ADVAPI32.@]
2109 * Ends the impersonation of a user.
2111 * PARAMS
2112 * void []
2114 * RETURNS
2115 * Success: TRUE.
2116 * Failure: FALSE.
2118 BOOL WINAPI
2119 RevertToSelf( void )
2121 HANDLE Token = NULL;
2122 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2123 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2126 /******************************************************************************
2127 * ImpersonateSelf [ADVAPI32.@]
2129 * Makes an impersonation token that represents the process user and assigns
2130 * to the current thread.
2132 * PARAMS
2133 * ImpersonationLevel [I] Level at which to impersonate.
2135 * RETURNS
2136 * Success: TRUE.
2137 * Failure: FALSE.
2139 BOOL WINAPI
2140 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2142 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2145 /******************************************************************************
2146 * ImpersonateLoggedOnUser [ADVAPI32.@]
2148 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2150 DWORD size;
2151 NTSTATUS Status;
2152 HANDLE ImpersonationToken;
2153 TOKEN_TYPE Type;
2155 FIXME( "(%p)\n", hToken );
2157 if (!GetTokenInformation( hToken, TokenType, &Type,
2158 sizeof(TOKEN_TYPE), &size ))
2159 return FALSE;
2161 if (Type == TokenPrimary)
2163 OBJECT_ATTRIBUTES ObjectAttributes;
2165 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2167 Status = NtDuplicateToken( hToken,
2168 TOKEN_IMPERSONATE | TOKEN_QUERY,
2169 &ObjectAttributes,
2170 SecurityImpersonation,
2171 TokenImpersonation,
2172 &ImpersonationToken );
2173 if (Status != STATUS_SUCCESS)
2175 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2176 SetLastError( RtlNtStatusToDosError( Status ) );
2177 return FALSE;
2180 else
2181 ImpersonationToken = hToken;
2183 Status = NtSetInformationThread( GetCurrentThread(),
2184 ThreadImpersonationToken,
2185 &ImpersonationToken,
2186 sizeof(ImpersonationToken) );
2188 if (Type == TokenPrimary)
2189 NtClose( ImpersonationToken );
2191 if (Status != STATUS_SUCCESS)
2193 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2194 SetLastError( RtlNtStatusToDosError( Status ) );
2195 return FALSE;
2198 return TRUE;
2201 /******************************************************************************
2202 * AccessCheck [ADVAPI32.@]
2204 BOOL WINAPI
2205 AccessCheck(
2206 PSECURITY_DESCRIPTOR SecurityDescriptor,
2207 HANDLE ClientToken,
2208 DWORD DesiredAccess,
2209 PGENERIC_MAPPING GenericMapping,
2210 PPRIVILEGE_SET PrivilegeSet,
2211 LPDWORD PrivilegeSetLength,
2212 LPDWORD GrantedAccess,
2213 LPBOOL AccessStatus)
2215 NTSTATUS access_status;
2216 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2217 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2218 GrantedAccess, &access_status) );
2219 if (ret) *AccessStatus = set_ntstatus( access_status );
2220 return ret;
2224 /******************************************************************************
2225 * AccessCheckByType [ADVAPI32.@]
2227 BOOL WINAPI AccessCheckByType(
2228 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2229 PSID PrincipalSelfSid,
2230 HANDLE ClientToken,
2231 DWORD DesiredAccess,
2232 POBJECT_TYPE_LIST ObjectTypeList,
2233 DWORD ObjectTypeListLength,
2234 PGENERIC_MAPPING GenericMapping,
2235 PPRIVILEGE_SET PrivilegeSet,
2236 LPDWORD PrivilegeSetLength,
2237 LPDWORD GrantedAccess,
2238 LPBOOL AccessStatus)
2240 FIXME("stub\n");
2242 *AccessStatus = TRUE;
2244 return !*AccessStatus;
2247 /******************************************************************************
2248 * MapGenericMask [ADVAPI32.@]
2250 * Maps generic access rights into specific access rights according to the
2251 * supplied mapping.
2253 * PARAMS
2254 * AccessMask [I/O] Access rights.
2255 * GenericMapping [I] The mapping between generic and specific rights.
2257 * RETURNS
2258 * Nothing.
2260 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2262 RtlMapGenericMask( AccessMask, GenericMapping );
2265 /*************************************************************************
2266 * SetKernelObjectSecurity [ADVAPI32.@]
2268 BOOL WINAPI SetKernelObjectSecurity (
2269 IN HANDLE Handle,
2270 IN SECURITY_INFORMATION SecurityInformation,
2271 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2273 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2277 /******************************************************************************
2278 * AddAuditAccessAce [ADVAPI32.@]
2280 BOOL WINAPI AddAuditAccessAce(
2281 IN OUT PACL pAcl,
2282 IN DWORD dwAceRevision,
2283 IN DWORD dwAccessMask,
2284 IN PSID pSid,
2285 IN BOOL bAuditSuccess,
2286 IN BOOL bAuditFailure)
2288 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2289 bAuditSuccess, bAuditFailure) );
2292 /******************************************************************************
2293 * AddAuditAccessAce [ADVAPI32.@]
2295 BOOL WINAPI AddAuditAccessAceEx(
2296 IN OUT PACL pAcl,
2297 IN DWORD dwAceRevision,
2298 IN DWORD dwAceFlags,
2299 IN DWORD dwAccessMask,
2300 IN PSID pSid,
2301 IN BOOL bAuditSuccess,
2302 IN BOOL bAuditFailure)
2304 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2305 bAuditSuccess, bAuditFailure) );
2308 /******************************************************************************
2309 * LookupAccountNameA [ADVAPI32.@]
2311 BOOL WINAPI
2312 LookupAccountNameA(
2313 IN LPCSTR system,
2314 IN LPCSTR account,
2315 OUT PSID sid,
2316 OUT LPDWORD cbSid,
2317 LPSTR ReferencedDomainName,
2318 IN OUT LPDWORD cbReferencedDomainName,
2319 OUT PSID_NAME_USE name_use )
2321 BOOL ret;
2322 UNICODE_STRING lpSystemW;
2323 UNICODE_STRING lpAccountW;
2324 LPWSTR lpReferencedDomainNameW = NULL;
2326 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2327 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2329 if (ReferencedDomainName)
2330 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2332 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2333 cbReferencedDomainName, name_use);
2335 if (ret && lpReferencedDomainNameW)
2337 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2338 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2341 RtlFreeUnicodeString(&lpSystemW);
2342 RtlFreeUnicodeString(&lpAccountW);
2343 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2345 return ret;
2348 /******************************************************************************
2349 * LookupAccountNameW [ADVAPI32.@]
2351 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2352 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2353 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2355 /* Default implementation: Always return a default SID */
2356 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2357 BOOL ret;
2358 PSID pSid;
2359 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2361 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2362 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2364 ret = AllocateAndInitializeSid(&identifierAuthority,
2366 SECURITY_BUILTIN_DOMAIN_RID,
2367 DOMAIN_ALIAS_RID_ADMINS,
2368 0, 0, 0, 0, 0, 0,
2369 &pSid);
2371 if (!ret)
2372 return FALSE;
2374 if (!RtlValidSid(pSid))
2376 FreeSid(pSid);
2377 return FALSE;
2380 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2381 CopySid(*cbSid, Sid, pSid);
2382 if (*cbSid < GetLengthSid(pSid))
2384 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2385 ret = FALSE;
2387 *cbSid = GetLengthSid(pSid);
2389 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2390 strcpyW(ReferencedDomainName, dm);
2392 if (*cchReferencedDomainName <= strlenW(dm))
2394 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2395 ret = FALSE;
2398 *cchReferencedDomainName = strlenW(dm)+1;
2400 FreeSid(pSid);
2402 return ret;
2405 /******************************************************************************
2406 * PrivilegeCheck [ADVAPI32.@]
2408 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2410 BOOL ret;
2411 BOOLEAN Result;
2413 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2415 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2416 if (ret)
2417 *pfResult = Result;
2418 return ret;
2421 /******************************************************************************
2422 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2424 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2425 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2426 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2427 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2429 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2430 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2431 SecurityDescriptor, DesiredAccess, GenericMapping,
2432 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2433 return TRUE;
2436 /******************************************************************************
2437 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2439 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2440 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2441 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2442 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2444 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2445 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2446 SecurityDescriptor, DesiredAccess, GenericMapping,
2447 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2448 return TRUE;
2451 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2453 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2455 return TRUE;
2458 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2460 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2462 return TRUE;
2465 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2467 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2469 return TRUE;
2472 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2473 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2474 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2475 LPBOOL GenerateOnClose)
2477 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2478 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2479 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2480 GenerateOnClose);
2482 return TRUE;
2485 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2486 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2487 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2488 LPBOOL GenerateOnClose)
2490 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2491 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2492 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2493 GenerateOnClose);
2495 return TRUE;
2498 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2499 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2501 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2502 DesiredAccess, Privileges, AccessGranted);
2504 return TRUE;
2507 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2508 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2510 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2511 DesiredAccess, Privileges, AccessGranted);
2513 return TRUE;
2516 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2517 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2519 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2520 ClientToken, Privileges, AccessGranted);
2522 return TRUE;
2525 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2526 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2528 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2529 ClientToken, Privileges, AccessGranted);
2531 return TRUE;
2534 /******************************************************************************
2535 * GetSecurityInfo [ADVAPI32.@]
2537 DWORD WINAPI GetSecurityInfo(
2538 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2539 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2540 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2541 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2544 FIXME("stub!\n");
2545 return ERROR_BAD_PROVIDER;
2548 /******************************************************************************
2549 * GetSecurityInfoExW [ADVAPI32.@]
2551 DWORD WINAPI GetSecurityInfoExW(
2552 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2553 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2554 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2555 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2558 FIXME("stub!\n");
2559 return ERROR_BAD_PROVIDER;
2562 /******************************************************************************
2563 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2565 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2566 LPSTR pTrusteeName, DWORD AccessPermissions,
2567 ACCESS_MODE AccessMode, DWORD Inheritance )
2569 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2570 AccessPermissions, AccessMode, Inheritance);
2572 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2573 pExplicitAccess->grfAccessMode = AccessMode;
2574 pExplicitAccess->grfInheritance = Inheritance;
2576 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2577 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2578 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2579 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2580 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2583 /******************************************************************************
2584 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2586 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2587 LPWSTR pTrusteeName, DWORD AccessPermissions,
2588 ACCESS_MODE AccessMode, DWORD Inheritance )
2590 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2591 AccessPermissions, AccessMode, Inheritance);
2593 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2594 pExplicitAccess->grfAccessMode = AccessMode;
2595 pExplicitAccess->grfInheritance = Inheritance;
2597 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2598 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2599 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2600 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2601 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2604 /******************************************************************************
2605 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2607 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2608 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2609 LPSTR InheritedObjectTypeName, LPSTR Name )
2611 DWORD ObjectsPresent = 0;
2613 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2614 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2616 /* Fill the OBJECTS_AND_NAME structure */
2617 pObjName->ObjectType = ObjectType;
2618 if (ObjectTypeName != NULL)
2620 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2623 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2624 if (InheritedObjectTypeName != NULL)
2626 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2629 pObjName->ObjectsPresent = ObjectsPresent;
2630 pObjName->ptstrName = Name;
2632 /* Fill the TRUSTEE structure */
2633 pTrustee->pMultipleTrustee = NULL;
2634 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2635 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2636 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2637 pTrustee->ptstrName = (LPSTR)pObjName;
2640 /******************************************************************************
2641 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2643 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2644 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2645 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2647 DWORD ObjectsPresent = 0;
2649 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2650 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2652 /* Fill the OBJECTS_AND_NAME structure */
2653 pObjName->ObjectType = ObjectType;
2654 if (ObjectTypeName != NULL)
2656 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2659 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2660 if (InheritedObjectTypeName != NULL)
2662 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2665 pObjName->ObjectsPresent = ObjectsPresent;
2666 pObjName->ptstrName = Name;
2668 /* Fill the TRUSTEE structure */
2669 pTrustee->pMultipleTrustee = NULL;
2670 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2671 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2672 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2673 pTrustee->ptstrName = (LPWSTR)pObjName;
2676 /******************************************************************************
2677 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2679 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2680 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2682 DWORD ObjectsPresent = 0;
2684 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2686 /* Fill the OBJECTS_AND_SID structure */
2687 if (pObjectGuid != NULL)
2689 pObjSid->ObjectTypeGuid = *pObjectGuid;
2690 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2692 else
2694 ZeroMemory(&pObjSid->ObjectTypeGuid,
2695 sizeof(GUID));
2698 if (pInheritedObjectGuid != NULL)
2700 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2701 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2703 else
2705 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2706 sizeof(GUID));
2709 pObjSid->ObjectsPresent = ObjectsPresent;
2710 pObjSid->pSid = pSid;
2712 /* Fill the TRUSTEE structure */
2713 pTrustee->pMultipleTrustee = NULL;
2714 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2715 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2716 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2717 pTrustee->ptstrName = (LPSTR) pObjSid;
2720 /******************************************************************************
2721 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2723 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2724 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2726 DWORD ObjectsPresent = 0;
2728 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2730 /* Fill the OBJECTS_AND_SID structure */
2731 if (pObjectGuid != NULL)
2733 pObjSid->ObjectTypeGuid = *pObjectGuid;
2734 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2736 else
2738 ZeroMemory(&pObjSid->ObjectTypeGuid,
2739 sizeof(GUID));
2742 if (pInheritedObjectGuid != NULL)
2744 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2745 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2747 else
2749 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2750 sizeof(GUID));
2753 pObjSid->ObjectsPresent = ObjectsPresent;
2754 pObjSid->pSid = pSid;
2756 /* Fill the TRUSTEE structure */
2757 pTrustee->pMultipleTrustee = NULL;
2758 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2759 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2760 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2761 pTrustee->ptstrName = (LPWSTR) pObjSid;
2764 /******************************************************************************
2765 * BuildTrusteeWithSidA [ADVAPI32.@]
2767 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2769 TRACE("%p %p\n", pTrustee, pSid);
2771 pTrustee->pMultipleTrustee = NULL;
2772 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2773 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2774 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2775 pTrustee->ptstrName = (LPSTR) pSid;
2778 /******************************************************************************
2779 * BuildTrusteeWithSidW [ADVAPI32.@]
2781 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2783 TRACE("%p %p\n", pTrustee, pSid);
2785 pTrustee->pMultipleTrustee = NULL;
2786 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2787 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2788 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2789 pTrustee->ptstrName = (LPWSTR) pSid;
2792 /******************************************************************************
2793 * BuildTrusteeWithNameA [ADVAPI32.@]
2795 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2797 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2799 pTrustee->pMultipleTrustee = NULL;
2800 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2801 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2802 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2803 pTrustee->ptstrName = name;
2806 /******************************************************************************
2807 * BuildTrusteeWithNameW [ADVAPI32.@]
2809 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2811 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2813 pTrustee->pMultipleTrustee = NULL;
2814 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2815 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2816 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2817 pTrustee->ptstrName = name;
2820 /******************************************************************************
2821 * GetTrusteeFormA [ADVAPI32.@]
2823 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2825 TRACE("(%p)\n", pTrustee);
2827 if (!pTrustee)
2828 return TRUSTEE_BAD_FORM;
2830 return pTrustee->TrusteeForm;
2833 /******************************************************************************
2834 * GetTrusteeFormW [ADVAPI32.@]
2836 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2838 TRACE("(%p)\n", pTrustee);
2840 if (!pTrustee)
2841 return TRUSTEE_BAD_FORM;
2843 return pTrustee->TrusteeForm;
2846 /******************************************************************************
2847 * GetTrusteeNameA [ADVAPI32.@]
2849 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2851 TRACE("(%p)\n", pTrustee);
2853 if (!pTrustee)
2854 return NULL;
2856 return pTrustee->ptstrName;
2859 /******************************************************************************
2860 * GetTrusteeNameW [ADVAPI32.@]
2862 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2864 TRACE("(%p)\n", pTrustee);
2866 if (!pTrustee)
2867 return NULL;
2869 return pTrustee->ptstrName;
2872 /******************************************************************************
2873 * GetTrusteeTypeA [ADVAPI32.@]
2875 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2877 TRACE("(%p)\n", pTrustee);
2879 if (!pTrustee)
2880 return TRUSTEE_IS_UNKNOWN;
2882 return pTrustee->TrusteeType;
2885 /******************************************************************************
2886 * GetTrusteeTypeW [ADVAPI32.@]
2888 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
2890 TRACE("(%p)\n", pTrustee);
2892 if (!pTrustee)
2893 return TRUSTEE_IS_UNKNOWN;
2895 return pTrustee->TrusteeType;
2898 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2899 DWORD nAclInformationLength,
2900 ACL_INFORMATION_CLASS dwAclInformationClass )
2902 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
2903 nAclInformationLength, dwAclInformationClass);
2905 return TRUE;
2908 /******************************************************************************
2909 * SetEntriesInAclA [ADVAPI32.@]
2911 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2912 PACL OldAcl, PACL* NewAcl )
2914 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2915 *NewAcl = NULL;
2916 return ERROR_SUCCESS;
2919 /******************************************************************************
2920 * SetEntriesInAclW [ADVAPI32.@]
2922 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2923 PACL OldAcl, PACL* NewAcl )
2925 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2926 *NewAcl = NULL;
2927 return ERROR_SUCCESS;
2930 /******************************************************************************
2931 * SetNamedSecurityInfoA [ADVAPI32.@]
2933 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2934 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2935 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2937 DWORD len;
2938 LPWSTR wstr = NULL;
2939 DWORD r;
2941 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2942 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2944 if( pObjectName )
2946 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2947 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2948 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2951 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2952 psidGroup, pDacl, pSacl );
2954 HeapFree( GetProcessHeap(), 0, wstr );
2956 return r;
2959 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2960 PSECURITY_DESCRIPTOR ModificationDescriptor,
2961 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2962 PGENERIC_MAPPING GenericMapping,
2963 HANDLE Token )
2965 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2966 ObjectsSecurityDescriptor, GenericMapping, Token);
2968 return TRUE;
2971 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2972 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2973 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2975 FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2976 ControlBitsToSet);
2978 return TRUE;
2981 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2983 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2986 /******************************************************************************
2987 * AreAnyAccessesGranted [ADVAPI32.@]
2989 * Determines whether or not any of a set of specified access permissions have
2990 * been granted or not.
2992 * PARAMS
2993 * GrantedAccess [I] The permissions that have been granted.
2994 * DesiredAccess [I] The permissions that you want to have.
2996 * RETURNS
2997 * Nonzero if any of the permissions have been granted, zero if none of the
2998 * permissions have been granted.
3001 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3003 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3006 /******************************************************************************
3007 * SetNamedSecurityInfoW [ADVAPI32.@]
3009 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3010 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3011 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3013 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3014 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3015 return ERROR_SUCCESS;
3018 /******************************************************************************
3019 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3021 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3022 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3024 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3025 return ERROR_CALL_NOT_IMPLEMENTED;
3028 /******************************************************************************
3029 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3031 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3032 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3034 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3035 return ERROR_CALL_NOT_IMPLEMENTED;
3039 /******************************************************************************
3040 * ParseAclStringFlags
3042 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3044 DWORD flags = 0;
3045 LPCWSTR szAcl = *StringAcl;
3047 while (*szAcl != '(')
3049 if (*szAcl == 'P')
3051 flags |= SE_DACL_PROTECTED;
3053 else if (*szAcl == 'A')
3055 szAcl++;
3056 if (*szAcl == 'R')
3057 flags |= SE_DACL_AUTO_INHERIT_REQ;
3058 else if (*szAcl == 'I')
3059 flags |= SE_DACL_AUTO_INHERITED;
3061 szAcl++;
3064 *StringAcl = szAcl;
3065 return flags;
3068 /******************************************************************************
3069 * ParseAceStringType
3071 static const ACEFLAG AceType[] =
3073 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3074 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3075 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3076 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3078 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3079 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3080 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3081 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3083 { NULL, 0 },
3086 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3088 UINT len = 0;
3089 LPCWSTR szAcl = *StringAcl;
3090 const ACEFLAG *lpaf = AceType;
3092 while (lpaf->wstr &&
3093 (len = strlenW(lpaf->wstr)) &&
3094 strncmpW(lpaf->wstr, szAcl, len))
3095 lpaf++;
3097 if (!lpaf->wstr)
3098 return 0;
3100 *StringAcl += len;
3101 return lpaf->value;
3105 /******************************************************************************
3106 * ParseAceStringFlags
3108 static const ACEFLAG AceFlags[] =
3110 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3111 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3112 { SDDL_INHERITED, INHERITED_ACE },
3113 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3114 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3115 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3116 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3117 { NULL, 0 },
3120 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3122 UINT len = 0;
3123 BYTE flags = 0;
3124 LPCWSTR szAcl = *StringAcl;
3126 while (*szAcl != ';')
3128 const ACEFLAG *lpaf = AceFlags;
3130 while (lpaf->wstr &&
3131 (len = strlenW(lpaf->wstr)) &&
3132 strncmpW(lpaf->wstr, szAcl, len))
3133 lpaf++;
3135 if (!lpaf->wstr)
3136 return 0;
3138 flags |= lpaf->value;
3139 szAcl += len;
3142 *StringAcl = szAcl;
3143 return flags;
3147 /******************************************************************************
3148 * ParseAceStringRights
3150 static const ACEFLAG AceRights[] =
3152 { SDDL_GENERIC_ALL, GENERIC_ALL },
3153 { SDDL_GENERIC_READ, GENERIC_READ },
3154 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3155 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3157 { SDDL_READ_CONTROL, READ_CONTROL },
3158 { SDDL_STANDARD_DELETE, DELETE },
3159 { SDDL_WRITE_DAC, WRITE_DAC },
3160 { SDDL_WRITE_OWNER, WRITE_OWNER },
3162 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3163 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3164 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3165 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3166 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3167 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3168 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3169 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3170 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3172 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3173 { SDDL_FILE_READ, FILE_GENERIC_READ },
3174 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3175 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3177 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3178 { SDDL_KEY_READ, KEY_READ },
3179 { SDDL_KEY_WRITE, KEY_WRITE },
3180 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3181 { NULL, 0 },
3184 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3186 UINT len = 0;
3187 DWORD rights = 0;
3188 LPCWSTR szAcl = *StringAcl;
3190 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3192 LPCWSTR p = szAcl;
3194 while (*p && *p != ';')
3195 p++;
3197 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3199 rights = strtoulW(szAcl, NULL, 16);
3200 szAcl = p;
3202 else
3203 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3205 else
3207 while (*szAcl != ';')
3209 const ACEFLAG *lpaf = AceRights;
3211 while (lpaf->wstr &&
3212 (len = strlenW(lpaf->wstr)) &&
3213 strncmpW(lpaf->wstr, szAcl, len))
3215 lpaf++;
3218 if (!lpaf->wstr)
3219 return 0;
3221 rights |= lpaf->value;
3222 szAcl += len;
3226 *StringAcl = szAcl;
3227 return rights;
3231 /******************************************************************************
3232 * ParseStringAclToAcl
3234 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3236 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3237 PACL pAcl, LPDWORD cBytes)
3239 DWORD val;
3240 DWORD sidlen;
3241 DWORD length = sizeof(ACL);
3242 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3244 TRACE("%s\n", debugstr_w(StringAcl));
3246 if (!StringAcl)
3247 return FALSE;
3249 if (pAcl) /* pAce is only useful if we're setting values */
3250 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3252 /* Parse ACL flags */
3253 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3255 /* Parse ACE */
3256 while (*StringAcl == '(')
3258 StringAcl++;
3260 /* Parse ACE type */
3261 val = ParseAceStringType(&StringAcl);
3262 if (pAce)
3263 pAce->Header.AceType = (BYTE) val;
3264 if (*StringAcl != ';')
3265 goto lerr;
3266 StringAcl++;
3268 /* Parse ACE flags */
3269 val = ParseAceStringFlags(&StringAcl);
3270 if (pAce)
3271 pAce->Header.AceFlags = (BYTE) val;
3272 if (*StringAcl != ';')
3273 goto lerr;
3274 StringAcl++;
3276 /* Parse ACE rights */
3277 val = ParseAceStringRights(&StringAcl);
3278 if (pAce)
3279 pAce->Mask = val;
3280 if (*StringAcl != ';')
3281 goto lerr;
3282 StringAcl++;
3284 /* Parse ACE object guid */
3285 if (*StringAcl != ';')
3287 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3288 goto lerr;
3290 StringAcl++;
3292 /* Parse ACE inherit object guid */
3293 if (*StringAcl != ';')
3295 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3296 goto lerr;
3298 StringAcl++;
3300 /* Parse ACE account sid */
3301 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3303 while (*StringAcl && *StringAcl != ')')
3304 StringAcl++;
3307 if (*StringAcl != ')')
3308 goto lerr;
3309 StringAcl++;
3311 length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3314 *cBytes = length;
3315 return TRUE;
3317 lerr:
3318 WARN("Invalid ACE string format\n");
3319 return FALSE;
3323 /******************************************************************************
3324 * ParseStringSecurityDescriptorToSecurityDescriptor
3326 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3327 LPCWSTR StringSecurityDescriptor,
3328 SECURITY_DESCRIPTOR* SecurityDescriptor,
3329 LPDWORD cBytes)
3331 BOOL bret = FALSE;
3332 WCHAR toktype;
3333 WCHAR tok[MAX_PATH];
3334 LPCWSTR lptoken;
3335 LPBYTE lpNext = NULL;
3336 DWORD len;
3338 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3340 if (SecurityDescriptor)
3341 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3343 while (*StringSecurityDescriptor)
3345 toktype = *StringSecurityDescriptor;
3347 /* Expect char identifier followed by ':' */
3348 StringSecurityDescriptor++;
3349 if (*StringSecurityDescriptor != ':')
3351 SetLastError(ERROR_INVALID_PARAMETER);
3352 goto lend;
3354 StringSecurityDescriptor++;
3356 /* Extract token */
3357 lptoken = StringSecurityDescriptor;
3358 while (*lptoken && *lptoken != ':')
3359 lptoken++;
3361 if (*lptoken)
3362 lptoken--;
3364 len = lptoken - StringSecurityDescriptor;
3365 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3366 tok[len] = 0;
3368 switch (toktype)
3370 case 'O':
3372 DWORD bytes;
3374 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3375 goto lend;
3377 if (SecurityDescriptor)
3379 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3380 lpNext += bytes; /* Advance to next token */
3383 *cBytes += bytes;
3385 break;
3388 case 'G':
3390 DWORD bytes;
3392 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3393 goto lend;
3395 if (SecurityDescriptor)
3397 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3398 lpNext += bytes; /* Advance to next token */
3401 *cBytes += bytes;
3403 break;
3406 case 'D':
3408 DWORD flags;
3409 DWORD bytes;
3411 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3412 goto lend;
3414 if (SecurityDescriptor)
3416 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3417 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3418 lpNext += bytes; /* Advance to next token */
3421 *cBytes += bytes;
3423 break;
3426 case 'S':
3428 DWORD flags;
3429 DWORD bytes;
3431 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3432 goto lend;
3434 if (SecurityDescriptor)
3436 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3437 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3438 lpNext += bytes; /* Advance to next token */
3441 *cBytes += bytes;
3443 break;
3446 default:
3447 FIXME("Unknown token\n");
3448 SetLastError(ERROR_INVALID_PARAMETER);
3449 goto lend;
3452 StringSecurityDescriptor = lptoken;
3455 bret = TRUE;
3457 lend:
3458 return bret;
3461 /******************************************************************************
3462 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3464 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3465 LPCSTR StringSecurityDescriptor,
3466 DWORD StringSDRevision,
3467 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3468 PULONG SecurityDescriptorSize)
3470 UINT len;
3471 BOOL ret = FALSE;
3472 LPWSTR StringSecurityDescriptorW;
3474 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3475 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3477 if (StringSecurityDescriptorW)
3479 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3481 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3482 StringSDRevision, SecurityDescriptor,
3483 SecurityDescriptorSize);
3484 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3487 return ret;
3490 /******************************************************************************
3491 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3493 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3494 LPCWSTR StringSecurityDescriptor,
3495 DWORD StringSDRevision,
3496 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3497 PULONG SecurityDescriptorSize)
3499 DWORD cBytes;
3500 SECURITY_DESCRIPTOR* psd;
3501 BOOL bret = FALSE;
3503 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3505 if (GetVersion() & 0x80000000)
3507 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3508 goto lend;
3510 else if (StringSDRevision != SID_REVISION)
3512 SetLastError(ERROR_UNKNOWN_REVISION);
3513 goto lend;
3516 /* Compute security descriptor length */
3517 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3518 NULL, &cBytes))
3519 goto lend;
3521 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3522 GMEM_ZEROINIT, cBytes);
3523 if (!psd) goto lend;
3525 psd->Revision = SID_REVISION;
3526 psd->Control |= SE_SELF_RELATIVE;
3528 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3529 psd, &cBytes))
3531 LocalFree(psd);
3532 goto lend;
3535 if (SecurityDescriptorSize)
3536 *SecurityDescriptorSize = cBytes;
3538 bret = TRUE;
3540 lend:
3541 TRACE(" ret=%d\n", bret);
3542 return bret;
3545 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3547 if (cch == -1)
3548 cch = strlenW(string);
3550 if (plen)
3551 *plen += cch;
3553 if (pwptr)
3555 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3556 *pwptr += cch;
3560 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3562 DWORD i;
3563 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3564 WCHAR subauthfmt[] = { '-','%','u',0 };
3565 WCHAR buf[26];
3566 SID *pisid = psid;
3568 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3570 SetLastError(ERROR_INVALID_SID);
3571 return FALSE;
3574 if (pisid->IdentifierAuthority.Value[0] ||
3575 pisid->IdentifierAuthority.Value[1])
3577 FIXME("not matching MS' bugs\n");
3578 SetLastError(ERROR_INVALID_SID);
3579 return FALSE;
3582 sprintfW( buf, fmt, pisid->Revision,
3583 MAKELONG(
3584 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3585 pisid->IdentifierAuthority.Value[4] ),
3586 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3587 pisid->IdentifierAuthority.Value[2] )
3588 ) );
3589 DumpString(buf, -1, pwptr, plen);
3591 for( i=0; i<pisid->SubAuthorityCount; i++ )
3593 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3594 DumpString(buf, -1, pwptr, plen);
3596 return TRUE;
3599 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3601 int i;
3602 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3604 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3606 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3607 return TRUE;
3611 return DumpSidNumeric(psid, pwptr, plen);
3614 static const LPCWSTR AceRightBitNames[32] = {
3615 SDDL_CREATE_CHILD, /* 0 */
3616 SDDL_DELETE_CHILD,
3617 SDDL_LIST_CHILDREN,
3618 SDDL_SELF_WRITE,
3619 SDDL_READ_PROPERTY, /* 4 */
3620 SDDL_WRITE_PROPERTY,
3621 SDDL_DELETE_TREE,
3622 SDDL_LIST_OBJECT,
3623 SDDL_CONTROL_ACCESS, /* 8 */
3624 NULL,
3625 NULL,
3626 NULL,
3627 NULL, /* 12 */
3628 NULL,
3629 NULL,
3630 NULL,
3631 SDDL_STANDARD_DELETE, /* 16 */
3632 SDDL_READ_CONTROL,
3633 SDDL_WRITE_DAC,
3634 SDDL_WRITE_OWNER,
3635 NULL, /* 20 */
3636 NULL,
3637 NULL,
3638 NULL,
3639 NULL, /* 24 */
3640 NULL,
3641 NULL,
3642 NULL,
3643 SDDL_GENERIC_ALL, /* 28 */
3644 SDDL_GENERIC_EXECUTE,
3645 SDDL_GENERIC_WRITE,
3646 SDDL_GENERIC_READ
3649 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
3651 static const WCHAR fmtW[] = {'0','x','%','x',0};
3652 WCHAR buf[15];
3653 int i;
3655 if (mask == 0)
3656 return;
3658 /* first check if the right have name */
3659 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
3661 if (AceRights[i].wstr == NULL)
3662 break;
3663 if (mask == AceRights[i].value)
3665 DumpString(AceRights[i].wstr, -1, pwptr, plen);
3666 return;
3670 /* then check if it can be built from bit names */
3671 for (i = 0; i < 32; i++)
3673 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
3675 /* can't be built from bit names */
3676 sprintfW(buf, fmtW, mask);
3677 DumpString(buf, -1, pwptr, plen);
3678 return;
3682 /* build from bit names */
3683 for (i = 0; i < 32; i++)
3684 if (mask & (1 << i))
3685 DumpString(AceRightBitNames[i], -1, pwptr, plen);
3688 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
3690 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
3691 static const WCHAR openbr = '(';
3692 static const WCHAR closebr = ')';
3693 static const WCHAR semicolon = ';';
3695 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
3697 SetLastError(ERROR_INVALID_ACL);
3698 return FALSE;
3701 piace = (ACCESS_ALLOWED_ACE *)pace;
3702 DumpString(&openbr, 1, pwptr, plen);
3703 switch (piace->Header.AceType)
3705 case ACCESS_ALLOWED_ACE_TYPE:
3706 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
3707 break;
3708 case ACCESS_DENIED_ACE_TYPE:
3709 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
3710 break;
3711 case SYSTEM_AUDIT_ACE_TYPE:
3712 DumpString(SDDL_AUDIT, -1, pwptr, plen);
3713 break;
3714 case SYSTEM_ALARM_ACE_TYPE:
3715 DumpString(SDDL_ALARM, -1, pwptr, plen);
3716 break;
3718 DumpString(&semicolon, 1, pwptr, plen);
3720 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
3721 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
3722 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
3723 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
3724 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
3725 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
3726 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
3727 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
3728 if (piace->Header.AceFlags & INHERITED_ACE)
3729 DumpString(SDDL_INHERITED, -1, pwptr, plen);
3730 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
3731 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
3732 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
3733 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
3734 DumpString(&semicolon, 1, pwptr, plen);
3735 DumpRights(piace->Mask, pwptr, plen);
3736 DumpString(&semicolon, 1, pwptr, plen);
3737 /* objects not supported */
3738 DumpString(&semicolon, 1, pwptr, plen);
3739 /* objects not supported */
3740 DumpString(&semicolon, 1, pwptr, plen);
3741 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
3742 return FALSE;
3743 DumpString(&closebr, 1, pwptr, plen);
3744 return TRUE;
3747 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
3749 WORD count;
3750 int i;
3752 if (protected)
3753 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
3754 if (autoInheritReq)
3755 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3756 if (autoInherited)
3757 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3759 if (pacl == NULL)
3760 return TRUE;
3762 if (!IsValidAcl(pacl))
3763 return FALSE;
3765 count = pacl->AceCount;
3766 for (i = 0; i < count; i++)
3768 LPVOID ace;
3769 if (!GetAce(pacl, i, &ace))
3770 return FALSE;
3771 if (!DumpAce(ace, pwptr, plen))
3772 return FALSE;
3775 return TRUE;
3778 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3780 static const WCHAR prefix[] = {'O',':',0};
3781 BOOL bDefaulted;
3782 PSID psid;
3784 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3785 return FALSE;
3787 if (psid == NULL)
3788 return TRUE;
3790 DumpString(prefix, -1, pwptr, plen);
3791 if (!DumpSid(psid, pwptr, plen))
3792 return FALSE;
3793 return TRUE;
3796 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3798 static const WCHAR prefix[] = {'G',':',0};
3799 BOOL bDefaulted;
3800 PSID psid;
3802 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3803 return FALSE;
3805 if (psid == NULL)
3806 return TRUE;
3808 DumpString(prefix, -1, pwptr, plen);
3809 if (!DumpSid(psid, pwptr, plen))
3810 return FALSE;
3811 return TRUE;
3814 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3816 static const WCHAR dacl[] = {'D',':',0};
3817 SECURITY_DESCRIPTOR_CONTROL control;
3818 BOOL present, defaulted;
3819 DWORD revision;
3820 PACL pacl;
3822 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3823 return FALSE;
3825 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3826 return FALSE;
3828 if (!present)
3829 return TRUE;
3831 DumpString(dacl, 2, pwptr, plen);
3832 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3833 return FALSE;
3834 return TRUE;
3837 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3839 static const WCHAR sacl[] = {'S',':',0};
3840 SECURITY_DESCRIPTOR_CONTROL control;
3841 BOOL present, defaulted;
3842 DWORD revision;
3843 PACL pacl;
3845 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3846 return FALSE;
3848 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3849 return FALSE;
3851 if (!present)
3852 return TRUE;
3854 DumpString(sacl, 2, pwptr, plen);
3855 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3856 return FALSE;
3857 return TRUE;
3860 /******************************************************************************
3861 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3863 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, ULONG *OutputLen)
3865 ULONG len;
3866 WCHAR *wptr, *wstr;
3868 if (SDRevision != SDDL_REVISION_1)
3870 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
3871 SetLastError(ERROR_UNKNOWN_REVISION);
3872 return FALSE;
3875 len = 0;
3876 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3877 if (!DumpOwner(SecurityDescriptor, NULL, &len))
3878 return FALSE;
3879 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3880 if (!DumpGroup(SecurityDescriptor, NULL, &len))
3881 return FALSE;
3882 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3883 if (!DumpDacl(SecurityDescriptor, NULL, &len))
3884 return FALSE;
3885 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3886 if (!DumpSacl(SecurityDescriptor, NULL, &len))
3887 return FALSE;
3889 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
3890 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
3891 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
3892 return FALSE;
3893 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
3894 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
3895 return FALSE;
3896 if (RequestedInformation & DACL_SECURITY_INFORMATION)
3897 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
3898 return FALSE;
3899 if (RequestedInformation & SACL_SECURITY_INFORMATION)
3900 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
3901 return FALSE;
3902 *wptr = 0;
3904 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
3905 *OutputString = wstr;
3906 if (OutputLen)
3907 *OutputLen = strlenW(*OutputString)+1;
3908 return TRUE;
3911 /******************************************************************************
3912 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3914 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, ULONG *OutputLen)
3916 LPWSTR wstr;
3917 ULONG len;
3918 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
3920 int lenA;
3922 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
3923 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
3924 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
3925 LocalFree(wstr);
3927 if (OutputLen != NULL)
3928 *OutputLen = lenA;
3929 return TRUE;
3931 else
3933 *OutputString = NULL;
3934 if (OutputLen)
3935 *OutputLen = 0;
3936 return FALSE;
3940 /******************************************************************************
3941 * ConvertStringSidToSidW [ADVAPI32.@]
3943 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3945 BOOL bret = FALSE;
3946 DWORD cBytes;
3948 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3949 if (GetVersion() & 0x80000000)
3950 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3951 else if (!StringSid || !Sid)
3952 SetLastError(ERROR_INVALID_PARAMETER);
3953 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3955 PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3957 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3958 if (!bret)
3959 LocalFree(*Sid);
3961 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3962 return bret;
3965 /******************************************************************************
3966 * ConvertStringSidToSidA [ADVAPI32.@]
3968 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3970 BOOL bret = FALSE;
3972 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3973 if (GetVersion() & 0x80000000)
3974 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3975 else if (!StringSid || !Sid)
3976 SetLastError(ERROR_INVALID_PARAMETER);
3977 else
3979 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3980 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3981 len * sizeof(WCHAR));
3983 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3984 bret = ConvertStringSidToSidW(wStringSid, Sid);
3985 HeapFree(GetProcessHeap(), 0, wStringSid);
3987 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3988 return bret;
3991 /******************************************************************************
3992 * ConvertSidToStringSidW [ADVAPI32.@]
3994 * format of SID string is:
3995 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3996 * where
3997 * <rev> is the revision of the SID encoded as decimal
3998 * <auth> is the identifier authority encoded as hex
3999 * <subauthN> is the subauthority id encoded as decimal
4001 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4003 DWORD len = 0;
4004 LPWSTR wstr, wptr;
4006 TRACE("%p %p\n", pSid, pstr );
4008 len = 0;
4009 if (!DumpSidNumeric(pSid, NULL, &len))
4010 return FALSE;
4011 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4012 DumpSidNumeric(pSid, &wptr, NULL);
4013 *wptr = 0;
4015 *pstr = wstr;
4016 return TRUE;
4019 /******************************************************************************
4020 * ConvertSidToStringSidA [ADVAPI32.@]
4022 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4024 LPWSTR wstr = NULL;
4025 LPSTR str;
4026 UINT len;
4028 TRACE("%p %p\n", pSid, pstr );
4030 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4031 return FALSE;
4033 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4034 str = LocalAlloc( 0, len );
4035 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4036 LocalFree( wstr );
4038 *pstr = str;
4040 return TRUE;
4043 BOOL WINAPI CreatePrivateObjectSecurity(
4044 PSECURITY_DESCRIPTOR ParentDescriptor,
4045 PSECURITY_DESCRIPTOR CreatorDescriptor,
4046 PSECURITY_DESCRIPTOR* NewDescriptor,
4047 BOOL IsDirectoryObject,
4048 HANDLE Token,
4049 PGENERIC_MAPPING GenericMapping )
4051 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4052 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4054 return FALSE;
4057 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4059 FIXME("%p - stub\n", ObjectDescriptor);
4061 return TRUE;
4064 BOOL WINAPI CreateProcessAsUserA(
4065 HANDLE hToken,
4066 LPCSTR lpApplicationName,
4067 LPSTR lpCommandLine,
4068 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4069 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4070 BOOL bInheritHandles,
4071 DWORD dwCreationFlags,
4072 LPVOID lpEnvironment,
4073 LPCSTR lpCurrentDirectory,
4074 LPSTARTUPINFOA lpStartupInfo,
4075 LPPROCESS_INFORMATION lpProcessInformation )
4077 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4078 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4079 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4081 return FALSE;
4084 BOOL WINAPI CreateProcessAsUserW(
4085 HANDLE hToken,
4086 LPCWSTR lpApplicationName,
4087 LPWSTR lpCommandLine,
4088 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4089 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4090 BOOL bInheritHandles,
4091 DWORD dwCreationFlags,
4092 LPVOID lpEnvironment,
4093 LPCWSTR lpCurrentDirectory,
4094 LPSTARTUPINFOW lpStartupInfo,
4095 LPPROCESS_INFORMATION lpProcessInformation )
4097 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4098 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4099 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4100 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4102 /* We should create the process with a suspended main thread */
4103 if (!CreateProcessW (lpApplicationName,
4104 lpCommandLine,
4105 lpProcessAttributes,
4106 lpThreadAttributes,
4107 bInheritHandles,
4108 dwCreationFlags, /* CREATE_SUSPENDED */
4109 lpEnvironment,
4110 lpCurrentDirectory,
4111 lpStartupInfo,
4112 lpProcessInformation))
4114 return FALSE;
4117 return TRUE;
4120 /******************************************************************************
4121 * DuplicateTokenEx [ADVAPI32.@]
4123 BOOL WINAPI DuplicateTokenEx(
4124 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4125 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4126 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4127 TOKEN_TYPE TokenType,
4128 PHANDLE DuplicateTokenHandle )
4130 OBJECT_ATTRIBUTES ObjectAttributes;
4132 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4133 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4135 InitializeObjectAttributes(
4136 &ObjectAttributes,
4137 NULL,
4138 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4139 NULL,
4140 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4142 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4143 dwDesiredAccess,
4144 &ObjectAttributes,
4145 ImpersonationLevel,
4146 TokenType,
4147 DuplicateTokenHandle ) );
4150 BOOL WINAPI DuplicateToken(
4151 HANDLE ExistingTokenHandle,
4152 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4153 PHANDLE DuplicateTokenHandle )
4155 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4156 NULL, ImpersonationLevel, TokenImpersonation,
4157 DuplicateTokenHandle );
4160 BOOL WINAPI EnumDependentServicesA(
4161 SC_HANDLE hService,
4162 DWORD dwServiceState,
4163 LPENUM_SERVICE_STATUSA lpServices,
4164 DWORD cbBufSize,
4165 LPDWORD pcbBytesNeeded,
4166 LPDWORD lpServicesReturned )
4168 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4169 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4171 return FALSE;
4174 BOOL WINAPI EnumDependentServicesW(
4175 SC_HANDLE hService,
4176 DWORD dwServiceState,
4177 LPENUM_SERVICE_STATUSW lpServices,
4178 DWORD cbBufSize,
4179 LPDWORD pcbBytesNeeded,
4180 LPDWORD lpServicesReturned )
4182 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4183 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4185 return FALSE;
4188 /******************************************************************************
4189 * ComputeStringSidSize
4191 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4193 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4195 int ctok = 0;
4196 while (*StringSid)
4198 if (*StringSid == '-')
4199 ctok++;
4200 StringSid++;
4203 if (ctok >= 3)
4204 return GetSidLengthRequired(ctok - 2);
4206 else /* String constant format - Only available in winxp and above */
4208 unsigned int i;
4210 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4211 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4212 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4215 return GetSidLengthRequired(0);
4218 /******************************************************************************
4219 * ParseStringSidToSid
4221 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4223 BOOL bret = FALSE;
4224 SID* pisid=pSid;
4226 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4227 if (!StringSid)
4229 SetLastError(ERROR_INVALID_PARAMETER);
4230 TRACE("StringSid is NULL, returning FALSE\n");
4231 return FALSE;
4234 *cBytes = ComputeStringSidSize(StringSid);
4235 if (!pisid) /* Simply compute the size */
4237 TRACE("only size requested, returning TRUE\n");
4238 return TRUE;
4241 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4243 DWORD i = 0, identAuth;
4244 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4246 StringSid += 2; /* Advance to Revision */
4247 pisid->Revision = atoiW(StringSid);
4249 if (pisid->Revision != SDDL_REVISION)
4251 TRACE("Revision %d is unknown\n", pisid->Revision);
4252 goto lend; /* ERROR_INVALID_SID */
4254 if (csubauth == 0)
4256 TRACE("SubAuthorityCount is 0\n");
4257 goto lend; /* ERROR_INVALID_SID */
4260 pisid->SubAuthorityCount = csubauth;
4262 /* Advance to identifier authority */
4263 while (*StringSid && *StringSid != '-')
4264 StringSid++;
4265 if (*StringSid == '-')
4266 StringSid++;
4268 /* MS' implementation can't handle values greater than 2^32 - 1, so
4269 * we don't either; assume most significant bytes are always 0
4271 pisid->IdentifierAuthority.Value[0] = 0;
4272 pisid->IdentifierAuthority.Value[1] = 0;
4273 identAuth = atoiW(StringSid);
4274 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4275 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4276 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4277 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4279 /* Advance to first sub authority */
4280 while (*StringSid && *StringSid != '-')
4281 StringSid++;
4282 if (*StringSid == '-')
4283 StringSid++;
4285 while (*StringSid)
4287 pisid->SubAuthority[i++] = atoiW(StringSid);
4289 while (*StringSid && *StringSid != '-')
4290 StringSid++;
4291 if (*StringSid == '-')
4292 StringSid++;
4295 if (i != pisid->SubAuthorityCount)
4296 goto lend; /* ERROR_INVALID_SID */
4298 bret = TRUE;
4300 else /* String constant format - Only available in winxp and above */
4302 unsigned int i;
4303 pisid->Revision = SDDL_REVISION;
4305 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4306 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4308 DWORD j;
4309 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4310 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4311 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4312 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4313 bret = TRUE;
4316 if (!bret)
4317 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4320 lend:
4321 if (!bret)
4322 SetLastError(ERROR_INVALID_SID);
4324 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4325 return bret;
4328 /******************************************************************************
4329 * GetNamedSecurityInfoA [ADVAPI32.@]
4331 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4332 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4333 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4334 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4336 DWORD len;
4337 LPWSTR wstr = NULL;
4338 DWORD r;
4340 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4341 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4343 if( pObjectName )
4345 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4346 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4347 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4350 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4351 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4353 HeapFree( GetProcessHeap(), 0, wstr );
4355 return r;
4358 /******************************************************************************
4359 * GetNamedSecurityInfoW [ADVAPI32.@]
4361 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4362 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4363 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4365 DWORD needed, offset;
4366 SECURITY_DESCRIPTOR_RELATIVE *relative;
4367 BYTE *buffer;
4369 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4370 group, dacl, sacl, descriptor );
4372 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4374 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4375 if (info & OWNER_SECURITY_INFORMATION)
4376 needed += sizeof(sidWorld);
4377 if (info & GROUP_SECURITY_INFORMATION)
4378 needed += sizeof(sidWorld);
4379 if (info & DACL_SECURITY_INFORMATION)
4380 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4381 if (info & SACL_SECURITY_INFORMATION)
4382 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4384 /* must be freed by caller */
4385 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4386 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4388 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4390 HeapFree( GetProcessHeap(), 0, *descriptor );
4391 return ERROR_INVALID_SECURITY_DESCR;
4394 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4395 relative->Control |= SE_SELF_RELATIVE;
4396 buffer = (BYTE *)relative;
4397 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4399 if (info & OWNER_SECURITY_INFORMATION)
4401 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4402 relative->Owner = offset;
4403 if (owner)
4404 *owner = buffer + offset;
4405 offset += sizeof(sidWorld);
4407 if (info & GROUP_SECURITY_INFORMATION)
4409 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4410 relative->Group = offset;
4411 if (group)
4412 *group = buffer + offset;
4413 offset += sizeof(sidWorld);
4415 if (info & DACL_SECURITY_INFORMATION)
4417 relative->Control |= SE_DACL_PRESENT;
4418 GetWorldAccessACL( (PACL)(buffer + offset) );
4419 relative->Dacl = offset;
4420 if (dacl)
4421 *dacl = (PACL)(buffer + offset);
4422 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4424 if (info & SACL_SECURITY_INFORMATION)
4426 relative->Control |= SE_SACL_PRESENT;
4427 GetWorldAccessACL( (PACL)(buffer + offset) );
4428 relative->Sacl = offset;
4429 if (sacl)
4430 *sacl = (PACL)(buffer + offset);
4432 return ERROR_SUCCESS;
4435 /******************************************************************************
4436 * DecryptFileW [ADVAPI32.@]
4438 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4440 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4441 return TRUE;
4444 /******************************************************************************
4445 * DecryptFileA [ADVAPI32.@]
4447 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4449 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4450 return TRUE;
4453 /******************************************************************************
4454 * EncryptFileW [ADVAPI32.@]
4456 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4458 FIXME("%s\n", debugstr_w(lpFileName));
4459 return TRUE;
4462 /******************************************************************************
4463 * EncryptFileA [ADVAPI32.@]
4465 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4467 FIXME("%s\n", debugstr_a(lpFileName));
4468 return TRUE;
4471 /******************************************************************************
4472 * FileEncryptionStatusW [ADVAPI32.@]
4474 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4476 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4477 if (!lpStatus)
4478 return FALSE;
4479 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4480 return TRUE;
4483 /******************************************************************************
4484 * FileEncryptionStatusA [ADVAPI32.@]
4486 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4488 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4489 if (!lpStatus)
4490 return FALSE;
4491 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4492 return TRUE;
4495 /******************************************************************************
4496 * SetSecurityInfo [ADVAPI32.@]
4498 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4499 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4500 PSID psidGroup, PACL pDacl, PACL pSacl) {
4501 FIXME("stub\n");
4502 return ERROR_SUCCESS;