advapi32: Make CreateWellKnownSid create domain sids (with test).
[wine/wine-kai.git] / dlls / advapi32 / security.c
blob79f5a3a024bb79aa72cde3c4291a4240baecc13e
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 } } },
132 /* these SIDs must be constructed as relative to some domain - only the RID is well-kown */
133 typedef struct WELLKOWNRID
135 WELL_KNOWN_SID_TYPE Type;
136 DWORD Rid;
137 } WELLKNOWNRID;
139 WELLKNOWNRID WellKnownRids[] = {
140 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
141 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
142 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
143 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
144 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
145 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
146 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
147 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
148 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
149 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
150 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
151 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
152 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
156 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
158 typedef struct _AccountSid {
159 WELL_KNOWN_SID_TYPE type;
160 LPCWSTR account;
161 LPCWSTR domain;
162 SID_NAME_USE name_use;
163 } AccountSid;
165 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
166 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
167 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
168 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
169 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
170 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
171 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
172 static const WCHAR Blank[] = { 0 };
173 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
174 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
175 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
176 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 };
177 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
178 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 };
179 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
180 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 };
181 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
182 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
183 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
184 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
185 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
186 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
187 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
188 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 };
189 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
190 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 };
191 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
192 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
193 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
194 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
195 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
196 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
197 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 };
198 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
199 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
200 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
201 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
202 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
203 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
204 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 };
205 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 };
206 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
207 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 };
208 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
209 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
210 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
211 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 };
212 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 };
213 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
214 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
215 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 };
216 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
217 static const WCHAR SELF[] = { 'S','E','L','F',0 };
218 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
219 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
220 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
221 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 };
222 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
223 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
225 static const AccountSid ACCOUNT_SIDS[] = {
226 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
227 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
228 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
229 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
230 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
231 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
232 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
233 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
234 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
235 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
236 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
251 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
252 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
253 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
254 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
255 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
256 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
257 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
260 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
261 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
262 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
263 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
264 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
265 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
269 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
272 * ACE access rights
274 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
275 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
276 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
277 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
279 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
280 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
281 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
282 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
283 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
284 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
285 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
286 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
287 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
289 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
290 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
291 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
292 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
294 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
295 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
296 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
297 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
299 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
300 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
301 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
302 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
305 * ACL flags
307 static const WCHAR SDDL_PROTECTED[] = {'P',0};
308 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
309 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
312 * ACE types
314 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
315 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
316 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
317 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
318 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
319 static const WCHAR SDDL_ALARM[] = {'A','L',0};
320 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
321 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
324 * ACE flags
326 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
327 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
328 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
329 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
330 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
331 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
332 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
334 const char * debugstr_sid(PSID sid)
336 int auth = 0;
337 SID * psid = (SID *)sid;
339 if (psid == NULL)
340 return "(null)";
342 auth = psid->IdentifierAuthority.Value[5] +
343 (psid->IdentifierAuthority.Value[4] << 8) +
344 (psid->IdentifierAuthority.Value[3] << 16) +
345 (psid->IdentifierAuthority.Value[2] << 24);
347 switch (psid->SubAuthorityCount) {
348 case 0:
349 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
350 case 1:
351 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
352 psid->SubAuthority[0]);
353 case 2:
354 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
355 psid->SubAuthority[0], psid->SubAuthority[1]);
356 case 3:
357 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
358 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
359 case 4:
360 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
361 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
362 psid->SubAuthority[3]);
363 case 5:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
366 psid->SubAuthority[3], psid->SubAuthority[4]);
367 case 6:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
370 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
371 case 7:
372 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
373 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
374 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
375 psid->SubAuthority[6]);
376 case 8:
377 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
378 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
379 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
380 psid->SubAuthority[6], psid->SubAuthority[7]);
382 return "(too-big)";
385 /* set last error code from NT status and get the proper boolean return value */
386 /* used for functions that are a simple wrapper around the corresponding ntdll API */
387 static inline BOOL set_ntstatus( NTSTATUS status )
389 if (status) SetLastError( RtlNtStatusToDosError( status ));
390 return !status;
393 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
395 static void GetWorldAccessACL(PACL pACL)
397 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
399 pACL->AclRevision = ACL_REVISION;
400 pACL->Sbz1 = 0;
401 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
402 pACL->AceCount = 1;
403 pACL->Sbz2 = 0;
405 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
406 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
407 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
408 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
409 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
412 /************************************************************
413 * ADVAPI_IsLocalComputer
415 * Checks whether the server name indicates local machine.
417 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
419 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
420 BOOL Result;
421 LPWSTR buf;
423 if (!ServerName || !ServerName[0])
424 return TRUE;
426 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
427 Result = GetComputerNameW(buf, &dwSize);
428 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
429 ServerName += 2;
430 Result = Result && !lstrcmpW(ServerName, buf);
431 HeapFree(GetProcessHeap(), 0, buf);
433 return Result;
436 /************************************************************
437 * ADVAPI_GetComputerSid
439 * Reads the computer SID from the registry.
441 BOOL ADVAPI_GetComputerSid(PSID sid)
443 HKEY key;
444 LONG ret;
445 BOOL retval = FALSE;
446 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 };
447 static const WCHAR V[] = { 'V',0 };
449 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
450 KEY_READ, &key)) == ERROR_SUCCESS)
452 DWORD size = 0;
453 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
454 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
456 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
457 if (data)
459 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
460 data, &size)) == ERROR_SUCCESS)
462 /* the SID is in the last 24 bytes of the binary data */
463 CopyMemory(sid, &data[size-24], 24);
464 retval = TRUE;
466 HeapFree(GetProcessHeap(), 0, data);
469 RegCloseKey(key);
472 if(retval == TRUE) return retval;
474 /* create a new random SID */
475 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
476 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
478 PSID new_sid;
479 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
480 DWORD id[3];
482 if (RtlGenRandom(&id, sizeof(id)))
484 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
486 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
487 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
489 FreeSid(new_sid);
492 RegCloseKey(key);
495 return retval;
498 /* ##############################
499 ###### TOKEN FUNCTIONS ######
500 ##############################
503 /******************************************************************************
504 * OpenProcessToken [ADVAPI32.@]
505 * Opens the access token associated with a process handle.
507 * PARAMS
508 * ProcessHandle [I] Handle to process
509 * DesiredAccess [I] Desired access to process
510 * TokenHandle [O] Pointer to handle of open access token
512 * RETURNS
513 * Success: TRUE. TokenHandle contains the access token.
514 * Failure: FALSE.
516 * NOTES
517 * See NtOpenProcessToken.
519 BOOL WINAPI
520 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
521 HANDLE *TokenHandle )
523 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
526 /******************************************************************************
527 * OpenThreadToken [ADVAPI32.@]
529 * Opens the access token associated with a thread handle.
531 * PARAMS
532 * ThreadHandle [I] Handle to process
533 * DesiredAccess [I] Desired access to the thread
534 * OpenAsSelf [I] ???
535 * TokenHandle [O] Destination for the token handle
537 * RETURNS
538 * Success: TRUE. TokenHandle contains the access token.
539 * Failure: FALSE.
541 * NOTES
542 * See NtOpenThreadToken.
544 BOOL WINAPI
545 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
546 BOOL OpenAsSelf, HANDLE *TokenHandle)
548 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
551 BOOL WINAPI
552 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
553 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
555 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
556 PreviousState, ReturnLength));
559 /******************************************************************************
560 * AdjustTokenPrivileges [ADVAPI32.@]
562 * Adjust the privileges of an open token handle.
564 * PARAMS
565 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
566 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
567 * NewState [I] Desired new privileges of the token
568 * BufferLength [I] Length of NewState
569 * PreviousState [O] Destination for the previous state
570 * ReturnLength [I/O] Size of PreviousState
573 * RETURNS
574 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
575 * Failure: FALSE.
577 * NOTES
578 * See NtAdjustPrivilegesToken.
580 BOOL WINAPI
581 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
582 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
583 PTOKEN_PRIVILEGES PreviousState, LPDWORD ReturnLength )
585 NTSTATUS status;
587 TRACE("\n");
589 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
590 NewState, BufferLength, PreviousState,
591 ReturnLength);
592 SetLastError( RtlNtStatusToDosError( status ));
593 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
594 return TRUE;
595 else
596 return FALSE;
599 /******************************************************************************
600 * CheckTokenMembership [ADVAPI32.@]
602 * Determine if an access token is a member of a SID.
604 * PARAMS
605 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
606 * SidToCheck [I] SID that possibly contains the token
607 * IsMember [O] Destination for result.
609 * RETURNS
610 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
611 * Failure: FALSE.
613 BOOL WINAPI
614 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
615 PBOOL IsMember )
617 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
619 *IsMember = TRUE;
620 return(TRUE);
623 /******************************************************************************
624 * GetTokenInformation [ADVAPI32.@]
626 * Get a type of information about an access token.
628 * PARAMS
629 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
630 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
631 * tokeninfo [O] Destination for token information
632 * tokeninfolength [I] Length of tokeninfo
633 * retlen [O] Destination for returned token information length
635 * RETURNS
636 * Success: TRUE. tokeninfo contains retlen bytes of token information
637 * Failure: FALSE.
639 * NOTES
640 * See NtQueryInformationToken.
642 BOOL WINAPI
643 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
644 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
646 TRACE("(%p, %s, %p, %d, %p):\n",
647 token,
648 (tokeninfoclass == TokenUser) ? "TokenUser" :
649 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
650 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
651 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
652 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
653 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
654 (tokeninfoclass == TokenSource) ? "TokenSource" :
655 (tokeninfoclass == TokenType) ? "TokenType" :
656 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
657 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
658 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
659 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
660 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
661 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
662 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
663 "Unknown",
664 tokeninfo, tokeninfolength, retlen);
665 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
666 tokeninfolength, retlen));
669 /******************************************************************************
670 * SetTokenInformation [ADVAPI32.@]
672 * Set information for an access token.
674 * PARAMS
675 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
676 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
677 * tokeninfo [I] Token information to set
678 * tokeninfolength [I] Length of tokeninfo
680 * RETURNS
681 * Success: TRUE. The information for the token is set to tokeninfo.
682 * Failure: FALSE.
684 BOOL WINAPI
685 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
686 LPVOID tokeninfo, DWORD tokeninfolength )
688 TRACE("(%p, %s, %p, %d): stub\n",
689 token,
690 (tokeninfoclass == TokenUser) ? "TokenUser" :
691 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
692 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
693 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
694 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
695 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
696 (tokeninfoclass == TokenSource) ? "TokenSource" :
697 (tokeninfoclass == TokenType) ? "TokenType" :
698 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
699 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
700 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
701 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
702 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
703 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
704 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
705 "Unknown",
706 tokeninfo, tokeninfolength);
708 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
711 /*************************************************************************
712 * SetThreadToken [ADVAPI32.@]
714 * Assigns an 'impersonation token' to a thread so it can assume the
715 * security privileges of another thread or process. Can also remove
716 * a previously assigned token.
718 * PARAMS
719 * thread [O] Handle to thread to set the token for
720 * token [I] Token to set
722 * RETURNS
723 * Success: TRUE. The threads access token is set to token
724 * Failure: FALSE.
726 * NOTES
727 * Only supported on NT or higher. On Win9X this function does nothing.
728 * See SetTokenInformation.
730 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
732 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
733 ThreadImpersonationToken, &token, sizeof token ));
736 /* ##############################
737 ###### SID FUNCTIONS ######
738 ##############################
741 /******************************************************************************
742 * AllocateAndInitializeSid [ADVAPI32.@]
744 * PARAMS
745 * pIdentifierAuthority []
746 * nSubAuthorityCount []
747 * nSubAuthority0 []
748 * nSubAuthority1 []
749 * nSubAuthority2 []
750 * nSubAuthority3 []
751 * nSubAuthority4 []
752 * nSubAuthority5 []
753 * nSubAuthority6 []
754 * nSubAuthority7 []
755 * pSid []
757 BOOL WINAPI
758 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
759 BYTE nSubAuthorityCount,
760 DWORD nSubAuthority0, DWORD nSubAuthority1,
761 DWORD nSubAuthority2, DWORD nSubAuthority3,
762 DWORD nSubAuthority4, DWORD nSubAuthority5,
763 DWORD nSubAuthority6, DWORD nSubAuthority7,
764 PSID *pSid )
766 return set_ntstatus( RtlAllocateAndInitializeSid(
767 pIdentifierAuthority, nSubAuthorityCount,
768 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
769 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
770 pSid ));
773 /******************************************************************************
774 * FreeSid [ADVAPI32.@]
776 * PARAMS
777 * pSid []
779 PVOID WINAPI
780 FreeSid( PSID pSid )
782 RtlFreeSid(pSid);
783 return NULL; /* is documented like this */
786 /******************************************************************************
787 * CopySid [ADVAPI32.@]
789 * PARAMS
790 * nDestinationSidLength []
791 * pDestinationSid []
792 * pSourceSid []
794 BOOL WINAPI
795 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
797 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
800 /******************************************************************************
801 * CreateWellKnownSid [ADVAPI32.@]
803 BOOL WINAPI
804 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
805 PSID DomainSid,
806 PSID pSid,
807 DWORD* cbSid)
809 unsigned int i;
810 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
812 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
813 SetLastError(ERROR_INVALID_PARAMETER);
814 return FALSE;
817 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
818 if (WellKnownSids[i].Type == WellKnownSidType) {
819 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
821 if (*cbSid < length) {
822 SetLastError(ERROR_INSUFFICIENT_BUFFER);
823 return FALSE;
826 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
827 *cbSid = length;
828 return TRUE;
832 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
834 SetLastError(ERROR_INVALID_PARAMETER);
835 return FALSE;
838 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
839 if (WellKnownRids[i].Type == WellKnownSidType) {
840 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
841 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
842 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
844 if (*cbSid < output_sid_length) {
845 SetLastError(ERROR_INSUFFICIENT_BUFFER);
846 return FALSE;
849 CopyMemory(pSid, DomainSid, domain_sid_length);
850 (*GetSidSubAuthorityCount(pSid))++;
851 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
852 *cbSid = output_sid_length;
853 return TRUE;
856 SetLastError(ERROR_INVALID_PARAMETER);
857 return FALSE;
860 /******************************************************************************
861 * IsWellKnownSid [ADVAPI32.@]
863 BOOL WINAPI
864 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
866 unsigned int i;
867 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
869 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
870 if (WellKnownSids[i].Type == WellKnownSidType)
871 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
872 return TRUE;
874 return FALSE;
877 BOOL WINAPI
878 IsTokenRestricted( HANDLE TokenHandle )
880 TOKEN_GROUPS *groups;
881 DWORD size;
882 NTSTATUS status;
883 BOOL restricted;
885 TRACE("(%p)\n", TokenHandle);
887 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
888 if (status != STATUS_BUFFER_TOO_SMALL)
889 return FALSE;
891 groups = HeapAlloc(GetProcessHeap(), 0, size);
892 if (!groups)
894 SetLastError(ERROR_OUTOFMEMORY);
895 return FALSE;
898 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
899 if (status != STATUS_SUCCESS)
901 HeapFree(GetProcessHeap(), 0, groups);
902 return set_ntstatus(status);
905 if (groups->GroupCount)
906 restricted = TRUE;
907 else
908 restricted = FALSE;
910 HeapFree(GetProcessHeap(), 0, groups);
912 return restricted;
915 /******************************************************************************
916 * IsValidSid [ADVAPI32.@]
918 * PARAMS
919 * pSid []
921 BOOL WINAPI
922 IsValidSid( PSID pSid )
924 return RtlValidSid( pSid );
927 /******************************************************************************
928 * EqualSid [ADVAPI32.@]
930 * PARAMS
931 * pSid1 []
932 * pSid2 []
934 BOOL WINAPI
935 EqualSid( PSID pSid1, PSID pSid2 )
937 return RtlEqualSid( pSid1, pSid2 );
940 /******************************************************************************
941 * EqualPrefixSid [ADVAPI32.@]
943 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
945 return RtlEqualPrefixSid(pSid1, pSid2);
948 /******************************************************************************
949 * GetSidLengthRequired [ADVAPI32.@]
951 * PARAMS
952 * nSubAuthorityCount []
954 DWORD WINAPI
955 GetSidLengthRequired( BYTE nSubAuthorityCount )
957 return RtlLengthRequiredSid(nSubAuthorityCount);
960 /******************************************************************************
961 * InitializeSid [ADVAPI32.@]
963 * PARAMS
964 * pIdentifierAuthority []
966 BOOL WINAPI
967 InitializeSid (
968 PSID pSid,
969 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
970 BYTE nSubAuthorityCount)
972 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
975 DWORD WINAPI
976 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
978 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
980 return 1;
983 DWORD WINAPI
984 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
986 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
988 return 1;
991 /******************************************************************************
992 * GetSidIdentifierAuthority [ADVAPI32.@]
994 * PARAMS
995 * pSid []
997 PSID_IDENTIFIER_AUTHORITY WINAPI
998 GetSidIdentifierAuthority( PSID pSid )
1000 return RtlIdentifierAuthoritySid(pSid);
1003 /******************************************************************************
1004 * GetSidSubAuthority [ADVAPI32.@]
1006 * PARAMS
1007 * pSid []
1008 * nSubAuthority []
1010 PDWORD WINAPI
1011 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1013 return RtlSubAuthoritySid(pSid, nSubAuthority);
1016 /******************************************************************************
1017 * GetSidSubAuthorityCount [ADVAPI32.@]
1019 * PARAMS
1020 * pSid []
1022 PUCHAR WINAPI
1023 GetSidSubAuthorityCount (PSID pSid)
1025 return RtlSubAuthorityCountSid(pSid);
1028 /******************************************************************************
1029 * GetLengthSid [ADVAPI32.@]
1031 * PARAMS
1032 * pSid []
1034 DWORD WINAPI
1035 GetLengthSid (PSID pSid)
1037 return RtlLengthSid(pSid);
1040 /* ##############################################
1041 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1042 ##############################################
1045 /******************************************************************************
1046 * BuildSecurityDescriptorA [ADVAPI32.@]
1048 * Builds a SD from
1050 * PARAMS
1051 * pOwner [I]
1052 * pGroup [I]
1053 * cCountOfAccessEntries [I]
1054 * pListOfAccessEntries [I]
1055 * cCountOfAuditEntries [I]
1056 * pListofAuditEntries [I]
1057 * pOldSD [I]
1058 * lpdwBufferLength [I/O]
1059 * pNewSD [O]
1061 * RETURNS
1062 * Success: ERROR_SUCCESS
1063 * Failure: nonzero error code from Winerror.h
1065 DWORD WINAPI BuildSecurityDescriptorA(
1066 IN PTRUSTEEA pOwner,
1067 IN PTRUSTEEA pGroup,
1068 IN ULONG cCountOfAccessEntries,
1069 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1070 IN ULONG cCountOfAuditEntries,
1071 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1072 IN PSECURITY_DESCRIPTOR pOldSD,
1073 IN OUT PULONG lpdwBufferLength,
1074 OUT PSECURITY_DESCRIPTOR* pNewSD)
1076 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1077 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1078 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1080 return ERROR_CALL_NOT_IMPLEMENTED;
1083 /******************************************************************************
1084 * BuildSecurityDescriptorW [ADVAPI32.@]
1086 * See BuildSecurityDescriptorA.
1088 DWORD WINAPI BuildSecurityDescriptorW(
1089 IN PTRUSTEEW pOwner,
1090 IN PTRUSTEEW pGroup,
1091 IN ULONG cCountOfAccessEntries,
1092 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1093 IN ULONG cCountOfAuditEntries,
1094 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1095 IN PSECURITY_DESCRIPTOR pOldSD,
1096 IN OUT PULONG lpdwBufferLength,
1097 OUT PSECURITY_DESCRIPTOR* pNewSD)
1099 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1100 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1101 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1103 return ERROR_CALL_NOT_IMPLEMENTED;
1106 /******************************************************************************
1107 * InitializeSecurityDescriptor [ADVAPI32.@]
1109 * PARAMS
1110 * pDescr []
1111 * revision []
1113 BOOL WINAPI
1114 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1116 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1120 /******************************************************************************
1121 * MakeAbsoluteSD [ADVAPI32.@]
1123 BOOL WINAPI MakeAbsoluteSD (
1124 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1125 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1126 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1127 OUT PACL pDacl,
1128 OUT LPDWORD lpdwDaclSize,
1129 OUT PACL pSacl,
1130 OUT LPDWORD lpdwSaclSize,
1131 OUT PSID pOwner,
1132 OUT LPDWORD lpdwOwnerSize,
1133 OUT PSID pPrimaryGroup,
1134 OUT LPDWORD lpdwPrimaryGroupSize)
1136 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1137 pAbsoluteSecurityDescriptor,
1138 lpdwAbsoluteSecurityDescriptorSize,
1139 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1140 pOwner, lpdwOwnerSize,
1141 pPrimaryGroup, lpdwPrimaryGroupSize));
1144 /******************************************************************************
1145 * GetKernelObjectSecurity [ADVAPI32.@]
1147 BOOL WINAPI GetKernelObjectSecurity(
1148 HANDLE Handle,
1149 SECURITY_INFORMATION RequestedInformation,
1150 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1151 DWORD nLength,
1152 LPDWORD lpnLengthNeeded )
1154 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1155 pSecurityDescriptor, nLength, lpnLengthNeeded);
1157 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1158 nLength, lpnLengthNeeded ));
1161 /******************************************************************************
1162 * GetPrivateObjectSecurity [ADVAPI32.@]
1164 BOOL WINAPI GetPrivateObjectSecurity(
1165 PSECURITY_DESCRIPTOR ObjectDescriptor,
1166 SECURITY_INFORMATION SecurityInformation,
1167 PSECURITY_DESCRIPTOR ResultantDescriptor,
1168 DWORD DescriptorLength,
1169 PDWORD ReturnLength )
1171 SECURITY_DESCRIPTOR desc;
1172 BOOL defaulted, present;
1173 PACL pacl;
1174 PSID psid;
1176 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1177 ResultantDescriptor, DescriptorLength, ReturnLength);
1179 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1180 return FALSE;
1182 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1184 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1185 return FALSE;
1186 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1189 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1191 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1192 return FALSE;
1193 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1196 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1198 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1199 return FALSE;
1200 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1203 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1205 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1206 return FALSE;
1207 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1210 *ReturnLength = DescriptorLength;
1211 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1214 /******************************************************************************
1215 * GetSecurityDescriptorLength [ADVAPI32.@]
1217 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1219 return RtlLengthSecurityDescriptor(pDescr);
1222 /******************************************************************************
1223 * GetSecurityDescriptorOwner [ADVAPI32.@]
1225 * PARAMS
1226 * pOwner []
1227 * lpbOwnerDefaulted []
1229 BOOL WINAPI
1230 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1231 LPBOOL lpbOwnerDefaulted )
1233 BOOLEAN defaulted;
1234 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1235 *lpbOwnerDefaulted = defaulted;
1236 return ret;
1239 /******************************************************************************
1240 * SetSecurityDescriptorOwner [ADVAPI32.@]
1242 * PARAMS
1244 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1245 PSID pOwner, BOOL bOwnerDefaulted)
1247 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1249 /******************************************************************************
1250 * GetSecurityDescriptorGroup [ADVAPI32.@]
1252 BOOL WINAPI GetSecurityDescriptorGroup(
1253 PSECURITY_DESCRIPTOR SecurityDescriptor,
1254 PSID *Group,
1255 LPBOOL GroupDefaulted)
1257 BOOLEAN defaulted;
1258 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1259 *GroupDefaulted = defaulted;
1260 return ret;
1262 /******************************************************************************
1263 * SetSecurityDescriptorGroup [ADVAPI32.@]
1265 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1266 PSID Group, BOOL GroupDefaulted)
1268 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1271 /******************************************************************************
1272 * IsValidSecurityDescriptor [ADVAPI32.@]
1274 * PARAMS
1275 * lpsecdesc []
1277 BOOL WINAPI
1278 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1280 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1283 /******************************************************************************
1284 * GetSecurityDescriptorDacl [ADVAPI32.@]
1286 BOOL WINAPI GetSecurityDescriptorDacl(
1287 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1288 OUT LPBOOL lpbDaclPresent,
1289 OUT PACL *pDacl,
1290 OUT LPBOOL lpbDaclDefaulted)
1292 BOOLEAN present, defaulted;
1293 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1294 *lpbDaclPresent = present;
1295 *lpbDaclDefaulted = defaulted;
1296 return ret;
1299 /******************************************************************************
1300 * SetSecurityDescriptorDacl [ADVAPI32.@]
1302 BOOL WINAPI
1303 SetSecurityDescriptorDacl (
1304 PSECURITY_DESCRIPTOR lpsd,
1305 BOOL daclpresent,
1306 PACL dacl,
1307 BOOL dacldefaulted )
1309 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1311 /******************************************************************************
1312 * GetSecurityDescriptorSacl [ADVAPI32.@]
1314 BOOL WINAPI GetSecurityDescriptorSacl(
1315 IN PSECURITY_DESCRIPTOR lpsd,
1316 OUT LPBOOL lpbSaclPresent,
1317 OUT PACL *pSacl,
1318 OUT LPBOOL lpbSaclDefaulted)
1320 BOOLEAN present, defaulted;
1321 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1322 *lpbSaclPresent = present;
1323 *lpbSaclDefaulted = defaulted;
1324 return ret;
1327 /**************************************************************************
1328 * SetSecurityDescriptorSacl [ADVAPI32.@]
1330 BOOL WINAPI SetSecurityDescriptorSacl (
1331 PSECURITY_DESCRIPTOR lpsd,
1332 BOOL saclpresent,
1333 PACL lpsacl,
1334 BOOL sacldefaulted)
1336 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1338 /******************************************************************************
1339 * MakeSelfRelativeSD [ADVAPI32.@]
1341 * PARAMS
1342 * lpabssecdesc []
1343 * lpselfsecdesc []
1344 * lpbuflen []
1346 BOOL WINAPI
1347 MakeSelfRelativeSD(
1348 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1349 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1350 IN OUT LPDWORD lpdwBufferLength)
1352 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1353 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1356 /******************************************************************************
1357 * GetSecurityDescriptorControl [ADVAPI32.@]
1360 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1361 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1363 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1366 /* ##############################
1367 ###### ACL FUNCTIONS ######
1368 ##############################
1371 /*************************************************************************
1372 * InitializeAcl [ADVAPI32.@]
1374 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1376 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1379 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1381 IO_STATUS_BLOCK io_block;
1383 TRACE("(%p)\n", hNamedPipe);
1385 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1386 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1389 /******************************************************************************
1390 * AddAccessAllowedAce [ADVAPI32.@]
1392 BOOL WINAPI AddAccessAllowedAce(
1393 IN OUT PACL pAcl,
1394 IN DWORD dwAceRevision,
1395 IN DWORD AccessMask,
1396 IN PSID pSid)
1398 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1401 /******************************************************************************
1402 * AddAccessAllowedAceEx [ADVAPI32.@]
1404 BOOL WINAPI AddAccessAllowedAceEx(
1405 IN OUT PACL pAcl,
1406 IN DWORD dwAceRevision,
1407 IN DWORD AceFlags,
1408 IN DWORD AccessMask,
1409 IN PSID pSid)
1411 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1414 /******************************************************************************
1415 * AddAccessDeniedAce [ADVAPI32.@]
1417 BOOL WINAPI AddAccessDeniedAce(
1418 IN OUT PACL pAcl,
1419 IN DWORD dwAceRevision,
1420 IN DWORD AccessMask,
1421 IN PSID pSid)
1423 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1426 /******************************************************************************
1427 * AddAccessDeniedAceEx [ADVAPI32.@]
1429 BOOL WINAPI AddAccessDeniedAceEx(
1430 IN OUT PACL pAcl,
1431 IN DWORD dwAceRevision,
1432 IN DWORD AceFlags,
1433 IN DWORD AccessMask,
1434 IN PSID pSid)
1436 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1439 /******************************************************************************
1440 * AddAce [ADVAPI32.@]
1442 BOOL WINAPI AddAce(
1443 IN OUT PACL pAcl,
1444 IN DWORD dwAceRevision,
1445 IN DWORD dwStartingAceIndex,
1446 LPVOID pAceList,
1447 DWORD nAceListLength)
1449 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1452 /******************************************************************************
1453 * DeleteAce [ADVAPI32.@]
1455 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1457 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1460 /******************************************************************************
1461 * FindFirstFreeAce [ADVAPI32.@]
1463 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1465 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1468 /******************************************************************************
1469 * GetAce [ADVAPI32.@]
1471 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1473 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1476 /******************************************************************************
1477 * GetAclInformation [ADVAPI32.@]
1479 BOOL WINAPI GetAclInformation(
1480 PACL pAcl,
1481 LPVOID pAclInformation,
1482 DWORD nAclInformationLength,
1483 ACL_INFORMATION_CLASS dwAclInformationClass)
1485 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1486 nAclInformationLength, dwAclInformationClass));
1489 /******************************************************************************
1490 * IsValidAcl [ADVAPI32.@]
1492 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1494 return RtlValidAcl(pAcl);
1497 /* ##############################
1498 ###### MISC FUNCTIONS ######
1499 ##############################
1502 /******************************************************************************
1503 * AllocateLocallyUniqueId [ADVAPI32.@]
1505 * PARAMS
1506 * lpLuid []
1508 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1510 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1513 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1514 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1515 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1516 { '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 };
1517 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1518 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1519 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1520 { '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 };
1521 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1522 { '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 };
1523 static const WCHAR SE_TCB_NAME_W[] =
1524 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1525 static const WCHAR SE_SECURITY_NAME_W[] =
1526 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1527 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1528 { '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 };
1529 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1530 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1531 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1532 { '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 };
1533 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1534 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1535 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1536 { '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 };
1537 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1538 { '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 };
1539 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1540 { '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 };
1541 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1542 { '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 };
1543 static const WCHAR SE_BACKUP_NAME_W[] =
1544 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1545 static const WCHAR SE_RESTORE_NAME_W[] =
1546 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1547 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1548 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1549 static const WCHAR SE_DEBUG_NAME_W[] =
1550 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1551 static const WCHAR SE_AUDIT_NAME_W[] =
1552 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1553 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1554 { '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 };
1555 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1556 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1557 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1558 { '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 };
1559 static const WCHAR SE_UNDOCK_NAME_W[] =
1560 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1561 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1562 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1563 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1564 { '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 };
1565 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1566 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1567 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1568 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1570 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1572 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1574 NULL,
1575 NULL,
1576 SE_CREATE_TOKEN_NAME_W,
1577 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1578 SE_LOCK_MEMORY_NAME_W,
1579 SE_INCREASE_QUOTA_NAME_W,
1580 SE_MACHINE_ACCOUNT_NAME_W,
1581 SE_TCB_NAME_W,
1582 SE_SECURITY_NAME_W,
1583 SE_TAKE_OWNERSHIP_NAME_W,
1584 SE_LOAD_DRIVER_NAME_W,
1585 SE_SYSTEM_PROFILE_NAME_W,
1586 SE_SYSTEMTIME_NAME_W,
1587 SE_PROF_SINGLE_PROCESS_NAME_W,
1588 SE_INC_BASE_PRIORITY_NAME_W,
1589 SE_CREATE_PAGEFILE_NAME_W,
1590 SE_CREATE_PERMANENT_NAME_W,
1591 SE_BACKUP_NAME_W,
1592 SE_RESTORE_NAME_W,
1593 SE_SHUTDOWN_NAME_W,
1594 SE_DEBUG_NAME_W,
1595 SE_AUDIT_NAME_W,
1596 SE_SYSTEM_ENVIRONMENT_NAME_W,
1597 SE_CHANGE_NOTIFY_NAME_W,
1598 SE_REMOTE_SHUTDOWN_NAME_W,
1599 SE_UNDOCK_NAME_W,
1600 SE_SYNC_AGENT_NAME_W,
1601 SE_ENABLE_DELEGATION_NAME_W,
1602 SE_MANAGE_VOLUME_NAME_W,
1603 SE_IMPERSONATE_NAME_W,
1604 SE_CREATE_GLOBAL_NAME_W,
1607 /******************************************************************************
1608 * LookupPrivilegeValueW [ADVAPI32.@]
1610 * See LookupPrivilegeValueA.
1612 BOOL WINAPI
1613 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1615 UINT i;
1617 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1619 if (!ADVAPI_IsLocalComputer(lpSystemName))
1621 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1622 return FALSE;
1624 if (!lpName)
1626 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1627 return FALSE;
1629 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1631 if( !WellKnownPrivNames[i] )
1632 continue;
1633 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1634 continue;
1635 lpLuid->LowPart = i;
1636 lpLuid->HighPart = 0;
1637 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1638 lpLuid->HighPart, lpLuid->LowPart );
1639 return TRUE;
1641 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1642 return FALSE;
1645 /******************************************************************************
1646 * LookupPrivilegeValueA [ADVAPI32.@]
1648 * Retrieves LUID used on a system to represent the privilege name.
1650 * PARAMS
1651 * lpSystemName [I] Name of the system
1652 * lpName [I] Name of the privilege
1653 * lpLuid [O] Destination for the resulting LUID
1655 * RETURNS
1656 * Success: TRUE. lpLuid contains the requested LUID.
1657 * Failure: FALSE.
1659 BOOL WINAPI
1660 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1662 UNICODE_STRING lpSystemNameW;
1663 UNICODE_STRING lpNameW;
1664 BOOL ret;
1666 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1667 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1668 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1669 RtlFreeUnicodeString(&lpNameW);
1670 RtlFreeUnicodeString(&lpSystemNameW);
1671 return ret;
1674 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1675 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1677 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1678 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1680 return FALSE;
1683 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1684 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1686 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1687 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1689 return FALSE;
1692 /******************************************************************************
1693 * LookupPrivilegeNameA [ADVAPI32.@]
1695 * See LookupPrivilegeNameW.
1697 BOOL WINAPI
1698 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1699 LPDWORD cchName)
1701 UNICODE_STRING lpSystemNameW;
1702 BOOL ret;
1703 DWORD wLen = 0;
1705 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1707 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1708 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1709 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1711 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1713 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1714 &wLen);
1715 if (ret)
1717 /* Windows crashes if cchName is NULL, so will I */
1718 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1719 *cchName, NULL, NULL);
1721 if (len == 0)
1723 /* WideCharToMultiByte failed */
1724 ret = FALSE;
1726 else if (len > *cchName)
1728 *cchName = len;
1729 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1730 ret = FALSE;
1732 else
1734 /* WideCharToMultiByte succeeded, output length needs to be
1735 * length not including NULL terminator
1737 *cchName = len - 1;
1740 HeapFree(GetProcessHeap(), 0, lpNameW);
1742 RtlFreeUnicodeString(&lpSystemNameW);
1743 return ret;
1746 /******************************************************************************
1747 * LookupPrivilegeNameW [ADVAPI32.@]
1749 * Retrieves the privilege name referred to by the LUID lpLuid.
1751 * PARAMS
1752 * lpSystemName [I] Name of the system
1753 * lpLuid [I] Privilege value
1754 * lpName [O] Name of the privilege
1755 * cchName [I/O] Number of characters in lpName.
1757 * RETURNS
1758 * Success: TRUE. lpName contains the name of the privilege whose value is
1759 * *lpLuid.
1760 * Failure: FALSE.
1762 * REMARKS
1763 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1764 * using this function.
1765 * If the length of lpName is too small, on return *cchName will contain the
1766 * number of WCHARs needed to contain the privilege, including the NULL
1767 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1768 * On success, *cchName will contain the number of characters stored in
1769 * lpName, NOT including the NULL terminator.
1771 BOOL WINAPI
1772 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1773 LPDWORD cchName)
1775 size_t privNameLen;
1777 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1779 if (!ADVAPI_IsLocalComputer(lpSystemName))
1781 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1782 return FALSE;
1784 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1785 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1787 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1788 return FALSE;
1790 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1791 /* Windows crashes if cchName is NULL, so will I */
1792 if (*cchName <= privNameLen)
1794 *cchName = privNameLen + 1;
1795 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1796 return FALSE;
1798 else
1800 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1801 *cchName = privNameLen;
1802 return TRUE;
1806 /******************************************************************************
1807 * GetFileSecurityA [ADVAPI32.@]
1809 * Obtains Specified information about the security of a file or directory.
1811 * PARAMS
1812 * lpFileName [I] Name of the file to get info for
1813 * RequestedInformation [I] SE_ flags from "winnt.h"
1814 * pSecurityDescriptor [O] Destination for security information
1815 * nLength [I] Length of pSecurityDescriptor
1816 * lpnLengthNeeded [O] Destination for length of returned security information
1818 * RETURNS
1819 * Success: TRUE. pSecurityDescriptor contains the requested information.
1820 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1822 * NOTES
1823 * The information returned is constrained by the callers access rights and
1824 * privileges.
1826 BOOL WINAPI
1827 GetFileSecurityA( LPCSTR lpFileName,
1828 SECURITY_INFORMATION RequestedInformation,
1829 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1830 DWORD nLength, LPDWORD lpnLengthNeeded )
1832 DWORD len;
1833 BOOL r;
1834 LPWSTR name = NULL;
1836 if( lpFileName )
1838 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1839 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1840 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1843 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1844 nLength, lpnLengthNeeded );
1845 HeapFree( GetProcessHeap(), 0, name );
1847 return r;
1850 /******************************************************************************
1851 * GetFileSecurityW [ADVAPI32.@]
1853 * See GetFileSecurityA.
1855 BOOL WINAPI
1856 GetFileSecurityW( LPCWSTR lpFileName,
1857 SECURITY_INFORMATION RequestedInformation,
1858 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1859 DWORD nLength, LPDWORD lpnLengthNeeded )
1861 HANDLE hfile;
1862 NTSTATUS status;
1863 DWORD access = 0;
1865 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1866 DACL_SECURITY_INFORMATION))
1867 access |= READ_CONTROL;
1868 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1869 access |= ACCESS_SYSTEM_SECURITY;
1871 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1872 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1873 if ( hfile == INVALID_HANDLE_VALUE )
1874 return FALSE;
1876 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1877 nLength, lpnLengthNeeded );
1878 CloseHandle( hfile );
1879 return set_ntstatus( status );
1883 /******************************************************************************
1884 * LookupAccountSidA [ADVAPI32.@]
1886 BOOL WINAPI
1887 LookupAccountSidA(
1888 IN LPCSTR system,
1889 IN PSID sid,
1890 OUT LPSTR account,
1891 IN OUT LPDWORD accountSize,
1892 OUT LPSTR domain,
1893 IN OUT LPDWORD domainSize,
1894 OUT PSID_NAME_USE name_use )
1896 DWORD len;
1897 BOOL r;
1898 LPWSTR systemW = NULL;
1899 LPWSTR accountW = NULL;
1900 LPWSTR domainW = NULL;
1901 DWORD accountSizeW = *accountSize;
1902 DWORD domainSizeW = *domainSize;
1904 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1905 debugstr_a(system),debugstr_sid(sid),
1906 account,accountSize,accountSize?*accountSize:0,
1907 domain,domainSize,domainSize?*domainSize:0,
1908 name_use);
1910 if (system) {
1911 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1912 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1913 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1915 if (account)
1916 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1917 if (domain)
1918 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1920 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1922 if (r) {
1923 if (accountW && *accountSize) {
1924 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1925 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1926 *accountSize = len;
1927 } else
1928 *accountSize = accountSizeW + 1;
1930 if (domainW && *domainSize) {
1931 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1932 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1933 *domainSize = len;
1934 } else
1935 *domainSize = domainSizeW + 1;
1938 HeapFree( GetProcessHeap(), 0, systemW );
1939 HeapFree( GetProcessHeap(), 0, accountW );
1940 HeapFree( GetProcessHeap(), 0, domainW );
1942 return r;
1945 /******************************************************************************
1946 * LookupAccountSidW [ADVAPI32.@]
1948 * PARAMS
1949 * system []
1950 * sid []
1951 * account []
1952 * accountSize []
1953 * domain []
1954 * domainSize []
1955 * name_use []
1958 BOOL WINAPI
1959 LookupAccountSidW(
1960 IN LPCWSTR system,
1961 IN PSID sid,
1962 OUT LPWSTR account,
1963 IN OUT LPDWORD accountSize,
1964 OUT LPWSTR domain,
1965 IN OUT LPDWORD domainSize,
1966 OUT PSID_NAME_USE name_use )
1968 unsigned int i, j;
1969 const WCHAR * ac = NULL;
1970 const WCHAR * dm = NULL;
1971 SID_NAME_USE use = 0;
1972 LPWSTR computer_name = NULL;
1974 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1975 debugstr_w(system),debugstr_sid(sid),
1976 account,accountSize,accountSize?*accountSize:0,
1977 domain,domainSize,domainSize?*domainSize:0,
1978 name_use);
1980 if (!ADVAPI_IsLocalComputer(system)) {
1981 FIXME("Only local computer supported!\n");
1982 SetLastError(ERROR_NONE_MAPPED);
1983 return FALSE;
1986 /* check the well known SIDs first */
1987 for (i = 0; i <= 60; i++) {
1988 if (IsWellKnownSid(sid, i)) {
1989 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1990 if (ACCOUNT_SIDS[j].type == i) {
1991 ac = ACCOUNT_SIDS[j].account;
1992 dm = ACCOUNT_SIDS[j].domain;
1993 use = ACCOUNT_SIDS[j].name_use;
1996 break;
2000 if (dm == NULL) {
2001 MAX_SID local;
2003 /* check for the local computer next */
2004 if (ADVAPI_GetComputerSid(&local)) {
2005 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2006 BOOL result;
2008 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2009 result = GetComputerNameW(computer_name, &size);
2011 if (result) {
2012 if (EqualSid(sid, &local)) {
2013 dm = computer_name;
2014 ac = Blank;
2015 use = 3;
2016 } else {
2017 local.SubAuthorityCount++;
2019 if (EqualPrefixSid(sid, &local)) {
2020 dm = computer_name;
2021 use = 1;
2022 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2023 case DOMAIN_USER_RID_ADMIN:
2024 ac = Administrator;
2025 break;
2026 case DOMAIN_USER_RID_GUEST:
2027 ac = Guest;
2028 break;
2029 case DOMAIN_GROUP_RID_ADMINS:
2030 ac = Domain_Admins;
2031 break;
2032 case DOMAIN_GROUP_RID_USERS:
2033 ac = Domain_Users;
2034 break;
2035 case DOMAIN_GROUP_RID_GUESTS:
2036 ac = Domain_Guests;
2037 break;
2038 case DOMAIN_GROUP_RID_COMPUTERS:
2039 ac = Domain_Computers;
2040 break;
2041 case DOMAIN_GROUP_RID_CONTROLLERS:
2042 ac = Domain_Controllers;
2043 break;
2044 case DOMAIN_GROUP_RID_CERT_ADMINS:
2045 ac = Cert_Publishers;
2046 break;
2047 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2048 ac = Schema_Admins;
2049 break;
2050 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2051 ac = Enterprise_Admins;
2052 break;
2053 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2054 ac = Group_Policy_Creator_Owners;
2055 break;
2056 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2057 ac = RAS_and_IAS_Servers;
2058 break;
2059 default:
2060 dm = NULL;
2061 break;
2069 if (dm) {
2070 BOOL status = TRUE;
2071 if (*accountSize > lstrlenW(ac)) {
2072 if (account)
2073 lstrcpyW(account, ac);
2075 if (*domainSize > lstrlenW(dm)) {
2076 if (domain)
2077 lstrcpyW(domain, dm);
2079 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2080 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2081 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2082 status = FALSE;
2084 if (*domainSize)
2085 *domainSize = strlenW(dm);
2086 else
2087 *domainSize = strlenW(dm) + 1;
2088 if (*accountSize)
2089 *accountSize = strlenW(ac);
2090 else
2091 *accountSize = strlenW(ac) + 1;
2092 *name_use = use;
2093 HeapFree(GetProcessHeap(), 0, computer_name);
2094 return status;
2097 HeapFree(GetProcessHeap(), 0, computer_name);
2098 SetLastError(ERROR_NONE_MAPPED);
2099 return FALSE;
2102 /******************************************************************************
2103 * SetFileSecurityA [ADVAPI32.@]
2105 * See SetFileSecurityW.
2107 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2108 SECURITY_INFORMATION RequestedInformation,
2109 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2111 DWORD len;
2112 BOOL r;
2113 LPWSTR name = NULL;
2115 if( lpFileName )
2117 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2118 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2119 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2122 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2123 HeapFree( GetProcessHeap(), 0, name );
2125 return r;
2128 /******************************************************************************
2129 * SetFileSecurityW [ADVAPI32.@]
2131 * Sets the security of a file or directory.
2133 * PARAMS
2134 * lpFileName []
2135 * RequestedInformation []
2136 * pSecurityDescriptor []
2138 * RETURNS
2139 * Success: TRUE.
2140 * Failure: FALSE.
2142 BOOL WINAPI
2143 SetFileSecurityW( LPCWSTR lpFileName,
2144 SECURITY_INFORMATION RequestedInformation,
2145 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2147 HANDLE file;
2148 DWORD access = 0;
2149 NTSTATUS status;
2151 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2152 pSecurityDescriptor );
2154 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2155 RequestedInformation & GROUP_SECURITY_INFORMATION)
2156 access |= WRITE_OWNER;
2157 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2158 access |= ACCESS_SYSTEM_SECURITY;
2159 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2160 access |= WRITE_DAC;
2162 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2163 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2164 if (file == INVALID_HANDLE_VALUE)
2165 return FALSE;
2167 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2168 CloseHandle( file );
2169 return set_ntstatus( status );
2172 /******************************************************************************
2173 * QueryWindows31FilesMigration [ADVAPI32.@]
2175 * PARAMS
2176 * x1 []
2178 BOOL WINAPI
2179 QueryWindows31FilesMigration( DWORD x1 )
2181 FIXME("(%d):stub\n",x1);
2182 return TRUE;
2185 /******************************************************************************
2186 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2188 * PARAMS
2189 * x1 []
2190 * x2 []
2191 * x3 []
2192 * x4 []
2194 BOOL WINAPI
2195 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2196 DWORD x4 )
2198 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2199 return TRUE;
2202 /******************************************************************************
2203 * NotifyBootConfigStatus [ADVAPI32.@]
2205 * PARAMS
2206 * x1 []
2208 BOOL WINAPI
2209 NotifyBootConfigStatus( BOOL x1 )
2211 FIXME("(0x%08d):stub\n",x1);
2212 return 1;
2215 /******************************************************************************
2216 * RevertToSelf [ADVAPI32.@]
2218 * Ends the impersonation of a user.
2220 * PARAMS
2221 * void []
2223 * RETURNS
2224 * Success: TRUE.
2225 * Failure: FALSE.
2227 BOOL WINAPI
2228 RevertToSelf( void )
2230 HANDLE Token = NULL;
2231 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2232 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2235 /******************************************************************************
2236 * ImpersonateSelf [ADVAPI32.@]
2238 * Makes an impersonation token that represents the process user and assigns
2239 * to the current thread.
2241 * PARAMS
2242 * ImpersonationLevel [I] Level at which to impersonate.
2244 * RETURNS
2245 * Success: TRUE.
2246 * Failure: FALSE.
2248 BOOL WINAPI
2249 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2251 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2254 /******************************************************************************
2255 * ImpersonateLoggedOnUser [ADVAPI32.@]
2257 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2259 DWORD size;
2260 NTSTATUS Status;
2261 HANDLE ImpersonationToken;
2262 TOKEN_TYPE Type;
2264 FIXME( "(%p)\n", hToken );
2266 if (!GetTokenInformation( hToken, TokenType, &Type,
2267 sizeof(TOKEN_TYPE), &size ))
2268 return FALSE;
2270 if (Type == TokenPrimary)
2272 OBJECT_ATTRIBUTES ObjectAttributes;
2274 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2276 Status = NtDuplicateToken( hToken,
2277 TOKEN_IMPERSONATE | TOKEN_QUERY,
2278 &ObjectAttributes,
2279 SecurityImpersonation,
2280 TokenImpersonation,
2281 &ImpersonationToken );
2282 if (Status != STATUS_SUCCESS)
2284 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2285 SetLastError( RtlNtStatusToDosError( Status ) );
2286 return FALSE;
2289 else
2290 ImpersonationToken = hToken;
2292 Status = NtSetInformationThread( GetCurrentThread(),
2293 ThreadImpersonationToken,
2294 &ImpersonationToken,
2295 sizeof(ImpersonationToken) );
2297 if (Type == TokenPrimary)
2298 NtClose( ImpersonationToken );
2300 if (Status != STATUS_SUCCESS)
2302 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2303 SetLastError( RtlNtStatusToDosError( Status ) );
2304 return FALSE;
2307 return TRUE;
2310 /******************************************************************************
2311 * AccessCheck [ADVAPI32.@]
2313 BOOL WINAPI
2314 AccessCheck(
2315 PSECURITY_DESCRIPTOR SecurityDescriptor,
2316 HANDLE ClientToken,
2317 DWORD DesiredAccess,
2318 PGENERIC_MAPPING GenericMapping,
2319 PPRIVILEGE_SET PrivilegeSet,
2320 LPDWORD PrivilegeSetLength,
2321 LPDWORD GrantedAccess,
2322 LPBOOL AccessStatus)
2324 NTSTATUS access_status;
2325 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2326 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2327 GrantedAccess, &access_status) );
2328 if (ret) *AccessStatus = set_ntstatus( access_status );
2329 return ret;
2333 /******************************************************************************
2334 * AccessCheckByType [ADVAPI32.@]
2336 BOOL WINAPI AccessCheckByType(
2337 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2338 PSID PrincipalSelfSid,
2339 HANDLE ClientToken,
2340 DWORD DesiredAccess,
2341 POBJECT_TYPE_LIST ObjectTypeList,
2342 DWORD ObjectTypeListLength,
2343 PGENERIC_MAPPING GenericMapping,
2344 PPRIVILEGE_SET PrivilegeSet,
2345 LPDWORD PrivilegeSetLength,
2346 LPDWORD GrantedAccess,
2347 LPBOOL AccessStatus)
2349 FIXME("stub\n");
2351 *AccessStatus = TRUE;
2353 return !*AccessStatus;
2356 /******************************************************************************
2357 * MapGenericMask [ADVAPI32.@]
2359 * Maps generic access rights into specific access rights according to the
2360 * supplied mapping.
2362 * PARAMS
2363 * AccessMask [I/O] Access rights.
2364 * GenericMapping [I] The mapping between generic and specific rights.
2366 * RETURNS
2367 * Nothing.
2369 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2371 RtlMapGenericMask( AccessMask, GenericMapping );
2374 /*************************************************************************
2375 * SetKernelObjectSecurity [ADVAPI32.@]
2377 BOOL WINAPI SetKernelObjectSecurity (
2378 IN HANDLE Handle,
2379 IN SECURITY_INFORMATION SecurityInformation,
2380 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2382 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2386 /******************************************************************************
2387 * AddAuditAccessAce [ADVAPI32.@]
2389 BOOL WINAPI AddAuditAccessAce(
2390 IN OUT PACL pAcl,
2391 IN DWORD dwAceRevision,
2392 IN DWORD dwAccessMask,
2393 IN PSID pSid,
2394 IN BOOL bAuditSuccess,
2395 IN BOOL bAuditFailure)
2397 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2398 bAuditSuccess, bAuditFailure) );
2401 /******************************************************************************
2402 * AddAuditAccessAce [ADVAPI32.@]
2404 BOOL WINAPI AddAuditAccessAceEx(
2405 IN OUT PACL pAcl,
2406 IN DWORD dwAceRevision,
2407 IN DWORD dwAceFlags,
2408 IN DWORD dwAccessMask,
2409 IN PSID pSid,
2410 IN BOOL bAuditSuccess,
2411 IN BOOL bAuditFailure)
2413 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2414 bAuditSuccess, bAuditFailure) );
2417 /******************************************************************************
2418 * LookupAccountNameA [ADVAPI32.@]
2420 BOOL WINAPI
2421 LookupAccountNameA(
2422 IN LPCSTR system,
2423 IN LPCSTR account,
2424 OUT PSID sid,
2425 OUT LPDWORD cbSid,
2426 LPSTR ReferencedDomainName,
2427 IN OUT LPDWORD cbReferencedDomainName,
2428 OUT PSID_NAME_USE name_use )
2430 BOOL ret;
2431 UNICODE_STRING lpSystemW;
2432 UNICODE_STRING lpAccountW;
2433 LPWSTR lpReferencedDomainNameW = NULL;
2435 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2436 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2438 if (ReferencedDomainName)
2439 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2441 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2442 cbReferencedDomainName, name_use);
2444 if (ret && lpReferencedDomainNameW)
2446 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2447 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2450 RtlFreeUnicodeString(&lpSystemW);
2451 RtlFreeUnicodeString(&lpAccountW);
2452 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2454 return ret;
2457 /******************************************************************************
2458 * LookupAccountNameW [ADVAPI32.@]
2460 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2461 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2462 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2464 /* Default implementation: Always return a default SID */
2465 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2466 BOOL ret;
2467 PSID pSid;
2468 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2470 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2471 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2473 ret = AllocateAndInitializeSid(&identifierAuthority,
2475 SECURITY_BUILTIN_DOMAIN_RID,
2476 DOMAIN_ALIAS_RID_ADMINS,
2477 0, 0, 0, 0, 0, 0,
2478 &pSid);
2480 if (!ret)
2481 return FALSE;
2483 if (!RtlValidSid(pSid))
2485 FreeSid(pSid);
2486 return FALSE;
2489 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2490 CopySid(*cbSid, Sid, pSid);
2491 if (*cbSid < GetLengthSid(pSid))
2493 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2494 ret = FALSE;
2496 *cbSid = GetLengthSid(pSid);
2498 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2499 strcpyW(ReferencedDomainName, dm);
2501 if (*cchReferencedDomainName <= strlenW(dm))
2503 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2504 ret = FALSE;
2507 *cchReferencedDomainName = strlenW(dm)+1;
2509 FreeSid(pSid);
2511 return ret;
2514 /******************************************************************************
2515 * PrivilegeCheck [ADVAPI32.@]
2517 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2519 BOOL ret;
2520 BOOLEAN Result;
2522 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2524 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2525 if (ret)
2526 *pfResult = Result;
2527 return ret;
2530 /******************************************************************************
2531 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2533 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2534 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2535 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2536 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2538 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2539 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2540 SecurityDescriptor, DesiredAccess, GenericMapping,
2541 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2542 return TRUE;
2545 /******************************************************************************
2546 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2548 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2549 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2550 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2551 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2553 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2554 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2555 SecurityDescriptor, DesiredAccess, GenericMapping,
2556 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2557 return TRUE;
2560 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2562 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2564 return TRUE;
2567 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2569 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2571 return TRUE;
2574 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2576 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2578 return TRUE;
2581 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2582 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2583 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2584 LPBOOL GenerateOnClose)
2586 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2587 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2588 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2589 GenerateOnClose);
2591 return TRUE;
2594 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2595 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2596 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2597 LPBOOL GenerateOnClose)
2599 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2600 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2601 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2602 GenerateOnClose);
2604 return TRUE;
2607 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2608 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2610 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2611 DesiredAccess, Privileges, AccessGranted);
2613 return TRUE;
2616 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2617 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2619 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2620 DesiredAccess, Privileges, AccessGranted);
2622 return TRUE;
2625 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2626 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2628 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2629 ClientToken, Privileges, AccessGranted);
2631 return TRUE;
2634 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2635 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2637 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2638 ClientToken, Privileges, AccessGranted);
2640 return TRUE;
2643 /******************************************************************************
2644 * GetSecurityInfo [ADVAPI32.@]
2646 DWORD WINAPI GetSecurityInfo(
2647 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2648 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2649 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2650 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2653 FIXME("stub!\n");
2654 return ERROR_BAD_PROVIDER;
2657 /******************************************************************************
2658 * GetSecurityInfoExW [ADVAPI32.@]
2660 DWORD WINAPI GetSecurityInfoExW(
2661 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2662 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2663 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2664 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2667 FIXME("stub!\n");
2668 return ERROR_BAD_PROVIDER;
2671 /******************************************************************************
2672 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2674 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2675 LPSTR pTrusteeName, DWORD AccessPermissions,
2676 ACCESS_MODE AccessMode, DWORD Inheritance )
2678 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2679 AccessPermissions, AccessMode, Inheritance);
2681 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2682 pExplicitAccess->grfAccessMode = AccessMode;
2683 pExplicitAccess->grfInheritance = Inheritance;
2685 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2686 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2687 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2688 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2689 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2692 /******************************************************************************
2693 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2695 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2696 LPWSTR pTrusteeName, DWORD AccessPermissions,
2697 ACCESS_MODE AccessMode, DWORD Inheritance )
2699 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2700 AccessPermissions, AccessMode, Inheritance);
2702 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2703 pExplicitAccess->grfAccessMode = AccessMode;
2704 pExplicitAccess->grfInheritance = Inheritance;
2706 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2707 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2708 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2709 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2710 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2713 /******************************************************************************
2714 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2716 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2717 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2718 LPSTR InheritedObjectTypeName, LPSTR Name )
2720 DWORD ObjectsPresent = 0;
2722 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2723 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2725 /* Fill the OBJECTS_AND_NAME structure */
2726 pObjName->ObjectType = ObjectType;
2727 if (ObjectTypeName != NULL)
2729 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2732 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2733 if (InheritedObjectTypeName != NULL)
2735 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2738 pObjName->ObjectsPresent = ObjectsPresent;
2739 pObjName->ptstrName = Name;
2741 /* Fill the TRUSTEE structure */
2742 pTrustee->pMultipleTrustee = NULL;
2743 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2744 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2745 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2746 pTrustee->ptstrName = (LPSTR)pObjName;
2749 /******************************************************************************
2750 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2752 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2753 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2754 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2756 DWORD ObjectsPresent = 0;
2758 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2759 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2761 /* Fill the OBJECTS_AND_NAME structure */
2762 pObjName->ObjectType = ObjectType;
2763 if (ObjectTypeName != NULL)
2765 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2768 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2769 if (InheritedObjectTypeName != NULL)
2771 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2774 pObjName->ObjectsPresent = ObjectsPresent;
2775 pObjName->ptstrName = Name;
2777 /* Fill the TRUSTEE structure */
2778 pTrustee->pMultipleTrustee = NULL;
2779 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2780 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2781 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2782 pTrustee->ptstrName = (LPWSTR)pObjName;
2785 /******************************************************************************
2786 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2788 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2789 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2791 DWORD ObjectsPresent = 0;
2793 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2795 /* Fill the OBJECTS_AND_SID structure */
2796 if (pObjectGuid != NULL)
2798 pObjSid->ObjectTypeGuid = *pObjectGuid;
2799 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2801 else
2803 ZeroMemory(&pObjSid->ObjectTypeGuid,
2804 sizeof(GUID));
2807 if (pInheritedObjectGuid != NULL)
2809 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2810 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2812 else
2814 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2815 sizeof(GUID));
2818 pObjSid->ObjectsPresent = ObjectsPresent;
2819 pObjSid->pSid = pSid;
2821 /* Fill the TRUSTEE structure */
2822 pTrustee->pMultipleTrustee = NULL;
2823 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2824 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2825 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2826 pTrustee->ptstrName = (LPSTR) pObjSid;
2829 /******************************************************************************
2830 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2832 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2833 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2835 DWORD ObjectsPresent = 0;
2837 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2839 /* Fill the OBJECTS_AND_SID structure */
2840 if (pObjectGuid != NULL)
2842 pObjSid->ObjectTypeGuid = *pObjectGuid;
2843 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2845 else
2847 ZeroMemory(&pObjSid->ObjectTypeGuid,
2848 sizeof(GUID));
2851 if (pInheritedObjectGuid != NULL)
2853 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2854 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2856 else
2858 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2859 sizeof(GUID));
2862 pObjSid->ObjectsPresent = ObjectsPresent;
2863 pObjSid->pSid = pSid;
2865 /* Fill the TRUSTEE structure */
2866 pTrustee->pMultipleTrustee = NULL;
2867 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2868 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2869 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2870 pTrustee->ptstrName = (LPWSTR) pObjSid;
2873 /******************************************************************************
2874 * BuildTrusteeWithSidA [ADVAPI32.@]
2876 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2878 TRACE("%p %p\n", pTrustee, pSid);
2880 pTrustee->pMultipleTrustee = NULL;
2881 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2882 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2883 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2884 pTrustee->ptstrName = (LPSTR) pSid;
2887 /******************************************************************************
2888 * BuildTrusteeWithSidW [ADVAPI32.@]
2890 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2892 TRACE("%p %p\n", pTrustee, pSid);
2894 pTrustee->pMultipleTrustee = NULL;
2895 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2896 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2897 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2898 pTrustee->ptstrName = (LPWSTR) pSid;
2901 /******************************************************************************
2902 * BuildTrusteeWithNameA [ADVAPI32.@]
2904 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2906 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2908 pTrustee->pMultipleTrustee = NULL;
2909 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2910 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2911 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2912 pTrustee->ptstrName = name;
2915 /******************************************************************************
2916 * BuildTrusteeWithNameW [ADVAPI32.@]
2918 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2920 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2922 pTrustee->pMultipleTrustee = NULL;
2923 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2924 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2925 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2926 pTrustee->ptstrName = name;
2929 /******************************************************************************
2930 * GetTrusteeFormA [ADVAPI32.@]
2932 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2934 TRACE("(%p)\n", pTrustee);
2936 if (!pTrustee)
2937 return TRUSTEE_BAD_FORM;
2939 return pTrustee->TrusteeForm;
2942 /******************************************************************************
2943 * GetTrusteeFormW [ADVAPI32.@]
2945 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2947 TRACE("(%p)\n", pTrustee);
2949 if (!pTrustee)
2950 return TRUSTEE_BAD_FORM;
2952 return pTrustee->TrusteeForm;
2955 /******************************************************************************
2956 * GetTrusteeNameA [ADVAPI32.@]
2958 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2960 TRACE("(%p)\n", pTrustee);
2962 if (!pTrustee)
2963 return NULL;
2965 return pTrustee->ptstrName;
2968 /******************************************************************************
2969 * GetTrusteeNameW [ADVAPI32.@]
2971 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2973 TRACE("(%p)\n", pTrustee);
2975 if (!pTrustee)
2976 return NULL;
2978 return pTrustee->ptstrName;
2981 /******************************************************************************
2982 * GetTrusteeTypeA [ADVAPI32.@]
2984 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2986 TRACE("(%p)\n", pTrustee);
2988 if (!pTrustee)
2989 return TRUSTEE_IS_UNKNOWN;
2991 return pTrustee->TrusteeType;
2994 /******************************************************************************
2995 * GetTrusteeTypeW [ADVAPI32.@]
2997 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
2999 TRACE("(%p)\n", pTrustee);
3001 if (!pTrustee)
3002 return TRUSTEE_IS_UNKNOWN;
3004 return pTrustee->TrusteeType;
3007 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3008 DWORD nAclInformationLength,
3009 ACL_INFORMATION_CLASS dwAclInformationClass )
3011 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3012 nAclInformationLength, dwAclInformationClass);
3014 return TRUE;
3017 /******************************************************************************
3018 * SetEntriesInAclA [ADVAPI32.@]
3020 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3021 PACL OldAcl, PACL* NewAcl )
3023 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3024 *NewAcl = NULL;
3025 return ERROR_SUCCESS;
3028 /******************************************************************************
3029 * SetEntriesInAclW [ADVAPI32.@]
3031 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3032 PACL OldAcl, PACL* NewAcl )
3034 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3035 *NewAcl = NULL;
3036 return ERROR_SUCCESS;
3039 /******************************************************************************
3040 * SetNamedSecurityInfoA [ADVAPI32.@]
3042 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3043 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3044 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3046 DWORD len;
3047 LPWSTR wstr = NULL;
3048 DWORD r;
3050 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3051 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3053 if( pObjectName )
3055 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3056 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3057 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3060 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3061 psidGroup, pDacl, pSacl );
3063 HeapFree( GetProcessHeap(), 0, wstr );
3065 return r;
3068 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3069 PSECURITY_DESCRIPTOR ModificationDescriptor,
3070 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3071 PGENERIC_MAPPING GenericMapping,
3072 HANDLE Token )
3074 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3075 ObjectsSecurityDescriptor, GenericMapping, Token);
3077 return TRUE;
3080 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
3081 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
3082 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
3084 FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
3085 ControlBitsToSet);
3087 return TRUE;
3090 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3092 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3095 /******************************************************************************
3096 * AreAnyAccessesGranted [ADVAPI32.@]
3098 * Determines whether or not any of a set of specified access permissions have
3099 * been granted or not.
3101 * PARAMS
3102 * GrantedAccess [I] The permissions that have been granted.
3103 * DesiredAccess [I] The permissions that you want to have.
3105 * RETURNS
3106 * Nonzero if any of the permissions have been granted, zero if none of the
3107 * permissions have been granted.
3110 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3112 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3115 /******************************************************************************
3116 * SetNamedSecurityInfoW [ADVAPI32.@]
3118 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3119 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3120 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3122 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3123 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3124 return ERROR_SUCCESS;
3127 /******************************************************************************
3128 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3130 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3131 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3133 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3134 return ERROR_CALL_NOT_IMPLEMENTED;
3137 /******************************************************************************
3138 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3140 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3141 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3143 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3144 return ERROR_CALL_NOT_IMPLEMENTED;
3148 /******************************************************************************
3149 * ParseAclStringFlags
3151 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3153 DWORD flags = 0;
3154 LPCWSTR szAcl = *StringAcl;
3156 while (*szAcl != '(')
3158 if (*szAcl == 'P')
3160 flags |= SE_DACL_PROTECTED;
3162 else if (*szAcl == 'A')
3164 szAcl++;
3165 if (*szAcl == 'R')
3166 flags |= SE_DACL_AUTO_INHERIT_REQ;
3167 else if (*szAcl == 'I')
3168 flags |= SE_DACL_AUTO_INHERITED;
3170 szAcl++;
3173 *StringAcl = szAcl;
3174 return flags;
3177 /******************************************************************************
3178 * ParseAceStringType
3180 static const ACEFLAG AceType[] =
3182 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3183 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3184 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3185 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3187 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3188 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3189 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3190 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3192 { NULL, 0 },
3195 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3197 UINT len = 0;
3198 LPCWSTR szAcl = *StringAcl;
3199 const ACEFLAG *lpaf = AceType;
3201 while (lpaf->wstr &&
3202 (len = strlenW(lpaf->wstr)) &&
3203 strncmpW(lpaf->wstr, szAcl, len))
3204 lpaf++;
3206 if (!lpaf->wstr)
3207 return 0;
3209 *StringAcl += len;
3210 return lpaf->value;
3214 /******************************************************************************
3215 * ParseAceStringFlags
3217 static const ACEFLAG AceFlags[] =
3219 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3220 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3221 { SDDL_INHERITED, INHERITED_ACE },
3222 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3223 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3224 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3225 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3226 { NULL, 0 },
3229 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3231 UINT len = 0;
3232 BYTE flags = 0;
3233 LPCWSTR szAcl = *StringAcl;
3235 while (*szAcl != ';')
3237 const ACEFLAG *lpaf = AceFlags;
3239 while (lpaf->wstr &&
3240 (len = strlenW(lpaf->wstr)) &&
3241 strncmpW(lpaf->wstr, szAcl, len))
3242 lpaf++;
3244 if (!lpaf->wstr)
3245 return 0;
3247 flags |= lpaf->value;
3248 szAcl += len;
3251 *StringAcl = szAcl;
3252 return flags;
3256 /******************************************************************************
3257 * ParseAceStringRights
3259 static const ACEFLAG AceRights[] =
3261 { SDDL_GENERIC_ALL, GENERIC_ALL },
3262 { SDDL_GENERIC_READ, GENERIC_READ },
3263 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3264 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3266 { SDDL_READ_CONTROL, READ_CONTROL },
3267 { SDDL_STANDARD_DELETE, DELETE },
3268 { SDDL_WRITE_DAC, WRITE_DAC },
3269 { SDDL_WRITE_OWNER, WRITE_OWNER },
3271 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3272 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3273 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3274 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3275 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3276 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3277 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3278 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3279 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3281 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3282 { SDDL_FILE_READ, FILE_GENERIC_READ },
3283 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3284 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3286 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3287 { SDDL_KEY_READ, KEY_READ },
3288 { SDDL_KEY_WRITE, KEY_WRITE },
3289 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3290 { NULL, 0 },
3293 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3295 UINT len = 0;
3296 DWORD rights = 0;
3297 LPCWSTR szAcl = *StringAcl;
3299 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3301 LPCWSTR p = szAcl;
3303 while (*p && *p != ';')
3304 p++;
3306 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3308 rights = strtoulW(szAcl, NULL, 16);
3309 szAcl = p;
3311 else
3312 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3314 else
3316 while (*szAcl != ';')
3318 const ACEFLAG *lpaf = AceRights;
3320 while (lpaf->wstr &&
3321 (len = strlenW(lpaf->wstr)) &&
3322 strncmpW(lpaf->wstr, szAcl, len))
3324 lpaf++;
3327 if (!lpaf->wstr)
3328 return 0;
3330 rights |= lpaf->value;
3331 szAcl += len;
3335 *StringAcl = szAcl;
3336 return rights;
3340 /******************************************************************************
3341 * ParseStringAclToAcl
3343 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3345 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3346 PACL pAcl, LPDWORD cBytes)
3348 DWORD val;
3349 DWORD sidlen;
3350 DWORD length = sizeof(ACL);
3351 DWORD acesize = 0;
3352 DWORD acecount = 0;
3353 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3355 TRACE("%s\n", debugstr_w(StringAcl));
3357 if (!StringAcl)
3358 return FALSE;
3360 if (pAcl) /* pAce is only useful if we're setting values */
3361 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3363 /* Parse ACL flags */
3364 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3366 /* Parse ACE */
3367 while (*StringAcl == '(')
3369 StringAcl++;
3371 /* Parse ACE type */
3372 val = ParseAceStringType(&StringAcl);
3373 if (pAce)
3374 pAce->Header.AceType = (BYTE) val;
3375 if (*StringAcl != ';')
3376 goto lerr;
3377 StringAcl++;
3379 /* Parse ACE flags */
3380 val = ParseAceStringFlags(&StringAcl);
3381 if (pAce)
3382 pAce->Header.AceFlags = (BYTE) val;
3383 if (*StringAcl != ';')
3384 goto lerr;
3385 StringAcl++;
3387 /* Parse ACE rights */
3388 val = ParseAceStringRights(&StringAcl);
3389 if (pAce)
3390 pAce->Mask = val;
3391 if (*StringAcl != ';')
3392 goto lerr;
3393 StringAcl++;
3395 /* Parse ACE object guid */
3396 if (*StringAcl != ';')
3398 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3399 goto lerr;
3401 StringAcl++;
3403 /* Parse ACE inherit object guid */
3404 if (*StringAcl != ';')
3406 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3407 goto lerr;
3409 StringAcl++;
3411 /* Parse ACE account sid */
3412 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3414 while (*StringAcl && *StringAcl != ')')
3415 StringAcl++;
3418 if (*StringAcl != ')')
3419 goto lerr;
3420 StringAcl++;
3422 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3423 length += acesize;
3424 if (pAce)
3426 pAce->Header.AceSize = acesize;
3427 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3429 acecount++;
3432 *cBytes = length;
3434 if (length > 0xffff)
3436 ERR("ACL too large\n");
3437 goto lerr;
3440 if (pAcl)
3442 pAcl->AclRevision = ACL_REVISION;
3443 pAcl->Sbz1 = 0;
3444 pAcl->AclSize = length;
3445 pAcl->AceCount = acecount++;
3446 pAcl->Sbz2 = 0;
3448 return TRUE;
3450 lerr:
3451 WARN("Invalid ACE string format\n");
3452 return FALSE;
3456 /******************************************************************************
3457 * ParseStringSecurityDescriptorToSecurityDescriptor
3459 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3460 LPCWSTR StringSecurityDescriptor,
3461 SECURITY_DESCRIPTOR* SecurityDescriptor,
3462 LPDWORD cBytes)
3464 BOOL bret = FALSE;
3465 WCHAR toktype;
3466 WCHAR tok[MAX_PATH];
3467 LPCWSTR lptoken;
3468 LPBYTE lpNext = NULL;
3469 DWORD len;
3471 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3473 if (SecurityDescriptor)
3474 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3476 while (*StringSecurityDescriptor)
3478 toktype = *StringSecurityDescriptor;
3480 /* Expect char identifier followed by ':' */
3481 StringSecurityDescriptor++;
3482 if (*StringSecurityDescriptor != ':')
3484 SetLastError(ERROR_INVALID_PARAMETER);
3485 goto lend;
3487 StringSecurityDescriptor++;
3489 /* Extract token */
3490 lptoken = StringSecurityDescriptor;
3491 while (*lptoken && *lptoken != ':')
3492 lptoken++;
3494 if (*lptoken)
3495 lptoken--;
3497 len = lptoken - StringSecurityDescriptor;
3498 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3499 tok[len] = 0;
3501 switch (toktype)
3503 case 'O':
3505 DWORD bytes;
3507 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3508 goto lend;
3510 if (SecurityDescriptor)
3512 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3513 lpNext += bytes; /* Advance to next token */
3516 *cBytes += bytes;
3518 break;
3521 case 'G':
3523 DWORD bytes;
3525 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3526 goto lend;
3528 if (SecurityDescriptor)
3530 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3531 lpNext += bytes; /* Advance to next token */
3534 *cBytes += bytes;
3536 break;
3539 case 'D':
3541 DWORD flags;
3542 DWORD bytes;
3544 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3545 goto lend;
3547 if (SecurityDescriptor)
3549 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3550 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3551 lpNext += bytes; /* Advance to next token */
3554 *cBytes += bytes;
3556 break;
3559 case 'S':
3561 DWORD flags;
3562 DWORD bytes;
3564 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3565 goto lend;
3567 if (SecurityDescriptor)
3569 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3570 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3571 lpNext += bytes; /* Advance to next token */
3574 *cBytes += bytes;
3576 break;
3579 default:
3580 FIXME("Unknown token\n");
3581 SetLastError(ERROR_INVALID_PARAMETER);
3582 goto lend;
3585 StringSecurityDescriptor = lptoken;
3588 bret = TRUE;
3590 lend:
3591 return bret;
3594 /******************************************************************************
3595 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3597 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3598 LPCSTR StringSecurityDescriptor,
3599 DWORD StringSDRevision,
3600 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3601 PULONG SecurityDescriptorSize)
3603 UINT len;
3604 BOOL ret = FALSE;
3605 LPWSTR StringSecurityDescriptorW;
3607 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3608 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3610 if (StringSecurityDescriptorW)
3612 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3614 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3615 StringSDRevision, SecurityDescriptor,
3616 SecurityDescriptorSize);
3617 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3620 return ret;
3623 /******************************************************************************
3624 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3626 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3627 LPCWSTR StringSecurityDescriptor,
3628 DWORD StringSDRevision,
3629 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3630 PULONG SecurityDescriptorSize)
3632 DWORD cBytes;
3633 SECURITY_DESCRIPTOR* psd;
3634 BOOL bret = FALSE;
3636 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3638 if (GetVersion() & 0x80000000)
3640 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3641 goto lend;
3643 else if (StringSDRevision != SID_REVISION)
3645 SetLastError(ERROR_UNKNOWN_REVISION);
3646 goto lend;
3649 /* Compute security descriptor length */
3650 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3651 NULL, &cBytes))
3652 goto lend;
3654 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3655 GMEM_ZEROINIT, cBytes);
3656 if (!psd) goto lend;
3658 psd->Revision = SID_REVISION;
3659 psd->Control |= SE_SELF_RELATIVE;
3661 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3662 psd, &cBytes))
3664 LocalFree(psd);
3665 goto lend;
3668 if (SecurityDescriptorSize)
3669 *SecurityDescriptorSize = cBytes;
3671 bret = TRUE;
3673 lend:
3674 TRACE(" ret=%d\n", bret);
3675 return bret;
3678 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3680 if (cch == -1)
3681 cch = strlenW(string);
3683 if (plen)
3684 *plen += cch;
3686 if (pwptr)
3688 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3689 *pwptr += cch;
3693 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3695 DWORD i;
3696 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3697 WCHAR subauthfmt[] = { '-','%','u',0 };
3698 WCHAR buf[26];
3699 SID *pisid = psid;
3701 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3703 SetLastError(ERROR_INVALID_SID);
3704 return FALSE;
3707 if (pisid->IdentifierAuthority.Value[0] ||
3708 pisid->IdentifierAuthority.Value[1])
3710 FIXME("not matching MS' bugs\n");
3711 SetLastError(ERROR_INVALID_SID);
3712 return FALSE;
3715 sprintfW( buf, fmt, pisid->Revision,
3716 MAKELONG(
3717 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3718 pisid->IdentifierAuthority.Value[4] ),
3719 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3720 pisid->IdentifierAuthority.Value[2] )
3721 ) );
3722 DumpString(buf, -1, pwptr, plen);
3724 for( i=0; i<pisid->SubAuthorityCount; i++ )
3726 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3727 DumpString(buf, -1, pwptr, plen);
3729 return TRUE;
3732 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3734 int i;
3735 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3737 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3739 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3740 return TRUE;
3744 return DumpSidNumeric(psid, pwptr, plen);
3747 static const LPCWSTR AceRightBitNames[32] = {
3748 SDDL_CREATE_CHILD, /* 0 */
3749 SDDL_DELETE_CHILD,
3750 SDDL_LIST_CHILDREN,
3751 SDDL_SELF_WRITE,
3752 SDDL_READ_PROPERTY, /* 4 */
3753 SDDL_WRITE_PROPERTY,
3754 SDDL_DELETE_TREE,
3755 SDDL_LIST_OBJECT,
3756 SDDL_CONTROL_ACCESS, /* 8 */
3757 NULL,
3758 NULL,
3759 NULL,
3760 NULL, /* 12 */
3761 NULL,
3762 NULL,
3763 NULL,
3764 SDDL_STANDARD_DELETE, /* 16 */
3765 SDDL_READ_CONTROL,
3766 SDDL_WRITE_DAC,
3767 SDDL_WRITE_OWNER,
3768 NULL, /* 20 */
3769 NULL,
3770 NULL,
3771 NULL,
3772 NULL, /* 24 */
3773 NULL,
3774 NULL,
3775 NULL,
3776 SDDL_GENERIC_ALL, /* 28 */
3777 SDDL_GENERIC_EXECUTE,
3778 SDDL_GENERIC_WRITE,
3779 SDDL_GENERIC_READ
3782 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
3784 static const WCHAR fmtW[] = {'0','x','%','x',0};
3785 WCHAR buf[15];
3786 int i;
3788 if (mask == 0)
3789 return;
3791 /* first check if the right have name */
3792 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
3794 if (AceRights[i].wstr == NULL)
3795 break;
3796 if (mask == AceRights[i].value)
3798 DumpString(AceRights[i].wstr, -1, pwptr, plen);
3799 return;
3803 /* then check if it can be built from bit names */
3804 for (i = 0; i < 32; i++)
3806 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
3808 /* can't be built from bit names */
3809 sprintfW(buf, fmtW, mask);
3810 DumpString(buf, -1, pwptr, plen);
3811 return;
3815 /* build from bit names */
3816 for (i = 0; i < 32; i++)
3817 if (mask & (1 << i))
3818 DumpString(AceRightBitNames[i], -1, pwptr, plen);
3821 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
3823 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
3824 static const WCHAR openbr = '(';
3825 static const WCHAR closebr = ')';
3826 static const WCHAR semicolon = ';';
3828 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
3830 SetLastError(ERROR_INVALID_ACL);
3831 return FALSE;
3834 piace = (ACCESS_ALLOWED_ACE *)pace;
3835 DumpString(&openbr, 1, pwptr, plen);
3836 switch (piace->Header.AceType)
3838 case ACCESS_ALLOWED_ACE_TYPE:
3839 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
3840 break;
3841 case ACCESS_DENIED_ACE_TYPE:
3842 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
3843 break;
3844 case SYSTEM_AUDIT_ACE_TYPE:
3845 DumpString(SDDL_AUDIT, -1, pwptr, plen);
3846 break;
3847 case SYSTEM_ALARM_ACE_TYPE:
3848 DumpString(SDDL_ALARM, -1, pwptr, plen);
3849 break;
3851 DumpString(&semicolon, 1, pwptr, plen);
3853 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
3854 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
3855 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
3856 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
3857 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
3858 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
3859 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
3860 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
3861 if (piace->Header.AceFlags & INHERITED_ACE)
3862 DumpString(SDDL_INHERITED, -1, pwptr, plen);
3863 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
3864 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
3865 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
3866 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
3867 DumpString(&semicolon, 1, pwptr, plen);
3868 DumpRights(piace->Mask, pwptr, plen);
3869 DumpString(&semicolon, 1, pwptr, plen);
3870 /* objects not supported */
3871 DumpString(&semicolon, 1, pwptr, plen);
3872 /* objects not supported */
3873 DumpString(&semicolon, 1, pwptr, plen);
3874 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
3875 return FALSE;
3876 DumpString(&closebr, 1, pwptr, plen);
3877 return TRUE;
3880 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
3882 WORD count;
3883 int i;
3885 if (protected)
3886 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
3887 if (autoInheritReq)
3888 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
3889 if (autoInherited)
3890 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
3892 if (pacl == NULL)
3893 return TRUE;
3895 if (!IsValidAcl(pacl))
3896 return FALSE;
3898 count = pacl->AceCount;
3899 for (i = 0; i < count; i++)
3901 LPVOID ace;
3902 if (!GetAce(pacl, i, &ace))
3903 return FALSE;
3904 if (!DumpAce(ace, pwptr, plen))
3905 return FALSE;
3908 return TRUE;
3911 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3913 static const WCHAR prefix[] = {'O',':',0};
3914 BOOL bDefaulted;
3915 PSID psid;
3917 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
3918 return FALSE;
3920 if (psid == NULL)
3921 return TRUE;
3923 DumpString(prefix, -1, pwptr, plen);
3924 if (!DumpSid(psid, pwptr, plen))
3925 return FALSE;
3926 return TRUE;
3929 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3931 static const WCHAR prefix[] = {'G',':',0};
3932 BOOL bDefaulted;
3933 PSID psid;
3935 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
3936 return FALSE;
3938 if (psid == NULL)
3939 return TRUE;
3941 DumpString(prefix, -1, pwptr, plen);
3942 if (!DumpSid(psid, pwptr, plen))
3943 return FALSE;
3944 return TRUE;
3947 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3949 static const WCHAR dacl[] = {'D',':',0};
3950 SECURITY_DESCRIPTOR_CONTROL control;
3951 BOOL present, defaulted;
3952 DWORD revision;
3953 PACL pacl;
3955 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
3956 return FALSE;
3958 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3959 return FALSE;
3961 if (!present)
3962 return TRUE;
3964 DumpString(dacl, 2, pwptr, plen);
3965 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
3966 return FALSE;
3967 return TRUE;
3970 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
3972 static const WCHAR sacl[] = {'S',':',0};
3973 SECURITY_DESCRIPTOR_CONTROL control;
3974 BOOL present, defaulted;
3975 DWORD revision;
3976 PACL pacl;
3978 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
3979 return FALSE;
3981 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
3982 return FALSE;
3984 if (!present)
3985 return TRUE;
3987 DumpString(sacl, 2, pwptr, plen);
3988 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
3989 return FALSE;
3990 return TRUE;
3993 /******************************************************************************
3994 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
3996 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
3998 ULONG len;
3999 WCHAR *wptr, *wstr;
4001 if (SDRevision != SDDL_REVISION_1)
4003 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4004 SetLastError(ERROR_UNKNOWN_REVISION);
4005 return FALSE;
4008 len = 0;
4009 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4010 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4011 return FALSE;
4012 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4013 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4014 return FALSE;
4015 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4016 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4017 return FALSE;
4018 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4019 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4020 return FALSE;
4022 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4023 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4024 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4025 return FALSE;
4026 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4027 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4028 return FALSE;
4029 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4030 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4031 return FALSE;
4032 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4033 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4034 return FALSE;
4035 *wptr = 0;
4037 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4038 *OutputString = wstr;
4039 if (OutputLen)
4040 *OutputLen = strlenW(*OutputString)+1;
4041 return TRUE;
4044 /******************************************************************************
4045 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4047 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4049 LPWSTR wstr;
4050 ULONG len;
4051 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4053 int lenA;
4055 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4056 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4057 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4058 LocalFree(wstr);
4060 if (OutputLen != NULL)
4061 *OutputLen = lenA;
4062 return TRUE;
4064 else
4066 *OutputString = NULL;
4067 if (OutputLen)
4068 *OutputLen = 0;
4069 return FALSE;
4073 /******************************************************************************
4074 * ConvertStringSidToSidW [ADVAPI32.@]
4076 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4078 BOOL bret = FALSE;
4079 DWORD cBytes;
4081 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4082 if (GetVersion() & 0x80000000)
4083 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4084 else if (!StringSid || !Sid)
4085 SetLastError(ERROR_INVALID_PARAMETER);
4086 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4088 PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
4090 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4091 if (!bret)
4092 LocalFree(*Sid);
4094 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4095 return bret;
4098 /******************************************************************************
4099 * ConvertStringSidToSidA [ADVAPI32.@]
4101 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4103 BOOL bret = FALSE;
4105 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4106 if (GetVersion() & 0x80000000)
4107 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4108 else if (!StringSid || !Sid)
4109 SetLastError(ERROR_INVALID_PARAMETER);
4110 else
4112 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4113 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4114 len * sizeof(WCHAR));
4116 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4117 bret = ConvertStringSidToSidW(wStringSid, Sid);
4118 HeapFree(GetProcessHeap(), 0, wStringSid);
4120 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4121 return bret;
4124 /******************************************************************************
4125 * ConvertSidToStringSidW [ADVAPI32.@]
4127 * format of SID string is:
4128 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4129 * where
4130 * <rev> is the revision of the SID encoded as decimal
4131 * <auth> is the identifier authority encoded as hex
4132 * <subauthN> is the subauthority id encoded as decimal
4134 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4136 DWORD len = 0;
4137 LPWSTR wstr, wptr;
4139 TRACE("%p %p\n", pSid, pstr );
4141 len = 0;
4142 if (!DumpSidNumeric(pSid, NULL, &len))
4143 return FALSE;
4144 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4145 DumpSidNumeric(pSid, &wptr, NULL);
4146 *wptr = 0;
4148 *pstr = wstr;
4149 return TRUE;
4152 /******************************************************************************
4153 * ConvertSidToStringSidA [ADVAPI32.@]
4155 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4157 LPWSTR wstr = NULL;
4158 LPSTR str;
4159 UINT len;
4161 TRACE("%p %p\n", pSid, pstr );
4163 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4164 return FALSE;
4166 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4167 str = LocalAlloc( 0, len );
4168 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4169 LocalFree( wstr );
4171 *pstr = str;
4173 return TRUE;
4176 BOOL WINAPI CreatePrivateObjectSecurity(
4177 PSECURITY_DESCRIPTOR ParentDescriptor,
4178 PSECURITY_DESCRIPTOR CreatorDescriptor,
4179 PSECURITY_DESCRIPTOR* NewDescriptor,
4180 BOOL IsDirectoryObject,
4181 HANDLE Token,
4182 PGENERIC_MAPPING GenericMapping )
4184 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4185 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4187 return FALSE;
4190 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4192 FIXME("%p - stub\n", ObjectDescriptor);
4194 return TRUE;
4197 BOOL WINAPI CreateProcessAsUserA(
4198 HANDLE hToken,
4199 LPCSTR lpApplicationName,
4200 LPSTR lpCommandLine,
4201 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4202 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4203 BOOL bInheritHandles,
4204 DWORD dwCreationFlags,
4205 LPVOID lpEnvironment,
4206 LPCSTR lpCurrentDirectory,
4207 LPSTARTUPINFOA lpStartupInfo,
4208 LPPROCESS_INFORMATION lpProcessInformation )
4210 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4211 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4212 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4214 return FALSE;
4217 BOOL WINAPI CreateProcessAsUserW(
4218 HANDLE hToken,
4219 LPCWSTR lpApplicationName,
4220 LPWSTR lpCommandLine,
4221 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4222 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4223 BOOL bInheritHandles,
4224 DWORD dwCreationFlags,
4225 LPVOID lpEnvironment,
4226 LPCWSTR lpCurrentDirectory,
4227 LPSTARTUPINFOW lpStartupInfo,
4228 LPPROCESS_INFORMATION lpProcessInformation )
4230 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4231 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4232 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4233 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4235 /* We should create the process with a suspended main thread */
4236 if (!CreateProcessW (lpApplicationName,
4237 lpCommandLine,
4238 lpProcessAttributes,
4239 lpThreadAttributes,
4240 bInheritHandles,
4241 dwCreationFlags, /* CREATE_SUSPENDED */
4242 lpEnvironment,
4243 lpCurrentDirectory,
4244 lpStartupInfo,
4245 lpProcessInformation))
4247 return FALSE;
4250 return TRUE;
4253 /******************************************************************************
4254 * DuplicateTokenEx [ADVAPI32.@]
4256 BOOL WINAPI DuplicateTokenEx(
4257 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4258 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4259 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4260 TOKEN_TYPE TokenType,
4261 PHANDLE DuplicateTokenHandle )
4263 OBJECT_ATTRIBUTES ObjectAttributes;
4265 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4266 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4268 InitializeObjectAttributes(
4269 &ObjectAttributes,
4270 NULL,
4271 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4272 NULL,
4273 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4275 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4276 dwDesiredAccess,
4277 &ObjectAttributes,
4278 ImpersonationLevel,
4279 TokenType,
4280 DuplicateTokenHandle ) );
4283 BOOL WINAPI DuplicateToken(
4284 HANDLE ExistingTokenHandle,
4285 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4286 PHANDLE DuplicateTokenHandle )
4288 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4289 NULL, ImpersonationLevel, TokenImpersonation,
4290 DuplicateTokenHandle );
4293 BOOL WINAPI EnumDependentServicesA(
4294 SC_HANDLE hService,
4295 DWORD dwServiceState,
4296 LPENUM_SERVICE_STATUSA lpServices,
4297 DWORD cbBufSize,
4298 LPDWORD pcbBytesNeeded,
4299 LPDWORD lpServicesReturned )
4301 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4302 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4304 return FALSE;
4307 BOOL WINAPI EnumDependentServicesW(
4308 SC_HANDLE hService,
4309 DWORD dwServiceState,
4310 LPENUM_SERVICE_STATUSW lpServices,
4311 DWORD cbBufSize,
4312 LPDWORD pcbBytesNeeded,
4313 LPDWORD lpServicesReturned )
4315 FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
4316 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
4318 return FALSE;
4321 /******************************************************************************
4322 * ComputeStringSidSize
4324 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4326 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4328 int ctok = 0;
4329 while (*StringSid)
4331 if (*StringSid == '-')
4332 ctok++;
4333 StringSid++;
4336 if (ctok >= 3)
4337 return GetSidLengthRequired(ctok - 2);
4339 else /* String constant format - Only available in winxp and above */
4341 unsigned int i;
4343 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4344 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4345 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4348 return GetSidLengthRequired(0);
4351 /******************************************************************************
4352 * ParseStringSidToSid
4354 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4356 BOOL bret = FALSE;
4357 SID* pisid=pSid;
4359 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4360 if (!StringSid)
4362 SetLastError(ERROR_INVALID_PARAMETER);
4363 TRACE("StringSid is NULL, returning FALSE\n");
4364 return FALSE;
4367 *cBytes = ComputeStringSidSize(StringSid);
4368 if (!pisid) /* Simply compute the size */
4370 TRACE("only size requested, returning TRUE\n");
4371 return TRUE;
4374 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4376 DWORD i = 0, identAuth;
4377 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4379 StringSid += 2; /* Advance to Revision */
4380 pisid->Revision = atoiW(StringSid);
4382 if (pisid->Revision != SDDL_REVISION)
4384 TRACE("Revision %d is unknown\n", pisid->Revision);
4385 goto lend; /* ERROR_INVALID_SID */
4387 if (csubauth == 0)
4389 TRACE("SubAuthorityCount is 0\n");
4390 goto lend; /* ERROR_INVALID_SID */
4393 pisid->SubAuthorityCount = csubauth;
4395 /* Advance to identifier authority */
4396 while (*StringSid && *StringSid != '-')
4397 StringSid++;
4398 if (*StringSid == '-')
4399 StringSid++;
4401 /* MS' implementation can't handle values greater than 2^32 - 1, so
4402 * we don't either; assume most significant bytes are always 0
4404 pisid->IdentifierAuthority.Value[0] = 0;
4405 pisid->IdentifierAuthority.Value[1] = 0;
4406 identAuth = atoiW(StringSid);
4407 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4408 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4409 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4410 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4412 /* Advance to first sub authority */
4413 while (*StringSid && *StringSid != '-')
4414 StringSid++;
4415 if (*StringSid == '-')
4416 StringSid++;
4418 while (*StringSid)
4420 pisid->SubAuthority[i++] = atoiW(StringSid);
4422 while (*StringSid && *StringSid != '-')
4423 StringSid++;
4424 if (*StringSid == '-')
4425 StringSid++;
4428 if (i != pisid->SubAuthorityCount)
4429 goto lend; /* ERROR_INVALID_SID */
4431 bret = TRUE;
4433 else /* String constant format - Only available in winxp and above */
4435 unsigned int i;
4436 pisid->Revision = SDDL_REVISION;
4438 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4439 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4441 DWORD j;
4442 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4443 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4444 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4445 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4446 bret = TRUE;
4449 if (!bret)
4450 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4453 lend:
4454 if (!bret)
4455 SetLastError(ERROR_INVALID_SID);
4457 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4458 return bret;
4461 /******************************************************************************
4462 * GetNamedSecurityInfoA [ADVAPI32.@]
4464 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4465 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4466 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4467 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4469 DWORD len;
4470 LPWSTR wstr = NULL;
4471 DWORD r;
4473 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4474 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4476 if( pObjectName )
4478 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4479 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4480 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4483 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4484 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4486 HeapFree( GetProcessHeap(), 0, wstr );
4488 return r;
4491 /******************************************************************************
4492 * GetNamedSecurityInfoW [ADVAPI32.@]
4494 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4495 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4496 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4498 DWORD needed, offset;
4499 SECURITY_DESCRIPTOR_RELATIVE *relative;
4500 BYTE *buffer;
4502 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4503 group, dacl, sacl, descriptor );
4505 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4507 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4508 if (info & OWNER_SECURITY_INFORMATION)
4509 needed += sizeof(sidWorld);
4510 if (info & GROUP_SECURITY_INFORMATION)
4511 needed += sizeof(sidWorld);
4512 if (info & DACL_SECURITY_INFORMATION)
4513 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4514 if (info & SACL_SECURITY_INFORMATION)
4515 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4517 /* must be freed by caller */
4518 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4519 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4521 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4523 HeapFree( GetProcessHeap(), 0, *descriptor );
4524 return ERROR_INVALID_SECURITY_DESCR;
4527 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4528 relative->Control |= SE_SELF_RELATIVE;
4529 buffer = (BYTE *)relative;
4530 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4532 if (info & OWNER_SECURITY_INFORMATION)
4534 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4535 relative->Owner = offset;
4536 if (owner)
4537 *owner = buffer + offset;
4538 offset += sizeof(sidWorld);
4540 if (info & GROUP_SECURITY_INFORMATION)
4542 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4543 relative->Group = offset;
4544 if (group)
4545 *group = buffer + offset;
4546 offset += sizeof(sidWorld);
4548 if (info & DACL_SECURITY_INFORMATION)
4550 relative->Control |= SE_DACL_PRESENT;
4551 GetWorldAccessACL( (PACL)(buffer + offset) );
4552 relative->Dacl = offset;
4553 if (dacl)
4554 *dacl = (PACL)(buffer + offset);
4555 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4557 if (info & SACL_SECURITY_INFORMATION)
4559 relative->Control |= SE_SACL_PRESENT;
4560 GetWorldAccessACL( (PACL)(buffer + offset) );
4561 relative->Sacl = offset;
4562 if (sacl)
4563 *sacl = (PACL)(buffer + offset);
4565 return ERROR_SUCCESS;
4568 /******************************************************************************
4569 * DecryptFileW [ADVAPI32.@]
4571 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4573 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4574 return TRUE;
4577 /******************************************************************************
4578 * DecryptFileA [ADVAPI32.@]
4580 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4582 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4583 return TRUE;
4586 /******************************************************************************
4587 * EncryptFileW [ADVAPI32.@]
4589 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4591 FIXME("%s\n", debugstr_w(lpFileName));
4592 return TRUE;
4595 /******************************************************************************
4596 * EncryptFileA [ADVAPI32.@]
4598 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4600 FIXME("%s\n", debugstr_a(lpFileName));
4601 return TRUE;
4604 /******************************************************************************
4605 * FileEncryptionStatusW [ADVAPI32.@]
4607 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4609 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4610 if (!lpStatus)
4611 return FALSE;
4612 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4613 return TRUE;
4616 /******************************************************************************
4617 * FileEncryptionStatusA [ADVAPI32.@]
4619 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4621 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4622 if (!lpStatus)
4623 return FALSE;
4624 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4625 return TRUE;
4628 /******************************************************************************
4629 * SetSecurityInfo [ADVAPI32.@]
4631 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4632 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4633 PSID psidGroup, PACL pDacl, PACL pSacl) {
4634 FIXME("stub\n");
4635 return ERROR_SUCCESS;