push d49b3885cdb0e58b792f6bf912143b7a9a4ea546
[wine/hacks.git] / dlls / advapi32 / security.c
bloba26e81a74626c7efdec7a5055960e0a59d95c64e
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 "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 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 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 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 };
187 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
188 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 };
189 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
190 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
191 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
192 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
193 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
194 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
195 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
196 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 };
197 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
198 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 };
199 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
200 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
201 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
202 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
203 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
205 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
206 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 };
207 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
208 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
209 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
210 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
211 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
212 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
213 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
214 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 };
215 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 };
216 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
217 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 };
218 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
219 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
220 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
221 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 };
222 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 };
223 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
224 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
225 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 };
226 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
227 static const WCHAR SELF[] = { 'S','E','L','F',0 };
228 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
229 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
230 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
231 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 };
232 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
233 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
235 static const AccountSid ACCOUNT_SIDS[] = {
236 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
237 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
238 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
239 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
240 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
241 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
242 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
244 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
259 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
260 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
261 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
262 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
264 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
265 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
270 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
271 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
272 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
273 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
279 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
282 * ACE access rights
284 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
285 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
286 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
287 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
289 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
290 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
291 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
292 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
293 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
294 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
295 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
296 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
297 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
299 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
300 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
301 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
302 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
304 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
305 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
306 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
307 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
309 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
310 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
311 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
312 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
315 * ACL flags
317 static const WCHAR SDDL_PROTECTED[] = {'P',0};
318 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
319 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
322 * ACE types
324 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
325 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
326 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
328 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
329 static const WCHAR SDDL_ALARM[] = {'A','L',0};
330 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
331 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
334 * ACE flags
336 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
337 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
338 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
339 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
340 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
341 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
342 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
344 const char * debugstr_sid(PSID sid)
346 int auth = 0;
347 SID * psid = sid;
349 if (psid == NULL)
350 return "(null)";
352 auth = psid->IdentifierAuthority.Value[5] +
353 (psid->IdentifierAuthority.Value[4] << 8) +
354 (psid->IdentifierAuthority.Value[3] << 16) +
355 (psid->IdentifierAuthority.Value[2] << 24);
357 switch (psid->SubAuthorityCount) {
358 case 0:
359 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
360 case 1:
361 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
362 psid->SubAuthority[0]);
363 case 2:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1]);
366 case 3:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
369 case 4:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[3]);
373 case 5:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[3], psid->SubAuthority[4]);
377 case 6:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
381 case 7:
382 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
383 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
384 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
385 psid->SubAuthority[6]);
386 case 8:
387 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
388 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
389 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
390 psid->SubAuthority[6], psid->SubAuthority[7]);
392 return "(too-big)";
395 /* set last error code from NT status and get the proper boolean return value */
396 /* used for functions that are a simple wrapper around the corresponding ntdll API */
397 static inline BOOL set_ntstatus( NTSTATUS status )
399 if (status) SetLastError( RtlNtStatusToDosError( status ));
400 return !status;
403 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405 static void GetWorldAccessACL(PACL pACL)
407 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409 pACL->AclRevision = ACL_REVISION;
410 pACL->Sbz1 = 0;
411 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
412 pACL->AceCount = 1;
413 pACL->Sbz2 = 0;
415 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
416 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
417 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
418 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
419 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
422 /************************************************************
423 * ADVAPI_IsLocalComputer
425 * Checks whether the server name indicates local machine.
427 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
430 BOOL Result;
431 LPWSTR buf;
433 if (!ServerName || !ServerName[0])
434 return TRUE;
436 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
437 Result = GetComputerNameW(buf, &dwSize);
438 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
439 ServerName += 2;
440 Result = Result && !lstrcmpW(ServerName, buf);
441 HeapFree(GetProcessHeap(), 0, buf);
443 return Result;
446 /************************************************************
447 * ADVAPI_GetComputerSid
449 * Reads the computer SID from the registry.
451 BOOL ADVAPI_GetComputerSid(PSID sid)
453 HKEY key;
454 LONG ret;
455 BOOL retval = FALSE;
456 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 };
457 static const WCHAR V[] = { 'V',0 };
459 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
460 KEY_READ, &key)) == ERROR_SUCCESS)
462 DWORD size = 0;
463 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
464 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
467 if (data)
469 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
470 data, &size)) == ERROR_SUCCESS)
472 /* the SID is in the last 24 bytes of the binary data */
473 CopyMemory(sid, &data[size-24], 24);
474 retval = TRUE;
476 HeapFree(GetProcessHeap(), 0, data);
479 RegCloseKey(key);
482 if(retval == TRUE) return retval;
484 /* create a new random SID */
485 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
486 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488 PSID new_sid;
489 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
490 DWORD id[3];
492 if (RtlGenRandom(id, sizeof(id)))
494 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
497 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499 FreeSid(new_sid);
502 RegCloseKey(key);
505 return retval;
508 /* ##############################
509 ###### TOKEN FUNCTIONS ######
510 ##############################
513 /******************************************************************************
514 * OpenProcessToken [ADVAPI32.@]
515 * Opens the access token associated with a process handle.
517 * PARAMS
518 * ProcessHandle [I] Handle to process
519 * DesiredAccess [I] Desired access to process
520 * TokenHandle [O] Pointer to handle of open access token
522 * RETURNS
523 * Success: TRUE. TokenHandle contains the access token.
524 * Failure: FALSE.
526 * NOTES
527 * See NtOpenProcessToken.
529 BOOL WINAPI
530 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
531 HANDLE *TokenHandle )
533 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
536 /******************************************************************************
537 * OpenThreadToken [ADVAPI32.@]
539 * Opens the access token associated with a thread handle.
541 * PARAMS
542 * ThreadHandle [I] Handle to process
543 * DesiredAccess [I] Desired access to the thread
544 * OpenAsSelf [I] ???
545 * TokenHandle [O] Destination for the token handle
547 * RETURNS
548 * Success: TRUE. TokenHandle contains the access token.
549 * Failure: FALSE.
551 * NOTES
552 * See NtOpenThreadToken.
554 BOOL WINAPI
555 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
556 BOOL OpenAsSelf, HANDLE *TokenHandle)
558 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
561 BOOL WINAPI
562 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
563 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
566 PreviousState, ReturnLength));
569 /******************************************************************************
570 * AdjustTokenPrivileges [ADVAPI32.@]
572 * Adjust the privileges of an open token handle.
574 * PARAMS
575 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
576 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
577 * NewState [I] Desired new privileges of the token
578 * BufferLength [I] Length of NewState
579 * PreviousState [O] Destination for the previous state
580 * ReturnLength [I/O] Size of PreviousState
583 * RETURNS
584 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
585 * Failure: FALSE.
587 * NOTES
588 * See NtAdjustPrivilegesToken.
590 BOOL WINAPI
591 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
592 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
593 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 NTSTATUS status;
597 TRACE("\n");
599 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
600 NewState, BufferLength, PreviousState,
601 ReturnLength);
602 SetLastError( RtlNtStatusToDosError( status ));
603 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
604 return TRUE;
605 else
606 return FALSE;
609 /******************************************************************************
610 * CheckTokenMembership [ADVAPI32.@]
612 * Determine if an access token is a member of a SID.
614 * PARAMS
615 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
616 * SidToCheck [I] SID that possibly contains the token
617 * IsMember [O] Destination for result.
619 * RETURNS
620 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
621 * Failure: FALSE.
623 BOOL WINAPI
624 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
625 PBOOL IsMember )
627 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629 *IsMember = TRUE;
630 return(TRUE);
633 /******************************************************************************
634 * GetTokenInformation [ADVAPI32.@]
636 * Get a type of information about an access token.
638 * PARAMS
639 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
640 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
641 * tokeninfo [O] Destination for token information
642 * tokeninfolength [I] Length of tokeninfo
643 * retlen [O] Destination for returned token information length
645 * RETURNS
646 * Success: TRUE. tokeninfo contains retlen bytes of token information
647 * Failure: FALSE.
649 * NOTES
650 * See NtQueryInformationToken.
652 BOOL WINAPI
653 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
654 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 TRACE("(%p, %s, %p, %d, %p):\n",
657 token,
658 (tokeninfoclass == TokenUser) ? "TokenUser" :
659 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
660 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
661 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
662 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
663 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
664 (tokeninfoclass == TokenSource) ? "TokenSource" :
665 (tokeninfoclass == TokenType) ? "TokenType" :
666 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
667 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
668 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
669 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
670 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
671 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
672 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
673 "Unknown",
674 tokeninfo, tokeninfolength, retlen);
675 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
676 tokeninfolength, retlen));
679 /******************************************************************************
680 * SetTokenInformation [ADVAPI32.@]
682 * Set information for an access token.
684 * PARAMS
685 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
686 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
687 * tokeninfo [I] Token information to set
688 * tokeninfolength [I] Length of tokeninfo
690 * RETURNS
691 * Success: TRUE. The information for the token is set to tokeninfo.
692 * Failure: FALSE.
694 BOOL WINAPI
695 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
696 LPVOID tokeninfo, DWORD tokeninfolength )
698 TRACE("(%p, %s, %p, %d): stub\n",
699 token,
700 (tokeninfoclass == TokenUser) ? "TokenUser" :
701 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
702 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
703 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
704 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
705 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
706 (tokeninfoclass == TokenSource) ? "TokenSource" :
707 (tokeninfoclass == TokenType) ? "TokenType" :
708 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
709 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
710 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
711 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
712 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
713 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
714 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
715 "Unknown",
716 tokeninfo, tokeninfolength);
718 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
721 /*************************************************************************
722 * SetThreadToken [ADVAPI32.@]
724 * Assigns an 'impersonation token' to a thread so it can assume the
725 * security privileges of another thread or process. Can also remove
726 * a previously assigned token.
728 * PARAMS
729 * thread [O] Handle to thread to set the token for
730 * token [I] Token to set
732 * RETURNS
733 * Success: TRUE. The threads access token is set to token
734 * Failure: FALSE.
736 * NOTES
737 * Only supported on NT or higher. On Win9X this function does nothing.
738 * See SetTokenInformation.
740 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
743 ThreadImpersonationToken, &token, sizeof token ));
746 /*************************************************************************
747 * CreateRestrictedToken [ADVAPI32.@]
749 * Create a new more restricted token from an existing token.
751 * PARAMS
752 * baseToken [I] Token to base the new restricted token on
753 * flags [I] Options
754 * nDisableSids [I] Length of disableSids array
755 * disableSids [I] Array of SIDs to disable in the new token
756 * nDeletePrivs [I] Length of deletePrivs array
757 * deletePrivs [I] Array of privileges to delete in the new token
758 * nRestrictSids [I] Length of restrictSids array
759 * restrictSids [I] Array of SIDs to restrict in the new token
760 * newToken [O] Address where the new token is stored
762 * RETURNS
763 * Success: TRUE
764 * Failure: FALSE
766 BOOL WINAPI CreateRestrictedToken(
767 HANDLE baseToken,
768 DWORD flags,
769 DWORD nDisableSids,
770 PSID_AND_ATTRIBUTES disableSids,
771 DWORD nDeletePrivs,
772 PLUID_AND_ATTRIBUTES deletePrivs,
773 DWORD nRestrictSids,
774 PSID_AND_ATTRIBUTES restrictSids,
775 PHANDLE newToken)
777 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
778 baseToken, flags, nDisableSids, disableSids,
779 nDeletePrivs, deletePrivs,
780 nRestrictSids, restrictSids,
781 newToken);
782 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
783 return FALSE;
786 /* ##############################
787 ###### SID FUNCTIONS ######
788 ##############################
791 /******************************************************************************
792 * AllocateAndInitializeSid [ADVAPI32.@]
794 * PARAMS
795 * pIdentifierAuthority []
796 * nSubAuthorityCount []
797 * nSubAuthority0 []
798 * nSubAuthority1 []
799 * nSubAuthority2 []
800 * nSubAuthority3 []
801 * nSubAuthority4 []
802 * nSubAuthority5 []
803 * nSubAuthority6 []
804 * nSubAuthority7 []
805 * pSid []
807 BOOL WINAPI
808 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
809 BYTE nSubAuthorityCount,
810 DWORD nSubAuthority0, DWORD nSubAuthority1,
811 DWORD nSubAuthority2, DWORD nSubAuthority3,
812 DWORD nSubAuthority4, DWORD nSubAuthority5,
813 DWORD nSubAuthority6, DWORD nSubAuthority7,
814 PSID *pSid )
816 return set_ntstatus( RtlAllocateAndInitializeSid(
817 pIdentifierAuthority, nSubAuthorityCount,
818 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
819 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
820 pSid ));
823 /******************************************************************************
824 * FreeSid [ADVAPI32.@]
826 * PARAMS
827 * pSid []
829 PVOID WINAPI
830 FreeSid( PSID pSid )
832 RtlFreeSid(pSid);
833 return NULL; /* is documented like this */
836 /******************************************************************************
837 * CopySid [ADVAPI32.@]
839 * PARAMS
840 * nDestinationSidLength []
841 * pDestinationSid []
842 * pSourceSid []
844 BOOL WINAPI
845 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
850 /******************************************************************************
851 * CreateWellKnownSid [ADVAPI32.@]
853 BOOL WINAPI
854 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
855 PSID DomainSid,
856 PSID pSid,
857 DWORD* cbSid)
859 unsigned int i;
860 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
863 SetLastError(ERROR_INVALID_PARAMETER);
864 return FALSE;
867 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
868 if (WellKnownSids[i].Type == WellKnownSidType) {
869 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
871 if (*cbSid < length) {
872 SetLastError(ERROR_INSUFFICIENT_BUFFER);
873 return FALSE;
876 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
877 *cbSid = length;
878 return TRUE;
882 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
884 SetLastError(ERROR_INVALID_PARAMETER);
885 return FALSE;
888 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
889 if (WellKnownRids[i].Type == WellKnownSidType) {
890 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
891 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
892 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
894 if (*cbSid < output_sid_length) {
895 SetLastError(ERROR_INSUFFICIENT_BUFFER);
896 return FALSE;
899 CopyMemory(pSid, DomainSid, domain_sid_length);
900 (*GetSidSubAuthorityCount(pSid))++;
901 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
902 *cbSid = output_sid_length;
903 return TRUE;
906 SetLastError(ERROR_INVALID_PARAMETER);
907 return FALSE;
910 /******************************************************************************
911 * IsWellKnownSid [ADVAPI32.@]
913 BOOL WINAPI
914 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
916 unsigned int i;
917 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
919 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
920 if (WellKnownSids[i].Type == WellKnownSidType)
921 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
922 return TRUE;
924 return FALSE;
927 BOOL WINAPI
928 IsTokenRestricted( HANDLE TokenHandle )
930 TOKEN_GROUPS *groups;
931 DWORD size;
932 NTSTATUS status;
933 BOOL restricted;
935 TRACE("(%p)\n", TokenHandle);
937 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
938 if (status != STATUS_BUFFER_TOO_SMALL)
939 return FALSE;
941 groups = HeapAlloc(GetProcessHeap(), 0, size);
942 if (!groups)
944 SetLastError(ERROR_OUTOFMEMORY);
945 return FALSE;
948 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
949 if (status != STATUS_SUCCESS)
951 HeapFree(GetProcessHeap(), 0, groups);
952 return set_ntstatus(status);
955 if (groups->GroupCount)
956 restricted = TRUE;
957 else
958 restricted = FALSE;
960 HeapFree(GetProcessHeap(), 0, groups);
962 return restricted;
965 /******************************************************************************
966 * IsValidSid [ADVAPI32.@]
968 * PARAMS
969 * pSid []
971 BOOL WINAPI
972 IsValidSid( PSID pSid )
974 return RtlValidSid( pSid );
977 /******************************************************************************
978 * EqualSid [ADVAPI32.@]
980 * PARAMS
981 * pSid1 []
982 * pSid2 []
984 BOOL WINAPI
985 EqualSid( PSID pSid1, PSID pSid2 )
987 return RtlEqualSid( pSid1, pSid2 );
990 /******************************************************************************
991 * EqualPrefixSid [ADVAPI32.@]
993 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
995 return RtlEqualPrefixSid(pSid1, pSid2);
998 /******************************************************************************
999 * GetSidLengthRequired [ADVAPI32.@]
1001 * PARAMS
1002 * nSubAuthorityCount []
1004 DWORD WINAPI
1005 GetSidLengthRequired( BYTE nSubAuthorityCount )
1007 return RtlLengthRequiredSid(nSubAuthorityCount);
1010 /******************************************************************************
1011 * InitializeSid [ADVAPI32.@]
1013 * PARAMS
1014 * pIdentifierAuthority []
1016 BOOL WINAPI
1017 InitializeSid (
1018 PSID pSid,
1019 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1020 BYTE nSubAuthorityCount)
1022 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1025 DWORD WINAPI
1026 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1028 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1030 return 1;
1033 DWORD WINAPI
1034 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1036 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1038 return 1;
1041 /******************************************************************************
1042 * GetSidIdentifierAuthority [ADVAPI32.@]
1044 * PARAMS
1045 * pSid []
1047 PSID_IDENTIFIER_AUTHORITY WINAPI
1048 GetSidIdentifierAuthority( PSID pSid )
1050 return RtlIdentifierAuthoritySid(pSid);
1053 /******************************************************************************
1054 * GetSidSubAuthority [ADVAPI32.@]
1056 * PARAMS
1057 * pSid []
1058 * nSubAuthority []
1060 PDWORD WINAPI
1061 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1063 return RtlSubAuthoritySid(pSid, nSubAuthority);
1066 /******************************************************************************
1067 * GetSidSubAuthorityCount [ADVAPI32.@]
1069 * PARAMS
1070 * pSid []
1072 PUCHAR WINAPI
1073 GetSidSubAuthorityCount (PSID pSid)
1075 return RtlSubAuthorityCountSid(pSid);
1078 /******************************************************************************
1079 * GetLengthSid [ADVAPI32.@]
1081 * PARAMS
1082 * pSid []
1084 DWORD WINAPI
1085 GetLengthSid (PSID pSid)
1087 return RtlLengthSid(pSid);
1090 /* ##############################################
1091 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1092 ##############################################
1095 /******************************************************************************
1096 * BuildSecurityDescriptorA [ADVAPI32.@]
1098 * Builds a SD from
1100 * PARAMS
1101 * pOwner [I]
1102 * pGroup [I]
1103 * cCountOfAccessEntries [I]
1104 * pListOfAccessEntries [I]
1105 * cCountOfAuditEntries [I]
1106 * pListofAuditEntries [I]
1107 * pOldSD [I]
1108 * lpdwBufferLength [I/O]
1109 * pNewSD [O]
1111 * RETURNS
1112 * Success: ERROR_SUCCESS
1113 * Failure: nonzero error code from Winerror.h
1115 DWORD WINAPI BuildSecurityDescriptorA(
1116 IN PTRUSTEEA pOwner,
1117 IN PTRUSTEEA pGroup,
1118 IN ULONG cCountOfAccessEntries,
1119 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1120 IN ULONG cCountOfAuditEntries,
1121 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1122 IN PSECURITY_DESCRIPTOR pOldSD,
1123 IN OUT PULONG lpdwBufferLength,
1124 OUT PSECURITY_DESCRIPTOR* pNewSD)
1126 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1127 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1128 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1130 return ERROR_CALL_NOT_IMPLEMENTED;
1133 /******************************************************************************
1134 * BuildSecurityDescriptorW [ADVAPI32.@]
1136 * See BuildSecurityDescriptorA.
1138 DWORD WINAPI BuildSecurityDescriptorW(
1139 IN PTRUSTEEW pOwner,
1140 IN PTRUSTEEW pGroup,
1141 IN ULONG cCountOfAccessEntries,
1142 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1143 IN ULONG cCountOfAuditEntries,
1144 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1145 IN PSECURITY_DESCRIPTOR pOldSD,
1146 IN OUT PULONG lpdwBufferLength,
1147 OUT PSECURITY_DESCRIPTOR* pNewSD)
1149 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1150 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1151 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1153 return ERROR_CALL_NOT_IMPLEMENTED;
1156 /******************************************************************************
1157 * InitializeSecurityDescriptor [ADVAPI32.@]
1159 * PARAMS
1160 * pDescr []
1161 * revision []
1163 BOOL WINAPI
1164 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1166 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1170 /******************************************************************************
1171 * MakeAbsoluteSD [ADVAPI32.@]
1173 BOOL WINAPI MakeAbsoluteSD (
1174 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1175 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1176 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1177 OUT PACL pDacl,
1178 OUT LPDWORD lpdwDaclSize,
1179 OUT PACL pSacl,
1180 OUT LPDWORD lpdwSaclSize,
1181 OUT PSID pOwner,
1182 OUT LPDWORD lpdwOwnerSize,
1183 OUT PSID pPrimaryGroup,
1184 OUT LPDWORD lpdwPrimaryGroupSize)
1186 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1187 pAbsoluteSecurityDescriptor,
1188 lpdwAbsoluteSecurityDescriptorSize,
1189 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1190 pOwner, lpdwOwnerSize,
1191 pPrimaryGroup, lpdwPrimaryGroupSize));
1194 /******************************************************************************
1195 * GetKernelObjectSecurity [ADVAPI32.@]
1197 BOOL WINAPI GetKernelObjectSecurity(
1198 HANDLE Handle,
1199 SECURITY_INFORMATION RequestedInformation,
1200 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1201 DWORD nLength,
1202 LPDWORD lpnLengthNeeded )
1204 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1205 pSecurityDescriptor, nLength, lpnLengthNeeded);
1207 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1208 nLength, lpnLengthNeeded ));
1211 /******************************************************************************
1212 * GetPrivateObjectSecurity [ADVAPI32.@]
1214 BOOL WINAPI GetPrivateObjectSecurity(
1215 PSECURITY_DESCRIPTOR ObjectDescriptor,
1216 SECURITY_INFORMATION SecurityInformation,
1217 PSECURITY_DESCRIPTOR ResultantDescriptor,
1218 DWORD DescriptorLength,
1219 PDWORD ReturnLength )
1221 SECURITY_DESCRIPTOR desc;
1222 BOOL defaulted, present;
1223 PACL pacl;
1224 PSID psid;
1226 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1227 ResultantDescriptor, DescriptorLength, ReturnLength);
1229 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1230 return FALSE;
1232 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1234 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1235 return FALSE;
1236 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1239 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1241 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1242 return FALSE;
1243 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1246 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1248 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1249 return FALSE;
1250 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1253 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1255 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1256 return FALSE;
1257 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1260 *ReturnLength = DescriptorLength;
1261 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1264 /******************************************************************************
1265 * GetSecurityDescriptorLength [ADVAPI32.@]
1267 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1269 return RtlLengthSecurityDescriptor(pDescr);
1272 /******************************************************************************
1273 * GetSecurityDescriptorOwner [ADVAPI32.@]
1275 * PARAMS
1276 * pOwner []
1277 * lpbOwnerDefaulted []
1279 BOOL WINAPI
1280 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1281 LPBOOL lpbOwnerDefaulted )
1283 BOOLEAN defaulted;
1284 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1285 *lpbOwnerDefaulted = defaulted;
1286 return ret;
1289 /******************************************************************************
1290 * SetSecurityDescriptorOwner [ADVAPI32.@]
1292 * PARAMS
1294 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1295 PSID pOwner, BOOL bOwnerDefaulted)
1297 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1299 /******************************************************************************
1300 * GetSecurityDescriptorGroup [ADVAPI32.@]
1302 BOOL WINAPI GetSecurityDescriptorGroup(
1303 PSECURITY_DESCRIPTOR SecurityDescriptor,
1304 PSID *Group,
1305 LPBOOL GroupDefaulted)
1307 BOOLEAN defaulted;
1308 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1309 *GroupDefaulted = defaulted;
1310 return ret;
1312 /******************************************************************************
1313 * SetSecurityDescriptorGroup [ADVAPI32.@]
1315 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1316 PSID Group, BOOL GroupDefaulted)
1318 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1321 /******************************************************************************
1322 * IsValidSecurityDescriptor [ADVAPI32.@]
1324 * PARAMS
1325 * lpsecdesc []
1327 BOOL WINAPI
1328 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1330 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1333 /******************************************************************************
1334 * GetSecurityDescriptorDacl [ADVAPI32.@]
1336 BOOL WINAPI GetSecurityDescriptorDacl(
1337 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1338 OUT LPBOOL lpbDaclPresent,
1339 OUT PACL *pDacl,
1340 OUT LPBOOL lpbDaclDefaulted)
1342 BOOLEAN present, defaulted;
1343 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1344 *lpbDaclPresent = present;
1345 *lpbDaclDefaulted = defaulted;
1346 return ret;
1349 /******************************************************************************
1350 * SetSecurityDescriptorDacl [ADVAPI32.@]
1352 BOOL WINAPI
1353 SetSecurityDescriptorDacl (
1354 PSECURITY_DESCRIPTOR lpsd,
1355 BOOL daclpresent,
1356 PACL dacl,
1357 BOOL dacldefaulted )
1359 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1361 /******************************************************************************
1362 * GetSecurityDescriptorSacl [ADVAPI32.@]
1364 BOOL WINAPI GetSecurityDescriptorSacl(
1365 IN PSECURITY_DESCRIPTOR lpsd,
1366 OUT LPBOOL lpbSaclPresent,
1367 OUT PACL *pSacl,
1368 OUT LPBOOL lpbSaclDefaulted)
1370 BOOLEAN present, defaulted;
1371 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1372 *lpbSaclPresent = present;
1373 *lpbSaclDefaulted = defaulted;
1374 return ret;
1377 /**************************************************************************
1378 * SetSecurityDescriptorSacl [ADVAPI32.@]
1380 BOOL WINAPI SetSecurityDescriptorSacl (
1381 PSECURITY_DESCRIPTOR lpsd,
1382 BOOL saclpresent,
1383 PACL lpsacl,
1384 BOOL sacldefaulted)
1386 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1388 /******************************************************************************
1389 * MakeSelfRelativeSD [ADVAPI32.@]
1391 * PARAMS
1392 * lpabssecdesc []
1393 * lpselfsecdesc []
1394 * lpbuflen []
1396 BOOL WINAPI
1397 MakeSelfRelativeSD(
1398 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1399 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1400 IN OUT LPDWORD lpdwBufferLength)
1402 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1403 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1406 /******************************************************************************
1407 * GetSecurityDescriptorControl [ADVAPI32.@]
1410 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1413 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1416 /******************************************************************************
1417 * SetSecurityDescriptorControl [ADVAPI32.@]
1419 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1420 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1421 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1423 return set_ntstatus( RtlSetControlSecurityDescriptor(
1424 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1427 /* ##############################
1428 ###### ACL FUNCTIONS ######
1429 ##############################
1432 /*************************************************************************
1433 * InitializeAcl [ADVAPI32.@]
1435 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1437 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1440 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1442 IO_STATUS_BLOCK io_block;
1444 TRACE("(%p)\n", hNamedPipe);
1446 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1447 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1450 /******************************************************************************
1451 * AddAccessAllowedAce [ADVAPI32.@]
1453 BOOL WINAPI AddAccessAllowedAce(
1454 IN OUT PACL pAcl,
1455 IN DWORD dwAceRevision,
1456 IN DWORD AccessMask,
1457 IN PSID pSid)
1459 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1462 /******************************************************************************
1463 * AddAccessAllowedAceEx [ADVAPI32.@]
1465 BOOL WINAPI AddAccessAllowedAceEx(
1466 IN OUT PACL pAcl,
1467 IN DWORD dwAceRevision,
1468 IN DWORD AceFlags,
1469 IN DWORD AccessMask,
1470 IN PSID pSid)
1472 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1475 /******************************************************************************
1476 * AddAccessDeniedAce [ADVAPI32.@]
1478 BOOL WINAPI AddAccessDeniedAce(
1479 IN OUT PACL pAcl,
1480 IN DWORD dwAceRevision,
1481 IN DWORD AccessMask,
1482 IN PSID pSid)
1484 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1487 /******************************************************************************
1488 * AddAccessDeniedAceEx [ADVAPI32.@]
1490 BOOL WINAPI AddAccessDeniedAceEx(
1491 IN OUT PACL pAcl,
1492 IN DWORD dwAceRevision,
1493 IN DWORD AceFlags,
1494 IN DWORD AccessMask,
1495 IN PSID pSid)
1497 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1500 /******************************************************************************
1501 * AddAce [ADVAPI32.@]
1503 BOOL WINAPI AddAce(
1504 IN OUT PACL pAcl,
1505 IN DWORD dwAceRevision,
1506 IN DWORD dwStartingAceIndex,
1507 LPVOID pAceList,
1508 DWORD nAceListLength)
1510 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1513 /******************************************************************************
1514 * DeleteAce [ADVAPI32.@]
1516 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1518 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1521 /******************************************************************************
1522 * FindFirstFreeAce [ADVAPI32.@]
1524 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1526 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1529 /******************************************************************************
1530 * GetAce [ADVAPI32.@]
1532 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1534 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1537 /******************************************************************************
1538 * GetAclInformation [ADVAPI32.@]
1540 BOOL WINAPI GetAclInformation(
1541 PACL pAcl,
1542 LPVOID pAclInformation,
1543 DWORD nAclInformationLength,
1544 ACL_INFORMATION_CLASS dwAclInformationClass)
1546 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1547 nAclInformationLength, dwAclInformationClass));
1550 /******************************************************************************
1551 * IsValidAcl [ADVAPI32.@]
1553 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1555 return RtlValidAcl(pAcl);
1558 /* ##############################
1559 ###### MISC FUNCTIONS ######
1560 ##############################
1563 /******************************************************************************
1564 * AllocateLocallyUniqueId [ADVAPI32.@]
1566 * PARAMS
1567 * lpLuid []
1569 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1571 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1574 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1575 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1576 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1577 { '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 };
1578 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1579 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1580 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1581 { '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 };
1582 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1583 { '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 };
1584 static const WCHAR SE_TCB_NAME_W[] =
1585 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1586 static const WCHAR SE_SECURITY_NAME_W[] =
1587 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1588 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1589 { '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 };
1590 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1591 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1593 { '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 };
1594 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1595 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1597 { '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 };
1598 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1599 { '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 };
1600 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1601 { '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 };
1602 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1603 { '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 };
1604 static const WCHAR SE_BACKUP_NAME_W[] =
1605 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1606 static const WCHAR SE_RESTORE_NAME_W[] =
1607 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1609 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1610 static const WCHAR SE_DEBUG_NAME_W[] =
1611 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_AUDIT_NAME_W[] =
1613 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1614 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1615 { '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 };
1616 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1617 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1618 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1619 { '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 };
1620 static const WCHAR SE_UNDOCK_NAME_W[] =
1621 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1623 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1625 { '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 };
1626 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1627 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1629 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1631 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1633 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1635 NULL,
1636 NULL,
1637 SE_CREATE_TOKEN_NAME_W,
1638 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1639 SE_LOCK_MEMORY_NAME_W,
1640 SE_INCREASE_QUOTA_NAME_W,
1641 SE_MACHINE_ACCOUNT_NAME_W,
1642 SE_TCB_NAME_W,
1643 SE_SECURITY_NAME_W,
1644 SE_TAKE_OWNERSHIP_NAME_W,
1645 SE_LOAD_DRIVER_NAME_W,
1646 SE_SYSTEM_PROFILE_NAME_W,
1647 SE_SYSTEMTIME_NAME_W,
1648 SE_PROF_SINGLE_PROCESS_NAME_W,
1649 SE_INC_BASE_PRIORITY_NAME_W,
1650 SE_CREATE_PAGEFILE_NAME_W,
1651 SE_CREATE_PERMANENT_NAME_W,
1652 SE_BACKUP_NAME_W,
1653 SE_RESTORE_NAME_W,
1654 SE_SHUTDOWN_NAME_W,
1655 SE_DEBUG_NAME_W,
1656 SE_AUDIT_NAME_W,
1657 SE_SYSTEM_ENVIRONMENT_NAME_W,
1658 SE_CHANGE_NOTIFY_NAME_W,
1659 SE_REMOTE_SHUTDOWN_NAME_W,
1660 SE_UNDOCK_NAME_W,
1661 SE_SYNC_AGENT_NAME_W,
1662 SE_ENABLE_DELEGATION_NAME_W,
1663 SE_MANAGE_VOLUME_NAME_W,
1664 SE_IMPERSONATE_NAME_W,
1665 SE_CREATE_GLOBAL_NAME_W,
1668 /******************************************************************************
1669 * LookupPrivilegeValueW [ADVAPI32.@]
1671 * See LookupPrivilegeValueA.
1673 BOOL WINAPI
1674 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1676 UINT i;
1678 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1680 if (!ADVAPI_IsLocalComputer(lpSystemName))
1682 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1683 return FALSE;
1685 if (!lpName)
1687 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1688 return FALSE;
1690 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1692 if( !WellKnownPrivNames[i] )
1693 continue;
1694 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1695 continue;
1696 lpLuid->LowPart = i;
1697 lpLuid->HighPart = 0;
1698 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1699 lpLuid->HighPart, lpLuid->LowPart );
1700 return TRUE;
1702 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1703 return FALSE;
1706 /******************************************************************************
1707 * LookupPrivilegeValueA [ADVAPI32.@]
1709 * Retrieves LUID used on a system to represent the privilege name.
1711 * PARAMS
1712 * lpSystemName [I] Name of the system
1713 * lpName [I] Name of the privilege
1714 * lpLuid [O] Destination for the resulting LUID
1716 * RETURNS
1717 * Success: TRUE. lpLuid contains the requested LUID.
1718 * Failure: FALSE.
1720 BOOL WINAPI
1721 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1723 UNICODE_STRING lpSystemNameW;
1724 UNICODE_STRING lpNameW;
1725 BOOL ret;
1727 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1728 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1729 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1730 RtlFreeUnicodeString(&lpNameW);
1731 RtlFreeUnicodeString(&lpSystemNameW);
1732 return ret;
1735 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1736 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1738 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1739 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1741 return FALSE;
1744 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1745 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1747 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1748 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1750 return FALSE;
1753 /******************************************************************************
1754 * LookupPrivilegeNameA [ADVAPI32.@]
1756 * See LookupPrivilegeNameW.
1758 BOOL WINAPI
1759 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1760 LPDWORD cchName)
1762 UNICODE_STRING lpSystemNameW;
1763 BOOL ret;
1764 DWORD wLen = 0;
1766 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1768 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1769 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1770 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1772 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1774 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1775 &wLen);
1776 if (ret)
1778 /* Windows crashes if cchName is NULL, so will I */
1779 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1780 *cchName, NULL, NULL);
1782 if (len == 0)
1784 /* WideCharToMultiByte failed */
1785 ret = FALSE;
1787 else if (len > *cchName)
1789 *cchName = len;
1790 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1791 ret = FALSE;
1793 else
1795 /* WideCharToMultiByte succeeded, output length needs to be
1796 * length not including NULL terminator
1798 *cchName = len - 1;
1801 HeapFree(GetProcessHeap(), 0, lpNameW);
1803 RtlFreeUnicodeString(&lpSystemNameW);
1804 return ret;
1807 /******************************************************************************
1808 * LookupPrivilegeNameW [ADVAPI32.@]
1810 * Retrieves the privilege name referred to by the LUID lpLuid.
1812 * PARAMS
1813 * lpSystemName [I] Name of the system
1814 * lpLuid [I] Privilege value
1815 * lpName [O] Name of the privilege
1816 * cchName [I/O] Number of characters in lpName.
1818 * RETURNS
1819 * Success: TRUE. lpName contains the name of the privilege whose value is
1820 * *lpLuid.
1821 * Failure: FALSE.
1823 * REMARKS
1824 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1825 * using this function.
1826 * If the length of lpName is too small, on return *cchName will contain the
1827 * number of WCHARs needed to contain the privilege, including the NULL
1828 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1829 * On success, *cchName will contain the number of characters stored in
1830 * lpName, NOT including the NULL terminator.
1832 BOOL WINAPI
1833 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1834 LPDWORD cchName)
1836 size_t privNameLen;
1838 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1840 if (!ADVAPI_IsLocalComputer(lpSystemName))
1842 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1843 return FALSE;
1845 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1846 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1848 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1849 return FALSE;
1851 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1852 /* Windows crashes if cchName is NULL, so will I */
1853 if (*cchName <= privNameLen)
1855 *cchName = privNameLen + 1;
1856 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1857 return FALSE;
1859 else
1861 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1862 *cchName = privNameLen;
1863 return TRUE;
1867 /******************************************************************************
1868 * GetFileSecurityA [ADVAPI32.@]
1870 * Obtains Specified information about the security of a file or directory.
1872 * PARAMS
1873 * lpFileName [I] Name of the file to get info for
1874 * RequestedInformation [I] SE_ flags from "winnt.h"
1875 * pSecurityDescriptor [O] Destination for security information
1876 * nLength [I] Length of pSecurityDescriptor
1877 * lpnLengthNeeded [O] Destination for length of returned security information
1879 * RETURNS
1880 * Success: TRUE. pSecurityDescriptor contains the requested information.
1881 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1883 * NOTES
1884 * The information returned is constrained by the callers access rights and
1885 * privileges.
1887 BOOL WINAPI
1888 GetFileSecurityA( LPCSTR lpFileName,
1889 SECURITY_INFORMATION RequestedInformation,
1890 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1891 DWORD nLength, LPDWORD lpnLengthNeeded )
1893 DWORD len;
1894 BOOL r;
1895 LPWSTR name = NULL;
1897 if( lpFileName )
1899 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1900 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1901 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1904 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1905 nLength, lpnLengthNeeded );
1906 HeapFree( GetProcessHeap(), 0, name );
1908 return r;
1911 /******************************************************************************
1912 * GetFileSecurityW [ADVAPI32.@]
1914 * See GetFileSecurityA.
1916 BOOL WINAPI
1917 GetFileSecurityW( LPCWSTR lpFileName,
1918 SECURITY_INFORMATION RequestedInformation,
1919 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1920 DWORD nLength, LPDWORD lpnLengthNeeded )
1922 HANDLE hfile;
1923 NTSTATUS status;
1924 DWORD access = 0;
1926 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1927 RequestedInformation, pSecurityDescriptor,
1928 nLength, lpnLengthNeeded);
1930 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1931 DACL_SECURITY_INFORMATION))
1932 access |= READ_CONTROL;
1933 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1934 access |= ACCESS_SYSTEM_SECURITY;
1936 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1937 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1938 if ( hfile == INVALID_HANDLE_VALUE )
1939 return FALSE;
1941 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1942 nLength, lpnLengthNeeded );
1943 CloseHandle( hfile );
1944 return set_ntstatus( status );
1948 /******************************************************************************
1949 * LookupAccountSidA [ADVAPI32.@]
1951 BOOL WINAPI
1952 LookupAccountSidA(
1953 IN LPCSTR system,
1954 IN PSID sid,
1955 OUT LPSTR account,
1956 IN OUT LPDWORD accountSize,
1957 OUT LPSTR domain,
1958 IN OUT LPDWORD domainSize,
1959 OUT PSID_NAME_USE name_use )
1961 DWORD len;
1962 BOOL r;
1963 LPWSTR systemW = NULL;
1964 LPWSTR accountW = NULL;
1965 LPWSTR domainW = NULL;
1966 DWORD accountSizeW = *accountSize;
1967 DWORD domainSizeW = *domainSize;
1969 if (system) {
1970 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1971 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1972 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1974 if (account)
1975 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1976 if (domain)
1977 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1979 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1981 if (r) {
1982 if (accountW && *accountSize) {
1983 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1984 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1985 *accountSize = len;
1986 } else
1987 *accountSize = accountSizeW + 1;
1989 if (domainW && *domainSize) {
1990 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1991 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1992 *domainSize = len;
1993 } else
1994 *domainSize = domainSizeW + 1;
1997 HeapFree( GetProcessHeap(), 0, systemW );
1998 HeapFree( GetProcessHeap(), 0, accountW );
1999 HeapFree( GetProcessHeap(), 0, domainW );
2001 return r;
2004 /******************************************************************************
2005 * LookupAccountSidW [ADVAPI32.@]
2007 * PARAMS
2008 * system []
2009 * sid []
2010 * account []
2011 * accountSize []
2012 * domain []
2013 * domainSize []
2014 * name_use []
2017 BOOL WINAPI
2018 LookupAccountSidW(
2019 IN LPCWSTR system,
2020 IN PSID sid,
2021 OUT LPWSTR account,
2022 IN OUT LPDWORD accountSize,
2023 OUT LPWSTR domain,
2024 IN OUT LPDWORD domainSize,
2025 OUT PSID_NAME_USE name_use )
2027 unsigned int i, j;
2028 const WCHAR * ac = NULL;
2029 const WCHAR * dm = NULL;
2030 SID_NAME_USE use = 0;
2031 LPWSTR computer_name = NULL;
2032 LPWSTR account_name = NULL;
2034 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2035 debugstr_w(system),debugstr_sid(sid),
2036 account,accountSize,accountSize?*accountSize:0,
2037 domain,domainSize,domainSize?*domainSize:0,
2038 name_use);
2040 if (!ADVAPI_IsLocalComputer(system)) {
2041 FIXME("Only local computer supported!\n");
2042 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2043 return FALSE;
2046 /* check the well known SIDs first */
2047 for (i = 0; i <= 60; i++) {
2048 if (IsWellKnownSid(sid, i)) {
2049 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2050 if (ACCOUNT_SIDS[j].type == i) {
2051 ac = ACCOUNT_SIDS[j].account;
2052 dm = ACCOUNT_SIDS[j].domain;
2053 use = ACCOUNT_SIDS[j].name_use;
2056 break;
2060 if (dm == NULL) {
2061 MAX_SID local;
2063 /* check for the local computer next */
2064 if (ADVAPI_GetComputerSid(&local)) {
2065 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2066 BOOL result;
2068 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2069 result = GetComputerNameW(computer_name, &size);
2071 if (result) {
2072 if (EqualSid(sid, &local)) {
2073 dm = computer_name;
2074 ac = Blank;
2075 use = 3;
2076 } else {
2077 local.SubAuthorityCount++;
2079 if (EqualPrefixSid(sid, &local)) {
2080 dm = computer_name;
2081 use = 1;
2082 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2083 case DOMAIN_USER_RID_ADMIN:
2084 ac = Administrator;
2085 break;
2086 case DOMAIN_USER_RID_GUEST:
2087 ac = Guest;
2088 break;
2089 case DOMAIN_GROUP_RID_ADMINS:
2090 ac = Domain_Admins;
2091 break;
2092 case DOMAIN_GROUP_RID_USERS:
2093 ac = Domain_Users;
2094 break;
2095 case DOMAIN_GROUP_RID_GUESTS:
2096 ac = Domain_Guests;
2097 break;
2098 case DOMAIN_GROUP_RID_COMPUTERS:
2099 ac = Domain_Computers;
2100 break;
2101 case DOMAIN_GROUP_RID_CONTROLLERS:
2102 ac = Domain_Controllers;
2103 break;
2104 case DOMAIN_GROUP_RID_CERT_ADMINS:
2105 ac = Cert_Publishers;
2106 break;
2107 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2108 ac = Schema_Admins;
2109 break;
2110 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2111 ac = Enterprise_Admins;
2112 break;
2113 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2114 ac = Group_Policy_Creator_Owners;
2115 break;
2116 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2117 ac = RAS_and_IAS_Servers;
2118 break;
2119 case 1000: /* first user account */
2120 size = UNLEN + 1;
2121 account_name = HeapAlloc(
2122 GetProcessHeap(), 0, size * sizeof(WCHAR));
2123 if (GetUserNameW(account_name, &size))
2124 ac = account_name;
2125 else
2126 dm = NULL;
2128 break;
2129 default:
2130 dm = NULL;
2131 break;
2139 if (dm) {
2140 DWORD ac_len = lstrlenW(ac);
2141 DWORD dm_len = lstrlenW(dm);
2142 BOOL status = TRUE;
2144 if (*accountSize > ac_len) {
2145 if (account)
2146 lstrcpyW(account, ac);
2148 if (*domainSize > dm_len) {
2149 if (domain)
2150 lstrcpyW(domain, dm);
2152 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2153 ((*domainSize != 0) && (*domainSize < dm_len))) {
2154 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2155 status = FALSE;
2157 if (*domainSize)
2158 *domainSize = dm_len;
2159 else
2160 *domainSize = dm_len + 1;
2161 if (*accountSize)
2162 *accountSize = ac_len;
2163 else
2164 *accountSize = ac_len + 1;
2165 *name_use = use;
2166 HeapFree(GetProcessHeap(), 0, account_name);
2167 HeapFree(GetProcessHeap(), 0, computer_name);
2168 return status;
2171 HeapFree(GetProcessHeap(), 0, account_name);
2172 HeapFree(GetProcessHeap(), 0, computer_name);
2173 SetLastError(ERROR_NONE_MAPPED);
2174 return FALSE;
2177 /******************************************************************************
2178 * SetFileSecurityA [ADVAPI32.@]
2180 * See SetFileSecurityW.
2182 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2183 SECURITY_INFORMATION RequestedInformation,
2184 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2186 DWORD len;
2187 BOOL r;
2188 LPWSTR name = NULL;
2190 if( lpFileName )
2192 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2193 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2194 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2197 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2198 HeapFree( GetProcessHeap(), 0, name );
2200 return r;
2203 /******************************************************************************
2204 * SetFileSecurityW [ADVAPI32.@]
2206 * Sets the security of a file or directory.
2208 * PARAMS
2209 * lpFileName []
2210 * RequestedInformation []
2211 * pSecurityDescriptor []
2213 * RETURNS
2214 * Success: TRUE.
2215 * Failure: FALSE.
2217 BOOL WINAPI
2218 SetFileSecurityW( LPCWSTR lpFileName,
2219 SECURITY_INFORMATION RequestedInformation,
2220 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2222 HANDLE file;
2223 DWORD access = 0;
2224 NTSTATUS status;
2226 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2227 pSecurityDescriptor );
2229 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2230 RequestedInformation & GROUP_SECURITY_INFORMATION)
2231 access |= WRITE_OWNER;
2232 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2233 access |= ACCESS_SYSTEM_SECURITY;
2234 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2235 access |= WRITE_DAC;
2237 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2238 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2239 if (file == INVALID_HANDLE_VALUE)
2240 return FALSE;
2242 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2243 CloseHandle( file );
2244 return set_ntstatus( status );
2247 /******************************************************************************
2248 * QueryWindows31FilesMigration [ADVAPI32.@]
2250 * PARAMS
2251 * x1 []
2253 BOOL WINAPI
2254 QueryWindows31FilesMigration( DWORD x1 )
2256 FIXME("(%d):stub\n",x1);
2257 return TRUE;
2260 /******************************************************************************
2261 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2263 * PARAMS
2264 * x1 []
2265 * x2 []
2266 * x3 []
2267 * x4 []
2269 BOOL WINAPI
2270 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2271 DWORD x4 )
2273 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2274 return TRUE;
2277 /******************************************************************************
2278 * NotifyBootConfigStatus [ADVAPI32.@]
2280 * PARAMS
2281 * x1 []
2283 BOOL WINAPI
2284 NotifyBootConfigStatus( BOOL x1 )
2286 FIXME("(0x%08d):stub\n",x1);
2287 return 1;
2290 /******************************************************************************
2291 * RevertToSelf [ADVAPI32.@]
2293 * Ends the impersonation of a user.
2295 * PARAMS
2296 * void []
2298 * RETURNS
2299 * Success: TRUE.
2300 * Failure: FALSE.
2302 BOOL WINAPI
2303 RevertToSelf( void )
2305 HANDLE Token = NULL;
2306 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2307 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2310 /******************************************************************************
2311 * ImpersonateSelf [ADVAPI32.@]
2313 * Makes an impersonation token that represents the process user and assigns
2314 * to the current thread.
2316 * PARAMS
2317 * ImpersonationLevel [I] Level at which to impersonate.
2319 * RETURNS
2320 * Success: TRUE.
2321 * Failure: FALSE.
2323 BOOL WINAPI
2324 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2326 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2329 /******************************************************************************
2330 * ImpersonateLoggedOnUser [ADVAPI32.@]
2332 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2334 DWORD size;
2335 NTSTATUS Status;
2336 HANDLE ImpersonationToken;
2337 TOKEN_TYPE Type;
2338 static BOOL warn = TRUE;
2340 if (warn)
2342 FIXME( "(%p)\n", hToken );
2343 warn = FALSE;
2345 if (!GetTokenInformation( hToken, TokenType, &Type,
2346 sizeof(TOKEN_TYPE), &size ))
2347 return FALSE;
2349 if (Type == TokenPrimary)
2351 OBJECT_ATTRIBUTES ObjectAttributes;
2353 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2355 Status = NtDuplicateToken( hToken,
2356 TOKEN_IMPERSONATE | TOKEN_QUERY,
2357 &ObjectAttributes,
2358 SecurityImpersonation,
2359 TokenImpersonation,
2360 &ImpersonationToken );
2361 if (Status != STATUS_SUCCESS)
2363 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2364 SetLastError( RtlNtStatusToDosError( Status ) );
2365 return FALSE;
2368 else
2369 ImpersonationToken = hToken;
2371 Status = NtSetInformationThread( GetCurrentThread(),
2372 ThreadImpersonationToken,
2373 &ImpersonationToken,
2374 sizeof(ImpersonationToken) );
2376 if (Type == TokenPrimary)
2377 NtClose( ImpersonationToken );
2379 if (Status != STATUS_SUCCESS)
2381 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2382 SetLastError( RtlNtStatusToDosError( Status ) );
2383 return FALSE;
2386 return TRUE;
2389 /******************************************************************************
2390 * AccessCheck [ADVAPI32.@]
2392 BOOL WINAPI
2393 AccessCheck(
2394 PSECURITY_DESCRIPTOR SecurityDescriptor,
2395 HANDLE ClientToken,
2396 DWORD DesiredAccess,
2397 PGENERIC_MAPPING GenericMapping,
2398 PPRIVILEGE_SET PrivilegeSet,
2399 LPDWORD PrivilegeSetLength,
2400 LPDWORD GrantedAccess,
2401 LPBOOL AccessStatus)
2403 NTSTATUS access_status;
2404 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2405 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2406 GrantedAccess, &access_status) );
2407 if (ret) *AccessStatus = set_ntstatus( access_status );
2408 return ret;
2412 /******************************************************************************
2413 * AccessCheckByType [ADVAPI32.@]
2415 BOOL WINAPI AccessCheckByType(
2416 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2417 PSID PrincipalSelfSid,
2418 HANDLE ClientToken,
2419 DWORD DesiredAccess,
2420 POBJECT_TYPE_LIST ObjectTypeList,
2421 DWORD ObjectTypeListLength,
2422 PGENERIC_MAPPING GenericMapping,
2423 PPRIVILEGE_SET PrivilegeSet,
2424 LPDWORD PrivilegeSetLength,
2425 LPDWORD GrantedAccess,
2426 LPBOOL AccessStatus)
2428 FIXME("stub\n");
2430 *AccessStatus = TRUE;
2432 return !*AccessStatus;
2435 /******************************************************************************
2436 * MapGenericMask [ADVAPI32.@]
2438 * Maps generic access rights into specific access rights according to the
2439 * supplied mapping.
2441 * PARAMS
2442 * AccessMask [I/O] Access rights.
2443 * GenericMapping [I] The mapping between generic and specific rights.
2445 * RETURNS
2446 * Nothing.
2448 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2450 RtlMapGenericMask( AccessMask, GenericMapping );
2453 /*************************************************************************
2454 * SetKernelObjectSecurity [ADVAPI32.@]
2456 BOOL WINAPI SetKernelObjectSecurity (
2457 IN HANDLE Handle,
2458 IN SECURITY_INFORMATION SecurityInformation,
2459 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2461 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2465 /******************************************************************************
2466 * AddAuditAccessAce [ADVAPI32.@]
2468 BOOL WINAPI AddAuditAccessAce(
2469 IN OUT PACL pAcl,
2470 IN DWORD dwAceRevision,
2471 IN DWORD dwAccessMask,
2472 IN PSID pSid,
2473 IN BOOL bAuditSuccess,
2474 IN BOOL bAuditFailure)
2476 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2477 bAuditSuccess, bAuditFailure) );
2480 /******************************************************************************
2481 * AddAuditAccessAce [ADVAPI32.@]
2483 BOOL WINAPI AddAuditAccessAceEx(
2484 IN OUT PACL pAcl,
2485 IN DWORD dwAceRevision,
2486 IN DWORD dwAceFlags,
2487 IN DWORD dwAccessMask,
2488 IN PSID pSid,
2489 IN BOOL bAuditSuccess,
2490 IN BOOL bAuditFailure)
2492 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2493 bAuditSuccess, bAuditFailure) );
2496 /******************************************************************************
2497 * LookupAccountNameA [ADVAPI32.@]
2499 BOOL WINAPI
2500 LookupAccountNameA(
2501 IN LPCSTR system,
2502 IN LPCSTR account,
2503 OUT PSID sid,
2504 OUT LPDWORD cbSid,
2505 LPSTR ReferencedDomainName,
2506 IN OUT LPDWORD cbReferencedDomainName,
2507 OUT PSID_NAME_USE name_use )
2509 BOOL ret;
2510 UNICODE_STRING lpSystemW;
2511 UNICODE_STRING lpAccountW;
2512 LPWSTR lpReferencedDomainNameW = NULL;
2514 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2515 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2517 if (ReferencedDomainName)
2518 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2520 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2521 cbReferencedDomainName, name_use);
2523 if (ret && lpReferencedDomainNameW)
2525 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2526 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2529 RtlFreeUnicodeString(&lpSystemW);
2530 RtlFreeUnicodeString(&lpAccountW);
2531 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2533 return ret;
2536 /******************************************************************************
2537 * lookup_user_account_name
2539 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2540 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2542 /* Default implementation: Always return a default SID */
2543 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2544 BOOL ret;
2545 PSID pSid;
2546 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2547 DWORD nameLen;
2548 LPCWSTR domainName;
2550 ret = AllocateAndInitializeSid(&identifierAuthority,
2552 SECURITY_BUILTIN_DOMAIN_RID,
2553 DOMAIN_ALIAS_RID_ADMINS,
2554 0, 0, 0, 0, 0, 0,
2555 &pSid);
2557 if (!ret)
2558 return FALSE;
2560 if (!RtlValidSid(pSid))
2562 FreeSid(pSid);
2563 return FALSE;
2566 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2567 CopySid(*cbSid, Sid, pSid);
2568 if (*cbSid < GetLengthSid(pSid))
2570 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2571 ret = FALSE;
2573 *cbSid = GetLengthSid(pSid);
2575 domainName = dm;
2576 nameLen = strlenW(domainName);
2578 if (*cchReferencedDomainName <= nameLen || !ret)
2580 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2581 nameLen += 1;
2582 ret = FALSE;
2584 else if (ReferencedDomainName)
2585 strcpyW(ReferencedDomainName, domainName);
2587 *cchReferencedDomainName = nameLen;
2589 if (ret)
2590 *peUse = SidTypeUser;
2592 FreeSid(pSid);
2594 return ret;
2597 /******************************************************************************
2598 * lookup_computer_account_name
2600 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2601 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2603 MAX_SID local;
2604 BOOL ret;
2605 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2606 DWORD nameLen;
2607 LPCWSTR domainName;
2609 if ((ret = ADVAPI_GetComputerSid(&local)))
2611 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2612 CopySid(*cbSid, Sid, &local);
2613 if (*cbSid < GetLengthSid(&local))
2615 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2616 ret = FALSE;
2618 *cbSid = GetLengthSid(&local);
2621 domainName = dm;
2622 nameLen = strlenW(domainName);
2624 if (*cchReferencedDomainName <= nameLen || !ret)
2626 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2627 nameLen += 1;
2628 ret = FALSE;
2630 else if (ReferencedDomainName)
2631 strcpyW(ReferencedDomainName, domainName);
2633 *cchReferencedDomainName = nameLen;
2635 if (ret)
2636 *peUse = SidTypeDomain;
2638 return ret;
2641 /******************************************************************************
2642 * LookupAccountNameW [ADVAPI32.@]
2644 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2645 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2646 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2648 BOOL ret;
2649 PSID pSid;
2650 unsigned int i;
2651 DWORD nameLen;
2652 LPWSTR userName = NULL;
2653 LPCWSTR domainName;
2655 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2656 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2658 if (!ADVAPI_IsLocalComputer(lpSystemName))
2660 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2661 return FALSE;
2664 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2666 lpAccountName = BUILTIN;
2669 /* Check well known SIDs first */
2671 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2673 if (!strcmpiW(lpAccountName, ACCOUNT_SIDS[i].account) ||
2674 (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountName, ACCOUNT_SIDS[i].alias)))
2676 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2678 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2680 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2682 if (ret)
2684 if (*cbSid < sidLen)
2686 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2687 ret = FALSE;
2689 else if (Sid)
2691 CopySid(*cbSid, Sid, pSid);
2694 *cbSid = sidLen;
2697 domainName = ACCOUNT_SIDS[i].domain;
2698 nameLen = strlenW(domainName);
2700 if (*cchReferencedDomainName <= nameLen || !ret)
2702 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2703 nameLen += 1;
2704 ret = FALSE;
2706 else if (ReferencedDomainName)
2708 strcpyW(ReferencedDomainName, domainName);
2711 *cchReferencedDomainName = nameLen;
2713 if (ret)
2715 *peUse = ACCOUNT_SIDS[i].name_use;
2718 HeapFree(GetProcessHeap(), 0, pSid);
2720 return ret;
2724 /* Let the current Unix user id masquerade as first Windows user account */
2726 nameLen = UNLEN + 1;
2728 userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2730 if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2731 ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2732 cchReferencedDomainName, peUse);
2733 else
2735 nameLen = UNLEN + 1;
2736 if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2737 ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2738 cchReferencedDomainName, peUse);
2739 else
2741 SetLastError(ERROR_NONE_MAPPED);
2742 ret = FALSE;
2746 HeapFree(GetProcessHeap(), 0, userName);
2748 return ret;
2751 /******************************************************************************
2752 * PrivilegeCheck [ADVAPI32.@]
2754 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2756 BOOL ret;
2757 BOOLEAN Result;
2759 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2761 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2762 if (ret)
2763 *pfResult = Result;
2764 return ret;
2767 /******************************************************************************
2768 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2770 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2771 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2772 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2773 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2775 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2776 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2777 SecurityDescriptor, DesiredAccess, GenericMapping,
2778 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2779 return TRUE;
2782 /******************************************************************************
2783 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2785 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2786 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2787 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2788 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2790 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2791 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2792 SecurityDescriptor, DesiredAccess, GenericMapping,
2793 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2794 return TRUE;
2797 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2799 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2801 return TRUE;
2804 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2806 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2808 return TRUE;
2811 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2813 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2815 return TRUE;
2818 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2819 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2820 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2821 LPBOOL GenerateOnClose)
2823 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2824 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2825 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2826 GenerateOnClose);
2828 return TRUE;
2831 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2832 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2833 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2834 LPBOOL GenerateOnClose)
2836 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2837 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2838 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2839 GenerateOnClose);
2841 return TRUE;
2844 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2845 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2847 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2848 DesiredAccess, Privileges, AccessGranted);
2850 return TRUE;
2853 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2854 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2856 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2857 DesiredAccess, Privileges, AccessGranted);
2859 return TRUE;
2862 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2863 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2865 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2866 ClientToken, Privileges, AccessGranted);
2868 return TRUE;
2871 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2872 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2874 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2875 ClientToken, Privileges, AccessGranted);
2877 return TRUE;
2880 /******************************************************************************
2881 * GetSecurityInfo [ADVAPI32.@]
2883 * Retrieves a copy of the security descriptor associated with an object.
2885 * PARAMS
2886 * hObject [I] A handle for the object.
2887 * ObjectType [I] The type of object.
2888 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2889 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2890 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2891 * ppDacl [O] If non-null, receives a pointer to the DACL.
2892 * ppSacl [O] If non-null, receives a pointer to the SACL.
2893 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2894 * which must be freed with LocalFree.
2896 * RETURNS
2897 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2899 DWORD WINAPI GetSecurityInfo(
2900 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2901 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2902 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2903 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2906 PSECURITY_DESCRIPTOR sd;
2907 NTSTATUS status;
2908 ULONG n1, n2;
2909 BOOL present, defaulted;
2911 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2912 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2913 return RtlNtStatusToDosError(status);
2915 sd = LocalAlloc(0, n1);
2916 if (!sd)
2917 return ERROR_NOT_ENOUGH_MEMORY;
2919 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2920 if (status != STATUS_SUCCESS)
2922 LocalFree(sd);
2923 return RtlNtStatusToDosError(status);
2926 if (ppsidOwner)
2928 *ppsidOwner = NULL;
2929 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2931 if (ppsidGroup)
2933 *ppsidGroup = NULL;
2934 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2936 if (ppDacl)
2938 *ppDacl = NULL;
2939 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2941 if (ppSacl)
2943 *ppSacl = NULL;
2944 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2946 if (ppSecurityDescriptor)
2947 *ppSecurityDescriptor = sd;
2949 return ERROR_SUCCESS;
2952 /******************************************************************************
2953 * GetSecurityInfoExA [ADVAPI32.@]
2955 DWORD WINAPI GetSecurityInfoExA(
2956 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2957 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2958 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2959 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2962 FIXME("stub!\n");
2963 return ERROR_BAD_PROVIDER;
2966 /******************************************************************************
2967 * GetSecurityInfoExW [ADVAPI32.@]
2969 DWORD WINAPI GetSecurityInfoExW(
2970 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2971 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2972 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2973 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2976 FIXME("stub!\n");
2977 return ERROR_BAD_PROVIDER;
2980 /******************************************************************************
2981 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2983 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2984 LPSTR pTrusteeName, DWORD AccessPermissions,
2985 ACCESS_MODE AccessMode, DWORD Inheritance )
2987 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2988 AccessPermissions, AccessMode, Inheritance);
2990 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2991 pExplicitAccess->grfAccessMode = AccessMode;
2992 pExplicitAccess->grfInheritance = Inheritance;
2994 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2995 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2996 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2997 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2998 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3001 /******************************************************************************
3002 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3004 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3005 LPWSTR pTrusteeName, DWORD AccessPermissions,
3006 ACCESS_MODE AccessMode, DWORD Inheritance )
3008 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3009 AccessPermissions, AccessMode, Inheritance);
3011 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3012 pExplicitAccess->grfAccessMode = AccessMode;
3013 pExplicitAccess->grfInheritance = Inheritance;
3015 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3016 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3017 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3018 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3019 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3022 /******************************************************************************
3023 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3025 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3026 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3027 LPSTR InheritedObjectTypeName, LPSTR Name )
3029 DWORD ObjectsPresent = 0;
3031 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3032 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3034 /* Fill the OBJECTS_AND_NAME structure */
3035 pObjName->ObjectType = ObjectType;
3036 if (ObjectTypeName != NULL)
3038 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3041 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3042 if (InheritedObjectTypeName != NULL)
3044 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3047 pObjName->ObjectsPresent = ObjectsPresent;
3048 pObjName->ptstrName = Name;
3050 /* Fill the TRUSTEE structure */
3051 pTrustee->pMultipleTrustee = NULL;
3052 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3053 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3054 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3055 pTrustee->ptstrName = (LPSTR)pObjName;
3058 /******************************************************************************
3059 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3061 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3062 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3063 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3065 DWORD ObjectsPresent = 0;
3067 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3068 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3070 /* Fill the OBJECTS_AND_NAME structure */
3071 pObjName->ObjectType = ObjectType;
3072 if (ObjectTypeName != NULL)
3074 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3077 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3078 if (InheritedObjectTypeName != NULL)
3080 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3083 pObjName->ObjectsPresent = ObjectsPresent;
3084 pObjName->ptstrName = Name;
3086 /* Fill the TRUSTEE structure */
3087 pTrustee->pMultipleTrustee = NULL;
3088 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3089 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3090 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3091 pTrustee->ptstrName = (LPWSTR)pObjName;
3094 /******************************************************************************
3095 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3097 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3098 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3100 DWORD ObjectsPresent = 0;
3102 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3104 /* Fill the OBJECTS_AND_SID structure */
3105 if (pObjectGuid != NULL)
3107 pObjSid->ObjectTypeGuid = *pObjectGuid;
3108 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3110 else
3112 ZeroMemory(&pObjSid->ObjectTypeGuid,
3113 sizeof(GUID));
3116 if (pInheritedObjectGuid != NULL)
3118 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3119 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3121 else
3123 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3124 sizeof(GUID));
3127 pObjSid->ObjectsPresent = ObjectsPresent;
3128 pObjSid->pSid = pSid;
3130 /* Fill the TRUSTEE structure */
3131 pTrustee->pMultipleTrustee = NULL;
3132 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3133 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3134 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3135 pTrustee->ptstrName = (LPSTR) pObjSid;
3138 /******************************************************************************
3139 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3141 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3142 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3144 DWORD ObjectsPresent = 0;
3146 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3148 /* Fill the OBJECTS_AND_SID structure */
3149 if (pObjectGuid != NULL)
3151 pObjSid->ObjectTypeGuid = *pObjectGuid;
3152 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3154 else
3156 ZeroMemory(&pObjSid->ObjectTypeGuid,
3157 sizeof(GUID));
3160 if (pInheritedObjectGuid != NULL)
3162 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3163 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3165 else
3167 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3168 sizeof(GUID));
3171 pObjSid->ObjectsPresent = ObjectsPresent;
3172 pObjSid->pSid = pSid;
3174 /* Fill the TRUSTEE structure */
3175 pTrustee->pMultipleTrustee = NULL;
3176 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3177 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3178 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3179 pTrustee->ptstrName = (LPWSTR) pObjSid;
3182 /******************************************************************************
3183 * BuildTrusteeWithSidA [ADVAPI32.@]
3185 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3187 TRACE("%p %p\n", pTrustee, pSid);
3189 pTrustee->pMultipleTrustee = NULL;
3190 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3191 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3192 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3193 pTrustee->ptstrName = pSid;
3196 /******************************************************************************
3197 * BuildTrusteeWithSidW [ADVAPI32.@]
3199 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3201 TRACE("%p %p\n", pTrustee, pSid);
3203 pTrustee->pMultipleTrustee = NULL;
3204 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3205 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3206 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3207 pTrustee->ptstrName = pSid;
3210 /******************************************************************************
3211 * BuildTrusteeWithNameA [ADVAPI32.@]
3213 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3215 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3217 pTrustee->pMultipleTrustee = NULL;
3218 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3219 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3220 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3221 pTrustee->ptstrName = name;
3224 /******************************************************************************
3225 * BuildTrusteeWithNameW [ADVAPI32.@]
3227 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3229 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3231 pTrustee->pMultipleTrustee = NULL;
3232 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3233 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3234 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3235 pTrustee->ptstrName = name;
3238 /******************************************************************************
3239 * GetTrusteeFormA [ADVAPI32.@]
3241 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3243 TRACE("(%p)\n", pTrustee);
3245 if (!pTrustee)
3246 return TRUSTEE_BAD_FORM;
3248 return pTrustee->TrusteeForm;
3251 /******************************************************************************
3252 * GetTrusteeFormW [ADVAPI32.@]
3254 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3256 TRACE("(%p)\n", pTrustee);
3258 if (!pTrustee)
3259 return TRUSTEE_BAD_FORM;
3261 return pTrustee->TrusteeForm;
3264 /******************************************************************************
3265 * GetTrusteeNameA [ADVAPI32.@]
3267 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3269 TRACE("(%p)\n", pTrustee);
3271 if (!pTrustee)
3272 return NULL;
3274 return pTrustee->ptstrName;
3277 /******************************************************************************
3278 * GetTrusteeNameW [ADVAPI32.@]
3280 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3282 TRACE("(%p)\n", pTrustee);
3284 if (!pTrustee)
3285 return NULL;
3287 return pTrustee->ptstrName;
3290 /******************************************************************************
3291 * GetTrusteeTypeA [ADVAPI32.@]
3293 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3295 TRACE("(%p)\n", pTrustee);
3297 if (!pTrustee)
3298 return TRUSTEE_IS_UNKNOWN;
3300 return pTrustee->TrusteeType;
3303 /******************************************************************************
3304 * GetTrusteeTypeW [ADVAPI32.@]
3306 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3308 TRACE("(%p)\n", pTrustee);
3310 if (!pTrustee)
3311 return TRUSTEE_IS_UNKNOWN;
3313 return pTrustee->TrusteeType;
3316 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3317 DWORD nAclInformationLength,
3318 ACL_INFORMATION_CLASS dwAclInformationClass )
3320 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3321 nAclInformationLength, dwAclInformationClass);
3323 return TRUE;
3326 /******************************************************************************
3327 * SetEntriesInAclA [ADVAPI32.@]
3329 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3330 PACL OldAcl, PACL* NewAcl )
3332 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3333 if (NewAcl)
3334 *NewAcl = NULL;
3335 return ERROR_SUCCESS;
3338 /******************************************************************************
3339 * SetEntriesInAclW [ADVAPI32.@]
3341 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3342 PACL OldAcl, PACL* NewAcl )
3344 ULONG i;
3345 PSID *ppsid;
3346 DWORD ret = ERROR_SUCCESS;
3347 DWORD acl_size = sizeof(ACL);
3348 NTSTATUS status;
3350 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3352 *NewAcl = NULL;
3354 if (!count && !OldAcl)
3355 return ERROR_SUCCESS;
3357 /* allocate array of maximum sized sids allowed */
3358 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3359 if (!ppsid)
3360 return ERROR_OUTOFMEMORY;
3362 for (i = 0; i < count; i++)
3364 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3366 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3367 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3368 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3369 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3370 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3371 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3372 pEntries[i].Trustee.ptstrName);
3374 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3376 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3377 ret = ERROR_INVALID_PARAMETER;
3378 goto exit;
3381 switch (pEntries[i].Trustee.TrusteeForm)
3383 case TRUSTEE_IS_SID:
3384 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3385 ppsid[i], pEntries[i].Trustee.ptstrName))
3387 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3388 ret = ERROR_INVALID_PARAMETER;
3389 goto exit;
3391 break;
3392 case TRUSTEE_IS_NAME:
3394 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3395 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3396 SID_NAME_USE use;
3397 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3399 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3400 ret = ERROR_INVALID_PARAMETER;
3401 goto exit;
3403 break;
3405 case TRUSTEE_IS_OBJECTS_AND_SID:
3406 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3407 break;
3408 case TRUSTEE_IS_OBJECTS_AND_NAME:
3409 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3410 break;
3411 default:
3412 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3413 ret = ERROR_INVALID_PARAMETER;
3414 goto exit;
3417 /* Note: we overestimate the ACL size here as a tradeoff between
3418 * instructions (simplicity) and memory */
3419 switch (pEntries[i].grfAccessMode)
3421 case GRANT_ACCESS:
3422 case SET_ACCESS:
3423 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3424 break;
3425 case DENY_ACCESS:
3426 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3427 break;
3428 case SET_AUDIT_SUCCESS:
3429 case SET_AUDIT_FAILURE:
3430 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3431 break;
3432 case REVOKE_ACCESS:
3433 break;
3434 default:
3435 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3436 ret = ERROR_INVALID_PARAMETER;
3437 goto exit;
3441 if (OldAcl)
3443 ACL_SIZE_INFORMATION size_info;
3445 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3446 if (status != STATUS_SUCCESS)
3448 ret = RtlNtStatusToDosError(status);
3449 goto exit;
3451 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3454 *NewAcl = LocalAlloc(0, acl_size);
3455 if (!*NewAcl)
3457 ret = ERROR_OUTOFMEMORY;
3458 goto exit;
3461 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3462 if (status != STATUS_SUCCESS)
3464 ret = RtlNtStatusToDosError(status);
3465 goto exit;
3468 for (i = 0; i < count; i++)
3470 switch (pEntries[i].grfAccessMode)
3472 case GRANT_ACCESS:
3473 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3474 pEntries[i].grfInheritance,
3475 pEntries[i].grfAccessPermissions,
3476 ppsid[i]);
3477 break;
3478 case SET_ACCESS:
3480 ULONG j;
3481 BOOL add = TRUE;
3482 if (OldAcl)
3484 for (j = 0; ; j++)
3486 const ACE_HEADER *existing_ace_header;
3487 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3488 if (status != STATUS_SUCCESS)
3489 break;
3490 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3491 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3492 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3494 add = FALSE;
3495 break;
3499 if (add)
3500 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3501 pEntries[i].grfInheritance,
3502 pEntries[i].grfAccessPermissions,
3503 ppsid[i]);
3504 break;
3506 case DENY_ACCESS:
3507 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3508 pEntries[i].grfInheritance,
3509 pEntries[i].grfAccessPermissions,
3510 ppsid[i]);
3511 break;
3512 case SET_AUDIT_SUCCESS:
3513 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3514 pEntries[i].grfInheritance,
3515 pEntries[i].grfAccessPermissions,
3516 ppsid[i], TRUE, FALSE);
3517 break;
3518 case SET_AUDIT_FAILURE:
3519 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3520 pEntries[i].grfInheritance,
3521 pEntries[i].grfAccessPermissions,
3522 ppsid[i], FALSE, TRUE);
3523 break;
3524 default:
3525 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3529 if (OldAcl)
3531 for (i = 0; ; i++)
3533 BOOL add = TRUE;
3534 ULONG j;
3535 const ACE_HEADER *old_ace_header;
3536 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3537 if (status != STATUS_SUCCESS) break;
3538 for (j = 0; j < count; j++)
3540 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3541 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3542 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3544 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3545 add = FALSE;
3546 break;
3548 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3550 switch (old_ace_header->AceType)
3552 case ACCESS_ALLOWED_ACE_TYPE:
3553 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3554 add = FALSE;
3555 break;
3556 case ACCESS_DENIED_ACE_TYPE:
3557 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3558 add = FALSE;
3559 break;
3560 case SYSTEM_AUDIT_ACE_TYPE:
3561 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3562 add = FALSE;
3563 break;
3564 case SYSTEM_ALARM_ACE_TYPE:
3565 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3566 add = FALSE;
3567 break;
3568 default:
3569 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3572 if (!add)
3573 break;
3576 if (add)
3577 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3578 if (status != STATUS_SUCCESS)
3580 WARN("RtlAddAce failed with error 0x%08x\n", status);
3581 ret = RtlNtStatusToDosError(status);
3582 break;
3587 exit:
3588 HeapFree(GetProcessHeap(), 0, ppsid);
3589 return ret;
3592 /******************************************************************************
3593 * SetNamedSecurityInfoA [ADVAPI32.@]
3595 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3596 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3597 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3599 DWORD len;
3600 LPWSTR wstr = NULL;
3601 DWORD r;
3603 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3604 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3606 if( pObjectName )
3608 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3609 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3610 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3613 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3614 psidGroup, pDacl, pSacl );
3616 HeapFree( GetProcessHeap(), 0, wstr );
3618 return r;
3621 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3622 PSECURITY_DESCRIPTOR ModificationDescriptor,
3623 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3624 PGENERIC_MAPPING GenericMapping,
3625 HANDLE Token )
3627 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3628 ObjectsSecurityDescriptor, GenericMapping, Token);
3630 return TRUE;
3633 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3635 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3638 /******************************************************************************
3639 * AreAnyAccessesGranted [ADVAPI32.@]
3641 * Determines whether or not any of a set of specified access permissions have
3642 * been granted or not.
3644 * PARAMS
3645 * GrantedAccess [I] The permissions that have been granted.
3646 * DesiredAccess [I] The permissions that you want to have.
3648 * RETURNS
3649 * Nonzero if any of the permissions have been granted, zero if none of the
3650 * permissions have been granted.
3653 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3655 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3658 /******************************************************************************
3659 * SetNamedSecurityInfoW [ADVAPI32.@]
3661 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3662 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3663 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3665 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3666 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3667 return ERROR_SUCCESS;
3670 /******************************************************************************
3671 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3673 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3674 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3676 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3677 return ERROR_CALL_NOT_IMPLEMENTED;
3680 /******************************************************************************
3681 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3683 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3684 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3686 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3687 return ERROR_CALL_NOT_IMPLEMENTED;
3690 /******************************************************************************
3691 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3693 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3694 PACCESS_MASK pFailedAuditRights)
3696 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3697 return ERROR_CALL_NOT_IMPLEMENTED;
3701 /******************************************************************************
3702 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3704 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3705 PACCESS_MASK pFailedAuditRights)
3707 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3708 return ERROR_CALL_NOT_IMPLEMENTED;
3712 /******************************************************************************
3713 * ParseAclStringFlags
3715 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3717 DWORD flags = 0;
3718 LPCWSTR szAcl = *StringAcl;
3720 while (*szAcl != '(')
3722 if (*szAcl == 'P')
3724 flags |= SE_DACL_PROTECTED;
3726 else if (*szAcl == 'A')
3728 szAcl++;
3729 if (*szAcl == 'R')
3730 flags |= SE_DACL_AUTO_INHERIT_REQ;
3731 else if (*szAcl == 'I')
3732 flags |= SE_DACL_AUTO_INHERITED;
3734 szAcl++;
3737 *StringAcl = szAcl;
3738 return flags;
3741 /******************************************************************************
3742 * ParseAceStringType
3744 static const ACEFLAG AceType[] =
3746 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3747 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3748 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3749 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3751 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3752 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3753 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3754 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3756 { NULL, 0 },
3759 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3761 UINT len = 0;
3762 LPCWSTR szAcl = *StringAcl;
3763 const ACEFLAG *lpaf = AceType;
3765 while (lpaf->wstr &&
3766 (len = strlenW(lpaf->wstr)) &&
3767 strncmpW(lpaf->wstr, szAcl, len))
3768 lpaf++;
3770 if (!lpaf->wstr)
3771 return 0;
3773 *StringAcl += len;
3774 return lpaf->value;
3778 /******************************************************************************
3779 * ParseAceStringFlags
3781 static const ACEFLAG AceFlags[] =
3783 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3784 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3785 { SDDL_INHERITED, INHERITED_ACE },
3786 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3787 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3788 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3789 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3790 { NULL, 0 },
3793 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3795 UINT len = 0;
3796 BYTE flags = 0;
3797 LPCWSTR szAcl = *StringAcl;
3799 while (*szAcl != ';')
3801 const ACEFLAG *lpaf = AceFlags;
3803 while (lpaf->wstr &&
3804 (len = strlenW(lpaf->wstr)) &&
3805 strncmpW(lpaf->wstr, szAcl, len))
3806 lpaf++;
3808 if (!lpaf->wstr)
3809 return 0;
3811 flags |= lpaf->value;
3812 szAcl += len;
3815 *StringAcl = szAcl;
3816 return flags;
3820 /******************************************************************************
3821 * ParseAceStringRights
3823 static const ACEFLAG AceRights[] =
3825 { SDDL_GENERIC_ALL, GENERIC_ALL },
3826 { SDDL_GENERIC_READ, GENERIC_READ },
3827 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3828 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3830 { SDDL_READ_CONTROL, READ_CONTROL },
3831 { SDDL_STANDARD_DELETE, DELETE },
3832 { SDDL_WRITE_DAC, WRITE_DAC },
3833 { SDDL_WRITE_OWNER, WRITE_OWNER },
3835 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3836 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3837 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3838 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3839 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3840 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3841 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3842 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3843 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3845 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3846 { SDDL_FILE_READ, FILE_GENERIC_READ },
3847 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3848 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3850 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3851 { SDDL_KEY_READ, KEY_READ },
3852 { SDDL_KEY_WRITE, KEY_WRITE },
3853 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3854 { NULL, 0 },
3857 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3859 UINT len = 0;
3860 DWORD rights = 0;
3861 LPCWSTR szAcl = *StringAcl;
3863 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3865 LPCWSTR p = szAcl;
3867 while (*p && *p != ';')
3868 p++;
3870 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3872 rights = strtoulW(szAcl, NULL, 16);
3873 szAcl = p;
3875 else
3876 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3878 else
3880 while (*szAcl != ';')
3882 const ACEFLAG *lpaf = AceRights;
3884 while (lpaf->wstr &&
3885 (len = strlenW(lpaf->wstr)) &&
3886 strncmpW(lpaf->wstr, szAcl, len))
3888 lpaf++;
3891 if (!lpaf->wstr)
3892 return 0;
3894 rights |= lpaf->value;
3895 szAcl += len;
3899 *StringAcl = szAcl;
3900 return rights;
3904 /******************************************************************************
3905 * ParseStringAclToAcl
3907 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3909 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3910 PACL pAcl, LPDWORD cBytes)
3912 DWORD val;
3913 DWORD sidlen;
3914 DWORD length = sizeof(ACL);
3915 DWORD acesize = 0;
3916 DWORD acecount = 0;
3917 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3919 TRACE("%s\n", debugstr_w(StringAcl));
3921 if (!StringAcl)
3922 return FALSE;
3924 if (pAcl) /* pAce is only useful if we're setting values */
3925 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3927 /* Parse ACL flags */
3928 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3930 /* Parse ACE */
3931 while (*StringAcl == '(')
3933 StringAcl++;
3935 /* Parse ACE type */
3936 val = ParseAceStringType(&StringAcl);
3937 if (pAce)
3938 pAce->Header.AceType = (BYTE) val;
3939 if (*StringAcl != ';')
3940 goto lerr;
3941 StringAcl++;
3943 /* Parse ACE flags */
3944 val = ParseAceStringFlags(&StringAcl);
3945 if (pAce)
3946 pAce->Header.AceFlags = (BYTE) val;
3947 if (*StringAcl != ';')
3948 goto lerr;
3949 StringAcl++;
3951 /* Parse ACE rights */
3952 val = ParseAceStringRights(&StringAcl);
3953 if (pAce)
3954 pAce->Mask = val;
3955 if (*StringAcl != ';')
3956 goto lerr;
3957 StringAcl++;
3959 /* Parse ACE object guid */
3960 if (*StringAcl != ';')
3962 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3963 goto lerr;
3965 StringAcl++;
3967 /* Parse ACE inherit object guid */
3968 if (*StringAcl != ';')
3970 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3971 goto lerr;
3973 StringAcl++;
3975 /* Parse ACE account sid */
3976 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
3978 while (*StringAcl && *StringAcl != ')')
3979 StringAcl++;
3982 if (*StringAcl != ')')
3983 goto lerr;
3984 StringAcl++;
3986 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3987 length += acesize;
3988 if (pAce)
3990 pAce->Header.AceSize = acesize;
3991 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3993 acecount++;
3996 *cBytes = length;
3998 if (length > 0xffff)
4000 ERR("ACL too large\n");
4001 goto lerr;
4004 if (pAcl)
4006 pAcl->AclRevision = ACL_REVISION;
4007 pAcl->Sbz1 = 0;
4008 pAcl->AclSize = length;
4009 pAcl->AceCount = acecount++;
4010 pAcl->Sbz2 = 0;
4012 return TRUE;
4014 lerr:
4015 SetLastError(ERROR_INVALID_ACL);
4016 WARN("Invalid ACE string format\n");
4017 return FALSE;
4021 /******************************************************************************
4022 * ParseStringSecurityDescriptorToSecurityDescriptor
4024 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4025 LPCWSTR StringSecurityDescriptor,
4026 SECURITY_DESCRIPTOR* SecurityDescriptor,
4027 LPDWORD cBytes)
4029 BOOL bret = FALSE;
4030 WCHAR toktype;
4031 WCHAR tok[MAX_PATH];
4032 LPCWSTR lptoken;
4033 LPBYTE lpNext = NULL;
4034 DWORD len;
4036 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4038 if (SecurityDescriptor)
4039 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
4041 while (*StringSecurityDescriptor)
4043 toktype = *StringSecurityDescriptor;
4045 /* Expect char identifier followed by ':' */
4046 StringSecurityDescriptor++;
4047 if (*StringSecurityDescriptor != ':')
4049 SetLastError(ERROR_INVALID_PARAMETER);
4050 goto lend;
4052 StringSecurityDescriptor++;
4054 /* Extract token */
4055 lptoken = StringSecurityDescriptor;
4056 while (*lptoken && *lptoken != ':')
4057 lptoken++;
4059 if (*lptoken)
4060 lptoken--;
4062 len = lptoken - StringSecurityDescriptor;
4063 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4064 tok[len] = 0;
4066 switch (toktype)
4068 case 'O':
4070 DWORD bytes;
4072 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4073 goto lend;
4075 if (SecurityDescriptor)
4077 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4078 lpNext += bytes; /* Advance to next token */
4081 *cBytes += bytes;
4083 break;
4086 case 'G':
4088 DWORD bytes;
4090 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4091 goto lend;
4093 if (SecurityDescriptor)
4095 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4096 lpNext += bytes; /* Advance to next token */
4099 *cBytes += bytes;
4101 break;
4104 case 'D':
4106 DWORD flags;
4107 DWORD bytes;
4109 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4110 goto lend;
4112 if (SecurityDescriptor)
4114 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4115 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4116 lpNext += bytes; /* Advance to next token */
4119 *cBytes += bytes;
4121 break;
4124 case 'S':
4126 DWORD flags;
4127 DWORD bytes;
4129 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4130 goto lend;
4132 if (SecurityDescriptor)
4134 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4135 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4136 lpNext += bytes; /* Advance to next token */
4139 *cBytes += bytes;
4141 break;
4144 default:
4145 FIXME("Unknown token\n");
4146 SetLastError(ERROR_INVALID_PARAMETER);
4147 goto lend;
4150 StringSecurityDescriptor = lptoken;
4153 bret = TRUE;
4155 lend:
4156 return bret;
4159 /******************************************************************************
4160 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4162 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4163 LPCSTR StringSecurityDescriptor,
4164 DWORD StringSDRevision,
4165 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4166 PULONG SecurityDescriptorSize)
4168 UINT len;
4169 BOOL ret = FALSE;
4170 LPWSTR StringSecurityDescriptorW;
4172 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4173 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4175 if (StringSecurityDescriptorW)
4177 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4179 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4180 StringSDRevision, SecurityDescriptor,
4181 SecurityDescriptorSize);
4182 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4185 return ret;
4188 /******************************************************************************
4189 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4191 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4192 LPCWSTR StringSecurityDescriptor,
4193 DWORD StringSDRevision,
4194 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4195 PULONG SecurityDescriptorSize)
4197 DWORD cBytes;
4198 SECURITY_DESCRIPTOR* psd;
4199 BOOL bret = FALSE;
4201 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4203 if (GetVersion() & 0x80000000)
4205 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4206 goto lend;
4208 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4210 SetLastError(ERROR_INVALID_PARAMETER);
4211 goto lend;
4213 else if (StringSDRevision != SID_REVISION)
4215 SetLastError(ERROR_UNKNOWN_REVISION);
4216 goto lend;
4219 /* Compute security descriptor length */
4220 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4221 NULL, &cBytes))
4222 goto lend;
4224 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4225 if (!psd) goto lend;
4227 psd->Revision = SID_REVISION;
4228 psd->Control |= SE_SELF_RELATIVE;
4230 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4231 psd, &cBytes))
4233 LocalFree(psd);
4234 goto lend;
4237 if (SecurityDescriptorSize)
4238 *SecurityDescriptorSize = cBytes;
4240 bret = TRUE;
4242 lend:
4243 TRACE(" ret=%d\n", bret);
4244 return bret;
4247 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4249 if (cch == -1)
4250 cch = strlenW(string);
4252 if (plen)
4253 *plen += cch;
4255 if (pwptr)
4257 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4258 *pwptr += cch;
4262 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4264 DWORD i;
4265 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4266 WCHAR subauthfmt[] = { '-','%','u',0 };
4267 WCHAR buf[26];
4268 SID *pisid = psid;
4270 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4272 SetLastError(ERROR_INVALID_SID);
4273 return FALSE;
4276 if (pisid->IdentifierAuthority.Value[0] ||
4277 pisid->IdentifierAuthority.Value[1])
4279 FIXME("not matching MS' bugs\n");
4280 SetLastError(ERROR_INVALID_SID);
4281 return FALSE;
4284 sprintfW( buf, fmt, pisid->Revision,
4285 MAKELONG(
4286 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4287 pisid->IdentifierAuthority.Value[4] ),
4288 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4289 pisid->IdentifierAuthority.Value[2] )
4290 ) );
4291 DumpString(buf, -1, pwptr, plen);
4293 for( i=0; i<pisid->SubAuthorityCount; i++ )
4295 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4296 DumpString(buf, -1, pwptr, plen);
4298 return TRUE;
4301 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4303 size_t i;
4304 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4306 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4308 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4309 return TRUE;
4313 return DumpSidNumeric(psid, pwptr, plen);
4316 static const LPCWSTR AceRightBitNames[32] = {
4317 SDDL_CREATE_CHILD, /* 0 */
4318 SDDL_DELETE_CHILD,
4319 SDDL_LIST_CHILDREN,
4320 SDDL_SELF_WRITE,
4321 SDDL_READ_PROPERTY, /* 4 */
4322 SDDL_WRITE_PROPERTY,
4323 SDDL_DELETE_TREE,
4324 SDDL_LIST_OBJECT,
4325 SDDL_CONTROL_ACCESS, /* 8 */
4326 NULL,
4327 NULL,
4328 NULL,
4329 NULL, /* 12 */
4330 NULL,
4331 NULL,
4332 NULL,
4333 SDDL_STANDARD_DELETE, /* 16 */
4334 SDDL_READ_CONTROL,
4335 SDDL_WRITE_DAC,
4336 SDDL_WRITE_OWNER,
4337 NULL, /* 20 */
4338 NULL,
4339 NULL,
4340 NULL,
4341 NULL, /* 24 */
4342 NULL,
4343 NULL,
4344 NULL,
4345 SDDL_GENERIC_ALL, /* 28 */
4346 SDDL_GENERIC_EXECUTE,
4347 SDDL_GENERIC_WRITE,
4348 SDDL_GENERIC_READ
4351 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4353 static const WCHAR fmtW[] = {'0','x','%','x',0};
4354 WCHAR buf[15];
4355 size_t i;
4357 if (mask == 0)
4358 return;
4360 /* first check if the right have name */
4361 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4363 if (AceRights[i].wstr == NULL)
4364 break;
4365 if (mask == AceRights[i].value)
4367 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4368 return;
4372 /* then check if it can be built from bit names */
4373 for (i = 0; i < 32; i++)
4375 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4377 /* can't be built from bit names */
4378 sprintfW(buf, fmtW, mask);
4379 DumpString(buf, -1, pwptr, plen);
4380 return;
4384 /* build from bit names */
4385 for (i = 0; i < 32; i++)
4386 if (mask & (1 << i))
4387 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4390 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4392 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4393 static const WCHAR openbr = '(';
4394 static const WCHAR closebr = ')';
4395 static const WCHAR semicolon = ';';
4397 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4399 SetLastError(ERROR_INVALID_ACL);
4400 return FALSE;
4403 piace = pace;
4404 DumpString(&openbr, 1, pwptr, plen);
4405 switch (piace->Header.AceType)
4407 case ACCESS_ALLOWED_ACE_TYPE:
4408 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4409 break;
4410 case ACCESS_DENIED_ACE_TYPE:
4411 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4412 break;
4413 case SYSTEM_AUDIT_ACE_TYPE:
4414 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4415 break;
4416 case SYSTEM_ALARM_ACE_TYPE:
4417 DumpString(SDDL_ALARM, -1, pwptr, plen);
4418 break;
4420 DumpString(&semicolon, 1, pwptr, plen);
4422 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4423 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4424 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4425 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4426 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4427 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4428 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4429 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4430 if (piace->Header.AceFlags & INHERITED_ACE)
4431 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4432 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4433 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4434 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4435 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4436 DumpString(&semicolon, 1, pwptr, plen);
4437 DumpRights(piace->Mask, pwptr, plen);
4438 DumpString(&semicolon, 1, pwptr, plen);
4439 /* objects not supported */
4440 DumpString(&semicolon, 1, pwptr, plen);
4441 /* objects not supported */
4442 DumpString(&semicolon, 1, pwptr, plen);
4443 if (!DumpSid(&piace->SidStart, pwptr, plen))
4444 return FALSE;
4445 DumpString(&closebr, 1, pwptr, plen);
4446 return TRUE;
4449 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4451 WORD count;
4452 int i;
4454 if (protected)
4455 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4456 if (autoInheritReq)
4457 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4458 if (autoInherited)
4459 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4461 if (pacl == NULL)
4462 return TRUE;
4464 if (!IsValidAcl(pacl))
4465 return FALSE;
4467 count = pacl->AceCount;
4468 for (i = 0; i < count; i++)
4470 LPVOID ace;
4471 if (!GetAce(pacl, i, &ace))
4472 return FALSE;
4473 if (!DumpAce(ace, pwptr, plen))
4474 return FALSE;
4477 return TRUE;
4480 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4482 static const WCHAR prefix[] = {'O',':',0};
4483 BOOL bDefaulted;
4484 PSID psid;
4486 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4487 return FALSE;
4489 if (psid == NULL)
4490 return TRUE;
4492 DumpString(prefix, -1, pwptr, plen);
4493 if (!DumpSid(psid, pwptr, plen))
4494 return FALSE;
4495 return TRUE;
4498 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4500 static const WCHAR prefix[] = {'G',':',0};
4501 BOOL bDefaulted;
4502 PSID psid;
4504 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4505 return FALSE;
4507 if (psid == NULL)
4508 return TRUE;
4510 DumpString(prefix, -1, pwptr, plen);
4511 if (!DumpSid(psid, pwptr, plen))
4512 return FALSE;
4513 return TRUE;
4516 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4518 static const WCHAR dacl[] = {'D',':',0};
4519 SECURITY_DESCRIPTOR_CONTROL control;
4520 BOOL present, defaulted;
4521 DWORD revision;
4522 PACL pacl;
4524 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4525 return FALSE;
4527 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4528 return FALSE;
4530 if (!present)
4531 return TRUE;
4533 DumpString(dacl, 2, pwptr, plen);
4534 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4535 return FALSE;
4536 return TRUE;
4539 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4541 static const WCHAR sacl[] = {'S',':',0};
4542 SECURITY_DESCRIPTOR_CONTROL control;
4543 BOOL present, defaulted;
4544 DWORD revision;
4545 PACL pacl;
4547 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4548 return FALSE;
4550 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4551 return FALSE;
4553 if (!present)
4554 return TRUE;
4556 DumpString(sacl, 2, pwptr, plen);
4557 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4558 return FALSE;
4559 return TRUE;
4562 /******************************************************************************
4563 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4565 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4567 ULONG len;
4568 WCHAR *wptr, *wstr;
4570 if (SDRevision != SDDL_REVISION_1)
4572 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4573 SetLastError(ERROR_UNKNOWN_REVISION);
4574 return FALSE;
4577 len = 0;
4578 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4579 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4580 return FALSE;
4581 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4582 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4583 return FALSE;
4584 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4585 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4586 return FALSE;
4587 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4588 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4589 return FALSE;
4591 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4592 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4593 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4594 return FALSE;
4595 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4596 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4597 return FALSE;
4598 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4599 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4600 return FALSE;
4601 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4602 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4603 return FALSE;
4604 *wptr = 0;
4606 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4607 *OutputString = wstr;
4608 if (OutputLen)
4609 *OutputLen = strlenW(*OutputString)+1;
4610 return TRUE;
4613 /******************************************************************************
4614 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4616 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4618 LPWSTR wstr;
4619 ULONG len;
4620 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4622 int lenA;
4624 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4625 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4626 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4627 LocalFree(wstr);
4629 if (OutputLen != NULL)
4630 *OutputLen = lenA;
4631 return TRUE;
4633 else
4635 *OutputString = NULL;
4636 if (OutputLen)
4637 *OutputLen = 0;
4638 return FALSE;
4642 /******************************************************************************
4643 * ConvertStringSidToSidW [ADVAPI32.@]
4645 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4647 BOOL bret = FALSE;
4648 DWORD cBytes;
4650 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4651 if (GetVersion() & 0x80000000)
4652 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4653 else if (!StringSid || !Sid)
4654 SetLastError(ERROR_INVALID_PARAMETER);
4655 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4657 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4659 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4660 if (!bret)
4661 LocalFree(*Sid);
4663 return bret;
4666 /******************************************************************************
4667 * ConvertStringSidToSidA [ADVAPI32.@]
4669 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4671 BOOL bret = FALSE;
4673 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4674 if (GetVersion() & 0x80000000)
4675 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4676 else if (!StringSid || !Sid)
4677 SetLastError(ERROR_INVALID_PARAMETER);
4678 else
4680 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4681 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4682 len * sizeof(WCHAR));
4684 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4685 bret = ConvertStringSidToSidW(wStringSid, Sid);
4686 HeapFree(GetProcessHeap(), 0, wStringSid);
4688 return bret;
4691 /******************************************************************************
4692 * ConvertSidToStringSidW [ADVAPI32.@]
4694 * format of SID string is:
4695 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4696 * where
4697 * <rev> is the revision of the SID encoded as decimal
4698 * <auth> is the identifier authority encoded as hex
4699 * <subauthN> is the subauthority id encoded as decimal
4701 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4703 DWORD len = 0;
4704 LPWSTR wstr, wptr;
4706 TRACE("%p %p\n", pSid, pstr );
4708 len = 0;
4709 if (!DumpSidNumeric(pSid, NULL, &len))
4710 return FALSE;
4711 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4712 DumpSidNumeric(pSid, &wptr, NULL);
4713 *wptr = 0;
4715 *pstr = wstr;
4716 return TRUE;
4719 /******************************************************************************
4720 * ConvertSidToStringSidA [ADVAPI32.@]
4722 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4724 LPWSTR wstr = NULL;
4725 LPSTR str;
4726 UINT len;
4728 TRACE("%p %p\n", pSid, pstr );
4730 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4731 return FALSE;
4733 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4734 str = LocalAlloc( 0, len );
4735 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4736 LocalFree( wstr );
4738 *pstr = str;
4740 return TRUE;
4743 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4744 PSECURITY_DESCRIPTOR pdesc,
4745 PSECURITY_DESCRIPTOR cdesc,
4746 PSECURITY_DESCRIPTOR* ndesc,
4747 GUID* objtype,
4748 BOOL isdir,
4749 PGENERIC_MAPPING genmap )
4751 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4753 return FALSE;
4756 BOOL WINAPI CreatePrivateObjectSecurity(
4757 PSECURITY_DESCRIPTOR ParentDescriptor,
4758 PSECURITY_DESCRIPTOR CreatorDescriptor,
4759 PSECURITY_DESCRIPTOR* NewDescriptor,
4760 BOOL IsDirectoryObject,
4761 HANDLE Token,
4762 PGENERIC_MAPPING GenericMapping )
4764 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4765 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4767 return FALSE;
4770 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4772 FIXME("%p - stub\n", ObjectDescriptor);
4774 return TRUE;
4777 BOOL WINAPI CreateProcessAsUserA(
4778 HANDLE hToken,
4779 LPCSTR lpApplicationName,
4780 LPSTR lpCommandLine,
4781 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4782 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4783 BOOL bInheritHandles,
4784 DWORD dwCreationFlags,
4785 LPVOID lpEnvironment,
4786 LPCSTR lpCurrentDirectory,
4787 LPSTARTUPINFOA lpStartupInfo,
4788 LPPROCESS_INFORMATION lpProcessInformation )
4790 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4791 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4792 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4794 return FALSE;
4797 BOOL WINAPI CreateProcessAsUserW(
4798 HANDLE hToken,
4799 LPCWSTR lpApplicationName,
4800 LPWSTR lpCommandLine,
4801 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4802 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4803 BOOL bInheritHandles,
4804 DWORD dwCreationFlags,
4805 LPVOID lpEnvironment,
4806 LPCWSTR lpCurrentDirectory,
4807 LPSTARTUPINFOW lpStartupInfo,
4808 LPPROCESS_INFORMATION lpProcessInformation )
4810 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4811 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4812 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4813 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4815 /* We should create the process with a suspended main thread */
4816 if (!CreateProcessW (lpApplicationName,
4817 lpCommandLine,
4818 lpProcessAttributes,
4819 lpThreadAttributes,
4820 bInheritHandles,
4821 dwCreationFlags, /* CREATE_SUSPENDED */
4822 lpEnvironment,
4823 lpCurrentDirectory,
4824 lpStartupInfo,
4825 lpProcessInformation))
4827 return FALSE;
4830 return TRUE;
4833 /******************************************************************************
4834 * CreateProcessWithLogonW
4836 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4837 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4838 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4840 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4841 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4842 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4843 lpStartupInfo, lpProcessInformation);
4845 return FALSE;
4848 /******************************************************************************
4849 * DuplicateTokenEx [ADVAPI32.@]
4851 BOOL WINAPI DuplicateTokenEx(
4852 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4853 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4854 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4855 TOKEN_TYPE TokenType,
4856 PHANDLE DuplicateTokenHandle )
4858 OBJECT_ATTRIBUTES ObjectAttributes;
4860 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4861 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4863 InitializeObjectAttributes(
4864 &ObjectAttributes,
4865 NULL,
4866 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4867 NULL,
4868 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4870 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4871 dwDesiredAccess,
4872 &ObjectAttributes,
4873 ImpersonationLevel,
4874 TokenType,
4875 DuplicateTokenHandle ) );
4878 BOOL WINAPI DuplicateToken(
4879 HANDLE ExistingTokenHandle,
4880 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4881 PHANDLE DuplicateTokenHandle )
4883 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4884 NULL, ImpersonationLevel, TokenImpersonation,
4885 DuplicateTokenHandle );
4888 /******************************************************************************
4889 * ComputeStringSidSize
4891 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4893 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4895 int ctok = 0;
4896 while (*StringSid)
4898 if (*StringSid == '-')
4899 ctok++;
4900 StringSid++;
4903 if (ctok >= 3)
4904 return GetSidLengthRequired(ctok - 2);
4906 else /* String constant format - Only available in winxp and above */
4908 unsigned int i;
4910 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4911 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4912 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4915 return GetSidLengthRequired(0);
4918 /******************************************************************************
4919 * ParseStringSidToSid
4921 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4923 BOOL bret = FALSE;
4924 SID* pisid=pSid;
4926 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4927 if (!StringSid)
4929 SetLastError(ERROR_INVALID_PARAMETER);
4930 TRACE("StringSid is NULL, returning FALSE\n");
4931 return FALSE;
4934 *cBytes = ComputeStringSidSize(StringSid);
4935 if (!pisid) /* Simply compute the size */
4937 TRACE("only size requested, returning TRUE\n");
4938 return TRUE;
4941 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4943 DWORD i = 0, identAuth;
4944 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4946 StringSid += 2; /* Advance to Revision */
4947 pisid->Revision = atoiW(StringSid);
4949 if (pisid->Revision != SDDL_REVISION)
4951 TRACE("Revision %d is unknown\n", pisid->Revision);
4952 goto lend; /* ERROR_INVALID_SID */
4954 if (csubauth == 0)
4956 TRACE("SubAuthorityCount is 0\n");
4957 goto lend; /* ERROR_INVALID_SID */
4960 pisid->SubAuthorityCount = csubauth;
4962 /* Advance to identifier authority */
4963 while (*StringSid && *StringSid != '-')
4964 StringSid++;
4965 if (*StringSid == '-')
4966 StringSid++;
4968 /* MS' implementation can't handle values greater than 2^32 - 1, so
4969 * we don't either; assume most significant bytes are always 0
4971 pisid->IdentifierAuthority.Value[0] = 0;
4972 pisid->IdentifierAuthority.Value[1] = 0;
4973 identAuth = atoiW(StringSid);
4974 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4975 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4976 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4977 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4979 /* Advance to first sub authority */
4980 while (*StringSid && *StringSid != '-')
4981 StringSid++;
4982 if (*StringSid == '-')
4983 StringSid++;
4985 while (*StringSid)
4987 pisid->SubAuthority[i++] = atoiW(StringSid);
4989 while (*StringSid && *StringSid != '-')
4990 StringSid++;
4991 if (*StringSid == '-')
4992 StringSid++;
4995 if (i != pisid->SubAuthorityCount)
4996 goto lend; /* ERROR_INVALID_SID */
4998 bret = TRUE;
5000 else /* String constant format - Only available in winxp and above */
5002 unsigned int i;
5003 pisid->Revision = SDDL_REVISION;
5005 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5006 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5008 DWORD j;
5009 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5010 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5011 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5012 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5013 bret = TRUE;
5016 if (!bret)
5017 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5020 lend:
5021 if (!bret)
5022 SetLastError(ERROR_INVALID_SID);
5024 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5025 return bret;
5028 /******************************************************************************
5029 * GetNamedSecurityInfoA [ADVAPI32.@]
5031 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5032 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5033 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5034 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5036 DWORD len;
5037 LPWSTR wstr = NULL;
5038 DWORD r;
5040 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5041 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5043 if( pObjectName )
5045 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5046 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5047 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5050 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5051 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5053 HeapFree( GetProcessHeap(), 0, wstr );
5055 return r;
5058 /******************************************************************************
5059 * GetNamedSecurityInfoW [ADVAPI32.@]
5061 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5062 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5063 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5065 DWORD needed, offset;
5066 SECURITY_DESCRIPTOR_RELATIVE *relative;
5067 BYTE *buffer;
5069 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5070 group, dacl, sacl, descriptor );
5072 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5074 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5075 if (info & OWNER_SECURITY_INFORMATION)
5076 needed += sizeof(sidWorld);
5077 if (info & GROUP_SECURITY_INFORMATION)
5078 needed += sizeof(sidWorld);
5079 if (info & DACL_SECURITY_INFORMATION)
5080 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5081 if (info & SACL_SECURITY_INFORMATION)
5082 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5084 /* must be freed by caller */
5085 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5086 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5088 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5090 HeapFree( GetProcessHeap(), 0, *descriptor );
5091 return ERROR_INVALID_SECURITY_DESCR;
5094 relative = *descriptor;
5095 relative->Control |= SE_SELF_RELATIVE;
5096 buffer = (BYTE *)relative;
5097 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5099 if (info & OWNER_SECURITY_INFORMATION)
5101 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5102 relative->Owner = offset;
5103 if (owner)
5104 *owner = buffer + offset;
5105 offset += sizeof(sidWorld);
5107 if (info & GROUP_SECURITY_INFORMATION)
5109 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5110 relative->Group = offset;
5111 if (group)
5112 *group = buffer + offset;
5113 offset += sizeof(sidWorld);
5115 if (info & DACL_SECURITY_INFORMATION)
5117 relative->Control |= SE_DACL_PRESENT;
5118 GetWorldAccessACL( (PACL)(buffer + offset) );
5119 relative->Dacl = offset;
5120 if (dacl)
5121 *dacl = (PACL)(buffer + offset);
5122 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5124 if (info & SACL_SECURITY_INFORMATION)
5126 relative->Control |= SE_SACL_PRESENT;
5127 GetWorldAccessACL( (PACL)(buffer + offset) );
5128 relative->Sacl = offset;
5129 if (sacl)
5130 *sacl = (PACL)(buffer + offset);
5132 return ERROR_SUCCESS;
5135 /******************************************************************************
5136 * DecryptFileW [ADVAPI32.@]
5138 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5140 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5141 return TRUE;
5144 /******************************************************************************
5145 * DecryptFileA [ADVAPI32.@]
5147 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5149 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5150 return TRUE;
5153 /******************************************************************************
5154 * EncryptFileW [ADVAPI32.@]
5156 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5158 FIXME("%s\n", debugstr_w(lpFileName));
5159 return TRUE;
5162 /******************************************************************************
5163 * EncryptFileA [ADVAPI32.@]
5165 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5167 FIXME("%s\n", debugstr_a(lpFileName));
5168 return TRUE;
5171 /******************************************************************************
5172 * FileEncryptionStatusW [ADVAPI32.@]
5174 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5176 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5177 if (!lpStatus)
5178 return FALSE;
5179 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5180 return TRUE;
5183 /******************************************************************************
5184 * FileEncryptionStatusA [ADVAPI32.@]
5186 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5188 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5189 if (!lpStatus)
5190 return FALSE;
5191 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5192 return TRUE;
5195 /******************************************************************************
5196 * SetSecurityInfo [ADVAPI32.@]
5198 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5199 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5200 PSID psidGroup, PACL pDacl, PACL pSacl) {
5201 FIXME("stub\n");
5202 return ERROR_SUCCESS;
5205 /******************************************************************************
5206 * SaferCreateLevel [ADVAPI32.@]
5208 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5209 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5211 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5212 return FALSE;
5215 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5216 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5217 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5218 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5219 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5221 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5222 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5223 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5225 return ERROR_SUCCESS;