push 6ad4febc802779d39881ae7cccabf16fa19e6741
[wine/hacks.git] / dlls / advapi32 / security.c
blob3c2665494e1743e5e8ea631f681eca7d2e29d6ef
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}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
126 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
127 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
128 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
129 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
130 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
134 typedef struct WELLKNOWNRID
136 WELL_KNOWN_SID_TYPE Type;
137 DWORD Rid;
138 } WELLKNOWNRID;
140 static const WELLKNOWNRID WellKnownRids[] = {
141 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
142 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
143 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
144 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
145 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
146 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
147 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
148 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
149 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
150 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
151 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
152 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
153 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
157 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
159 typedef struct _AccountSid {
160 WELL_KNOWN_SID_TYPE type;
161 LPCWSTR account;
162 LPCWSTR domain;
163 SID_NAME_USE name_use;
164 } AccountSid;
166 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
167 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
168 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
169 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
170 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
171 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
172 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
173 static const WCHAR Blank[] = { 0 };
174 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
175 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
176 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
177 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 };
178 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
179 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 };
180 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
181 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 };
182 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
183 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
184 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
185 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
186 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
187 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
188 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
189 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 };
190 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
191 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 };
192 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
193 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
194 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
195 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
196 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
197 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
198 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 };
199 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
201 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
202 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
203 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
204 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
205 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 };
206 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 };
207 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
208 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 };
209 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
210 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
211 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
212 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 };
213 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 };
214 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
215 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
216 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 };
217 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
218 static const WCHAR SELF[] = { 'S','E','L','F',0 };
219 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
221 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
222 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 };
223 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
224 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
226 static const AccountSid ACCOUNT_SIDS[] = {
227 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
228 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
229 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
230 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
231 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
232 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
233 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
234 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
235 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
236 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
252 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
253 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
254 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
255 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
256 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
257 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
261 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
262 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
264 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
265 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
270 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
273 * ACE access rights
275 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
276 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
277 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
278 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
280 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
281 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
282 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
283 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
284 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
285 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
286 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
287 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
288 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
290 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
291 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
292 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
293 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
295 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
296 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
297 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
298 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
300 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
301 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
302 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
303 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
306 * ACL flags
308 static const WCHAR SDDL_PROTECTED[] = {'P',0};
309 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
310 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
313 * ACE types
315 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
316 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
317 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
319 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
320 static const WCHAR SDDL_ALARM[] = {'A','L',0};
321 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
322 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
325 * ACE flags
327 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
328 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
329 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
330 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
331 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
332 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
333 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
335 const char * debugstr_sid(PSID sid)
337 int auth = 0;
338 SID * psid = (SID *)sid;
340 if (psid == NULL)
341 return "(null)";
343 auth = psid->IdentifierAuthority.Value[5] +
344 (psid->IdentifierAuthority.Value[4] << 8) +
345 (psid->IdentifierAuthority.Value[3] << 16) +
346 (psid->IdentifierAuthority.Value[2] << 24);
348 switch (psid->SubAuthorityCount) {
349 case 0:
350 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
351 case 1:
352 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
353 psid->SubAuthority[0]);
354 case 2:
355 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
356 psid->SubAuthority[0], psid->SubAuthority[1]);
357 case 3:
358 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
359 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
360 case 4:
361 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
362 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
363 psid->SubAuthority[3]);
364 case 5:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
367 psid->SubAuthority[3], psid->SubAuthority[4]);
368 case 6:
369 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
370 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
371 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
372 case 7:
373 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
374 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
375 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
376 psid->SubAuthority[6]);
377 case 8:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
381 psid->SubAuthority[6], psid->SubAuthority[7]);
383 return "(too-big)";
386 /* set last error code from NT status and get the proper boolean return value */
387 /* used for functions that are a simple wrapper around the corresponding ntdll API */
388 static inline BOOL set_ntstatus( NTSTATUS status )
390 if (status) SetLastError( RtlNtStatusToDosError( status ));
391 return !status;
394 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
396 static void GetWorldAccessACL(PACL pACL)
398 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
400 pACL->AclRevision = ACL_REVISION;
401 pACL->Sbz1 = 0;
402 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
403 pACL->AceCount = 1;
404 pACL->Sbz2 = 0;
406 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
407 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
408 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
409 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
410 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
413 /************************************************************
414 * ADVAPI_IsLocalComputer
416 * Checks whether the server name indicates local machine.
418 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
420 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
421 BOOL Result;
422 LPWSTR buf;
424 if (!ServerName || !ServerName[0])
425 return TRUE;
427 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
428 Result = GetComputerNameW(buf, &dwSize);
429 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
430 ServerName += 2;
431 Result = Result && !lstrcmpW(ServerName, buf);
432 HeapFree(GetProcessHeap(), 0, buf);
434 return Result;
437 /************************************************************
438 * ADVAPI_GetComputerSid
440 * Reads the computer SID from the registry.
442 BOOL ADVAPI_GetComputerSid(PSID sid)
444 HKEY key;
445 LONG ret;
446 BOOL retval = FALSE;
447 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 };
448 static const WCHAR V[] = { 'V',0 };
450 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
451 KEY_READ, &key)) == ERROR_SUCCESS)
453 DWORD size = 0;
454 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
455 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
457 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
458 if (data)
460 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
461 data, &size)) == ERROR_SUCCESS)
463 /* the SID is in the last 24 bytes of the binary data */
464 CopyMemory(sid, &data[size-24], 24);
465 retval = TRUE;
467 HeapFree(GetProcessHeap(), 0, data);
470 RegCloseKey(key);
473 if(retval == TRUE) return retval;
475 /* create a new random SID */
476 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
477 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
479 PSID new_sid;
480 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
481 DWORD id[3];
483 if (RtlGenRandom(id, sizeof(id)))
485 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
487 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
488 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
490 FreeSid(new_sid);
493 RegCloseKey(key);
496 return retval;
499 /* ##############################
500 ###### TOKEN FUNCTIONS ######
501 ##############################
504 /******************************************************************************
505 * OpenProcessToken [ADVAPI32.@]
506 * Opens the access token associated with a process handle.
508 * PARAMS
509 * ProcessHandle [I] Handle to process
510 * DesiredAccess [I] Desired access to process
511 * TokenHandle [O] Pointer to handle of open access token
513 * RETURNS
514 * Success: TRUE. TokenHandle contains the access token.
515 * Failure: FALSE.
517 * NOTES
518 * See NtOpenProcessToken.
520 BOOL WINAPI
521 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
522 HANDLE *TokenHandle )
524 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
527 /******************************************************************************
528 * OpenThreadToken [ADVAPI32.@]
530 * Opens the access token associated with a thread handle.
532 * PARAMS
533 * ThreadHandle [I] Handle to process
534 * DesiredAccess [I] Desired access to the thread
535 * OpenAsSelf [I] ???
536 * TokenHandle [O] Destination for the token handle
538 * RETURNS
539 * Success: TRUE. TokenHandle contains the access token.
540 * Failure: FALSE.
542 * NOTES
543 * See NtOpenThreadToken.
545 BOOL WINAPI
546 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
547 BOOL OpenAsSelf, HANDLE *TokenHandle)
549 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
552 BOOL WINAPI
553 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
554 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
556 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
557 PreviousState, ReturnLength));
560 /******************************************************************************
561 * AdjustTokenPrivileges [ADVAPI32.@]
563 * Adjust the privileges of an open token handle.
565 * PARAMS
566 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
567 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
568 * NewState [I] Desired new privileges of the token
569 * BufferLength [I] Length of NewState
570 * PreviousState [O] Destination for the previous state
571 * ReturnLength [I/O] Size of PreviousState
574 * RETURNS
575 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
576 * Failure: FALSE.
578 * NOTES
579 * See NtAdjustPrivilegesToken.
581 BOOL WINAPI
582 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
583 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
584 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
586 NTSTATUS status;
588 TRACE("\n");
590 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
591 NewState, BufferLength, PreviousState,
592 ReturnLength);
593 SetLastError( RtlNtStatusToDosError( status ));
594 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
595 return TRUE;
596 else
597 return FALSE;
600 /******************************************************************************
601 * CheckTokenMembership [ADVAPI32.@]
603 * Determine if an access token is a member of a SID.
605 * PARAMS
606 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
607 * SidToCheck [I] SID that possibly contains the token
608 * IsMember [O] Destination for result.
610 * RETURNS
611 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
612 * Failure: FALSE.
614 BOOL WINAPI
615 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
616 PBOOL IsMember )
618 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
620 *IsMember = TRUE;
621 return(TRUE);
624 /******************************************************************************
625 * GetTokenInformation [ADVAPI32.@]
627 * Get a type of information about an access token.
629 * PARAMS
630 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
631 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
632 * tokeninfo [O] Destination for token information
633 * tokeninfolength [I] Length of tokeninfo
634 * retlen [O] Destination for returned token information length
636 * RETURNS
637 * Success: TRUE. tokeninfo contains retlen bytes of token information
638 * Failure: FALSE.
640 * NOTES
641 * See NtQueryInformationToken.
643 BOOL WINAPI
644 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
645 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
647 TRACE("(%p, %s, %p, %d, %p):\n",
648 token,
649 (tokeninfoclass == TokenUser) ? "TokenUser" :
650 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
651 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
652 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
653 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
654 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
655 (tokeninfoclass == TokenSource) ? "TokenSource" :
656 (tokeninfoclass == TokenType) ? "TokenType" :
657 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
658 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
659 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
660 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
661 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
662 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
663 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
664 "Unknown",
665 tokeninfo, tokeninfolength, retlen);
666 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
667 tokeninfolength, retlen));
670 /******************************************************************************
671 * SetTokenInformation [ADVAPI32.@]
673 * Set information for an access token.
675 * PARAMS
676 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
677 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
678 * tokeninfo [I] Token information to set
679 * tokeninfolength [I] Length of tokeninfo
681 * RETURNS
682 * Success: TRUE. The information for the token is set to tokeninfo.
683 * Failure: FALSE.
685 BOOL WINAPI
686 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
687 LPVOID tokeninfo, DWORD tokeninfolength )
689 TRACE("(%p, %s, %p, %d): stub\n",
690 token,
691 (tokeninfoclass == TokenUser) ? "TokenUser" :
692 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
693 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
694 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
695 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
696 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
697 (tokeninfoclass == TokenSource) ? "TokenSource" :
698 (tokeninfoclass == TokenType) ? "TokenType" :
699 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
700 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
701 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
702 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
703 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
704 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
705 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
706 "Unknown",
707 tokeninfo, tokeninfolength);
709 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
712 /*************************************************************************
713 * SetThreadToken [ADVAPI32.@]
715 * Assigns an 'impersonation token' to a thread so it can assume the
716 * security privileges of another thread or process. Can also remove
717 * a previously assigned token.
719 * PARAMS
720 * thread [O] Handle to thread to set the token for
721 * token [I] Token to set
723 * RETURNS
724 * Success: TRUE. The threads access token is set to token
725 * Failure: FALSE.
727 * NOTES
728 * Only supported on NT or higher. On Win9X this function does nothing.
729 * See SetTokenInformation.
731 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
733 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
734 ThreadImpersonationToken, &token, sizeof token ));
737 /*************************************************************************
738 * CreateRestrictedToken [ADVAPI32.@]
740 * Create a new more restricted token from an existing token.
742 * PARAMS
743 * baseToken [I] Token to base the new restricted token on
744 * flags [I] Options
745 * nDisableSids [I] Length of disableSids array
746 * disableSids [I] Array of SIDs to disable in the new token
747 * nDeletePrivs [I] Length of deletePrivs array
748 * deletePrivs [I] Array of privileges to delete in the new token
749 * nRestrictSids [I] Length of restrictSids array
750 * restrictSids [I] Array of SIDs to restrict in the new token
751 * newToken [O] Address where the new token is stored
753 * RETURNS
754 * Success: TRUE
755 * Failure: FALSE
757 BOOL WINAPI CreateRestrictedToken(
758 HANDLE baseToken,
759 DWORD flags,
760 DWORD nDisableSids,
761 PSID_AND_ATTRIBUTES disableSids,
762 DWORD nDeletePrivs,
763 PLUID_AND_ATTRIBUTES deletePrivs,
764 DWORD nRestrictSids,
765 PSID_AND_ATTRIBUTES restrictSids,
766 PHANDLE newToken)
768 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
769 baseToken, flags, nDisableSids, disableSids,
770 nDeletePrivs, deletePrivs,
771 nRestrictSids, restrictSids,
772 newToken);
773 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
774 return FALSE;
777 /* ##############################
778 ###### SID FUNCTIONS ######
779 ##############################
782 /******************************************************************************
783 * AllocateAndInitializeSid [ADVAPI32.@]
785 * PARAMS
786 * pIdentifierAuthority []
787 * nSubAuthorityCount []
788 * nSubAuthority0 []
789 * nSubAuthority1 []
790 * nSubAuthority2 []
791 * nSubAuthority3 []
792 * nSubAuthority4 []
793 * nSubAuthority5 []
794 * nSubAuthority6 []
795 * nSubAuthority7 []
796 * pSid []
798 BOOL WINAPI
799 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
800 BYTE nSubAuthorityCount,
801 DWORD nSubAuthority0, DWORD nSubAuthority1,
802 DWORD nSubAuthority2, DWORD nSubAuthority3,
803 DWORD nSubAuthority4, DWORD nSubAuthority5,
804 DWORD nSubAuthority6, DWORD nSubAuthority7,
805 PSID *pSid )
807 return set_ntstatus( RtlAllocateAndInitializeSid(
808 pIdentifierAuthority, nSubAuthorityCount,
809 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
810 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
811 pSid ));
814 /******************************************************************************
815 * FreeSid [ADVAPI32.@]
817 * PARAMS
818 * pSid []
820 PVOID WINAPI
821 FreeSid( PSID pSid )
823 RtlFreeSid(pSid);
824 return NULL; /* is documented like this */
827 /******************************************************************************
828 * CopySid [ADVAPI32.@]
830 * PARAMS
831 * nDestinationSidLength []
832 * pDestinationSid []
833 * pSourceSid []
835 BOOL WINAPI
836 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
838 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
841 /******************************************************************************
842 * CreateWellKnownSid [ADVAPI32.@]
844 BOOL WINAPI
845 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
846 PSID DomainSid,
847 PSID pSid,
848 DWORD* cbSid)
850 unsigned int i;
851 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
853 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
854 SetLastError(ERROR_INVALID_PARAMETER);
855 return FALSE;
858 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
859 if (WellKnownSids[i].Type == WellKnownSidType) {
860 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
862 if (*cbSid < length) {
863 SetLastError(ERROR_INSUFFICIENT_BUFFER);
864 return FALSE;
867 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
868 *cbSid = length;
869 return TRUE;
873 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
875 SetLastError(ERROR_INVALID_PARAMETER);
876 return FALSE;
879 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
880 if (WellKnownRids[i].Type == WellKnownSidType) {
881 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
882 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
883 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
885 if (*cbSid < output_sid_length) {
886 SetLastError(ERROR_INSUFFICIENT_BUFFER);
887 return FALSE;
890 CopyMemory(pSid, DomainSid, domain_sid_length);
891 (*GetSidSubAuthorityCount(pSid))++;
892 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
893 *cbSid = output_sid_length;
894 return TRUE;
897 SetLastError(ERROR_INVALID_PARAMETER);
898 return FALSE;
901 /******************************************************************************
902 * IsWellKnownSid [ADVAPI32.@]
904 BOOL WINAPI
905 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
907 unsigned int i;
908 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
910 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
911 if (WellKnownSids[i].Type == WellKnownSidType)
912 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
913 return TRUE;
915 return FALSE;
918 BOOL WINAPI
919 IsTokenRestricted( HANDLE TokenHandle )
921 TOKEN_GROUPS *groups;
922 DWORD size;
923 NTSTATUS status;
924 BOOL restricted;
926 TRACE("(%p)\n", TokenHandle);
928 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
929 if (status != STATUS_BUFFER_TOO_SMALL)
930 return FALSE;
932 groups = HeapAlloc(GetProcessHeap(), 0, size);
933 if (!groups)
935 SetLastError(ERROR_OUTOFMEMORY);
936 return FALSE;
939 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
940 if (status != STATUS_SUCCESS)
942 HeapFree(GetProcessHeap(), 0, groups);
943 return set_ntstatus(status);
946 if (groups->GroupCount)
947 restricted = TRUE;
948 else
949 restricted = FALSE;
951 HeapFree(GetProcessHeap(), 0, groups);
953 return restricted;
956 /******************************************************************************
957 * IsValidSid [ADVAPI32.@]
959 * PARAMS
960 * pSid []
962 BOOL WINAPI
963 IsValidSid( PSID pSid )
965 return RtlValidSid( pSid );
968 /******************************************************************************
969 * EqualSid [ADVAPI32.@]
971 * PARAMS
972 * pSid1 []
973 * pSid2 []
975 BOOL WINAPI
976 EqualSid( PSID pSid1, PSID pSid2 )
978 return RtlEqualSid( pSid1, pSid2 );
981 /******************************************************************************
982 * EqualPrefixSid [ADVAPI32.@]
984 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
986 return RtlEqualPrefixSid(pSid1, pSid2);
989 /******************************************************************************
990 * GetSidLengthRequired [ADVAPI32.@]
992 * PARAMS
993 * nSubAuthorityCount []
995 DWORD WINAPI
996 GetSidLengthRequired( BYTE nSubAuthorityCount )
998 return RtlLengthRequiredSid(nSubAuthorityCount);
1001 /******************************************************************************
1002 * InitializeSid [ADVAPI32.@]
1004 * PARAMS
1005 * pIdentifierAuthority []
1007 BOOL WINAPI
1008 InitializeSid (
1009 PSID pSid,
1010 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1011 BYTE nSubAuthorityCount)
1013 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1016 DWORD WINAPI
1017 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1019 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1021 return 1;
1024 DWORD WINAPI
1025 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1027 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1029 return 1;
1032 /******************************************************************************
1033 * GetSidIdentifierAuthority [ADVAPI32.@]
1035 * PARAMS
1036 * pSid []
1038 PSID_IDENTIFIER_AUTHORITY WINAPI
1039 GetSidIdentifierAuthority( PSID pSid )
1041 return RtlIdentifierAuthoritySid(pSid);
1044 /******************************************************************************
1045 * GetSidSubAuthority [ADVAPI32.@]
1047 * PARAMS
1048 * pSid []
1049 * nSubAuthority []
1051 PDWORD WINAPI
1052 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1054 return RtlSubAuthoritySid(pSid, nSubAuthority);
1057 /******************************************************************************
1058 * GetSidSubAuthorityCount [ADVAPI32.@]
1060 * PARAMS
1061 * pSid []
1063 PUCHAR WINAPI
1064 GetSidSubAuthorityCount (PSID pSid)
1066 return RtlSubAuthorityCountSid(pSid);
1069 /******************************************************************************
1070 * GetLengthSid [ADVAPI32.@]
1072 * PARAMS
1073 * pSid []
1075 DWORD WINAPI
1076 GetLengthSid (PSID pSid)
1078 return RtlLengthSid(pSid);
1081 /* ##############################################
1082 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1083 ##############################################
1086 /******************************************************************************
1087 * BuildSecurityDescriptorA [ADVAPI32.@]
1089 * Builds a SD from
1091 * PARAMS
1092 * pOwner [I]
1093 * pGroup [I]
1094 * cCountOfAccessEntries [I]
1095 * pListOfAccessEntries [I]
1096 * cCountOfAuditEntries [I]
1097 * pListofAuditEntries [I]
1098 * pOldSD [I]
1099 * lpdwBufferLength [I/O]
1100 * pNewSD [O]
1102 * RETURNS
1103 * Success: ERROR_SUCCESS
1104 * Failure: nonzero error code from Winerror.h
1106 DWORD WINAPI BuildSecurityDescriptorA(
1107 IN PTRUSTEEA pOwner,
1108 IN PTRUSTEEA pGroup,
1109 IN ULONG cCountOfAccessEntries,
1110 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1111 IN ULONG cCountOfAuditEntries,
1112 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1113 IN PSECURITY_DESCRIPTOR pOldSD,
1114 IN OUT PULONG lpdwBufferLength,
1115 OUT PSECURITY_DESCRIPTOR* pNewSD)
1117 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1118 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1119 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1121 return ERROR_CALL_NOT_IMPLEMENTED;
1124 /******************************************************************************
1125 * BuildSecurityDescriptorW [ADVAPI32.@]
1127 * See BuildSecurityDescriptorA.
1129 DWORD WINAPI BuildSecurityDescriptorW(
1130 IN PTRUSTEEW pOwner,
1131 IN PTRUSTEEW pGroup,
1132 IN ULONG cCountOfAccessEntries,
1133 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1134 IN ULONG cCountOfAuditEntries,
1135 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1136 IN PSECURITY_DESCRIPTOR pOldSD,
1137 IN OUT PULONG lpdwBufferLength,
1138 OUT PSECURITY_DESCRIPTOR* pNewSD)
1140 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1141 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1142 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1144 return ERROR_CALL_NOT_IMPLEMENTED;
1147 /******************************************************************************
1148 * InitializeSecurityDescriptor [ADVAPI32.@]
1150 * PARAMS
1151 * pDescr []
1152 * revision []
1154 BOOL WINAPI
1155 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1157 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1161 /******************************************************************************
1162 * MakeAbsoluteSD [ADVAPI32.@]
1164 BOOL WINAPI MakeAbsoluteSD (
1165 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1166 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1167 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1168 OUT PACL pDacl,
1169 OUT LPDWORD lpdwDaclSize,
1170 OUT PACL pSacl,
1171 OUT LPDWORD lpdwSaclSize,
1172 OUT PSID pOwner,
1173 OUT LPDWORD lpdwOwnerSize,
1174 OUT PSID pPrimaryGroup,
1175 OUT LPDWORD lpdwPrimaryGroupSize)
1177 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1178 pAbsoluteSecurityDescriptor,
1179 lpdwAbsoluteSecurityDescriptorSize,
1180 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1181 pOwner, lpdwOwnerSize,
1182 pPrimaryGroup, lpdwPrimaryGroupSize));
1185 /******************************************************************************
1186 * GetKernelObjectSecurity [ADVAPI32.@]
1188 BOOL WINAPI GetKernelObjectSecurity(
1189 HANDLE Handle,
1190 SECURITY_INFORMATION RequestedInformation,
1191 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1192 DWORD nLength,
1193 LPDWORD lpnLengthNeeded )
1195 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1196 pSecurityDescriptor, nLength, lpnLengthNeeded);
1198 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1199 nLength, lpnLengthNeeded ));
1202 /******************************************************************************
1203 * GetPrivateObjectSecurity [ADVAPI32.@]
1205 BOOL WINAPI GetPrivateObjectSecurity(
1206 PSECURITY_DESCRIPTOR ObjectDescriptor,
1207 SECURITY_INFORMATION SecurityInformation,
1208 PSECURITY_DESCRIPTOR ResultantDescriptor,
1209 DWORD DescriptorLength,
1210 PDWORD ReturnLength )
1212 SECURITY_DESCRIPTOR desc;
1213 BOOL defaulted, present;
1214 PACL pacl;
1215 PSID psid;
1217 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1218 ResultantDescriptor, DescriptorLength, ReturnLength);
1220 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1221 return FALSE;
1223 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1225 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1226 return FALSE;
1227 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1230 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1232 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1233 return FALSE;
1234 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1237 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1239 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1240 return FALSE;
1241 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1244 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1246 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1247 return FALSE;
1248 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1251 *ReturnLength = DescriptorLength;
1252 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1255 /******************************************************************************
1256 * GetSecurityDescriptorLength [ADVAPI32.@]
1258 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1260 return RtlLengthSecurityDescriptor(pDescr);
1263 /******************************************************************************
1264 * GetSecurityDescriptorOwner [ADVAPI32.@]
1266 * PARAMS
1267 * pOwner []
1268 * lpbOwnerDefaulted []
1270 BOOL WINAPI
1271 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1272 LPBOOL lpbOwnerDefaulted )
1274 BOOLEAN defaulted;
1275 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1276 *lpbOwnerDefaulted = defaulted;
1277 return ret;
1280 /******************************************************************************
1281 * SetSecurityDescriptorOwner [ADVAPI32.@]
1283 * PARAMS
1285 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1286 PSID pOwner, BOOL bOwnerDefaulted)
1288 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1290 /******************************************************************************
1291 * GetSecurityDescriptorGroup [ADVAPI32.@]
1293 BOOL WINAPI GetSecurityDescriptorGroup(
1294 PSECURITY_DESCRIPTOR SecurityDescriptor,
1295 PSID *Group,
1296 LPBOOL GroupDefaulted)
1298 BOOLEAN defaulted;
1299 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1300 *GroupDefaulted = defaulted;
1301 return ret;
1303 /******************************************************************************
1304 * SetSecurityDescriptorGroup [ADVAPI32.@]
1306 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1307 PSID Group, BOOL GroupDefaulted)
1309 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1312 /******************************************************************************
1313 * IsValidSecurityDescriptor [ADVAPI32.@]
1315 * PARAMS
1316 * lpsecdesc []
1318 BOOL WINAPI
1319 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1321 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1324 /******************************************************************************
1325 * GetSecurityDescriptorDacl [ADVAPI32.@]
1327 BOOL WINAPI GetSecurityDescriptorDacl(
1328 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1329 OUT LPBOOL lpbDaclPresent,
1330 OUT PACL *pDacl,
1331 OUT LPBOOL lpbDaclDefaulted)
1333 BOOLEAN present, defaulted;
1334 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1335 *lpbDaclPresent = present;
1336 *lpbDaclDefaulted = defaulted;
1337 return ret;
1340 /******************************************************************************
1341 * SetSecurityDescriptorDacl [ADVAPI32.@]
1343 BOOL WINAPI
1344 SetSecurityDescriptorDacl (
1345 PSECURITY_DESCRIPTOR lpsd,
1346 BOOL daclpresent,
1347 PACL dacl,
1348 BOOL dacldefaulted )
1350 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1352 /******************************************************************************
1353 * GetSecurityDescriptorSacl [ADVAPI32.@]
1355 BOOL WINAPI GetSecurityDescriptorSacl(
1356 IN PSECURITY_DESCRIPTOR lpsd,
1357 OUT LPBOOL lpbSaclPresent,
1358 OUT PACL *pSacl,
1359 OUT LPBOOL lpbSaclDefaulted)
1361 BOOLEAN present, defaulted;
1362 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1363 *lpbSaclPresent = present;
1364 *lpbSaclDefaulted = defaulted;
1365 return ret;
1368 /**************************************************************************
1369 * SetSecurityDescriptorSacl [ADVAPI32.@]
1371 BOOL WINAPI SetSecurityDescriptorSacl (
1372 PSECURITY_DESCRIPTOR lpsd,
1373 BOOL saclpresent,
1374 PACL lpsacl,
1375 BOOL sacldefaulted)
1377 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1379 /******************************************************************************
1380 * MakeSelfRelativeSD [ADVAPI32.@]
1382 * PARAMS
1383 * lpabssecdesc []
1384 * lpselfsecdesc []
1385 * lpbuflen []
1387 BOOL WINAPI
1388 MakeSelfRelativeSD(
1389 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1390 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1391 IN OUT LPDWORD lpdwBufferLength)
1393 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1394 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1397 /******************************************************************************
1398 * GetSecurityDescriptorControl [ADVAPI32.@]
1401 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1402 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1404 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1407 /******************************************************************************
1408 * SetSecurityDescriptorControl [ADVAPI32.@]
1410 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1412 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1414 return set_ntstatus( RtlSetControlSecurityDescriptor(
1415 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1418 /* ##############################
1419 ###### ACL FUNCTIONS ######
1420 ##############################
1423 /*************************************************************************
1424 * InitializeAcl [ADVAPI32.@]
1426 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1428 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1431 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1433 IO_STATUS_BLOCK io_block;
1435 TRACE("(%p)\n", hNamedPipe);
1437 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1438 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1441 /******************************************************************************
1442 * AddAccessAllowedAce [ADVAPI32.@]
1444 BOOL WINAPI AddAccessAllowedAce(
1445 IN OUT PACL pAcl,
1446 IN DWORD dwAceRevision,
1447 IN DWORD AccessMask,
1448 IN PSID pSid)
1450 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1453 /******************************************************************************
1454 * AddAccessAllowedAceEx [ADVAPI32.@]
1456 BOOL WINAPI AddAccessAllowedAceEx(
1457 IN OUT PACL pAcl,
1458 IN DWORD dwAceRevision,
1459 IN DWORD AceFlags,
1460 IN DWORD AccessMask,
1461 IN PSID pSid)
1463 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1466 /******************************************************************************
1467 * AddAccessDeniedAce [ADVAPI32.@]
1469 BOOL WINAPI AddAccessDeniedAce(
1470 IN OUT PACL pAcl,
1471 IN DWORD dwAceRevision,
1472 IN DWORD AccessMask,
1473 IN PSID pSid)
1475 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1478 /******************************************************************************
1479 * AddAccessDeniedAceEx [ADVAPI32.@]
1481 BOOL WINAPI AddAccessDeniedAceEx(
1482 IN OUT PACL pAcl,
1483 IN DWORD dwAceRevision,
1484 IN DWORD AceFlags,
1485 IN DWORD AccessMask,
1486 IN PSID pSid)
1488 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1491 /******************************************************************************
1492 * AddAce [ADVAPI32.@]
1494 BOOL WINAPI AddAce(
1495 IN OUT PACL pAcl,
1496 IN DWORD dwAceRevision,
1497 IN DWORD dwStartingAceIndex,
1498 LPVOID pAceList,
1499 DWORD nAceListLength)
1501 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1504 /******************************************************************************
1505 * DeleteAce [ADVAPI32.@]
1507 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1509 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1512 /******************************************************************************
1513 * FindFirstFreeAce [ADVAPI32.@]
1515 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1517 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1520 /******************************************************************************
1521 * GetAce [ADVAPI32.@]
1523 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1525 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1528 /******************************************************************************
1529 * GetAclInformation [ADVAPI32.@]
1531 BOOL WINAPI GetAclInformation(
1532 PACL pAcl,
1533 LPVOID pAclInformation,
1534 DWORD nAclInformationLength,
1535 ACL_INFORMATION_CLASS dwAclInformationClass)
1537 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1538 nAclInformationLength, dwAclInformationClass));
1541 /******************************************************************************
1542 * IsValidAcl [ADVAPI32.@]
1544 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1546 return RtlValidAcl(pAcl);
1549 /* ##############################
1550 ###### MISC FUNCTIONS ######
1551 ##############################
1554 /******************************************************************************
1555 * AllocateLocallyUniqueId [ADVAPI32.@]
1557 * PARAMS
1558 * lpLuid []
1560 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1562 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1565 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1566 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1567 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1568 { '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 };
1569 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1570 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1571 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1572 { '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 };
1573 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1574 { '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 };
1575 static const WCHAR SE_TCB_NAME_W[] =
1576 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_SECURITY_NAME_W[] =
1578 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1580 { '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 };
1581 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1582 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1584 { '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 };
1585 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1586 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1587 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1588 { '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 };
1589 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1592 { '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 };
1593 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_BACKUP_NAME_W[] =
1596 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1597 static const WCHAR SE_RESTORE_NAME_W[] =
1598 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1600 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_DEBUG_NAME_W[] =
1602 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_AUDIT_NAME_W[] =
1604 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1606 { '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 };
1607 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1608 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1610 { '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 };
1611 static const WCHAR SE_UNDOCK_NAME_W[] =
1612 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1613 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1614 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1618 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1620 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1622 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1626 NULL,
1627 NULL,
1628 SE_CREATE_TOKEN_NAME_W,
1629 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1630 SE_LOCK_MEMORY_NAME_W,
1631 SE_INCREASE_QUOTA_NAME_W,
1632 SE_MACHINE_ACCOUNT_NAME_W,
1633 SE_TCB_NAME_W,
1634 SE_SECURITY_NAME_W,
1635 SE_TAKE_OWNERSHIP_NAME_W,
1636 SE_LOAD_DRIVER_NAME_W,
1637 SE_SYSTEM_PROFILE_NAME_W,
1638 SE_SYSTEMTIME_NAME_W,
1639 SE_PROF_SINGLE_PROCESS_NAME_W,
1640 SE_INC_BASE_PRIORITY_NAME_W,
1641 SE_CREATE_PAGEFILE_NAME_W,
1642 SE_CREATE_PERMANENT_NAME_W,
1643 SE_BACKUP_NAME_W,
1644 SE_RESTORE_NAME_W,
1645 SE_SHUTDOWN_NAME_W,
1646 SE_DEBUG_NAME_W,
1647 SE_AUDIT_NAME_W,
1648 SE_SYSTEM_ENVIRONMENT_NAME_W,
1649 SE_CHANGE_NOTIFY_NAME_W,
1650 SE_REMOTE_SHUTDOWN_NAME_W,
1651 SE_UNDOCK_NAME_W,
1652 SE_SYNC_AGENT_NAME_W,
1653 SE_ENABLE_DELEGATION_NAME_W,
1654 SE_MANAGE_VOLUME_NAME_W,
1655 SE_IMPERSONATE_NAME_W,
1656 SE_CREATE_GLOBAL_NAME_W,
1659 /******************************************************************************
1660 * LookupPrivilegeValueW [ADVAPI32.@]
1662 * See LookupPrivilegeValueA.
1664 BOOL WINAPI
1665 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1667 UINT i;
1669 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1671 if (!ADVAPI_IsLocalComputer(lpSystemName))
1673 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1674 return FALSE;
1676 if (!lpName)
1678 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1679 return FALSE;
1681 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1683 if( !WellKnownPrivNames[i] )
1684 continue;
1685 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1686 continue;
1687 lpLuid->LowPart = i;
1688 lpLuid->HighPart = 0;
1689 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1690 lpLuid->HighPart, lpLuid->LowPart );
1691 return TRUE;
1693 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1694 return FALSE;
1697 /******************************************************************************
1698 * LookupPrivilegeValueA [ADVAPI32.@]
1700 * Retrieves LUID used on a system to represent the privilege name.
1702 * PARAMS
1703 * lpSystemName [I] Name of the system
1704 * lpName [I] Name of the privilege
1705 * lpLuid [O] Destination for the resulting LUID
1707 * RETURNS
1708 * Success: TRUE. lpLuid contains the requested LUID.
1709 * Failure: FALSE.
1711 BOOL WINAPI
1712 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1714 UNICODE_STRING lpSystemNameW;
1715 UNICODE_STRING lpNameW;
1716 BOOL ret;
1718 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1719 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1720 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1721 RtlFreeUnicodeString(&lpNameW);
1722 RtlFreeUnicodeString(&lpSystemNameW);
1723 return ret;
1726 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1727 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1729 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1730 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1732 return FALSE;
1735 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1736 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1738 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1739 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1741 return FALSE;
1744 /******************************************************************************
1745 * LookupPrivilegeNameA [ADVAPI32.@]
1747 * See LookupPrivilegeNameW.
1749 BOOL WINAPI
1750 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1751 LPDWORD cchName)
1753 UNICODE_STRING lpSystemNameW;
1754 BOOL ret;
1755 DWORD wLen = 0;
1757 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1759 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1760 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1761 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1763 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1765 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1766 &wLen);
1767 if (ret)
1769 /* Windows crashes if cchName is NULL, so will I */
1770 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1771 *cchName, NULL, NULL);
1773 if (len == 0)
1775 /* WideCharToMultiByte failed */
1776 ret = FALSE;
1778 else if (len > *cchName)
1780 *cchName = len;
1781 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1782 ret = FALSE;
1784 else
1786 /* WideCharToMultiByte succeeded, output length needs to be
1787 * length not including NULL terminator
1789 *cchName = len - 1;
1792 HeapFree(GetProcessHeap(), 0, lpNameW);
1794 RtlFreeUnicodeString(&lpSystemNameW);
1795 return ret;
1798 /******************************************************************************
1799 * LookupPrivilegeNameW [ADVAPI32.@]
1801 * Retrieves the privilege name referred to by the LUID lpLuid.
1803 * PARAMS
1804 * lpSystemName [I] Name of the system
1805 * lpLuid [I] Privilege value
1806 * lpName [O] Name of the privilege
1807 * cchName [I/O] Number of characters in lpName.
1809 * RETURNS
1810 * Success: TRUE. lpName contains the name of the privilege whose value is
1811 * *lpLuid.
1812 * Failure: FALSE.
1814 * REMARKS
1815 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1816 * using this function.
1817 * If the length of lpName is too small, on return *cchName will contain the
1818 * number of WCHARs needed to contain the privilege, including the NULL
1819 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1820 * On success, *cchName will contain the number of characters stored in
1821 * lpName, NOT including the NULL terminator.
1823 BOOL WINAPI
1824 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1825 LPDWORD cchName)
1827 size_t privNameLen;
1829 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1831 if (!ADVAPI_IsLocalComputer(lpSystemName))
1833 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1834 return FALSE;
1836 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1837 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1839 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1840 return FALSE;
1842 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1843 /* Windows crashes if cchName is NULL, so will I */
1844 if (*cchName <= privNameLen)
1846 *cchName = privNameLen + 1;
1847 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1848 return FALSE;
1850 else
1852 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1853 *cchName = privNameLen;
1854 return TRUE;
1858 /******************************************************************************
1859 * GetFileSecurityA [ADVAPI32.@]
1861 * Obtains Specified information about the security of a file or directory.
1863 * PARAMS
1864 * lpFileName [I] Name of the file to get info for
1865 * RequestedInformation [I] SE_ flags from "winnt.h"
1866 * pSecurityDescriptor [O] Destination for security information
1867 * nLength [I] Length of pSecurityDescriptor
1868 * lpnLengthNeeded [O] Destination for length of returned security information
1870 * RETURNS
1871 * Success: TRUE. pSecurityDescriptor contains the requested information.
1872 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1874 * NOTES
1875 * The information returned is constrained by the callers access rights and
1876 * privileges.
1878 BOOL WINAPI
1879 GetFileSecurityA( LPCSTR lpFileName,
1880 SECURITY_INFORMATION RequestedInformation,
1881 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1882 DWORD nLength, LPDWORD lpnLengthNeeded )
1884 DWORD len;
1885 BOOL r;
1886 LPWSTR name = NULL;
1888 if( lpFileName )
1890 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1891 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1892 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1895 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1896 nLength, lpnLengthNeeded );
1897 HeapFree( GetProcessHeap(), 0, name );
1899 return r;
1902 /******************************************************************************
1903 * GetFileSecurityW [ADVAPI32.@]
1905 * See GetFileSecurityA.
1907 BOOL WINAPI
1908 GetFileSecurityW( LPCWSTR lpFileName,
1909 SECURITY_INFORMATION RequestedInformation,
1910 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1911 DWORD nLength, LPDWORD lpnLengthNeeded )
1913 HANDLE hfile;
1914 NTSTATUS status;
1915 DWORD access = 0;
1917 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1918 DACL_SECURITY_INFORMATION))
1919 access |= READ_CONTROL;
1920 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1921 access |= ACCESS_SYSTEM_SECURITY;
1923 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1924 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1925 if ( hfile == INVALID_HANDLE_VALUE )
1926 return FALSE;
1928 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1929 nLength, lpnLengthNeeded );
1930 CloseHandle( hfile );
1931 return set_ntstatus( status );
1935 /******************************************************************************
1936 * LookupAccountSidA [ADVAPI32.@]
1938 BOOL WINAPI
1939 LookupAccountSidA(
1940 IN LPCSTR system,
1941 IN PSID sid,
1942 OUT LPSTR account,
1943 IN OUT LPDWORD accountSize,
1944 OUT LPSTR domain,
1945 IN OUT LPDWORD domainSize,
1946 OUT PSID_NAME_USE name_use )
1948 DWORD len;
1949 BOOL r;
1950 LPWSTR systemW = NULL;
1951 LPWSTR accountW = NULL;
1952 LPWSTR domainW = NULL;
1953 DWORD accountSizeW = *accountSize;
1954 DWORD domainSizeW = *domainSize;
1956 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1957 debugstr_a(system),debugstr_sid(sid),
1958 account,accountSize,accountSize?*accountSize:0,
1959 domain,domainSize,domainSize?*domainSize:0,
1960 name_use);
1962 if (system) {
1963 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1964 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1965 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1967 if (account)
1968 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1969 if (domain)
1970 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1972 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1974 if (r) {
1975 if (accountW && *accountSize) {
1976 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1977 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1978 *accountSize = len;
1979 } else
1980 *accountSize = accountSizeW + 1;
1982 if (domainW && *domainSize) {
1983 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1984 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1985 *domainSize = len;
1986 } else
1987 *domainSize = domainSizeW + 1;
1990 HeapFree( GetProcessHeap(), 0, systemW );
1991 HeapFree( GetProcessHeap(), 0, accountW );
1992 HeapFree( GetProcessHeap(), 0, domainW );
1994 return r;
1997 /******************************************************************************
1998 * LookupAccountSidW [ADVAPI32.@]
2000 * PARAMS
2001 * system []
2002 * sid []
2003 * account []
2004 * accountSize []
2005 * domain []
2006 * domainSize []
2007 * name_use []
2010 BOOL WINAPI
2011 LookupAccountSidW(
2012 IN LPCWSTR system,
2013 IN PSID sid,
2014 OUT LPWSTR account,
2015 IN OUT LPDWORD accountSize,
2016 OUT LPWSTR domain,
2017 IN OUT LPDWORD domainSize,
2018 OUT PSID_NAME_USE name_use )
2020 unsigned int i, j;
2021 const WCHAR * ac = NULL;
2022 const WCHAR * dm = NULL;
2023 SID_NAME_USE use = 0;
2024 LPWSTR computer_name = NULL;
2026 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2027 debugstr_w(system),debugstr_sid(sid),
2028 account,accountSize,accountSize?*accountSize:0,
2029 domain,domainSize,domainSize?*domainSize:0,
2030 name_use);
2032 if (!ADVAPI_IsLocalComputer(system)) {
2033 FIXME("Only local computer supported!\n");
2034 SetLastError(ERROR_NONE_MAPPED);
2035 return FALSE;
2038 /* check the well known SIDs first */
2039 for (i = 0; i <= 60; i++) {
2040 if (IsWellKnownSid(sid, i)) {
2041 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2042 if (ACCOUNT_SIDS[j].type == i) {
2043 ac = ACCOUNT_SIDS[j].account;
2044 dm = ACCOUNT_SIDS[j].domain;
2045 use = ACCOUNT_SIDS[j].name_use;
2048 break;
2052 if (dm == NULL) {
2053 MAX_SID local;
2055 /* check for the local computer next */
2056 if (ADVAPI_GetComputerSid(&local)) {
2057 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2058 BOOL result;
2060 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2061 result = GetComputerNameW(computer_name, &size);
2063 if (result) {
2064 if (EqualSid(sid, &local)) {
2065 dm = computer_name;
2066 ac = Blank;
2067 use = 3;
2068 } else {
2069 local.SubAuthorityCount++;
2071 if (EqualPrefixSid(sid, &local)) {
2072 dm = computer_name;
2073 use = 1;
2074 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2075 case DOMAIN_USER_RID_ADMIN:
2076 ac = Administrator;
2077 break;
2078 case DOMAIN_USER_RID_GUEST:
2079 ac = Guest;
2080 break;
2081 case DOMAIN_GROUP_RID_ADMINS:
2082 ac = Domain_Admins;
2083 break;
2084 case DOMAIN_GROUP_RID_USERS:
2085 ac = Domain_Users;
2086 break;
2087 case DOMAIN_GROUP_RID_GUESTS:
2088 ac = Domain_Guests;
2089 break;
2090 case DOMAIN_GROUP_RID_COMPUTERS:
2091 ac = Domain_Computers;
2092 break;
2093 case DOMAIN_GROUP_RID_CONTROLLERS:
2094 ac = Domain_Controllers;
2095 break;
2096 case DOMAIN_GROUP_RID_CERT_ADMINS:
2097 ac = Cert_Publishers;
2098 break;
2099 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2100 ac = Schema_Admins;
2101 break;
2102 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2103 ac = Enterprise_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2106 ac = Group_Policy_Creator_Owners;
2107 break;
2108 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2109 ac = RAS_and_IAS_Servers;
2110 break;
2111 default:
2112 dm = NULL;
2113 break;
2121 if (dm) {
2122 DWORD ac_len = lstrlenW(ac);
2123 DWORD dm_len = lstrlenW(dm);
2124 BOOL status = TRUE;
2126 if (*accountSize > ac_len) {
2127 if (account)
2128 lstrcpyW(account, ac);
2130 if (*domainSize > dm_len) {
2131 if (domain)
2132 lstrcpyW(domain, dm);
2134 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2135 ((*domainSize != 0) && (*domainSize < dm_len))) {
2136 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2137 status = FALSE;
2139 if (*domainSize)
2140 *domainSize = dm_len;
2141 else
2142 *domainSize = dm_len + 1;
2143 if (*accountSize)
2144 *accountSize = ac_len;
2145 else
2146 *accountSize = ac_len + 1;
2147 *name_use = use;
2148 HeapFree(GetProcessHeap(), 0, computer_name);
2149 return status;
2152 HeapFree(GetProcessHeap(), 0, computer_name);
2153 SetLastError(ERROR_NONE_MAPPED);
2154 return FALSE;
2157 /******************************************************************************
2158 * SetFileSecurityA [ADVAPI32.@]
2160 * See SetFileSecurityW.
2162 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2163 SECURITY_INFORMATION RequestedInformation,
2164 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2166 DWORD len;
2167 BOOL r;
2168 LPWSTR name = NULL;
2170 if( lpFileName )
2172 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2173 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2174 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2177 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2178 HeapFree( GetProcessHeap(), 0, name );
2180 return r;
2183 /******************************************************************************
2184 * SetFileSecurityW [ADVAPI32.@]
2186 * Sets the security of a file or directory.
2188 * PARAMS
2189 * lpFileName []
2190 * RequestedInformation []
2191 * pSecurityDescriptor []
2193 * RETURNS
2194 * Success: TRUE.
2195 * Failure: FALSE.
2197 BOOL WINAPI
2198 SetFileSecurityW( LPCWSTR lpFileName,
2199 SECURITY_INFORMATION RequestedInformation,
2200 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2202 HANDLE file;
2203 DWORD access = 0;
2204 NTSTATUS status;
2206 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2207 pSecurityDescriptor );
2209 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2210 RequestedInformation & GROUP_SECURITY_INFORMATION)
2211 access |= WRITE_OWNER;
2212 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2213 access |= ACCESS_SYSTEM_SECURITY;
2214 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2215 access |= WRITE_DAC;
2217 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2218 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2219 if (file == INVALID_HANDLE_VALUE)
2220 return FALSE;
2222 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2223 CloseHandle( file );
2224 return set_ntstatus( status );
2227 /******************************************************************************
2228 * QueryWindows31FilesMigration [ADVAPI32.@]
2230 * PARAMS
2231 * x1 []
2233 BOOL WINAPI
2234 QueryWindows31FilesMigration( DWORD x1 )
2236 FIXME("(%d):stub\n",x1);
2237 return TRUE;
2240 /******************************************************************************
2241 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2243 * PARAMS
2244 * x1 []
2245 * x2 []
2246 * x3 []
2247 * x4 []
2249 BOOL WINAPI
2250 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2251 DWORD x4 )
2253 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2254 return TRUE;
2257 /******************************************************************************
2258 * NotifyBootConfigStatus [ADVAPI32.@]
2260 * PARAMS
2261 * x1 []
2263 BOOL WINAPI
2264 NotifyBootConfigStatus( BOOL x1 )
2266 FIXME("(0x%08d):stub\n",x1);
2267 return 1;
2270 /******************************************************************************
2271 * RevertToSelf [ADVAPI32.@]
2273 * Ends the impersonation of a user.
2275 * PARAMS
2276 * void []
2278 * RETURNS
2279 * Success: TRUE.
2280 * Failure: FALSE.
2282 BOOL WINAPI
2283 RevertToSelf( void )
2285 HANDLE Token = NULL;
2286 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2287 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2290 /******************************************************************************
2291 * ImpersonateSelf [ADVAPI32.@]
2293 * Makes an impersonation token that represents the process user and assigns
2294 * to the current thread.
2296 * PARAMS
2297 * ImpersonationLevel [I] Level at which to impersonate.
2299 * RETURNS
2300 * Success: TRUE.
2301 * Failure: FALSE.
2303 BOOL WINAPI
2304 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2306 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2309 /******************************************************************************
2310 * ImpersonateLoggedOnUser [ADVAPI32.@]
2312 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2314 DWORD size;
2315 NTSTATUS Status;
2316 HANDLE ImpersonationToken;
2317 TOKEN_TYPE Type;
2318 static BOOL warn = TRUE;
2320 if (warn)
2322 FIXME( "(%p)\n", hToken );
2323 warn = FALSE;
2325 if (!GetTokenInformation( hToken, TokenType, &Type,
2326 sizeof(TOKEN_TYPE), &size ))
2327 return FALSE;
2329 if (Type == TokenPrimary)
2331 OBJECT_ATTRIBUTES ObjectAttributes;
2333 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2335 Status = NtDuplicateToken( hToken,
2336 TOKEN_IMPERSONATE | TOKEN_QUERY,
2337 &ObjectAttributes,
2338 SecurityImpersonation,
2339 TokenImpersonation,
2340 &ImpersonationToken );
2341 if (Status != STATUS_SUCCESS)
2343 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2344 SetLastError( RtlNtStatusToDosError( Status ) );
2345 return FALSE;
2348 else
2349 ImpersonationToken = hToken;
2351 Status = NtSetInformationThread( GetCurrentThread(),
2352 ThreadImpersonationToken,
2353 &ImpersonationToken,
2354 sizeof(ImpersonationToken) );
2356 if (Type == TokenPrimary)
2357 NtClose( ImpersonationToken );
2359 if (Status != STATUS_SUCCESS)
2361 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2362 SetLastError( RtlNtStatusToDosError( Status ) );
2363 return FALSE;
2366 return TRUE;
2369 /******************************************************************************
2370 * AccessCheck [ADVAPI32.@]
2372 BOOL WINAPI
2373 AccessCheck(
2374 PSECURITY_DESCRIPTOR SecurityDescriptor,
2375 HANDLE ClientToken,
2376 DWORD DesiredAccess,
2377 PGENERIC_MAPPING GenericMapping,
2378 PPRIVILEGE_SET PrivilegeSet,
2379 LPDWORD PrivilegeSetLength,
2380 LPDWORD GrantedAccess,
2381 LPBOOL AccessStatus)
2383 NTSTATUS access_status;
2384 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2385 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2386 GrantedAccess, &access_status) );
2387 if (ret) *AccessStatus = set_ntstatus( access_status );
2388 return ret;
2392 /******************************************************************************
2393 * AccessCheckByType [ADVAPI32.@]
2395 BOOL WINAPI AccessCheckByType(
2396 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2397 PSID PrincipalSelfSid,
2398 HANDLE ClientToken,
2399 DWORD DesiredAccess,
2400 POBJECT_TYPE_LIST ObjectTypeList,
2401 DWORD ObjectTypeListLength,
2402 PGENERIC_MAPPING GenericMapping,
2403 PPRIVILEGE_SET PrivilegeSet,
2404 LPDWORD PrivilegeSetLength,
2405 LPDWORD GrantedAccess,
2406 LPBOOL AccessStatus)
2408 FIXME("stub\n");
2410 *AccessStatus = TRUE;
2412 return !*AccessStatus;
2415 /******************************************************************************
2416 * MapGenericMask [ADVAPI32.@]
2418 * Maps generic access rights into specific access rights according to the
2419 * supplied mapping.
2421 * PARAMS
2422 * AccessMask [I/O] Access rights.
2423 * GenericMapping [I] The mapping between generic and specific rights.
2425 * RETURNS
2426 * Nothing.
2428 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2430 RtlMapGenericMask( AccessMask, GenericMapping );
2433 /*************************************************************************
2434 * SetKernelObjectSecurity [ADVAPI32.@]
2436 BOOL WINAPI SetKernelObjectSecurity (
2437 IN HANDLE Handle,
2438 IN SECURITY_INFORMATION SecurityInformation,
2439 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2441 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2445 /******************************************************************************
2446 * AddAuditAccessAce [ADVAPI32.@]
2448 BOOL WINAPI AddAuditAccessAce(
2449 IN OUT PACL pAcl,
2450 IN DWORD dwAceRevision,
2451 IN DWORD dwAccessMask,
2452 IN PSID pSid,
2453 IN BOOL bAuditSuccess,
2454 IN BOOL bAuditFailure)
2456 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2457 bAuditSuccess, bAuditFailure) );
2460 /******************************************************************************
2461 * AddAuditAccessAce [ADVAPI32.@]
2463 BOOL WINAPI AddAuditAccessAceEx(
2464 IN OUT PACL pAcl,
2465 IN DWORD dwAceRevision,
2466 IN DWORD dwAceFlags,
2467 IN DWORD dwAccessMask,
2468 IN PSID pSid,
2469 IN BOOL bAuditSuccess,
2470 IN BOOL bAuditFailure)
2472 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2473 bAuditSuccess, bAuditFailure) );
2476 /******************************************************************************
2477 * LookupAccountNameA [ADVAPI32.@]
2479 BOOL WINAPI
2480 LookupAccountNameA(
2481 IN LPCSTR system,
2482 IN LPCSTR account,
2483 OUT PSID sid,
2484 OUT LPDWORD cbSid,
2485 LPSTR ReferencedDomainName,
2486 IN OUT LPDWORD cbReferencedDomainName,
2487 OUT PSID_NAME_USE name_use )
2489 BOOL ret;
2490 UNICODE_STRING lpSystemW;
2491 UNICODE_STRING lpAccountW;
2492 LPWSTR lpReferencedDomainNameW = NULL;
2494 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2495 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2497 if (ReferencedDomainName)
2498 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2500 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2501 cbReferencedDomainName, name_use);
2503 if (ret && lpReferencedDomainNameW)
2505 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2506 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2509 RtlFreeUnicodeString(&lpSystemW);
2510 RtlFreeUnicodeString(&lpAccountW);
2511 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2513 return ret;
2516 /******************************************************************************
2517 * LookupAccountNameW [ADVAPI32.@]
2519 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2520 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2521 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2523 /* Default implementation: Always return a default SID */
2524 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2525 BOOL ret;
2526 PSID pSid;
2527 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2528 unsigned int i;
2530 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2531 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2533 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2535 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2537 if (*cchReferencedDomainName)
2538 *ReferencedDomainName = '\0';
2539 *cchReferencedDomainName = 0;
2540 *peUse = SidTypeWellKnownGroup;
2541 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
2545 ret = AllocateAndInitializeSid(&identifierAuthority,
2547 SECURITY_BUILTIN_DOMAIN_RID,
2548 DOMAIN_ALIAS_RID_ADMINS,
2549 0, 0, 0, 0, 0, 0,
2550 &pSid);
2552 if (!ret)
2553 return FALSE;
2555 if (!RtlValidSid(pSid))
2557 FreeSid(pSid);
2558 return FALSE;
2561 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2562 CopySid(*cbSid, Sid, pSid);
2563 if (*cbSid < GetLengthSid(pSid))
2565 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2566 ret = FALSE;
2568 *cbSid = GetLengthSid(pSid);
2570 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2571 strcpyW(ReferencedDomainName, dm);
2573 if (*cchReferencedDomainName <= strlenW(dm))
2575 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2576 ret = FALSE;
2579 *cchReferencedDomainName = strlenW(dm)+1;
2581 FreeSid(pSid);
2583 return ret;
2586 /******************************************************************************
2587 * PrivilegeCheck [ADVAPI32.@]
2589 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2591 BOOL ret;
2592 BOOLEAN Result;
2594 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2596 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2597 if (ret)
2598 *pfResult = Result;
2599 return ret;
2602 /******************************************************************************
2603 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2605 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2606 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2607 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2608 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2610 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2611 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2612 SecurityDescriptor, DesiredAccess, GenericMapping,
2613 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2614 return TRUE;
2617 /******************************************************************************
2618 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2620 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2621 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2622 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2623 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2625 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2626 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2627 SecurityDescriptor, DesiredAccess, GenericMapping,
2628 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2629 return TRUE;
2632 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2634 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2636 return TRUE;
2639 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2641 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2643 return TRUE;
2646 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2648 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2650 return TRUE;
2653 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2654 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2655 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2656 LPBOOL GenerateOnClose)
2658 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2659 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2660 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2661 GenerateOnClose);
2663 return TRUE;
2666 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2667 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2668 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2669 LPBOOL GenerateOnClose)
2671 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2672 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2673 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2674 GenerateOnClose);
2676 return TRUE;
2679 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2680 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2682 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2683 DesiredAccess, Privileges, AccessGranted);
2685 return TRUE;
2688 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2689 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2691 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2692 DesiredAccess, Privileges, AccessGranted);
2694 return TRUE;
2697 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2698 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2700 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2701 ClientToken, Privileges, AccessGranted);
2703 return TRUE;
2706 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2707 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2709 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2710 ClientToken, Privileges, AccessGranted);
2712 return TRUE;
2715 /******************************************************************************
2716 * GetSecurityInfo [ADVAPI32.@]
2718 * Retrieves a copy of the security descriptor associated with an object.
2720 * PARAMS
2721 * hObject [I] A handle for the object.
2722 * ObjectType [I] The type of object.
2723 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2724 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2725 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2726 * ppDacl [O] If non-null, receives a pointer to the DACL.
2727 * ppSacl [O] If non-null, receives a pointer to the SACL.
2728 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2729 * which must be freed with LocalFree.
2731 * RETURNS
2732 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2734 DWORD WINAPI GetSecurityInfo(
2735 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2736 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2737 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2738 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2741 PSECURITY_DESCRIPTOR sd;
2742 NTSTATUS status;
2743 ULONG n1, n2;
2744 BOOL present, defaulted;
2746 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2747 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2748 return RtlNtStatusToDosError(status);
2750 sd = LocalAlloc(0, n1);
2751 if (!sd)
2752 return ERROR_NOT_ENOUGH_MEMORY;
2754 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2755 if (status != STATUS_SUCCESS)
2757 LocalFree(sd);
2758 return RtlNtStatusToDosError(status);
2761 if (ppsidOwner)
2763 *ppsidOwner = NULL;
2764 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2766 if (ppsidGroup)
2768 *ppsidGroup = NULL;
2769 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2771 if (ppDacl)
2773 *ppDacl = NULL;
2774 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2776 if (ppSacl)
2778 *ppSacl = NULL;
2779 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2781 if (ppSecurityDescriptor)
2782 *ppSecurityDescriptor = sd;
2784 return ERROR_SUCCESS;
2787 /******************************************************************************
2788 * GetSecurityInfoExW [ADVAPI32.@]
2790 DWORD WINAPI GetSecurityInfoExW(
2791 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2792 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2793 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2794 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2797 FIXME("stub!\n");
2798 return ERROR_BAD_PROVIDER;
2801 /******************************************************************************
2802 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2804 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2805 LPSTR pTrusteeName, DWORD AccessPermissions,
2806 ACCESS_MODE AccessMode, DWORD Inheritance )
2808 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2809 AccessPermissions, AccessMode, Inheritance);
2811 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2812 pExplicitAccess->grfAccessMode = AccessMode;
2813 pExplicitAccess->grfInheritance = Inheritance;
2815 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2816 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2817 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2818 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2819 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2822 /******************************************************************************
2823 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2825 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2826 LPWSTR pTrusteeName, DWORD AccessPermissions,
2827 ACCESS_MODE AccessMode, DWORD Inheritance )
2829 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2830 AccessPermissions, AccessMode, Inheritance);
2832 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2833 pExplicitAccess->grfAccessMode = AccessMode;
2834 pExplicitAccess->grfInheritance = Inheritance;
2836 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2837 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2838 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2839 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2840 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2843 /******************************************************************************
2844 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2846 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2847 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2848 LPSTR InheritedObjectTypeName, LPSTR Name )
2850 DWORD ObjectsPresent = 0;
2852 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2853 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2855 /* Fill the OBJECTS_AND_NAME structure */
2856 pObjName->ObjectType = ObjectType;
2857 if (ObjectTypeName != NULL)
2859 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2862 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2863 if (InheritedObjectTypeName != NULL)
2865 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2868 pObjName->ObjectsPresent = ObjectsPresent;
2869 pObjName->ptstrName = Name;
2871 /* Fill the TRUSTEE structure */
2872 pTrustee->pMultipleTrustee = NULL;
2873 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2874 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2875 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2876 pTrustee->ptstrName = (LPSTR)pObjName;
2879 /******************************************************************************
2880 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2882 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2883 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2884 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2886 DWORD ObjectsPresent = 0;
2888 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2889 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2891 /* Fill the OBJECTS_AND_NAME structure */
2892 pObjName->ObjectType = ObjectType;
2893 if (ObjectTypeName != NULL)
2895 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2898 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2899 if (InheritedObjectTypeName != NULL)
2901 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2904 pObjName->ObjectsPresent = ObjectsPresent;
2905 pObjName->ptstrName = Name;
2907 /* Fill the TRUSTEE structure */
2908 pTrustee->pMultipleTrustee = NULL;
2909 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2910 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2911 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2912 pTrustee->ptstrName = (LPWSTR)pObjName;
2915 /******************************************************************************
2916 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2918 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2919 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2921 DWORD ObjectsPresent = 0;
2923 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2925 /* Fill the OBJECTS_AND_SID structure */
2926 if (pObjectGuid != NULL)
2928 pObjSid->ObjectTypeGuid = *pObjectGuid;
2929 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2931 else
2933 ZeroMemory(&pObjSid->ObjectTypeGuid,
2934 sizeof(GUID));
2937 if (pInheritedObjectGuid != NULL)
2939 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2940 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2942 else
2944 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2945 sizeof(GUID));
2948 pObjSid->ObjectsPresent = ObjectsPresent;
2949 pObjSid->pSid = pSid;
2951 /* Fill the TRUSTEE structure */
2952 pTrustee->pMultipleTrustee = NULL;
2953 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2954 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2955 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2956 pTrustee->ptstrName = (LPSTR) pObjSid;
2959 /******************************************************************************
2960 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2962 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2963 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2965 DWORD ObjectsPresent = 0;
2967 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2969 /* Fill the OBJECTS_AND_SID structure */
2970 if (pObjectGuid != NULL)
2972 pObjSid->ObjectTypeGuid = *pObjectGuid;
2973 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2975 else
2977 ZeroMemory(&pObjSid->ObjectTypeGuid,
2978 sizeof(GUID));
2981 if (pInheritedObjectGuid != NULL)
2983 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2984 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2986 else
2988 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2989 sizeof(GUID));
2992 pObjSid->ObjectsPresent = ObjectsPresent;
2993 pObjSid->pSid = pSid;
2995 /* Fill the TRUSTEE structure */
2996 pTrustee->pMultipleTrustee = NULL;
2997 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2998 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2999 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3000 pTrustee->ptstrName = (LPWSTR) pObjSid;
3003 /******************************************************************************
3004 * BuildTrusteeWithSidA [ADVAPI32.@]
3006 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3008 TRACE("%p %p\n", pTrustee, pSid);
3010 pTrustee->pMultipleTrustee = NULL;
3011 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3012 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3013 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3014 pTrustee->ptstrName = (LPSTR) pSid;
3017 /******************************************************************************
3018 * BuildTrusteeWithSidW [ADVAPI32.@]
3020 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3022 TRACE("%p %p\n", pTrustee, pSid);
3024 pTrustee->pMultipleTrustee = NULL;
3025 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3026 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3027 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3028 pTrustee->ptstrName = (LPWSTR) pSid;
3031 /******************************************************************************
3032 * BuildTrusteeWithNameA [ADVAPI32.@]
3034 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3036 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3038 pTrustee->pMultipleTrustee = NULL;
3039 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3040 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3041 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3042 pTrustee->ptstrName = name;
3045 /******************************************************************************
3046 * BuildTrusteeWithNameW [ADVAPI32.@]
3048 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3050 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3052 pTrustee->pMultipleTrustee = NULL;
3053 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3054 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3055 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3056 pTrustee->ptstrName = name;
3059 /******************************************************************************
3060 * GetTrusteeFormA [ADVAPI32.@]
3062 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3064 TRACE("(%p)\n", pTrustee);
3066 if (!pTrustee)
3067 return TRUSTEE_BAD_FORM;
3069 return pTrustee->TrusteeForm;
3072 /******************************************************************************
3073 * GetTrusteeFormW [ADVAPI32.@]
3075 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3077 TRACE("(%p)\n", pTrustee);
3079 if (!pTrustee)
3080 return TRUSTEE_BAD_FORM;
3082 return pTrustee->TrusteeForm;
3085 /******************************************************************************
3086 * GetTrusteeNameA [ADVAPI32.@]
3088 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3090 TRACE("(%p)\n", pTrustee);
3092 if (!pTrustee)
3093 return NULL;
3095 return pTrustee->ptstrName;
3098 /******************************************************************************
3099 * GetTrusteeNameW [ADVAPI32.@]
3101 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3103 TRACE("(%p)\n", pTrustee);
3105 if (!pTrustee)
3106 return NULL;
3108 return pTrustee->ptstrName;
3111 /******************************************************************************
3112 * GetTrusteeTypeA [ADVAPI32.@]
3114 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3116 TRACE("(%p)\n", pTrustee);
3118 if (!pTrustee)
3119 return TRUSTEE_IS_UNKNOWN;
3121 return pTrustee->TrusteeType;
3124 /******************************************************************************
3125 * GetTrusteeTypeW [ADVAPI32.@]
3127 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3129 TRACE("(%p)\n", pTrustee);
3131 if (!pTrustee)
3132 return TRUSTEE_IS_UNKNOWN;
3134 return pTrustee->TrusteeType;
3137 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3138 DWORD nAclInformationLength,
3139 ACL_INFORMATION_CLASS dwAclInformationClass )
3141 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3142 nAclInformationLength, dwAclInformationClass);
3144 return TRUE;
3147 /******************************************************************************
3148 * SetEntriesInAclA [ADVAPI32.@]
3150 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3151 PACL OldAcl, PACL* NewAcl )
3153 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3154 if (NewAcl)
3155 *NewAcl = NULL;
3156 return ERROR_SUCCESS;
3159 /******************************************************************************
3160 * SetEntriesInAclW [ADVAPI32.@]
3162 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3163 PACL OldAcl, PACL* NewAcl )
3165 ULONG i;
3166 PSID *ppsid;
3167 DWORD ret = ERROR_SUCCESS;
3168 DWORD acl_size = sizeof(ACL);
3169 NTSTATUS status;
3171 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3173 *NewAcl = NULL;
3175 if (!count && !OldAcl)
3176 return ERROR_SUCCESS;
3178 /* allocate array of maximum sized sids allowed */
3179 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3180 if (!ppsid)
3181 return ERROR_OUTOFMEMORY;
3183 for (i = 0; i < count; i++)
3185 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3187 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3188 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3189 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3190 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3191 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3192 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3193 pEntries[i].Trustee.ptstrName);
3195 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3197 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3198 ret = ERROR_INVALID_PARAMETER;
3199 goto exit;
3202 switch (pEntries[i].Trustee.TrusteeForm)
3204 case TRUSTEE_IS_SID:
3205 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3206 ppsid[i], pEntries[i].Trustee.ptstrName))
3208 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3209 ret = ERROR_INVALID_PARAMETER;
3210 goto exit;
3212 break;
3213 case TRUSTEE_IS_NAME:
3215 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3216 DWORD domain_size = 0;
3217 SID_NAME_USE use;
3218 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3220 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3221 ret = ERROR_INVALID_PARAMETER;
3222 goto exit;
3224 break;
3226 case TRUSTEE_IS_OBJECTS_AND_SID:
3227 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3228 break;
3229 case TRUSTEE_IS_OBJECTS_AND_NAME:
3230 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3231 break;
3232 default:
3233 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3234 ret = ERROR_INVALID_PARAMETER;
3235 goto exit;
3238 /* Note: we overestimate the ACL size here as a tradeoff between
3239 * instructions (simplicity) and memory */
3240 switch (pEntries[i].grfAccessMode)
3242 case GRANT_ACCESS:
3243 case SET_ACCESS:
3244 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3245 break;
3246 case DENY_ACCESS:
3247 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3248 break;
3249 case SET_AUDIT_SUCCESS:
3250 case SET_AUDIT_FAILURE:
3251 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3252 break;
3253 case REVOKE_ACCESS:
3254 break;
3255 default:
3256 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3257 ret = ERROR_INVALID_PARAMETER;
3258 goto exit;
3262 if (OldAcl)
3264 ACL_SIZE_INFORMATION size_info;
3266 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3267 if (status != STATUS_SUCCESS)
3269 ret = RtlNtStatusToDosError(status);
3270 goto exit;
3272 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3275 *NewAcl = LocalAlloc(0, acl_size);
3276 if (!*NewAcl)
3278 ret = ERROR_OUTOFMEMORY;
3279 goto exit;
3282 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3283 if (status != STATUS_SUCCESS)
3285 ret = RtlNtStatusToDosError(status);
3286 goto exit;
3289 for (i = 0; i < count; i++)
3291 switch (pEntries[i].grfAccessMode)
3293 case GRANT_ACCESS:
3294 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3295 pEntries[i].grfInheritance,
3296 pEntries[i].grfAccessPermissions,
3297 ppsid[i]);
3298 break;
3299 case SET_ACCESS:
3301 ULONG j;
3302 BOOL add = TRUE;
3303 if (OldAcl)
3305 for (j = 0; ; j++)
3307 const ACE_HEADER *existing_ace_header;
3308 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3309 if (status != STATUS_SUCCESS)
3310 break;
3311 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3312 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3313 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3315 add = FALSE;
3316 break;
3320 if (add)
3321 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3322 pEntries[i].grfInheritance,
3323 pEntries[i].grfAccessPermissions,
3324 ppsid[i]);
3325 break;
3327 case DENY_ACCESS:
3328 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3329 pEntries[i].grfInheritance,
3330 pEntries[i].grfAccessPermissions,
3331 ppsid[i]);
3332 break;
3333 case SET_AUDIT_SUCCESS:
3334 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3335 pEntries[i].grfInheritance,
3336 pEntries[i].grfAccessPermissions,
3337 ppsid[i], TRUE, FALSE);
3338 break;
3339 case SET_AUDIT_FAILURE:
3340 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3341 pEntries[i].grfInheritance,
3342 pEntries[i].grfAccessPermissions,
3343 ppsid[i], FALSE, TRUE);
3344 break;
3345 default:
3346 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3350 if (OldAcl)
3352 for (i = 0; ; i++)
3354 BOOL add = TRUE;
3355 ULONG j;
3356 const ACE_HEADER *old_ace_header;
3357 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3358 if (status != STATUS_SUCCESS) break;
3359 for (j = 0; j < count; j++)
3361 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3362 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3363 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3365 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3366 add = FALSE;
3367 break;
3369 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3371 switch (old_ace_header->AceType)
3373 case ACCESS_ALLOWED_ACE_TYPE:
3374 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3375 add = FALSE;
3376 break;
3377 case ACCESS_DENIED_ACE_TYPE:
3378 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3379 add = FALSE;
3380 break;
3381 case SYSTEM_AUDIT_ACE_TYPE:
3382 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3383 add = FALSE;
3384 break;
3385 case SYSTEM_ALARM_ACE_TYPE:
3386 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3387 add = FALSE;
3388 break;
3389 default:
3390 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3393 if (!add)
3394 break;
3397 if (add)
3398 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3399 if (status != STATUS_SUCCESS)
3401 WARN("RtlAddAce failed with error 0x%08x\n", status);
3402 ret = RtlNtStatusToDosError(status);
3403 break;
3408 exit:
3409 HeapFree(GetProcessHeap(), 0, ppsid);
3410 return ret;
3413 /******************************************************************************
3414 * SetNamedSecurityInfoA [ADVAPI32.@]
3416 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3417 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3418 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3420 DWORD len;
3421 LPWSTR wstr = NULL;
3422 DWORD r;
3424 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3425 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3427 if( pObjectName )
3429 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3430 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3431 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3434 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3435 psidGroup, pDacl, pSacl );
3437 HeapFree( GetProcessHeap(), 0, wstr );
3439 return r;
3442 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3443 PSECURITY_DESCRIPTOR ModificationDescriptor,
3444 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3445 PGENERIC_MAPPING GenericMapping,
3446 HANDLE Token )
3448 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3449 ObjectsSecurityDescriptor, GenericMapping, Token);
3451 return TRUE;
3454 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3456 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3459 /******************************************************************************
3460 * AreAnyAccessesGranted [ADVAPI32.@]
3462 * Determines whether or not any of a set of specified access permissions have
3463 * been granted or not.
3465 * PARAMS
3466 * GrantedAccess [I] The permissions that have been granted.
3467 * DesiredAccess [I] The permissions that you want to have.
3469 * RETURNS
3470 * Nonzero if any of the permissions have been granted, zero if none of the
3471 * permissions have been granted.
3474 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3476 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3479 /******************************************************************************
3480 * SetNamedSecurityInfoW [ADVAPI32.@]
3482 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3483 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3484 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3486 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3487 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3488 return ERROR_SUCCESS;
3491 /******************************************************************************
3492 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3494 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3495 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3497 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3498 return ERROR_CALL_NOT_IMPLEMENTED;
3501 /******************************************************************************
3502 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3504 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3505 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3507 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3508 return ERROR_CALL_NOT_IMPLEMENTED;
3511 /******************************************************************************
3512 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3514 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3515 PACCESS_MASK pFailedAuditRights)
3517 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3518 return ERROR_CALL_NOT_IMPLEMENTED;
3522 /******************************************************************************
3523 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3525 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3526 PACCESS_MASK pFailedAuditRights)
3528 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3529 return ERROR_CALL_NOT_IMPLEMENTED;
3533 /******************************************************************************
3534 * ParseAclStringFlags
3536 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3538 DWORD flags = 0;
3539 LPCWSTR szAcl = *StringAcl;
3541 while (*szAcl != '(')
3543 if (*szAcl == 'P')
3545 flags |= SE_DACL_PROTECTED;
3547 else if (*szAcl == 'A')
3549 szAcl++;
3550 if (*szAcl == 'R')
3551 flags |= SE_DACL_AUTO_INHERIT_REQ;
3552 else if (*szAcl == 'I')
3553 flags |= SE_DACL_AUTO_INHERITED;
3555 szAcl++;
3558 *StringAcl = szAcl;
3559 return flags;
3562 /******************************************************************************
3563 * ParseAceStringType
3565 static const ACEFLAG AceType[] =
3567 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3568 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3569 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3570 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3572 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3573 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3574 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3575 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3577 { NULL, 0 },
3580 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3582 UINT len = 0;
3583 LPCWSTR szAcl = *StringAcl;
3584 const ACEFLAG *lpaf = AceType;
3586 while (lpaf->wstr &&
3587 (len = strlenW(lpaf->wstr)) &&
3588 strncmpW(lpaf->wstr, szAcl, len))
3589 lpaf++;
3591 if (!lpaf->wstr)
3592 return 0;
3594 *StringAcl += len;
3595 return lpaf->value;
3599 /******************************************************************************
3600 * ParseAceStringFlags
3602 static const ACEFLAG AceFlags[] =
3604 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3605 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3606 { SDDL_INHERITED, INHERITED_ACE },
3607 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3608 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3609 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3610 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3611 { NULL, 0 },
3614 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3616 UINT len = 0;
3617 BYTE flags = 0;
3618 LPCWSTR szAcl = *StringAcl;
3620 while (*szAcl != ';')
3622 const ACEFLAG *lpaf = AceFlags;
3624 while (lpaf->wstr &&
3625 (len = strlenW(lpaf->wstr)) &&
3626 strncmpW(lpaf->wstr, szAcl, len))
3627 lpaf++;
3629 if (!lpaf->wstr)
3630 return 0;
3632 flags |= lpaf->value;
3633 szAcl += len;
3636 *StringAcl = szAcl;
3637 return flags;
3641 /******************************************************************************
3642 * ParseAceStringRights
3644 static const ACEFLAG AceRights[] =
3646 { SDDL_GENERIC_ALL, GENERIC_ALL },
3647 { SDDL_GENERIC_READ, GENERIC_READ },
3648 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3649 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3651 { SDDL_READ_CONTROL, READ_CONTROL },
3652 { SDDL_STANDARD_DELETE, DELETE },
3653 { SDDL_WRITE_DAC, WRITE_DAC },
3654 { SDDL_WRITE_OWNER, WRITE_OWNER },
3656 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3657 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3658 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3659 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3660 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3661 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3662 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3663 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3664 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3666 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3667 { SDDL_FILE_READ, FILE_GENERIC_READ },
3668 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3669 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3671 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3672 { SDDL_KEY_READ, KEY_READ },
3673 { SDDL_KEY_WRITE, KEY_WRITE },
3674 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3675 { NULL, 0 },
3678 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3680 UINT len = 0;
3681 DWORD rights = 0;
3682 LPCWSTR szAcl = *StringAcl;
3684 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3686 LPCWSTR p = szAcl;
3688 while (*p && *p != ';')
3689 p++;
3691 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3693 rights = strtoulW(szAcl, NULL, 16);
3694 szAcl = p;
3696 else
3697 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3699 else
3701 while (*szAcl != ';')
3703 const ACEFLAG *lpaf = AceRights;
3705 while (lpaf->wstr &&
3706 (len = strlenW(lpaf->wstr)) &&
3707 strncmpW(lpaf->wstr, szAcl, len))
3709 lpaf++;
3712 if (!lpaf->wstr)
3713 return 0;
3715 rights |= lpaf->value;
3716 szAcl += len;
3720 *StringAcl = szAcl;
3721 return rights;
3725 /******************************************************************************
3726 * ParseStringAclToAcl
3728 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3730 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3731 PACL pAcl, LPDWORD cBytes)
3733 DWORD val;
3734 DWORD sidlen;
3735 DWORD length = sizeof(ACL);
3736 DWORD acesize = 0;
3737 DWORD acecount = 0;
3738 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3740 TRACE("%s\n", debugstr_w(StringAcl));
3742 if (!StringAcl)
3743 return FALSE;
3745 if (pAcl) /* pAce is only useful if we're setting values */
3746 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3748 /* Parse ACL flags */
3749 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3751 /* Parse ACE */
3752 while (*StringAcl == '(')
3754 StringAcl++;
3756 /* Parse ACE type */
3757 val = ParseAceStringType(&StringAcl);
3758 if (pAce)
3759 pAce->Header.AceType = (BYTE) val;
3760 if (*StringAcl != ';')
3761 goto lerr;
3762 StringAcl++;
3764 /* Parse ACE flags */
3765 val = ParseAceStringFlags(&StringAcl);
3766 if (pAce)
3767 pAce->Header.AceFlags = (BYTE) val;
3768 if (*StringAcl != ';')
3769 goto lerr;
3770 StringAcl++;
3772 /* Parse ACE rights */
3773 val = ParseAceStringRights(&StringAcl);
3774 if (pAce)
3775 pAce->Mask = val;
3776 if (*StringAcl != ';')
3777 goto lerr;
3778 StringAcl++;
3780 /* Parse ACE object guid */
3781 if (*StringAcl != ';')
3783 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3784 goto lerr;
3786 StringAcl++;
3788 /* Parse ACE inherit object guid */
3789 if (*StringAcl != ';')
3791 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3792 goto lerr;
3794 StringAcl++;
3796 /* Parse ACE account sid */
3797 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3799 while (*StringAcl && *StringAcl != ')')
3800 StringAcl++;
3803 if (*StringAcl != ')')
3804 goto lerr;
3805 StringAcl++;
3807 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3808 length += acesize;
3809 if (pAce)
3811 pAce->Header.AceSize = acesize;
3812 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3814 acecount++;
3817 *cBytes = length;
3819 if (length > 0xffff)
3821 ERR("ACL too large\n");
3822 goto lerr;
3825 if (pAcl)
3827 pAcl->AclRevision = ACL_REVISION;
3828 pAcl->Sbz1 = 0;
3829 pAcl->AclSize = length;
3830 pAcl->AceCount = acecount++;
3831 pAcl->Sbz2 = 0;
3833 return TRUE;
3835 lerr:
3836 SetLastError(ERROR_INVALID_ACL);
3837 WARN("Invalid ACE string format\n");
3838 return FALSE;
3842 /******************************************************************************
3843 * ParseStringSecurityDescriptorToSecurityDescriptor
3845 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3846 LPCWSTR StringSecurityDescriptor,
3847 SECURITY_DESCRIPTOR* SecurityDescriptor,
3848 LPDWORD cBytes)
3850 BOOL bret = FALSE;
3851 WCHAR toktype;
3852 WCHAR tok[MAX_PATH];
3853 LPCWSTR lptoken;
3854 LPBYTE lpNext = NULL;
3855 DWORD len;
3857 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3859 if (SecurityDescriptor)
3860 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3862 while (*StringSecurityDescriptor)
3864 toktype = *StringSecurityDescriptor;
3866 /* Expect char identifier followed by ':' */
3867 StringSecurityDescriptor++;
3868 if (*StringSecurityDescriptor != ':')
3870 SetLastError(ERROR_INVALID_PARAMETER);
3871 goto lend;
3873 StringSecurityDescriptor++;
3875 /* Extract token */
3876 lptoken = StringSecurityDescriptor;
3877 while (*lptoken && *lptoken != ':')
3878 lptoken++;
3880 if (*lptoken)
3881 lptoken--;
3883 len = lptoken - StringSecurityDescriptor;
3884 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3885 tok[len] = 0;
3887 switch (toktype)
3889 case 'O':
3891 DWORD bytes;
3893 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3894 goto lend;
3896 if (SecurityDescriptor)
3898 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3899 lpNext += bytes; /* Advance to next token */
3902 *cBytes += bytes;
3904 break;
3907 case 'G':
3909 DWORD bytes;
3911 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3912 goto lend;
3914 if (SecurityDescriptor)
3916 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3917 lpNext += bytes; /* Advance to next token */
3920 *cBytes += bytes;
3922 break;
3925 case 'D':
3927 DWORD flags;
3928 DWORD bytes;
3930 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3931 goto lend;
3933 if (SecurityDescriptor)
3935 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3936 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3937 lpNext += bytes; /* Advance to next token */
3940 *cBytes += bytes;
3942 break;
3945 case 'S':
3947 DWORD flags;
3948 DWORD bytes;
3950 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3951 goto lend;
3953 if (SecurityDescriptor)
3955 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3956 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3957 lpNext += bytes; /* Advance to next token */
3960 *cBytes += bytes;
3962 break;
3965 default:
3966 FIXME("Unknown token\n");
3967 SetLastError(ERROR_INVALID_PARAMETER);
3968 goto lend;
3971 StringSecurityDescriptor = lptoken;
3974 bret = TRUE;
3976 lend:
3977 return bret;
3980 /******************************************************************************
3981 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3983 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3984 LPCSTR StringSecurityDescriptor,
3985 DWORD StringSDRevision,
3986 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3987 PULONG SecurityDescriptorSize)
3989 UINT len;
3990 BOOL ret = FALSE;
3991 LPWSTR StringSecurityDescriptorW;
3993 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3994 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3996 if (StringSecurityDescriptorW)
3998 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4000 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4001 StringSDRevision, SecurityDescriptor,
4002 SecurityDescriptorSize);
4003 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4006 return ret;
4009 /******************************************************************************
4010 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4012 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4013 LPCWSTR StringSecurityDescriptor,
4014 DWORD StringSDRevision,
4015 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4016 PULONG SecurityDescriptorSize)
4018 DWORD cBytes;
4019 SECURITY_DESCRIPTOR* psd;
4020 BOOL bret = FALSE;
4022 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4024 if (GetVersion() & 0x80000000)
4026 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4027 goto lend;
4029 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4031 SetLastError(ERROR_INVALID_PARAMETER);
4032 goto lend;
4034 else if (StringSDRevision != SID_REVISION)
4036 SetLastError(ERROR_UNKNOWN_REVISION);
4037 goto lend;
4040 /* Compute security descriptor length */
4041 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4042 NULL, &cBytes))
4043 goto lend;
4045 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4046 GMEM_ZEROINIT, cBytes);
4047 if (!psd) goto lend;
4049 psd->Revision = SID_REVISION;
4050 psd->Control |= SE_SELF_RELATIVE;
4052 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4053 psd, &cBytes))
4055 LocalFree(psd);
4056 goto lend;
4059 if (SecurityDescriptorSize)
4060 *SecurityDescriptorSize = cBytes;
4062 bret = TRUE;
4064 lend:
4065 TRACE(" ret=%d\n", bret);
4066 return bret;
4069 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4071 if (cch == -1)
4072 cch = strlenW(string);
4074 if (plen)
4075 *plen += cch;
4077 if (pwptr)
4079 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4080 *pwptr += cch;
4084 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4086 DWORD i;
4087 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4088 WCHAR subauthfmt[] = { '-','%','u',0 };
4089 WCHAR buf[26];
4090 SID *pisid = psid;
4092 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4094 SetLastError(ERROR_INVALID_SID);
4095 return FALSE;
4098 if (pisid->IdentifierAuthority.Value[0] ||
4099 pisid->IdentifierAuthority.Value[1])
4101 FIXME("not matching MS' bugs\n");
4102 SetLastError(ERROR_INVALID_SID);
4103 return FALSE;
4106 sprintfW( buf, fmt, pisid->Revision,
4107 MAKELONG(
4108 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4109 pisid->IdentifierAuthority.Value[4] ),
4110 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4111 pisid->IdentifierAuthority.Value[2] )
4112 ) );
4113 DumpString(buf, -1, pwptr, plen);
4115 for( i=0; i<pisid->SubAuthorityCount; i++ )
4117 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4118 DumpString(buf, -1, pwptr, plen);
4120 return TRUE;
4123 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4125 size_t i;
4126 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4128 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4130 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4131 return TRUE;
4135 return DumpSidNumeric(psid, pwptr, plen);
4138 static const LPCWSTR AceRightBitNames[32] = {
4139 SDDL_CREATE_CHILD, /* 0 */
4140 SDDL_DELETE_CHILD,
4141 SDDL_LIST_CHILDREN,
4142 SDDL_SELF_WRITE,
4143 SDDL_READ_PROPERTY, /* 4 */
4144 SDDL_WRITE_PROPERTY,
4145 SDDL_DELETE_TREE,
4146 SDDL_LIST_OBJECT,
4147 SDDL_CONTROL_ACCESS, /* 8 */
4148 NULL,
4149 NULL,
4150 NULL,
4151 NULL, /* 12 */
4152 NULL,
4153 NULL,
4154 NULL,
4155 SDDL_STANDARD_DELETE, /* 16 */
4156 SDDL_READ_CONTROL,
4157 SDDL_WRITE_DAC,
4158 SDDL_WRITE_OWNER,
4159 NULL, /* 20 */
4160 NULL,
4161 NULL,
4162 NULL,
4163 NULL, /* 24 */
4164 NULL,
4165 NULL,
4166 NULL,
4167 SDDL_GENERIC_ALL, /* 28 */
4168 SDDL_GENERIC_EXECUTE,
4169 SDDL_GENERIC_WRITE,
4170 SDDL_GENERIC_READ
4173 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4175 static const WCHAR fmtW[] = {'0','x','%','x',0};
4176 WCHAR buf[15];
4177 size_t i;
4179 if (mask == 0)
4180 return;
4182 /* first check if the right have name */
4183 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4185 if (AceRights[i].wstr == NULL)
4186 break;
4187 if (mask == AceRights[i].value)
4189 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4190 return;
4194 /* then check if it can be built from bit names */
4195 for (i = 0; i < 32; i++)
4197 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4199 /* can't be built from bit names */
4200 sprintfW(buf, fmtW, mask);
4201 DumpString(buf, -1, pwptr, plen);
4202 return;
4206 /* build from bit names */
4207 for (i = 0; i < 32; i++)
4208 if (mask & (1 << i))
4209 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4212 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4214 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4215 static const WCHAR openbr = '(';
4216 static const WCHAR closebr = ')';
4217 static const WCHAR semicolon = ';';
4219 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4221 SetLastError(ERROR_INVALID_ACL);
4222 return FALSE;
4225 piace = (ACCESS_ALLOWED_ACE *)pace;
4226 DumpString(&openbr, 1, pwptr, plen);
4227 switch (piace->Header.AceType)
4229 case ACCESS_ALLOWED_ACE_TYPE:
4230 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4231 break;
4232 case ACCESS_DENIED_ACE_TYPE:
4233 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4234 break;
4235 case SYSTEM_AUDIT_ACE_TYPE:
4236 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4237 break;
4238 case SYSTEM_ALARM_ACE_TYPE:
4239 DumpString(SDDL_ALARM, -1, pwptr, plen);
4240 break;
4242 DumpString(&semicolon, 1, pwptr, plen);
4244 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4245 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4246 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4247 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4248 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4249 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4250 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4251 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4252 if (piace->Header.AceFlags & INHERITED_ACE)
4253 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4254 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4255 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4256 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4257 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4258 DumpString(&semicolon, 1, pwptr, plen);
4259 DumpRights(piace->Mask, pwptr, plen);
4260 DumpString(&semicolon, 1, pwptr, plen);
4261 /* objects not supported */
4262 DumpString(&semicolon, 1, pwptr, plen);
4263 /* objects not supported */
4264 DumpString(&semicolon, 1, pwptr, plen);
4265 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4266 return FALSE;
4267 DumpString(&closebr, 1, pwptr, plen);
4268 return TRUE;
4271 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4273 WORD count;
4274 int i;
4276 if (protected)
4277 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4278 if (autoInheritReq)
4279 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4280 if (autoInherited)
4281 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4283 if (pacl == NULL)
4284 return TRUE;
4286 if (!IsValidAcl(pacl))
4287 return FALSE;
4289 count = pacl->AceCount;
4290 for (i = 0; i < count; i++)
4292 LPVOID ace;
4293 if (!GetAce(pacl, i, &ace))
4294 return FALSE;
4295 if (!DumpAce(ace, pwptr, plen))
4296 return FALSE;
4299 return TRUE;
4302 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4304 static const WCHAR prefix[] = {'O',':',0};
4305 BOOL bDefaulted;
4306 PSID psid;
4308 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4309 return FALSE;
4311 if (psid == NULL)
4312 return TRUE;
4314 DumpString(prefix, -1, pwptr, plen);
4315 if (!DumpSid(psid, pwptr, plen))
4316 return FALSE;
4317 return TRUE;
4320 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4322 static const WCHAR prefix[] = {'G',':',0};
4323 BOOL bDefaulted;
4324 PSID psid;
4326 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4327 return FALSE;
4329 if (psid == NULL)
4330 return TRUE;
4332 DumpString(prefix, -1, pwptr, plen);
4333 if (!DumpSid(psid, pwptr, plen))
4334 return FALSE;
4335 return TRUE;
4338 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4340 static const WCHAR dacl[] = {'D',':',0};
4341 SECURITY_DESCRIPTOR_CONTROL control;
4342 BOOL present, defaulted;
4343 DWORD revision;
4344 PACL pacl;
4346 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4347 return FALSE;
4349 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4350 return FALSE;
4352 if (!present)
4353 return TRUE;
4355 DumpString(dacl, 2, pwptr, plen);
4356 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4357 return FALSE;
4358 return TRUE;
4361 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4363 static const WCHAR sacl[] = {'S',':',0};
4364 SECURITY_DESCRIPTOR_CONTROL control;
4365 BOOL present, defaulted;
4366 DWORD revision;
4367 PACL pacl;
4369 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4370 return FALSE;
4372 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4373 return FALSE;
4375 if (!present)
4376 return TRUE;
4378 DumpString(sacl, 2, pwptr, plen);
4379 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4380 return FALSE;
4381 return TRUE;
4384 /******************************************************************************
4385 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4387 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4389 ULONG len;
4390 WCHAR *wptr, *wstr;
4392 if (SDRevision != SDDL_REVISION_1)
4394 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4395 SetLastError(ERROR_UNKNOWN_REVISION);
4396 return FALSE;
4399 len = 0;
4400 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4401 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4402 return FALSE;
4403 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4404 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4405 return FALSE;
4406 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4407 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4408 return FALSE;
4409 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4410 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4411 return FALSE;
4413 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4414 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4415 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4416 return FALSE;
4417 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4418 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4419 return FALSE;
4420 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4421 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4422 return FALSE;
4423 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4424 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4425 return FALSE;
4426 *wptr = 0;
4428 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4429 *OutputString = wstr;
4430 if (OutputLen)
4431 *OutputLen = strlenW(*OutputString)+1;
4432 return TRUE;
4435 /******************************************************************************
4436 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4438 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4440 LPWSTR wstr;
4441 ULONG len;
4442 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4444 int lenA;
4446 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4447 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4448 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4449 LocalFree(wstr);
4451 if (OutputLen != NULL)
4452 *OutputLen = lenA;
4453 return TRUE;
4455 else
4457 *OutputString = NULL;
4458 if (OutputLen)
4459 *OutputLen = 0;
4460 return FALSE;
4464 /******************************************************************************
4465 * ConvertStringSidToSidW [ADVAPI32.@]
4467 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4469 BOOL bret = FALSE;
4470 DWORD cBytes;
4472 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4473 if (GetVersion() & 0x80000000)
4474 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4475 else if (!StringSid || !Sid)
4476 SetLastError(ERROR_INVALID_PARAMETER);
4477 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4479 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4481 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4482 if (!bret)
4483 LocalFree(*Sid);
4485 return bret;
4488 /******************************************************************************
4489 * ConvertStringSidToSidA [ADVAPI32.@]
4491 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4493 BOOL bret = FALSE;
4495 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4496 if (GetVersion() & 0x80000000)
4497 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4498 else if (!StringSid || !Sid)
4499 SetLastError(ERROR_INVALID_PARAMETER);
4500 else
4502 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4503 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4504 len * sizeof(WCHAR));
4506 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4507 bret = ConvertStringSidToSidW(wStringSid, Sid);
4508 HeapFree(GetProcessHeap(), 0, wStringSid);
4510 return bret;
4513 /******************************************************************************
4514 * ConvertSidToStringSidW [ADVAPI32.@]
4516 * format of SID string is:
4517 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4518 * where
4519 * <rev> is the revision of the SID encoded as decimal
4520 * <auth> is the identifier authority encoded as hex
4521 * <subauthN> is the subauthority id encoded as decimal
4523 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4525 DWORD len = 0;
4526 LPWSTR wstr, wptr;
4528 TRACE("%p %p\n", pSid, pstr );
4530 len = 0;
4531 if (!DumpSidNumeric(pSid, NULL, &len))
4532 return FALSE;
4533 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4534 DumpSidNumeric(pSid, &wptr, NULL);
4535 *wptr = 0;
4537 *pstr = wstr;
4538 return TRUE;
4541 /******************************************************************************
4542 * ConvertSidToStringSidA [ADVAPI32.@]
4544 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4546 LPWSTR wstr = NULL;
4547 LPSTR str;
4548 UINT len;
4550 TRACE("%p %p\n", pSid, pstr );
4552 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4553 return FALSE;
4555 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4556 str = LocalAlloc( 0, len );
4557 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4558 LocalFree( wstr );
4560 *pstr = str;
4562 return TRUE;
4565 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4566 PSECURITY_DESCRIPTOR pdesc,
4567 PSECURITY_DESCRIPTOR cdesc,
4568 PSECURITY_DESCRIPTOR* ndesc,
4569 GUID* objtype,
4570 BOOL isdir,
4571 PGENERIC_MAPPING genmap )
4573 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4575 return FALSE;
4578 BOOL WINAPI CreatePrivateObjectSecurity(
4579 PSECURITY_DESCRIPTOR ParentDescriptor,
4580 PSECURITY_DESCRIPTOR CreatorDescriptor,
4581 PSECURITY_DESCRIPTOR* NewDescriptor,
4582 BOOL IsDirectoryObject,
4583 HANDLE Token,
4584 PGENERIC_MAPPING GenericMapping )
4586 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4587 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4589 return FALSE;
4592 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4594 FIXME("%p - stub\n", ObjectDescriptor);
4596 return TRUE;
4599 BOOL WINAPI CreateProcessAsUserA(
4600 HANDLE hToken,
4601 LPCSTR lpApplicationName,
4602 LPSTR lpCommandLine,
4603 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4604 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4605 BOOL bInheritHandles,
4606 DWORD dwCreationFlags,
4607 LPVOID lpEnvironment,
4608 LPCSTR lpCurrentDirectory,
4609 LPSTARTUPINFOA lpStartupInfo,
4610 LPPROCESS_INFORMATION lpProcessInformation )
4612 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4613 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4614 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4616 return FALSE;
4619 BOOL WINAPI CreateProcessAsUserW(
4620 HANDLE hToken,
4621 LPCWSTR lpApplicationName,
4622 LPWSTR lpCommandLine,
4623 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4624 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4625 BOOL bInheritHandles,
4626 DWORD dwCreationFlags,
4627 LPVOID lpEnvironment,
4628 LPCWSTR lpCurrentDirectory,
4629 LPSTARTUPINFOW lpStartupInfo,
4630 LPPROCESS_INFORMATION lpProcessInformation )
4632 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4633 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4634 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4635 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4637 /* We should create the process with a suspended main thread */
4638 if (!CreateProcessW (lpApplicationName,
4639 lpCommandLine,
4640 lpProcessAttributes,
4641 lpThreadAttributes,
4642 bInheritHandles,
4643 dwCreationFlags, /* CREATE_SUSPENDED */
4644 lpEnvironment,
4645 lpCurrentDirectory,
4646 lpStartupInfo,
4647 lpProcessInformation))
4649 return FALSE;
4652 return TRUE;
4655 /******************************************************************************
4656 * CreateProcessWithLogonW
4658 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4659 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4660 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4662 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4663 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4664 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4665 lpStartupInfo, lpProcessInformation);
4667 return FALSE;
4670 /******************************************************************************
4671 * DuplicateTokenEx [ADVAPI32.@]
4673 BOOL WINAPI DuplicateTokenEx(
4674 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4675 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4676 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4677 TOKEN_TYPE TokenType,
4678 PHANDLE DuplicateTokenHandle )
4680 OBJECT_ATTRIBUTES ObjectAttributes;
4682 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4683 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4685 InitializeObjectAttributes(
4686 &ObjectAttributes,
4687 NULL,
4688 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4689 NULL,
4690 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4692 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4693 dwDesiredAccess,
4694 &ObjectAttributes,
4695 ImpersonationLevel,
4696 TokenType,
4697 DuplicateTokenHandle ) );
4700 BOOL WINAPI DuplicateToken(
4701 HANDLE ExistingTokenHandle,
4702 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4703 PHANDLE DuplicateTokenHandle )
4705 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4706 NULL, ImpersonationLevel, TokenImpersonation,
4707 DuplicateTokenHandle );
4710 /******************************************************************************
4711 * ComputeStringSidSize
4713 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4715 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4717 int ctok = 0;
4718 while (*StringSid)
4720 if (*StringSid == '-')
4721 ctok++;
4722 StringSid++;
4725 if (ctok >= 3)
4726 return GetSidLengthRequired(ctok - 2);
4728 else /* String constant format - Only available in winxp and above */
4730 unsigned int i;
4732 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4733 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4734 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4737 return GetSidLengthRequired(0);
4740 /******************************************************************************
4741 * ParseStringSidToSid
4743 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4745 BOOL bret = FALSE;
4746 SID* pisid=pSid;
4748 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4749 if (!StringSid)
4751 SetLastError(ERROR_INVALID_PARAMETER);
4752 TRACE("StringSid is NULL, returning FALSE\n");
4753 return FALSE;
4756 *cBytes = ComputeStringSidSize(StringSid);
4757 if (!pisid) /* Simply compute the size */
4759 TRACE("only size requested, returning TRUE\n");
4760 return TRUE;
4763 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4765 DWORD i = 0, identAuth;
4766 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4768 StringSid += 2; /* Advance to Revision */
4769 pisid->Revision = atoiW(StringSid);
4771 if (pisid->Revision != SDDL_REVISION)
4773 TRACE("Revision %d is unknown\n", pisid->Revision);
4774 goto lend; /* ERROR_INVALID_SID */
4776 if (csubauth == 0)
4778 TRACE("SubAuthorityCount is 0\n");
4779 goto lend; /* ERROR_INVALID_SID */
4782 pisid->SubAuthorityCount = csubauth;
4784 /* Advance to identifier authority */
4785 while (*StringSid && *StringSid != '-')
4786 StringSid++;
4787 if (*StringSid == '-')
4788 StringSid++;
4790 /* MS' implementation can't handle values greater than 2^32 - 1, so
4791 * we don't either; assume most significant bytes are always 0
4793 pisid->IdentifierAuthority.Value[0] = 0;
4794 pisid->IdentifierAuthority.Value[1] = 0;
4795 identAuth = atoiW(StringSid);
4796 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4797 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4798 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4799 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4801 /* Advance to first sub authority */
4802 while (*StringSid && *StringSid != '-')
4803 StringSid++;
4804 if (*StringSid == '-')
4805 StringSid++;
4807 while (*StringSid)
4809 pisid->SubAuthority[i++] = atoiW(StringSid);
4811 while (*StringSid && *StringSid != '-')
4812 StringSid++;
4813 if (*StringSid == '-')
4814 StringSid++;
4817 if (i != pisid->SubAuthorityCount)
4818 goto lend; /* ERROR_INVALID_SID */
4820 bret = TRUE;
4822 else /* String constant format - Only available in winxp and above */
4824 unsigned int i;
4825 pisid->Revision = SDDL_REVISION;
4827 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4828 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4830 DWORD j;
4831 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4832 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4833 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4834 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4835 bret = TRUE;
4838 if (!bret)
4839 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4842 lend:
4843 if (!bret)
4844 SetLastError(ERROR_INVALID_SID);
4846 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4847 return bret;
4850 /******************************************************************************
4851 * GetNamedSecurityInfoA [ADVAPI32.@]
4853 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4854 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4855 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4856 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4858 DWORD len;
4859 LPWSTR wstr = NULL;
4860 DWORD r;
4862 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4863 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4865 if( pObjectName )
4867 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4868 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4869 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4872 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4873 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4875 HeapFree( GetProcessHeap(), 0, wstr );
4877 return r;
4880 /******************************************************************************
4881 * GetNamedSecurityInfoW [ADVAPI32.@]
4883 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4884 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4885 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4887 DWORD needed, offset;
4888 SECURITY_DESCRIPTOR_RELATIVE *relative;
4889 BYTE *buffer;
4891 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4892 group, dacl, sacl, descriptor );
4894 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4896 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4897 if (info & OWNER_SECURITY_INFORMATION)
4898 needed += sizeof(sidWorld);
4899 if (info & GROUP_SECURITY_INFORMATION)
4900 needed += sizeof(sidWorld);
4901 if (info & DACL_SECURITY_INFORMATION)
4902 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4903 if (info & SACL_SECURITY_INFORMATION)
4904 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4906 /* must be freed by caller */
4907 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4908 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4910 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4912 HeapFree( GetProcessHeap(), 0, *descriptor );
4913 return ERROR_INVALID_SECURITY_DESCR;
4916 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4917 relative->Control |= SE_SELF_RELATIVE;
4918 buffer = (BYTE *)relative;
4919 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4921 if (info & OWNER_SECURITY_INFORMATION)
4923 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4924 relative->Owner = offset;
4925 if (owner)
4926 *owner = buffer + offset;
4927 offset += sizeof(sidWorld);
4929 if (info & GROUP_SECURITY_INFORMATION)
4931 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4932 relative->Group = offset;
4933 if (group)
4934 *group = buffer + offset;
4935 offset += sizeof(sidWorld);
4937 if (info & DACL_SECURITY_INFORMATION)
4939 relative->Control |= SE_DACL_PRESENT;
4940 GetWorldAccessACL( (PACL)(buffer + offset) );
4941 relative->Dacl = offset;
4942 if (dacl)
4943 *dacl = (PACL)(buffer + offset);
4944 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4946 if (info & SACL_SECURITY_INFORMATION)
4948 relative->Control |= SE_SACL_PRESENT;
4949 GetWorldAccessACL( (PACL)(buffer + offset) );
4950 relative->Sacl = offset;
4951 if (sacl)
4952 *sacl = (PACL)(buffer + offset);
4954 return ERROR_SUCCESS;
4957 /******************************************************************************
4958 * DecryptFileW [ADVAPI32.@]
4960 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4962 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4963 return TRUE;
4966 /******************************************************************************
4967 * DecryptFileA [ADVAPI32.@]
4969 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4971 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4972 return TRUE;
4975 /******************************************************************************
4976 * EncryptFileW [ADVAPI32.@]
4978 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4980 FIXME("%s\n", debugstr_w(lpFileName));
4981 return TRUE;
4984 /******************************************************************************
4985 * EncryptFileA [ADVAPI32.@]
4987 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4989 FIXME("%s\n", debugstr_a(lpFileName));
4990 return TRUE;
4993 /******************************************************************************
4994 * FileEncryptionStatusW [ADVAPI32.@]
4996 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4998 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4999 if (!lpStatus)
5000 return FALSE;
5001 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5002 return TRUE;
5005 /******************************************************************************
5006 * FileEncryptionStatusA [ADVAPI32.@]
5008 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5010 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5011 if (!lpStatus)
5012 return FALSE;
5013 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5014 return TRUE;
5017 /******************************************************************************
5018 * SetSecurityInfo [ADVAPI32.@]
5020 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5021 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5022 PSID psidGroup, PACL pDacl, PACL pSacl) {
5023 FIXME("stub\n");
5024 return ERROR_SUCCESS;