push 7f8c39dca3a5819e8ef115eebf7abed537de3a22
[wine/hacks.git] / dlls / advapi32 / security.c
blob2f9132968b7912567c137cd990db4cce18af4a8e
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
47 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
48 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
49 PACL pAcl, LPDWORD cBytes);
50 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
51 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
52 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
53 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
54 LPCWSTR StringSecurityDescriptor,
55 SECURITY_DESCRIPTOR* SecurityDescriptor,
56 LPDWORD cBytes);
57 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
59 typedef struct _ACEFLAG
61 LPCWSTR wstr;
62 DWORD value;
63 } ACEFLAG, *LPACEFLAG;
65 typedef struct _MAX_SID
67 /* same fields as struct _SID */
68 BYTE Revision;
69 BYTE SubAuthorityCount;
70 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } MAX_SID;
74 typedef struct WELLKNOWNSID
76 WCHAR wstr[2];
77 WELL_KNOWN_SID_TYPE Type;
78 MAX_SID Sid;
79 } WELLKNOWNSID;
81 static const WELLKNOWNSID WellKnownSids[] =
83 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
84 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
85 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
86 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
87 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
88 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
89 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
90 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
91 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
92 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
93 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
94 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
95 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
96 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
97 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
98 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
99 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
100 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
101 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
102 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
103 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
104 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
105 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
106 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
107 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
108 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
109 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
110 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
111 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
112 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
113 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
114 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
115 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
116 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
117 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
118 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
119 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
121 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
122 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
123 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
124 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
125 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
126 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
127 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
128 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
129 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
130 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
134 typedef struct WELLKNOWNRID
136 WELL_KNOWN_SID_TYPE Type;
137 DWORD Rid;
138 } WELLKNOWNRID;
140 static const WELLKNOWNRID WellKnownRids[] = {
141 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
142 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
143 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
144 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
145 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
146 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
147 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
148 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
149 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
150 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
151 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
152 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
153 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
157 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
159 typedef struct _AccountSid {
160 WELL_KNOWN_SID_TYPE type;
161 LPCWSTR account;
162 LPCWSTR domain;
163 SID_NAME_USE name_use;
164 } AccountSid;
166 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
167 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
168 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
169 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
170 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
171 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
172 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
173 static const WCHAR Blank[] = { 0 };
174 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
175 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
176 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
177 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
178 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
179 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
180 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
181 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
182 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
183 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
184 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
185 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
186 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
187 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
188 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
189 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
190 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
191 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
192 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
193 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
194 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
195 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
196 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
197 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
198 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
199 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
201 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
202 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
203 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
204 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
205 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
206 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
207 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
208 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
209 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
210 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
211 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
212 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
213 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
214 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
215 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
216 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
217 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
218 static const WCHAR SELF[] = { 'S','E','L','F',0 };
219 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
221 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
222 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
223 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
224 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
226 static const AccountSid ACCOUNT_SIDS[] = {
227 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
228 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
229 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
230 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
231 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
232 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
233 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
234 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
235 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
236 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
252 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
253 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
254 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
255 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
256 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
257 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
261 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
262 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
264 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
265 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
270 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
273 * ACE access rights
275 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
276 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
277 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
278 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
280 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
281 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
282 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
283 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
284 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
285 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
286 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
287 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
288 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
290 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
291 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
292 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
293 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
295 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
296 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
297 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
298 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
300 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
301 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
302 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
303 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
306 * ACL flags
308 static const WCHAR SDDL_PROTECTED[] = {'P',0};
309 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
310 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
313 * ACE types
315 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
316 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
317 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
319 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
320 static const WCHAR SDDL_ALARM[] = {'A','L',0};
321 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
322 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
325 * ACE flags
327 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
328 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
329 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
330 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
331 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
332 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
333 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
335 const char * debugstr_sid(PSID sid)
337 int auth = 0;
338 SID * psid = (SID *)sid;
340 if (psid == NULL)
341 return "(null)";
343 auth = psid->IdentifierAuthority.Value[5] +
344 (psid->IdentifierAuthority.Value[4] << 8) +
345 (psid->IdentifierAuthority.Value[3] << 16) +
346 (psid->IdentifierAuthority.Value[2] << 24);
348 switch (psid->SubAuthorityCount) {
349 case 0:
350 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
351 case 1:
352 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
353 psid->SubAuthority[0]);
354 case 2:
355 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
356 psid->SubAuthority[0], psid->SubAuthority[1]);
357 case 3:
358 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
359 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
360 case 4:
361 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
362 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
363 psid->SubAuthority[3]);
364 case 5:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
367 psid->SubAuthority[3], psid->SubAuthority[4]);
368 case 6:
369 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
370 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
371 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
372 case 7:
373 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
374 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
375 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
376 psid->SubAuthority[6]);
377 case 8:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
381 psid->SubAuthority[6], psid->SubAuthority[7]);
383 return "(too-big)";
386 /* set last error code from NT status and get the proper boolean return value */
387 /* used for functions that are a simple wrapper around the corresponding ntdll API */
388 static inline BOOL set_ntstatus( NTSTATUS status )
390 if (status) SetLastError( RtlNtStatusToDosError( status ));
391 return !status;
394 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
396 static void GetWorldAccessACL(PACL pACL)
398 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
400 pACL->AclRevision = ACL_REVISION;
401 pACL->Sbz1 = 0;
402 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
403 pACL->AceCount = 1;
404 pACL->Sbz2 = 0;
406 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
407 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
408 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
409 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
410 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
413 /************************************************************
414 * ADVAPI_IsLocalComputer
416 * Checks whether the server name indicates local machine.
418 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
420 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
421 BOOL Result;
422 LPWSTR buf;
424 if (!ServerName || !ServerName[0])
425 return TRUE;
427 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
428 Result = GetComputerNameW(buf, &dwSize);
429 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
430 ServerName += 2;
431 Result = Result && !lstrcmpW(ServerName, buf);
432 HeapFree(GetProcessHeap(), 0, buf);
434 return Result;
437 /************************************************************
438 * ADVAPI_GetComputerSid
440 * Reads the computer SID from the registry.
442 BOOL ADVAPI_GetComputerSid(PSID sid)
444 HKEY key;
445 LONG ret;
446 BOOL retval = FALSE;
447 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
448 static const WCHAR V[] = { 'V',0 };
450 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
451 KEY_READ, &key)) == ERROR_SUCCESS)
453 DWORD size = 0;
454 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
455 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
457 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
458 if (data)
460 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
461 data, &size)) == ERROR_SUCCESS)
463 /* the SID is in the last 24 bytes of the binary data */
464 CopyMemory(sid, &data[size-24], 24);
465 retval = TRUE;
467 HeapFree(GetProcessHeap(), 0, data);
470 RegCloseKey(key);
473 if(retval == TRUE) return retval;
475 /* create a new random SID */
476 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
477 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
479 PSID new_sid;
480 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
481 DWORD id[3];
483 if (RtlGenRandom(&id, sizeof(id)))
485 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
487 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
488 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
490 FreeSid(new_sid);
493 RegCloseKey(key);
496 return retval;
499 /* ##############################
500 ###### TOKEN FUNCTIONS ######
501 ##############################
504 /******************************************************************************
505 * OpenProcessToken [ADVAPI32.@]
506 * Opens the access token associated with a process handle.
508 * PARAMS
509 * ProcessHandle [I] Handle to process
510 * DesiredAccess [I] Desired access to process
511 * TokenHandle [O] Pointer to handle of open access token
513 * RETURNS
514 * Success: TRUE. TokenHandle contains the access token.
515 * Failure: FALSE.
517 * NOTES
518 * See NtOpenProcessToken.
520 BOOL WINAPI
521 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
522 HANDLE *TokenHandle )
524 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
527 /******************************************************************************
528 * OpenThreadToken [ADVAPI32.@]
530 * Opens the access token associated with a thread handle.
532 * PARAMS
533 * ThreadHandle [I] Handle to process
534 * DesiredAccess [I] Desired access to the thread
535 * OpenAsSelf [I] ???
536 * TokenHandle [O] Destination for the token handle
538 * RETURNS
539 * Success: TRUE. TokenHandle contains the access token.
540 * Failure: FALSE.
542 * NOTES
543 * See NtOpenThreadToken.
545 BOOL WINAPI
546 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
547 BOOL OpenAsSelf, HANDLE *TokenHandle)
549 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
552 BOOL WINAPI
553 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
554 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
556 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
557 PreviousState, ReturnLength));
560 /******************************************************************************
561 * AdjustTokenPrivileges [ADVAPI32.@]
563 * Adjust the privileges of an open token handle.
565 * PARAMS
566 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
567 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
568 * NewState [I] Desired new privileges of the token
569 * BufferLength [I] Length of NewState
570 * PreviousState [O] Destination for the previous state
571 * ReturnLength [I/O] Size of PreviousState
574 * RETURNS
575 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
576 * Failure: FALSE.
578 * NOTES
579 * See NtAdjustPrivilegesToken.
581 BOOL WINAPI
582 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
583 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
584 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
586 NTSTATUS status;
588 TRACE("\n");
590 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
591 NewState, BufferLength, PreviousState,
592 ReturnLength);
593 SetLastError( RtlNtStatusToDosError( status ));
594 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
595 return TRUE;
596 else
597 return FALSE;
600 /******************************************************************************
601 * CheckTokenMembership [ADVAPI32.@]
603 * Determine if an access token is a member of a SID.
605 * PARAMS
606 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
607 * SidToCheck [I] SID that possibly contains the token
608 * IsMember [O] Destination for result.
610 * RETURNS
611 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
612 * Failure: FALSE.
614 BOOL WINAPI
615 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
616 PBOOL IsMember )
618 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
620 *IsMember = TRUE;
621 return(TRUE);
624 /******************************************************************************
625 * GetTokenInformation [ADVAPI32.@]
627 * Get a type of information about an access token.
629 * PARAMS
630 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
631 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
632 * tokeninfo [O] Destination for token information
633 * tokeninfolength [I] Length of tokeninfo
634 * retlen [O] Destination for returned token information length
636 * RETURNS
637 * Success: TRUE. tokeninfo contains retlen bytes of token information
638 * Failure: FALSE.
640 * NOTES
641 * See NtQueryInformationToken.
643 BOOL WINAPI
644 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
645 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
647 TRACE("(%p, %s, %p, %d, %p):\n",
648 token,
649 (tokeninfoclass == TokenUser) ? "TokenUser" :
650 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
651 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
652 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
653 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
654 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
655 (tokeninfoclass == TokenSource) ? "TokenSource" :
656 (tokeninfoclass == TokenType) ? "TokenType" :
657 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
658 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
659 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
660 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
661 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
662 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
663 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
664 "Unknown",
665 tokeninfo, tokeninfolength, retlen);
666 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
667 tokeninfolength, retlen));
670 /******************************************************************************
671 * SetTokenInformation [ADVAPI32.@]
673 * Set information for an access token.
675 * PARAMS
676 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
677 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
678 * tokeninfo [I] Token information to set
679 * tokeninfolength [I] Length of tokeninfo
681 * RETURNS
682 * Success: TRUE. The information for the token is set to tokeninfo.
683 * Failure: FALSE.
685 BOOL WINAPI
686 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
687 LPVOID tokeninfo, DWORD tokeninfolength )
689 TRACE("(%p, %s, %p, %d): stub\n",
690 token,
691 (tokeninfoclass == TokenUser) ? "TokenUser" :
692 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
693 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
694 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
695 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
696 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
697 (tokeninfoclass == TokenSource) ? "TokenSource" :
698 (tokeninfoclass == TokenType) ? "TokenType" :
699 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
700 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
701 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
702 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
703 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
704 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
705 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
706 "Unknown",
707 tokeninfo, tokeninfolength);
709 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
712 /*************************************************************************
713 * SetThreadToken [ADVAPI32.@]
715 * Assigns an 'impersonation token' to a thread so it can assume the
716 * security privileges of another thread or process. Can also remove
717 * a previously assigned token.
719 * PARAMS
720 * thread [O] Handle to thread to set the token for
721 * token [I] Token to set
723 * RETURNS
724 * Success: TRUE. The threads access token is set to token
725 * Failure: FALSE.
727 * NOTES
728 * Only supported on NT or higher. On Win9X this function does nothing.
729 * See SetTokenInformation.
731 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
733 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
734 ThreadImpersonationToken, &token, sizeof token ));
737 /*************************************************************************
738 * CreateRestrictedToken [ADVAPI32.@]
740 * Create a new more restricted token from an existing token.
742 * PARAMS
743 * baseToken [I] Token to base the new restricted token on
744 * flags [I] Options
745 * nDisableSids [I] Length of disableSids array
746 * disableSids [I] Array of SIDs to disable in the new token
747 * nDeletePrivs [I] Length of deletePrivs array
748 * deletePrivs [I] Array of privileges to delete in the new token
749 * nRestrictSids [I] Length of restrictSids array
750 * restrictSids [I] Array of SIDs to restrict in the new token
751 * newToken [O] Address where the new token is stored
753 * RETURNS
754 * Success: TRUE
755 * Failure: FALSE
757 BOOL WINAPI CreateRestrictedToken(
758 HANDLE baseToken,
759 DWORD flags,
760 DWORD nDisableSids,
761 PSID_AND_ATTRIBUTES disableSids,
762 DWORD nDeletePrivs,
763 PLUID_AND_ATTRIBUTES deletePrivs,
764 DWORD nRestrictSids,
765 PSID_AND_ATTRIBUTES restrictSids,
766 PHANDLE newToken)
768 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
769 baseToken, flags, nDisableSids, disableSids,
770 nDeletePrivs, deletePrivs,
771 nRestrictSids, restrictSids,
772 newToken);
773 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
774 return FALSE;
777 /* ##############################
778 ###### SID FUNCTIONS ######
779 ##############################
782 /******************************************************************************
783 * AllocateAndInitializeSid [ADVAPI32.@]
785 * PARAMS
786 * pIdentifierAuthority []
787 * nSubAuthorityCount []
788 * nSubAuthority0 []
789 * nSubAuthority1 []
790 * nSubAuthority2 []
791 * nSubAuthority3 []
792 * nSubAuthority4 []
793 * nSubAuthority5 []
794 * nSubAuthority6 []
795 * nSubAuthority7 []
796 * pSid []
798 BOOL WINAPI
799 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
800 BYTE nSubAuthorityCount,
801 DWORD nSubAuthority0, DWORD nSubAuthority1,
802 DWORD nSubAuthority2, DWORD nSubAuthority3,
803 DWORD nSubAuthority4, DWORD nSubAuthority5,
804 DWORD nSubAuthority6, DWORD nSubAuthority7,
805 PSID *pSid )
807 return set_ntstatus( RtlAllocateAndInitializeSid(
808 pIdentifierAuthority, nSubAuthorityCount,
809 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
810 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
811 pSid ));
814 /******************************************************************************
815 * FreeSid [ADVAPI32.@]
817 * PARAMS
818 * pSid []
820 PVOID WINAPI
821 FreeSid( PSID pSid )
823 RtlFreeSid(pSid);
824 return NULL; /* is documented like this */
827 /******************************************************************************
828 * CopySid [ADVAPI32.@]
830 * PARAMS
831 * nDestinationSidLength []
832 * pDestinationSid []
833 * pSourceSid []
835 BOOL WINAPI
836 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
838 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
841 /******************************************************************************
842 * CreateWellKnownSid [ADVAPI32.@]
844 BOOL WINAPI
845 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
846 PSID DomainSid,
847 PSID pSid,
848 DWORD* cbSid)
850 unsigned int i;
851 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
853 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
854 SetLastError(ERROR_INVALID_PARAMETER);
855 return FALSE;
858 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
859 if (WellKnownSids[i].Type == WellKnownSidType) {
860 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
862 if (*cbSid < length) {
863 SetLastError(ERROR_INSUFFICIENT_BUFFER);
864 return FALSE;
867 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
868 *cbSid = length;
869 return TRUE;
873 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
875 SetLastError(ERROR_INVALID_PARAMETER);
876 return FALSE;
879 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
880 if (WellKnownRids[i].Type == WellKnownSidType) {
881 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
882 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
883 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
885 if (*cbSid < output_sid_length) {
886 SetLastError(ERROR_INSUFFICIENT_BUFFER);
887 return FALSE;
890 CopyMemory(pSid, DomainSid, domain_sid_length);
891 (*GetSidSubAuthorityCount(pSid))++;
892 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
893 *cbSid = output_sid_length;
894 return TRUE;
897 SetLastError(ERROR_INVALID_PARAMETER);
898 return FALSE;
901 /******************************************************************************
902 * IsWellKnownSid [ADVAPI32.@]
904 BOOL WINAPI
905 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
907 unsigned int i;
908 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
910 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
911 if (WellKnownSids[i].Type == WellKnownSidType)
912 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
913 return TRUE;
915 return FALSE;
918 BOOL WINAPI
919 IsTokenRestricted( HANDLE TokenHandle )
921 TOKEN_GROUPS *groups;
922 DWORD size;
923 NTSTATUS status;
924 BOOL restricted;
926 TRACE("(%p)\n", TokenHandle);
928 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
929 if (status != STATUS_BUFFER_TOO_SMALL)
930 return FALSE;
932 groups = HeapAlloc(GetProcessHeap(), 0, size);
933 if (!groups)
935 SetLastError(ERROR_OUTOFMEMORY);
936 return FALSE;
939 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
940 if (status != STATUS_SUCCESS)
942 HeapFree(GetProcessHeap(), 0, groups);
943 return set_ntstatus(status);
946 if (groups->GroupCount)
947 restricted = TRUE;
948 else
949 restricted = FALSE;
951 HeapFree(GetProcessHeap(), 0, groups);
953 return restricted;
956 /******************************************************************************
957 * IsValidSid [ADVAPI32.@]
959 * PARAMS
960 * pSid []
962 BOOL WINAPI
963 IsValidSid( PSID pSid )
965 return RtlValidSid( pSid );
968 /******************************************************************************
969 * EqualSid [ADVAPI32.@]
971 * PARAMS
972 * pSid1 []
973 * pSid2 []
975 BOOL WINAPI
976 EqualSid( PSID pSid1, PSID pSid2 )
978 return RtlEqualSid( pSid1, pSid2 );
981 /******************************************************************************
982 * EqualPrefixSid [ADVAPI32.@]
984 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
986 return RtlEqualPrefixSid(pSid1, pSid2);
989 /******************************************************************************
990 * GetSidLengthRequired [ADVAPI32.@]
992 * PARAMS
993 * nSubAuthorityCount []
995 DWORD WINAPI
996 GetSidLengthRequired( BYTE nSubAuthorityCount )
998 return RtlLengthRequiredSid(nSubAuthorityCount);
1001 /******************************************************************************
1002 * InitializeSid [ADVAPI32.@]
1004 * PARAMS
1005 * pIdentifierAuthority []
1007 BOOL WINAPI
1008 InitializeSid (
1009 PSID pSid,
1010 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1011 BYTE nSubAuthorityCount)
1013 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1016 DWORD WINAPI
1017 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1019 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1021 return 1;
1024 DWORD WINAPI
1025 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1027 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1029 return 1;
1032 /******************************************************************************
1033 * GetSidIdentifierAuthority [ADVAPI32.@]
1035 * PARAMS
1036 * pSid []
1038 PSID_IDENTIFIER_AUTHORITY WINAPI
1039 GetSidIdentifierAuthority( PSID pSid )
1041 return RtlIdentifierAuthoritySid(pSid);
1044 /******************************************************************************
1045 * GetSidSubAuthority [ADVAPI32.@]
1047 * PARAMS
1048 * pSid []
1049 * nSubAuthority []
1051 PDWORD WINAPI
1052 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1054 return RtlSubAuthoritySid(pSid, nSubAuthority);
1057 /******************************************************************************
1058 * GetSidSubAuthorityCount [ADVAPI32.@]
1060 * PARAMS
1061 * pSid []
1063 PUCHAR WINAPI
1064 GetSidSubAuthorityCount (PSID pSid)
1066 return RtlSubAuthorityCountSid(pSid);
1069 /******************************************************************************
1070 * GetLengthSid [ADVAPI32.@]
1072 * PARAMS
1073 * pSid []
1075 DWORD WINAPI
1076 GetLengthSid (PSID pSid)
1078 return RtlLengthSid(pSid);
1081 /* ##############################################
1082 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1083 ##############################################
1086 /******************************************************************************
1087 * BuildSecurityDescriptorA [ADVAPI32.@]
1089 * Builds a SD from
1091 * PARAMS
1092 * pOwner [I]
1093 * pGroup [I]
1094 * cCountOfAccessEntries [I]
1095 * pListOfAccessEntries [I]
1096 * cCountOfAuditEntries [I]
1097 * pListofAuditEntries [I]
1098 * pOldSD [I]
1099 * lpdwBufferLength [I/O]
1100 * pNewSD [O]
1102 * RETURNS
1103 * Success: ERROR_SUCCESS
1104 * Failure: nonzero error code from Winerror.h
1106 DWORD WINAPI BuildSecurityDescriptorA(
1107 IN PTRUSTEEA pOwner,
1108 IN PTRUSTEEA pGroup,
1109 IN ULONG cCountOfAccessEntries,
1110 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1111 IN ULONG cCountOfAuditEntries,
1112 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1113 IN PSECURITY_DESCRIPTOR pOldSD,
1114 IN OUT PULONG lpdwBufferLength,
1115 OUT PSECURITY_DESCRIPTOR* pNewSD)
1117 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1118 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1119 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1121 return ERROR_CALL_NOT_IMPLEMENTED;
1124 /******************************************************************************
1125 * BuildSecurityDescriptorW [ADVAPI32.@]
1127 * See BuildSecurityDescriptorA.
1129 DWORD WINAPI BuildSecurityDescriptorW(
1130 IN PTRUSTEEW pOwner,
1131 IN PTRUSTEEW pGroup,
1132 IN ULONG cCountOfAccessEntries,
1133 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1134 IN ULONG cCountOfAuditEntries,
1135 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1136 IN PSECURITY_DESCRIPTOR pOldSD,
1137 IN OUT PULONG lpdwBufferLength,
1138 OUT PSECURITY_DESCRIPTOR* pNewSD)
1140 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1141 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1142 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1144 return ERROR_CALL_NOT_IMPLEMENTED;
1147 /******************************************************************************
1148 * InitializeSecurityDescriptor [ADVAPI32.@]
1150 * PARAMS
1151 * pDescr []
1152 * revision []
1154 BOOL WINAPI
1155 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1157 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1161 /******************************************************************************
1162 * MakeAbsoluteSD [ADVAPI32.@]
1164 BOOL WINAPI MakeAbsoluteSD (
1165 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1166 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1167 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1168 OUT PACL pDacl,
1169 OUT LPDWORD lpdwDaclSize,
1170 OUT PACL pSacl,
1171 OUT LPDWORD lpdwSaclSize,
1172 OUT PSID pOwner,
1173 OUT LPDWORD lpdwOwnerSize,
1174 OUT PSID pPrimaryGroup,
1175 OUT LPDWORD lpdwPrimaryGroupSize)
1177 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1178 pAbsoluteSecurityDescriptor,
1179 lpdwAbsoluteSecurityDescriptorSize,
1180 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1181 pOwner, lpdwOwnerSize,
1182 pPrimaryGroup, lpdwPrimaryGroupSize));
1185 /******************************************************************************
1186 * GetKernelObjectSecurity [ADVAPI32.@]
1188 BOOL WINAPI GetKernelObjectSecurity(
1189 HANDLE Handle,
1190 SECURITY_INFORMATION RequestedInformation,
1191 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1192 DWORD nLength,
1193 LPDWORD lpnLengthNeeded )
1195 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1196 pSecurityDescriptor, nLength, lpnLengthNeeded);
1198 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1199 nLength, lpnLengthNeeded ));
1202 /******************************************************************************
1203 * GetPrivateObjectSecurity [ADVAPI32.@]
1205 BOOL WINAPI GetPrivateObjectSecurity(
1206 PSECURITY_DESCRIPTOR ObjectDescriptor,
1207 SECURITY_INFORMATION SecurityInformation,
1208 PSECURITY_DESCRIPTOR ResultantDescriptor,
1209 DWORD DescriptorLength,
1210 PDWORD ReturnLength )
1212 SECURITY_DESCRIPTOR desc;
1213 BOOL defaulted, present;
1214 PACL pacl;
1215 PSID psid;
1217 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1218 ResultantDescriptor, DescriptorLength, ReturnLength);
1220 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1221 return FALSE;
1223 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1225 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1226 return FALSE;
1227 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1230 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1232 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1233 return FALSE;
1234 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1237 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1239 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1240 return FALSE;
1241 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1244 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1246 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1247 return FALSE;
1248 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1251 *ReturnLength = DescriptorLength;
1252 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1255 /******************************************************************************
1256 * GetSecurityDescriptorLength [ADVAPI32.@]
1258 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1260 return RtlLengthSecurityDescriptor(pDescr);
1263 /******************************************************************************
1264 * GetSecurityDescriptorOwner [ADVAPI32.@]
1266 * PARAMS
1267 * pOwner []
1268 * lpbOwnerDefaulted []
1270 BOOL WINAPI
1271 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1272 LPBOOL lpbOwnerDefaulted )
1274 BOOLEAN defaulted;
1275 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1276 *lpbOwnerDefaulted = defaulted;
1277 return ret;
1280 /******************************************************************************
1281 * SetSecurityDescriptorOwner [ADVAPI32.@]
1283 * PARAMS
1285 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1286 PSID pOwner, BOOL bOwnerDefaulted)
1288 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1290 /******************************************************************************
1291 * GetSecurityDescriptorGroup [ADVAPI32.@]
1293 BOOL WINAPI GetSecurityDescriptorGroup(
1294 PSECURITY_DESCRIPTOR SecurityDescriptor,
1295 PSID *Group,
1296 LPBOOL GroupDefaulted)
1298 BOOLEAN defaulted;
1299 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1300 *GroupDefaulted = defaulted;
1301 return ret;
1303 /******************************************************************************
1304 * SetSecurityDescriptorGroup [ADVAPI32.@]
1306 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1307 PSID Group, BOOL GroupDefaulted)
1309 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1312 /******************************************************************************
1313 * IsValidSecurityDescriptor [ADVAPI32.@]
1315 * PARAMS
1316 * lpsecdesc []
1318 BOOL WINAPI
1319 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1321 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1324 /******************************************************************************
1325 * GetSecurityDescriptorDacl [ADVAPI32.@]
1327 BOOL WINAPI GetSecurityDescriptorDacl(
1328 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1329 OUT LPBOOL lpbDaclPresent,
1330 OUT PACL *pDacl,
1331 OUT LPBOOL lpbDaclDefaulted)
1333 BOOLEAN present, defaulted;
1334 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1335 *lpbDaclPresent = present;
1336 *lpbDaclDefaulted = defaulted;
1337 return ret;
1340 /******************************************************************************
1341 * SetSecurityDescriptorDacl [ADVAPI32.@]
1343 BOOL WINAPI
1344 SetSecurityDescriptorDacl (
1345 PSECURITY_DESCRIPTOR lpsd,
1346 BOOL daclpresent,
1347 PACL dacl,
1348 BOOL dacldefaulted )
1350 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1352 /******************************************************************************
1353 * GetSecurityDescriptorSacl [ADVAPI32.@]
1355 BOOL WINAPI GetSecurityDescriptorSacl(
1356 IN PSECURITY_DESCRIPTOR lpsd,
1357 OUT LPBOOL lpbSaclPresent,
1358 OUT PACL *pSacl,
1359 OUT LPBOOL lpbSaclDefaulted)
1361 BOOLEAN present, defaulted;
1362 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1363 *lpbSaclPresent = present;
1364 *lpbSaclDefaulted = defaulted;
1365 return ret;
1368 /**************************************************************************
1369 * SetSecurityDescriptorSacl [ADVAPI32.@]
1371 BOOL WINAPI SetSecurityDescriptorSacl (
1372 PSECURITY_DESCRIPTOR lpsd,
1373 BOOL saclpresent,
1374 PACL lpsacl,
1375 BOOL sacldefaulted)
1377 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1379 /******************************************************************************
1380 * MakeSelfRelativeSD [ADVAPI32.@]
1382 * PARAMS
1383 * lpabssecdesc []
1384 * lpselfsecdesc []
1385 * lpbuflen []
1387 BOOL WINAPI
1388 MakeSelfRelativeSD(
1389 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1390 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1391 IN OUT LPDWORD lpdwBufferLength)
1393 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1394 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1397 /******************************************************************************
1398 * GetSecurityDescriptorControl [ADVAPI32.@]
1401 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1402 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1404 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1407 /******************************************************************************
1408 * SetSecurityDescriptorControl [ADVAPI32.@]
1410 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1412 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1414 return set_ntstatus( RtlSetControlSecurityDescriptor(
1415 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1418 /* ##############################
1419 ###### ACL FUNCTIONS ######
1420 ##############################
1423 /*************************************************************************
1424 * InitializeAcl [ADVAPI32.@]
1426 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1428 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1431 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1433 IO_STATUS_BLOCK io_block;
1435 TRACE("(%p)\n", hNamedPipe);
1437 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1438 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1441 /******************************************************************************
1442 * AddAccessAllowedAce [ADVAPI32.@]
1444 BOOL WINAPI AddAccessAllowedAce(
1445 IN OUT PACL pAcl,
1446 IN DWORD dwAceRevision,
1447 IN DWORD AccessMask,
1448 IN PSID pSid)
1450 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1453 /******************************************************************************
1454 * AddAccessAllowedAceEx [ADVAPI32.@]
1456 BOOL WINAPI AddAccessAllowedAceEx(
1457 IN OUT PACL pAcl,
1458 IN DWORD dwAceRevision,
1459 IN DWORD AceFlags,
1460 IN DWORD AccessMask,
1461 IN PSID pSid)
1463 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1466 /******************************************************************************
1467 * AddAccessDeniedAce [ADVAPI32.@]
1469 BOOL WINAPI AddAccessDeniedAce(
1470 IN OUT PACL pAcl,
1471 IN DWORD dwAceRevision,
1472 IN DWORD AccessMask,
1473 IN PSID pSid)
1475 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1478 /******************************************************************************
1479 * AddAccessDeniedAceEx [ADVAPI32.@]
1481 BOOL WINAPI AddAccessDeniedAceEx(
1482 IN OUT PACL pAcl,
1483 IN DWORD dwAceRevision,
1484 IN DWORD AceFlags,
1485 IN DWORD AccessMask,
1486 IN PSID pSid)
1488 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1491 /******************************************************************************
1492 * AddAce [ADVAPI32.@]
1494 BOOL WINAPI AddAce(
1495 IN OUT PACL pAcl,
1496 IN DWORD dwAceRevision,
1497 IN DWORD dwStartingAceIndex,
1498 LPVOID pAceList,
1499 DWORD nAceListLength)
1501 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1504 /******************************************************************************
1505 * DeleteAce [ADVAPI32.@]
1507 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1509 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1512 /******************************************************************************
1513 * FindFirstFreeAce [ADVAPI32.@]
1515 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1517 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1520 /******************************************************************************
1521 * GetAce [ADVAPI32.@]
1523 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1525 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1528 /******************************************************************************
1529 * GetAclInformation [ADVAPI32.@]
1531 BOOL WINAPI GetAclInformation(
1532 PACL pAcl,
1533 LPVOID pAclInformation,
1534 DWORD nAclInformationLength,
1535 ACL_INFORMATION_CLASS dwAclInformationClass)
1537 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1538 nAclInformationLength, dwAclInformationClass));
1541 /******************************************************************************
1542 * IsValidAcl [ADVAPI32.@]
1544 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1546 return RtlValidAcl(pAcl);
1549 /* ##############################
1550 ###### MISC FUNCTIONS ######
1551 ##############################
1554 /******************************************************************************
1555 * AllocateLocallyUniqueId [ADVAPI32.@]
1557 * PARAMS
1558 * lpLuid []
1560 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1562 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1565 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1566 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1567 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1568 { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1570 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1571 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1572 { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1574 { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1575 static const WCHAR SE_TCB_NAME_W[] =
1576 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_SECURITY_NAME_W[] =
1578 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1580 { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1581 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1582 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1584 { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1585 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1586 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1587 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1588 { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1590 { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1591 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1592 { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1594 { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1595 static const WCHAR SE_BACKUP_NAME_W[] =
1596 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1597 static const WCHAR SE_RESTORE_NAME_W[] =
1598 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1600 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_DEBUG_NAME_W[] =
1602 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_AUDIT_NAME_W[] =
1604 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1606 { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1608 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1610 { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_UNDOCK_NAME_W[] =
1612 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1613 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1614 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1616 { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1617 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1618 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1620 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1622 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1626 NULL,
1627 NULL,
1628 SE_CREATE_TOKEN_NAME_W,
1629 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1630 SE_LOCK_MEMORY_NAME_W,
1631 SE_INCREASE_QUOTA_NAME_W,
1632 SE_MACHINE_ACCOUNT_NAME_W,
1633 SE_TCB_NAME_W,
1634 SE_SECURITY_NAME_W,
1635 SE_TAKE_OWNERSHIP_NAME_W,
1636 SE_LOAD_DRIVER_NAME_W,
1637 SE_SYSTEM_PROFILE_NAME_W,
1638 SE_SYSTEMTIME_NAME_W,
1639 SE_PROF_SINGLE_PROCESS_NAME_W,
1640 SE_INC_BASE_PRIORITY_NAME_W,
1641 SE_CREATE_PAGEFILE_NAME_W,
1642 SE_CREATE_PERMANENT_NAME_W,
1643 SE_BACKUP_NAME_W,
1644 SE_RESTORE_NAME_W,
1645 SE_SHUTDOWN_NAME_W,
1646 SE_DEBUG_NAME_W,
1647 SE_AUDIT_NAME_W,
1648 SE_SYSTEM_ENVIRONMENT_NAME_W,
1649 SE_CHANGE_NOTIFY_NAME_W,
1650 SE_REMOTE_SHUTDOWN_NAME_W,
1651 SE_UNDOCK_NAME_W,
1652 SE_SYNC_AGENT_NAME_W,
1653 SE_ENABLE_DELEGATION_NAME_W,
1654 SE_MANAGE_VOLUME_NAME_W,
1655 SE_IMPERSONATE_NAME_W,
1656 SE_CREATE_GLOBAL_NAME_W,
1659 /******************************************************************************
1660 * LookupPrivilegeValueW [ADVAPI32.@]
1662 * See LookupPrivilegeValueA.
1664 BOOL WINAPI
1665 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1667 UINT i;
1669 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1671 if (!ADVAPI_IsLocalComputer(lpSystemName))
1673 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1674 return FALSE;
1676 if (!lpName)
1678 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1679 return FALSE;
1681 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1683 if( !WellKnownPrivNames[i] )
1684 continue;
1685 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1686 continue;
1687 lpLuid->LowPart = i;
1688 lpLuid->HighPart = 0;
1689 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1690 lpLuid->HighPart, lpLuid->LowPart );
1691 return TRUE;
1693 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1694 return FALSE;
1697 /******************************************************************************
1698 * LookupPrivilegeValueA [ADVAPI32.@]
1700 * Retrieves LUID used on a system to represent the privilege name.
1702 * PARAMS
1703 * lpSystemName [I] Name of the system
1704 * lpName [I] Name of the privilege
1705 * lpLuid [O] Destination for the resulting LUID
1707 * RETURNS
1708 * Success: TRUE. lpLuid contains the requested LUID.
1709 * Failure: FALSE.
1711 BOOL WINAPI
1712 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1714 UNICODE_STRING lpSystemNameW;
1715 UNICODE_STRING lpNameW;
1716 BOOL ret;
1718 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1719 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1720 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1721 RtlFreeUnicodeString(&lpNameW);
1722 RtlFreeUnicodeString(&lpSystemNameW);
1723 return ret;
1726 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1727 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1729 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1730 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1732 return FALSE;
1735 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1736 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1738 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1739 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1741 return FALSE;
1744 /******************************************************************************
1745 * LookupPrivilegeNameA [ADVAPI32.@]
1747 * See LookupPrivilegeNameW.
1749 BOOL WINAPI
1750 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1751 LPDWORD cchName)
1753 UNICODE_STRING lpSystemNameW;
1754 BOOL ret;
1755 DWORD wLen = 0;
1757 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1759 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1760 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1761 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1763 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1765 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1766 &wLen);
1767 if (ret)
1769 /* Windows crashes if cchName is NULL, so will I */
1770 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1771 *cchName, NULL, NULL);
1773 if (len == 0)
1775 /* WideCharToMultiByte failed */
1776 ret = FALSE;
1778 else if (len > *cchName)
1780 *cchName = len;
1781 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1782 ret = FALSE;
1784 else
1786 /* WideCharToMultiByte succeeded, output length needs to be
1787 * length not including NULL terminator
1789 *cchName = len - 1;
1792 HeapFree(GetProcessHeap(), 0, lpNameW);
1794 RtlFreeUnicodeString(&lpSystemNameW);
1795 return ret;
1798 /******************************************************************************
1799 * LookupPrivilegeNameW [ADVAPI32.@]
1801 * Retrieves the privilege name referred to by the LUID lpLuid.
1803 * PARAMS
1804 * lpSystemName [I] Name of the system
1805 * lpLuid [I] Privilege value
1806 * lpName [O] Name of the privilege
1807 * cchName [I/O] Number of characters in lpName.
1809 * RETURNS
1810 * Success: TRUE. lpName contains the name of the privilege whose value is
1811 * *lpLuid.
1812 * Failure: FALSE.
1814 * REMARKS
1815 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1816 * using this function.
1817 * If the length of lpName is too small, on return *cchName will contain the
1818 * number of WCHARs needed to contain the privilege, including the NULL
1819 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1820 * On success, *cchName will contain the number of characters stored in
1821 * lpName, NOT including the NULL terminator.
1823 BOOL WINAPI
1824 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1825 LPDWORD cchName)
1827 size_t privNameLen;
1829 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1831 if (!ADVAPI_IsLocalComputer(lpSystemName))
1833 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1834 return FALSE;
1836 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1837 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1839 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1840 return FALSE;
1842 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1843 /* Windows crashes if cchName is NULL, so will I */
1844 if (*cchName <= privNameLen)
1846 *cchName = privNameLen + 1;
1847 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1848 return FALSE;
1850 else
1852 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1853 *cchName = privNameLen;
1854 return TRUE;
1858 /******************************************************************************
1859 * GetFileSecurityA [ADVAPI32.@]
1861 * Obtains Specified information about the security of a file or directory.
1863 * PARAMS
1864 * lpFileName [I] Name of the file to get info for
1865 * RequestedInformation [I] SE_ flags from "winnt.h"
1866 * pSecurityDescriptor [O] Destination for security information
1867 * nLength [I] Length of pSecurityDescriptor
1868 * lpnLengthNeeded [O] Destination for length of returned security information
1870 * RETURNS
1871 * Success: TRUE. pSecurityDescriptor contains the requested information.
1872 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1874 * NOTES
1875 * The information returned is constrained by the callers access rights and
1876 * privileges.
1878 BOOL WINAPI
1879 GetFileSecurityA( LPCSTR lpFileName,
1880 SECURITY_INFORMATION RequestedInformation,
1881 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1882 DWORD nLength, LPDWORD lpnLengthNeeded )
1884 DWORD len;
1885 BOOL r;
1886 LPWSTR name = NULL;
1888 if( lpFileName )
1890 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1891 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1892 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1895 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1896 nLength, lpnLengthNeeded );
1897 HeapFree( GetProcessHeap(), 0, name );
1899 return r;
1902 /******************************************************************************
1903 * GetFileSecurityW [ADVAPI32.@]
1905 * See GetFileSecurityA.
1907 BOOL WINAPI
1908 GetFileSecurityW( LPCWSTR lpFileName,
1909 SECURITY_INFORMATION RequestedInformation,
1910 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1911 DWORD nLength, LPDWORD lpnLengthNeeded )
1913 HANDLE hfile;
1914 NTSTATUS status;
1915 DWORD access = 0;
1917 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1918 DACL_SECURITY_INFORMATION))
1919 access |= READ_CONTROL;
1920 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1921 access |= ACCESS_SYSTEM_SECURITY;
1923 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1924 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1925 if ( hfile == INVALID_HANDLE_VALUE )
1926 return FALSE;
1928 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1929 nLength, lpnLengthNeeded );
1930 CloseHandle( hfile );
1931 return set_ntstatus( status );
1935 /******************************************************************************
1936 * LookupAccountSidA [ADVAPI32.@]
1938 BOOL WINAPI
1939 LookupAccountSidA(
1940 IN LPCSTR system,
1941 IN PSID sid,
1942 OUT LPSTR account,
1943 IN OUT LPDWORD accountSize,
1944 OUT LPSTR domain,
1945 IN OUT LPDWORD domainSize,
1946 OUT PSID_NAME_USE name_use )
1948 DWORD len;
1949 BOOL r;
1950 LPWSTR systemW = NULL;
1951 LPWSTR accountW = NULL;
1952 LPWSTR domainW = NULL;
1953 DWORD accountSizeW = *accountSize;
1954 DWORD domainSizeW = *domainSize;
1956 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1957 debugstr_a(system),debugstr_sid(sid),
1958 account,accountSize,accountSize?*accountSize:0,
1959 domain,domainSize,domainSize?*domainSize:0,
1960 name_use);
1962 if (system) {
1963 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1964 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1965 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1967 if (account)
1968 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1969 if (domain)
1970 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1972 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1974 if (r) {
1975 if (accountW && *accountSize) {
1976 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1977 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1978 *accountSize = len;
1979 } else
1980 *accountSize = accountSizeW + 1;
1982 if (domainW && *domainSize) {
1983 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1984 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1985 *domainSize = len;
1986 } else
1987 *domainSize = domainSizeW + 1;
1990 HeapFree( GetProcessHeap(), 0, systemW );
1991 HeapFree( GetProcessHeap(), 0, accountW );
1992 HeapFree( GetProcessHeap(), 0, domainW );
1994 return r;
1997 /******************************************************************************
1998 * LookupAccountSidW [ADVAPI32.@]
2000 * PARAMS
2001 * system []
2002 * sid []
2003 * account []
2004 * accountSize []
2005 * domain []
2006 * domainSize []
2007 * name_use []
2010 BOOL WINAPI
2011 LookupAccountSidW(
2012 IN LPCWSTR system,
2013 IN PSID sid,
2014 OUT LPWSTR account,
2015 IN OUT LPDWORD accountSize,
2016 OUT LPWSTR domain,
2017 IN OUT LPDWORD domainSize,
2018 OUT PSID_NAME_USE name_use )
2020 unsigned int i, j;
2021 const WCHAR * ac = NULL;
2022 const WCHAR * dm = NULL;
2023 SID_NAME_USE use = 0;
2024 LPWSTR computer_name = NULL;
2026 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2027 debugstr_w(system),debugstr_sid(sid),
2028 account,accountSize,accountSize?*accountSize:0,
2029 domain,domainSize,domainSize?*domainSize:0,
2030 name_use);
2032 if (!ADVAPI_IsLocalComputer(system)) {
2033 FIXME("Only local computer supported!\n");
2034 SetLastError(ERROR_NONE_MAPPED);
2035 return FALSE;
2038 /* check the well known SIDs first */
2039 for (i = 0; i <= 60; i++) {
2040 if (IsWellKnownSid(sid, i)) {
2041 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2042 if (ACCOUNT_SIDS[j].type == i) {
2043 ac = ACCOUNT_SIDS[j].account;
2044 dm = ACCOUNT_SIDS[j].domain;
2045 use = ACCOUNT_SIDS[j].name_use;
2048 break;
2052 if (dm == NULL) {
2053 MAX_SID local;
2055 /* check for the local computer next */
2056 if (ADVAPI_GetComputerSid(&local)) {
2057 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2058 BOOL result;
2060 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2061 result = GetComputerNameW(computer_name, &size);
2063 if (result) {
2064 if (EqualSid(sid, &local)) {
2065 dm = computer_name;
2066 ac = Blank;
2067 use = 3;
2068 } else {
2069 local.SubAuthorityCount++;
2071 if (EqualPrefixSid(sid, &local)) {
2072 dm = computer_name;
2073 use = 1;
2074 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2075 case DOMAIN_USER_RID_ADMIN:
2076 ac = Administrator;
2077 break;
2078 case DOMAIN_USER_RID_GUEST:
2079 ac = Guest;
2080 break;
2081 case DOMAIN_GROUP_RID_ADMINS:
2082 ac = Domain_Admins;
2083 break;
2084 case DOMAIN_GROUP_RID_USERS:
2085 ac = Domain_Users;
2086 break;
2087 case DOMAIN_GROUP_RID_GUESTS:
2088 ac = Domain_Guests;
2089 break;
2090 case DOMAIN_GROUP_RID_COMPUTERS:
2091 ac = Domain_Computers;
2092 break;
2093 case DOMAIN_GROUP_RID_CONTROLLERS:
2094 ac = Domain_Controllers;
2095 break;
2096 case DOMAIN_GROUP_RID_CERT_ADMINS:
2097 ac = Cert_Publishers;
2098 break;
2099 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2100 ac = Schema_Admins;
2101 break;
2102 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2103 ac = Enterprise_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2106 ac = Group_Policy_Creator_Owners;
2107 break;
2108 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2109 ac = RAS_and_IAS_Servers;
2110 break;
2111 default:
2112 dm = NULL;
2113 break;
2121 if (dm) {
2122 BOOL status = TRUE;
2123 if (*accountSize > lstrlenW(ac)) {
2124 if (account)
2125 lstrcpyW(account, ac);
2127 if (*domainSize > lstrlenW(dm)) {
2128 if (domain)
2129 lstrcpyW(domain, dm);
2131 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2132 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2133 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2134 status = FALSE;
2136 if (*domainSize)
2137 *domainSize = strlenW(dm);
2138 else
2139 *domainSize = strlenW(dm) + 1;
2140 if (*accountSize)
2141 *accountSize = strlenW(ac);
2142 else
2143 *accountSize = strlenW(ac) + 1;
2144 *name_use = use;
2145 HeapFree(GetProcessHeap(), 0, computer_name);
2146 return status;
2149 HeapFree(GetProcessHeap(), 0, computer_name);
2150 SetLastError(ERROR_NONE_MAPPED);
2151 return FALSE;
2154 /******************************************************************************
2155 * SetFileSecurityA [ADVAPI32.@]
2157 * See SetFileSecurityW.
2159 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2160 SECURITY_INFORMATION RequestedInformation,
2161 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2163 DWORD len;
2164 BOOL r;
2165 LPWSTR name = NULL;
2167 if( lpFileName )
2169 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2170 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2171 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2174 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2175 HeapFree( GetProcessHeap(), 0, name );
2177 return r;
2180 /******************************************************************************
2181 * SetFileSecurityW [ADVAPI32.@]
2183 * Sets the security of a file or directory.
2185 * PARAMS
2186 * lpFileName []
2187 * RequestedInformation []
2188 * pSecurityDescriptor []
2190 * RETURNS
2191 * Success: TRUE.
2192 * Failure: FALSE.
2194 BOOL WINAPI
2195 SetFileSecurityW( LPCWSTR lpFileName,
2196 SECURITY_INFORMATION RequestedInformation,
2197 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2199 HANDLE file;
2200 DWORD access = 0;
2201 NTSTATUS status;
2203 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2204 pSecurityDescriptor );
2206 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2207 RequestedInformation & GROUP_SECURITY_INFORMATION)
2208 access |= WRITE_OWNER;
2209 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2210 access |= ACCESS_SYSTEM_SECURITY;
2211 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2212 access |= WRITE_DAC;
2214 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2215 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2216 if (file == INVALID_HANDLE_VALUE)
2217 return FALSE;
2219 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2220 CloseHandle( file );
2221 return set_ntstatus( status );
2224 /******************************************************************************
2225 * QueryWindows31FilesMigration [ADVAPI32.@]
2227 * PARAMS
2228 * x1 []
2230 BOOL WINAPI
2231 QueryWindows31FilesMigration( DWORD x1 )
2233 FIXME("(%d):stub\n",x1);
2234 return TRUE;
2237 /******************************************************************************
2238 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2240 * PARAMS
2241 * x1 []
2242 * x2 []
2243 * x3 []
2244 * x4 []
2246 BOOL WINAPI
2247 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2248 DWORD x4 )
2250 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2251 return TRUE;
2254 /******************************************************************************
2255 * NotifyBootConfigStatus [ADVAPI32.@]
2257 * PARAMS
2258 * x1 []
2260 BOOL WINAPI
2261 NotifyBootConfigStatus( BOOL x1 )
2263 FIXME("(0x%08d):stub\n",x1);
2264 return 1;
2267 /******************************************************************************
2268 * RevertToSelf [ADVAPI32.@]
2270 * Ends the impersonation of a user.
2272 * PARAMS
2273 * void []
2275 * RETURNS
2276 * Success: TRUE.
2277 * Failure: FALSE.
2279 BOOL WINAPI
2280 RevertToSelf( void )
2282 HANDLE Token = NULL;
2283 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2284 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2287 /******************************************************************************
2288 * ImpersonateSelf [ADVAPI32.@]
2290 * Makes an impersonation token that represents the process user and assigns
2291 * to the current thread.
2293 * PARAMS
2294 * ImpersonationLevel [I] Level at which to impersonate.
2296 * RETURNS
2297 * Success: TRUE.
2298 * Failure: FALSE.
2300 BOOL WINAPI
2301 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2303 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2306 /******************************************************************************
2307 * ImpersonateLoggedOnUser [ADVAPI32.@]
2309 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2311 DWORD size;
2312 NTSTATUS Status;
2313 HANDLE ImpersonationToken;
2314 TOKEN_TYPE Type;
2316 FIXME( "(%p)\n", hToken );
2318 if (!GetTokenInformation( hToken, TokenType, &Type,
2319 sizeof(TOKEN_TYPE), &size ))
2320 return FALSE;
2322 if (Type == TokenPrimary)
2324 OBJECT_ATTRIBUTES ObjectAttributes;
2326 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2328 Status = NtDuplicateToken( hToken,
2329 TOKEN_IMPERSONATE | TOKEN_QUERY,
2330 &ObjectAttributes,
2331 SecurityImpersonation,
2332 TokenImpersonation,
2333 &ImpersonationToken );
2334 if (Status != STATUS_SUCCESS)
2336 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2337 SetLastError( RtlNtStatusToDosError( Status ) );
2338 return FALSE;
2341 else
2342 ImpersonationToken = hToken;
2344 Status = NtSetInformationThread( GetCurrentThread(),
2345 ThreadImpersonationToken,
2346 &ImpersonationToken,
2347 sizeof(ImpersonationToken) );
2349 if (Type == TokenPrimary)
2350 NtClose( ImpersonationToken );
2352 if (Status != STATUS_SUCCESS)
2354 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2355 SetLastError( RtlNtStatusToDosError( Status ) );
2356 return FALSE;
2359 return TRUE;
2362 /******************************************************************************
2363 * AccessCheck [ADVAPI32.@]
2365 BOOL WINAPI
2366 AccessCheck(
2367 PSECURITY_DESCRIPTOR SecurityDescriptor,
2368 HANDLE ClientToken,
2369 DWORD DesiredAccess,
2370 PGENERIC_MAPPING GenericMapping,
2371 PPRIVILEGE_SET PrivilegeSet,
2372 LPDWORD PrivilegeSetLength,
2373 LPDWORD GrantedAccess,
2374 LPBOOL AccessStatus)
2376 NTSTATUS access_status;
2377 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2378 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2379 GrantedAccess, &access_status) );
2380 if (ret) *AccessStatus = set_ntstatus( access_status );
2381 return ret;
2385 /******************************************************************************
2386 * AccessCheckByType [ADVAPI32.@]
2388 BOOL WINAPI AccessCheckByType(
2389 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2390 PSID PrincipalSelfSid,
2391 HANDLE ClientToken,
2392 DWORD DesiredAccess,
2393 POBJECT_TYPE_LIST ObjectTypeList,
2394 DWORD ObjectTypeListLength,
2395 PGENERIC_MAPPING GenericMapping,
2396 PPRIVILEGE_SET PrivilegeSet,
2397 LPDWORD PrivilegeSetLength,
2398 LPDWORD GrantedAccess,
2399 LPBOOL AccessStatus)
2401 FIXME("stub\n");
2403 *AccessStatus = TRUE;
2405 return !*AccessStatus;
2408 /******************************************************************************
2409 * MapGenericMask [ADVAPI32.@]
2411 * Maps generic access rights into specific access rights according to the
2412 * supplied mapping.
2414 * PARAMS
2415 * AccessMask [I/O] Access rights.
2416 * GenericMapping [I] The mapping between generic and specific rights.
2418 * RETURNS
2419 * Nothing.
2421 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2423 RtlMapGenericMask( AccessMask, GenericMapping );
2426 /*************************************************************************
2427 * SetKernelObjectSecurity [ADVAPI32.@]
2429 BOOL WINAPI SetKernelObjectSecurity (
2430 IN HANDLE Handle,
2431 IN SECURITY_INFORMATION SecurityInformation,
2432 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2434 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2438 /******************************************************************************
2439 * AddAuditAccessAce [ADVAPI32.@]
2441 BOOL WINAPI AddAuditAccessAce(
2442 IN OUT PACL pAcl,
2443 IN DWORD dwAceRevision,
2444 IN DWORD dwAccessMask,
2445 IN PSID pSid,
2446 IN BOOL bAuditSuccess,
2447 IN BOOL bAuditFailure)
2449 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2450 bAuditSuccess, bAuditFailure) );
2453 /******************************************************************************
2454 * AddAuditAccessAce [ADVAPI32.@]
2456 BOOL WINAPI AddAuditAccessAceEx(
2457 IN OUT PACL pAcl,
2458 IN DWORD dwAceRevision,
2459 IN DWORD dwAceFlags,
2460 IN DWORD dwAccessMask,
2461 IN PSID pSid,
2462 IN BOOL bAuditSuccess,
2463 IN BOOL bAuditFailure)
2465 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2466 bAuditSuccess, bAuditFailure) );
2469 /******************************************************************************
2470 * LookupAccountNameA [ADVAPI32.@]
2472 BOOL WINAPI
2473 LookupAccountNameA(
2474 IN LPCSTR system,
2475 IN LPCSTR account,
2476 OUT PSID sid,
2477 OUT LPDWORD cbSid,
2478 LPSTR ReferencedDomainName,
2479 IN OUT LPDWORD cbReferencedDomainName,
2480 OUT PSID_NAME_USE name_use )
2482 BOOL ret;
2483 UNICODE_STRING lpSystemW;
2484 UNICODE_STRING lpAccountW;
2485 LPWSTR lpReferencedDomainNameW = NULL;
2487 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2488 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2490 if (ReferencedDomainName)
2491 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2493 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2494 cbReferencedDomainName, name_use);
2496 if (ret && lpReferencedDomainNameW)
2498 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2499 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2502 RtlFreeUnicodeString(&lpSystemW);
2503 RtlFreeUnicodeString(&lpAccountW);
2504 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2506 return ret;
2509 /******************************************************************************
2510 * LookupAccountNameW [ADVAPI32.@]
2512 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2513 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2514 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2516 /* Default implementation: Always return a default SID */
2517 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2518 BOOL ret;
2519 PSID pSid;
2520 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2521 unsigned int i;
2523 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2524 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2526 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2528 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2530 if (*cchReferencedDomainName)
2531 *ReferencedDomainName = '\0';
2532 *cchReferencedDomainName = 0;
2533 *peUse = SidTypeWellKnownGroup;
2534 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
2538 ret = AllocateAndInitializeSid(&identifierAuthority,
2540 SECURITY_BUILTIN_DOMAIN_RID,
2541 DOMAIN_ALIAS_RID_ADMINS,
2542 0, 0, 0, 0, 0, 0,
2543 &pSid);
2545 if (!ret)
2546 return FALSE;
2548 if (!RtlValidSid(pSid))
2550 FreeSid(pSid);
2551 return FALSE;
2554 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2555 CopySid(*cbSid, Sid, pSid);
2556 if (*cbSid < GetLengthSid(pSid))
2558 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2559 ret = FALSE;
2561 *cbSid = GetLengthSid(pSid);
2563 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2564 strcpyW(ReferencedDomainName, dm);
2566 if (*cchReferencedDomainName <= strlenW(dm))
2568 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2569 ret = FALSE;
2572 *cchReferencedDomainName = strlenW(dm)+1;
2574 FreeSid(pSid);
2576 return ret;
2579 /******************************************************************************
2580 * PrivilegeCheck [ADVAPI32.@]
2582 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2584 BOOL ret;
2585 BOOLEAN Result;
2587 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2589 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2590 if (ret)
2591 *pfResult = Result;
2592 return ret;
2595 /******************************************************************************
2596 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2598 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2599 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2600 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2601 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2603 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2604 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2605 SecurityDescriptor, DesiredAccess, GenericMapping,
2606 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2607 return TRUE;
2610 /******************************************************************************
2611 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2613 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2614 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2615 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2616 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2618 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2619 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2620 SecurityDescriptor, DesiredAccess, GenericMapping,
2621 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2622 return TRUE;
2625 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2627 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2629 return TRUE;
2632 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2634 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2636 return TRUE;
2639 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2641 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2643 return TRUE;
2646 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2647 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2648 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2649 LPBOOL GenerateOnClose)
2651 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2652 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2653 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2654 GenerateOnClose);
2656 return TRUE;
2659 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2660 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2661 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2662 LPBOOL GenerateOnClose)
2664 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2665 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2666 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2667 GenerateOnClose);
2669 return TRUE;
2672 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2673 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2675 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2676 DesiredAccess, Privileges, AccessGranted);
2678 return TRUE;
2681 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2682 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2684 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2685 DesiredAccess, Privileges, AccessGranted);
2687 return TRUE;
2690 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2691 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2693 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2694 ClientToken, Privileges, AccessGranted);
2696 return TRUE;
2699 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2700 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2702 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2703 ClientToken, Privileges, AccessGranted);
2705 return TRUE;
2708 /******************************************************************************
2709 * GetSecurityInfo [ADVAPI32.@]
2711 DWORD WINAPI GetSecurityInfo(
2712 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2713 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2714 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2715 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2718 FIXME("stub!\n");
2719 return ERROR_BAD_PROVIDER;
2722 /******************************************************************************
2723 * GetSecurityInfoExW [ADVAPI32.@]
2725 DWORD WINAPI GetSecurityInfoExW(
2726 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2727 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2728 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2729 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2732 FIXME("stub!\n");
2733 return ERROR_BAD_PROVIDER;
2736 /******************************************************************************
2737 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2739 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2740 LPSTR pTrusteeName, DWORD AccessPermissions,
2741 ACCESS_MODE AccessMode, DWORD Inheritance )
2743 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2744 AccessPermissions, AccessMode, Inheritance);
2746 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2747 pExplicitAccess->grfAccessMode = AccessMode;
2748 pExplicitAccess->grfInheritance = Inheritance;
2750 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2751 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2752 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2753 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2754 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2757 /******************************************************************************
2758 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2760 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2761 LPWSTR pTrusteeName, DWORD AccessPermissions,
2762 ACCESS_MODE AccessMode, DWORD Inheritance )
2764 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2765 AccessPermissions, AccessMode, Inheritance);
2767 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2768 pExplicitAccess->grfAccessMode = AccessMode;
2769 pExplicitAccess->grfInheritance = Inheritance;
2771 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2772 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2773 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2774 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2775 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2778 /******************************************************************************
2779 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2781 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2782 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2783 LPSTR InheritedObjectTypeName, LPSTR Name )
2785 DWORD ObjectsPresent = 0;
2787 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2788 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2790 /* Fill the OBJECTS_AND_NAME structure */
2791 pObjName->ObjectType = ObjectType;
2792 if (ObjectTypeName != NULL)
2794 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2797 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2798 if (InheritedObjectTypeName != NULL)
2800 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2803 pObjName->ObjectsPresent = ObjectsPresent;
2804 pObjName->ptstrName = Name;
2806 /* Fill the TRUSTEE structure */
2807 pTrustee->pMultipleTrustee = NULL;
2808 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2809 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2810 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2811 pTrustee->ptstrName = (LPSTR)pObjName;
2814 /******************************************************************************
2815 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2817 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2818 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2819 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2821 DWORD ObjectsPresent = 0;
2823 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2824 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2826 /* Fill the OBJECTS_AND_NAME structure */
2827 pObjName->ObjectType = ObjectType;
2828 if (ObjectTypeName != NULL)
2830 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2833 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2834 if (InheritedObjectTypeName != NULL)
2836 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2839 pObjName->ObjectsPresent = ObjectsPresent;
2840 pObjName->ptstrName = Name;
2842 /* Fill the TRUSTEE structure */
2843 pTrustee->pMultipleTrustee = NULL;
2844 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2845 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2846 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2847 pTrustee->ptstrName = (LPWSTR)pObjName;
2850 /******************************************************************************
2851 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2853 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2854 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2856 DWORD ObjectsPresent = 0;
2858 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2860 /* Fill the OBJECTS_AND_SID structure */
2861 if (pObjectGuid != NULL)
2863 pObjSid->ObjectTypeGuid = *pObjectGuid;
2864 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2866 else
2868 ZeroMemory(&pObjSid->ObjectTypeGuid,
2869 sizeof(GUID));
2872 if (pInheritedObjectGuid != NULL)
2874 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2875 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2877 else
2879 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2880 sizeof(GUID));
2883 pObjSid->ObjectsPresent = ObjectsPresent;
2884 pObjSid->pSid = pSid;
2886 /* Fill the TRUSTEE structure */
2887 pTrustee->pMultipleTrustee = NULL;
2888 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2889 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2890 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2891 pTrustee->ptstrName = (LPSTR) pObjSid;
2894 /******************************************************************************
2895 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2897 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2898 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2900 DWORD ObjectsPresent = 0;
2902 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2904 /* Fill the OBJECTS_AND_SID structure */
2905 if (pObjectGuid != NULL)
2907 pObjSid->ObjectTypeGuid = *pObjectGuid;
2908 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2910 else
2912 ZeroMemory(&pObjSid->ObjectTypeGuid,
2913 sizeof(GUID));
2916 if (pInheritedObjectGuid != NULL)
2918 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2919 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2921 else
2923 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2924 sizeof(GUID));
2927 pObjSid->ObjectsPresent = ObjectsPresent;
2928 pObjSid->pSid = pSid;
2930 /* Fill the TRUSTEE structure */
2931 pTrustee->pMultipleTrustee = NULL;
2932 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2933 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2934 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2935 pTrustee->ptstrName = (LPWSTR) pObjSid;
2938 /******************************************************************************
2939 * BuildTrusteeWithSidA [ADVAPI32.@]
2941 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2943 TRACE("%p %p\n", pTrustee, pSid);
2945 pTrustee->pMultipleTrustee = NULL;
2946 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2947 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2948 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2949 pTrustee->ptstrName = (LPSTR) pSid;
2952 /******************************************************************************
2953 * BuildTrusteeWithSidW [ADVAPI32.@]
2955 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2957 TRACE("%p %p\n", pTrustee, pSid);
2959 pTrustee->pMultipleTrustee = NULL;
2960 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2961 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2962 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2963 pTrustee->ptstrName = (LPWSTR) pSid;
2966 /******************************************************************************
2967 * BuildTrusteeWithNameA [ADVAPI32.@]
2969 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2971 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2973 pTrustee->pMultipleTrustee = NULL;
2974 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2975 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2976 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2977 pTrustee->ptstrName = name;
2980 /******************************************************************************
2981 * BuildTrusteeWithNameW [ADVAPI32.@]
2983 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2985 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2987 pTrustee->pMultipleTrustee = NULL;
2988 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2989 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2990 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2991 pTrustee->ptstrName = name;
2994 /******************************************************************************
2995 * GetTrusteeFormA [ADVAPI32.@]
2997 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2999 TRACE("(%p)\n", pTrustee);
3001 if (!pTrustee)
3002 return TRUSTEE_BAD_FORM;
3004 return pTrustee->TrusteeForm;
3007 /******************************************************************************
3008 * GetTrusteeFormW [ADVAPI32.@]
3010 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3012 TRACE("(%p)\n", pTrustee);
3014 if (!pTrustee)
3015 return TRUSTEE_BAD_FORM;
3017 return pTrustee->TrusteeForm;
3020 /******************************************************************************
3021 * GetTrusteeNameA [ADVAPI32.@]
3023 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3025 TRACE("(%p)\n", pTrustee);
3027 if (!pTrustee)
3028 return NULL;
3030 return pTrustee->ptstrName;
3033 /******************************************************************************
3034 * GetTrusteeNameW [ADVAPI32.@]
3036 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3038 TRACE("(%p)\n", pTrustee);
3040 if (!pTrustee)
3041 return NULL;
3043 return pTrustee->ptstrName;
3046 /******************************************************************************
3047 * GetTrusteeTypeA [ADVAPI32.@]
3049 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3051 TRACE("(%p)\n", pTrustee);
3053 if (!pTrustee)
3054 return TRUSTEE_IS_UNKNOWN;
3056 return pTrustee->TrusteeType;
3059 /******************************************************************************
3060 * GetTrusteeTypeW [ADVAPI32.@]
3062 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3064 TRACE("(%p)\n", pTrustee);
3066 if (!pTrustee)
3067 return TRUSTEE_IS_UNKNOWN;
3069 return pTrustee->TrusteeType;
3072 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3073 DWORD nAclInformationLength,
3074 ACL_INFORMATION_CLASS dwAclInformationClass )
3076 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3077 nAclInformationLength, dwAclInformationClass);
3079 return TRUE;
3082 /******************************************************************************
3083 * SetEntriesInAclA [ADVAPI32.@]
3085 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3086 PACL OldAcl, PACL* NewAcl )
3088 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3089 *NewAcl = NULL;
3090 return ERROR_SUCCESS;
3093 /******************************************************************************
3094 * SetEntriesInAclW [ADVAPI32.@]
3096 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3097 PACL OldAcl, PACL* NewAcl )
3099 ULONG i;
3100 PSID *ppsid;
3101 DWORD ret = ERROR_SUCCESS;
3102 DWORD acl_size = sizeof(ACL);
3103 NTSTATUS status;
3105 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3107 *NewAcl = NULL;
3109 if (!count && !OldAcl)
3110 return ERROR_SUCCESS;
3112 /* allocate array of maximum sized sids allowed */
3113 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3114 if (!ppsid)
3115 return ERROR_OUTOFMEMORY;
3117 for (i = 0; i < count; i++)
3119 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3121 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3122 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3123 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3124 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3125 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3126 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3127 pEntries[i].Trustee.ptstrName);
3129 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3131 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3132 ret = ERROR_INVALID_PARAMETER;
3133 goto exit;
3136 switch (pEntries[i].Trustee.TrusteeForm)
3138 case TRUSTEE_IS_SID:
3139 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3140 ppsid[i], pEntries[i].Trustee.ptstrName))
3142 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3143 ret = ERROR_INVALID_PARAMETER;
3144 goto exit;
3146 break;
3147 case TRUSTEE_IS_NAME:
3149 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3150 DWORD domain_size = 0;
3151 SID_NAME_USE use;
3152 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3154 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3155 ret = ERROR_INVALID_PARAMETER;
3156 goto exit;
3158 break;
3160 case TRUSTEE_IS_OBJECTS_AND_SID:
3161 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3162 break;
3163 case TRUSTEE_IS_OBJECTS_AND_NAME:
3164 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3165 break;
3166 default:
3167 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3168 ret = ERROR_INVALID_PARAMETER;
3169 goto exit;
3172 /* Note: we overestimate the ACL size here as a tradeoff between
3173 * instructions (simplicity) and memory */
3174 switch (pEntries[i].grfAccessMode)
3176 case GRANT_ACCESS:
3177 case SET_ACCESS:
3178 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3179 break;
3180 case DENY_ACCESS:
3181 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3182 break;
3183 case SET_AUDIT_SUCCESS:
3184 case SET_AUDIT_FAILURE:
3185 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3186 break;
3187 case REVOKE_ACCESS:
3188 break;
3189 default:
3190 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3191 ret = ERROR_INVALID_PARAMETER;
3192 goto exit;
3196 if (OldAcl)
3198 ACL_SIZE_INFORMATION size_info;
3200 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3201 if (status != STATUS_SUCCESS)
3203 ret = RtlNtStatusToDosError(status);
3204 goto exit;
3206 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3209 *NewAcl = LocalAlloc(0, acl_size);
3210 if (!*NewAcl)
3212 ret = ERROR_OUTOFMEMORY;
3213 goto exit;
3216 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3217 if (status != STATUS_SUCCESS)
3219 ret = RtlNtStatusToDosError(status);
3220 goto exit;
3223 for (i = 0; i < count; i++)
3225 switch (pEntries[i].grfAccessMode)
3227 case GRANT_ACCESS:
3228 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3229 pEntries[i].grfInheritance,
3230 pEntries[i].grfAccessPermissions,
3231 ppsid[i]);
3232 break;
3233 case SET_ACCESS:
3235 ULONG j;
3236 BOOL add = TRUE;
3237 if (OldAcl)
3239 for (j = 0; ; j++)
3241 const ACE_HEADER *existing_ace_header;
3242 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3243 if (status != STATUS_SUCCESS)
3244 break;
3245 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3246 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3247 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3249 add = FALSE;
3250 break;
3254 if (add)
3255 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3256 pEntries[i].grfInheritance,
3257 pEntries[i].grfAccessPermissions,
3258 ppsid[i]);
3259 break;
3261 case DENY_ACCESS:
3262 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3263 pEntries[i].grfInheritance,
3264 pEntries[i].grfAccessPermissions,
3265 ppsid[i]);
3266 break;
3267 case SET_AUDIT_SUCCESS:
3268 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3269 pEntries[i].grfInheritance,
3270 pEntries[i].grfAccessPermissions,
3271 ppsid[i], TRUE, FALSE);
3272 break;
3273 case SET_AUDIT_FAILURE:
3274 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3275 pEntries[i].grfInheritance,
3276 pEntries[i].grfAccessPermissions,
3277 ppsid[i], FALSE, TRUE);
3278 break;
3279 default:
3280 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3284 if (OldAcl)
3286 for (i = 0; ; i++)
3288 BOOL add = TRUE;
3289 ULONG j;
3290 const ACE_HEADER *old_ace_header;
3291 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3292 if (status != STATUS_SUCCESS) break;
3293 for (j = 0; j < count; j++)
3295 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3296 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3297 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3299 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3300 add = FALSE;
3301 break;
3303 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3305 switch (old_ace_header->AceType)
3307 case ACCESS_ALLOWED_ACE_TYPE:
3308 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3309 add = FALSE;
3310 break;
3311 case ACCESS_DENIED_ACE_TYPE:
3312 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3313 add = FALSE;
3314 break;
3315 case SYSTEM_AUDIT_ACE_TYPE:
3316 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3317 add = FALSE;
3318 break;
3319 case SYSTEM_ALARM_ACE_TYPE:
3320 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3321 add = FALSE;
3322 break;
3323 default:
3324 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3327 if (!add)
3328 break;
3331 if (add)
3332 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3333 if (status != STATUS_SUCCESS)
3335 WARN("RtlAddAce failed with error 0x%08x\n", status);
3336 ret = RtlNtStatusToDosError(status);
3337 break;
3342 exit:
3343 HeapFree(GetProcessHeap(), 0, ppsid);
3344 return ret;
3347 /******************************************************************************
3348 * SetNamedSecurityInfoA [ADVAPI32.@]
3350 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3351 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3352 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3354 DWORD len;
3355 LPWSTR wstr = NULL;
3356 DWORD r;
3358 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3359 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3361 if( pObjectName )
3363 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3364 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3365 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3368 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3369 psidGroup, pDacl, pSacl );
3371 HeapFree( GetProcessHeap(), 0, wstr );
3373 return r;
3376 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3377 PSECURITY_DESCRIPTOR ModificationDescriptor,
3378 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3379 PGENERIC_MAPPING GenericMapping,
3380 HANDLE Token )
3382 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3383 ObjectsSecurityDescriptor, GenericMapping, Token);
3385 return TRUE;
3388 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3390 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3393 /******************************************************************************
3394 * AreAnyAccessesGranted [ADVAPI32.@]
3396 * Determines whether or not any of a set of specified access permissions have
3397 * been granted or not.
3399 * PARAMS
3400 * GrantedAccess [I] The permissions that have been granted.
3401 * DesiredAccess [I] The permissions that you want to have.
3403 * RETURNS
3404 * Nonzero if any of the permissions have been granted, zero if none of the
3405 * permissions have been granted.
3408 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3410 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3413 /******************************************************************************
3414 * SetNamedSecurityInfoW [ADVAPI32.@]
3416 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3417 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3418 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3420 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3421 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3422 return ERROR_SUCCESS;
3425 /******************************************************************************
3426 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3428 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3429 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3431 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3432 return ERROR_CALL_NOT_IMPLEMENTED;
3435 /******************************************************************************
3436 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3438 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3439 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3441 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3442 return ERROR_CALL_NOT_IMPLEMENTED;
3445 /******************************************************************************
3446 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3448 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3449 PACCESS_MASK pFailedAuditRights)
3451 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3452 return ERROR_CALL_NOT_IMPLEMENTED;
3456 /******************************************************************************
3457 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3459 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3460 PACCESS_MASK pFailedAuditRights)
3462 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3463 return ERROR_CALL_NOT_IMPLEMENTED;
3467 /******************************************************************************
3468 * ParseAclStringFlags
3470 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3472 DWORD flags = 0;
3473 LPCWSTR szAcl = *StringAcl;
3475 while (*szAcl != '(')
3477 if (*szAcl == 'P')
3479 flags |= SE_DACL_PROTECTED;
3481 else if (*szAcl == 'A')
3483 szAcl++;
3484 if (*szAcl == 'R')
3485 flags |= SE_DACL_AUTO_INHERIT_REQ;
3486 else if (*szAcl == 'I')
3487 flags |= SE_DACL_AUTO_INHERITED;
3489 szAcl++;
3492 *StringAcl = szAcl;
3493 return flags;
3496 /******************************************************************************
3497 * ParseAceStringType
3499 static const ACEFLAG AceType[] =
3501 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3502 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3503 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3504 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3506 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3507 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3508 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3509 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3511 { NULL, 0 },
3514 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3516 UINT len = 0;
3517 LPCWSTR szAcl = *StringAcl;
3518 const ACEFLAG *lpaf = AceType;
3520 while (lpaf->wstr &&
3521 (len = strlenW(lpaf->wstr)) &&
3522 strncmpW(lpaf->wstr, szAcl, len))
3523 lpaf++;
3525 if (!lpaf->wstr)
3526 return 0;
3528 *StringAcl += len;
3529 return lpaf->value;
3533 /******************************************************************************
3534 * ParseAceStringFlags
3536 static const ACEFLAG AceFlags[] =
3538 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3539 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3540 { SDDL_INHERITED, INHERITED_ACE },
3541 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3542 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3543 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3544 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3545 { NULL, 0 },
3548 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3550 UINT len = 0;
3551 BYTE flags = 0;
3552 LPCWSTR szAcl = *StringAcl;
3554 while (*szAcl != ';')
3556 const ACEFLAG *lpaf = AceFlags;
3558 while (lpaf->wstr &&
3559 (len = strlenW(lpaf->wstr)) &&
3560 strncmpW(lpaf->wstr, szAcl, len))
3561 lpaf++;
3563 if (!lpaf->wstr)
3564 return 0;
3566 flags |= lpaf->value;
3567 szAcl += len;
3570 *StringAcl = szAcl;
3571 return flags;
3575 /******************************************************************************
3576 * ParseAceStringRights
3578 static const ACEFLAG AceRights[] =
3580 { SDDL_GENERIC_ALL, GENERIC_ALL },
3581 { SDDL_GENERIC_READ, GENERIC_READ },
3582 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3583 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3585 { SDDL_READ_CONTROL, READ_CONTROL },
3586 { SDDL_STANDARD_DELETE, DELETE },
3587 { SDDL_WRITE_DAC, WRITE_DAC },
3588 { SDDL_WRITE_OWNER, WRITE_OWNER },
3590 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3591 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3592 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3593 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3594 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3595 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3596 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3597 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3598 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3600 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3601 { SDDL_FILE_READ, FILE_GENERIC_READ },
3602 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3603 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3605 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3606 { SDDL_KEY_READ, KEY_READ },
3607 { SDDL_KEY_WRITE, KEY_WRITE },
3608 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3609 { NULL, 0 },
3612 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3614 UINT len = 0;
3615 DWORD rights = 0;
3616 LPCWSTR szAcl = *StringAcl;
3618 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3620 LPCWSTR p = szAcl;
3622 while (*p && *p != ';')
3623 p++;
3625 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3627 rights = strtoulW(szAcl, NULL, 16);
3628 szAcl = p;
3630 else
3631 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3633 else
3635 while (*szAcl != ';')
3637 const ACEFLAG *lpaf = AceRights;
3639 while (lpaf->wstr &&
3640 (len = strlenW(lpaf->wstr)) &&
3641 strncmpW(lpaf->wstr, szAcl, len))
3643 lpaf++;
3646 if (!lpaf->wstr)
3647 return 0;
3649 rights |= lpaf->value;
3650 szAcl += len;
3654 *StringAcl = szAcl;
3655 return rights;
3659 /******************************************************************************
3660 * ParseStringAclToAcl
3662 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3664 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3665 PACL pAcl, LPDWORD cBytes)
3667 DWORD val;
3668 DWORD sidlen;
3669 DWORD length = sizeof(ACL);
3670 DWORD acesize = 0;
3671 DWORD acecount = 0;
3672 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3674 TRACE("%s\n", debugstr_w(StringAcl));
3676 if (!StringAcl)
3677 return FALSE;
3679 if (pAcl) /* pAce is only useful if we're setting values */
3680 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3682 /* Parse ACL flags */
3683 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3685 /* Parse ACE */
3686 while (*StringAcl == '(')
3688 StringAcl++;
3690 /* Parse ACE type */
3691 val = ParseAceStringType(&StringAcl);
3692 if (pAce)
3693 pAce->Header.AceType = (BYTE) val;
3694 if (*StringAcl != ';')
3695 goto lerr;
3696 StringAcl++;
3698 /* Parse ACE flags */
3699 val = ParseAceStringFlags(&StringAcl);
3700 if (pAce)
3701 pAce->Header.AceFlags = (BYTE) val;
3702 if (*StringAcl != ';')
3703 goto lerr;
3704 StringAcl++;
3706 /* Parse ACE rights */
3707 val = ParseAceStringRights(&StringAcl);
3708 if (pAce)
3709 pAce->Mask = val;
3710 if (*StringAcl != ';')
3711 goto lerr;
3712 StringAcl++;
3714 /* Parse ACE object guid */
3715 if (*StringAcl != ';')
3717 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3718 goto lerr;
3720 StringAcl++;
3722 /* Parse ACE inherit object guid */
3723 if (*StringAcl != ';')
3725 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3726 goto lerr;
3728 StringAcl++;
3730 /* Parse ACE account sid */
3731 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3733 while (*StringAcl && *StringAcl != ')')
3734 StringAcl++;
3737 if (*StringAcl != ')')
3738 goto lerr;
3739 StringAcl++;
3741 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3742 length += acesize;
3743 if (pAce)
3745 pAce->Header.AceSize = acesize;
3746 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3748 acecount++;
3751 *cBytes = length;
3753 if (length > 0xffff)
3755 ERR("ACL too large\n");
3756 goto lerr;
3759 if (pAcl)
3761 pAcl->AclRevision = ACL_REVISION;
3762 pAcl->Sbz1 = 0;
3763 pAcl->AclSize = length;
3764 pAcl->AceCount = acecount++;
3765 pAcl->Sbz2 = 0;
3767 return TRUE;
3769 lerr:
3770 WARN("Invalid ACE string format\n");
3771 return FALSE;
3775 /******************************************************************************
3776 * ParseStringSecurityDescriptorToSecurityDescriptor
3778 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3779 LPCWSTR StringSecurityDescriptor,
3780 SECURITY_DESCRIPTOR* SecurityDescriptor,
3781 LPDWORD cBytes)
3783 BOOL bret = FALSE;
3784 WCHAR toktype;
3785 WCHAR tok[MAX_PATH];
3786 LPCWSTR lptoken;
3787 LPBYTE lpNext = NULL;
3788 DWORD len;
3790 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3792 if (SecurityDescriptor)
3793 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3795 while (*StringSecurityDescriptor)
3797 toktype = *StringSecurityDescriptor;
3799 /* Expect char identifier followed by ':' */
3800 StringSecurityDescriptor++;
3801 if (*StringSecurityDescriptor != ':')
3803 SetLastError(ERROR_INVALID_PARAMETER);
3804 goto lend;
3806 StringSecurityDescriptor++;
3808 /* Extract token */
3809 lptoken = StringSecurityDescriptor;
3810 while (*lptoken && *lptoken != ':')
3811 lptoken++;
3813 if (*lptoken)
3814 lptoken--;
3816 len = lptoken - StringSecurityDescriptor;
3817 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3818 tok[len] = 0;
3820 switch (toktype)
3822 case 'O':
3824 DWORD bytes;
3826 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3827 goto lend;
3829 if (SecurityDescriptor)
3831 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3832 lpNext += bytes; /* Advance to next token */
3835 *cBytes += bytes;
3837 break;
3840 case 'G':
3842 DWORD bytes;
3844 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3845 goto lend;
3847 if (SecurityDescriptor)
3849 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3850 lpNext += bytes; /* Advance to next token */
3853 *cBytes += bytes;
3855 break;
3858 case 'D':
3860 DWORD flags;
3861 DWORD bytes;
3863 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3864 goto lend;
3866 if (SecurityDescriptor)
3868 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3869 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3870 lpNext += bytes; /* Advance to next token */
3873 *cBytes += bytes;
3875 break;
3878 case 'S':
3880 DWORD flags;
3881 DWORD bytes;
3883 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3884 goto lend;
3886 if (SecurityDescriptor)
3888 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3889 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3890 lpNext += bytes; /* Advance to next token */
3893 *cBytes += bytes;
3895 break;
3898 default:
3899 FIXME("Unknown token\n");
3900 SetLastError(ERROR_INVALID_PARAMETER);
3901 goto lend;
3904 StringSecurityDescriptor = lptoken;
3907 bret = TRUE;
3909 lend:
3910 return bret;
3913 /******************************************************************************
3914 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3916 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3917 LPCSTR StringSecurityDescriptor,
3918 DWORD StringSDRevision,
3919 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3920 PULONG SecurityDescriptorSize)
3922 UINT len;
3923 BOOL ret = FALSE;
3924 LPWSTR StringSecurityDescriptorW;
3926 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3927 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3929 if (StringSecurityDescriptorW)
3931 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3933 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3934 StringSDRevision, SecurityDescriptor,
3935 SecurityDescriptorSize);
3936 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3939 return ret;
3942 /******************************************************************************
3943 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3945 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3946 LPCWSTR StringSecurityDescriptor,
3947 DWORD StringSDRevision,
3948 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3949 PULONG SecurityDescriptorSize)
3951 DWORD cBytes;
3952 SECURITY_DESCRIPTOR* psd;
3953 BOOL bret = FALSE;
3955 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3957 if (GetVersion() & 0x80000000)
3959 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3960 goto lend;
3962 else if (StringSDRevision != SID_REVISION)
3964 SetLastError(ERROR_UNKNOWN_REVISION);
3965 goto lend;
3968 /* Compute security descriptor length */
3969 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3970 NULL, &cBytes))
3971 goto lend;
3973 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3974 GMEM_ZEROINIT, cBytes);
3975 if (!psd) goto lend;
3977 psd->Revision = SID_REVISION;
3978 psd->Control |= SE_SELF_RELATIVE;
3980 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3981 psd, &cBytes))
3983 LocalFree(psd);
3984 goto lend;
3987 if (SecurityDescriptorSize)
3988 *SecurityDescriptorSize = cBytes;
3990 bret = TRUE;
3992 lend:
3993 TRACE(" ret=%d\n", bret);
3994 return bret;
3997 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3999 if (cch == -1)
4000 cch = strlenW(string);
4002 if (plen)
4003 *plen += cch;
4005 if (pwptr)
4007 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4008 *pwptr += cch;
4012 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4014 DWORD i;
4015 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4016 WCHAR subauthfmt[] = { '-','%','u',0 };
4017 WCHAR buf[26];
4018 SID *pisid = psid;
4020 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4022 SetLastError(ERROR_INVALID_SID);
4023 return FALSE;
4026 if (pisid->IdentifierAuthority.Value[0] ||
4027 pisid->IdentifierAuthority.Value[1])
4029 FIXME("not matching MS' bugs\n");
4030 SetLastError(ERROR_INVALID_SID);
4031 return FALSE;
4034 sprintfW( buf, fmt, pisid->Revision,
4035 MAKELONG(
4036 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4037 pisid->IdentifierAuthority.Value[4] ),
4038 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4039 pisid->IdentifierAuthority.Value[2] )
4040 ) );
4041 DumpString(buf, -1, pwptr, plen);
4043 for( i=0; i<pisid->SubAuthorityCount; i++ )
4045 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4046 DumpString(buf, -1, pwptr, plen);
4048 return TRUE;
4051 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4053 int i;
4054 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4056 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4058 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4059 return TRUE;
4063 return DumpSidNumeric(psid, pwptr, plen);
4066 static const LPCWSTR AceRightBitNames[32] = {
4067 SDDL_CREATE_CHILD, /* 0 */
4068 SDDL_DELETE_CHILD,
4069 SDDL_LIST_CHILDREN,
4070 SDDL_SELF_WRITE,
4071 SDDL_READ_PROPERTY, /* 4 */
4072 SDDL_WRITE_PROPERTY,
4073 SDDL_DELETE_TREE,
4074 SDDL_LIST_OBJECT,
4075 SDDL_CONTROL_ACCESS, /* 8 */
4076 NULL,
4077 NULL,
4078 NULL,
4079 NULL, /* 12 */
4080 NULL,
4081 NULL,
4082 NULL,
4083 SDDL_STANDARD_DELETE, /* 16 */
4084 SDDL_READ_CONTROL,
4085 SDDL_WRITE_DAC,
4086 SDDL_WRITE_OWNER,
4087 NULL, /* 20 */
4088 NULL,
4089 NULL,
4090 NULL,
4091 NULL, /* 24 */
4092 NULL,
4093 NULL,
4094 NULL,
4095 SDDL_GENERIC_ALL, /* 28 */
4096 SDDL_GENERIC_EXECUTE,
4097 SDDL_GENERIC_WRITE,
4098 SDDL_GENERIC_READ
4101 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4103 static const WCHAR fmtW[] = {'0','x','%','x',0};
4104 WCHAR buf[15];
4105 int i;
4107 if (mask == 0)
4108 return;
4110 /* first check if the right have name */
4111 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4113 if (AceRights[i].wstr == NULL)
4114 break;
4115 if (mask == AceRights[i].value)
4117 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4118 return;
4122 /* then check if it can be built from bit names */
4123 for (i = 0; i < 32; i++)
4125 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4127 /* can't be built from bit names */
4128 sprintfW(buf, fmtW, mask);
4129 DumpString(buf, -1, pwptr, plen);
4130 return;
4134 /* build from bit names */
4135 for (i = 0; i < 32; i++)
4136 if (mask & (1 << i))
4137 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4140 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4142 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4143 static const WCHAR openbr = '(';
4144 static const WCHAR closebr = ')';
4145 static const WCHAR semicolon = ';';
4147 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4149 SetLastError(ERROR_INVALID_ACL);
4150 return FALSE;
4153 piace = (ACCESS_ALLOWED_ACE *)pace;
4154 DumpString(&openbr, 1, pwptr, plen);
4155 switch (piace->Header.AceType)
4157 case ACCESS_ALLOWED_ACE_TYPE:
4158 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4159 break;
4160 case ACCESS_DENIED_ACE_TYPE:
4161 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4162 break;
4163 case SYSTEM_AUDIT_ACE_TYPE:
4164 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4165 break;
4166 case SYSTEM_ALARM_ACE_TYPE:
4167 DumpString(SDDL_ALARM, -1, pwptr, plen);
4168 break;
4170 DumpString(&semicolon, 1, pwptr, plen);
4172 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4173 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4174 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4175 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4176 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4177 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4178 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4179 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4180 if (piace->Header.AceFlags & INHERITED_ACE)
4181 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4182 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4183 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4184 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4185 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4186 DumpString(&semicolon, 1, pwptr, plen);
4187 DumpRights(piace->Mask, pwptr, plen);
4188 DumpString(&semicolon, 1, pwptr, plen);
4189 /* objects not supported */
4190 DumpString(&semicolon, 1, pwptr, plen);
4191 /* objects not supported */
4192 DumpString(&semicolon, 1, pwptr, plen);
4193 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4194 return FALSE;
4195 DumpString(&closebr, 1, pwptr, plen);
4196 return TRUE;
4199 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4201 WORD count;
4202 int i;
4204 if (protected)
4205 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4206 if (autoInheritReq)
4207 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4208 if (autoInherited)
4209 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4211 if (pacl == NULL)
4212 return TRUE;
4214 if (!IsValidAcl(pacl))
4215 return FALSE;
4217 count = pacl->AceCount;
4218 for (i = 0; i < count; i++)
4220 LPVOID ace;
4221 if (!GetAce(pacl, i, &ace))
4222 return FALSE;
4223 if (!DumpAce(ace, pwptr, plen))
4224 return FALSE;
4227 return TRUE;
4230 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4232 static const WCHAR prefix[] = {'O',':',0};
4233 BOOL bDefaulted;
4234 PSID psid;
4236 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4237 return FALSE;
4239 if (psid == NULL)
4240 return TRUE;
4242 DumpString(prefix, -1, pwptr, plen);
4243 if (!DumpSid(psid, pwptr, plen))
4244 return FALSE;
4245 return TRUE;
4248 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4250 static const WCHAR prefix[] = {'G',':',0};
4251 BOOL bDefaulted;
4252 PSID psid;
4254 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4255 return FALSE;
4257 if (psid == NULL)
4258 return TRUE;
4260 DumpString(prefix, -1, pwptr, plen);
4261 if (!DumpSid(psid, pwptr, plen))
4262 return FALSE;
4263 return TRUE;
4266 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4268 static const WCHAR dacl[] = {'D',':',0};
4269 SECURITY_DESCRIPTOR_CONTROL control;
4270 BOOL present, defaulted;
4271 DWORD revision;
4272 PACL pacl;
4274 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4275 return FALSE;
4277 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4278 return FALSE;
4280 if (!present)
4281 return TRUE;
4283 DumpString(dacl, 2, pwptr, plen);
4284 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4285 return FALSE;
4286 return TRUE;
4289 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4291 static const WCHAR sacl[] = {'S',':',0};
4292 SECURITY_DESCRIPTOR_CONTROL control;
4293 BOOL present, defaulted;
4294 DWORD revision;
4295 PACL pacl;
4297 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4298 return FALSE;
4300 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4301 return FALSE;
4303 if (!present)
4304 return TRUE;
4306 DumpString(sacl, 2, pwptr, plen);
4307 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4308 return FALSE;
4309 return TRUE;
4312 /******************************************************************************
4313 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4315 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4317 ULONG len;
4318 WCHAR *wptr, *wstr;
4320 if (SDRevision != SDDL_REVISION_1)
4322 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4323 SetLastError(ERROR_UNKNOWN_REVISION);
4324 return FALSE;
4327 len = 0;
4328 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4329 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4330 return FALSE;
4331 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4332 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4333 return FALSE;
4334 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4335 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4336 return FALSE;
4337 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4338 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4339 return FALSE;
4341 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4342 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4343 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4344 return FALSE;
4345 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4346 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4347 return FALSE;
4348 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4349 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4350 return FALSE;
4351 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4352 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4353 return FALSE;
4354 *wptr = 0;
4356 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4357 *OutputString = wstr;
4358 if (OutputLen)
4359 *OutputLen = strlenW(*OutputString)+1;
4360 return TRUE;
4363 /******************************************************************************
4364 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4366 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4368 LPWSTR wstr;
4369 ULONG len;
4370 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4372 int lenA;
4374 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4375 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4376 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4377 LocalFree(wstr);
4379 if (OutputLen != NULL)
4380 *OutputLen = lenA;
4381 return TRUE;
4383 else
4385 *OutputString = NULL;
4386 if (OutputLen)
4387 *OutputLen = 0;
4388 return FALSE;
4392 /******************************************************************************
4393 * ConvertStringSidToSidW [ADVAPI32.@]
4395 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4397 BOOL bret = FALSE;
4398 DWORD cBytes;
4400 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4401 if (GetVersion() & 0x80000000)
4402 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4403 else if (!StringSid || !Sid)
4404 SetLastError(ERROR_INVALID_PARAMETER);
4405 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4407 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4409 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4410 if (!bret)
4411 LocalFree(*Sid);
4413 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4414 return bret;
4417 /******************************************************************************
4418 * ConvertStringSidToSidA [ADVAPI32.@]
4420 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4422 BOOL bret = FALSE;
4424 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4425 if (GetVersion() & 0x80000000)
4426 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4427 else if (!StringSid || !Sid)
4428 SetLastError(ERROR_INVALID_PARAMETER);
4429 else
4431 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4432 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4433 len * sizeof(WCHAR));
4435 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4436 bret = ConvertStringSidToSidW(wStringSid, Sid);
4437 HeapFree(GetProcessHeap(), 0, wStringSid);
4439 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4440 return bret;
4443 /******************************************************************************
4444 * ConvertSidToStringSidW [ADVAPI32.@]
4446 * format of SID string is:
4447 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4448 * where
4449 * <rev> is the revision of the SID encoded as decimal
4450 * <auth> is the identifier authority encoded as hex
4451 * <subauthN> is the subauthority id encoded as decimal
4453 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4455 DWORD len = 0;
4456 LPWSTR wstr, wptr;
4458 TRACE("%p %p\n", pSid, pstr );
4460 len = 0;
4461 if (!DumpSidNumeric(pSid, NULL, &len))
4462 return FALSE;
4463 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4464 DumpSidNumeric(pSid, &wptr, NULL);
4465 *wptr = 0;
4467 *pstr = wstr;
4468 return TRUE;
4471 /******************************************************************************
4472 * ConvertSidToStringSidA [ADVAPI32.@]
4474 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4476 LPWSTR wstr = NULL;
4477 LPSTR str;
4478 UINT len;
4480 TRACE("%p %p\n", pSid, pstr );
4482 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4483 return FALSE;
4485 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4486 str = LocalAlloc( 0, len );
4487 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4488 LocalFree( wstr );
4490 *pstr = str;
4492 return TRUE;
4495 BOOL WINAPI CreatePrivateObjectSecurity(
4496 PSECURITY_DESCRIPTOR ParentDescriptor,
4497 PSECURITY_DESCRIPTOR CreatorDescriptor,
4498 PSECURITY_DESCRIPTOR* NewDescriptor,
4499 BOOL IsDirectoryObject,
4500 HANDLE Token,
4501 PGENERIC_MAPPING GenericMapping )
4503 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4504 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4506 return FALSE;
4509 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4511 FIXME("%p - stub\n", ObjectDescriptor);
4513 return TRUE;
4516 BOOL WINAPI CreateProcessAsUserA(
4517 HANDLE hToken,
4518 LPCSTR lpApplicationName,
4519 LPSTR lpCommandLine,
4520 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4521 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4522 BOOL bInheritHandles,
4523 DWORD dwCreationFlags,
4524 LPVOID lpEnvironment,
4525 LPCSTR lpCurrentDirectory,
4526 LPSTARTUPINFOA lpStartupInfo,
4527 LPPROCESS_INFORMATION lpProcessInformation )
4529 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4530 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4531 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4533 return FALSE;
4536 BOOL WINAPI CreateProcessAsUserW(
4537 HANDLE hToken,
4538 LPCWSTR lpApplicationName,
4539 LPWSTR lpCommandLine,
4540 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4541 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4542 BOOL bInheritHandles,
4543 DWORD dwCreationFlags,
4544 LPVOID lpEnvironment,
4545 LPCWSTR lpCurrentDirectory,
4546 LPSTARTUPINFOW lpStartupInfo,
4547 LPPROCESS_INFORMATION lpProcessInformation )
4549 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4550 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4551 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4552 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4554 /* We should create the process with a suspended main thread */
4555 if (!CreateProcessW (lpApplicationName,
4556 lpCommandLine,
4557 lpProcessAttributes,
4558 lpThreadAttributes,
4559 bInheritHandles,
4560 dwCreationFlags, /* CREATE_SUSPENDED */
4561 lpEnvironment,
4562 lpCurrentDirectory,
4563 lpStartupInfo,
4564 lpProcessInformation))
4566 return FALSE;
4569 return TRUE;
4572 /******************************************************************************
4573 * CreateProcessWithLogonW
4575 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4576 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4577 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4579 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4580 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4581 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4582 lpStartupInfo, lpProcessInformation);
4584 return FALSE;
4587 /******************************************************************************
4588 * DuplicateTokenEx [ADVAPI32.@]
4590 BOOL WINAPI DuplicateTokenEx(
4591 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4592 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4593 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4594 TOKEN_TYPE TokenType,
4595 PHANDLE DuplicateTokenHandle )
4597 OBJECT_ATTRIBUTES ObjectAttributes;
4599 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4600 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4602 InitializeObjectAttributes(
4603 &ObjectAttributes,
4604 NULL,
4605 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4606 NULL,
4607 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4609 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4610 dwDesiredAccess,
4611 &ObjectAttributes,
4612 ImpersonationLevel,
4613 TokenType,
4614 DuplicateTokenHandle ) );
4617 BOOL WINAPI DuplicateToken(
4618 HANDLE ExistingTokenHandle,
4619 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4620 PHANDLE DuplicateTokenHandle )
4622 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4623 NULL, ImpersonationLevel, TokenImpersonation,
4624 DuplicateTokenHandle );
4627 /******************************************************************************
4628 * ComputeStringSidSize
4630 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4632 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4634 int ctok = 0;
4635 while (*StringSid)
4637 if (*StringSid == '-')
4638 ctok++;
4639 StringSid++;
4642 if (ctok >= 3)
4643 return GetSidLengthRequired(ctok - 2);
4645 else /* String constant format - Only available in winxp and above */
4647 unsigned int i;
4649 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4650 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4651 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4654 return GetSidLengthRequired(0);
4657 /******************************************************************************
4658 * ParseStringSidToSid
4660 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4662 BOOL bret = FALSE;
4663 SID* pisid=pSid;
4665 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4666 if (!StringSid)
4668 SetLastError(ERROR_INVALID_PARAMETER);
4669 TRACE("StringSid is NULL, returning FALSE\n");
4670 return FALSE;
4673 *cBytes = ComputeStringSidSize(StringSid);
4674 if (!pisid) /* Simply compute the size */
4676 TRACE("only size requested, returning TRUE\n");
4677 return TRUE;
4680 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4682 DWORD i = 0, identAuth;
4683 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4685 StringSid += 2; /* Advance to Revision */
4686 pisid->Revision = atoiW(StringSid);
4688 if (pisid->Revision != SDDL_REVISION)
4690 TRACE("Revision %d is unknown\n", pisid->Revision);
4691 goto lend; /* ERROR_INVALID_SID */
4693 if (csubauth == 0)
4695 TRACE("SubAuthorityCount is 0\n");
4696 goto lend; /* ERROR_INVALID_SID */
4699 pisid->SubAuthorityCount = csubauth;
4701 /* Advance to identifier authority */
4702 while (*StringSid && *StringSid != '-')
4703 StringSid++;
4704 if (*StringSid == '-')
4705 StringSid++;
4707 /* MS' implementation can't handle values greater than 2^32 - 1, so
4708 * we don't either; assume most significant bytes are always 0
4710 pisid->IdentifierAuthority.Value[0] = 0;
4711 pisid->IdentifierAuthority.Value[1] = 0;
4712 identAuth = atoiW(StringSid);
4713 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4714 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4715 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4716 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4718 /* Advance to first sub authority */
4719 while (*StringSid && *StringSid != '-')
4720 StringSid++;
4721 if (*StringSid == '-')
4722 StringSid++;
4724 while (*StringSid)
4726 pisid->SubAuthority[i++] = atoiW(StringSid);
4728 while (*StringSid && *StringSid != '-')
4729 StringSid++;
4730 if (*StringSid == '-')
4731 StringSid++;
4734 if (i != pisid->SubAuthorityCount)
4735 goto lend; /* ERROR_INVALID_SID */
4737 bret = TRUE;
4739 else /* String constant format - Only available in winxp and above */
4741 unsigned int i;
4742 pisid->Revision = SDDL_REVISION;
4744 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4745 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4747 DWORD j;
4748 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4749 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4750 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4751 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4752 bret = TRUE;
4755 if (!bret)
4756 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4759 lend:
4760 if (!bret)
4761 SetLastError(ERROR_INVALID_SID);
4763 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4764 return bret;
4767 /******************************************************************************
4768 * GetNamedSecurityInfoA [ADVAPI32.@]
4770 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4771 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4772 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4773 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4775 DWORD len;
4776 LPWSTR wstr = NULL;
4777 DWORD r;
4779 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4780 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4782 if( pObjectName )
4784 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4785 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4786 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4789 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4790 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4792 HeapFree( GetProcessHeap(), 0, wstr );
4794 return r;
4797 /******************************************************************************
4798 * GetNamedSecurityInfoW [ADVAPI32.@]
4800 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4801 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4802 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4804 DWORD needed, offset;
4805 SECURITY_DESCRIPTOR_RELATIVE *relative;
4806 BYTE *buffer;
4808 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4809 group, dacl, sacl, descriptor );
4811 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4813 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4814 if (info & OWNER_SECURITY_INFORMATION)
4815 needed += sizeof(sidWorld);
4816 if (info & GROUP_SECURITY_INFORMATION)
4817 needed += sizeof(sidWorld);
4818 if (info & DACL_SECURITY_INFORMATION)
4819 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4820 if (info & SACL_SECURITY_INFORMATION)
4821 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4823 /* must be freed by caller */
4824 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4825 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4827 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4829 HeapFree( GetProcessHeap(), 0, *descriptor );
4830 return ERROR_INVALID_SECURITY_DESCR;
4833 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4834 relative->Control |= SE_SELF_RELATIVE;
4835 buffer = (BYTE *)relative;
4836 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4838 if (info & OWNER_SECURITY_INFORMATION)
4840 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4841 relative->Owner = offset;
4842 if (owner)
4843 *owner = buffer + offset;
4844 offset += sizeof(sidWorld);
4846 if (info & GROUP_SECURITY_INFORMATION)
4848 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4849 relative->Group = offset;
4850 if (group)
4851 *group = buffer + offset;
4852 offset += sizeof(sidWorld);
4854 if (info & DACL_SECURITY_INFORMATION)
4856 relative->Control |= SE_DACL_PRESENT;
4857 GetWorldAccessACL( (PACL)(buffer + offset) );
4858 relative->Dacl = offset;
4859 if (dacl)
4860 *dacl = (PACL)(buffer + offset);
4861 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4863 if (info & SACL_SECURITY_INFORMATION)
4865 relative->Control |= SE_SACL_PRESENT;
4866 GetWorldAccessACL( (PACL)(buffer + offset) );
4867 relative->Sacl = offset;
4868 if (sacl)
4869 *sacl = (PACL)(buffer + offset);
4871 return ERROR_SUCCESS;
4874 /******************************************************************************
4875 * DecryptFileW [ADVAPI32.@]
4877 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4879 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4880 return TRUE;
4883 /******************************************************************************
4884 * DecryptFileA [ADVAPI32.@]
4886 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4888 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4889 return TRUE;
4892 /******************************************************************************
4893 * EncryptFileW [ADVAPI32.@]
4895 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4897 FIXME("%s\n", debugstr_w(lpFileName));
4898 return TRUE;
4901 /******************************************************************************
4902 * EncryptFileA [ADVAPI32.@]
4904 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4906 FIXME("%s\n", debugstr_a(lpFileName));
4907 return TRUE;
4910 /******************************************************************************
4911 * FileEncryptionStatusW [ADVAPI32.@]
4913 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4915 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4916 if (!lpStatus)
4917 return FALSE;
4918 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4919 return TRUE;
4922 /******************************************************************************
4923 * FileEncryptionStatusA [ADVAPI32.@]
4925 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4927 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4928 if (!lpStatus)
4929 return FALSE;
4930 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4931 return TRUE;
4934 /******************************************************************************
4935 * SetSecurityInfo [ADVAPI32.@]
4937 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4938 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4939 PSID psidGroup, PACL pDacl, PACL pSacl) {
4940 FIXME("stub\n");
4941 return ERROR_SUCCESS;