push 8724397e7ede0f147b6e05994a72142d44d4fecc
[wine/hacks.git] / dlls / advapi32 / security.c
blob454c98f580cb6ef182b50fced429bf4668d215de
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 } AccountSid;
172 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
173 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
174 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
175 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
176 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
177 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
178 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
179 static const WCHAR Blank[] = { 0 };
180 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
181 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
182 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
183 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 };
184 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
185 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 };
186 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
187 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 };
188 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
189 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
190 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
191 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
192 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
193 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
194 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
195 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 };
196 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
197 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 };
198 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
199 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
200 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
201 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
202 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
203 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
204 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 };
205 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
206 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
207 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
208 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
209 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
210 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
211 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 };
212 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 };
213 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
214 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 };
215 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
216 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
217 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
218 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 };
219 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 };
220 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
221 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
222 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 };
223 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
224 static const WCHAR SELF[] = { 'S','E','L','F',0 };
225 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
226 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
227 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
228 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 };
229 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
230 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
232 static const AccountSid ACCOUNT_SIDS[] = {
233 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
234 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
235 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
236 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
237 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
238 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
239 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
240 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
241 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
258 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
259 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
260 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
261 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
262 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
263 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
264 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
265 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
267 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
268 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
269 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
270 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
271 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
272 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
273 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
276 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
279 * ACE access rights
281 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
282 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
283 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
284 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
286 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
287 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
288 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
289 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
290 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
291 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
292 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
293 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
294 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
296 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
297 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
298 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
299 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
301 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
302 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
303 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
304 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
306 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
307 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
308 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
309 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
312 * ACL flags
314 static const WCHAR SDDL_PROTECTED[] = {'P',0};
315 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
316 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
319 * ACE types
321 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
322 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
323 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
324 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
325 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
326 static const WCHAR SDDL_ALARM[] = {'A','L',0};
327 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
328 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
331 * ACE flags
333 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
334 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
335 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
336 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
337 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
338 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
339 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
341 const char * debugstr_sid(PSID sid)
343 int auth = 0;
344 SID * psid = sid;
346 if (psid == NULL)
347 return "(null)";
349 auth = psid->IdentifierAuthority.Value[5] +
350 (psid->IdentifierAuthority.Value[4] << 8) +
351 (psid->IdentifierAuthority.Value[3] << 16) +
352 (psid->IdentifierAuthority.Value[2] << 24);
354 switch (psid->SubAuthorityCount) {
355 case 0:
356 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
357 case 1:
358 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
359 psid->SubAuthority[0]);
360 case 2:
361 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
362 psid->SubAuthority[0], psid->SubAuthority[1]);
363 case 3:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
366 case 4:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
369 psid->SubAuthority[3]);
370 case 5:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3], psid->SubAuthority[4]);
374 case 6:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
378 case 7:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
382 psid->SubAuthority[6]);
383 case 8:
384 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
385 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
386 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
387 psid->SubAuthority[6], psid->SubAuthority[7]);
389 return "(too-big)";
392 /* set last error code from NT status and get the proper boolean return value */
393 /* used for functions that are a simple wrapper around the corresponding ntdll API */
394 static inline BOOL set_ntstatus( NTSTATUS status )
396 if (status) SetLastError( RtlNtStatusToDosError( status ));
397 return !status;
400 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
402 static void GetWorldAccessACL(PACL pACL)
404 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
406 pACL->AclRevision = ACL_REVISION;
407 pACL->Sbz1 = 0;
408 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
409 pACL->AceCount = 1;
410 pACL->Sbz2 = 0;
412 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
413 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
414 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
415 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
416 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
419 /************************************************************
420 * ADVAPI_IsLocalComputer
422 * Checks whether the server name indicates local machine.
424 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
426 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
427 BOOL Result;
428 LPWSTR buf;
430 if (!ServerName || !ServerName[0])
431 return TRUE;
433 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
434 Result = GetComputerNameW(buf, &dwSize);
435 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
436 ServerName += 2;
437 Result = Result && !lstrcmpW(ServerName, buf);
438 HeapFree(GetProcessHeap(), 0, buf);
440 return Result;
443 /************************************************************
444 * ADVAPI_GetComputerSid
446 * Reads the computer SID from the registry.
448 BOOL ADVAPI_GetComputerSid(PSID sid)
450 HKEY key;
451 LONG ret;
452 BOOL retval = FALSE;
453 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 };
454 static const WCHAR V[] = { 'V',0 };
456 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
457 KEY_READ, &key)) == ERROR_SUCCESS)
459 DWORD size = 0;
460 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
461 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
463 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
464 if (data)
466 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
467 data, &size)) == ERROR_SUCCESS)
469 /* the SID is in the last 24 bytes of the binary data */
470 CopyMemory(sid, &data[size-24], 24);
471 retval = TRUE;
473 HeapFree(GetProcessHeap(), 0, data);
476 RegCloseKey(key);
479 if(retval == TRUE) return retval;
481 /* create a new random SID */
482 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
483 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
485 PSID new_sid;
486 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
487 DWORD id[3];
489 if (RtlGenRandom(id, sizeof(id)))
491 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
493 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
494 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
496 FreeSid(new_sid);
499 RegCloseKey(key);
502 return retval;
505 /* ##############################
506 ###### TOKEN FUNCTIONS ######
507 ##############################
510 /******************************************************************************
511 * OpenProcessToken [ADVAPI32.@]
512 * Opens the access token associated with a process handle.
514 * PARAMS
515 * ProcessHandle [I] Handle to process
516 * DesiredAccess [I] Desired access to process
517 * TokenHandle [O] Pointer to handle of open access token
519 * RETURNS
520 * Success: TRUE. TokenHandle contains the access token.
521 * Failure: FALSE.
523 * NOTES
524 * See NtOpenProcessToken.
526 BOOL WINAPI
527 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
528 HANDLE *TokenHandle )
530 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
533 /******************************************************************************
534 * OpenThreadToken [ADVAPI32.@]
536 * Opens the access token associated with a thread handle.
538 * PARAMS
539 * ThreadHandle [I] Handle to process
540 * DesiredAccess [I] Desired access to the thread
541 * OpenAsSelf [I] ???
542 * TokenHandle [O] Destination for the token handle
544 * RETURNS
545 * Success: TRUE. TokenHandle contains the access token.
546 * Failure: FALSE.
548 * NOTES
549 * See NtOpenThreadToken.
551 BOOL WINAPI
552 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
553 BOOL OpenAsSelf, HANDLE *TokenHandle)
555 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
558 BOOL WINAPI
559 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
560 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
562 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
563 PreviousState, ReturnLength));
566 /******************************************************************************
567 * AdjustTokenPrivileges [ADVAPI32.@]
569 * Adjust the privileges of an open token handle.
571 * PARAMS
572 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
574 * NewState [I] Desired new privileges of the token
575 * BufferLength [I] Length of NewState
576 * PreviousState [O] Destination for the previous state
577 * ReturnLength [I/O] Size of PreviousState
580 * RETURNS
581 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
582 * Failure: FALSE.
584 * NOTES
585 * See NtAdjustPrivilegesToken.
587 BOOL WINAPI
588 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
589 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
590 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
592 NTSTATUS status;
594 TRACE("\n");
596 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
597 NewState, BufferLength, PreviousState,
598 ReturnLength);
599 SetLastError( RtlNtStatusToDosError( status ));
600 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
601 return TRUE;
602 else
603 return FALSE;
606 /******************************************************************************
607 * CheckTokenMembership [ADVAPI32.@]
609 * Determine if an access token is a member of a SID.
611 * PARAMS
612 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
613 * SidToCheck [I] SID that possibly contains the token
614 * IsMember [O] Destination for result.
616 * RETURNS
617 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
618 * Failure: FALSE.
620 BOOL WINAPI
621 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
622 PBOOL IsMember )
624 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
626 *IsMember = TRUE;
627 return(TRUE);
630 /******************************************************************************
631 * GetTokenInformation [ADVAPI32.@]
633 * Get a type of information about an access token.
635 * PARAMS
636 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
637 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
638 * tokeninfo [O] Destination for token information
639 * tokeninfolength [I] Length of tokeninfo
640 * retlen [O] Destination for returned token information length
642 * RETURNS
643 * Success: TRUE. tokeninfo contains retlen bytes of token information
644 * Failure: FALSE.
646 * NOTES
647 * See NtQueryInformationToken.
649 BOOL WINAPI
650 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
651 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
653 TRACE("(%p, %s, %p, %d, %p):\n",
654 token,
655 (tokeninfoclass == TokenUser) ? "TokenUser" :
656 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
657 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
658 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
659 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
660 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
661 (tokeninfoclass == TokenSource) ? "TokenSource" :
662 (tokeninfoclass == TokenType) ? "TokenType" :
663 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
664 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
665 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
666 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
667 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
668 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
669 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
670 "Unknown",
671 tokeninfo, tokeninfolength, retlen);
672 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
673 tokeninfolength, retlen));
676 /******************************************************************************
677 * SetTokenInformation [ADVAPI32.@]
679 * Set information for an access token.
681 * PARAMS
682 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
683 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
684 * tokeninfo [I] Token information to set
685 * tokeninfolength [I] Length of tokeninfo
687 * RETURNS
688 * Success: TRUE. The information for the token is set to tokeninfo.
689 * Failure: FALSE.
691 BOOL WINAPI
692 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
693 LPVOID tokeninfo, DWORD tokeninfolength )
695 TRACE("(%p, %s, %p, %d): stub\n",
696 token,
697 (tokeninfoclass == TokenUser) ? "TokenUser" :
698 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
699 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
700 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
701 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
702 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
703 (tokeninfoclass == TokenSource) ? "TokenSource" :
704 (tokeninfoclass == TokenType) ? "TokenType" :
705 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
706 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
707 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
708 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
709 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
710 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
711 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
712 "Unknown",
713 tokeninfo, tokeninfolength);
715 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
718 /*************************************************************************
719 * SetThreadToken [ADVAPI32.@]
721 * Assigns an 'impersonation token' to a thread so it can assume the
722 * security privileges of another thread or process. Can also remove
723 * a previously assigned token.
725 * PARAMS
726 * thread [O] Handle to thread to set the token for
727 * token [I] Token to set
729 * RETURNS
730 * Success: TRUE. The threads access token is set to token
731 * Failure: FALSE.
733 * NOTES
734 * Only supported on NT or higher. On Win9X this function does nothing.
735 * See SetTokenInformation.
737 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
739 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
740 ThreadImpersonationToken, &token, sizeof token ));
743 /*************************************************************************
744 * CreateRestrictedToken [ADVAPI32.@]
746 * Create a new more restricted token from an existing token.
748 * PARAMS
749 * baseToken [I] Token to base the new restricted token on
750 * flags [I] Options
751 * nDisableSids [I] Length of disableSids array
752 * disableSids [I] Array of SIDs to disable in the new token
753 * nDeletePrivs [I] Length of deletePrivs array
754 * deletePrivs [I] Array of privileges to delete in the new token
755 * nRestrictSids [I] Length of restrictSids array
756 * restrictSids [I] Array of SIDs to restrict in the new token
757 * newToken [O] Address where the new token is stored
759 * RETURNS
760 * Success: TRUE
761 * Failure: FALSE
763 BOOL WINAPI CreateRestrictedToken(
764 HANDLE baseToken,
765 DWORD flags,
766 DWORD nDisableSids,
767 PSID_AND_ATTRIBUTES disableSids,
768 DWORD nDeletePrivs,
769 PLUID_AND_ATTRIBUTES deletePrivs,
770 DWORD nRestrictSids,
771 PSID_AND_ATTRIBUTES restrictSids,
772 PHANDLE newToken)
774 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
775 baseToken, flags, nDisableSids, disableSids,
776 nDeletePrivs, deletePrivs,
777 nRestrictSids, restrictSids,
778 newToken);
779 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
780 return FALSE;
783 /* ##############################
784 ###### SID FUNCTIONS ######
785 ##############################
788 /******************************************************************************
789 * AllocateAndInitializeSid [ADVAPI32.@]
791 * PARAMS
792 * pIdentifierAuthority []
793 * nSubAuthorityCount []
794 * nSubAuthority0 []
795 * nSubAuthority1 []
796 * nSubAuthority2 []
797 * nSubAuthority3 []
798 * nSubAuthority4 []
799 * nSubAuthority5 []
800 * nSubAuthority6 []
801 * nSubAuthority7 []
802 * pSid []
804 BOOL WINAPI
805 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
806 BYTE nSubAuthorityCount,
807 DWORD nSubAuthority0, DWORD nSubAuthority1,
808 DWORD nSubAuthority2, DWORD nSubAuthority3,
809 DWORD nSubAuthority4, DWORD nSubAuthority5,
810 DWORD nSubAuthority6, DWORD nSubAuthority7,
811 PSID *pSid )
813 return set_ntstatus( RtlAllocateAndInitializeSid(
814 pIdentifierAuthority, nSubAuthorityCount,
815 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
816 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
817 pSid ));
820 /******************************************************************************
821 * FreeSid [ADVAPI32.@]
823 * PARAMS
824 * pSid []
826 PVOID WINAPI
827 FreeSid( PSID pSid )
829 RtlFreeSid(pSid);
830 return NULL; /* is documented like this */
833 /******************************************************************************
834 * CopySid [ADVAPI32.@]
836 * PARAMS
837 * nDestinationSidLength []
838 * pDestinationSid []
839 * pSourceSid []
841 BOOL WINAPI
842 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
844 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
847 /******************************************************************************
848 * CreateWellKnownSid [ADVAPI32.@]
850 BOOL WINAPI
851 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
852 PSID DomainSid,
853 PSID pSid,
854 DWORD* cbSid)
856 unsigned int i;
857 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
859 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
860 SetLastError(ERROR_INVALID_PARAMETER);
861 return FALSE;
864 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
865 if (WellKnownSids[i].Type == WellKnownSidType) {
866 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
868 if (*cbSid < length) {
869 SetLastError(ERROR_INSUFFICIENT_BUFFER);
870 return FALSE;
873 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
874 *cbSid = length;
875 return TRUE;
879 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
881 SetLastError(ERROR_INVALID_PARAMETER);
882 return FALSE;
885 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
886 if (WellKnownRids[i].Type == WellKnownSidType) {
887 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
888 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
889 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
891 if (*cbSid < output_sid_length) {
892 SetLastError(ERROR_INSUFFICIENT_BUFFER);
893 return FALSE;
896 CopyMemory(pSid, DomainSid, domain_sid_length);
897 (*GetSidSubAuthorityCount(pSid))++;
898 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
899 *cbSid = output_sid_length;
900 return TRUE;
903 SetLastError(ERROR_INVALID_PARAMETER);
904 return FALSE;
907 /******************************************************************************
908 * IsWellKnownSid [ADVAPI32.@]
910 BOOL WINAPI
911 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
913 unsigned int i;
914 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
916 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
917 if (WellKnownSids[i].Type == WellKnownSidType)
918 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
919 return TRUE;
921 return FALSE;
924 BOOL WINAPI
925 IsTokenRestricted( HANDLE TokenHandle )
927 TOKEN_GROUPS *groups;
928 DWORD size;
929 NTSTATUS status;
930 BOOL restricted;
932 TRACE("(%p)\n", TokenHandle);
934 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
935 if (status != STATUS_BUFFER_TOO_SMALL)
936 return FALSE;
938 groups = HeapAlloc(GetProcessHeap(), 0, size);
939 if (!groups)
941 SetLastError(ERROR_OUTOFMEMORY);
942 return FALSE;
945 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
946 if (status != STATUS_SUCCESS)
948 HeapFree(GetProcessHeap(), 0, groups);
949 return set_ntstatus(status);
952 if (groups->GroupCount)
953 restricted = TRUE;
954 else
955 restricted = FALSE;
957 HeapFree(GetProcessHeap(), 0, groups);
959 return restricted;
962 /******************************************************************************
963 * IsValidSid [ADVAPI32.@]
965 * PARAMS
966 * pSid []
968 BOOL WINAPI
969 IsValidSid( PSID pSid )
971 return RtlValidSid( pSid );
974 /******************************************************************************
975 * EqualSid [ADVAPI32.@]
977 * PARAMS
978 * pSid1 []
979 * pSid2 []
981 BOOL WINAPI
982 EqualSid( PSID pSid1, PSID pSid2 )
984 return RtlEqualSid( pSid1, pSid2 );
987 /******************************************************************************
988 * EqualPrefixSid [ADVAPI32.@]
990 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
992 return RtlEqualPrefixSid(pSid1, pSid2);
995 /******************************************************************************
996 * GetSidLengthRequired [ADVAPI32.@]
998 * PARAMS
999 * nSubAuthorityCount []
1001 DWORD WINAPI
1002 GetSidLengthRequired( BYTE nSubAuthorityCount )
1004 return RtlLengthRequiredSid(nSubAuthorityCount);
1007 /******************************************************************************
1008 * InitializeSid [ADVAPI32.@]
1010 * PARAMS
1011 * pIdentifierAuthority []
1013 BOOL WINAPI
1014 InitializeSid (
1015 PSID pSid,
1016 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1017 BYTE nSubAuthorityCount)
1019 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1022 DWORD WINAPI
1023 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1025 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1027 return 1;
1030 DWORD WINAPI
1031 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1033 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1035 return 1;
1038 /******************************************************************************
1039 * GetSidIdentifierAuthority [ADVAPI32.@]
1041 * PARAMS
1042 * pSid []
1044 PSID_IDENTIFIER_AUTHORITY WINAPI
1045 GetSidIdentifierAuthority( PSID pSid )
1047 return RtlIdentifierAuthoritySid(pSid);
1050 /******************************************************************************
1051 * GetSidSubAuthority [ADVAPI32.@]
1053 * PARAMS
1054 * pSid []
1055 * nSubAuthority []
1057 PDWORD WINAPI
1058 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1060 return RtlSubAuthoritySid(pSid, nSubAuthority);
1063 /******************************************************************************
1064 * GetSidSubAuthorityCount [ADVAPI32.@]
1066 * PARAMS
1067 * pSid []
1069 PUCHAR WINAPI
1070 GetSidSubAuthorityCount (PSID pSid)
1072 return RtlSubAuthorityCountSid(pSid);
1075 /******************************************************************************
1076 * GetLengthSid [ADVAPI32.@]
1078 * PARAMS
1079 * pSid []
1081 DWORD WINAPI
1082 GetLengthSid (PSID pSid)
1084 return RtlLengthSid(pSid);
1087 /* ##############################################
1088 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1089 ##############################################
1092 /******************************************************************************
1093 * BuildSecurityDescriptorA [ADVAPI32.@]
1095 * Builds a SD from
1097 * PARAMS
1098 * pOwner [I]
1099 * pGroup [I]
1100 * cCountOfAccessEntries [I]
1101 * pListOfAccessEntries [I]
1102 * cCountOfAuditEntries [I]
1103 * pListofAuditEntries [I]
1104 * pOldSD [I]
1105 * lpdwBufferLength [I/O]
1106 * pNewSD [O]
1108 * RETURNS
1109 * Success: ERROR_SUCCESS
1110 * Failure: nonzero error code from Winerror.h
1112 DWORD WINAPI BuildSecurityDescriptorA(
1113 IN PTRUSTEEA pOwner,
1114 IN PTRUSTEEA pGroup,
1115 IN ULONG cCountOfAccessEntries,
1116 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1117 IN ULONG cCountOfAuditEntries,
1118 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1119 IN PSECURITY_DESCRIPTOR pOldSD,
1120 IN OUT PULONG lpdwBufferLength,
1121 OUT PSECURITY_DESCRIPTOR* pNewSD)
1123 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1124 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1125 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1127 return ERROR_CALL_NOT_IMPLEMENTED;
1130 /******************************************************************************
1131 * BuildSecurityDescriptorW [ADVAPI32.@]
1133 * See BuildSecurityDescriptorA.
1135 DWORD WINAPI BuildSecurityDescriptorW(
1136 IN PTRUSTEEW pOwner,
1137 IN PTRUSTEEW pGroup,
1138 IN ULONG cCountOfAccessEntries,
1139 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1140 IN ULONG cCountOfAuditEntries,
1141 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1142 IN PSECURITY_DESCRIPTOR pOldSD,
1143 IN OUT PULONG lpdwBufferLength,
1144 OUT PSECURITY_DESCRIPTOR* pNewSD)
1146 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1147 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1148 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1150 return ERROR_CALL_NOT_IMPLEMENTED;
1153 /******************************************************************************
1154 * InitializeSecurityDescriptor [ADVAPI32.@]
1156 * PARAMS
1157 * pDescr []
1158 * revision []
1160 BOOL WINAPI
1161 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1163 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1167 /******************************************************************************
1168 * MakeAbsoluteSD [ADVAPI32.@]
1170 BOOL WINAPI MakeAbsoluteSD (
1171 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1172 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1173 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1174 OUT PACL pDacl,
1175 OUT LPDWORD lpdwDaclSize,
1176 OUT PACL pSacl,
1177 OUT LPDWORD lpdwSaclSize,
1178 OUT PSID pOwner,
1179 OUT LPDWORD lpdwOwnerSize,
1180 OUT PSID pPrimaryGroup,
1181 OUT LPDWORD lpdwPrimaryGroupSize)
1183 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1184 pAbsoluteSecurityDescriptor,
1185 lpdwAbsoluteSecurityDescriptorSize,
1186 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1187 pOwner, lpdwOwnerSize,
1188 pPrimaryGroup, lpdwPrimaryGroupSize));
1191 /******************************************************************************
1192 * GetKernelObjectSecurity [ADVAPI32.@]
1194 BOOL WINAPI GetKernelObjectSecurity(
1195 HANDLE Handle,
1196 SECURITY_INFORMATION RequestedInformation,
1197 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1198 DWORD nLength,
1199 LPDWORD lpnLengthNeeded )
1201 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1202 pSecurityDescriptor, nLength, lpnLengthNeeded);
1204 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1205 nLength, lpnLengthNeeded ));
1208 /******************************************************************************
1209 * GetPrivateObjectSecurity [ADVAPI32.@]
1211 BOOL WINAPI GetPrivateObjectSecurity(
1212 PSECURITY_DESCRIPTOR ObjectDescriptor,
1213 SECURITY_INFORMATION SecurityInformation,
1214 PSECURITY_DESCRIPTOR ResultantDescriptor,
1215 DWORD DescriptorLength,
1216 PDWORD ReturnLength )
1218 SECURITY_DESCRIPTOR desc;
1219 BOOL defaulted, present;
1220 PACL pacl;
1221 PSID psid;
1223 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1224 ResultantDescriptor, DescriptorLength, ReturnLength);
1226 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1227 return FALSE;
1229 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1231 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1232 return FALSE;
1233 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1236 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1238 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1239 return FALSE;
1240 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1243 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1245 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1246 return FALSE;
1247 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1250 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1252 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1253 return FALSE;
1254 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1257 *ReturnLength = DescriptorLength;
1258 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1261 /******************************************************************************
1262 * GetSecurityDescriptorLength [ADVAPI32.@]
1264 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1266 return RtlLengthSecurityDescriptor(pDescr);
1269 /******************************************************************************
1270 * GetSecurityDescriptorOwner [ADVAPI32.@]
1272 * PARAMS
1273 * pOwner []
1274 * lpbOwnerDefaulted []
1276 BOOL WINAPI
1277 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1278 LPBOOL lpbOwnerDefaulted )
1280 BOOLEAN defaulted;
1281 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1282 *lpbOwnerDefaulted = defaulted;
1283 return ret;
1286 /******************************************************************************
1287 * SetSecurityDescriptorOwner [ADVAPI32.@]
1289 * PARAMS
1291 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1292 PSID pOwner, BOOL bOwnerDefaulted)
1294 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1296 /******************************************************************************
1297 * GetSecurityDescriptorGroup [ADVAPI32.@]
1299 BOOL WINAPI GetSecurityDescriptorGroup(
1300 PSECURITY_DESCRIPTOR SecurityDescriptor,
1301 PSID *Group,
1302 LPBOOL GroupDefaulted)
1304 BOOLEAN defaulted;
1305 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1306 *GroupDefaulted = defaulted;
1307 return ret;
1309 /******************************************************************************
1310 * SetSecurityDescriptorGroup [ADVAPI32.@]
1312 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1313 PSID Group, BOOL GroupDefaulted)
1315 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1318 /******************************************************************************
1319 * IsValidSecurityDescriptor [ADVAPI32.@]
1321 * PARAMS
1322 * lpsecdesc []
1324 BOOL WINAPI
1325 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1327 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1330 /******************************************************************************
1331 * GetSecurityDescriptorDacl [ADVAPI32.@]
1333 BOOL WINAPI GetSecurityDescriptorDacl(
1334 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1335 OUT LPBOOL lpbDaclPresent,
1336 OUT PACL *pDacl,
1337 OUT LPBOOL lpbDaclDefaulted)
1339 BOOLEAN present, defaulted;
1340 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1341 *lpbDaclPresent = present;
1342 *lpbDaclDefaulted = defaulted;
1343 return ret;
1346 /******************************************************************************
1347 * SetSecurityDescriptorDacl [ADVAPI32.@]
1349 BOOL WINAPI
1350 SetSecurityDescriptorDacl (
1351 PSECURITY_DESCRIPTOR lpsd,
1352 BOOL daclpresent,
1353 PACL dacl,
1354 BOOL dacldefaulted )
1356 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1358 /******************************************************************************
1359 * GetSecurityDescriptorSacl [ADVAPI32.@]
1361 BOOL WINAPI GetSecurityDescriptorSacl(
1362 IN PSECURITY_DESCRIPTOR lpsd,
1363 OUT LPBOOL lpbSaclPresent,
1364 OUT PACL *pSacl,
1365 OUT LPBOOL lpbSaclDefaulted)
1367 BOOLEAN present, defaulted;
1368 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1369 *lpbSaclPresent = present;
1370 *lpbSaclDefaulted = defaulted;
1371 return ret;
1374 /**************************************************************************
1375 * SetSecurityDescriptorSacl [ADVAPI32.@]
1377 BOOL WINAPI SetSecurityDescriptorSacl (
1378 PSECURITY_DESCRIPTOR lpsd,
1379 BOOL saclpresent,
1380 PACL lpsacl,
1381 BOOL sacldefaulted)
1383 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1385 /******************************************************************************
1386 * MakeSelfRelativeSD [ADVAPI32.@]
1388 * PARAMS
1389 * lpabssecdesc []
1390 * lpselfsecdesc []
1391 * lpbuflen []
1393 BOOL WINAPI
1394 MakeSelfRelativeSD(
1395 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1396 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1397 IN OUT LPDWORD lpdwBufferLength)
1399 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1400 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1403 /******************************************************************************
1404 * GetSecurityDescriptorControl [ADVAPI32.@]
1407 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1408 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1410 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1413 /******************************************************************************
1414 * SetSecurityDescriptorControl [ADVAPI32.@]
1416 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1417 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1418 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1420 return set_ntstatus( RtlSetControlSecurityDescriptor(
1421 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1424 /* ##############################
1425 ###### ACL FUNCTIONS ######
1426 ##############################
1429 /*************************************************************************
1430 * InitializeAcl [ADVAPI32.@]
1432 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1434 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1437 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1439 IO_STATUS_BLOCK io_block;
1441 TRACE("(%p)\n", hNamedPipe);
1443 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1444 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1447 /******************************************************************************
1448 * AddAccessAllowedAce [ADVAPI32.@]
1450 BOOL WINAPI AddAccessAllowedAce(
1451 IN OUT PACL pAcl,
1452 IN DWORD dwAceRevision,
1453 IN DWORD AccessMask,
1454 IN PSID pSid)
1456 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1459 /******************************************************************************
1460 * AddAccessAllowedAceEx [ADVAPI32.@]
1462 BOOL WINAPI AddAccessAllowedAceEx(
1463 IN OUT PACL pAcl,
1464 IN DWORD dwAceRevision,
1465 IN DWORD AceFlags,
1466 IN DWORD AccessMask,
1467 IN PSID pSid)
1469 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1472 /******************************************************************************
1473 * AddAccessDeniedAce [ADVAPI32.@]
1475 BOOL WINAPI AddAccessDeniedAce(
1476 IN OUT PACL pAcl,
1477 IN DWORD dwAceRevision,
1478 IN DWORD AccessMask,
1479 IN PSID pSid)
1481 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1484 /******************************************************************************
1485 * AddAccessDeniedAceEx [ADVAPI32.@]
1487 BOOL WINAPI AddAccessDeniedAceEx(
1488 IN OUT PACL pAcl,
1489 IN DWORD dwAceRevision,
1490 IN DWORD AceFlags,
1491 IN DWORD AccessMask,
1492 IN PSID pSid)
1494 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1497 /******************************************************************************
1498 * AddAce [ADVAPI32.@]
1500 BOOL WINAPI AddAce(
1501 IN OUT PACL pAcl,
1502 IN DWORD dwAceRevision,
1503 IN DWORD dwStartingAceIndex,
1504 LPVOID pAceList,
1505 DWORD nAceListLength)
1507 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1510 /******************************************************************************
1511 * DeleteAce [ADVAPI32.@]
1513 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1515 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1518 /******************************************************************************
1519 * FindFirstFreeAce [ADVAPI32.@]
1521 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1523 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1526 /******************************************************************************
1527 * GetAce [ADVAPI32.@]
1529 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1531 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1534 /******************************************************************************
1535 * GetAclInformation [ADVAPI32.@]
1537 BOOL WINAPI GetAclInformation(
1538 PACL pAcl,
1539 LPVOID pAclInformation,
1540 DWORD nAclInformationLength,
1541 ACL_INFORMATION_CLASS dwAclInformationClass)
1543 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1544 nAclInformationLength, dwAclInformationClass));
1547 /******************************************************************************
1548 * IsValidAcl [ADVAPI32.@]
1550 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1552 return RtlValidAcl(pAcl);
1555 /* ##############################
1556 ###### MISC FUNCTIONS ######
1557 ##############################
1560 /******************************************************************************
1561 * AllocateLocallyUniqueId [ADVAPI32.@]
1563 * PARAMS
1564 * lpLuid []
1566 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1568 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1571 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1572 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1574 { '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 };
1575 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1576 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1578 { '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 };
1579 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1580 { '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 };
1581 static const WCHAR SE_TCB_NAME_W[] =
1582 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_SECURITY_NAME_W[] =
1584 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1585 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1586 { '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 };
1587 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1588 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1592 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1596 { '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 };
1597 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1598 { '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 };
1599 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1600 { '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 };
1601 static const WCHAR SE_BACKUP_NAME_W[] =
1602 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_RESTORE_NAME_W[] =
1604 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1606 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_DEBUG_NAME_W[] =
1608 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_AUDIT_NAME_W[] =
1610 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1612 { '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 };
1613 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1614 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_UNDOCK_NAME_W[] =
1618 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1620 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1622 { '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 };
1623 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1624 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1626 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1627 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1628 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1632 NULL,
1633 NULL,
1634 SE_CREATE_TOKEN_NAME_W,
1635 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1636 SE_LOCK_MEMORY_NAME_W,
1637 SE_INCREASE_QUOTA_NAME_W,
1638 SE_MACHINE_ACCOUNT_NAME_W,
1639 SE_TCB_NAME_W,
1640 SE_SECURITY_NAME_W,
1641 SE_TAKE_OWNERSHIP_NAME_W,
1642 SE_LOAD_DRIVER_NAME_W,
1643 SE_SYSTEM_PROFILE_NAME_W,
1644 SE_SYSTEMTIME_NAME_W,
1645 SE_PROF_SINGLE_PROCESS_NAME_W,
1646 SE_INC_BASE_PRIORITY_NAME_W,
1647 SE_CREATE_PAGEFILE_NAME_W,
1648 SE_CREATE_PERMANENT_NAME_W,
1649 SE_BACKUP_NAME_W,
1650 SE_RESTORE_NAME_W,
1651 SE_SHUTDOWN_NAME_W,
1652 SE_DEBUG_NAME_W,
1653 SE_AUDIT_NAME_W,
1654 SE_SYSTEM_ENVIRONMENT_NAME_W,
1655 SE_CHANGE_NOTIFY_NAME_W,
1656 SE_REMOTE_SHUTDOWN_NAME_W,
1657 SE_UNDOCK_NAME_W,
1658 SE_SYNC_AGENT_NAME_W,
1659 SE_ENABLE_DELEGATION_NAME_W,
1660 SE_MANAGE_VOLUME_NAME_W,
1661 SE_IMPERSONATE_NAME_W,
1662 SE_CREATE_GLOBAL_NAME_W,
1665 /******************************************************************************
1666 * LookupPrivilegeValueW [ADVAPI32.@]
1668 * See LookupPrivilegeValueA.
1670 BOOL WINAPI
1671 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1673 UINT i;
1675 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1677 if (!ADVAPI_IsLocalComputer(lpSystemName))
1679 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1680 return FALSE;
1682 if (!lpName)
1684 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1685 return FALSE;
1687 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1689 if( !WellKnownPrivNames[i] )
1690 continue;
1691 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1692 continue;
1693 lpLuid->LowPart = i;
1694 lpLuid->HighPart = 0;
1695 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1696 lpLuid->HighPart, lpLuid->LowPart );
1697 return TRUE;
1699 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1700 return FALSE;
1703 /******************************************************************************
1704 * LookupPrivilegeValueA [ADVAPI32.@]
1706 * Retrieves LUID used on a system to represent the privilege name.
1708 * PARAMS
1709 * lpSystemName [I] Name of the system
1710 * lpName [I] Name of the privilege
1711 * lpLuid [O] Destination for the resulting LUID
1713 * RETURNS
1714 * Success: TRUE. lpLuid contains the requested LUID.
1715 * Failure: FALSE.
1717 BOOL WINAPI
1718 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1720 UNICODE_STRING lpSystemNameW;
1721 UNICODE_STRING lpNameW;
1722 BOOL ret;
1724 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1725 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1726 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1727 RtlFreeUnicodeString(&lpNameW);
1728 RtlFreeUnicodeString(&lpSystemNameW);
1729 return ret;
1732 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1733 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1735 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1736 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1738 return FALSE;
1741 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1742 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1744 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1745 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1747 return FALSE;
1750 /******************************************************************************
1751 * LookupPrivilegeNameA [ADVAPI32.@]
1753 * See LookupPrivilegeNameW.
1755 BOOL WINAPI
1756 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1757 LPDWORD cchName)
1759 UNICODE_STRING lpSystemNameW;
1760 BOOL ret;
1761 DWORD wLen = 0;
1763 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1765 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1766 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1767 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1769 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1771 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1772 &wLen);
1773 if (ret)
1775 /* Windows crashes if cchName is NULL, so will I */
1776 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1777 *cchName, NULL, NULL);
1779 if (len == 0)
1781 /* WideCharToMultiByte failed */
1782 ret = FALSE;
1784 else if (len > *cchName)
1786 *cchName = len;
1787 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1788 ret = FALSE;
1790 else
1792 /* WideCharToMultiByte succeeded, output length needs to be
1793 * length not including NULL terminator
1795 *cchName = len - 1;
1798 HeapFree(GetProcessHeap(), 0, lpNameW);
1800 RtlFreeUnicodeString(&lpSystemNameW);
1801 return ret;
1804 /******************************************************************************
1805 * LookupPrivilegeNameW [ADVAPI32.@]
1807 * Retrieves the privilege name referred to by the LUID lpLuid.
1809 * PARAMS
1810 * lpSystemName [I] Name of the system
1811 * lpLuid [I] Privilege value
1812 * lpName [O] Name of the privilege
1813 * cchName [I/O] Number of characters in lpName.
1815 * RETURNS
1816 * Success: TRUE. lpName contains the name of the privilege whose value is
1817 * *lpLuid.
1818 * Failure: FALSE.
1820 * REMARKS
1821 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1822 * using this function.
1823 * If the length of lpName is too small, on return *cchName will contain the
1824 * number of WCHARs needed to contain the privilege, including the NULL
1825 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1826 * On success, *cchName will contain the number of characters stored in
1827 * lpName, NOT including the NULL terminator.
1829 BOOL WINAPI
1830 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1831 LPDWORD cchName)
1833 size_t privNameLen;
1835 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1837 if (!ADVAPI_IsLocalComputer(lpSystemName))
1839 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1840 return FALSE;
1842 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1843 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1845 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1846 return FALSE;
1848 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1849 /* Windows crashes if cchName is NULL, so will I */
1850 if (*cchName <= privNameLen)
1852 *cchName = privNameLen + 1;
1853 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1854 return FALSE;
1856 else
1858 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1859 *cchName = privNameLen;
1860 return TRUE;
1864 /******************************************************************************
1865 * GetFileSecurityA [ADVAPI32.@]
1867 * Obtains Specified information about the security of a file or directory.
1869 * PARAMS
1870 * lpFileName [I] Name of the file to get info for
1871 * RequestedInformation [I] SE_ flags from "winnt.h"
1872 * pSecurityDescriptor [O] Destination for security information
1873 * nLength [I] Length of pSecurityDescriptor
1874 * lpnLengthNeeded [O] Destination for length of returned security information
1876 * RETURNS
1877 * Success: TRUE. pSecurityDescriptor contains the requested information.
1878 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1880 * NOTES
1881 * The information returned is constrained by the callers access rights and
1882 * privileges.
1884 BOOL WINAPI
1885 GetFileSecurityA( LPCSTR lpFileName,
1886 SECURITY_INFORMATION RequestedInformation,
1887 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1888 DWORD nLength, LPDWORD lpnLengthNeeded )
1890 DWORD len;
1891 BOOL r;
1892 LPWSTR name = NULL;
1894 if( lpFileName )
1896 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1897 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1898 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1901 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1902 nLength, lpnLengthNeeded );
1903 HeapFree( GetProcessHeap(), 0, name );
1905 return r;
1908 /******************************************************************************
1909 * GetFileSecurityW [ADVAPI32.@]
1911 * See GetFileSecurityA.
1913 BOOL WINAPI
1914 GetFileSecurityW( LPCWSTR lpFileName,
1915 SECURITY_INFORMATION RequestedInformation,
1916 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1917 DWORD nLength, LPDWORD lpnLengthNeeded )
1919 HANDLE hfile;
1920 NTSTATUS status;
1921 DWORD access = 0;
1923 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1924 RequestedInformation, pSecurityDescriptor,
1925 nLength, lpnLengthNeeded);
1927 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1928 DACL_SECURITY_INFORMATION))
1929 access |= READ_CONTROL;
1930 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1931 access |= ACCESS_SYSTEM_SECURITY;
1933 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1934 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1935 if ( hfile == INVALID_HANDLE_VALUE )
1936 return FALSE;
1938 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1939 nLength, lpnLengthNeeded );
1940 CloseHandle( hfile );
1941 return set_ntstatus( status );
1945 /******************************************************************************
1946 * LookupAccountSidA [ADVAPI32.@]
1948 BOOL WINAPI
1949 LookupAccountSidA(
1950 IN LPCSTR system,
1951 IN PSID sid,
1952 OUT LPSTR account,
1953 IN OUT LPDWORD accountSize,
1954 OUT LPSTR domain,
1955 IN OUT LPDWORD domainSize,
1956 OUT PSID_NAME_USE name_use )
1958 DWORD len;
1959 BOOL r;
1960 LPWSTR systemW = NULL;
1961 LPWSTR accountW = NULL;
1962 LPWSTR domainW = NULL;
1963 DWORD accountSizeW = *accountSize;
1964 DWORD domainSizeW = *domainSize;
1966 if (system) {
1967 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1968 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1969 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1971 if (account)
1972 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1973 if (domain)
1974 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1976 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1978 if (r) {
1979 if (accountW && *accountSize) {
1980 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1981 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1982 *accountSize = len;
1983 } else
1984 *accountSize = accountSizeW + 1;
1986 if (domainW && *domainSize) {
1987 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1988 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1989 *domainSize = len;
1990 } else
1991 *domainSize = domainSizeW + 1;
1994 HeapFree( GetProcessHeap(), 0, systemW );
1995 HeapFree( GetProcessHeap(), 0, accountW );
1996 HeapFree( GetProcessHeap(), 0, domainW );
1998 return r;
2001 /******************************************************************************
2002 * LookupAccountSidW [ADVAPI32.@]
2004 * PARAMS
2005 * system []
2006 * sid []
2007 * account []
2008 * accountSize []
2009 * domain []
2010 * domainSize []
2011 * name_use []
2014 BOOL WINAPI
2015 LookupAccountSidW(
2016 IN LPCWSTR system,
2017 IN PSID sid,
2018 OUT LPWSTR account,
2019 IN OUT LPDWORD accountSize,
2020 OUT LPWSTR domain,
2021 IN OUT LPDWORD domainSize,
2022 OUT PSID_NAME_USE name_use )
2024 unsigned int i, j;
2025 const WCHAR * ac = NULL;
2026 const WCHAR * dm = NULL;
2027 SID_NAME_USE use = 0;
2028 LPWSTR computer_name = NULL;
2029 LPWSTR account_name = NULL;
2031 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2032 debugstr_w(system),debugstr_sid(sid),
2033 account,accountSize,accountSize?*accountSize:0,
2034 domain,domainSize,domainSize?*domainSize:0,
2035 name_use);
2037 if (!ADVAPI_IsLocalComputer(system)) {
2038 FIXME("Only local computer supported!\n");
2039 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2040 return FALSE;
2043 /* check the well known SIDs first */
2044 for (i = 0; i <= 60; i++) {
2045 if (IsWellKnownSid(sid, i)) {
2046 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2047 if (ACCOUNT_SIDS[j].type == i) {
2048 ac = ACCOUNT_SIDS[j].account;
2049 dm = ACCOUNT_SIDS[j].domain;
2050 use = ACCOUNT_SIDS[j].name_use;
2053 break;
2057 if (dm == NULL) {
2058 MAX_SID local;
2060 /* check for the local computer next */
2061 if (ADVAPI_GetComputerSid(&local)) {
2062 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2063 BOOL result;
2065 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2066 result = GetComputerNameW(computer_name, &size);
2068 if (result) {
2069 if (EqualSid(sid, &local)) {
2070 dm = computer_name;
2071 ac = Blank;
2072 use = 3;
2073 } else {
2074 local.SubAuthorityCount++;
2076 if (EqualPrefixSid(sid, &local)) {
2077 dm = computer_name;
2078 use = 1;
2079 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2080 case DOMAIN_USER_RID_ADMIN:
2081 ac = Administrator;
2082 break;
2083 case DOMAIN_USER_RID_GUEST:
2084 ac = Guest;
2085 break;
2086 case DOMAIN_GROUP_RID_ADMINS:
2087 ac = Domain_Admins;
2088 break;
2089 case DOMAIN_GROUP_RID_USERS:
2090 ac = Domain_Users;
2091 break;
2092 case DOMAIN_GROUP_RID_GUESTS:
2093 ac = Domain_Guests;
2094 break;
2095 case DOMAIN_GROUP_RID_COMPUTERS:
2096 ac = Domain_Computers;
2097 break;
2098 case DOMAIN_GROUP_RID_CONTROLLERS:
2099 ac = Domain_Controllers;
2100 break;
2101 case DOMAIN_GROUP_RID_CERT_ADMINS:
2102 ac = Cert_Publishers;
2103 break;
2104 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2105 ac = Schema_Admins;
2106 break;
2107 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2108 ac = Enterprise_Admins;
2109 break;
2110 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2111 ac = Group_Policy_Creator_Owners;
2112 break;
2113 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2114 ac = RAS_and_IAS_Servers;
2115 break;
2116 case 1000: /* first user account */
2117 size = UNLEN + 1;
2118 account_name = HeapAlloc(
2119 GetProcessHeap(), 0, size * sizeof(WCHAR));
2120 if (GetUserNameW(account_name, &size))
2121 ac = account_name;
2122 else
2123 dm = NULL;
2125 break;
2126 default:
2127 dm = NULL;
2128 break;
2136 if (dm) {
2137 DWORD ac_len = lstrlenW(ac);
2138 DWORD dm_len = lstrlenW(dm);
2139 BOOL status = TRUE;
2141 if (*accountSize > ac_len) {
2142 if (account)
2143 lstrcpyW(account, ac);
2145 if (*domainSize > dm_len) {
2146 if (domain)
2147 lstrcpyW(domain, dm);
2149 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2150 ((*domainSize != 0) && (*domainSize < dm_len))) {
2151 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2152 status = FALSE;
2154 if (*domainSize)
2155 *domainSize = dm_len;
2156 else
2157 *domainSize = dm_len + 1;
2158 if (*accountSize)
2159 *accountSize = ac_len;
2160 else
2161 *accountSize = ac_len + 1;
2162 *name_use = use;
2163 HeapFree(GetProcessHeap(), 0, account_name);
2164 HeapFree(GetProcessHeap(), 0, computer_name);
2165 return status;
2168 HeapFree(GetProcessHeap(), 0, account_name);
2169 HeapFree(GetProcessHeap(), 0, computer_name);
2170 SetLastError(ERROR_NONE_MAPPED);
2171 return FALSE;
2174 /******************************************************************************
2175 * SetFileSecurityA [ADVAPI32.@]
2177 * See SetFileSecurityW.
2179 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2180 SECURITY_INFORMATION RequestedInformation,
2181 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2183 DWORD len;
2184 BOOL r;
2185 LPWSTR name = NULL;
2187 if( lpFileName )
2189 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2190 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2191 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2194 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2195 HeapFree( GetProcessHeap(), 0, name );
2197 return r;
2200 /******************************************************************************
2201 * SetFileSecurityW [ADVAPI32.@]
2203 * Sets the security of a file or directory.
2205 * PARAMS
2206 * lpFileName []
2207 * RequestedInformation []
2208 * pSecurityDescriptor []
2210 * RETURNS
2211 * Success: TRUE.
2212 * Failure: FALSE.
2214 BOOL WINAPI
2215 SetFileSecurityW( LPCWSTR lpFileName,
2216 SECURITY_INFORMATION RequestedInformation,
2217 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2219 HANDLE file;
2220 DWORD access = 0;
2221 NTSTATUS status;
2223 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2224 pSecurityDescriptor );
2226 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2227 RequestedInformation & GROUP_SECURITY_INFORMATION)
2228 access |= WRITE_OWNER;
2229 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2230 access |= ACCESS_SYSTEM_SECURITY;
2231 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2232 access |= WRITE_DAC;
2234 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2235 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2236 if (file == INVALID_HANDLE_VALUE)
2237 return FALSE;
2239 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2240 CloseHandle( file );
2241 return set_ntstatus( status );
2244 /******************************************************************************
2245 * QueryWindows31FilesMigration [ADVAPI32.@]
2247 * PARAMS
2248 * x1 []
2250 BOOL WINAPI
2251 QueryWindows31FilesMigration( DWORD x1 )
2253 FIXME("(%d):stub\n",x1);
2254 return TRUE;
2257 /******************************************************************************
2258 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2260 * PARAMS
2261 * x1 []
2262 * x2 []
2263 * x3 []
2264 * x4 []
2266 BOOL WINAPI
2267 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2268 DWORD x4 )
2270 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2271 return TRUE;
2274 /******************************************************************************
2275 * NotifyBootConfigStatus [ADVAPI32.@]
2277 * PARAMS
2278 * x1 []
2280 BOOL WINAPI
2281 NotifyBootConfigStatus( BOOL x1 )
2283 FIXME("(0x%08d):stub\n",x1);
2284 return 1;
2287 /******************************************************************************
2288 * RevertToSelf [ADVAPI32.@]
2290 * Ends the impersonation of a user.
2292 * PARAMS
2293 * void []
2295 * RETURNS
2296 * Success: TRUE.
2297 * Failure: FALSE.
2299 BOOL WINAPI
2300 RevertToSelf( void )
2302 HANDLE Token = NULL;
2303 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2304 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2307 /******************************************************************************
2308 * ImpersonateSelf [ADVAPI32.@]
2310 * Makes an impersonation token that represents the process user and assigns
2311 * to the current thread.
2313 * PARAMS
2314 * ImpersonationLevel [I] Level at which to impersonate.
2316 * RETURNS
2317 * Success: TRUE.
2318 * Failure: FALSE.
2320 BOOL WINAPI
2321 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2323 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2326 /******************************************************************************
2327 * ImpersonateLoggedOnUser [ADVAPI32.@]
2329 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2331 DWORD size;
2332 NTSTATUS Status;
2333 HANDLE ImpersonationToken;
2334 TOKEN_TYPE Type;
2335 static BOOL warn = TRUE;
2337 if (warn)
2339 FIXME( "(%p)\n", hToken );
2340 warn = FALSE;
2342 if (!GetTokenInformation( hToken, TokenType, &Type,
2343 sizeof(TOKEN_TYPE), &size ))
2344 return FALSE;
2346 if (Type == TokenPrimary)
2348 OBJECT_ATTRIBUTES ObjectAttributes;
2350 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2352 Status = NtDuplicateToken( hToken,
2353 TOKEN_IMPERSONATE | TOKEN_QUERY,
2354 &ObjectAttributes,
2355 SecurityImpersonation,
2356 TokenImpersonation,
2357 &ImpersonationToken );
2358 if (Status != STATUS_SUCCESS)
2360 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2361 SetLastError( RtlNtStatusToDosError( Status ) );
2362 return FALSE;
2365 else
2366 ImpersonationToken = hToken;
2368 Status = NtSetInformationThread( GetCurrentThread(),
2369 ThreadImpersonationToken,
2370 &ImpersonationToken,
2371 sizeof(ImpersonationToken) );
2373 if (Type == TokenPrimary)
2374 NtClose( ImpersonationToken );
2376 if (Status != STATUS_SUCCESS)
2378 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2379 SetLastError( RtlNtStatusToDosError( Status ) );
2380 return FALSE;
2383 return TRUE;
2386 /******************************************************************************
2387 * AccessCheck [ADVAPI32.@]
2389 BOOL WINAPI
2390 AccessCheck(
2391 PSECURITY_DESCRIPTOR SecurityDescriptor,
2392 HANDLE ClientToken,
2393 DWORD DesiredAccess,
2394 PGENERIC_MAPPING GenericMapping,
2395 PPRIVILEGE_SET PrivilegeSet,
2396 LPDWORD PrivilegeSetLength,
2397 LPDWORD GrantedAccess,
2398 LPBOOL AccessStatus)
2400 NTSTATUS access_status;
2401 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2402 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2403 GrantedAccess, &access_status) );
2404 if (ret) *AccessStatus = set_ntstatus( access_status );
2405 return ret;
2409 /******************************************************************************
2410 * AccessCheckByType [ADVAPI32.@]
2412 BOOL WINAPI AccessCheckByType(
2413 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2414 PSID PrincipalSelfSid,
2415 HANDLE ClientToken,
2416 DWORD DesiredAccess,
2417 POBJECT_TYPE_LIST ObjectTypeList,
2418 DWORD ObjectTypeListLength,
2419 PGENERIC_MAPPING GenericMapping,
2420 PPRIVILEGE_SET PrivilegeSet,
2421 LPDWORD PrivilegeSetLength,
2422 LPDWORD GrantedAccess,
2423 LPBOOL AccessStatus)
2425 FIXME("stub\n");
2427 *AccessStatus = TRUE;
2429 return !*AccessStatus;
2432 /******************************************************************************
2433 * MapGenericMask [ADVAPI32.@]
2435 * Maps generic access rights into specific access rights according to the
2436 * supplied mapping.
2438 * PARAMS
2439 * AccessMask [I/O] Access rights.
2440 * GenericMapping [I] The mapping between generic and specific rights.
2442 * RETURNS
2443 * Nothing.
2445 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2447 RtlMapGenericMask( AccessMask, GenericMapping );
2450 /*************************************************************************
2451 * SetKernelObjectSecurity [ADVAPI32.@]
2453 BOOL WINAPI SetKernelObjectSecurity (
2454 IN HANDLE Handle,
2455 IN SECURITY_INFORMATION SecurityInformation,
2456 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2458 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2462 /******************************************************************************
2463 * AddAuditAccessAce [ADVAPI32.@]
2465 BOOL WINAPI AddAuditAccessAce(
2466 IN OUT PACL pAcl,
2467 IN DWORD dwAceRevision,
2468 IN DWORD dwAccessMask,
2469 IN PSID pSid,
2470 IN BOOL bAuditSuccess,
2471 IN BOOL bAuditFailure)
2473 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2474 bAuditSuccess, bAuditFailure) );
2477 /******************************************************************************
2478 * AddAuditAccessAce [ADVAPI32.@]
2480 BOOL WINAPI AddAuditAccessAceEx(
2481 IN OUT PACL pAcl,
2482 IN DWORD dwAceRevision,
2483 IN DWORD dwAceFlags,
2484 IN DWORD dwAccessMask,
2485 IN PSID pSid,
2486 IN BOOL bAuditSuccess,
2487 IN BOOL bAuditFailure)
2489 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2490 bAuditSuccess, bAuditFailure) );
2493 /******************************************************************************
2494 * LookupAccountNameA [ADVAPI32.@]
2496 BOOL WINAPI
2497 LookupAccountNameA(
2498 IN LPCSTR system,
2499 IN LPCSTR account,
2500 OUT PSID sid,
2501 OUT LPDWORD cbSid,
2502 LPSTR ReferencedDomainName,
2503 IN OUT LPDWORD cbReferencedDomainName,
2504 OUT PSID_NAME_USE name_use )
2506 BOOL ret;
2507 UNICODE_STRING lpSystemW;
2508 UNICODE_STRING lpAccountW;
2509 LPWSTR lpReferencedDomainNameW = NULL;
2511 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2512 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2514 if (ReferencedDomainName)
2515 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2517 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2518 cbReferencedDomainName, name_use);
2520 if (ret && lpReferencedDomainNameW)
2522 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2523 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2526 RtlFreeUnicodeString(&lpSystemW);
2527 RtlFreeUnicodeString(&lpAccountW);
2528 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2530 return ret;
2533 /******************************************************************************
2534 * lookup_user_account_name
2536 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2537 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2539 /* Default implementation: Always return a default SID */
2540 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2541 BOOL ret;
2542 PSID pSid;
2543 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2544 DWORD nameLen;
2545 LPCWSTR domainName;
2547 ret = AllocateAndInitializeSid(&identifierAuthority,
2549 SECURITY_BUILTIN_DOMAIN_RID,
2550 DOMAIN_ALIAS_RID_ADMINS,
2551 0, 0, 0, 0, 0, 0,
2552 &pSid);
2554 if (!ret)
2555 return FALSE;
2557 if (!RtlValidSid(pSid))
2559 FreeSid(pSid);
2560 return FALSE;
2563 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2564 CopySid(*cbSid, Sid, pSid);
2565 if (*cbSid < GetLengthSid(pSid))
2567 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2568 ret = FALSE;
2570 *cbSid = GetLengthSid(pSid);
2572 domainName = dm;
2573 nameLen = strlenW(domainName);
2575 if (*cchReferencedDomainName <= nameLen || !ret)
2577 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2578 nameLen += 1;
2579 ret = FALSE;
2581 else if (ReferencedDomainName)
2582 strcpyW(ReferencedDomainName, domainName);
2584 *cchReferencedDomainName = nameLen;
2586 if (ret)
2587 *peUse = SidTypeUser;
2589 FreeSid(pSid);
2591 return ret;
2594 /******************************************************************************
2595 * lookup_computer_account_name
2597 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2598 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2600 MAX_SID local;
2601 BOOL ret;
2602 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2603 DWORD nameLen;
2604 LPCWSTR domainName;
2606 if ((ret = ADVAPI_GetComputerSid(&local)))
2608 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2609 CopySid(*cbSid, Sid, &local);
2610 if (*cbSid < GetLengthSid(&local))
2612 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2613 ret = FALSE;
2615 *cbSid = GetLengthSid(&local);
2618 domainName = dm;
2619 nameLen = strlenW(domainName);
2621 if (*cchReferencedDomainName <= nameLen || !ret)
2623 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2624 nameLen += 1;
2625 ret = FALSE;
2627 else if (ReferencedDomainName)
2628 strcpyW(ReferencedDomainName, domainName);
2630 *cchReferencedDomainName = nameLen;
2632 if (ret)
2633 *peUse = SidTypeDomain;
2635 return ret;
2638 /******************************************************************************
2639 * LookupAccountNameW [ADVAPI32.@]
2641 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2642 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2643 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2645 BOOL ret;
2646 PSID pSid;
2647 unsigned int i;
2648 DWORD nameLen;
2649 LPWSTR userName = NULL;
2650 LPCWSTR domainName;
2652 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2653 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2655 if (!ADVAPI_IsLocalComputer(lpSystemName))
2657 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2658 return FALSE;
2661 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2663 lpAccountName = BUILTIN;
2666 /* Check well known SIDs first */
2668 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2670 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2672 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2674 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2676 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2678 if (ret)
2680 if (*cbSid < sidLen)
2682 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2683 ret = FALSE;
2685 else if (Sid)
2687 CopySid(*cbSid, Sid, pSid);
2690 *cbSid = sidLen;
2693 domainName = ACCOUNT_SIDS[i].domain;
2694 nameLen = strlenW(domainName);
2696 if (*cchReferencedDomainName <= nameLen || !ret)
2698 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2699 nameLen += 1;
2700 ret = FALSE;
2702 else if (ReferencedDomainName)
2704 strcpyW(ReferencedDomainName, domainName);
2707 *cchReferencedDomainName = nameLen;
2709 if (ret)
2711 *peUse = ACCOUNT_SIDS[i].name_use;
2714 HeapFree(GetProcessHeap(), 0, pSid);
2716 return ret;
2720 /* Let the current Unix user id masquerade as first Windows user account */
2722 nameLen = UNLEN + 1;
2724 userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2726 if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2727 ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2728 cchReferencedDomainName, peUse);
2729 else
2731 nameLen = UNLEN + 1;
2732 if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2733 ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2734 cchReferencedDomainName, peUse);
2735 else
2737 SetLastError(ERROR_NONE_MAPPED);
2738 ret = FALSE;
2742 HeapFree(GetProcessHeap(), 0, userName);
2744 return ret;
2747 /******************************************************************************
2748 * PrivilegeCheck [ADVAPI32.@]
2750 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2752 BOOL ret;
2753 BOOLEAN Result;
2755 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2757 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2758 if (ret)
2759 *pfResult = Result;
2760 return ret;
2763 /******************************************************************************
2764 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2766 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2767 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2768 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2769 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2771 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2772 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2773 SecurityDescriptor, DesiredAccess, GenericMapping,
2774 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2775 return TRUE;
2778 /******************************************************************************
2779 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2781 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2782 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2783 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2784 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2786 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2787 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2788 SecurityDescriptor, DesiredAccess, GenericMapping,
2789 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2790 return TRUE;
2793 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2795 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2797 return TRUE;
2800 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2802 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2804 return TRUE;
2807 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2809 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2811 return TRUE;
2814 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2815 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2816 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2817 LPBOOL GenerateOnClose)
2819 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2820 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2821 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2822 GenerateOnClose);
2824 return TRUE;
2827 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2828 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2829 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2830 LPBOOL GenerateOnClose)
2832 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2833 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2834 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2835 GenerateOnClose);
2837 return TRUE;
2840 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2841 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2843 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2844 DesiredAccess, Privileges, AccessGranted);
2846 return TRUE;
2849 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2850 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2852 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2853 DesiredAccess, Privileges, AccessGranted);
2855 return TRUE;
2858 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2859 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2861 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2862 ClientToken, Privileges, AccessGranted);
2864 return TRUE;
2867 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2868 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2870 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2871 ClientToken, Privileges, AccessGranted);
2873 return TRUE;
2876 /******************************************************************************
2877 * GetSecurityInfo [ADVAPI32.@]
2879 * Retrieves a copy of the security descriptor associated with an object.
2881 * PARAMS
2882 * hObject [I] A handle for the object.
2883 * ObjectType [I] The type of object.
2884 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2885 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2886 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2887 * ppDacl [O] If non-null, receives a pointer to the DACL.
2888 * ppSacl [O] If non-null, receives a pointer to the SACL.
2889 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2890 * which must be freed with LocalFree.
2892 * RETURNS
2893 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2895 DWORD WINAPI GetSecurityInfo(
2896 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2897 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2898 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2899 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2902 PSECURITY_DESCRIPTOR sd;
2903 NTSTATUS status;
2904 ULONG n1, n2;
2905 BOOL present, defaulted;
2907 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2908 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2909 return RtlNtStatusToDosError(status);
2911 sd = LocalAlloc(0, n1);
2912 if (!sd)
2913 return ERROR_NOT_ENOUGH_MEMORY;
2915 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2916 if (status != STATUS_SUCCESS)
2918 LocalFree(sd);
2919 return RtlNtStatusToDosError(status);
2922 if (ppsidOwner)
2924 *ppsidOwner = NULL;
2925 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2927 if (ppsidGroup)
2929 *ppsidGroup = NULL;
2930 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2932 if (ppDacl)
2934 *ppDacl = NULL;
2935 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2937 if (ppSacl)
2939 *ppSacl = NULL;
2940 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2942 if (ppSecurityDescriptor)
2943 *ppSecurityDescriptor = sd;
2945 return ERROR_SUCCESS;
2948 /******************************************************************************
2949 * GetSecurityInfoExA [ADVAPI32.@]
2951 DWORD WINAPI GetSecurityInfoExA(
2952 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2953 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
2954 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
2955 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
2958 FIXME("stub!\n");
2959 return ERROR_BAD_PROVIDER;
2962 /******************************************************************************
2963 * GetSecurityInfoExW [ADVAPI32.@]
2965 DWORD WINAPI GetSecurityInfoExW(
2966 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2967 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2968 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2969 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2972 FIXME("stub!\n");
2973 return ERROR_BAD_PROVIDER;
2976 /******************************************************************************
2977 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2979 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2980 LPSTR pTrusteeName, DWORD AccessPermissions,
2981 ACCESS_MODE AccessMode, DWORD Inheritance )
2983 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2984 AccessPermissions, AccessMode, Inheritance);
2986 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2987 pExplicitAccess->grfAccessMode = AccessMode;
2988 pExplicitAccess->grfInheritance = Inheritance;
2990 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2991 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2992 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2993 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2994 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2997 /******************************************************************************
2998 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3000 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3001 LPWSTR pTrusteeName, DWORD AccessPermissions,
3002 ACCESS_MODE AccessMode, DWORD Inheritance )
3004 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3005 AccessPermissions, AccessMode, Inheritance);
3007 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3008 pExplicitAccess->grfAccessMode = AccessMode;
3009 pExplicitAccess->grfInheritance = Inheritance;
3011 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3012 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3013 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3014 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3015 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3018 /******************************************************************************
3019 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3021 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3022 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3023 LPSTR InheritedObjectTypeName, LPSTR Name )
3025 DWORD ObjectsPresent = 0;
3027 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3028 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3030 /* Fill the OBJECTS_AND_NAME structure */
3031 pObjName->ObjectType = ObjectType;
3032 if (ObjectTypeName != NULL)
3034 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3037 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3038 if (InheritedObjectTypeName != NULL)
3040 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3043 pObjName->ObjectsPresent = ObjectsPresent;
3044 pObjName->ptstrName = Name;
3046 /* Fill the TRUSTEE structure */
3047 pTrustee->pMultipleTrustee = NULL;
3048 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3049 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3050 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3051 pTrustee->ptstrName = (LPSTR)pObjName;
3054 /******************************************************************************
3055 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3057 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3058 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3059 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3061 DWORD ObjectsPresent = 0;
3063 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3064 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3066 /* Fill the OBJECTS_AND_NAME structure */
3067 pObjName->ObjectType = ObjectType;
3068 if (ObjectTypeName != NULL)
3070 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3073 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3074 if (InheritedObjectTypeName != NULL)
3076 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3079 pObjName->ObjectsPresent = ObjectsPresent;
3080 pObjName->ptstrName = Name;
3082 /* Fill the TRUSTEE structure */
3083 pTrustee->pMultipleTrustee = NULL;
3084 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3085 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3086 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3087 pTrustee->ptstrName = (LPWSTR)pObjName;
3090 /******************************************************************************
3091 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3093 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3094 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3096 DWORD ObjectsPresent = 0;
3098 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3100 /* Fill the OBJECTS_AND_SID structure */
3101 if (pObjectGuid != NULL)
3103 pObjSid->ObjectTypeGuid = *pObjectGuid;
3104 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3106 else
3108 ZeroMemory(&pObjSid->ObjectTypeGuid,
3109 sizeof(GUID));
3112 if (pInheritedObjectGuid != NULL)
3114 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3115 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3117 else
3119 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3120 sizeof(GUID));
3123 pObjSid->ObjectsPresent = ObjectsPresent;
3124 pObjSid->pSid = pSid;
3126 /* Fill the TRUSTEE structure */
3127 pTrustee->pMultipleTrustee = NULL;
3128 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3129 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3130 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3131 pTrustee->ptstrName = (LPSTR) pObjSid;
3134 /******************************************************************************
3135 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3137 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3138 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3140 DWORD ObjectsPresent = 0;
3142 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3144 /* Fill the OBJECTS_AND_SID structure */
3145 if (pObjectGuid != NULL)
3147 pObjSid->ObjectTypeGuid = *pObjectGuid;
3148 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3150 else
3152 ZeroMemory(&pObjSid->ObjectTypeGuid,
3153 sizeof(GUID));
3156 if (pInheritedObjectGuid != NULL)
3158 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3159 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3161 else
3163 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3164 sizeof(GUID));
3167 pObjSid->ObjectsPresent = ObjectsPresent;
3168 pObjSid->pSid = pSid;
3170 /* Fill the TRUSTEE structure */
3171 pTrustee->pMultipleTrustee = NULL;
3172 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3173 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3174 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3175 pTrustee->ptstrName = (LPWSTR) pObjSid;
3178 /******************************************************************************
3179 * BuildTrusteeWithSidA [ADVAPI32.@]
3181 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3183 TRACE("%p %p\n", pTrustee, pSid);
3185 pTrustee->pMultipleTrustee = NULL;
3186 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3187 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3188 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3189 pTrustee->ptstrName = pSid;
3192 /******************************************************************************
3193 * BuildTrusteeWithSidW [ADVAPI32.@]
3195 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3197 TRACE("%p %p\n", pTrustee, pSid);
3199 pTrustee->pMultipleTrustee = NULL;
3200 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3201 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3202 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3203 pTrustee->ptstrName = pSid;
3206 /******************************************************************************
3207 * BuildTrusteeWithNameA [ADVAPI32.@]
3209 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3211 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3213 pTrustee->pMultipleTrustee = NULL;
3214 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3215 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3216 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3217 pTrustee->ptstrName = name;
3220 /******************************************************************************
3221 * BuildTrusteeWithNameW [ADVAPI32.@]
3223 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3225 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3227 pTrustee->pMultipleTrustee = NULL;
3228 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3229 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3230 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3231 pTrustee->ptstrName = name;
3234 /******************************************************************************
3235 * GetTrusteeFormA [ADVAPI32.@]
3237 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3239 TRACE("(%p)\n", pTrustee);
3241 if (!pTrustee)
3242 return TRUSTEE_BAD_FORM;
3244 return pTrustee->TrusteeForm;
3247 /******************************************************************************
3248 * GetTrusteeFormW [ADVAPI32.@]
3250 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3252 TRACE("(%p)\n", pTrustee);
3254 if (!pTrustee)
3255 return TRUSTEE_BAD_FORM;
3257 return pTrustee->TrusteeForm;
3260 /******************************************************************************
3261 * GetTrusteeNameA [ADVAPI32.@]
3263 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3265 TRACE("(%p)\n", pTrustee);
3267 if (!pTrustee)
3268 return NULL;
3270 return pTrustee->ptstrName;
3273 /******************************************************************************
3274 * GetTrusteeNameW [ADVAPI32.@]
3276 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3278 TRACE("(%p)\n", pTrustee);
3280 if (!pTrustee)
3281 return NULL;
3283 return pTrustee->ptstrName;
3286 /******************************************************************************
3287 * GetTrusteeTypeA [ADVAPI32.@]
3289 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3291 TRACE("(%p)\n", pTrustee);
3293 if (!pTrustee)
3294 return TRUSTEE_IS_UNKNOWN;
3296 return pTrustee->TrusteeType;
3299 /******************************************************************************
3300 * GetTrusteeTypeW [ADVAPI32.@]
3302 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3304 TRACE("(%p)\n", pTrustee);
3306 if (!pTrustee)
3307 return TRUSTEE_IS_UNKNOWN;
3309 return pTrustee->TrusteeType;
3312 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3313 DWORD nAclInformationLength,
3314 ACL_INFORMATION_CLASS dwAclInformationClass )
3316 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3317 nAclInformationLength, dwAclInformationClass);
3319 return TRUE;
3322 /******************************************************************************
3323 * SetEntriesInAclA [ADVAPI32.@]
3325 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3326 PACL OldAcl, PACL* NewAcl )
3328 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3329 if (NewAcl)
3330 *NewAcl = NULL;
3331 return ERROR_SUCCESS;
3334 /******************************************************************************
3335 * SetEntriesInAclW [ADVAPI32.@]
3337 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3338 PACL OldAcl, PACL* NewAcl )
3340 ULONG i;
3341 PSID *ppsid;
3342 DWORD ret = ERROR_SUCCESS;
3343 DWORD acl_size = sizeof(ACL);
3344 NTSTATUS status;
3346 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3348 *NewAcl = NULL;
3350 if (!count && !OldAcl)
3351 return ERROR_SUCCESS;
3353 /* allocate array of maximum sized sids allowed */
3354 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3355 if (!ppsid)
3356 return ERROR_OUTOFMEMORY;
3358 for (i = 0; i < count; i++)
3360 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3362 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3363 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3364 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3365 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3366 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3367 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3368 pEntries[i].Trustee.ptstrName);
3370 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3372 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3373 ret = ERROR_INVALID_PARAMETER;
3374 goto exit;
3377 switch (pEntries[i].Trustee.TrusteeForm)
3379 case TRUSTEE_IS_SID:
3380 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3381 ppsid[i], pEntries[i].Trustee.ptstrName))
3383 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3384 ret = ERROR_INVALID_PARAMETER;
3385 goto exit;
3387 break;
3388 case TRUSTEE_IS_NAME:
3390 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3391 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3392 SID_NAME_USE use;
3393 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3395 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3396 ret = ERROR_INVALID_PARAMETER;
3397 goto exit;
3399 break;
3401 case TRUSTEE_IS_OBJECTS_AND_SID:
3402 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3403 break;
3404 case TRUSTEE_IS_OBJECTS_AND_NAME:
3405 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3406 break;
3407 default:
3408 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3409 ret = ERROR_INVALID_PARAMETER;
3410 goto exit;
3413 /* Note: we overestimate the ACL size here as a tradeoff between
3414 * instructions (simplicity) and memory */
3415 switch (pEntries[i].grfAccessMode)
3417 case GRANT_ACCESS:
3418 case SET_ACCESS:
3419 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3420 break;
3421 case DENY_ACCESS:
3422 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3423 break;
3424 case SET_AUDIT_SUCCESS:
3425 case SET_AUDIT_FAILURE:
3426 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3427 break;
3428 case REVOKE_ACCESS:
3429 break;
3430 default:
3431 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3432 ret = ERROR_INVALID_PARAMETER;
3433 goto exit;
3437 if (OldAcl)
3439 ACL_SIZE_INFORMATION size_info;
3441 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3442 if (status != STATUS_SUCCESS)
3444 ret = RtlNtStatusToDosError(status);
3445 goto exit;
3447 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3450 *NewAcl = LocalAlloc(0, acl_size);
3451 if (!*NewAcl)
3453 ret = ERROR_OUTOFMEMORY;
3454 goto exit;
3457 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3458 if (status != STATUS_SUCCESS)
3460 ret = RtlNtStatusToDosError(status);
3461 goto exit;
3464 for (i = 0; i < count; i++)
3466 switch (pEntries[i].grfAccessMode)
3468 case GRANT_ACCESS:
3469 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3470 pEntries[i].grfInheritance,
3471 pEntries[i].grfAccessPermissions,
3472 ppsid[i]);
3473 break;
3474 case SET_ACCESS:
3476 ULONG j;
3477 BOOL add = TRUE;
3478 if (OldAcl)
3480 for (j = 0; ; j++)
3482 const ACE_HEADER *existing_ace_header;
3483 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3484 if (status != STATUS_SUCCESS)
3485 break;
3486 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3487 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3488 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3490 add = FALSE;
3491 break;
3495 if (add)
3496 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3497 pEntries[i].grfInheritance,
3498 pEntries[i].grfAccessPermissions,
3499 ppsid[i]);
3500 break;
3502 case DENY_ACCESS:
3503 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3504 pEntries[i].grfInheritance,
3505 pEntries[i].grfAccessPermissions,
3506 ppsid[i]);
3507 break;
3508 case SET_AUDIT_SUCCESS:
3509 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3510 pEntries[i].grfInheritance,
3511 pEntries[i].grfAccessPermissions,
3512 ppsid[i], TRUE, FALSE);
3513 break;
3514 case SET_AUDIT_FAILURE:
3515 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3516 pEntries[i].grfInheritance,
3517 pEntries[i].grfAccessPermissions,
3518 ppsid[i], FALSE, TRUE);
3519 break;
3520 default:
3521 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3525 if (OldAcl)
3527 for (i = 0; ; i++)
3529 BOOL add = TRUE;
3530 ULONG j;
3531 const ACE_HEADER *old_ace_header;
3532 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3533 if (status != STATUS_SUCCESS) break;
3534 for (j = 0; j < count; j++)
3536 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3537 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3538 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3540 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3541 add = FALSE;
3542 break;
3544 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3546 switch (old_ace_header->AceType)
3548 case ACCESS_ALLOWED_ACE_TYPE:
3549 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3550 add = FALSE;
3551 break;
3552 case ACCESS_DENIED_ACE_TYPE:
3553 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3554 add = FALSE;
3555 break;
3556 case SYSTEM_AUDIT_ACE_TYPE:
3557 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3558 add = FALSE;
3559 break;
3560 case SYSTEM_ALARM_ACE_TYPE:
3561 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3562 add = FALSE;
3563 break;
3564 default:
3565 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3568 if (!add)
3569 break;
3572 if (add)
3573 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3574 if (status != STATUS_SUCCESS)
3576 WARN("RtlAddAce failed with error 0x%08x\n", status);
3577 ret = RtlNtStatusToDosError(status);
3578 break;
3583 exit:
3584 HeapFree(GetProcessHeap(), 0, ppsid);
3585 return ret;
3588 /******************************************************************************
3589 * SetNamedSecurityInfoA [ADVAPI32.@]
3591 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3592 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3593 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3595 DWORD len;
3596 LPWSTR wstr = NULL;
3597 DWORD r;
3599 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3600 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3602 if( pObjectName )
3604 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3605 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3606 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3609 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3610 psidGroup, pDacl, pSacl );
3612 HeapFree( GetProcessHeap(), 0, wstr );
3614 return r;
3617 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3618 PSECURITY_DESCRIPTOR ModificationDescriptor,
3619 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3620 PGENERIC_MAPPING GenericMapping,
3621 HANDLE Token )
3623 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3624 ObjectsSecurityDescriptor, GenericMapping, Token);
3626 return TRUE;
3629 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3631 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3634 /******************************************************************************
3635 * AreAnyAccessesGranted [ADVAPI32.@]
3637 * Determines whether or not any of a set of specified access permissions have
3638 * been granted or not.
3640 * PARAMS
3641 * GrantedAccess [I] The permissions that have been granted.
3642 * DesiredAccess [I] The permissions that you want to have.
3644 * RETURNS
3645 * Nonzero if any of the permissions have been granted, zero if none of the
3646 * permissions have been granted.
3649 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3651 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3654 /******************************************************************************
3655 * SetNamedSecurityInfoW [ADVAPI32.@]
3657 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3658 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3659 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3661 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3662 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3663 return ERROR_SUCCESS;
3666 /******************************************************************************
3667 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3669 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3670 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3672 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3673 return ERROR_CALL_NOT_IMPLEMENTED;
3676 /******************************************************************************
3677 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3679 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3680 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3682 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3683 return ERROR_CALL_NOT_IMPLEMENTED;
3686 /******************************************************************************
3687 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3689 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3690 PACCESS_MASK pFailedAuditRights)
3692 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3693 return ERROR_CALL_NOT_IMPLEMENTED;
3697 /******************************************************************************
3698 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3700 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3701 PACCESS_MASK pFailedAuditRights)
3703 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3704 return ERROR_CALL_NOT_IMPLEMENTED;
3708 /******************************************************************************
3709 * ParseAclStringFlags
3711 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3713 DWORD flags = 0;
3714 LPCWSTR szAcl = *StringAcl;
3716 while (*szAcl != '(')
3718 if (*szAcl == 'P')
3720 flags |= SE_DACL_PROTECTED;
3722 else if (*szAcl == 'A')
3724 szAcl++;
3725 if (*szAcl == 'R')
3726 flags |= SE_DACL_AUTO_INHERIT_REQ;
3727 else if (*szAcl == 'I')
3728 flags |= SE_DACL_AUTO_INHERITED;
3730 szAcl++;
3733 *StringAcl = szAcl;
3734 return flags;
3737 /******************************************************************************
3738 * ParseAceStringType
3740 static const ACEFLAG AceType[] =
3742 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3743 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3744 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3745 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3747 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3748 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3749 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3750 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3752 { NULL, 0 },
3755 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3757 UINT len = 0;
3758 LPCWSTR szAcl = *StringAcl;
3759 const ACEFLAG *lpaf = AceType;
3761 while (lpaf->wstr &&
3762 (len = strlenW(lpaf->wstr)) &&
3763 strncmpW(lpaf->wstr, szAcl, len))
3764 lpaf++;
3766 if (!lpaf->wstr)
3767 return 0;
3769 *StringAcl += len;
3770 return lpaf->value;
3774 /******************************************************************************
3775 * ParseAceStringFlags
3777 static const ACEFLAG AceFlags[] =
3779 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3780 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3781 { SDDL_INHERITED, INHERITED_ACE },
3782 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3783 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3784 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3785 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3786 { NULL, 0 },
3789 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3791 UINT len = 0;
3792 BYTE flags = 0;
3793 LPCWSTR szAcl = *StringAcl;
3795 while (*szAcl != ';')
3797 const ACEFLAG *lpaf = AceFlags;
3799 while (lpaf->wstr &&
3800 (len = strlenW(lpaf->wstr)) &&
3801 strncmpW(lpaf->wstr, szAcl, len))
3802 lpaf++;
3804 if (!lpaf->wstr)
3805 return 0;
3807 flags |= lpaf->value;
3808 szAcl += len;
3811 *StringAcl = szAcl;
3812 return flags;
3816 /******************************************************************************
3817 * ParseAceStringRights
3819 static const ACEFLAG AceRights[] =
3821 { SDDL_GENERIC_ALL, GENERIC_ALL },
3822 { SDDL_GENERIC_READ, GENERIC_READ },
3823 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3824 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3826 { SDDL_READ_CONTROL, READ_CONTROL },
3827 { SDDL_STANDARD_DELETE, DELETE },
3828 { SDDL_WRITE_DAC, WRITE_DAC },
3829 { SDDL_WRITE_OWNER, WRITE_OWNER },
3831 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3832 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3833 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3834 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3835 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3836 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3837 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3838 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3839 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3841 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3842 { SDDL_FILE_READ, FILE_GENERIC_READ },
3843 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3844 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3846 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3847 { SDDL_KEY_READ, KEY_READ },
3848 { SDDL_KEY_WRITE, KEY_WRITE },
3849 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3850 { NULL, 0 },
3853 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3855 UINT len = 0;
3856 DWORD rights = 0;
3857 LPCWSTR szAcl = *StringAcl;
3859 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3861 LPCWSTR p = szAcl;
3863 while (*p && *p != ';')
3864 p++;
3866 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3868 rights = strtoulW(szAcl, NULL, 16);
3869 szAcl = p;
3871 else
3872 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3874 else
3876 while (*szAcl != ';')
3878 const ACEFLAG *lpaf = AceRights;
3880 while (lpaf->wstr &&
3881 (len = strlenW(lpaf->wstr)) &&
3882 strncmpW(lpaf->wstr, szAcl, len))
3884 lpaf++;
3887 if (!lpaf->wstr)
3888 return 0;
3890 rights |= lpaf->value;
3891 szAcl += len;
3895 *StringAcl = szAcl;
3896 return rights;
3900 /******************************************************************************
3901 * ParseStringAclToAcl
3903 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3905 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3906 PACL pAcl, LPDWORD cBytes)
3908 DWORD val;
3909 DWORD sidlen;
3910 DWORD length = sizeof(ACL);
3911 DWORD acesize = 0;
3912 DWORD acecount = 0;
3913 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3915 TRACE("%s\n", debugstr_w(StringAcl));
3917 if (!StringAcl)
3918 return FALSE;
3920 if (pAcl) /* pAce is only useful if we're setting values */
3921 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3923 /* Parse ACL flags */
3924 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3926 /* Parse ACE */
3927 while (*StringAcl == '(')
3929 StringAcl++;
3931 /* Parse ACE type */
3932 val = ParseAceStringType(&StringAcl);
3933 if (pAce)
3934 pAce->Header.AceType = (BYTE) val;
3935 if (*StringAcl != ';')
3936 goto lerr;
3937 StringAcl++;
3939 /* Parse ACE flags */
3940 val = ParseAceStringFlags(&StringAcl);
3941 if (pAce)
3942 pAce->Header.AceFlags = (BYTE) val;
3943 if (*StringAcl != ';')
3944 goto lerr;
3945 StringAcl++;
3947 /* Parse ACE rights */
3948 val = ParseAceStringRights(&StringAcl);
3949 if (pAce)
3950 pAce->Mask = val;
3951 if (*StringAcl != ';')
3952 goto lerr;
3953 StringAcl++;
3955 /* Parse ACE object guid */
3956 if (*StringAcl != ';')
3958 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3959 goto lerr;
3961 StringAcl++;
3963 /* Parse ACE inherit object guid */
3964 if (*StringAcl != ';')
3966 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3967 goto lerr;
3969 StringAcl++;
3971 /* Parse ACE account sid */
3972 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
3974 while (*StringAcl && *StringAcl != ')')
3975 StringAcl++;
3978 if (*StringAcl != ')')
3979 goto lerr;
3980 StringAcl++;
3982 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3983 length += acesize;
3984 if (pAce)
3986 pAce->Header.AceSize = acesize;
3987 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3989 acecount++;
3992 *cBytes = length;
3994 if (length > 0xffff)
3996 ERR("ACL too large\n");
3997 goto lerr;
4000 if (pAcl)
4002 pAcl->AclRevision = ACL_REVISION;
4003 pAcl->Sbz1 = 0;
4004 pAcl->AclSize = length;
4005 pAcl->AceCount = acecount++;
4006 pAcl->Sbz2 = 0;
4008 return TRUE;
4010 lerr:
4011 SetLastError(ERROR_INVALID_ACL);
4012 WARN("Invalid ACE string format\n");
4013 return FALSE;
4017 /******************************************************************************
4018 * ParseStringSecurityDescriptorToSecurityDescriptor
4020 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4021 LPCWSTR StringSecurityDescriptor,
4022 SECURITY_DESCRIPTOR* SecurityDescriptor,
4023 LPDWORD cBytes)
4025 BOOL bret = FALSE;
4026 WCHAR toktype;
4027 WCHAR tok[MAX_PATH];
4028 LPCWSTR lptoken;
4029 LPBYTE lpNext = NULL;
4030 DWORD len;
4032 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4034 if (SecurityDescriptor)
4035 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
4037 while (*StringSecurityDescriptor)
4039 toktype = *StringSecurityDescriptor;
4041 /* Expect char identifier followed by ':' */
4042 StringSecurityDescriptor++;
4043 if (*StringSecurityDescriptor != ':')
4045 SetLastError(ERROR_INVALID_PARAMETER);
4046 goto lend;
4048 StringSecurityDescriptor++;
4050 /* Extract token */
4051 lptoken = StringSecurityDescriptor;
4052 while (*lptoken && *lptoken != ':')
4053 lptoken++;
4055 if (*lptoken)
4056 lptoken--;
4058 len = lptoken - StringSecurityDescriptor;
4059 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4060 tok[len] = 0;
4062 switch (toktype)
4064 case 'O':
4066 DWORD bytes;
4068 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4069 goto lend;
4071 if (SecurityDescriptor)
4073 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4074 lpNext += bytes; /* Advance to next token */
4077 *cBytes += bytes;
4079 break;
4082 case 'G':
4084 DWORD bytes;
4086 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4087 goto lend;
4089 if (SecurityDescriptor)
4091 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4092 lpNext += bytes; /* Advance to next token */
4095 *cBytes += bytes;
4097 break;
4100 case 'D':
4102 DWORD flags;
4103 DWORD bytes;
4105 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4106 goto lend;
4108 if (SecurityDescriptor)
4110 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4111 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4112 lpNext += bytes; /* Advance to next token */
4115 *cBytes += bytes;
4117 break;
4120 case 'S':
4122 DWORD flags;
4123 DWORD bytes;
4125 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4126 goto lend;
4128 if (SecurityDescriptor)
4130 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4131 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4132 lpNext += bytes; /* Advance to next token */
4135 *cBytes += bytes;
4137 break;
4140 default:
4141 FIXME("Unknown token\n");
4142 SetLastError(ERROR_INVALID_PARAMETER);
4143 goto lend;
4146 StringSecurityDescriptor = lptoken;
4149 bret = TRUE;
4151 lend:
4152 return bret;
4155 /******************************************************************************
4156 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4158 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4159 LPCSTR StringSecurityDescriptor,
4160 DWORD StringSDRevision,
4161 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4162 PULONG SecurityDescriptorSize)
4164 UINT len;
4165 BOOL ret = FALSE;
4166 LPWSTR StringSecurityDescriptorW;
4168 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4169 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4171 if (StringSecurityDescriptorW)
4173 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4175 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4176 StringSDRevision, SecurityDescriptor,
4177 SecurityDescriptorSize);
4178 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4181 return ret;
4184 /******************************************************************************
4185 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4187 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4188 LPCWSTR StringSecurityDescriptor,
4189 DWORD StringSDRevision,
4190 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4191 PULONG SecurityDescriptorSize)
4193 DWORD cBytes;
4194 SECURITY_DESCRIPTOR* psd;
4195 BOOL bret = FALSE;
4197 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4199 if (GetVersion() & 0x80000000)
4201 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4202 goto lend;
4204 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4206 SetLastError(ERROR_INVALID_PARAMETER);
4207 goto lend;
4209 else if (StringSDRevision != SID_REVISION)
4211 SetLastError(ERROR_UNKNOWN_REVISION);
4212 goto lend;
4215 /* Compute security descriptor length */
4216 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4217 NULL, &cBytes))
4218 goto lend;
4220 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4221 if (!psd) goto lend;
4223 psd->Revision = SID_REVISION;
4224 psd->Control |= SE_SELF_RELATIVE;
4226 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4227 psd, &cBytes))
4229 LocalFree(psd);
4230 goto lend;
4233 if (SecurityDescriptorSize)
4234 *SecurityDescriptorSize = cBytes;
4236 bret = TRUE;
4238 lend:
4239 TRACE(" ret=%d\n", bret);
4240 return bret;
4243 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4245 if (cch == -1)
4246 cch = strlenW(string);
4248 if (plen)
4249 *plen += cch;
4251 if (pwptr)
4253 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4254 *pwptr += cch;
4258 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4260 DWORD i;
4261 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4262 WCHAR subauthfmt[] = { '-','%','u',0 };
4263 WCHAR buf[26];
4264 SID *pisid = psid;
4266 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4268 SetLastError(ERROR_INVALID_SID);
4269 return FALSE;
4272 if (pisid->IdentifierAuthority.Value[0] ||
4273 pisid->IdentifierAuthority.Value[1])
4275 FIXME("not matching MS' bugs\n");
4276 SetLastError(ERROR_INVALID_SID);
4277 return FALSE;
4280 sprintfW( buf, fmt, pisid->Revision,
4281 MAKELONG(
4282 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4283 pisid->IdentifierAuthority.Value[4] ),
4284 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4285 pisid->IdentifierAuthority.Value[2] )
4286 ) );
4287 DumpString(buf, -1, pwptr, plen);
4289 for( i=0; i<pisid->SubAuthorityCount; i++ )
4291 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4292 DumpString(buf, -1, pwptr, plen);
4294 return TRUE;
4297 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4299 size_t i;
4300 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4302 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4304 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4305 return TRUE;
4309 return DumpSidNumeric(psid, pwptr, plen);
4312 static const LPCWSTR AceRightBitNames[32] = {
4313 SDDL_CREATE_CHILD, /* 0 */
4314 SDDL_DELETE_CHILD,
4315 SDDL_LIST_CHILDREN,
4316 SDDL_SELF_WRITE,
4317 SDDL_READ_PROPERTY, /* 4 */
4318 SDDL_WRITE_PROPERTY,
4319 SDDL_DELETE_TREE,
4320 SDDL_LIST_OBJECT,
4321 SDDL_CONTROL_ACCESS, /* 8 */
4322 NULL,
4323 NULL,
4324 NULL,
4325 NULL, /* 12 */
4326 NULL,
4327 NULL,
4328 NULL,
4329 SDDL_STANDARD_DELETE, /* 16 */
4330 SDDL_READ_CONTROL,
4331 SDDL_WRITE_DAC,
4332 SDDL_WRITE_OWNER,
4333 NULL, /* 20 */
4334 NULL,
4335 NULL,
4336 NULL,
4337 NULL, /* 24 */
4338 NULL,
4339 NULL,
4340 NULL,
4341 SDDL_GENERIC_ALL, /* 28 */
4342 SDDL_GENERIC_EXECUTE,
4343 SDDL_GENERIC_WRITE,
4344 SDDL_GENERIC_READ
4347 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4349 static const WCHAR fmtW[] = {'0','x','%','x',0};
4350 WCHAR buf[15];
4351 size_t i;
4353 if (mask == 0)
4354 return;
4356 /* first check if the right have name */
4357 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4359 if (AceRights[i].wstr == NULL)
4360 break;
4361 if (mask == AceRights[i].value)
4363 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4364 return;
4368 /* then check if it can be built from bit names */
4369 for (i = 0; i < 32; i++)
4371 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4373 /* can't be built from bit names */
4374 sprintfW(buf, fmtW, mask);
4375 DumpString(buf, -1, pwptr, plen);
4376 return;
4380 /* build from bit names */
4381 for (i = 0; i < 32; i++)
4382 if (mask & (1 << i))
4383 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4386 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4388 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4389 static const WCHAR openbr = '(';
4390 static const WCHAR closebr = ')';
4391 static const WCHAR semicolon = ';';
4393 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4395 SetLastError(ERROR_INVALID_ACL);
4396 return FALSE;
4399 piace = pace;
4400 DumpString(&openbr, 1, pwptr, plen);
4401 switch (piace->Header.AceType)
4403 case ACCESS_ALLOWED_ACE_TYPE:
4404 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4405 break;
4406 case ACCESS_DENIED_ACE_TYPE:
4407 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4408 break;
4409 case SYSTEM_AUDIT_ACE_TYPE:
4410 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4411 break;
4412 case SYSTEM_ALARM_ACE_TYPE:
4413 DumpString(SDDL_ALARM, -1, pwptr, plen);
4414 break;
4416 DumpString(&semicolon, 1, pwptr, plen);
4418 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4419 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4420 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4421 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4422 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4423 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4424 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4425 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4426 if (piace->Header.AceFlags & INHERITED_ACE)
4427 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4428 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4429 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4430 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4431 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4432 DumpString(&semicolon, 1, pwptr, plen);
4433 DumpRights(piace->Mask, pwptr, plen);
4434 DumpString(&semicolon, 1, pwptr, plen);
4435 /* objects not supported */
4436 DumpString(&semicolon, 1, pwptr, plen);
4437 /* objects not supported */
4438 DumpString(&semicolon, 1, pwptr, plen);
4439 if (!DumpSid(&piace->SidStart, pwptr, plen))
4440 return FALSE;
4441 DumpString(&closebr, 1, pwptr, plen);
4442 return TRUE;
4445 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4447 WORD count;
4448 int i;
4450 if (protected)
4451 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4452 if (autoInheritReq)
4453 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4454 if (autoInherited)
4455 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4457 if (pacl == NULL)
4458 return TRUE;
4460 if (!IsValidAcl(pacl))
4461 return FALSE;
4463 count = pacl->AceCount;
4464 for (i = 0; i < count; i++)
4466 LPVOID ace;
4467 if (!GetAce(pacl, i, &ace))
4468 return FALSE;
4469 if (!DumpAce(ace, pwptr, plen))
4470 return FALSE;
4473 return TRUE;
4476 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4478 static const WCHAR prefix[] = {'O',':',0};
4479 BOOL bDefaulted;
4480 PSID psid;
4482 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4483 return FALSE;
4485 if (psid == NULL)
4486 return TRUE;
4488 DumpString(prefix, -1, pwptr, plen);
4489 if (!DumpSid(psid, pwptr, plen))
4490 return FALSE;
4491 return TRUE;
4494 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4496 static const WCHAR prefix[] = {'G',':',0};
4497 BOOL bDefaulted;
4498 PSID psid;
4500 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4501 return FALSE;
4503 if (psid == NULL)
4504 return TRUE;
4506 DumpString(prefix, -1, pwptr, plen);
4507 if (!DumpSid(psid, pwptr, plen))
4508 return FALSE;
4509 return TRUE;
4512 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4514 static const WCHAR dacl[] = {'D',':',0};
4515 SECURITY_DESCRIPTOR_CONTROL control;
4516 BOOL present, defaulted;
4517 DWORD revision;
4518 PACL pacl;
4520 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4521 return FALSE;
4523 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4524 return FALSE;
4526 if (!present)
4527 return TRUE;
4529 DumpString(dacl, 2, pwptr, plen);
4530 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4531 return FALSE;
4532 return TRUE;
4535 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4537 static const WCHAR sacl[] = {'S',':',0};
4538 SECURITY_DESCRIPTOR_CONTROL control;
4539 BOOL present, defaulted;
4540 DWORD revision;
4541 PACL pacl;
4543 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4544 return FALSE;
4546 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4547 return FALSE;
4549 if (!present)
4550 return TRUE;
4552 DumpString(sacl, 2, pwptr, plen);
4553 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4554 return FALSE;
4555 return TRUE;
4558 /******************************************************************************
4559 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4561 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4563 ULONG len;
4564 WCHAR *wptr, *wstr;
4566 if (SDRevision != SDDL_REVISION_1)
4568 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4569 SetLastError(ERROR_UNKNOWN_REVISION);
4570 return FALSE;
4573 len = 0;
4574 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4575 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4576 return FALSE;
4577 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4578 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4579 return FALSE;
4580 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4581 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4582 return FALSE;
4583 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4584 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4585 return FALSE;
4587 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4588 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4589 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4590 return FALSE;
4591 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4592 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4593 return FALSE;
4594 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4595 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4596 return FALSE;
4597 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4598 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4599 return FALSE;
4600 *wptr = 0;
4602 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4603 *OutputString = wstr;
4604 if (OutputLen)
4605 *OutputLen = strlenW(*OutputString)+1;
4606 return TRUE;
4609 /******************************************************************************
4610 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4612 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4614 LPWSTR wstr;
4615 ULONG len;
4616 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4618 int lenA;
4620 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4621 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4622 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4623 LocalFree(wstr);
4625 if (OutputLen != NULL)
4626 *OutputLen = lenA;
4627 return TRUE;
4629 else
4631 *OutputString = NULL;
4632 if (OutputLen)
4633 *OutputLen = 0;
4634 return FALSE;
4638 /******************************************************************************
4639 * ConvertStringSidToSidW [ADVAPI32.@]
4641 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4643 BOOL bret = FALSE;
4644 DWORD cBytes;
4646 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4647 if (GetVersion() & 0x80000000)
4648 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4649 else if (!StringSid || !Sid)
4650 SetLastError(ERROR_INVALID_PARAMETER);
4651 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4653 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4655 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4656 if (!bret)
4657 LocalFree(*Sid);
4659 return bret;
4662 /******************************************************************************
4663 * ConvertStringSidToSidA [ADVAPI32.@]
4665 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4667 BOOL bret = FALSE;
4669 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4670 if (GetVersion() & 0x80000000)
4671 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4672 else if (!StringSid || !Sid)
4673 SetLastError(ERROR_INVALID_PARAMETER);
4674 else
4676 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4677 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4678 len * sizeof(WCHAR));
4680 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4681 bret = ConvertStringSidToSidW(wStringSid, Sid);
4682 HeapFree(GetProcessHeap(), 0, wStringSid);
4684 return bret;
4687 /******************************************************************************
4688 * ConvertSidToStringSidW [ADVAPI32.@]
4690 * format of SID string is:
4691 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4692 * where
4693 * <rev> is the revision of the SID encoded as decimal
4694 * <auth> is the identifier authority encoded as hex
4695 * <subauthN> is the subauthority id encoded as decimal
4697 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4699 DWORD len = 0;
4700 LPWSTR wstr, wptr;
4702 TRACE("%p %p\n", pSid, pstr );
4704 len = 0;
4705 if (!DumpSidNumeric(pSid, NULL, &len))
4706 return FALSE;
4707 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4708 DumpSidNumeric(pSid, &wptr, NULL);
4709 *wptr = 0;
4711 *pstr = wstr;
4712 return TRUE;
4715 /******************************************************************************
4716 * ConvertSidToStringSidA [ADVAPI32.@]
4718 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4720 LPWSTR wstr = NULL;
4721 LPSTR str;
4722 UINT len;
4724 TRACE("%p %p\n", pSid, pstr );
4726 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4727 return FALSE;
4729 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4730 str = LocalAlloc( 0, len );
4731 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4732 LocalFree( wstr );
4734 *pstr = str;
4736 return TRUE;
4739 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4740 PSECURITY_DESCRIPTOR pdesc,
4741 PSECURITY_DESCRIPTOR cdesc,
4742 PSECURITY_DESCRIPTOR* ndesc,
4743 GUID* objtype,
4744 BOOL isdir,
4745 PGENERIC_MAPPING genmap )
4747 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4749 return FALSE;
4752 BOOL WINAPI CreatePrivateObjectSecurity(
4753 PSECURITY_DESCRIPTOR ParentDescriptor,
4754 PSECURITY_DESCRIPTOR CreatorDescriptor,
4755 PSECURITY_DESCRIPTOR* NewDescriptor,
4756 BOOL IsDirectoryObject,
4757 HANDLE Token,
4758 PGENERIC_MAPPING GenericMapping )
4760 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4761 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4763 return FALSE;
4766 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4768 FIXME("%p - stub\n", ObjectDescriptor);
4770 return TRUE;
4773 BOOL WINAPI CreateProcessAsUserA(
4774 HANDLE hToken,
4775 LPCSTR lpApplicationName,
4776 LPSTR lpCommandLine,
4777 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4778 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4779 BOOL bInheritHandles,
4780 DWORD dwCreationFlags,
4781 LPVOID lpEnvironment,
4782 LPCSTR lpCurrentDirectory,
4783 LPSTARTUPINFOA lpStartupInfo,
4784 LPPROCESS_INFORMATION lpProcessInformation )
4786 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4787 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4788 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4790 return FALSE;
4793 BOOL WINAPI CreateProcessAsUserW(
4794 HANDLE hToken,
4795 LPCWSTR lpApplicationName,
4796 LPWSTR lpCommandLine,
4797 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4798 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4799 BOOL bInheritHandles,
4800 DWORD dwCreationFlags,
4801 LPVOID lpEnvironment,
4802 LPCWSTR lpCurrentDirectory,
4803 LPSTARTUPINFOW lpStartupInfo,
4804 LPPROCESS_INFORMATION lpProcessInformation )
4806 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4807 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4808 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4809 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4811 /* We should create the process with a suspended main thread */
4812 if (!CreateProcessW (lpApplicationName,
4813 lpCommandLine,
4814 lpProcessAttributes,
4815 lpThreadAttributes,
4816 bInheritHandles,
4817 dwCreationFlags, /* CREATE_SUSPENDED */
4818 lpEnvironment,
4819 lpCurrentDirectory,
4820 lpStartupInfo,
4821 lpProcessInformation))
4823 return FALSE;
4826 return TRUE;
4829 /******************************************************************************
4830 * CreateProcessWithLogonW
4832 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4833 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4834 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4836 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4837 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4838 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4839 lpStartupInfo, lpProcessInformation);
4841 return FALSE;
4844 /******************************************************************************
4845 * DuplicateTokenEx [ADVAPI32.@]
4847 BOOL WINAPI DuplicateTokenEx(
4848 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4849 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4850 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4851 TOKEN_TYPE TokenType,
4852 PHANDLE DuplicateTokenHandle )
4854 OBJECT_ATTRIBUTES ObjectAttributes;
4856 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4857 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4859 InitializeObjectAttributes(
4860 &ObjectAttributes,
4861 NULL,
4862 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4863 NULL,
4864 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4866 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4867 dwDesiredAccess,
4868 &ObjectAttributes,
4869 ImpersonationLevel,
4870 TokenType,
4871 DuplicateTokenHandle ) );
4874 BOOL WINAPI DuplicateToken(
4875 HANDLE ExistingTokenHandle,
4876 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4877 PHANDLE DuplicateTokenHandle )
4879 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4880 NULL, ImpersonationLevel, TokenImpersonation,
4881 DuplicateTokenHandle );
4884 /******************************************************************************
4885 * ComputeStringSidSize
4887 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4889 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4891 int ctok = 0;
4892 while (*StringSid)
4894 if (*StringSid == '-')
4895 ctok++;
4896 StringSid++;
4899 if (ctok >= 3)
4900 return GetSidLengthRequired(ctok - 2);
4902 else /* String constant format - Only available in winxp and above */
4904 unsigned int i;
4906 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4907 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4908 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4911 return GetSidLengthRequired(0);
4914 /******************************************************************************
4915 * ParseStringSidToSid
4917 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4919 BOOL bret = FALSE;
4920 SID* pisid=pSid;
4922 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4923 if (!StringSid)
4925 SetLastError(ERROR_INVALID_PARAMETER);
4926 TRACE("StringSid is NULL, returning FALSE\n");
4927 return FALSE;
4930 *cBytes = ComputeStringSidSize(StringSid);
4931 if (!pisid) /* Simply compute the size */
4933 TRACE("only size requested, returning TRUE\n");
4934 return TRUE;
4937 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4939 DWORD i = 0, identAuth;
4940 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4942 StringSid += 2; /* Advance to Revision */
4943 pisid->Revision = atoiW(StringSid);
4945 if (pisid->Revision != SDDL_REVISION)
4947 TRACE("Revision %d is unknown\n", pisid->Revision);
4948 goto lend; /* ERROR_INVALID_SID */
4950 if (csubauth == 0)
4952 TRACE("SubAuthorityCount is 0\n");
4953 goto lend; /* ERROR_INVALID_SID */
4956 pisid->SubAuthorityCount = csubauth;
4958 /* Advance to identifier authority */
4959 while (*StringSid && *StringSid != '-')
4960 StringSid++;
4961 if (*StringSid == '-')
4962 StringSid++;
4964 /* MS' implementation can't handle values greater than 2^32 - 1, so
4965 * we don't either; assume most significant bytes are always 0
4967 pisid->IdentifierAuthority.Value[0] = 0;
4968 pisid->IdentifierAuthority.Value[1] = 0;
4969 identAuth = atoiW(StringSid);
4970 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4971 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4972 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4973 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4975 /* Advance to first sub authority */
4976 while (*StringSid && *StringSid != '-')
4977 StringSid++;
4978 if (*StringSid == '-')
4979 StringSid++;
4981 while (*StringSid)
4983 pisid->SubAuthority[i++] = atoiW(StringSid);
4985 while (*StringSid && *StringSid != '-')
4986 StringSid++;
4987 if (*StringSid == '-')
4988 StringSid++;
4991 if (i != pisid->SubAuthorityCount)
4992 goto lend; /* ERROR_INVALID_SID */
4994 bret = TRUE;
4996 else /* String constant format - Only available in winxp and above */
4998 unsigned int i;
4999 pisid->Revision = SDDL_REVISION;
5001 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5002 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5004 DWORD j;
5005 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5006 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5007 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5008 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5009 bret = TRUE;
5012 if (!bret)
5013 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5016 lend:
5017 if (!bret)
5018 SetLastError(ERROR_INVALID_SID);
5020 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5021 return bret;
5024 /******************************************************************************
5025 * GetNamedSecurityInfoA [ADVAPI32.@]
5027 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5028 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5029 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5030 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5032 DWORD len;
5033 LPWSTR wstr = NULL;
5034 DWORD r;
5036 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5037 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5039 if( pObjectName )
5041 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5042 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5043 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5046 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5047 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5049 HeapFree( GetProcessHeap(), 0, wstr );
5051 return r;
5054 /******************************************************************************
5055 * GetNamedSecurityInfoW [ADVAPI32.@]
5057 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5058 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5059 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5061 DWORD needed, offset;
5062 SECURITY_DESCRIPTOR_RELATIVE *relative;
5063 BYTE *buffer;
5065 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5066 group, dacl, sacl, descriptor );
5068 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5070 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5071 if (info & OWNER_SECURITY_INFORMATION)
5072 needed += sizeof(sidWorld);
5073 if (info & GROUP_SECURITY_INFORMATION)
5074 needed += sizeof(sidWorld);
5075 if (info & DACL_SECURITY_INFORMATION)
5076 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5077 if (info & SACL_SECURITY_INFORMATION)
5078 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5080 /* must be freed by caller */
5081 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5082 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5084 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5086 HeapFree( GetProcessHeap(), 0, *descriptor );
5087 return ERROR_INVALID_SECURITY_DESCR;
5090 relative = *descriptor;
5091 relative->Control |= SE_SELF_RELATIVE;
5092 buffer = (BYTE *)relative;
5093 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5095 if (info & OWNER_SECURITY_INFORMATION)
5097 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5098 relative->Owner = offset;
5099 if (owner)
5100 *owner = buffer + offset;
5101 offset += sizeof(sidWorld);
5103 if (info & GROUP_SECURITY_INFORMATION)
5105 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5106 relative->Group = offset;
5107 if (group)
5108 *group = buffer + offset;
5109 offset += sizeof(sidWorld);
5111 if (info & DACL_SECURITY_INFORMATION)
5113 relative->Control |= SE_DACL_PRESENT;
5114 GetWorldAccessACL( (PACL)(buffer + offset) );
5115 relative->Dacl = offset;
5116 if (dacl)
5117 *dacl = (PACL)(buffer + offset);
5118 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5120 if (info & SACL_SECURITY_INFORMATION)
5122 relative->Control |= SE_SACL_PRESENT;
5123 GetWorldAccessACL( (PACL)(buffer + offset) );
5124 relative->Sacl = offset;
5125 if (sacl)
5126 *sacl = (PACL)(buffer + offset);
5128 return ERROR_SUCCESS;
5131 /******************************************************************************
5132 * DecryptFileW [ADVAPI32.@]
5134 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5136 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5137 return TRUE;
5140 /******************************************************************************
5141 * DecryptFileA [ADVAPI32.@]
5143 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5145 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5146 return TRUE;
5149 /******************************************************************************
5150 * EncryptFileW [ADVAPI32.@]
5152 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5154 FIXME("%s\n", debugstr_w(lpFileName));
5155 return TRUE;
5158 /******************************************************************************
5159 * EncryptFileA [ADVAPI32.@]
5161 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5163 FIXME("%s\n", debugstr_a(lpFileName));
5164 return TRUE;
5167 /******************************************************************************
5168 * FileEncryptionStatusW [ADVAPI32.@]
5170 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5172 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5173 if (!lpStatus)
5174 return FALSE;
5175 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5176 return TRUE;
5179 /******************************************************************************
5180 * FileEncryptionStatusA [ADVAPI32.@]
5182 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5184 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5185 if (!lpStatus)
5186 return FALSE;
5187 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5188 return TRUE;
5191 /******************************************************************************
5192 * SetSecurityInfo [ADVAPI32.@]
5194 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5195 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5196 PSID psidGroup, PACL pDacl, PACL pSacl) {
5197 FIXME("stub\n");
5198 return ERROR_SUCCESS;
5201 /******************************************************************************
5202 * SaferCreateLevel [ADVAPI32.@]
5204 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5205 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5207 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5208 return FALSE;