advapi32: Implement SetEntriesInAclW.
[wine/testsucceed.git] / dlls / advapi32 / security.c
blobd51a22a1496f5b0d76dc881764c720f9df5e1a1d
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};
2482 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2483 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2485 ret = AllocateAndInitializeSid(&identifierAuthority,
2487 SECURITY_BUILTIN_DOMAIN_RID,
2488 DOMAIN_ALIAS_RID_ADMINS,
2489 0, 0, 0, 0, 0, 0,
2490 &pSid);
2492 if (!ret)
2493 return FALSE;
2495 if (!RtlValidSid(pSid))
2497 FreeSid(pSid);
2498 return FALSE;
2501 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2502 CopySid(*cbSid, Sid, pSid);
2503 if (*cbSid < GetLengthSid(pSid))
2505 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2506 ret = FALSE;
2508 *cbSid = GetLengthSid(pSid);
2510 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2511 strcpyW(ReferencedDomainName, dm);
2513 if (*cchReferencedDomainName <= strlenW(dm))
2515 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2516 ret = FALSE;
2519 *cchReferencedDomainName = strlenW(dm)+1;
2521 FreeSid(pSid);
2523 return ret;
2526 /******************************************************************************
2527 * PrivilegeCheck [ADVAPI32.@]
2529 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2531 BOOL ret;
2532 BOOLEAN Result;
2534 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2536 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2537 if (ret)
2538 *pfResult = Result;
2539 return ret;
2542 /******************************************************************************
2543 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2545 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2546 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2547 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2548 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2550 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2551 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2552 SecurityDescriptor, DesiredAccess, GenericMapping,
2553 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2554 return TRUE;
2557 /******************************************************************************
2558 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2560 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2561 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2562 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2563 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2565 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2566 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2567 SecurityDescriptor, DesiredAccess, GenericMapping,
2568 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2569 return TRUE;
2572 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2574 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2576 return TRUE;
2579 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2581 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2583 return TRUE;
2586 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2588 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2590 return TRUE;
2593 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2594 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2595 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2596 LPBOOL GenerateOnClose)
2598 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2599 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2600 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2601 GenerateOnClose);
2603 return TRUE;
2606 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2607 LPWSTR 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_w(SubsystemName),
2612 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2613 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2614 GenerateOnClose);
2616 return TRUE;
2619 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2620 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2622 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2623 DesiredAccess, Privileges, AccessGranted);
2625 return TRUE;
2628 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2629 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2631 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2632 DesiredAccess, Privileges, AccessGranted);
2634 return TRUE;
2637 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2638 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2640 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2641 ClientToken, Privileges, AccessGranted);
2643 return TRUE;
2646 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2647 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2649 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2650 ClientToken, Privileges, AccessGranted);
2652 return TRUE;
2655 /******************************************************************************
2656 * GetSecurityInfo [ADVAPI32.@]
2658 DWORD WINAPI GetSecurityInfo(
2659 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2660 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2661 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2662 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2665 FIXME("stub!\n");
2666 return ERROR_BAD_PROVIDER;
2669 /******************************************************************************
2670 * GetSecurityInfoExW [ADVAPI32.@]
2672 DWORD WINAPI GetSecurityInfoExW(
2673 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2674 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2675 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2676 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2679 FIXME("stub!\n");
2680 return ERROR_BAD_PROVIDER;
2683 /******************************************************************************
2684 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2686 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2687 LPSTR pTrusteeName, DWORD AccessPermissions,
2688 ACCESS_MODE AccessMode, DWORD Inheritance )
2690 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2691 AccessPermissions, AccessMode, Inheritance);
2693 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2694 pExplicitAccess->grfAccessMode = AccessMode;
2695 pExplicitAccess->grfInheritance = Inheritance;
2697 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2698 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2699 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2700 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2701 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2704 /******************************************************************************
2705 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2707 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2708 LPWSTR pTrusteeName, DWORD AccessPermissions,
2709 ACCESS_MODE AccessMode, DWORD Inheritance )
2711 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2712 AccessPermissions, AccessMode, Inheritance);
2714 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2715 pExplicitAccess->grfAccessMode = AccessMode;
2716 pExplicitAccess->grfInheritance = Inheritance;
2718 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2719 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2720 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2721 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2722 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2725 /******************************************************************************
2726 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2728 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2729 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2730 LPSTR InheritedObjectTypeName, LPSTR Name )
2732 DWORD ObjectsPresent = 0;
2734 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2735 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2737 /* Fill the OBJECTS_AND_NAME structure */
2738 pObjName->ObjectType = ObjectType;
2739 if (ObjectTypeName != NULL)
2741 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2744 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2745 if (InheritedObjectTypeName != NULL)
2747 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2750 pObjName->ObjectsPresent = ObjectsPresent;
2751 pObjName->ptstrName = Name;
2753 /* Fill the TRUSTEE structure */
2754 pTrustee->pMultipleTrustee = NULL;
2755 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2756 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2757 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2758 pTrustee->ptstrName = (LPSTR)pObjName;
2761 /******************************************************************************
2762 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2764 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2765 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2766 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2768 DWORD ObjectsPresent = 0;
2770 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2771 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2773 /* Fill the OBJECTS_AND_NAME structure */
2774 pObjName->ObjectType = ObjectType;
2775 if (ObjectTypeName != NULL)
2777 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2780 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2781 if (InheritedObjectTypeName != NULL)
2783 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2786 pObjName->ObjectsPresent = ObjectsPresent;
2787 pObjName->ptstrName = Name;
2789 /* Fill the TRUSTEE structure */
2790 pTrustee->pMultipleTrustee = NULL;
2791 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2792 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2793 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2794 pTrustee->ptstrName = (LPWSTR)pObjName;
2797 /******************************************************************************
2798 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2800 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2801 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2803 DWORD ObjectsPresent = 0;
2805 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2807 /* Fill the OBJECTS_AND_SID structure */
2808 if (pObjectGuid != NULL)
2810 pObjSid->ObjectTypeGuid = *pObjectGuid;
2811 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2813 else
2815 ZeroMemory(&pObjSid->ObjectTypeGuid,
2816 sizeof(GUID));
2819 if (pInheritedObjectGuid != NULL)
2821 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2822 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2824 else
2826 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2827 sizeof(GUID));
2830 pObjSid->ObjectsPresent = ObjectsPresent;
2831 pObjSid->pSid = pSid;
2833 /* Fill the TRUSTEE structure */
2834 pTrustee->pMultipleTrustee = NULL;
2835 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2836 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2837 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2838 pTrustee->ptstrName = (LPSTR) pObjSid;
2841 /******************************************************************************
2842 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2844 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2845 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2847 DWORD ObjectsPresent = 0;
2849 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2851 /* Fill the OBJECTS_AND_SID structure */
2852 if (pObjectGuid != NULL)
2854 pObjSid->ObjectTypeGuid = *pObjectGuid;
2855 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2857 else
2859 ZeroMemory(&pObjSid->ObjectTypeGuid,
2860 sizeof(GUID));
2863 if (pInheritedObjectGuid != NULL)
2865 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2866 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2868 else
2870 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2871 sizeof(GUID));
2874 pObjSid->ObjectsPresent = ObjectsPresent;
2875 pObjSid->pSid = pSid;
2877 /* Fill the TRUSTEE structure */
2878 pTrustee->pMultipleTrustee = NULL;
2879 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2880 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2881 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2882 pTrustee->ptstrName = (LPWSTR) pObjSid;
2885 /******************************************************************************
2886 * BuildTrusteeWithSidA [ADVAPI32.@]
2888 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2890 TRACE("%p %p\n", pTrustee, pSid);
2892 pTrustee->pMultipleTrustee = NULL;
2893 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2894 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2895 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2896 pTrustee->ptstrName = (LPSTR) pSid;
2899 /******************************************************************************
2900 * BuildTrusteeWithSidW [ADVAPI32.@]
2902 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2904 TRACE("%p %p\n", pTrustee, pSid);
2906 pTrustee->pMultipleTrustee = NULL;
2907 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2908 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2909 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2910 pTrustee->ptstrName = (LPWSTR) pSid;
2913 /******************************************************************************
2914 * BuildTrusteeWithNameA [ADVAPI32.@]
2916 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2918 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2920 pTrustee->pMultipleTrustee = NULL;
2921 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2922 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2923 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2924 pTrustee->ptstrName = name;
2927 /******************************************************************************
2928 * BuildTrusteeWithNameW [ADVAPI32.@]
2930 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2932 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2934 pTrustee->pMultipleTrustee = NULL;
2935 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2936 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2937 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2938 pTrustee->ptstrName = name;
2941 /******************************************************************************
2942 * GetTrusteeFormA [ADVAPI32.@]
2944 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2946 TRACE("(%p)\n", pTrustee);
2948 if (!pTrustee)
2949 return TRUSTEE_BAD_FORM;
2951 return pTrustee->TrusteeForm;
2954 /******************************************************************************
2955 * GetTrusteeFormW [ADVAPI32.@]
2957 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2959 TRACE("(%p)\n", pTrustee);
2961 if (!pTrustee)
2962 return TRUSTEE_BAD_FORM;
2964 return pTrustee->TrusteeForm;
2967 /******************************************************************************
2968 * GetTrusteeNameA [ADVAPI32.@]
2970 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2972 TRACE("(%p)\n", pTrustee);
2974 if (!pTrustee)
2975 return NULL;
2977 return pTrustee->ptstrName;
2980 /******************************************************************************
2981 * GetTrusteeNameW [ADVAPI32.@]
2983 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2985 TRACE("(%p)\n", pTrustee);
2987 if (!pTrustee)
2988 return NULL;
2990 return pTrustee->ptstrName;
2993 /******************************************************************************
2994 * GetTrusteeTypeA [ADVAPI32.@]
2996 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2998 TRACE("(%p)\n", pTrustee);
3000 if (!pTrustee)
3001 return TRUSTEE_IS_UNKNOWN;
3003 return pTrustee->TrusteeType;
3006 /******************************************************************************
3007 * GetTrusteeTypeW [ADVAPI32.@]
3009 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3011 TRACE("(%p)\n", pTrustee);
3013 if (!pTrustee)
3014 return TRUSTEE_IS_UNKNOWN;
3016 return pTrustee->TrusteeType;
3019 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3020 DWORD nAclInformationLength,
3021 ACL_INFORMATION_CLASS dwAclInformationClass )
3023 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3024 nAclInformationLength, dwAclInformationClass);
3026 return TRUE;
3029 /******************************************************************************
3030 * SetEntriesInAclA [ADVAPI32.@]
3032 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3033 PACL OldAcl, PACL* NewAcl )
3035 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3036 *NewAcl = NULL;
3037 return ERROR_SUCCESS;
3040 /******************************************************************************
3041 * SetEntriesInAclW [ADVAPI32.@]
3043 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3044 PACL OldAcl, PACL* NewAcl )
3046 ULONG i;
3047 PSID *ppsid;
3048 DWORD ret = ERROR_SUCCESS;
3049 DWORD acl_size = sizeof(ACL);
3050 NTSTATUS status;
3052 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3054 *NewAcl = NULL;
3056 if (!count && !OldAcl)
3057 return ERROR_SUCCESS;
3059 /* allocate array of maximum sized sids allowed */
3060 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3061 if (!ppsid)
3062 return ERROR_OUTOFMEMORY;
3064 for (i = 0; i < count; i++)
3066 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3068 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3069 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3070 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3071 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3072 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3073 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3074 pEntries[i].Trustee.ptstrName);
3076 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3078 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3079 ret = ERROR_INVALID_PARAMETER;
3080 goto exit;
3083 switch (pEntries[i].Trustee.TrusteeForm)
3085 case TRUSTEE_IS_SID:
3086 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3087 ppsid[i], pEntries[i].Trustee.ptstrName))
3089 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3090 ret = ERROR_INVALID_PARAMETER;
3091 goto exit;
3093 break;
3094 case TRUSTEE_IS_NAME:
3096 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3097 DWORD domain_size = 0;
3098 SID_NAME_USE use;
3099 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3101 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3102 ret = ERROR_INVALID_PARAMETER;
3103 goto exit;
3105 break;
3107 case TRUSTEE_IS_OBJECTS_AND_SID:
3108 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3109 break;
3110 case TRUSTEE_IS_OBJECTS_AND_NAME:
3111 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3112 break;
3113 default:
3114 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3115 ret = ERROR_INVALID_PARAMETER;
3116 goto exit;
3119 /* Note: we overestimate the ACL size here as a tradeoff between
3120 * instructions (simplicity) and memory */
3121 switch (pEntries[i].grfAccessMode)
3123 case GRANT_ACCESS:
3124 case SET_ACCESS:
3125 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3126 break;
3127 case DENY_ACCESS:
3128 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3129 break;
3130 case SET_AUDIT_SUCCESS:
3131 case SET_AUDIT_FAILURE:
3132 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3133 break;
3134 case REVOKE_ACCESS:
3135 break;
3136 default:
3137 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3138 ret = ERROR_INVALID_PARAMETER;
3139 goto exit;
3143 if (OldAcl)
3145 ACL_SIZE_INFORMATION size_info;
3147 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3148 if (status != STATUS_SUCCESS)
3150 ret = RtlNtStatusToDosError(status);
3151 goto exit;
3153 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3156 *NewAcl = LocalAlloc(0, acl_size);
3157 if (!*NewAcl)
3159 ret = ERROR_OUTOFMEMORY;
3160 goto exit;
3163 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3164 if (status != STATUS_SUCCESS)
3166 ret = RtlNtStatusToDosError(status);
3167 goto exit;
3170 for (i = 0; i < count; i++)
3172 switch (pEntries[i].grfAccessMode)
3174 case GRANT_ACCESS:
3175 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3176 pEntries[i].grfInheritance,
3177 pEntries[i].grfAccessPermissions,
3178 ppsid[i]);
3179 break;
3180 case SET_ACCESS:
3182 ULONG j;
3183 BOOL add = TRUE;
3184 if (OldAcl)
3186 for (j = 0; ; j++)
3188 const ACE_HEADER *existing_ace_header;
3189 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3190 if (status != STATUS_SUCCESS)
3191 break;
3192 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3193 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3194 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3196 add = FALSE;
3197 break;
3201 if (add)
3202 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3203 pEntries[i].grfInheritance,
3204 pEntries[i].grfAccessPermissions,
3205 ppsid[i]);
3206 break;
3208 case DENY_ACCESS:
3209 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3210 pEntries[i].grfInheritance,
3211 pEntries[i].grfAccessPermissions,
3212 ppsid[i]);
3213 break;
3214 case SET_AUDIT_SUCCESS:
3215 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3216 pEntries[i].grfInheritance,
3217 pEntries[i].grfAccessPermissions,
3218 ppsid[i], TRUE, FALSE);
3219 break;
3220 case SET_AUDIT_FAILURE:
3221 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3222 pEntries[i].grfInheritance,
3223 pEntries[i].grfAccessPermissions,
3224 ppsid[i], FALSE, TRUE);
3225 break;
3226 default:
3227 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3231 if (OldAcl)
3233 for (i = 0; ; i++)
3235 BOOL add = TRUE;
3236 ULONG j;
3237 const ACE_HEADER *old_ace_header;
3238 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3239 if (status != STATUS_SUCCESS) break;
3240 for (j = 0; j < count; j++)
3242 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3243 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3244 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3246 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3247 add = FALSE;
3248 break;
3250 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3252 switch (old_ace_header->AceType)
3254 case ACCESS_ALLOWED_ACE_TYPE:
3255 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3256 add = FALSE;
3257 break;
3258 case ACCESS_DENIED_ACE_TYPE:
3259 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3260 add = FALSE;
3261 break;
3262 case SYSTEM_AUDIT_ACE_TYPE:
3263 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3264 add = FALSE;
3265 break;
3266 case SYSTEM_ALARM_ACE_TYPE:
3267 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3268 add = FALSE;
3269 break;
3270 default:
3271 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3274 if (!add)
3275 break;
3278 if (add)
3279 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3280 if (status != STATUS_SUCCESS)
3282 WARN("RtlAddAce failed with error 0x%08x\n", status);
3283 ret = RtlNtStatusToDosError(status);
3284 break;
3289 exit:
3290 HeapFree(GetProcessHeap(), 0, ppsid);
3291 return ret;
3294 /******************************************************************************
3295 * SetNamedSecurityInfoA [ADVAPI32.@]
3297 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3298 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3299 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3301 DWORD len;
3302 LPWSTR wstr = NULL;
3303 DWORD r;
3305 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3306 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3308 if( pObjectName )
3310 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3311 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3312 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3315 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3316 psidGroup, pDacl, pSacl );
3318 HeapFree( GetProcessHeap(), 0, wstr );
3320 return r;
3323 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3324 PSECURITY_DESCRIPTOR ModificationDescriptor,
3325 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3326 PGENERIC_MAPPING GenericMapping,
3327 HANDLE Token )
3329 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3330 ObjectsSecurityDescriptor, GenericMapping, Token);
3332 return TRUE;
3335 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3337 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3340 /******************************************************************************
3341 * AreAnyAccessesGranted [ADVAPI32.@]
3343 * Determines whether or not any of a set of specified access permissions have
3344 * been granted or not.
3346 * PARAMS
3347 * GrantedAccess [I] The permissions that have been granted.
3348 * DesiredAccess [I] The permissions that you want to have.
3350 * RETURNS
3351 * Nonzero if any of the permissions have been granted, zero if none of the
3352 * permissions have been granted.
3355 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3357 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3360 /******************************************************************************
3361 * SetNamedSecurityInfoW [ADVAPI32.@]
3363 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3364 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3365 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3367 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3368 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3369 return ERROR_SUCCESS;
3372 /******************************************************************************
3373 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3375 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3376 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3378 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3379 return ERROR_CALL_NOT_IMPLEMENTED;
3382 /******************************************************************************
3383 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3385 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3386 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3388 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3389 return ERROR_CALL_NOT_IMPLEMENTED;
3393 /******************************************************************************
3394 * ParseAclStringFlags
3396 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3398 DWORD flags = 0;
3399 LPCWSTR szAcl = *StringAcl;
3401 while (*szAcl != '(')
3403 if (*szAcl == 'P')
3405 flags |= SE_DACL_PROTECTED;
3407 else if (*szAcl == 'A')
3409 szAcl++;
3410 if (*szAcl == 'R')
3411 flags |= SE_DACL_AUTO_INHERIT_REQ;
3412 else if (*szAcl == 'I')
3413 flags |= SE_DACL_AUTO_INHERITED;
3415 szAcl++;
3418 *StringAcl = szAcl;
3419 return flags;
3422 /******************************************************************************
3423 * ParseAceStringType
3425 static const ACEFLAG AceType[] =
3427 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3428 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3429 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3430 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3432 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3433 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3434 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3435 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3437 { NULL, 0 },
3440 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3442 UINT len = 0;
3443 LPCWSTR szAcl = *StringAcl;
3444 const ACEFLAG *lpaf = AceType;
3446 while (lpaf->wstr &&
3447 (len = strlenW(lpaf->wstr)) &&
3448 strncmpW(lpaf->wstr, szAcl, len))
3449 lpaf++;
3451 if (!lpaf->wstr)
3452 return 0;
3454 *StringAcl += len;
3455 return lpaf->value;
3459 /******************************************************************************
3460 * ParseAceStringFlags
3462 static const ACEFLAG AceFlags[] =
3464 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3465 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3466 { SDDL_INHERITED, INHERITED_ACE },
3467 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3468 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3469 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3470 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3471 { NULL, 0 },
3474 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3476 UINT len = 0;
3477 BYTE flags = 0;
3478 LPCWSTR szAcl = *StringAcl;
3480 while (*szAcl != ';')
3482 const ACEFLAG *lpaf = AceFlags;
3484 while (lpaf->wstr &&
3485 (len = strlenW(lpaf->wstr)) &&
3486 strncmpW(lpaf->wstr, szAcl, len))
3487 lpaf++;
3489 if (!lpaf->wstr)
3490 return 0;
3492 flags |= lpaf->value;
3493 szAcl += len;
3496 *StringAcl = szAcl;
3497 return flags;
3501 /******************************************************************************
3502 * ParseAceStringRights
3504 static const ACEFLAG AceRights[] =
3506 { SDDL_GENERIC_ALL, GENERIC_ALL },
3507 { SDDL_GENERIC_READ, GENERIC_READ },
3508 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3509 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3511 { SDDL_READ_CONTROL, READ_CONTROL },
3512 { SDDL_STANDARD_DELETE, DELETE },
3513 { SDDL_WRITE_DAC, WRITE_DAC },
3514 { SDDL_WRITE_OWNER, WRITE_OWNER },
3516 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3517 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3518 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3519 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3520 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3521 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3522 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3523 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3524 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3526 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3527 { SDDL_FILE_READ, FILE_GENERIC_READ },
3528 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3529 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3531 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3532 { SDDL_KEY_READ, KEY_READ },
3533 { SDDL_KEY_WRITE, KEY_WRITE },
3534 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3535 { NULL, 0 },
3538 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3540 UINT len = 0;
3541 DWORD rights = 0;
3542 LPCWSTR szAcl = *StringAcl;
3544 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3546 LPCWSTR p = szAcl;
3548 while (*p && *p != ';')
3549 p++;
3551 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3553 rights = strtoulW(szAcl, NULL, 16);
3554 szAcl = p;
3556 else
3557 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3559 else
3561 while (*szAcl != ';')
3563 const ACEFLAG *lpaf = AceRights;
3565 while (lpaf->wstr &&
3566 (len = strlenW(lpaf->wstr)) &&
3567 strncmpW(lpaf->wstr, szAcl, len))
3569 lpaf++;
3572 if (!lpaf->wstr)
3573 return 0;
3575 rights |= lpaf->value;
3576 szAcl += len;
3580 *StringAcl = szAcl;
3581 return rights;
3585 /******************************************************************************
3586 * ParseStringAclToAcl
3588 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3590 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3591 PACL pAcl, LPDWORD cBytes)
3593 DWORD val;
3594 DWORD sidlen;
3595 DWORD length = sizeof(ACL);
3596 DWORD acesize = 0;
3597 DWORD acecount = 0;
3598 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3600 TRACE("%s\n", debugstr_w(StringAcl));
3602 if (!StringAcl)
3603 return FALSE;
3605 if (pAcl) /* pAce is only useful if we're setting values */
3606 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3608 /* Parse ACL flags */
3609 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3611 /* Parse ACE */
3612 while (*StringAcl == '(')
3614 StringAcl++;
3616 /* Parse ACE type */
3617 val = ParseAceStringType(&StringAcl);
3618 if (pAce)
3619 pAce->Header.AceType = (BYTE) val;
3620 if (*StringAcl != ';')
3621 goto lerr;
3622 StringAcl++;
3624 /* Parse ACE flags */
3625 val = ParseAceStringFlags(&StringAcl);
3626 if (pAce)
3627 pAce->Header.AceFlags = (BYTE) val;
3628 if (*StringAcl != ';')
3629 goto lerr;
3630 StringAcl++;
3632 /* Parse ACE rights */
3633 val = ParseAceStringRights(&StringAcl);
3634 if (pAce)
3635 pAce->Mask = val;
3636 if (*StringAcl != ';')
3637 goto lerr;
3638 StringAcl++;
3640 /* Parse ACE object guid */
3641 if (*StringAcl != ';')
3643 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3644 goto lerr;
3646 StringAcl++;
3648 /* Parse ACE inherit object guid */
3649 if (*StringAcl != ';')
3651 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3652 goto lerr;
3654 StringAcl++;
3656 /* Parse ACE account sid */
3657 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3659 while (*StringAcl && *StringAcl != ')')
3660 StringAcl++;
3663 if (*StringAcl != ')')
3664 goto lerr;
3665 StringAcl++;
3667 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3668 length += acesize;
3669 if (pAce)
3671 pAce->Header.AceSize = acesize;
3672 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3674 acecount++;
3677 *cBytes = length;
3679 if (length > 0xffff)
3681 ERR("ACL too large\n");
3682 goto lerr;
3685 if (pAcl)
3687 pAcl->AclRevision = ACL_REVISION;
3688 pAcl->Sbz1 = 0;
3689 pAcl->AclSize = length;
3690 pAcl->AceCount = acecount++;
3691 pAcl->Sbz2 = 0;
3693 return TRUE;
3695 lerr:
3696 WARN("Invalid ACE string format\n");
3697 return FALSE;
3701 /******************************************************************************
3702 * ParseStringSecurityDescriptorToSecurityDescriptor
3704 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3705 LPCWSTR StringSecurityDescriptor,
3706 SECURITY_DESCRIPTOR* SecurityDescriptor,
3707 LPDWORD cBytes)
3709 BOOL bret = FALSE;
3710 WCHAR toktype;
3711 WCHAR tok[MAX_PATH];
3712 LPCWSTR lptoken;
3713 LPBYTE lpNext = NULL;
3714 DWORD len;
3716 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3718 if (SecurityDescriptor)
3719 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3721 while (*StringSecurityDescriptor)
3723 toktype = *StringSecurityDescriptor;
3725 /* Expect char identifier followed by ':' */
3726 StringSecurityDescriptor++;
3727 if (*StringSecurityDescriptor != ':')
3729 SetLastError(ERROR_INVALID_PARAMETER);
3730 goto lend;
3732 StringSecurityDescriptor++;
3734 /* Extract token */
3735 lptoken = StringSecurityDescriptor;
3736 while (*lptoken && *lptoken != ':')
3737 lptoken++;
3739 if (*lptoken)
3740 lptoken--;
3742 len = lptoken - StringSecurityDescriptor;
3743 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3744 tok[len] = 0;
3746 switch (toktype)
3748 case 'O':
3750 DWORD bytes;
3752 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3753 goto lend;
3755 if (SecurityDescriptor)
3757 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3758 lpNext += bytes; /* Advance to next token */
3761 *cBytes += bytes;
3763 break;
3766 case 'G':
3768 DWORD bytes;
3770 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3771 goto lend;
3773 if (SecurityDescriptor)
3775 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3776 lpNext += bytes; /* Advance to next token */
3779 *cBytes += bytes;
3781 break;
3784 case 'D':
3786 DWORD flags;
3787 DWORD bytes;
3789 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3790 goto lend;
3792 if (SecurityDescriptor)
3794 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3795 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3796 lpNext += bytes; /* Advance to next token */
3799 *cBytes += bytes;
3801 break;
3804 case 'S':
3806 DWORD flags;
3807 DWORD bytes;
3809 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3810 goto lend;
3812 if (SecurityDescriptor)
3814 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3815 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3816 lpNext += bytes; /* Advance to next token */
3819 *cBytes += bytes;
3821 break;
3824 default:
3825 FIXME("Unknown token\n");
3826 SetLastError(ERROR_INVALID_PARAMETER);
3827 goto lend;
3830 StringSecurityDescriptor = lptoken;
3833 bret = TRUE;
3835 lend:
3836 return bret;
3839 /******************************************************************************
3840 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3842 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3843 LPCSTR StringSecurityDescriptor,
3844 DWORD StringSDRevision,
3845 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3846 PULONG SecurityDescriptorSize)
3848 UINT len;
3849 BOOL ret = FALSE;
3850 LPWSTR StringSecurityDescriptorW;
3852 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3853 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3855 if (StringSecurityDescriptorW)
3857 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3859 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3860 StringSDRevision, SecurityDescriptor,
3861 SecurityDescriptorSize);
3862 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3865 return ret;
3868 /******************************************************************************
3869 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3871 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3872 LPCWSTR StringSecurityDescriptor,
3873 DWORD StringSDRevision,
3874 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3875 PULONG SecurityDescriptorSize)
3877 DWORD cBytes;
3878 SECURITY_DESCRIPTOR* psd;
3879 BOOL bret = FALSE;
3881 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3883 if (GetVersion() & 0x80000000)
3885 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3886 goto lend;
3888 else if (StringSDRevision != SID_REVISION)
3890 SetLastError(ERROR_UNKNOWN_REVISION);
3891 goto lend;
3894 /* Compute security descriptor length */
3895 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3896 NULL, &cBytes))
3897 goto lend;
3899 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3900 GMEM_ZEROINIT, cBytes);
3901 if (!psd) goto lend;
3903 psd->Revision = SID_REVISION;
3904 psd->Control |= SE_SELF_RELATIVE;
3906 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3907 psd, &cBytes))
3909 LocalFree(psd);
3910 goto lend;
3913 if (SecurityDescriptorSize)
3914 *SecurityDescriptorSize = cBytes;
3916 bret = TRUE;
3918 lend:
3919 TRACE(" ret=%d\n", bret);
3920 return bret;
3923 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
3925 if (cch == -1)
3926 cch = strlenW(string);
3928 if (plen)
3929 *plen += cch;
3931 if (pwptr)
3933 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
3934 *pwptr += cch;
3938 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
3940 DWORD i;
3941 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3942 WCHAR subauthfmt[] = { '-','%','u',0 };
3943 WCHAR buf[26];
3944 SID *pisid = psid;
3946 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
3948 SetLastError(ERROR_INVALID_SID);
3949 return FALSE;
3952 if (pisid->IdentifierAuthority.Value[0] ||
3953 pisid->IdentifierAuthority.Value[1])
3955 FIXME("not matching MS' bugs\n");
3956 SetLastError(ERROR_INVALID_SID);
3957 return FALSE;
3960 sprintfW( buf, fmt, pisid->Revision,
3961 MAKELONG(
3962 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3963 pisid->IdentifierAuthority.Value[4] ),
3964 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3965 pisid->IdentifierAuthority.Value[2] )
3966 ) );
3967 DumpString(buf, -1, pwptr, plen);
3969 for( i=0; i<pisid->SubAuthorityCount; i++ )
3971 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
3972 DumpString(buf, -1, pwptr, plen);
3974 return TRUE;
3977 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
3979 int i;
3980 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
3982 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
3984 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
3985 return TRUE;
3989 return DumpSidNumeric(psid, pwptr, plen);
3992 static const LPCWSTR AceRightBitNames[32] = {
3993 SDDL_CREATE_CHILD, /* 0 */
3994 SDDL_DELETE_CHILD,
3995 SDDL_LIST_CHILDREN,
3996 SDDL_SELF_WRITE,
3997 SDDL_READ_PROPERTY, /* 4 */
3998 SDDL_WRITE_PROPERTY,
3999 SDDL_DELETE_TREE,
4000 SDDL_LIST_OBJECT,
4001 SDDL_CONTROL_ACCESS, /* 8 */
4002 NULL,
4003 NULL,
4004 NULL,
4005 NULL, /* 12 */
4006 NULL,
4007 NULL,
4008 NULL,
4009 SDDL_STANDARD_DELETE, /* 16 */
4010 SDDL_READ_CONTROL,
4011 SDDL_WRITE_DAC,
4012 SDDL_WRITE_OWNER,
4013 NULL, /* 20 */
4014 NULL,
4015 NULL,
4016 NULL,
4017 NULL, /* 24 */
4018 NULL,
4019 NULL,
4020 NULL,
4021 SDDL_GENERIC_ALL, /* 28 */
4022 SDDL_GENERIC_EXECUTE,
4023 SDDL_GENERIC_WRITE,
4024 SDDL_GENERIC_READ
4027 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4029 static const WCHAR fmtW[] = {'0','x','%','x',0};
4030 WCHAR buf[15];
4031 int i;
4033 if (mask == 0)
4034 return;
4036 /* first check if the right have name */
4037 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4039 if (AceRights[i].wstr == NULL)
4040 break;
4041 if (mask == AceRights[i].value)
4043 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4044 return;
4048 /* then check if it can be built from bit names */
4049 for (i = 0; i < 32; i++)
4051 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4053 /* can't be built from bit names */
4054 sprintfW(buf, fmtW, mask);
4055 DumpString(buf, -1, pwptr, plen);
4056 return;
4060 /* build from bit names */
4061 for (i = 0; i < 32; i++)
4062 if (mask & (1 << i))
4063 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4066 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4068 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4069 static const WCHAR openbr = '(';
4070 static const WCHAR closebr = ')';
4071 static const WCHAR semicolon = ';';
4073 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4075 SetLastError(ERROR_INVALID_ACL);
4076 return FALSE;
4079 piace = (ACCESS_ALLOWED_ACE *)pace;
4080 DumpString(&openbr, 1, pwptr, plen);
4081 switch (piace->Header.AceType)
4083 case ACCESS_ALLOWED_ACE_TYPE:
4084 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4085 break;
4086 case ACCESS_DENIED_ACE_TYPE:
4087 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4088 break;
4089 case SYSTEM_AUDIT_ACE_TYPE:
4090 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4091 break;
4092 case SYSTEM_ALARM_ACE_TYPE:
4093 DumpString(SDDL_ALARM, -1, pwptr, plen);
4094 break;
4096 DumpString(&semicolon, 1, pwptr, plen);
4098 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4099 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4100 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4101 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4102 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4103 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4104 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4105 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4106 if (piace->Header.AceFlags & INHERITED_ACE)
4107 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4108 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4109 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4110 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4111 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4112 DumpString(&semicolon, 1, pwptr, plen);
4113 DumpRights(piace->Mask, pwptr, plen);
4114 DumpString(&semicolon, 1, pwptr, plen);
4115 /* objects not supported */
4116 DumpString(&semicolon, 1, pwptr, plen);
4117 /* objects not supported */
4118 DumpString(&semicolon, 1, pwptr, plen);
4119 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4120 return FALSE;
4121 DumpString(&closebr, 1, pwptr, plen);
4122 return TRUE;
4125 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4127 WORD count;
4128 int i;
4130 if (protected)
4131 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4132 if (autoInheritReq)
4133 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4134 if (autoInherited)
4135 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4137 if (pacl == NULL)
4138 return TRUE;
4140 if (!IsValidAcl(pacl))
4141 return FALSE;
4143 count = pacl->AceCount;
4144 for (i = 0; i < count; i++)
4146 LPVOID ace;
4147 if (!GetAce(pacl, i, &ace))
4148 return FALSE;
4149 if (!DumpAce(ace, pwptr, plen))
4150 return FALSE;
4153 return TRUE;
4156 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4158 static const WCHAR prefix[] = {'O',':',0};
4159 BOOL bDefaulted;
4160 PSID psid;
4162 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4163 return FALSE;
4165 if (psid == NULL)
4166 return TRUE;
4168 DumpString(prefix, -1, pwptr, plen);
4169 if (!DumpSid(psid, pwptr, plen))
4170 return FALSE;
4171 return TRUE;
4174 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4176 static const WCHAR prefix[] = {'G',':',0};
4177 BOOL bDefaulted;
4178 PSID psid;
4180 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4181 return FALSE;
4183 if (psid == NULL)
4184 return TRUE;
4186 DumpString(prefix, -1, pwptr, plen);
4187 if (!DumpSid(psid, pwptr, plen))
4188 return FALSE;
4189 return TRUE;
4192 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4194 static const WCHAR dacl[] = {'D',':',0};
4195 SECURITY_DESCRIPTOR_CONTROL control;
4196 BOOL present, defaulted;
4197 DWORD revision;
4198 PACL pacl;
4200 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4201 return FALSE;
4203 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4204 return FALSE;
4206 if (!present)
4207 return TRUE;
4209 DumpString(dacl, 2, pwptr, plen);
4210 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4211 return FALSE;
4212 return TRUE;
4215 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4217 static const WCHAR sacl[] = {'S',':',0};
4218 SECURITY_DESCRIPTOR_CONTROL control;
4219 BOOL present, defaulted;
4220 DWORD revision;
4221 PACL pacl;
4223 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4224 return FALSE;
4226 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4227 return FALSE;
4229 if (!present)
4230 return TRUE;
4232 DumpString(sacl, 2, pwptr, plen);
4233 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4234 return FALSE;
4235 return TRUE;
4238 /******************************************************************************
4239 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4241 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4243 ULONG len;
4244 WCHAR *wptr, *wstr;
4246 if (SDRevision != SDDL_REVISION_1)
4248 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4249 SetLastError(ERROR_UNKNOWN_REVISION);
4250 return FALSE;
4253 len = 0;
4254 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4255 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4256 return FALSE;
4257 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4258 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4259 return FALSE;
4260 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4261 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4262 return FALSE;
4263 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4264 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4265 return FALSE;
4267 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4268 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4269 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4270 return FALSE;
4271 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4272 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4273 return FALSE;
4274 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4275 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4276 return FALSE;
4277 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4278 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4279 return FALSE;
4280 *wptr = 0;
4282 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4283 *OutputString = wstr;
4284 if (OutputLen)
4285 *OutputLen = strlenW(*OutputString)+1;
4286 return TRUE;
4289 /******************************************************************************
4290 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4292 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4294 LPWSTR wstr;
4295 ULONG len;
4296 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4298 int lenA;
4300 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4301 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4302 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4303 LocalFree(wstr);
4305 if (OutputLen != NULL)
4306 *OutputLen = lenA;
4307 return TRUE;
4309 else
4311 *OutputString = NULL;
4312 if (OutputLen)
4313 *OutputLen = 0;
4314 return FALSE;
4318 /******************************************************************************
4319 * ConvertStringSidToSidW [ADVAPI32.@]
4321 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4323 BOOL bret = FALSE;
4324 DWORD cBytes;
4326 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4327 if (GetVersion() & 0x80000000)
4328 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4329 else if (!StringSid || !Sid)
4330 SetLastError(ERROR_INVALID_PARAMETER);
4331 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4333 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4335 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4336 if (!bret)
4337 LocalFree(*Sid);
4339 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4340 return bret;
4343 /******************************************************************************
4344 * ConvertStringSidToSidA [ADVAPI32.@]
4346 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4348 BOOL bret = FALSE;
4350 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4351 if (GetVersion() & 0x80000000)
4352 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4353 else if (!StringSid || !Sid)
4354 SetLastError(ERROR_INVALID_PARAMETER);
4355 else
4357 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4358 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4359 len * sizeof(WCHAR));
4361 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4362 bret = ConvertStringSidToSidW(wStringSid, Sid);
4363 HeapFree(GetProcessHeap(), 0, wStringSid);
4365 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4366 return bret;
4369 /******************************************************************************
4370 * ConvertSidToStringSidW [ADVAPI32.@]
4372 * format of SID string is:
4373 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4374 * where
4375 * <rev> is the revision of the SID encoded as decimal
4376 * <auth> is the identifier authority encoded as hex
4377 * <subauthN> is the subauthority id encoded as decimal
4379 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4381 DWORD len = 0;
4382 LPWSTR wstr, wptr;
4384 TRACE("%p %p\n", pSid, pstr );
4386 len = 0;
4387 if (!DumpSidNumeric(pSid, NULL, &len))
4388 return FALSE;
4389 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4390 DumpSidNumeric(pSid, &wptr, NULL);
4391 *wptr = 0;
4393 *pstr = wstr;
4394 return TRUE;
4397 /******************************************************************************
4398 * ConvertSidToStringSidA [ADVAPI32.@]
4400 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4402 LPWSTR wstr = NULL;
4403 LPSTR str;
4404 UINT len;
4406 TRACE("%p %p\n", pSid, pstr );
4408 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4409 return FALSE;
4411 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4412 str = LocalAlloc( 0, len );
4413 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4414 LocalFree( wstr );
4416 *pstr = str;
4418 return TRUE;
4421 BOOL WINAPI CreatePrivateObjectSecurity(
4422 PSECURITY_DESCRIPTOR ParentDescriptor,
4423 PSECURITY_DESCRIPTOR CreatorDescriptor,
4424 PSECURITY_DESCRIPTOR* NewDescriptor,
4425 BOOL IsDirectoryObject,
4426 HANDLE Token,
4427 PGENERIC_MAPPING GenericMapping )
4429 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4430 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4432 return FALSE;
4435 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4437 FIXME("%p - stub\n", ObjectDescriptor);
4439 return TRUE;
4442 BOOL WINAPI CreateProcessAsUserA(
4443 HANDLE hToken,
4444 LPCSTR lpApplicationName,
4445 LPSTR lpCommandLine,
4446 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4447 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4448 BOOL bInheritHandles,
4449 DWORD dwCreationFlags,
4450 LPVOID lpEnvironment,
4451 LPCSTR lpCurrentDirectory,
4452 LPSTARTUPINFOA lpStartupInfo,
4453 LPPROCESS_INFORMATION lpProcessInformation )
4455 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4456 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4457 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4459 return FALSE;
4462 BOOL WINAPI CreateProcessAsUserW(
4463 HANDLE hToken,
4464 LPCWSTR lpApplicationName,
4465 LPWSTR lpCommandLine,
4466 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4467 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4468 BOOL bInheritHandles,
4469 DWORD dwCreationFlags,
4470 LPVOID lpEnvironment,
4471 LPCWSTR lpCurrentDirectory,
4472 LPSTARTUPINFOW lpStartupInfo,
4473 LPPROCESS_INFORMATION lpProcessInformation )
4475 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4476 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4477 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4478 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4480 /* We should create the process with a suspended main thread */
4481 if (!CreateProcessW (lpApplicationName,
4482 lpCommandLine,
4483 lpProcessAttributes,
4484 lpThreadAttributes,
4485 bInheritHandles,
4486 dwCreationFlags, /* CREATE_SUSPENDED */
4487 lpEnvironment,
4488 lpCurrentDirectory,
4489 lpStartupInfo,
4490 lpProcessInformation))
4492 return FALSE;
4495 return TRUE;
4498 /******************************************************************************
4499 * CreateProcessWithLogonW
4501 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4502 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4503 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4505 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4506 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4507 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4508 lpStartupInfo, lpProcessInformation);
4510 return FALSE;
4513 /******************************************************************************
4514 * DuplicateTokenEx [ADVAPI32.@]
4516 BOOL WINAPI DuplicateTokenEx(
4517 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4518 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4519 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4520 TOKEN_TYPE TokenType,
4521 PHANDLE DuplicateTokenHandle )
4523 OBJECT_ATTRIBUTES ObjectAttributes;
4525 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4526 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4528 InitializeObjectAttributes(
4529 &ObjectAttributes,
4530 NULL,
4531 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4532 NULL,
4533 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4535 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4536 dwDesiredAccess,
4537 &ObjectAttributes,
4538 ImpersonationLevel,
4539 TokenType,
4540 DuplicateTokenHandle ) );
4543 BOOL WINAPI DuplicateToken(
4544 HANDLE ExistingTokenHandle,
4545 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4546 PHANDLE DuplicateTokenHandle )
4548 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4549 NULL, ImpersonationLevel, TokenImpersonation,
4550 DuplicateTokenHandle );
4553 /******************************************************************************
4554 * ComputeStringSidSize
4556 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4558 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4560 int ctok = 0;
4561 while (*StringSid)
4563 if (*StringSid == '-')
4564 ctok++;
4565 StringSid++;
4568 if (ctok >= 3)
4569 return GetSidLengthRequired(ctok - 2);
4571 else /* String constant format - Only available in winxp and above */
4573 unsigned int i;
4575 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4576 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4577 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4580 return GetSidLengthRequired(0);
4583 /******************************************************************************
4584 * ParseStringSidToSid
4586 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4588 BOOL bret = FALSE;
4589 SID* pisid=pSid;
4591 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4592 if (!StringSid)
4594 SetLastError(ERROR_INVALID_PARAMETER);
4595 TRACE("StringSid is NULL, returning FALSE\n");
4596 return FALSE;
4599 *cBytes = ComputeStringSidSize(StringSid);
4600 if (!pisid) /* Simply compute the size */
4602 TRACE("only size requested, returning TRUE\n");
4603 return TRUE;
4606 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4608 DWORD i = 0, identAuth;
4609 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4611 StringSid += 2; /* Advance to Revision */
4612 pisid->Revision = atoiW(StringSid);
4614 if (pisid->Revision != SDDL_REVISION)
4616 TRACE("Revision %d is unknown\n", pisid->Revision);
4617 goto lend; /* ERROR_INVALID_SID */
4619 if (csubauth == 0)
4621 TRACE("SubAuthorityCount is 0\n");
4622 goto lend; /* ERROR_INVALID_SID */
4625 pisid->SubAuthorityCount = csubauth;
4627 /* Advance to identifier authority */
4628 while (*StringSid && *StringSid != '-')
4629 StringSid++;
4630 if (*StringSid == '-')
4631 StringSid++;
4633 /* MS' implementation can't handle values greater than 2^32 - 1, so
4634 * we don't either; assume most significant bytes are always 0
4636 pisid->IdentifierAuthority.Value[0] = 0;
4637 pisid->IdentifierAuthority.Value[1] = 0;
4638 identAuth = atoiW(StringSid);
4639 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4640 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4641 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4642 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4644 /* Advance to first sub authority */
4645 while (*StringSid && *StringSid != '-')
4646 StringSid++;
4647 if (*StringSid == '-')
4648 StringSid++;
4650 while (*StringSid)
4652 pisid->SubAuthority[i++] = atoiW(StringSid);
4654 while (*StringSid && *StringSid != '-')
4655 StringSid++;
4656 if (*StringSid == '-')
4657 StringSid++;
4660 if (i != pisid->SubAuthorityCount)
4661 goto lend; /* ERROR_INVALID_SID */
4663 bret = TRUE;
4665 else /* String constant format - Only available in winxp and above */
4667 unsigned int i;
4668 pisid->Revision = SDDL_REVISION;
4670 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4671 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4673 DWORD j;
4674 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4675 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4676 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4677 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4678 bret = TRUE;
4681 if (!bret)
4682 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4685 lend:
4686 if (!bret)
4687 SetLastError(ERROR_INVALID_SID);
4689 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4690 return bret;
4693 /******************************************************************************
4694 * GetNamedSecurityInfoA [ADVAPI32.@]
4696 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4697 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4698 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4699 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4701 DWORD len;
4702 LPWSTR wstr = NULL;
4703 DWORD r;
4705 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4706 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4708 if( pObjectName )
4710 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4711 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4712 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4715 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4716 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4718 HeapFree( GetProcessHeap(), 0, wstr );
4720 return r;
4723 /******************************************************************************
4724 * GetNamedSecurityInfoW [ADVAPI32.@]
4726 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4727 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4728 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4730 DWORD needed, offset;
4731 SECURITY_DESCRIPTOR_RELATIVE *relative;
4732 BYTE *buffer;
4734 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4735 group, dacl, sacl, descriptor );
4737 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4739 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4740 if (info & OWNER_SECURITY_INFORMATION)
4741 needed += sizeof(sidWorld);
4742 if (info & GROUP_SECURITY_INFORMATION)
4743 needed += sizeof(sidWorld);
4744 if (info & DACL_SECURITY_INFORMATION)
4745 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4746 if (info & SACL_SECURITY_INFORMATION)
4747 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4749 /* must be freed by caller */
4750 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4751 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4753 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4755 HeapFree( GetProcessHeap(), 0, *descriptor );
4756 return ERROR_INVALID_SECURITY_DESCR;
4759 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4760 relative->Control |= SE_SELF_RELATIVE;
4761 buffer = (BYTE *)relative;
4762 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4764 if (info & OWNER_SECURITY_INFORMATION)
4766 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4767 relative->Owner = offset;
4768 if (owner)
4769 *owner = buffer + offset;
4770 offset += sizeof(sidWorld);
4772 if (info & GROUP_SECURITY_INFORMATION)
4774 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4775 relative->Group = offset;
4776 if (group)
4777 *group = buffer + offset;
4778 offset += sizeof(sidWorld);
4780 if (info & DACL_SECURITY_INFORMATION)
4782 relative->Control |= SE_DACL_PRESENT;
4783 GetWorldAccessACL( (PACL)(buffer + offset) );
4784 relative->Dacl = offset;
4785 if (dacl)
4786 *dacl = (PACL)(buffer + offset);
4787 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4789 if (info & SACL_SECURITY_INFORMATION)
4791 relative->Control |= SE_SACL_PRESENT;
4792 GetWorldAccessACL( (PACL)(buffer + offset) );
4793 relative->Sacl = offset;
4794 if (sacl)
4795 *sacl = (PACL)(buffer + offset);
4797 return ERROR_SUCCESS;
4800 /******************************************************************************
4801 * DecryptFileW [ADVAPI32.@]
4803 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4805 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4806 return TRUE;
4809 /******************************************************************************
4810 * DecryptFileA [ADVAPI32.@]
4812 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4814 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4815 return TRUE;
4818 /******************************************************************************
4819 * EncryptFileW [ADVAPI32.@]
4821 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4823 FIXME("%s\n", debugstr_w(lpFileName));
4824 return TRUE;
4827 /******************************************************************************
4828 * EncryptFileA [ADVAPI32.@]
4830 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4832 FIXME("%s\n", debugstr_a(lpFileName));
4833 return TRUE;
4836 /******************************************************************************
4837 * FileEncryptionStatusW [ADVAPI32.@]
4839 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4841 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4842 if (!lpStatus)
4843 return FALSE;
4844 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4845 return TRUE;
4848 /******************************************************************************
4849 * FileEncryptionStatusA [ADVAPI32.@]
4851 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4853 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4854 if (!lpStatus)
4855 return FALSE;
4856 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4857 return TRUE;
4860 /******************************************************************************
4861 * SetSecurityInfo [ADVAPI32.@]
4863 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4864 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4865 PSID psidGroup, PACL pDacl, PACL pSacl) {
4866 FIXME("stub\n");
4867 return ERROR_SUCCESS;