push b59ba84f7e04af9ef068bd4c6e96701941f0256e
[wine/hacks.git] / dlls / advapi32 / security.c
blobb8c0a31cdaa8c09ca166ee4a5fa2d3cb19233b09
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 ###### SID FUNCTIONS ######
739 ##############################
742 /******************************************************************************
743 * AllocateAndInitializeSid [ADVAPI32.@]
745 * PARAMS
746 * pIdentifierAuthority []
747 * nSubAuthorityCount []
748 * nSubAuthority0 []
749 * nSubAuthority1 []
750 * nSubAuthority2 []
751 * nSubAuthority3 []
752 * nSubAuthority4 []
753 * nSubAuthority5 []
754 * nSubAuthority6 []
755 * nSubAuthority7 []
756 * pSid []
758 BOOL WINAPI
759 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
760 BYTE nSubAuthorityCount,
761 DWORD nSubAuthority0, DWORD nSubAuthority1,
762 DWORD nSubAuthority2, DWORD nSubAuthority3,
763 DWORD nSubAuthority4, DWORD nSubAuthority5,
764 DWORD nSubAuthority6, DWORD nSubAuthority7,
765 PSID *pSid )
767 return set_ntstatus( RtlAllocateAndInitializeSid(
768 pIdentifierAuthority, nSubAuthorityCount,
769 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
770 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
771 pSid ));
774 /******************************************************************************
775 * FreeSid [ADVAPI32.@]
777 * PARAMS
778 * pSid []
780 PVOID WINAPI
781 FreeSid( PSID pSid )
783 RtlFreeSid(pSid);
784 return NULL; /* is documented like this */
787 /******************************************************************************
788 * CopySid [ADVAPI32.@]
790 * PARAMS
791 * nDestinationSidLength []
792 * pDestinationSid []
793 * pSourceSid []
795 BOOL WINAPI
796 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
798 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
801 /******************************************************************************
802 * CreateWellKnownSid [ADVAPI32.@]
804 BOOL WINAPI
805 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
806 PSID DomainSid,
807 PSID pSid,
808 DWORD* cbSid)
810 unsigned int i;
811 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
813 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
814 SetLastError(ERROR_INVALID_PARAMETER);
815 return FALSE;
818 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
819 if (WellKnownSids[i].Type == WellKnownSidType) {
820 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
822 if (*cbSid < length) {
823 SetLastError(ERROR_INSUFFICIENT_BUFFER);
824 return FALSE;
827 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
828 *cbSid = length;
829 return TRUE;
833 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
835 SetLastError(ERROR_INVALID_PARAMETER);
836 return FALSE;
839 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
840 if (WellKnownRids[i].Type == WellKnownSidType) {
841 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
842 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
843 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
845 if (*cbSid < output_sid_length) {
846 SetLastError(ERROR_INSUFFICIENT_BUFFER);
847 return FALSE;
850 CopyMemory(pSid, DomainSid, domain_sid_length);
851 (*GetSidSubAuthorityCount(pSid))++;
852 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
853 *cbSid = output_sid_length;
854 return TRUE;
857 SetLastError(ERROR_INVALID_PARAMETER);
858 return FALSE;
861 /******************************************************************************
862 * IsWellKnownSid [ADVAPI32.@]
864 BOOL WINAPI
865 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
867 unsigned int i;
868 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
870 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
871 if (WellKnownSids[i].Type == WellKnownSidType)
872 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
873 return TRUE;
875 return FALSE;
878 BOOL WINAPI
879 IsTokenRestricted( HANDLE TokenHandle )
881 TOKEN_GROUPS *groups;
882 DWORD size;
883 NTSTATUS status;
884 BOOL restricted;
886 TRACE("(%p)\n", TokenHandle);
888 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
889 if (status != STATUS_BUFFER_TOO_SMALL)
890 return FALSE;
892 groups = HeapAlloc(GetProcessHeap(), 0, size);
893 if (!groups)
895 SetLastError(ERROR_OUTOFMEMORY);
896 return FALSE;
899 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
900 if (status != STATUS_SUCCESS)
902 HeapFree(GetProcessHeap(), 0, groups);
903 return set_ntstatus(status);
906 if (groups->GroupCount)
907 restricted = TRUE;
908 else
909 restricted = FALSE;
911 HeapFree(GetProcessHeap(), 0, groups);
913 return restricted;
916 /******************************************************************************
917 * IsValidSid [ADVAPI32.@]
919 * PARAMS
920 * pSid []
922 BOOL WINAPI
923 IsValidSid( PSID pSid )
925 return RtlValidSid( pSid );
928 /******************************************************************************
929 * EqualSid [ADVAPI32.@]
931 * PARAMS
932 * pSid1 []
933 * pSid2 []
935 BOOL WINAPI
936 EqualSid( PSID pSid1, PSID pSid2 )
938 return RtlEqualSid( pSid1, pSid2 );
941 /******************************************************************************
942 * EqualPrefixSid [ADVAPI32.@]
944 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
946 return RtlEqualPrefixSid(pSid1, pSid2);
949 /******************************************************************************
950 * GetSidLengthRequired [ADVAPI32.@]
952 * PARAMS
953 * nSubAuthorityCount []
955 DWORD WINAPI
956 GetSidLengthRequired( BYTE nSubAuthorityCount )
958 return RtlLengthRequiredSid(nSubAuthorityCount);
961 /******************************************************************************
962 * InitializeSid [ADVAPI32.@]
964 * PARAMS
965 * pIdentifierAuthority []
967 BOOL WINAPI
968 InitializeSid (
969 PSID pSid,
970 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
971 BYTE nSubAuthorityCount)
973 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
976 DWORD WINAPI
977 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
979 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
981 return 1;
984 DWORD WINAPI
985 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
987 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
989 return 1;
992 /******************************************************************************
993 * GetSidIdentifierAuthority [ADVAPI32.@]
995 * PARAMS
996 * pSid []
998 PSID_IDENTIFIER_AUTHORITY WINAPI
999 GetSidIdentifierAuthority( PSID pSid )
1001 return RtlIdentifierAuthoritySid(pSid);
1004 /******************************************************************************
1005 * GetSidSubAuthority [ADVAPI32.@]
1007 * PARAMS
1008 * pSid []
1009 * nSubAuthority []
1011 PDWORD WINAPI
1012 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1014 return RtlSubAuthoritySid(pSid, nSubAuthority);
1017 /******************************************************************************
1018 * GetSidSubAuthorityCount [ADVAPI32.@]
1020 * PARAMS
1021 * pSid []
1023 PUCHAR WINAPI
1024 GetSidSubAuthorityCount (PSID pSid)
1026 return RtlSubAuthorityCountSid(pSid);
1029 /******************************************************************************
1030 * GetLengthSid [ADVAPI32.@]
1032 * PARAMS
1033 * pSid []
1035 DWORD WINAPI
1036 GetLengthSid (PSID pSid)
1038 return RtlLengthSid(pSid);
1041 /* ##############################################
1042 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1043 ##############################################
1046 /******************************************************************************
1047 * BuildSecurityDescriptorA [ADVAPI32.@]
1049 * Builds a SD from
1051 * PARAMS
1052 * pOwner [I]
1053 * pGroup [I]
1054 * cCountOfAccessEntries [I]
1055 * pListOfAccessEntries [I]
1056 * cCountOfAuditEntries [I]
1057 * pListofAuditEntries [I]
1058 * pOldSD [I]
1059 * lpdwBufferLength [I/O]
1060 * pNewSD [O]
1062 * RETURNS
1063 * Success: ERROR_SUCCESS
1064 * Failure: nonzero error code from Winerror.h
1066 DWORD WINAPI BuildSecurityDescriptorA(
1067 IN PTRUSTEEA pOwner,
1068 IN PTRUSTEEA pGroup,
1069 IN ULONG cCountOfAccessEntries,
1070 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1071 IN ULONG cCountOfAuditEntries,
1072 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1073 IN PSECURITY_DESCRIPTOR pOldSD,
1074 IN OUT PULONG lpdwBufferLength,
1075 OUT PSECURITY_DESCRIPTOR* pNewSD)
1077 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1078 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1079 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1081 return ERROR_CALL_NOT_IMPLEMENTED;
1084 /******************************************************************************
1085 * BuildSecurityDescriptorW [ADVAPI32.@]
1087 * See BuildSecurityDescriptorA.
1089 DWORD WINAPI BuildSecurityDescriptorW(
1090 IN PTRUSTEEW pOwner,
1091 IN PTRUSTEEW pGroup,
1092 IN ULONG cCountOfAccessEntries,
1093 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1094 IN ULONG cCountOfAuditEntries,
1095 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1096 IN PSECURITY_DESCRIPTOR pOldSD,
1097 IN OUT PULONG lpdwBufferLength,
1098 OUT PSECURITY_DESCRIPTOR* pNewSD)
1100 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1101 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1102 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1104 return ERROR_CALL_NOT_IMPLEMENTED;
1107 /******************************************************************************
1108 * InitializeSecurityDescriptor [ADVAPI32.@]
1110 * PARAMS
1111 * pDescr []
1112 * revision []
1114 BOOL WINAPI
1115 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1117 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1121 /******************************************************************************
1122 * MakeAbsoluteSD [ADVAPI32.@]
1124 BOOL WINAPI MakeAbsoluteSD (
1125 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1126 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1127 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1128 OUT PACL pDacl,
1129 OUT LPDWORD lpdwDaclSize,
1130 OUT PACL pSacl,
1131 OUT LPDWORD lpdwSaclSize,
1132 OUT PSID pOwner,
1133 OUT LPDWORD lpdwOwnerSize,
1134 OUT PSID pPrimaryGroup,
1135 OUT LPDWORD lpdwPrimaryGroupSize)
1137 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1138 pAbsoluteSecurityDescriptor,
1139 lpdwAbsoluteSecurityDescriptorSize,
1140 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1141 pOwner, lpdwOwnerSize,
1142 pPrimaryGroup, lpdwPrimaryGroupSize));
1145 /******************************************************************************
1146 * GetKernelObjectSecurity [ADVAPI32.@]
1148 BOOL WINAPI GetKernelObjectSecurity(
1149 HANDLE Handle,
1150 SECURITY_INFORMATION RequestedInformation,
1151 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1152 DWORD nLength,
1153 LPDWORD lpnLengthNeeded )
1155 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1156 pSecurityDescriptor, nLength, lpnLengthNeeded);
1158 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1159 nLength, lpnLengthNeeded ));
1162 /******************************************************************************
1163 * GetPrivateObjectSecurity [ADVAPI32.@]
1165 BOOL WINAPI GetPrivateObjectSecurity(
1166 PSECURITY_DESCRIPTOR ObjectDescriptor,
1167 SECURITY_INFORMATION SecurityInformation,
1168 PSECURITY_DESCRIPTOR ResultantDescriptor,
1169 DWORD DescriptorLength,
1170 PDWORD ReturnLength )
1172 SECURITY_DESCRIPTOR desc;
1173 BOOL defaulted, present;
1174 PACL pacl;
1175 PSID psid;
1177 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1178 ResultantDescriptor, DescriptorLength, ReturnLength);
1180 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1181 return FALSE;
1183 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1185 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1186 return FALSE;
1187 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1190 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1192 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1193 return FALSE;
1194 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1197 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1199 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1200 return FALSE;
1201 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1204 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1206 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1207 return FALSE;
1208 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1211 *ReturnLength = DescriptorLength;
1212 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1215 /******************************************************************************
1216 * GetSecurityDescriptorLength [ADVAPI32.@]
1218 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1220 return RtlLengthSecurityDescriptor(pDescr);
1223 /******************************************************************************
1224 * GetSecurityDescriptorOwner [ADVAPI32.@]
1226 * PARAMS
1227 * pOwner []
1228 * lpbOwnerDefaulted []
1230 BOOL WINAPI
1231 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1232 LPBOOL lpbOwnerDefaulted )
1234 BOOLEAN defaulted;
1235 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1236 *lpbOwnerDefaulted = defaulted;
1237 return ret;
1240 /******************************************************************************
1241 * SetSecurityDescriptorOwner [ADVAPI32.@]
1243 * PARAMS
1245 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1246 PSID pOwner, BOOL bOwnerDefaulted)
1248 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1250 /******************************************************************************
1251 * GetSecurityDescriptorGroup [ADVAPI32.@]
1253 BOOL WINAPI GetSecurityDescriptorGroup(
1254 PSECURITY_DESCRIPTOR SecurityDescriptor,
1255 PSID *Group,
1256 LPBOOL GroupDefaulted)
1258 BOOLEAN defaulted;
1259 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1260 *GroupDefaulted = defaulted;
1261 return ret;
1263 /******************************************************************************
1264 * SetSecurityDescriptorGroup [ADVAPI32.@]
1266 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1267 PSID Group, BOOL GroupDefaulted)
1269 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1272 /******************************************************************************
1273 * IsValidSecurityDescriptor [ADVAPI32.@]
1275 * PARAMS
1276 * lpsecdesc []
1278 BOOL WINAPI
1279 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1281 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1284 /******************************************************************************
1285 * GetSecurityDescriptorDacl [ADVAPI32.@]
1287 BOOL WINAPI GetSecurityDescriptorDacl(
1288 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1289 OUT LPBOOL lpbDaclPresent,
1290 OUT PACL *pDacl,
1291 OUT LPBOOL lpbDaclDefaulted)
1293 BOOLEAN present, defaulted;
1294 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1295 *lpbDaclPresent = present;
1296 *lpbDaclDefaulted = defaulted;
1297 return ret;
1300 /******************************************************************************
1301 * SetSecurityDescriptorDacl [ADVAPI32.@]
1303 BOOL WINAPI
1304 SetSecurityDescriptorDacl (
1305 PSECURITY_DESCRIPTOR lpsd,
1306 BOOL daclpresent,
1307 PACL dacl,
1308 BOOL dacldefaulted )
1310 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1312 /******************************************************************************
1313 * GetSecurityDescriptorSacl [ADVAPI32.@]
1315 BOOL WINAPI GetSecurityDescriptorSacl(
1316 IN PSECURITY_DESCRIPTOR lpsd,
1317 OUT LPBOOL lpbSaclPresent,
1318 OUT PACL *pSacl,
1319 OUT LPBOOL lpbSaclDefaulted)
1321 BOOLEAN present, defaulted;
1322 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1323 *lpbSaclPresent = present;
1324 *lpbSaclDefaulted = defaulted;
1325 return ret;
1328 /**************************************************************************
1329 * SetSecurityDescriptorSacl [ADVAPI32.@]
1331 BOOL WINAPI SetSecurityDescriptorSacl (
1332 PSECURITY_DESCRIPTOR lpsd,
1333 BOOL saclpresent,
1334 PACL lpsacl,
1335 BOOL sacldefaulted)
1337 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1339 /******************************************************************************
1340 * MakeSelfRelativeSD [ADVAPI32.@]
1342 * PARAMS
1343 * lpabssecdesc []
1344 * lpselfsecdesc []
1345 * lpbuflen []
1347 BOOL WINAPI
1348 MakeSelfRelativeSD(
1349 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1350 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1351 IN OUT LPDWORD lpdwBufferLength)
1353 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1354 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1357 /******************************************************************************
1358 * GetSecurityDescriptorControl [ADVAPI32.@]
1361 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1362 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1364 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1367 /******************************************************************************
1368 * SetSecurityDescriptorControl [ADVAPI32.@]
1370 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1371 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1372 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1374 return set_ntstatus( RtlSetControlSecurityDescriptor(
1375 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1378 /* ##############################
1379 ###### ACL FUNCTIONS ######
1380 ##############################
1383 /*************************************************************************
1384 * InitializeAcl [ADVAPI32.@]
1386 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1388 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1391 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1393 IO_STATUS_BLOCK io_block;
1395 TRACE("(%p)\n", hNamedPipe);
1397 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1398 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1401 /******************************************************************************
1402 * AddAccessAllowedAce [ADVAPI32.@]
1404 BOOL WINAPI AddAccessAllowedAce(
1405 IN OUT PACL pAcl,
1406 IN DWORD dwAceRevision,
1407 IN DWORD AccessMask,
1408 IN PSID pSid)
1410 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1413 /******************************************************************************
1414 * AddAccessAllowedAceEx [ADVAPI32.@]
1416 BOOL WINAPI AddAccessAllowedAceEx(
1417 IN OUT PACL pAcl,
1418 IN DWORD dwAceRevision,
1419 IN DWORD AceFlags,
1420 IN DWORD AccessMask,
1421 IN PSID pSid)
1423 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1426 /******************************************************************************
1427 * AddAccessDeniedAce [ADVAPI32.@]
1429 BOOL WINAPI AddAccessDeniedAce(
1430 IN OUT PACL pAcl,
1431 IN DWORD dwAceRevision,
1432 IN DWORD AccessMask,
1433 IN PSID pSid)
1435 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1438 /******************************************************************************
1439 * AddAccessDeniedAceEx [ADVAPI32.@]
1441 BOOL WINAPI AddAccessDeniedAceEx(
1442 IN OUT PACL pAcl,
1443 IN DWORD dwAceRevision,
1444 IN DWORD AceFlags,
1445 IN DWORD AccessMask,
1446 IN PSID pSid)
1448 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1451 /******************************************************************************
1452 * AddAce [ADVAPI32.@]
1454 BOOL WINAPI AddAce(
1455 IN OUT PACL pAcl,
1456 IN DWORD dwAceRevision,
1457 IN DWORD dwStartingAceIndex,
1458 LPVOID pAceList,
1459 DWORD nAceListLength)
1461 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1464 /******************************************************************************
1465 * DeleteAce [ADVAPI32.@]
1467 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1469 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1472 /******************************************************************************
1473 * FindFirstFreeAce [ADVAPI32.@]
1475 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1477 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1480 /******************************************************************************
1481 * GetAce [ADVAPI32.@]
1483 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1485 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1488 /******************************************************************************
1489 * GetAclInformation [ADVAPI32.@]
1491 BOOL WINAPI GetAclInformation(
1492 PACL pAcl,
1493 LPVOID pAclInformation,
1494 DWORD nAclInformationLength,
1495 ACL_INFORMATION_CLASS dwAclInformationClass)
1497 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1498 nAclInformationLength, dwAclInformationClass));
1501 /******************************************************************************
1502 * IsValidAcl [ADVAPI32.@]
1504 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1506 return RtlValidAcl(pAcl);
1509 /* ##############################
1510 ###### MISC FUNCTIONS ######
1511 ##############################
1514 /******************************************************************************
1515 * AllocateLocallyUniqueId [ADVAPI32.@]
1517 * PARAMS
1518 * lpLuid []
1520 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1522 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1525 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1526 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1527 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1528 { '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 };
1529 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1530 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1531 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1532 { '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 };
1533 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1534 { '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 };
1535 static const WCHAR SE_TCB_NAME_W[] =
1536 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1537 static const WCHAR SE_SECURITY_NAME_W[] =
1538 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1539 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1540 { '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 };
1541 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1542 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1543 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1544 { '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 };
1545 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1546 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1547 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1548 { '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 };
1549 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1550 { '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 };
1551 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1552 { '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 };
1553 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1554 { '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 };
1555 static const WCHAR SE_BACKUP_NAME_W[] =
1556 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1557 static const WCHAR SE_RESTORE_NAME_W[] =
1558 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1559 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1560 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1561 static const WCHAR SE_DEBUG_NAME_W[] =
1562 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1563 static const WCHAR SE_AUDIT_NAME_W[] =
1564 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1565 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1566 { '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 };
1567 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1568 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1569 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1570 { '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 };
1571 static const WCHAR SE_UNDOCK_NAME_W[] =
1572 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1574 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1575 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1576 { '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 };
1577 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1578 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1580 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1581 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1582 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1584 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1586 NULL,
1587 NULL,
1588 SE_CREATE_TOKEN_NAME_W,
1589 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1590 SE_LOCK_MEMORY_NAME_W,
1591 SE_INCREASE_QUOTA_NAME_W,
1592 SE_MACHINE_ACCOUNT_NAME_W,
1593 SE_TCB_NAME_W,
1594 SE_SECURITY_NAME_W,
1595 SE_TAKE_OWNERSHIP_NAME_W,
1596 SE_LOAD_DRIVER_NAME_W,
1597 SE_SYSTEM_PROFILE_NAME_W,
1598 SE_SYSTEMTIME_NAME_W,
1599 SE_PROF_SINGLE_PROCESS_NAME_W,
1600 SE_INC_BASE_PRIORITY_NAME_W,
1601 SE_CREATE_PAGEFILE_NAME_W,
1602 SE_CREATE_PERMANENT_NAME_W,
1603 SE_BACKUP_NAME_W,
1604 SE_RESTORE_NAME_W,
1605 SE_SHUTDOWN_NAME_W,
1606 SE_DEBUG_NAME_W,
1607 SE_AUDIT_NAME_W,
1608 SE_SYSTEM_ENVIRONMENT_NAME_W,
1609 SE_CHANGE_NOTIFY_NAME_W,
1610 SE_REMOTE_SHUTDOWN_NAME_W,
1611 SE_UNDOCK_NAME_W,
1612 SE_SYNC_AGENT_NAME_W,
1613 SE_ENABLE_DELEGATION_NAME_W,
1614 SE_MANAGE_VOLUME_NAME_W,
1615 SE_IMPERSONATE_NAME_W,
1616 SE_CREATE_GLOBAL_NAME_W,
1619 /******************************************************************************
1620 * LookupPrivilegeValueW [ADVAPI32.@]
1622 * See LookupPrivilegeValueA.
1624 BOOL WINAPI
1625 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1627 UINT i;
1629 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1631 if (!ADVAPI_IsLocalComputer(lpSystemName))
1633 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1634 return FALSE;
1636 if (!lpName)
1638 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1639 return FALSE;
1641 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1643 if( !WellKnownPrivNames[i] )
1644 continue;
1645 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1646 continue;
1647 lpLuid->LowPart = i;
1648 lpLuid->HighPart = 0;
1649 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1650 lpLuid->HighPart, lpLuid->LowPart );
1651 return TRUE;
1653 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1654 return FALSE;
1657 /******************************************************************************
1658 * LookupPrivilegeValueA [ADVAPI32.@]
1660 * Retrieves LUID used on a system to represent the privilege name.
1662 * PARAMS
1663 * lpSystemName [I] Name of the system
1664 * lpName [I] Name of the privilege
1665 * lpLuid [O] Destination for the resulting LUID
1667 * RETURNS
1668 * Success: TRUE. lpLuid contains the requested LUID.
1669 * Failure: FALSE.
1671 BOOL WINAPI
1672 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1674 UNICODE_STRING lpSystemNameW;
1675 UNICODE_STRING lpNameW;
1676 BOOL ret;
1678 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1679 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1680 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1681 RtlFreeUnicodeString(&lpNameW);
1682 RtlFreeUnicodeString(&lpSystemNameW);
1683 return ret;
1686 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1687 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1689 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1690 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1692 return FALSE;
1695 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1696 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1698 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1699 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1701 return FALSE;
1704 /******************************************************************************
1705 * LookupPrivilegeNameA [ADVAPI32.@]
1707 * See LookupPrivilegeNameW.
1709 BOOL WINAPI
1710 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1711 LPDWORD cchName)
1713 UNICODE_STRING lpSystemNameW;
1714 BOOL ret;
1715 DWORD wLen = 0;
1717 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1719 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1720 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1721 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1723 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1725 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1726 &wLen);
1727 if (ret)
1729 /* Windows crashes if cchName is NULL, so will I */
1730 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1731 *cchName, NULL, NULL);
1733 if (len == 0)
1735 /* WideCharToMultiByte failed */
1736 ret = FALSE;
1738 else if (len > *cchName)
1740 *cchName = len;
1741 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1742 ret = FALSE;
1744 else
1746 /* WideCharToMultiByte succeeded, output length needs to be
1747 * length not including NULL terminator
1749 *cchName = len - 1;
1752 HeapFree(GetProcessHeap(), 0, lpNameW);
1754 RtlFreeUnicodeString(&lpSystemNameW);
1755 return ret;
1758 /******************************************************************************
1759 * LookupPrivilegeNameW [ADVAPI32.@]
1761 * Retrieves the privilege name referred to by the LUID lpLuid.
1763 * PARAMS
1764 * lpSystemName [I] Name of the system
1765 * lpLuid [I] Privilege value
1766 * lpName [O] Name of the privilege
1767 * cchName [I/O] Number of characters in lpName.
1769 * RETURNS
1770 * Success: TRUE. lpName contains the name of the privilege whose value is
1771 * *lpLuid.
1772 * Failure: FALSE.
1774 * REMARKS
1775 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1776 * using this function.
1777 * If the length of lpName is too small, on return *cchName will contain the
1778 * number of WCHARs needed to contain the privilege, including the NULL
1779 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1780 * On success, *cchName will contain the number of characters stored in
1781 * lpName, NOT including the NULL terminator.
1783 BOOL WINAPI
1784 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1785 LPDWORD cchName)
1787 size_t privNameLen;
1789 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1791 if (!ADVAPI_IsLocalComputer(lpSystemName))
1793 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1794 return FALSE;
1796 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1797 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1799 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1800 return FALSE;
1802 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1803 /* Windows crashes if cchName is NULL, so will I */
1804 if (*cchName <= privNameLen)
1806 *cchName = privNameLen + 1;
1807 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1808 return FALSE;
1810 else
1812 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1813 *cchName = privNameLen;
1814 return TRUE;
1818 /******************************************************************************
1819 * GetFileSecurityA [ADVAPI32.@]
1821 * Obtains Specified information about the security of a file or directory.
1823 * PARAMS
1824 * lpFileName [I] Name of the file to get info for
1825 * RequestedInformation [I] SE_ flags from "winnt.h"
1826 * pSecurityDescriptor [O] Destination for security information
1827 * nLength [I] Length of pSecurityDescriptor
1828 * lpnLengthNeeded [O] Destination for length of returned security information
1830 * RETURNS
1831 * Success: TRUE. pSecurityDescriptor contains the requested information.
1832 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1834 * NOTES
1835 * The information returned is constrained by the callers access rights and
1836 * privileges.
1838 BOOL WINAPI
1839 GetFileSecurityA( LPCSTR lpFileName,
1840 SECURITY_INFORMATION RequestedInformation,
1841 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1842 DWORD nLength, LPDWORD lpnLengthNeeded )
1844 DWORD len;
1845 BOOL r;
1846 LPWSTR name = NULL;
1848 if( lpFileName )
1850 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1851 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1852 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1855 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1856 nLength, lpnLengthNeeded );
1857 HeapFree( GetProcessHeap(), 0, name );
1859 return r;
1862 /******************************************************************************
1863 * GetFileSecurityW [ADVAPI32.@]
1865 * See GetFileSecurityA.
1867 BOOL WINAPI
1868 GetFileSecurityW( LPCWSTR lpFileName,
1869 SECURITY_INFORMATION RequestedInformation,
1870 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1871 DWORD nLength, LPDWORD lpnLengthNeeded )
1873 HANDLE hfile;
1874 NTSTATUS status;
1875 DWORD access = 0;
1877 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1878 DACL_SECURITY_INFORMATION))
1879 access |= READ_CONTROL;
1880 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1881 access |= ACCESS_SYSTEM_SECURITY;
1883 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1884 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1885 if ( hfile == INVALID_HANDLE_VALUE )
1886 return FALSE;
1888 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1889 nLength, lpnLengthNeeded );
1890 CloseHandle( hfile );
1891 return set_ntstatus( status );
1895 /******************************************************************************
1896 * LookupAccountSidA [ADVAPI32.@]
1898 BOOL WINAPI
1899 LookupAccountSidA(
1900 IN LPCSTR system,
1901 IN PSID sid,
1902 OUT LPSTR account,
1903 IN OUT LPDWORD accountSize,
1904 OUT LPSTR domain,
1905 IN OUT LPDWORD domainSize,
1906 OUT PSID_NAME_USE name_use )
1908 DWORD len;
1909 BOOL r;
1910 LPWSTR systemW = NULL;
1911 LPWSTR accountW = NULL;
1912 LPWSTR domainW = NULL;
1913 DWORD accountSizeW = *accountSize;
1914 DWORD domainSizeW = *domainSize;
1916 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1917 debugstr_a(system),debugstr_sid(sid),
1918 account,accountSize,accountSize?*accountSize:0,
1919 domain,domainSize,domainSize?*domainSize:0,
1920 name_use);
1922 if (system) {
1923 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1924 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1925 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1927 if (account)
1928 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1929 if (domain)
1930 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1932 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1934 if (r) {
1935 if (accountW && *accountSize) {
1936 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1937 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1938 *accountSize = len;
1939 } else
1940 *accountSize = accountSizeW + 1;
1942 if (domainW && *domainSize) {
1943 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1944 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1945 *domainSize = len;
1946 } else
1947 *domainSize = domainSizeW + 1;
1950 HeapFree( GetProcessHeap(), 0, systemW );
1951 HeapFree( GetProcessHeap(), 0, accountW );
1952 HeapFree( GetProcessHeap(), 0, domainW );
1954 return r;
1957 /******************************************************************************
1958 * LookupAccountSidW [ADVAPI32.@]
1960 * PARAMS
1961 * system []
1962 * sid []
1963 * account []
1964 * accountSize []
1965 * domain []
1966 * domainSize []
1967 * name_use []
1970 BOOL WINAPI
1971 LookupAccountSidW(
1972 IN LPCWSTR system,
1973 IN PSID sid,
1974 OUT LPWSTR account,
1975 IN OUT LPDWORD accountSize,
1976 OUT LPWSTR domain,
1977 IN OUT LPDWORD domainSize,
1978 OUT PSID_NAME_USE name_use )
1980 unsigned int i, j;
1981 const WCHAR * ac = NULL;
1982 const WCHAR * dm = NULL;
1983 SID_NAME_USE use = 0;
1984 LPWSTR computer_name = NULL;
1986 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1987 debugstr_w(system),debugstr_sid(sid),
1988 account,accountSize,accountSize?*accountSize:0,
1989 domain,domainSize,domainSize?*domainSize:0,
1990 name_use);
1992 if (!ADVAPI_IsLocalComputer(system)) {
1993 FIXME("Only local computer supported!\n");
1994 SetLastError(ERROR_NONE_MAPPED);
1995 return FALSE;
1998 /* check the well known SIDs first */
1999 for (i = 0; i <= 60; i++) {
2000 if (IsWellKnownSid(sid, i)) {
2001 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2002 if (ACCOUNT_SIDS[j].type == i) {
2003 ac = ACCOUNT_SIDS[j].account;
2004 dm = ACCOUNT_SIDS[j].domain;
2005 use = ACCOUNT_SIDS[j].name_use;
2008 break;
2012 if (dm == NULL) {
2013 MAX_SID local;
2015 /* check for the local computer next */
2016 if (ADVAPI_GetComputerSid(&local)) {
2017 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2018 BOOL result;
2020 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2021 result = GetComputerNameW(computer_name, &size);
2023 if (result) {
2024 if (EqualSid(sid, &local)) {
2025 dm = computer_name;
2026 ac = Blank;
2027 use = 3;
2028 } else {
2029 local.SubAuthorityCount++;
2031 if (EqualPrefixSid(sid, &local)) {
2032 dm = computer_name;
2033 use = 1;
2034 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2035 case DOMAIN_USER_RID_ADMIN:
2036 ac = Administrator;
2037 break;
2038 case DOMAIN_USER_RID_GUEST:
2039 ac = Guest;
2040 break;
2041 case DOMAIN_GROUP_RID_ADMINS:
2042 ac = Domain_Admins;
2043 break;
2044 case DOMAIN_GROUP_RID_USERS:
2045 ac = Domain_Users;
2046 break;
2047 case DOMAIN_GROUP_RID_GUESTS:
2048 ac = Domain_Guests;
2049 break;
2050 case DOMAIN_GROUP_RID_COMPUTERS:
2051 ac = Domain_Computers;
2052 break;
2053 case DOMAIN_GROUP_RID_CONTROLLERS:
2054 ac = Domain_Controllers;
2055 break;
2056 case DOMAIN_GROUP_RID_CERT_ADMINS:
2057 ac = Cert_Publishers;
2058 break;
2059 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2060 ac = Schema_Admins;
2061 break;
2062 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2063 ac = Enterprise_Admins;
2064 break;
2065 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2066 ac = Group_Policy_Creator_Owners;
2067 break;
2068 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2069 ac = RAS_and_IAS_Servers;
2070 break;
2071 default:
2072 dm = NULL;
2073 break;
2081 if (dm) {
2082 BOOL status = TRUE;
2083 if (*accountSize > lstrlenW(ac)) {
2084 if (account)
2085 lstrcpyW(account, ac);
2087 if (*domainSize > lstrlenW(dm)) {
2088 if (domain)
2089 lstrcpyW(domain, dm);
2091 if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
2092 ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
2093 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2094 status = FALSE;
2096 if (*domainSize)
2097 *domainSize = strlenW(dm);
2098 else
2099 *domainSize = strlenW(dm) + 1;
2100 if (*accountSize)
2101 *accountSize = strlenW(ac);
2102 else
2103 *accountSize = strlenW(ac) + 1;
2104 *name_use = use;
2105 HeapFree(GetProcessHeap(), 0, computer_name);
2106 return status;
2109 HeapFree(GetProcessHeap(), 0, computer_name);
2110 SetLastError(ERROR_NONE_MAPPED);
2111 return FALSE;
2114 /******************************************************************************
2115 * SetFileSecurityA [ADVAPI32.@]
2117 * See SetFileSecurityW.
2119 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2120 SECURITY_INFORMATION RequestedInformation,
2121 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2123 DWORD len;
2124 BOOL r;
2125 LPWSTR name = NULL;
2127 if( lpFileName )
2129 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2130 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2131 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2134 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2135 HeapFree( GetProcessHeap(), 0, name );
2137 return r;
2140 /******************************************************************************
2141 * SetFileSecurityW [ADVAPI32.@]
2143 * Sets the security of a file or directory.
2145 * PARAMS
2146 * lpFileName []
2147 * RequestedInformation []
2148 * pSecurityDescriptor []
2150 * RETURNS
2151 * Success: TRUE.
2152 * Failure: FALSE.
2154 BOOL WINAPI
2155 SetFileSecurityW( LPCWSTR lpFileName,
2156 SECURITY_INFORMATION RequestedInformation,
2157 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2159 HANDLE file;
2160 DWORD access = 0;
2161 NTSTATUS status;
2163 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2164 pSecurityDescriptor );
2166 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2167 RequestedInformation & GROUP_SECURITY_INFORMATION)
2168 access |= WRITE_OWNER;
2169 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2170 access |= ACCESS_SYSTEM_SECURITY;
2171 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2172 access |= WRITE_DAC;
2174 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2175 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2176 if (file == INVALID_HANDLE_VALUE)
2177 return FALSE;
2179 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2180 CloseHandle( file );
2181 return set_ntstatus( status );
2184 /******************************************************************************
2185 * QueryWindows31FilesMigration [ADVAPI32.@]
2187 * PARAMS
2188 * x1 []
2190 BOOL WINAPI
2191 QueryWindows31FilesMigration( DWORD x1 )
2193 FIXME("(%d):stub\n",x1);
2194 return TRUE;
2197 /******************************************************************************
2198 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2200 * PARAMS
2201 * x1 []
2202 * x2 []
2203 * x3 []
2204 * x4 []
2206 BOOL WINAPI
2207 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2208 DWORD x4 )
2210 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2211 return TRUE;
2214 /******************************************************************************
2215 * NotifyBootConfigStatus [ADVAPI32.@]
2217 * PARAMS
2218 * x1 []
2220 BOOL WINAPI
2221 NotifyBootConfigStatus( BOOL x1 )
2223 FIXME("(0x%08d):stub\n",x1);
2224 return 1;
2227 /******************************************************************************
2228 * RevertToSelf [ADVAPI32.@]
2230 * Ends the impersonation of a user.
2232 * PARAMS
2233 * void []
2235 * RETURNS
2236 * Success: TRUE.
2237 * Failure: FALSE.
2239 BOOL WINAPI
2240 RevertToSelf( void )
2242 HANDLE Token = NULL;
2243 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2244 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2247 /******************************************************************************
2248 * ImpersonateSelf [ADVAPI32.@]
2250 * Makes an impersonation token that represents the process user and assigns
2251 * to the current thread.
2253 * PARAMS
2254 * ImpersonationLevel [I] Level at which to impersonate.
2256 * RETURNS
2257 * Success: TRUE.
2258 * Failure: FALSE.
2260 BOOL WINAPI
2261 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2263 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2266 /******************************************************************************
2267 * ImpersonateLoggedOnUser [ADVAPI32.@]
2269 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2271 DWORD size;
2272 NTSTATUS Status;
2273 HANDLE ImpersonationToken;
2274 TOKEN_TYPE Type;
2276 FIXME( "(%p)\n", hToken );
2278 if (!GetTokenInformation( hToken, TokenType, &Type,
2279 sizeof(TOKEN_TYPE), &size ))
2280 return FALSE;
2282 if (Type == TokenPrimary)
2284 OBJECT_ATTRIBUTES ObjectAttributes;
2286 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2288 Status = NtDuplicateToken( hToken,
2289 TOKEN_IMPERSONATE | TOKEN_QUERY,
2290 &ObjectAttributes,
2291 SecurityImpersonation,
2292 TokenImpersonation,
2293 &ImpersonationToken );
2294 if (Status != STATUS_SUCCESS)
2296 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2297 SetLastError( RtlNtStatusToDosError( Status ) );
2298 return FALSE;
2301 else
2302 ImpersonationToken = hToken;
2304 Status = NtSetInformationThread( GetCurrentThread(),
2305 ThreadImpersonationToken,
2306 &ImpersonationToken,
2307 sizeof(ImpersonationToken) );
2309 if (Type == TokenPrimary)
2310 NtClose( ImpersonationToken );
2312 if (Status != STATUS_SUCCESS)
2314 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2315 SetLastError( RtlNtStatusToDosError( Status ) );
2316 return FALSE;
2319 return TRUE;
2322 /******************************************************************************
2323 * AccessCheck [ADVAPI32.@]
2325 BOOL WINAPI
2326 AccessCheck(
2327 PSECURITY_DESCRIPTOR SecurityDescriptor,
2328 HANDLE ClientToken,
2329 DWORD DesiredAccess,
2330 PGENERIC_MAPPING GenericMapping,
2331 PPRIVILEGE_SET PrivilegeSet,
2332 LPDWORD PrivilegeSetLength,
2333 LPDWORD GrantedAccess,
2334 LPBOOL AccessStatus)
2336 NTSTATUS access_status;
2337 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2338 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2339 GrantedAccess, &access_status) );
2340 if (ret) *AccessStatus = set_ntstatus( access_status );
2341 return ret;
2345 /******************************************************************************
2346 * AccessCheckByType [ADVAPI32.@]
2348 BOOL WINAPI AccessCheckByType(
2349 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2350 PSID PrincipalSelfSid,
2351 HANDLE ClientToken,
2352 DWORD DesiredAccess,
2353 POBJECT_TYPE_LIST ObjectTypeList,
2354 DWORD ObjectTypeListLength,
2355 PGENERIC_MAPPING GenericMapping,
2356 PPRIVILEGE_SET PrivilegeSet,
2357 LPDWORD PrivilegeSetLength,
2358 LPDWORD GrantedAccess,
2359 LPBOOL AccessStatus)
2361 FIXME("stub\n");
2363 *AccessStatus = TRUE;
2365 return !*AccessStatus;
2368 /******************************************************************************
2369 * MapGenericMask [ADVAPI32.@]
2371 * Maps generic access rights into specific access rights according to the
2372 * supplied mapping.
2374 * PARAMS
2375 * AccessMask [I/O] Access rights.
2376 * GenericMapping [I] The mapping between generic and specific rights.
2378 * RETURNS
2379 * Nothing.
2381 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2383 RtlMapGenericMask( AccessMask, GenericMapping );
2386 /*************************************************************************
2387 * SetKernelObjectSecurity [ADVAPI32.@]
2389 BOOL WINAPI SetKernelObjectSecurity (
2390 IN HANDLE Handle,
2391 IN SECURITY_INFORMATION SecurityInformation,
2392 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2394 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2398 /******************************************************************************
2399 * AddAuditAccessAce [ADVAPI32.@]
2401 BOOL WINAPI AddAuditAccessAce(
2402 IN OUT PACL pAcl,
2403 IN DWORD dwAceRevision,
2404 IN DWORD dwAccessMask,
2405 IN PSID pSid,
2406 IN BOOL bAuditSuccess,
2407 IN BOOL bAuditFailure)
2409 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2410 bAuditSuccess, bAuditFailure) );
2413 /******************************************************************************
2414 * AddAuditAccessAce [ADVAPI32.@]
2416 BOOL WINAPI AddAuditAccessAceEx(
2417 IN OUT PACL pAcl,
2418 IN DWORD dwAceRevision,
2419 IN DWORD dwAceFlags,
2420 IN DWORD dwAccessMask,
2421 IN PSID pSid,
2422 IN BOOL bAuditSuccess,
2423 IN BOOL bAuditFailure)
2425 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2426 bAuditSuccess, bAuditFailure) );
2429 /******************************************************************************
2430 * LookupAccountNameA [ADVAPI32.@]
2432 BOOL WINAPI
2433 LookupAccountNameA(
2434 IN LPCSTR system,
2435 IN LPCSTR account,
2436 OUT PSID sid,
2437 OUT LPDWORD cbSid,
2438 LPSTR ReferencedDomainName,
2439 IN OUT LPDWORD cbReferencedDomainName,
2440 OUT PSID_NAME_USE name_use )
2442 BOOL ret;
2443 UNICODE_STRING lpSystemW;
2444 UNICODE_STRING lpAccountW;
2445 LPWSTR lpReferencedDomainNameW = NULL;
2447 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2448 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2450 if (ReferencedDomainName)
2451 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2453 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2454 cbReferencedDomainName, name_use);
2456 if (ret && lpReferencedDomainNameW)
2458 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2459 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2462 RtlFreeUnicodeString(&lpSystemW);
2463 RtlFreeUnicodeString(&lpAccountW);
2464 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2466 return ret;
2469 /******************************************************************************
2470 * LookupAccountNameW [ADVAPI32.@]
2472 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2473 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2474 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2476 /* Default implementation: Always return a default SID */
2477 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2478 BOOL ret;
2479 PSID pSid;
2480 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2481 unsigned int i;
2483 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2484 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2486 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2488 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2490 if (*cchReferencedDomainName)
2491 *ReferencedDomainName = '\0';
2492 *cchReferencedDomainName = 0;
2493 *peUse = SidTypeWellKnownGroup;
2494 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
2498 ret = AllocateAndInitializeSid(&identifierAuthority,
2500 SECURITY_BUILTIN_DOMAIN_RID,
2501 DOMAIN_ALIAS_RID_ADMINS,
2502 0, 0, 0, 0, 0, 0,
2503 &pSid);
2505 if (!ret)
2506 return FALSE;
2508 if (!RtlValidSid(pSid))
2510 FreeSid(pSid);
2511 return FALSE;
2514 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2515 CopySid(*cbSid, Sid, pSid);
2516 if (*cbSid < GetLengthSid(pSid))
2518 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2519 ret = FALSE;
2521 *cbSid = GetLengthSid(pSid);
2523 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2524 strcpyW(ReferencedDomainName, dm);
2526 if (*cchReferencedDomainName <= strlenW(dm))
2528 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2529 ret = FALSE;
2532 *cchReferencedDomainName = strlenW(dm)+1;
2534 FreeSid(pSid);
2536 return ret;
2539 /******************************************************************************
2540 * PrivilegeCheck [ADVAPI32.@]
2542 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2544 BOOL ret;
2545 BOOLEAN Result;
2547 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2549 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2550 if (ret)
2551 *pfResult = Result;
2552 return ret;
2555 /******************************************************************************
2556 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2558 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2559 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2560 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2561 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2563 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2564 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2565 SecurityDescriptor, DesiredAccess, GenericMapping,
2566 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2567 return TRUE;
2570 /******************************************************************************
2571 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2573 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2574 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2575 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2576 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2578 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2579 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2580 SecurityDescriptor, DesiredAccess, GenericMapping,
2581 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2582 return TRUE;
2585 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2587 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2589 return TRUE;
2592 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2594 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2596 return TRUE;
2599 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2601 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2603 return TRUE;
2606 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2607 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2608 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2609 LPBOOL GenerateOnClose)
2611 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2612 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2613 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2614 GenerateOnClose);
2616 return TRUE;
2619 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2620 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2621 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2622 LPBOOL GenerateOnClose)
2624 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2625 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2626 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2627 GenerateOnClose);
2629 return TRUE;
2632 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2633 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2635 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2636 DesiredAccess, Privileges, AccessGranted);
2638 return TRUE;
2641 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2642 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2644 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2645 DesiredAccess, Privileges, AccessGranted);
2647 return TRUE;
2650 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2651 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2653 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2654 ClientToken, Privileges, AccessGranted);
2656 return TRUE;
2659 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2660 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2662 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2663 ClientToken, Privileges, AccessGranted);
2665 return TRUE;
2668 /******************************************************************************
2669 * GetSecurityInfo [ADVAPI32.@]
2671 DWORD WINAPI GetSecurityInfo(
2672 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2673 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2674 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2675 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2678 FIXME("stub!\n");
2679 return ERROR_BAD_PROVIDER;
2682 /******************************************************************************
2683 * GetSecurityInfoExW [ADVAPI32.@]
2685 DWORD WINAPI GetSecurityInfoExW(
2686 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2687 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2688 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2689 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2692 FIXME("stub!\n");
2693 return ERROR_BAD_PROVIDER;
2696 /******************************************************************************
2697 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2699 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2700 LPSTR pTrusteeName, DWORD AccessPermissions,
2701 ACCESS_MODE AccessMode, DWORD Inheritance )
2703 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2704 AccessPermissions, AccessMode, Inheritance);
2706 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2707 pExplicitAccess->grfAccessMode = AccessMode;
2708 pExplicitAccess->grfInheritance = Inheritance;
2710 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2711 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2712 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2713 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2714 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2717 /******************************************************************************
2718 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2720 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2721 LPWSTR pTrusteeName, DWORD AccessPermissions,
2722 ACCESS_MODE AccessMode, DWORD Inheritance )
2724 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2725 AccessPermissions, AccessMode, Inheritance);
2727 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2728 pExplicitAccess->grfAccessMode = AccessMode;
2729 pExplicitAccess->grfInheritance = Inheritance;
2731 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2732 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2733 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2734 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2735 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2738 /******************************************************************************
2739 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2741 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2742 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2743 LPSTR InheritedObjectTypeName, LPSTR Name )
2745 DWORD ObjectsPresent = 0;
2747 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2748 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2750 /* Fill the OBJECTS_AND_NAME structure */
2751 pObjName->ObjectType = ObjectType;
2752 if (ObjectTypeName != NULL)
2754 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2757 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2758 if (InheritedObjectTypeName != NULL)
2760 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2763 pObjName->ObjectsPresent = ObjectsPresent;
2764 pObjName->ptstrName = Name;
2766 /* Fill the TRUSTEE structure */
2767 pTrustee->pMultipleTrustee = NULL;
2768 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2769 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2770 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2771 pTrustee->ptstrName = (LPSTR)pObjName;
2774 /******************************************************************************
2775 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2777 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2778 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2779 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2781 DWORD ObjectsPresent = 0;
2783 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2784 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2786 /* Fill the OBJECTS_AND_NAME structure */
2787 pObjName->ObjectType = ObjectType;
2788 if (ObjectTypeName != NULL)
2790 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2793 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2794 if (InheritedObjectTypeName != NULL)
2796 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2799 pObjName->ObjectsPresent = ObjectsPresent;
2800 pObjName->ptstrName = Name;
2802 /* Fill the TRUSTEE structure */
2803 pTrustee->pMultipleTrustee = NULL;
2804 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2805 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2806 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2807 pTrustee->ptstrName = (LPWSTR)pObjName;
2810 /******************************************************************************
2811 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2813 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2814 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2816 DWORD ObjectsPresent = 0;
2818 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2820 /* Fill the OBJECTS_AND_SID structure */
2821 if (pObjectGuid != NULL)
2823 pObjSid->ObjectTypeGuid = *pObjectGuid;
2824 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2826 else
2828 ZeroMemory(&pObjSid->ObjectTypeGuid,
2829 sizeof(GUID));
2832 if (pInheritedObjectGuid != NULL)
2834 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2835 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2837 else
2839 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2840 sizeof(GUID));
2843 pObjSid->ObjectsPresent = ObjectsPresent;
2844 pObjSid->pSid = pSid;
2846 /* Fill the TRUSTEE structure */
2847 pTrustee->pMultipleTrustee = NULL;
2848 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2849 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2850 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2851 pTrustee->ptstrName = (LPSTR) pObjSid;
2854 /******************************************************************************
2855 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2857 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2858 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2860 DWORD ObjectsPresent = 0;
2862 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2864 /* Fill the OBJECTS_AND_SID structure */
2865 if (pObjectGuid != NULL)
2867 pObjSid->ObjectTypeGuid = *pObjectGuid;
2868 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2870 else
2872 ZeroMemory(&pObjSid->ObjectTypeGuid,
2873 sizeof(GUID));
2876 if (pInheritedObjectGuid != NULL)
2878 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2879 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2881 else
2883 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2884 sizeof(GUID));
2887 pObjSid->ObjectsPresent = ObjectsPresent;
2888 pObjSid->pSid = pSid;
2890 /* Fill the TRUSTEE structure */
2891 pTrustee->pMultipleTrustee = NULL;
2892 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2893 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2894 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2895 pTrustee->ptstrName = (LPWSTR) pObjSid;
2898 /******************************************************************************
2899 * BuildTrusteeWithSidA [ADVAPI32.@]
2901 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2903 TRACE("%p %p\n", pTrustee, pSid);
2905 pTrustee->pMultipleTrustee = NULL;
2906 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2907 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2908 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2909 pTrustee->ptstrName = (LPSTR) pSid;
2912 /******************************************************************************
2913 * BuildTrusteeWithSidW [ADVAPI32.@]
2915 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2917 TRACE("%p %p\n", pTrustee, pSid);
2919 pTrustee->pMultipleTrustee = NULL;
2920 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2921 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2922 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2923 pTrustee->ptstrName = (LPWSTR) pSid;
2926 /******************************************************************************
2927 * BuildTrusteeWithNameA [ADVAPI32.@]
2929 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2931 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2933 pTrustee->pMultipleTrustee = NULL;
2934 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2935 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2936 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2937 pTrustee->ptstrName = name;
2940 /******************************************************************************
2941 * BuildTrusteeWithNameW [ADVAPI32.@]
2943 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2945 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2947 pTrustee->pMultipleTrustee = NULL;
2948 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2949 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2950 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2951 pTrustee->ptstrName = name;
2954 /******************************************************************************
2955 * GetTrusteeFormA [ADVAPI32.@]
2957 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2959 TRACE("(%p)\n", pTrustee);
2961 if (!pTrustee)
2962 return TRUSTEE_BAD_FORM;
2964 return pTrustee->TrusteeForm;
2967 /******************************************************************************
2968 * GetTrusteeFormW [ADVAPI32.@]
2970 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2972 TRACE("(%p)\n", pTrustee);
2974 if (!pTrustee)
2975 return TRUSTEE_BAD_FORM;
2977 return pTrustee->TrusteeForm;
2980 /******************************************************************************
2981 * GetTrusteeNameA [ADVAPI32.@]
2983 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2985 TRACE("(%p)\n", pTrustee);
2987 if (!pTrustee)
2988 return NULL;
2990 return pTrustee->ptstrName;
2993 /******************************************************************************
2994 * GetTrusteeNameW [ADVAPI32.@]
2996 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2998 TRACE("(%p)\n", pTrustee);
3000 if (!pTrustee)
3001 return NULL;
3003 return pTrustee->ptstrName;
3006 /******************************************************************************
3007 * GetTrusteeTypeA [ADVAPI32.@]
3009 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3011 TRACE("(%p)\n", pTrustee);
3013 if (!pTrustee)
3014 return TRUSTEE_IS_UNKNOWN;
3016 return pTrustee->TrusteeType;
3019 /******************************************************************************
3020 * GetTrusteeTypeW [ADVAPI32.@]
3022 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3024 TRACE("(%p)\n", pTrustee);
3026 if (!pTrustee)
3027 return TRUSTEE_IS_UNKNOWN;
3029 return pTrustee->TrusteeType;
3032 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3033 DWORD nAclInformationLength,
3034 ACL_INFORMATION_CLASS dwAclInformationClass )
3036 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3037 nAclInformationLength, dwAclInformationClass);
3039 return TRUE;
3042 /******************************************************************************
3043 * SetEntriesInAclA [ADVAPI32.@]
3045 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3046 PACL OldAcl, PACL* NewAcl )
3048 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3049 *NewAcl = NULL;
3050 return ERROR_SUCCESS;
3053 /******************************************************************************
3054 * SetEntriesInAclW [ADVAPI32.@]
3056 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3057 PACL OldAcl, PACL* NewAcl )
3059 ULONG i;
3060 PSID *ppsid;
3061 DWORD ret = ERROR_SUCCESS;
3062 DWORD acl_size = sizeof(ACL);
3063 NTSTATUS status;
3065 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3067 *NewAcl = NULL;
3069 if (!count && !OldAcl)
3070 return ERROR_SUCCESS;
3072 /* allocate array of maximum sized sids allowed */
3073 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3074 if (!ppsid)
3075 return ERROR_OUTOFMEMORY;
3077 for (i = 0; i < count; i++)
3079 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3081 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3082 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3083 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3084 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3085 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3086 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3087 pEntries[i].Trustee.ptstrName);
3089 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3091 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3092 ret = ERROR_INVALID_PARAMETER;
3093 goto exit;
3096 switch (pEntries[i].Trustee.TrusteeForm)
3098 case TRUSTEE_IS_SID:
3099 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3100 ppsid[i], pEntries[i].Trustee.ptstrName))
3102 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3103 ret = ERROR_INVALID_PARAMETER;
3104 goto exit;
3106 break;
3107 case TRUSTEE_IS_NAME:
3109 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3110 DWORD domain_size = 0;
3111 SID_NAME_USE use;
3112 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3114 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3115 ret = ERROR_INVALID_PARAMETER;
3116 goto exit;
3118 break;
3120 case TRUSTEE_IS_OBJECTS_AND_SID:
3121 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3122 break;
3123 case TRUSTEE_IS_OBJECTS_AND_NAME:
3124 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3125 break;
3126 default:
3127 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3128 ret = ERROR_INVALID_PARAMETER;
3129 goto exit;
3132 /* Note: we overestimate the ACL size here as a tradeoff between
3133 * instructions (simplicity) and memory */
3134 switch (pEntries[i].grfAccessMode)
3136 case GRANT_ACCESS:
3137 case SET_ACCESS:
3138 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3139 break;
3140 case DENY_ACCESS:
3141 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3142 break;
3143 case SET_AUDIT_SUCCESS:
3144 case SET_AUDIT_FAILURE:
3145 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3146 break;
3147 case REVOKE_ACCESS:
3148 break;
3149 default:
3150 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3151 ret = ERROR_INVALID_PARAMETER;
3152 goto exit;
3156 if (OldAcl)
3158 ACL_SIZE_INFORMATION size_info;
3160 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3161 if (status != STATUS_SUCCESS)
3163 ret = RtlNtStatusToDosError(status);
3164 goto exit;
3166 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3169 *NewAcl = LocalAlloc(0, acl_size);
3170 if (!*NewAcl)
3172 ret = ERROR_OUTOFMEMORY;
3173 goto exit;
3176 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3177 if (status != STATUS_SUCCESS)
3179 ret = RtlNtStatusToDosError(status);
3180 goto exit;
3183 for (i = 0; i < count; i++)
3185 switch (pEntries[i].grfAccessMode)
3187 case GRANT_ACCESS:
3188 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3189 pEntries[i].grfInheritance,
3190 pEntries[i].grfAccessPermissions,
3191 ppsid[i]);
3192 break;
3193 case SET_ACCESS:
3195 ULONG j;
3196 BOOL add = TRUE;
3197 if (OldAcl)
3199 for (j = 0; ; j++)
3201 const ACE_HEADER *existing_ace_header;
3202 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3203 if (status != STATUS_SUCCESS)
3204 break;
3205 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3206 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3207 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3209 add = FALSE;
3210 break;
3214 if (add)
3215 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3216 pEntries[i].grfInheritance,
3217 pEntries[i].grfAccessPermissions,
3218 ppsid[i]);
3219 break;
3221 case DENY_ACCESS:
3222 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3223 pEntries[i].grfInheritance,
3224 pEntries[i].grfAccessPermissions,
3225 ppsid[i]);
3226 break;
3227 case SET_AUDIT_SUCCESS:
3228 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3229 pEntries[i].grfInheritance,
3230 pEntries[i].grfAccessPermissions,
3231 ppsid[i], TRUE, FALSE);
3232 break;
3233 case SET_AUDIT_FAILURE:
3234 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3235 pEntries[i].grfInheritance,
3236 pEntries[i].grfAccessPermissions,
3237 ppsid[i], FALSE, TRUE);
3238 break;
3239 default:
3240 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3244 if (OldAcl)
3246 for (i = 0; ; i++)
3248 BOOL add = TRUE;
3249 ULONG j;
3250 const ACE_HEADER *old_ace_header;
3251 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3252 if (status != STATUS_SUCCESS) break;
3253 for (j = 0; j < count; j++)
3255 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3256 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3257 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3259 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3260 add = FALSE;
3261 break;
3263 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3265 switch (old_ace_header->AceType)
3267 case ACCESS_ALLOWED_ACE_TYPE:
3268 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3269 add = FALSE;
3270 break;
3271 case ACCESS_DENIED_ACE_TYPE:
3272 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3273 add = FALSE;
3274 break;
3275 case SYSTEM_AUDIT_ACE_TYPE:
3276 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3277 add = FALSE;
3278 break;
3279 case SYSTEM_ALARM_ACE_TYPE:
3280 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3281 add = FALSE;
3282 break;
3283 default:
3284 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3287 if (!add)
3288 break;
3291 if (add)
3292 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3293 if (status != STATUS_SUCCESS)
3295 WARN("RtlAddAce failed with error 0x%08x\n", status);
3296 ret = RtlNtStatusToDosError(status);
3297 break;
3302 exit:
3303 HeapFree(GetProcessHeap(), 0, ppsid);
3304 return ret;
3307 /******************************************************************************
3308 * SetNamedSecurityInfoA [ADVAPI32.@]
3310 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3311 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3312 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3314 DWORD len;
3315 LPWSTR wstr = NULL;
3316 DWORD r;
3318 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3319 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3321 if( pObjectName )
3323 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3324 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3325 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3328 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3329 psidGroup, pDacl, pSacl );
3331 HeapFree( GetProcessHeap(), 0, wstr );
3333 return r;
3336 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3337 PSECURITY_DESCRIPTOR ModificationDescriptor,
3338 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3339 PGENERIC_MAPPING GenericMapping,
3340 HANDLE Token )
3342 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3343 ObjectsSecurityDescriptor, GenericMapping, Token);
3345 return TRUE;
3348 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3350 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3353 /******************************************************************************
3354 * AreAnyAccessesGranted [ADVAPI32.@]
3356 * Determines whether or not any of a set of specified access permissions have
3357 * been granted or not.
3359 * PARAMS
3360 * GrantedAccess [I] The permissions that have been granted.
3361 * DesiredAccess [I] The permissions that you want to have.
3363 * RETURNS
3364 * Nonzero if any of the permissions have been granted, zero if none of the
3365 * permissions have been granted.
3368 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3370 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3373 /******************************************************************************
3374 * SetNamedSecurityInfoW [ADVAPI32.@]
3376 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3377 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3378 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3380 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3381 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3382 return ERROR_SUCCESS;
3385 /******************************************************************************
3386 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3388 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3389 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3391 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3392 return ERROR_CALL_NOT_IMPLEMENTED;
3395 /******************************************************************************
3396 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3398 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3399 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3401 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3402 return ERROR_CALL_NOT_IMPLEMENTED;
3406 /******************************************************************************
3407 * ParseAclStringFlags
3409 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3411 DWORD flags = 0;
3412 LPCWSTR szAcl = *StringAcl;
3414 while (*szAcl != '(')
3416 if (*szAcl == 'P')
3418 flags |= SE_DACL_PROTECTED;
3420 else if (*szAcl == 'A')
3422 szAcl++;
3423 if (*szAcl == 'R')
3424 flags |= SE_DACL_AUTO_INHERIT_REQ;
3425 else if (*szAcl == 'I')
3426 flags |= SE_DACL_AUTO_INHERITED;
3428 szAcl++;
3431 *StringAcl = szAcl;
3432 return flags;
3435 /******************************************************************************
3436 * ParseAceStringType
3438 static const ACEFLAG AceType[] =
3440 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3441 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3442 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3443 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3445 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3446 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3447 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3448 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3450 { NULL, 0 },
3453 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3455 UINT len = 0;
3456 LPCWSTR szAcl = *StringAcl;
3457 const ACEFLAG *lpaf = AceType;
3459 while (lpaf->wstr &&
3460 (len = strlenW(lpaf->wstr)) &&
3461 strncmpW(lpaf->wstr, szAcl, len))
3462 lpaf++;
3464 if (!lpaf->wstr)
3465 return 0;
3467 *StringAcl += len;
3468 return lpaf->value;
3472 /******************************************************************************
3473 * ParseAceStringFlags
3475 static const ACEFLAG AceFlags[] =
3477 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3478 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3479 { SDDL_INHERITED, INHERITED_ACE },
3480 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3481 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3482 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3483 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3484 { NULL, 0 },
3487 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3489 UINT len = 0;
3490 BYTE flags = 0;
3491 LPCWSTR szAcl = *StringAcl;
3493 while (*szAcl != ';')
3495 const ACEFLAG *lpaf = AceFlags;
3497 while (lpaf->wstr &&
3498 (len = strlenW(lpaf->wstr)) &&
3499 strncmpW(lpaf->wstr, szAcl, len))
3500 lpaf++;
3502 if (!lpaf->wstr)
3503 return 0;
3505 flags |= lpaf->value;
3506 szAcl += len;
3509 *StringAcl = szAcl;
3510 return flags;
3514 /******************************************************************************
3515 * ParseAceStringRights
3517 static const ACEFLAG AceRights[] =
3519 { SDDL_GENERIC_ALL, GENERIC_ALL },
3520 { SDDL_GENERIC_READ, GENERIC_READ },
3521 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3522 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3524 { SDDL_READ_CONTROL, READ_CONTROL },
3525 { SDDL_STANDARD_DELETE, DELETE },
3526 { SDDL_WRITE_DAC, WRITE_DAC },
3527 { SDDL_WRITE_OWNER, WRITE_OWNER },
3529 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3530 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3531 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3532 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3533 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3534 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3535 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3536 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3537 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3539 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3540 { SDDL_FILE_READ, FILE_GENERIC_READ },
3541 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3542 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3544 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3545 { SDDL_KEY_READ, KEY_READ },
3546 { SDDL_KEY_WRITE, KEY_WRITE },
3547 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3548 { NULL, 0 },
3551 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3553 UINT len = 0;
3554 DWORD rights = 0;
3555 LPCWSTR szAcl = *StringAcl;
3557 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3559 LPCWSTR p = szAcl;
3561 while (*p && *p != ';')
3562 p++;
3564 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3566 rights = strtoulW(szAcl, NULL, 16);
3567 szAcl = p;
3569 else
3570 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3572 else
3574 while (*szAcl != ';')
3576 const ACEFLAG *lpaf = AceRights;
3578 while (lpaf->wstr &&
3579 (len = strlenW(lpaf->wstr)) &&
3580 strncmpW(lpaf->wstr, szAcl, len))
3582 lpaf++;
3585 if (!lpaf->wstr)
3586 return 0;
3588 rights |= lpaf->value;
3589 szAcl += len;
3593 *StringAcl = szAcl;
3594 return rights;
3598 /******************************************************************************
3599 * ParseStringAclToAcl
3601 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3603 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3604 PACL pAcl, LPDWORD cBytes)
3606 DWORD val;
3607 DWORD sidlen;
3608 DWORD length = sizeof(ACL);
3609 DWORD acesize = 0;
3610 DWORD acecount = 0;
3611 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3613 TRACE("%s\n", debugstr_w(StringAcl));
3615 if (!StringAcl)
3616 return FALSE;
3618 if (pAcl) /* pAce is only useful if we're setting values */
3619 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3621 /* Parse ACL flags */
3622 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3624 /* Parse ACE */
3625 while (*StringAcl == '(')
3627 StringAcl++;
3629 /* Parse ACE type */
3630 val = ParseAceStringType(&StringAcl);
3631 if (pAce)
3632 pAce->Header.AceType = (BYTE) val;
3633 if (*StringAcl != ';')
3634 goto lerr;
3635 StringAcl++;
3637 /* Parse ACE flags */
3638 val = ParseAceStringFlags(&StringAcl);
3639 if (pAce)
3640 pAce->Header.AceFlags = (BYTE) val;
3641 if (*StringAcl != ';')
3642 goto lerr;
3643 StringAcl++;
3645 /* Parse ACE rights */
3646 val = ParseAceStringRights(&StringAcl);
3647 if (pAce)
3648 pAce->Mask = val;
3649 if (*StringAcl != ';')
3650 goto lerr;
3651 StringAcl++;
3653 /* Parse ACE object guid */
3654 if (*StringAcl != ';')
3656 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3657 goto lerr;
3659 StringAcl++;
3661 /* Parse ACE inherit object guid */
3662 if (*StringAcl != ';')
3664 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3665 goto lerr;
3667 StringAcl++;
3669 /* Parse ACE account sid */
3670 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3672 while (*StringAcl && *StringAcl != ')')
3673 StringAcl++;
3676 if (*StringAcl != ')')
3677 goto lerr;
3678 StringAcl++;
3680 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3681 length += acesize;
3682 if (pAce)
3684 pAce->Header.AceSize = acesize;
3685 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3687 acecount++;
3690 *cBytes = length;
3692 if (length > 0xffff)
3694 ERR("ACL too large\n");
3695 goto lerr;
3698 if (pAcl)
3700 pAcl->AclRevision = ACL_REVISION;
3701 pAcl->Sbz1 = 0;
3702 pAcl->AclSize = length;
3703 pAcl->AceCount = acecount++;
3704 pAcl->Sbz2 = 0;
3706 return TRUE;
3708 lerr:
3709 WARN("Invalid ACE string format\n");
3710 return FALSE;
3714 /******************************************************************************
3715 * ParseStringSecurityDescriptorToSecurityDescriptor
3717 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3718 LPCWSTR StringSecurityDescriptor,
3719 SECURITY_DESCRIPTOR* SecurityDescriptor,
3720 LPDWORD cBytes)
3722 BOOL bret = FALSE;
3723 WCHAR toktype;
3724 WCHAR tok[MAX_PATH];
3725 LPCWSTR lptoken;
3726 LPBYTE lpNext = NULL;
3727 DWORD len;
3729 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3731 if (SecurityDescriptor)
3732 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3734 while (*StringSecurityDescriptor)
3736 toktype = *StringSecurityDescriptor;
3738 /* Expect char identifier followed by ':' */
3739 StringSecurityDescriptor++;
3740 if (*StringSecurityDescriptor != ':')
3742 SetLastError(ERROR_INVALID_PARAMETER);
3743 goto lend;
3745 StringSecurityDescriptor++;
3747 /* Extract token */
3748 lptoken = StringSecurityDescriptor;
3749 while (*lptoken && *lptoken != ':')
3750 lptoken++;
3752 if (*lptoken)
3753 lptoken--;
3755 len = lptoken - StringSecurityDescriptor;
3756 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3757 tok[len] = 0;
3759 switch (toktype)
3761 case 'O':
3763 DWORD bytes;
3765 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3766 goto lend;
3768 if (SecurityDescriptor)
3770 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3771 lpNext += bytes; /* Advance to next token */
3774 *cBytes += bytes;
3776 break;
3779 case 'G':
3781 DWORD bytes;
3783 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3784 goto lend;
3786 if (SecurityDescriptor)
3788 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3789 lpNext += bytes; /* Advance to next token */
3792 *cBytes += bytes;
3794 break;
3797 case 'D':
3799 DWORD flags;
3800 DWORD bytes;
3802 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3803 goto lend;
3805 if (SecurityDescriptor)
3807 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3808 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3809 lpNext += bytes; /* Advance to next token */
3812 *cBytes += bytes;
3814 break;
3817 case 'S':
3819 DWORD flags;
3820 DWORD bytes;
3822 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3823 goto lend;
3825 if (SecurityDescriptor)
3827 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3828 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3829 lpNext += bytes; /* Advance to next token */
3832 *cBytes += bytes;
3834 break;
3837 default:
3838 FIXME("Unknown token\n");
3839 SetLastError(ERROR_INVALID_PARAMETER);
3840 goto lend;
3843 StringSecurityDescriptor = lptoken;
3846 bret = TRUE;
3848 lend:
3849 return bret;
3852 /******************************************************************************
3853 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3855 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3856 LPCSTR StringSecurityDescriptor,
3857 DWORD StringSDRevision,
3858 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3859 PULONG SecurityDescriptorSize)
3861 UINT len;
3862 BOOL ret = FALSE;
3863 LPWSTR StringSecurityDescriptorW;
3865 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3866 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3868 if (StringSecurityDescriptorW)
3870 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3872 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3873 StringSDRevision, SecurityDescriptor,
3874 SecurityDescriptorSize);
3875 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3878 return ret;
3881 /******************************************************************************
3882 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3884 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3885 LPCWSTR StringSecurityDescriptor,
3886 DWORD StringSDRevision,
3887 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3888 PULONG SecurityDescriptorSize)
3890 DWORD cBytes;
3891 SECURITY_DESCRIPTOR* psd;
3892 BOOL bret = FALSE;
3894 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3896 if (GetVersion() & 0x80000000)
3898 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3899 goto lend;
3901 else if (StringSDRevision != SID_REVISION)
3903 SetLastError(ERROR_UNKNOWN_REVISION);
3904 goto lend;
3907 /* Compute security descriptor length */
3908 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3909 NULL, &cBytes))
3910 goto lend;
3912 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3913 GMEM_ZEROINIT, cBytes);
3914 if (!psd) goto lend;
3916 psd->Revision = SID_REVISION;
3917 psd->Control |= SE_SELF_RELATIVE;
3919 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3920 psd, &cBytes))
3922 LocalFree(psd);
3923 goto lend;
3926 if (SecurityDescriptorSize)
3927 *SecurityDescriptorSize = cBytes;
3929 bret = TRUE;
3931 lend:
3932 TRACE(" ret=%d\n", bret);
3933 return bret;
3936 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3938 if (cch == -1)
3939 cch = strlenW(string);
3941 if (plen)
3942 *plen += cch;
3944 if (pwptr)
3946 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3947 *pwptr += cch;
3951 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3953 DWORD i;
3954 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3955 WCHAR subauthfmt[] = { '-','%','u',0 };
3956 WCHAR buf[26];
3957 SID *pisid = psid;
3959 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3961 SetLastError(ERROR_INVALID_SID);
3962 return FALSE;
3965 if (pisid->IdentifierAuthority.Value[0] ||
3966 pisid->IdentifierAuthority.Value[1])
3968 FIXME("not matching MS' bugs\n");
3969 SetLastError(ERROR_INVALID_SID);
3970 return FALSE;
3973 sprintfW( buf, fmt, pisid->Revision,
3974 MAKELONG(
3975 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3976 pisid->IdentifierAuthority.Value[4] ),
3977 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3978 pisid->IdentifierAuthority.Value[2] )
3979 ) );
3980 DumpString(buf, -1, pwptr, plen);
3982 for( i=0; i<pisid->SubAuthorityCount; i++ )
3984 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3985 DumpString(buf, -1, pwptr, plen);
3987 return TRUE;
3990 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3992 int i;
3993 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3995 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3997 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3998 return TRUE;
4002 return DumpSidNumeric(psid, pwptr, plen);
4005 static const LPCWSTR AceRightBitNames[32] = {
4006 SDDL_CREATE_CHILD, /* 0 */
4007 SDDL_DELETE_CHILD,
4008 SDDL_LIST_CHILDREN,
4009 SDDL_SELF_WRITE,
4010 SDDL_READ_PROPERTY, /* 4 */
4011 SDDL_WRITE_PROPERTY,
4012 SDDL_DELETE_TREE,
4013 SDDL_LIST_OBJECT,
4014 SDDL_CONTROL_ACCESS, /* 8 */
4015 NULL,
4016 NULL,
4017 NULL,
4018 NULL, /* 12 */
4019 NULL,
4020 NULL,
4021 NULL,
4022 SDDL_STANDARD_DELETE, /* 16 */
4023 SDDL_READ_CONTROL,
4024 SDDL_WRITE_DAC,
4025 SDDL_WRITE_OWNER,
4026 NULL, /* 20 */
4027 NULL,
4028 NULL,
4029 NULL,
4030 NULL, /* 24 */
4031 NULL,
4032 NULL,
4033 NULL,
4034 SDDL_GENERIC_ALL, /* 28 */
4035 SDDL_GENERIC_EXECUTE,
4036 SDDL_GENERIC_WRITE,
4037 SDDL_GENERIC_READ
4040 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4042 static const WCHAR fmtW[] = {'0','x','%','x',0};
4043 WCHAR buf[15];
4044 int i;
4046 if (mask == 0)
4047 return;
4049 /* first check if the right have name */
4050 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4052 if (AceRights[i].wstr == NULL)
4053 break;
4054 if (mask == AceRights[i].value)
4056 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4057 return;
4061 /* then check if it can be built from bit names */
4062 for (i = 0; i < 32; i++)
4064 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4066 /* can't be built from bit names */
4067 sprintfW(buf, fmtW, mask);
4068 DumpString(buf, -1, pwptr, plen);
4069 return;
4073 /* build from bit names */
4074 for (i = 0; i < 32; i++)
4075 if (mask & (1 << i))
4076 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4079 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4081 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4082 static const WCHAR openbr = '(';
4083 static const WCHAR closebr = ')';
4084 static const WCHAR semicolon = ';';
4086 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4088 SetLastError(ERROR_INVALID_ACL);
4089 return FALSE;
4092 piace = (ACCESS_ALLOWED_ACE *)pace;
4093 DumpString(&openbr, 1, pwptr, plen);
4094 switch (piace->Header.AceType)
4096 case ACCESS_ALLOWED_ACE_TYPE:
4097 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4098 break;
4099 case ACCESS_DENIED_ACE_TYPE:
4100 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4101 break;
4102 case SYSTEM_AUDIT_ACE_TYPE:
4103 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4104 break;
4105 case SYSTEM_ALARM_ACE_TYPE:
4106 DumpString(SDDL_ALARM, -1, pwptr, plen);
4107 break;
4109 DumpString(&semicolon, 1, pwptr, plen);
4111 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4112 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4113 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4114 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4115 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4116 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4117 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4118 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4119 if (piace->Header.AceFlags & INHERITED_ACE)
4120 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4121 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4122 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4123 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4124 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4125 DumpString(&semicolon, 1, pwptr, plen);
4126 DumpRights(piace->Mask, pwptr, plen);
4127 DumpString(&semicolon, 1, pwptr, plen);
4128 /* objects not supported */
4129 DumpString(&semicolon, 1, pwptr, plen);
4130 /* objects not supported */
4131 DumpString(&semicolon, 1, pwptr, plen);
4132 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4133 return FALSE;
4134 DumpString(&closebr, 1, pwptr, plen);
4135 return TRUE;
4138 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4140 WORD count;
4141 int i;
4143 if (protected)
4144 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4145 if (autoInheritReq)
4146 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4147 if (autoInherited)
4148 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4150 if (pacl == NULL)
4151 return TRUE;
4153 if (!IsValidAcl(pacl))
4154 return FALSE;
4156 count = pacl->AceCount;
4157 for (i = 0; i < count; i++)
4159 LPVOID ace;
4160 if (!GetAce(pacl, i, &ace))
4161 return FALSE;
4162 if (!DumpAce(ace, pwptr, plen))
4163 return FALSE;
4166 return TRUE;
4169 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4171 static const WCHAR prefix[] = {'O',':',0};
4172 BOOL bDefaulted;
4173 PSID psid;
4175 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4176 return FALSE;
4178 if (psid == NULL)
4179 return TRUE;
4181 DumpString(prefix, -1, pwptr, plen);
4182 if (!DumpSid(psid, pwptr, plen))
4183 return FALSE;
4184 return TRUE;
4187 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4189 static const WCHAR prefix[] = {'G',':',0};
4190 BOOL bDefaulted;
4191 PSID psid;
4193 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4194 return FALSE;
4196 if (psid == NULL)
4197 return TRUE;
4199 DumpString(prefix, -1, pwptr, plen);
4200 if (!DumpSid(psid, pwptr, plen))
4201 return FALSE;
4202 return TRUE;
4205 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4207 static const WCHAR dacl[] = {'D',':',0};
4208 SECURITY_DESCRIPTOR_CONTROL control;
4209 BOOL present, defaulted;
4210 DWORD revision;
4211 PACL pacl;
4213 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4214 return FALSE;
4216 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4217 return FALSE;
4219 if (!present)
4220 return TRUE;
4222 DumpString(dacl, 2, pwptr, plen);
4223 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4224 return FALSE;
4225 return TRUE;
4228 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4230 static const WCHAR sacl[] = {'S',':',0};
4231 SECURITY_DESCRIPTOR_CONTROL control;
4232 BOOL present, defaulted;
4233 DWORD revision;
4234 PACL pacl;
4236 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4237 return FALSE;
4239 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4240 return FALSE;
4242 if (!present)
4243 return TRUE;
4245 DumpString(sacl, 2, pwptr, plen);
4246 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4247 return FALSE;
4248 return TRUE;
4251 /******************************************************************************
4252 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4254 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4256 ULONG len;
4257 WCHAR *wptr, *wstr;
4259 if (SDRevision != SDDL_REVISION_1)
4261 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4262 SetLastError(ERROR_UNKNOWN_REVISION);
4263 return FALSE;
4266 len = 0;
4267 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4268 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4269 return FALSE;
4270 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4271 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4272 return FALSE;
4273 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4274 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4275 return FALSE;
4276 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4277 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4278 return FALSE;
4280 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4281 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4282 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4283 return FALSE;
4284 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4285 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4286 return FALSE;
4287 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4288 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4289 return FALSE;
4290 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4291 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4292 return FALSE;
4293 *wptr = 0;
4295 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4296 *OutputString = wstr;
4297 if (OutputLen)
4298 *OutputLen = strlenW(*OutputString)+1;
4299 return TRUE;
4302 /******************************************************************************
4303 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4305 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4307 LPWSTR wstr;
4308 ULONG len;
4309 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4311 int lenA;
4313 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4314 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4315 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4316 LocalFree(wstr);
4318 if (OutputLen != NULL)
4319 *OutputLen = lenA;
4320 return TRUE;
4322 else
4324 *OutputString = NULL;
4325 if (OutputLen)
4326 *OutputLen = 0;
4327 return FALSE;
4331 /******************************************************************************
4332 * ConvertStringSidToSidW [ADVAPI32.@]
4334 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4336 BOOL bret = FALSE;
4337 DWORD cBytes;
4339 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4340 if (GetVersion() & 0x80000000)
4341 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4342 else if (!StringSid || !Sid)
4343 SetLastError(ERROR_INVALID_PARAMETER);
4344 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4346 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4348 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4349 if (!bret)
4350 LocalFree(*Sid);
4352 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4353 return bret;
4356 /******************************************************************************
4357 * ConvertStringSidToSidA [ADVAPI32.@]
4359 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4361 BOOL bret = FALSE;
4363 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4364 if (GetVersion() & 0x80000000)
4365 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4366 else if (!StringSid || !Sid)
4367 SetLastError(ERROR_INVALID_PARAMETER);
4368 else
4370 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4371 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4372 len * sizeof(WCHAR));
4374 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4375 bret = ConvertStringSidToSidW(wStringSid, Sid);
4376 HeapFree(GetProcessHeap(), 0, wStringSid);
4378 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4379 return bret;
4382 /******************************************************************************
4383 * ConvertSidToStringSidW [ADVAPI32.@]
4385 * format of SID string is:
4386 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4387 * where
4388 * <rev> is the revision of the SID encoded as decimal
4389 * <auth> is the identifier authority encoded as hex
4390 * <subauthN> is the subauthority id encoded as decimal
4392 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4394 DWORD len = 0;
4395 LPWSTR wstr, wptr;
4397 TRACE("%p %p\n", pSid, pstr );
4399 len = 0;
4400 if (!DumpSidNumeric(pSid, NULL, &len))
4401 return FALSE;
4402 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4403 DumpSidNumeric(pSid, &wptr, NULL);
4404 *wptr = 0;
4406 *pstr = wstr;
4407 return TRUE;
4410 /******************************************************************************
4411 * ConvertSidToStringSidA [ADVAPI32.@]
4413 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4415 LPWSTR wstr = NULL;
4416 LPSTR str;
4417 UINT len;
4419 TRACE("%p %p\n", pSid, pstr );
4421 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4422 return FALSE;
4424 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4425 str = LocalAlloc( 0, len );
4426 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4427 LocalFree( wstr );
4429 *pstr = str;
4431 return TRUE;
4434 BOOL WINAPI CreatePrivateObjectSecurity(
4435 PSECURITY_DESCRIPTOR ParentDescriptor,
4436 PSECURITY_DESCRIPTOR CreatorDescriptor,
4437 PSECURITY_DESCRIPTOR* NewDescriptor,
4438 BOOL IsDirectoryObject,
4439 HANDLE Token,
4440 PGENERIC_MAPPING GenericMapping )
4442 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4443 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4445 return FALSE;
4448 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4450 FIXME("%p - stub\n", ObjectDescriptor);
4452 return TRUE;
4455 BOOL WINAPI CreateProcessAsUserA(
4456 HANDLE hToken,
4457 LPCSTR lpApplicationName,
4458 LPSTR lpCommandLine,
4459 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4460 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4461 BOOL bInheritHandles,
4462 DWORD dwCreationFlags,
4463 LPVOID lpEnvironment,
4464 LPCSTR lpCurrentDirectory,
4465 LPSTARTUPINFOA lpStartupInfo,
4466 LPPROCESS_INFORMATION lpProcessInformation )
4468 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4469 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4470 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4472 return FALSE;
4475 BOOL WINAPI CreateProcessAsUserW(
4476 HANDLE hToken,
4477 LPCWSTR lpApplicationName,
4478 LPWSTR lpCommandLine,
4479 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4480 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4481 BOOL bInheritHandles,
4482 DWORD dwCreationFlags,
4483 LPVOID lpEnvironment,
4484 LPCWSTR lpCurrentDirectory,
4485 LPSTARTUPINFOW lpStartupInfo,
4486 LPPROCESS_INFORMATION lpProcessInformation )
4488 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4489 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4490 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4491 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4493 /* We should create the process with a suspended main thread */
4494 if (!CreateProcessW (lpApplicationName,
4495 lpCommandLine,
4496 lpProcessAttributes,
4497 lpThreadAttributes,
4498 bInheritHandles,
4499 dwCreationFlags, /* CREATE_SUSPENDED */
4500 lpEnvironment,
4501 lpCurrentDirectory,
4502 lpStartupInfo,
4503 lpProcessInformation))
4505 return FALSE;
4508 return TRUE;
4511 /******************************************************************************
4512 * CreateProcessWithLogonW
4514 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4515 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4516 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4518 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4519 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4520 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4521 lpStartupInfo, lpProcessInformation);
4523 return FALSE;
4526 /******************************************************************************
4527 * DuplicateTokenEx [ADVAPI32.@]
4529 BOOL WINAPI DuplicateTokenEx(
4530 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4531 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4532 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4533 TOKEN_TYPE TokenType,
4534 PHANDLE DuplicateTokenHandle )
4536 OBJECT_ATTRIBUTES ObjectAttributes;
4538 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4539 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4541 InitializeObjectAttributes(
4542 &ObjectAttributes,
4543 NULL,
4544 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4545 NULL,
4546 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4548 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4549 dwDesiredAccess,
4550 &ObjectAttributes,
4551 ImpersonationLevel,
4552 TokenType,
4553 DuplicateTokenHandle ) );
4556 BOOL WINAPI DuplicateToken(
4557 HANDLE ExistingTokenHandle,
4558 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4559 PHANDLE DuplicateTokenHandle )
4561 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4562 NULL, ImpersonationLevel, TokenImpersonation,
4563 DuplicateTokenHandle );
4566 /******************************************************************************
4567 * ComputeStringSidSize
4569 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4571 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4573 int ctok = 0;
4574 while (*StringSid)
4576 if (*StringSid == '-')
4577 ctok++;
4578 StringSid++;
4581 if (ctok >= 3)
4582 return GetSidLengthRequired(ctok - 2);
4584 else /* String constant format - Only available in winxp and above */
4586 unsigned int i;
4588 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4589 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4590 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4593 return GetSidLengthRequired(0);
4596 /******************************************************************************
4597 * ParseStringSidToSid
4599 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4601 BOOL bret = FALSE;
4602 SID* pisid=pSid;
4604 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4605 if (!StringSid)
4607 SetLastError(ERROR_INVALID_PARAMETER);
4608 TRACE("StringSid is NULL, returning FALSE\n");
4609 return FALSE;
4612 *cBytes = ComputeStringSidSize(StringSid);
4613 if (!pisid) /* Simply compute the size */
4615 TRACE("only size requested, returning TRUE\n");
4616 return TRUE;
4619 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4621 DWORD i = 0, identAuth;
4622 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4624 StringSid += 2; /* Advance to Revision */
4625 pisid->Revision = atoiW(StringSid);
4627 if (pisid->Revision != SDDL_REVISION)
4629 TRACE("Revision %d is unknown\n", pisid->Revision);
4630 goto lend; /* ERROR_INVALID_SID */
4632 if (csubauth == 0)
4634 TRACE("SubAuthorityCount is 0\n");
4635 goto lend; /* ERROR_INVALID_SID */
4638 pisid->SubAuthorityCount = csubauth;
4640 /* Advance to identifier authority */
4641 while (*StringSid && *StringSid != '-')
4642 StringSid++;
4643 if (*StringSid == '-')
4644 StringSid++;
4646 /* MS' implementation can't handle values greater than 2^32 - 1, so
4647 * we don't either; assume most significant bytes are always 0
4649 pisid->IdentifierAuthority.Value[0] = 0;
4650 pisid->IdentifierAuthority.Value[1] = 0;
4651 identAuth = atoiW(StringSid);
4652 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4653 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4654 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4655 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4657 /* Advance to first sub authority */
4658 while (*StringSid && *StringSid != '-')
4659 StringSid++;
4660 if (*StringSid == '-')
4661 StringSid++;
4663 while (*StringSid)
4665 pisid->SubAuthority[i++] = atoiW(StringSid);
4667 while (*StringSid && *StringSid != '-')
4668 StringSid++;
4669 if (*StringSid == '-')
4670 StringSid++;
4673 if (i != pisid->SubAuthorityCount)
4674 goto lend; /* ERROR_INVALID_SID */
4676 bret = TRUE;
4678 else /* String constant format - Only available in winxp and above */
4680 unsigned int i;
4681 pisid->Revision = SDDL_REVISION;
4683 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4684 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4686 DWORD j;
4687 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4688 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4689 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4690 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4691 bret = TRUE;
4694 if (!bret)
4695 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4698 lend:
4699 if (!bret)
4700 SetLastError(ERROR_INVALID_SID);
4702 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4703 return bret;
4706 /******************************************************************************
4707 * GetNamedSecurityInfoA [ADVAPI32.@]
4709 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4710 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4711 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4712 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4714 DWORD len;
4715 LPWSTR wstr = NULL;
4716 DWORD r;
4718 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4719 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4721 if( pObjectName )
4723 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4724 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4725 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4728 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4729 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4731 HeapFree( GetProcessHeap(), 0, wstr );
4733 return r;
4736 /******************************************************************************
4737 * GetNamedSecurityInfoW [ADVAPI32.@]
4739 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4740 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4741 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4743 DWORD needed, offset;
4744 SECURITY_DESCRIPTOR_RELATIVE *relative;
4745 BYTE *buffer;
4747 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4748 group, dacl, sacl, descriptor );
4750 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4752 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4753 if (info & OWNER_SECURITY_INFORMATION)
4754 needed += sizeof(sidWorld);
4755 if (info & GROUP_SECURITY_INFORMATION)
4756 needed += sizeof(sidWorld);
4757 if (info & DACL_SECURITY_INFORMATION)
4758 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4759 if (info & SACL_SECURITY_INFORMATION)
4760 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4762 /* must be freed by caller */
4763 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4764 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4766 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4768 HeapFree( GetProcessHeap(), 0, *descriptor );
4769 return ERROR_INVALID_SECURITY_DESCR;
4772 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4773 relative->Control |= SE_SELF_RELATIVE;
4774 buffer = (BYTE *)relative;
4775 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4777 if (info & OWNER_SECURITY_INFORMATION)
4779 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4780 relative->Owner = offset;
4781 if (owner)
4782 *owner = buffer + offset;
4783 offset += sizeof(sidWorld);
4785 if (info & GROUP_SECURITY_INFORMATION)
4787 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4788 relative->Group = offset;
4789 if (group)
4790 *group = buffer + offset;
4791 offset += sizeof(sidWorld);
4793 if (info & DACL_SECURITY_INFORMATION)
4795 relative->Control |= SE_DACL_PRESENT;
4796 GetWorldAccessACL( (PACL)(buffer + offset) );
4797 relative->Dacl = offset;
4798 if (dacl)
4799 *dacl = (PACL)(buffer + offset);
4800 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4802 if (info & SACL_SECURITY_INFORMATION)
4804 relative->Control |= SE_SACL_PRESENT;
4805 GetWorldAccessACL( (PACL)(buffer + offset) );
4806 relative->Sacl = offset;
4807 if (sacl)
4808 *sacl = (PACL)(buffer + offset);
4810 return ERROR_SUCCESS;
4813 /******************************************************************************
4814 * DecryptFileW [ADVAPI32.@]
4816 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4818 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4819 return TRUE;
4822 /******************************************************************************
4823 * DecryptFileA [ADVAPI32.@]
4825 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4827 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4828 return TRUE;
4831 /******************************************************************************
4832 * EncryptFileW [ADVAPI32.@]
4834 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4836 FIXME("%s\n", debugstr_w(lpFileName));
4837 return TRUE;
4840 /******************************************************************************
4841 * EncryptFileA [ADVAPI32.@]
4843 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4845 FIXME("%s\n", debugstr_a(lpFileName));
4846 return TRUE;
4849 /******************************************************************************
4850 * FileEncryptionStatusW [ADVAPI32.@]
4852 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4854 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4855 if (!lpStatus)
4856 return FALSE;
4857 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4858 return TRUE;
4861 /******************************************************************************
4862 * FileEncryptionStatusA [ADVAPI32.@]
4864 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4866 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4867 if (!lpStatus)
4868 return FALSE;
4869 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4870 return TRUE;
4873 /******************************************************************************
4874 * SetSecurityInfo [ADVAPI32.@]
4876 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4877 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4878 PSID psidGroup, PACL pDacl, PACL pSacl) {
4879 FIXME("stub\n");
4880 return ERROR_SUCCESS;