appwiz.cpl: Added support for installing packages from MSI files.
[wine/multimedia.git] / dlls / advapi32 / security.c
blobde090dc9cac412f2d8043819bb7e4780a6aab46f
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_RELATIVE* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 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 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 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 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 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 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 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 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 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 };
216 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 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 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 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 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 };
223 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 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 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 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 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 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 * Reads the computer SID from the registry.
452 BOOL ADVAPI_GetComputerSid(PSID sid)
454 HKEY key;
455 LONG ret;
456 BOOL retval = FALSE;
457 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 };
458 static const WCHAR V[] = { 'V',0 };
460 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461 KEY_READ, &key)) == ERROR_SUCCESS)
463 DWORD size = 0;
464 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
467 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468 if (data)
470 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471 data, &size)) == ERROR_SUCCESS)
473 /* the SID is in the last 24 bytes of the binary data */
474 CopyMemory(sid, &data[size-24], 24);
475 retval = TRUE;
477 HeapFree(GetProcessHeap(), 0, data);
480 RegCloseKey(key);
483 if(retval == TRUE) return retval;
485 /* create a new random SID */
486 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
489 PSID new_sid;
490 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491 DWORD id[3];
493 if (RtlGenRandom(id, sizeof(id)))
495 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
497 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
500 FreeSid(new_sid);
503 RegCloseKey(key);
506 return retval;
509 /* ##############################
510 ###### TOKEN FUNCTIONS ######
511 ##############################
514 /******************************************************************************
515 * OpenProcessToken [ADVAPI32.@]
516 * Opens the access token associated with a process handle.
518 * PARAMS
519 * ProcessHandle [I] Handle to process
520 * DesiredAccess [I] Desired access to process
521 * TokenHandle [O] Pointer to handle of open access token
523 * RETURNS
524 * Success: TRUE. TokenHandle contains the access token.
525 * Failure: FALSE.
527 * NOTES
528 * See NtOpenProcessToken.
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532 HANDLE *TokenHandle )
534 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
537 /******************************************************************************
538 * OpenThreadToken [ADVAPI32.@]
540 * Opens the access token associated with a thread handle.
542 * PARAMS
543 * ThreadHandle [I] Handle to process
544 * DesiredAccess [I] Desired access to the thread
545 * OpenAsSelf [I] ???
546 * TokenHandle [O] Destination for the token handle
548 * RETURNS
549 * Success: TRUE. TokenHandle contains the access token.
550 * Failure: FALSE.
552 * NOTES
553 * See NtOpenThreadToken.
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557 BOOL OpenAsSelf, HANDLE *TokenHandle)
559 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
566 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567 PreviousState, ReturnLength));
570 /******************************************************************************
571 * AdjustTokenPrivileges [ADVAPI32.@]
573 * Adjust the privileges of an open token handle.
575 * PARAMS
576 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
577 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
578 * NewState [I] Desired new privileges of the token
579 * BufferLength [I] Length of NewState
580 * PreviousState [O] Destination for the previous state
581 * ReturnLength [I/O] Size of PreviousState
584 * RETURNS
585 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586 * Failure: FALSE.
588 * NOTES
589 * See NtAdjustPrivilegesToken.
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
596 NTSTATUS status;
598 TRACE("\n");
600 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601 NewState, BufferLength, PreviousState,
602 ReturnLength);
603 SetLastError( RtlNtStatusToDosError( status ));
604 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605 return TRUE;
606 else
607 return FALSE;
610 /******************************************************************************
611 * CheckTokenMembership [ADVAPI32.@]
613 * Determine if an access token is a member of a SID.
615 * PARAMS
616 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617 * SidToCheck [I] SID that possibly contains the token
618 * IsMember [O] Destination for result.
620 * RETURNS
621 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622 * Failure: FALSE.
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE token, PSID sid_to_check,
626 PBOOL is_member )
628 PTOKEN_GROUPS token_groups = NULL;
629 HANDLE thread_token = NULL;
630 DWORD size, i;
631 BOOL ret;
633 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
635 *is_member = FALSE;
637 if (!token)
639 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
641 HANDLE process_token;
642 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
643 if (!ret)
644 goto exit;
645 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
646 NULL, SecurityImpersonation, TokenImpersonation,
647 &thread_token);
648 CloseHandle(process_token);
649 if (!ret)
650 goto exit;
652 token = thread_token;
655 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
656 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
657 goto exit;
659 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
660 if (!token_groups)
662 ret = FALSE;
663 goto exit;
666 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
667 if (!ret)
668 goto exit;
670 for (i = 0; i < token_groups->GroupCount; i++)
672 TRACE("Groups[%d]: {0x%x, %s}\n", i,
673 token_groups->Groups[i].Attributes,
674 debugstr_sid(token_groups->Groups[i].Sid));
675 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
676 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
678 *is_member = TRUE;
679 TRACE("sid enabled and found in token\n");
680 break;
684 exit:
685 HeapFree(GetProcessHeap(), 0, token_groups);
686 if (thread_token != NULL) CloseHandle(thread_token);
688 return ret;
691 /******************************************************************************
692 * GetTokenInformation [ADVAPI32.@]
694 * Get a type of information about an access token.
696 * PARAMS
697 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
698 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
699 * tokeninfo [O] Destination for token information
700 * tokeninfolength [I] Length of tokeninfo
701 * retlen [O] Destination for returned token information length
703 * RETURNS
704 * Success: TRUE. tokeninfo contains retlen bytes of token information
705 * Failure: FALSE.
707 * NOTES
708 * See NtQueryInformationToken.
710 BOOL WINAPI
711 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
712 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
714 TRACE("(%p, %s, %p, %d, %p):\n",
715 token,
716 (tokeninfoclass == TokenUser) ? "TokenUser" :
717 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
718 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
719 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
720 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
721 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
722 (tokeninfoclass == TokenSource) ? "TokenSource" :
723 (tokeninfoclass == TokenType) ? "TokenType" :
724 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
725 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
726 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
727 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
728 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
729 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
730 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
731 "Unknown",
732 tokeninfo, tokeninfolength, retlen);
733 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
734 tokeninfolength, retlen));
737 /******************************************************************************
738 * SetTokenInformation [ADVAPI32.@]
740 * Set information for an access token.
742 * PARAMS
743 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
744 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
745 * tokeninfo [I] Token information to set
746 * tokeninfolength [I] Length of tokeninfo
748 * RETURNS
749 * Success: TRUE. The information for the token is set to tokeninfo.
750 * Failure: FALSE.
752 BOOL WINAPI
753 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
754 LPVOID tokeninfo, DWORD tokeninfolength )
756 TRACE("(%p, %s, %p, %d): stub\n",
757 token,
758 (tokeninfoclass == TokenUser) ? "TokenUser" :
759 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
760 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
761 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
762 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
763 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
764 (tokeninfoclass == TokenSource) ? "TokenSource" :
765 (tokeninfoclass == TokenType) ? "TokenType" :
766 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
767 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
768 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
769 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
770 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
771 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
772 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
773 "Unknown",
774 tokeninfo, tokeninfolength);
776 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
779 /*************************************************************************
780 * SetThreadToken [ADVAPI32.@]
782 * Assigns an 'impersonation token' to a thread so it can assume the
783 * security privileges of another thread or process. Can also remove
784 * a previously assigned token.
786 * PARAMS
787 * thread [O] Handle to thread to set the token for
788 * token [I] Token to set
790 * RETURNS
791 * Success: TRUE. The threads access token is set to token
792 * Failure: FALSE.
794 * NOTES
795 * Only supported on NT or higher. On Win9X this function does nothing.
796 * See SetTokenInformation.
798 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
800 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
801 ThreadImpersonationToken, &token, sizeof token ));
804 /*************************************************************************
805 * CreateRestrictedToken [ADVAPI32.@]
807 * Create a new more restricted token from an existing token.
809 * PARAMS
810 * baseToken [I] Token to base the new restricted token on
811 * flags [I] Options
812 * nDisableSids [I] Length of disableSids array
813 * disableSids [I] Array of SIDs to disable in the new token
814 * nDeletePrivs [I] Length of deletePrivs array
815 * deletePrivs [I] Array of privileges to delete in the new token
816 * nRestrictSids [I] Length of restrictSids array
817 * restrictSids [I] Array of SIDs to restrict in the new token
818 * newToken [O] Address where the new token is stored
820 * RETURNS
821 * Success: TRUE
822 * Failure: FALSE
824 BOOL WINAPI CreateRestrictedToken(
825 HANDLE baseToken,
826 DWORD flags,
827 DWORD nDisableSids,
828 PSID_AND_ATTRIBUTES disableSids,
829 DWORD nDeletePrivs,
830 PLUID_AND_ATTRIBUTES deletePrivs,
831 DWORD nRestrictSids,
832 PSID_AND_ATTRIBUTES restrictSids,
833 PHANDLE newToken)
835 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
836 baseToken, flags, nDisableSids, disableSids,
837 nDeletePrivs, deletePrivs,
838 nRestrictSids, restrictSids,
839 newToken);
840 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
841 return FALSE;
844 /* ##############################
845 ###### SID FUNCTIONS ######
846 ##############################
849 /******************************************************************************
850 * AllocateAndInitializeSid [ADVAPI32.@]
852 * PARAMS
853 * pIdentifierAuthority []
854 * nSubAuthorityCount []
855 * nSubAuthority0 []
856 * nSubAuthority1 []
857 * nSubAuthority2 []
858 * nSubAuthority3 []
859 * nSubAuthority4 []
860 * nSubAuthority5 []
861 * nSubAuthority6 []
862 * nSubAuthority7 []
863 * pSid []
865 BOOL WINAPI
866 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
867 BYTE nSubAuthorityCount,
868 DWORD nSubAuthority0, DWORD nSubAuthority1,
869 DWORD nSubAuthority2, DWORD nSubAuthority3,
870 DWORD nSubAuthority4, DWORD nSubAuthority5,
871 DWORD nSubAuthority6, DWORD nSubAuthority7,
872 PSID *pSid )
874 return set_ntstatus( RtlAllocateAndInitializeSid(
875 pIdentifierAuthority, nSubAuthorityCount,
876 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
877 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
878 pSid ));
881 /******************************************************************************
882 * FreeSid [ADVAPI32.@]
884 * PARAMS
885 * pSid []
887 PVOID WINAPI
888 FreeSid( PSID pSid )
890 RtlFreeSid(pSid);
891 return NULL; /* is documented like this */
894 /******************************************************************************
895 * CopySid [ADVAPI32.@]
897 * PARAMS
898 * nDestinationSidLength []
899 * pDestinationSid []
900 * pSourceSid []
902 BOOL WINAPI
903 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
905 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
908 /******************************************************************************
909 * CreateWellKnownSid [ADVAPI32.@]
911 BOOL WINAPI
912 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
913 PSID DomainSid,
914 PSID pSid,
915 DWORD* cbSid)
917 unsigned int i;
918 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
920 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
922 SetLastError(ERROR_INVALID_PARAMETER);
923 return FALSE;
926 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
927 if (WellKnownSids[i].Type == WellKnownSidType) {
928 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
930 if (*cbSid < length)
932 *cbSid = length;
933 SetLastError(ERROR_INSUFFICIENT_BUFFER);
934 return FALSE;
936 if (!pSid)
938 SetLastError(ERROR_INVALID_PARAMETER);
939 return FALSE;
941 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
942 *cbSid = length;
943 return TRUE;
947 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return FALSE;
953 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
954 if (WellKnownRids[i].Type == WellKnownSidType) {
955 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
956 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
957 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
959 if (*cbSid < output_sid_length)
961 *cbSid = output_sid_length;
962 SetLastError(ERROR_INSUFFICIENT_BUFFER);
963 return FALSE;
965 if (!pSid)
967 SetLastError(ERROR_INVALID_PARAMETER);
968 return FALSE;
970 CopyMemory(pSid, DomainSid, domain_sid_length);
971 (*GetSidSubAuthorityCount(pSid))++;
972 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
973 *cbSid = output_sid_length;
974 return TRUE;
977 SetLastError(ERROR_INVALID_PARAMETER);
978 return FALSE;
981 /******************************************************************************
982 * IsWellKnownSid [ADVAPI32.@]
984 BOOL WINAPI
985 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
987 unsigned int i;
988 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
990 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
991 if (WellKnownSids[i].Type == WellKnownSidType)
992 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
993 return TRUE;
995 return FALSE;
998 BOOL WINAPI
999 IsTokenRestricted( HANDLE TokenHandle )
1001 TOKEN_GROUPS *groups;
1002 DWORD size;
1003 NTSTATUS status;
1004 BOOL restricted;
1006 TRACE("(%p)\n", TokenHandle);
1008 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1009 if (status != STATUS_BUFFER_TOO_SMALL)
1010 return FALSE;
1012 groups = HeapAlloc(GetProcessHeap(), 0, size);
1013 if (!groups)
1015 SetLastError(ERROR_OUTOFMEMORY);
1016 return FALSE;
1019 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1020 if (status != STATUS_SUCCESS)
1022 HeapFree(GetProcessHeap(), 0, groups);
1023 return set_ntstatus(status);
1026 if (groups->GroupCount)
1027 restricted = TRUE;
1028 else
1029 restricted = FALSE;
1031 HeapFree(GetProcessHeap(), 0, groups);
1033 return restricted;
1036 /******************************************************************************
1037 * IsValidSid [ADVAPI32.@]
1039 * PARAMS
1040 * pSid []
1042 BOOL WINAPI
1043 IsValidSid( PSID pSid )
1045 return RtlValidSid( pSid );
1048 /******************************************************************************
1049 * EqualSid [ADVAPI32.@]
1051 * PARAMS
1052 * pSid1 []
1053 * pSid2 []
1055 BOOL WINAPI
1056 EqualSid( PSID pSid1, PSID pSid2 )
1058 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1059 SetLastError(ERROR_SUCCESS);
1060 return ret;
1063 /******************************************************************************
1064 * EqualPrefixSid [ADVAPI32.@]
1066 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1068 return RtlEqualPrefixSid(pSid1, pSid2);
1071 /******************************************************************************
1072 * GetSidLengthRequired [ADVAPI32.@]
1074 * PARAMS
1075 * nSubAuthorityCount []
1077 DWORD WINAPI
1078 GetSidLengthRequired( BYTE nSubAuthorityCount )
1080 return RtlLengthRequiredSid(nSubAuthorityCount);
1083 /******************************************************************************
1084 * InitializeSid [ADVAPI32.@]
1086 * PARAMS
1087 * pIdentifierAuthority []
1089 BOOL WINAPI
1090 InitializeSid (
1091 PSID pSid,
1092 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1093 BYTE nSubAuthorityCount)
1095 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1098 DWORD WINAPI
1099 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1101 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1103 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1104 return 0;
1107 DWORD WINAPI
1108 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1110 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1112 return 1;
1115 /******************************************************************************
1116 * GetSidIdentifierAuthority [ADVAPI32.@]
1118 * PARAMS
1119 * pSid []
1121 PSID_IDENTIFIER_AUTHORITY WINAPI
1122 GetSidIdentifierAuthority( PSID pSid )
1124 return RtlIdentifierAuthoritySid(pSid);
1127 /******************************************************************************
1128 * GetSidSubAuthority [ADVAPI32.@]
1130 * PARAMS
1131 * pSid []
1132 * nSubAuthority []
1134 PDWORD WINAPI
1135 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1137 SetLastError(ERROR_SUCCESS);
1138 return RtlSubAuthoritySid(pSid, nSubAuthority);
1141 /******************************************************************************
1142 * GetSidSubAuthorityCount [ADVAPI32.@]
1144 * PARAMS
1145 * pSid []
1147 PUCHAR WINAPI
1148 GetSidSubAuthorityCount (PSID pSid)
1150 SetLastError(ERROR_SUCCESS);
1151 return RtlSubAuthorityCountSid(pSid);
1154 /******************************************************************************
1155 * GetLengthSid [ADVAPI32.@]
1157 * PARAMS
1158 * pSid []
1160 DWORD WINAPI
1161 GetLengthSid (PSID pSid)
1163 return RtlLengthSid(pSid);
1166 /* ##############################################
1167 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1168 ##############################################
1171 /******************************************************************************
1172 * BuildSecurityDescriptorA [ADVAPI32.@]
1174 * Builds a SD from
1176 * PARAMS
1177 * pOwner [I]
1178 * pGroup [I]
1179 * cCountOfAccessEntries [I]
1180 * pListOfAccessEntries [I]
1181 * cCountOfAuditEntries [I]
1182 * pListofAuditEntries [I]
1183 * pOldSD [I]
1184 * lpdwBufferLength [I/O]
1185 * pNewSD [O]
1187 * RETURNS
1188 * Success: ERROR_SUCCESS
1189 * Failure: nonzero error code from Winerror.h
1191 DWORD WINAPI BuildSecurityDescriptorA(
1192 IN PTRUSTEEA pOwner,
1193 IN PTRUSTEEA pGroup,
1194 IN ULONG cCountOfAccessEntries,
1195 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1196 IN ULONG cCountOfAuditEntries,
1197 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1198 IN PSECURITY_DESCRIPTOR pOldSD,
1199 IN OUT PULONG lpdwBufferLength,
1200 OUT PSECURITY_DESCRIPTOR* pNewSD)
1202 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1203 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1204 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1206 return ERROR_CALL_NOT_IMPLEMENTED;
1209 /******************************************************************************
1210 * BuildSecurityDescriptorW [ADVAPI32.@]
1212 * See BuildSecurityDescriptorA.
1214 DWORD WINAPI BuildSecurityDescriptorW(
1215 IN PTRUSTEEW pOwner,
1216 IN PTRUSTEEW pGroup,
1217 IN ULONG cCountOfAccessEntries,
1218 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1219 IN ULONG cCountOfAuditEntries,
1220 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1221 IN PSECURITY_DESCRIPTOR pOldSD,
1222 IN OUT PULONG lpdwBufferLength,
1223 OUT PSECURITY_DESCRIPTOR* pNewSD)
1225 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1226 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1227 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1229 return ERROR_CALL_NOT_IMPLEMENTED;
1232 /******************************************************************************
1233 * InitializeSecurityDescriptor [ADVAPI32.@]
1235 * PARAMS
1236 * pDescr []
1237 * revision []
1239 BOOL WINAPI
1240 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1242 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1246 /******************************************************************************
1247 * MakeAbsoluteSD [ADVAPI32.@]
1249 BOOL WINAPI MakeAbsoluteSD (
1250 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1251 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1252 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1253 OUT PACL pDacl,
1254 OUT LPDWORD lpdwDaclSize,
1255 OUT PACL pSacl,
1256 OUT LPDWORD lpdwSaclSize,
1257 OUT PSID pOwner,
1258 OUT LPDWORD lpdwOwnerSize,
1259 OUT PSID pPrimaryGroup,
1260 OUT LPDWORD lpdwPrimaryGroupSize)
1262 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1263 pAbsoluteSecurityDescriptor,
1264 lpdwAbsoluteSecurityDescriptorSize,
1265 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1266 pOwner, lpdwOwnerSize,
1267 pPrimaryGroup, lpdwPrimaryGroupSize));
1270 /******************************************************************************
1271 * GetKernelObjectSecurity [ADVAPI32.@]
1273 BOOL WINAPI GetKernelObjectSecurity(
1274 HANDLE Handle,
1275 SECURITY_INFORMATION RequestedInformation,
1276 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1277 DWORD nLength,
1278 LPDWORD lpnLengthNeeded )
1280 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1281 pSecurityDescriptor, nLength, lpnLengthNeeded);
1283 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1284 nLength, lpnLengthNeeded ));
1287 /******************************************************************************
1288 * GetPrivateObjectSecurity [ADVAPI32.@]
1290 BOOL WINAPI GetPrivateObjectSecurity(
1291 PSECURITY_DESCRIPTOR ObjectDescriptor,
1292 SECURITY_INFORMATION SecurityInformation,
1293 PSECURITY_DESCRIPTOR ResultantDescriptor,
1294 DWORD DescriptorLength,
1295 PDWORD ReturnLength )
1297 SECURITY_DESCRIPTOR desc;
1298 BOOL defaulted, present;
1299 PACL pacl;
1300 PSID psid;
1302 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1303 ResultantDescriptor, DescriptorLength, ReturnLength);
1305 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1306 return FALSE;
1308 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1310 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1311 return FALSE;
1312 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1315 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1317 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1318 return FALSE;
1319 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1322 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1324 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1325 return FALSE;
1326 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1329 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1331 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1332 return FALSE;
1333 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1336 *ReturnLength = DescriptorLength;
1337 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1340 /******************************************************************************
1341 * GetSecurityDescriptorLength [ADVAPI32.@]
1343 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1345 return RtlLengthSecurityDescriptor(pDescr);
1348 /******************************************************************************
1349 * GetSecurityDescriptorOwner [ADVAPI32.@]
1351 * PARAMS
1352 * pOwner []
1353 * lpbOwnerDefaulted []
1355 BOOL WINAPI
1356 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1357 LPBOOL lpbOwnerDefaulted )
1359 BOOLEAN defaulted;
1360 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1361 *lpbOwnerDefaulted = defaulted;
1362 return ret;
1365 /******************************************************************************
1366 * SetSecurityDescriptorOwner [ADVAPI32.@]
1368 * PARAMS
1370 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1371 PSID pOwner, BOOL bOwnerDefaulted)
1373 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1375 /******************************************************************************
1376 * GetSecurityDescriptorGroup [ADVAPI32.@]
1378 BOOL WINAPI GetSecurityDescriptorGroup(
1379 PSECURITY_DESCRIPTOR SecurityDescriptor,
1380 PSID *Group,
1381 LPBOOL GroupDefaulted)
1383 BOOLEAN defaulted;
1384 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1385 *GroupDefaulted = defaulted;
1386 return ret;
1388 /******************************************************************************
1389 * SetSecurityDescriptorGroup [ADVAPI32.@]
1391 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1392 PSID Group, BOOL GroupDefaulted)
1394 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1397 /******************************************************************************
1398 * IsValidSecurityDescriptor [ADVAPI32.@]
1400 * PARAMS
1401 * lpsecdesc []
1403 BOOL WINAPI
1404 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1406 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1409 /******************************************************************************
1410 * GetSecurityDescriptorDacl [ADVAPI32.@]
1412 BOOL WINAPI GetSecurityDescriptorDacl(
1413 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1414 OUT LPBOOL lpbDaclPresent,
1415 OUT PACL *pDacl,
1416 OUT LPBOOL lpbDaclDefaulted)
1418 BOOLEAN present, defaulted;
1419 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1420 *lpbDaclPresent = present;
1421 *lpbDaclDefaulted = defaulted;
1422 return ret;
1425 /******************************************************************************
1426 * SetSecurityDescriptorDacl [ADVAPI32.@]
1428 BOOL WINAPI
1429 SetSecurityDescriptorDacl (
1430 PSECURITY_DESCRIPTOR lpsd,
1431 BOOL daclpresent,
1432 PACL dacl,
1433 BOOL dacldefaulted )
1435 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1437 /******************************************************************************
1438 * GetSecurityDescriptorSacl [ADVAPI32.@]
1440 BOOL WINAPI GetSecurityDescriptorSacl(
1441 IN PSECURITY_DESCRIPTOR lpsd,
1442 OUT LPBOOL lpbSaclPresent,
1443 OUT PACL *pSacl,
1444 OUT LPBOOL lpbSaclDefaulted)
1446 BOOLEAN present, defaulted;
1447 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1448 *lpbSaclPresent = present;
1449 *lpbSaclDefaulted = defaulted;
1450 return ret;
1453 /**************************************************************************
1454 * SetSecurityDescriptorSacl [ADVAPI32.@]
1456 BOOL WINAPI SetSecurityDescriptorSacl (
1457 PSECURITY_DESCRIPTOR lpsd,
1458 BOOL saclpresent,
1459 PACL lpsacl,
1460 BOOL sacldefaulted)
1462 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1464 /******************************************************************************
1465 * MakeSelfRelativeSD [ADVAPI32.@]
1467 * PARAMS
1468 * lpabssecdesc []
1469 * lpselfsecdesc []
1470 * lpbuflen []
1472 BOOL WINAPI
1473 MakeSelfRelativeSD(
1474 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1475 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1476 IN OUT LPDWORD lpdwBufferLength)
1478 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1479 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1482 /******************************************************************************
1483 * GetSecurityDescriptorControl [ADVAPI32.@]
1486 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1487 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1489 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1492 /******************************************************************************
1493 * SetSecurityDescriptorControl [ADVAPI32.@]
1495 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1496 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1497 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1499 return set_ntstatus( RtlSetControlSecurityDescriptor(
1500 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1503 /* ##############################
1504 ###### ACL FUNCTIONS ######
1505 ##############################
1508 /*************************************************************************
1509 * InitializeAcl [ADVAPI32.@]
1511 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1513 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1516 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1518 IO_STATUS_BLOCK io_block;
1520 TRACE("(%p)\n", hNamedPipe);
1522 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1523 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1526 /******************************************************************************
1527 * AddAccessAllowedAce [ADVAPI32.@]
1529 BOOL WINAPI AddAccessAllowedAce(
1530 IN OUT PACL pAcl,
1531 IN DWORD dwAceRevision,
1532 IN DWORD AccessMask,
1533 IN PSID pSid)
1535 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1538 /******************************************************************************
1539 * AddAccessAllowedAceEx [ADVAPI32.@]
1541 BOOL WINAPI AddAccessAllowedAceEx(
1542 IN OUT PACL pAcl,
1543 IN DWORD dwAceRevision,
1544 IN DWORD AceFlags,
1545 IN DWORD AccessMask,
1546 IN PSID pSid)
1548 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1551 /******************************************************************************
1552 * AddAccessDeniedAce [ADVAPI32.@]
1554 BOOL WINAPI AddAccessDeniedAce(
1555 IN OUT PACL pAcl,
1556 IN DWORD dwAceRevision,
1557 IN DWORD AccessMask,
1558 IN PSID pSid)
1560 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1563 /******************************************************************************
1564 * AddAccessDeniedAceEx [ADVAPI32.@]
1566 BOOL WINAPI AddAccessDeniedAceEx(
1567 IN OUT PACL pAcl,
1568 IN DWORD dwAceRevision,
1569 IN DWORD AceFlags,
1570 IN DWORD AccessMask,
1571 IN PSID pSid)
1573 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1576 /******************************************************************************
1577 * AddAce [ADVAPI32.@]
1579 BOOL WINAPI AddAce(
1580 IN OUT PACL pAcl,
1581 IN DWORD dwAceRevision,
1582 IN DWORD dwStartingAceIndex,
1583 LPVOID pAceList,
1584 DWORD nAceListLength)
1586 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1589 /******************************************************************************
1590 * DeleteAce [ADVAPI32.@]
1592 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1594 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1597 /******************************************************************************
1598 * FindFirstFreeAce [ADVAPI32.@]
1600 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1602 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1605 /******************************************************************************
1606 * GetAce [ADVAPI32.@]
1608 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1610 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1613 /******************************************************************************
1614 * GetAclInformation [ADVAPI32.@]
1616 BOOL WINAPI GetAclInformation(
1617 PACL pAcl,
1618 LPVOID pAclInformation,
1619 DWORD nAclInformationLength,
1620 ACL_INFORMATION_CLASS dwAclInformationClass)
1622 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1623 nAclInformationLength, dwAclInformationClass));
1626 /******************************************************************************
1627 * IsValidAcl [ADVAPI32.@]
1629 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1631 return RtlValidAcl(pAcl);
1634 /* ##############################
1635 ###### MISC FUNCTIONS ######
1636 ##############################
1639 /******************************************************************************
1640 * AllocateLocallyUniqueId [ADVAPI32.@]
1642 * PARAMS
1643 * lpLuid []
1645 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1647 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1650 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1651 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1652 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1653 { '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 };
1654 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1655 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1656 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1657 { '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 };
1658 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1659 { '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 };
1660 static const WCHAR SE_TCB_NAME_W[] =
1661 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1662 static const WCHAR SE_SECURITY_NAME_W[] =
1663 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1664 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1665 { '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 };
1666 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1667 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1668 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1669 { '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 };
1670 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1671 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1672 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1673 { '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 };
1674 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1675 { '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 };
1676 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1677 { '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 };
1678 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1679 { '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 };
1680 static const WCHAR SE_BACKUP_NAME_W[] =
1681 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1682 static const WCHAR SE_RESTORE_NAME_W[] =
1683 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1684 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1685 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1686 static const WCHAR SE_DEBUG_NAME_W[] =
1687 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1688 static const WCHAR SE_AUDIT_NAME_W[] =
1689 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1690 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1691 { '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 };
1692 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1693 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1694 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1695 { '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 };
1696 static const WCHAR SE_UNDOCK_NAME_W[] =
1697 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1698 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1699 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1700 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1701 { '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 };
1702 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1703 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1704 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1705 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1706 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1707 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1709 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1711 NULL,
1712 NULL,
1713 SE_CREATE_TOKEN_NAME_W,
1714 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1715 SE_LOCK_MEMORY_NAME_W,
1716 SE_INCREASE_QUOTA_NAME_W,
1717 SE_MACHINE_ACCOUNT_NAME_W,
1718 SE_TCB_NAME_W,
1719 SE_SECURITY_NAME_W,
1720 SE_TAKE_OWNERSHIP_NAME_W,
1721 SE_LOAD_DRIVER_NAME_W,
1722 SE_SYSTEM_PROFILE_NAME_W,
1723 SE_SYSTEMTIME_NAME_W,
1724 SE_PROF_SINGLE_PROCESS_NAME_W,
1725 SE_INC_BASE_PRIORITY_NAME_W,
1726 SE_CREATE_PAGEFILE_NAME_W,
1727 SE_CREATE_PERMANENT_NAME_W,
1728 SE_BACKUP_NAME_W,
1729 SE_RESTORE_NAME_W,
1730 SE_SHUTDOWN_NAME_W,
1731 SE_DEBUG_NAME_W,
1732 SE_AUDIT_NAME_W,
1733 SE_SYSTEM_ENVIRONMENT_NAME_W,
1734 SE_CHANGE_NOTIFY_NAME_W,
1735 SE_REMOTE_SHUTDOWN_NAME_W,
1736 SE_UNDOCK_NAME_W,
1737 SE_SYNC_AGENT_NAME_W,
1738 SE_ENABLE_DELEGATION_NAME_W,
1739 SE_MANAGE_VOLUME_NAME_W,
1740 SE_IMPERSONATE_NAME_W,
1741 SE_CREATE_GLOBAL_NAME_W,
1744 /******************************************************************************
1745 * LookupPrivilegeValueW [ADVAPI32.@]
1747 * See LookupPrivilegeValueA.
1749 BOOL WINAPI
1750 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1752 UINT i;
1754 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1756 if (!ADVAPI_IsLocalComputer(lpSystemName))
1758 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1759 return FALSE;
1761 if (!lpName)
1763 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1764 return FALSE;
1766 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1768 if( !WellKnownPrivNames[i] )
1769 continue;
1770 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1771 continue;
1772 lpLuid->LowPart = i;
1773 lpLuid->HighPart = 0;
1774 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1775 lpLuid->HighPart, lpLuid->LowPart );
1776 return TRUE;
1778 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1779 return FALSE;
1782 /******************************************************************************
1783 * LookupPrivilegeValueA [ADVAPI32.@]
1785 * Retrieves LUID used on a system to represent the privilege name.
1787 * PARAMS
1788 * lpSystemName [I] Name of the system
1789 * lpName [I] Name of the privilege
1790 * lpLuid [O] Destination for the resulting LUID
1792 * RETURNS
1793 * Success: TRUE. lpLuid contains the requested LUID.
1794 * Failure: FALSE.
1796 BOOL WINAPI
1797 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1799 UNICODE_STRING lpSystemNameW;
1800 UNICODE_STRING lpNameW;
1801 BOOL ret;
1803 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1804 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1805 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1806 RtlFreeUnicodeString(&lpNameW);
1807 RtlFreeUnicodeString(&lpSystemNameW);
1808 return ret;
1811 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1812 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1814 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1815 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1817 return FALSE;
1820 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1821 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1823 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1824 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1826 return FALSE;
1829 /******************************************************************************
1830 * LookupPrivilegeNameA [ADVAPI32.@]
1832 * See LookupPrivilegeNameW.
1834 BOOL WINAPI
1835 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1836 LPDWORD cchName)
1838 UNICODE_STRING lpSystemNameW;
1839 BOOL ret;
1840 DWORD wLen = 0;
1842 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1844 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1845 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1846 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1848 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1850 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1851 &wLen);
1852 if (ret)
1854 /* Windows crashes if cchName is NULL, so will I */
1855 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1856 *cchName, NULL, NULL);
1858 if (len == 0)
1860 /* WideCharToMultiByte failed */
1861 ret = FALSE;
1863 else if (len > *cchName)
1865 *cchName = len;
1866 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1867 ret = FALSE;
1869 else
1871 /* WideCharToMultiByte succeeded, output length needs to be
1872 * length not including NULL terminator
1874 *cchName = len - 1;
1877 HeapFree(GetProcessHeap(), 0, lpNameW);
1879 RtlFreeUnicodeString(&lpSystemNameW);
1880 return ret;
1883 /******************************************************************************
1884 * LookupPrivilegeNameW [ADVAPI32.@]
1886 * Retrieves the privilege name referred to by the LUID lpLuid.
1888 * PARAMS
1889 * lpSystemName [I] Name of the system
1890 * lpLuid [I] Privilege value
1891 * lpName [O] Name of the privilege
1892 * cchName [I/O] Number of characters in lpName.
1894 * RETURNS
1895 * Success: TRUE. lpName contains the name of the privilege whose value is
1896 * *lpLuid.
1897 * Failure: FALSE.
1899 * REMARKS
1900 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1901 * using this function.
1902 * If the length of lpName is too small, on return *cchName will contain the
1903 * number of WCHARs needed to contain the privilege, including the NULL
1904 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1905 * On success, *cchName will contain the number of characters stored in
1906 * lpName, NOT including the NULL terminator.
1908 BOOL WINAPI
1909 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1910 LPDWORD cchName)
1912 size_t privNameLen;
1914 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1916 if (!ADVAPI_IsLocalComputer(lpSystemName))
1918 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1919 return FALSE;
1921 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1922 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1924 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1925 return FALSE;
1927 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1928 /* Windows crashes if cchName is NULL, so will I */
1929 if (*cchName <= privNameLen)
1931 *cchName = privNameLen + 1;
1932 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1933 return FALSE;
1935 else
1937 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1938 *cchName = privNameLen;
1939 return TRUE;
1943 /******************************************************************************
1944 * GetFileSecurityA [ADVAPI32.@]
1946 * Obtains Specified information about the security of a file or directory.
1948 * PARAMS
1949 * lpFileName [I] Name of the file to get info for
1950 * RequestedInformation [I] SE_ flags from "winnt.h"
1951 * pSecurityDescriptor [O] Destination for security information
1952 * nLength [I] Length of pSecurityDescriptor
1953 * lpnLengthNeeded [O] Destination for length of returned security information
1955 * RETURNS
1956 * Success: TRUE. pSecurityDescriptor contains the requested information.
1957 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1959 * NOTES
1960 * The information returned is constrained by the callers access rights and
1961 * privileges.
1963 BOOL WINAPI
1964 GetFileSecurityA( LPCSTR lpFileName,
1965 SECURITY_INFORMATION RequestedInformation,
1966 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1967 DWORD nLength, LPDWORD lpnLengthNeeded )
1969 DWORD len;
1970 BOOL r;
1971 LPWSTR name = NULL;
1973 if( lpFileName )
1975 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1976 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1977 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1980 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1981 nLength, lpnLengthNeeded );
1982 HeapFree( GetProcessHeap(), 0, name );
1984 return r;
1987 /******************************************************************************
1988 * GetFileSecurityW [ADVAPI32.@]
1990 * See GetFileSecurityA.
1992 BOOL WINAPI
1993 GetFileSecurityW( LPCWSTR lpFileName,
1994 SECURITY_INFORMATION RequestedInformation,
1995 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1996 DWORD nLength, LPDWORD lpnLengthNeeded )
1998 HANDLE hfile;
1999 NTSTATUS status;
2000 DWORD access = 0;
2002 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2003 RequestedInformation, pSecurityDescriptor,
2004 nLength, lpnLengthNeeded);
2006 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2007 DACL_SECURITY_INFORMATION))
2008 access |= READ_CONTROL;
2009 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2010 access |= ACCESS_SYSTEM_SECURITY;
2012 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2013 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2014 if ( hfile == INVALID_HANDLE_VALUE )
2015 return FALSE;
2017 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2018 nLength, lpnLengthNeeded );
2019 CloseHandle( hfile );
2020 return set_ntstatus( status );
2024 /******************************************************************************
2025 * LookupAccountSidA [ADVAPI32.@]
2027 BOOL WINAPI
2028 LookupAccountSidA(
2029 IN LPCSTR system,
2030 IN PSID sid,
2031 OUT LPSTR account,
2032 IN OUT LPDWORD accountSize,
2033 OUT LPSTR domain,
2034 IN OUT LPDWORD domainSize,
2035 OUT PSID_NAME_USE name_use )
2037 DWORD len;
2038 BOOL r;
2039 LPWSTR systemW = NULL;
2040 LPWSTR accountW = NULL;
2041 LPWSTR domainW = NULL;
2042 DWORD accountSizeW = *accountSize;
2043 DWORD domainSizeW = *domainSize;
2045 if (system) {
2046 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2047 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2048 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2050 if (account)
2051 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2052 if (domain)
2053 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2055 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2057 if (r) {
2058 if (accountW && *accountSize) {
2059 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2060 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2061 *accountSize = len;
2062 } else
2063 *accountSize = accountSizeW + 1;
2065 if (domainW && *domainSize) {
2066 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2067 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2068 *domainSize = len;
2069 } else
2070 *domainSize = domainSizeW + 1;
2072 else
2074 *accountSize = accountSizeW + 1;
2075 *domainSize = domainSizeW + 1;
2078 HeapFree( GetProcessHeap(), 0, systemW );
2079 HeapFree( GetProcessHeap(), 0, accountW );
2080 HeapFree( GetProcessHeap(), 0, domainW );
2082 return r;
2085 /******************************************************************************
2086 * LookupAccountSidW [ADVAPI32.@]
2088 * PARAMS
2089 * system []
2090 * sid []
2091 * account []
2092 * accountSize []
2093 * domain []
2094 * domainSize []
2095 * name_use []
2098 BOOL WINAPI
2099 LookupAccountSidW(
2100 IN LPCWSTR system,
2101 IN PSID sid,
2102 OUT LPWSTR account,
2103 IN OUT LPDWORD accountSize,
2104 OUT LPWSTR domain,
2105 IN OUT LPDWORD domainSize,
2106 OUT PSID_NAME_USE name_use )
2108 unsigned int i, j;
2109 const WCHAR * ac = NULL;
2110 const WCHAR * dm = NULL;
2111 SID_NAME_USE use = 0;
2112 LPWSTR computer_name = NULL;
2113 LPWSTR account_name = NULL;
2115 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2116 debugstr_w(system),debugstr_sid(sid),
2117 account,accountSize,accountSize?*accountSize:0,
2118 domain,domainSize,domainSize?*domainSize:0,
2119 name_use);
2121 if (!ADVAPI_IsLocalComputer(system)) {
2122 FIXME("Only local computer supported!\n");
2123 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2124 return FALSE;
2127 /* check the well known SIDs first */
2128 for (i = 0; i <= 60; i++) {
2129 if (IsWellKnownSid(sid, i)) {
2130 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2131 if (ACCOUNT_SIDS[j].type == i) {
2132 ac = ACCOUNT_SIDS[j].account;
2133 dm = ACCOUNT_SIDS[j].domain;
2134 use = ACCOUNT_SIDS[j].name_use;
2137 break;
2141 if (dm == NULL) {
2142 MAX_SID local;
2144 /* check for the local computer next */
2145 if (ADVAPI_GetComputerSid(&local)) {
2146 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2147 BOOL result;
2149 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2150 result = GetComputerNameW(computer_name, &size);
2152 if (result) {
2153 if (EqualSid(sid, &local)) {
2154 dm = computer_name;
2155 ac = Blank;
2156 use = 3;
2157 } else {
2158 local.SubAuthorityCount++;
2160 if (EqualPrefixSid(sid, &local)) {
2161 dm = computer_name;
2162 use = 1;
2163 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2164 case DOMAIN_USER_RID_ADMIN:
2165 ac = Administrator;
2166 break;
2167 case DOMAIN_USER_RID_GUEST:
2168 ac = Guest;
2169 break;
2170 case DOMAIN_GROUP_RID_ADMINS:
2171 ac = Domain_Admins;
2172 break;
2173 case DOMAIN_GROUP_RID_USERS:
2174 ac = Domain_Users;
2175 break;
2176 case DOMAIN_GROUP_RID_GUESTS:
2177 ac = Domain_Guests;
2178 break;
2179 case DOMAIN_GROUP_RID_COMPUTERS:
2180 ac = Domain_Computers;
2181 break;
2182 case DOMAIN_GROUP_RID_CONTROLLERS:
2183 ac = Domain_Controllers;
2184 break;
2185 case DOMAIN_GROUP_RID_CERT_ADMINS:
2186 ac = Cert_Publishers;
2187 break;
2188 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2189 ac = Schema_Admins;
2190 break;
2191 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2192 ac = Enterprise_Admins;
2193 break;
2194 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2195 ac = Group_Policy_Creator_Owners;
2196 break;
2197 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2198 ac = RAS_and_IAS_Servers;
2199 break;
2200 case 1000: /* first user account */
2201 size = UNLEN + 1;
2202 account_name = HeapAlloc(
2203 GetProcessHeap(), 0, size * sizeof(WCHAR));
2204 if (GetUserNameW(account_name, &size))
2205 ac = account_name;
2206 else
2207 dm = NULL;
2209 break;
2210 default:
2211 dm = NULL;
2212 break;
2220 if (dm) {
2221 DWORD ac_len = lstrlenW(ac);
2222 DWORD dm_len = lstrlenW(dm);
2223 BOOL status = TRUE;
2225 if (*accountSize > ac_len) {
2226 if (account)
2227 lstrcpyW(account, ac);
2229 if (*domainSize > dm_len) {
2230 if (domain)
2231 lstrcpyW(domain, dm);
2233 if ((*accountSize && *accountSize < ac_len) ||
2234 (!account && !*accountSize && ac_len) ||
2235 (*domainSize && *domainSize < dm_len) ||
2236 (!domain && !*domainSize && dm_len))
2238 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2239 status = FALSE;
2241 if (*domainSize)
2242 *domainSize = dm_len;
2243 else
2244 *domainSize = dm_len + 1;
2245 if (*accountSize)
2246 *accountSize = ac_len;
2247 else
2248 *accountSize = ac_len + 1;
2250 HeapFree(GetProcessHeap(), 0, account_name);
2251 HeapFree(GetProcessHeap(), 0, computer_name);
2252 if (status) *name_use = use;
2253 return status;
2256 HeapFree(GetProcessHeap(), 0, account_name);
2257 HeapFree(GetProcessHeap(), 0, computer_name);
2258 SetLastError(ERROR_NONE_MAPPED);
2259 return FALSE;
2262 /******************************************************************************
2263 * SetFileSecurityA [ADVAPI32.@]
2265 * See SetFileSecurityW.
2267 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2268 SECURITY_INFORMATION RequestedInformation,
2269 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2271 DWORD len;
2272 BOOL r;
2273 LPWSTR name = NULL;
2275 if( lpFileName )
2277 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2278 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2279 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2282 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2283 HeapFree( GetProcessHeap(), 0, name );
2285 return r;
2288 /******************************************************************************
2289 * SetFileSecurityW [ADVAPI32.@]
2291 * Sets the security of a file or directory.
2293 * PARAMS
2294 * lpFileName []
2295 * RequestedInformation []
2296 * pSecurityDescriptor []
2298 * RETURNS
2299 * Success: TRUE.
2300 * Failure: FALSE.
2302 BOOL WINAPI
2303 SetFileSecurityW( LPCWSTR lpFileName,
2304 SECURITY_INFORMATION RequestedInformation,
2305 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2307 HANDLE file;
2308 DWORD access = 0;
2309 NTSTATUS status;
2311 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2312 pSecurityDescriptor );
2314 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2315 RequestedInformation & GROUP_SECURITY_INFORMATION)
2316 access |= WRITE_OWNER;
2317 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2318 access |= ACCESS_SYSTEM_SECURITY;
2319 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2320 access |= WRITE_DAC;
2322 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2323 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2324 if (file == INVALID_HANDLE_VALUE)
2325 return FALSE;
2327 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2328 CloseHandle( file );
2329 return set_ntstatus( status );
2332 /******************************************************************************
2333 * QueryWindows31FilesMigration [ADVAPI32.@]
2335 * PARAMS
2336 * x1 []
2338 BOOL WINAPI
2339 QueryWindows31FilesMigration( DWORD x1 )
2341 FIXME("(%d):stub\n",x1);
2342 return TRUE;
2345 /******************************************************************************
2346 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2348 * PARAMS
2349 * x1 []
2350 * x2 []
2351 * x3 []
2352 * x4 []
2354 BOOL WINAPI
2355 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2356 DWORD x4 )
2358 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2359 return TRUE;
2362 /******************************************************************************
2363 * NotifyBootConfigStatus [ADVAPI32.@]
2365 * PARAMS
2366 * x1 []
2368 BOOL WINAPI
2369 NotifyBootConfigStatus( BOOL x1 )
2371 FIXME("(0x%08d):stub\n",x1);
2372 return 1;
2375 /******************************************************************************
2376 * RevertToSelf [ADVAPI32.@]
2378 * Ends the impersonation of a user.
2380 * PARAMS
2381 * void []
2383 * RETURNS
2384 * Success: TRUE.
2385 * Failure: FALSE.
2387 BOOL WINAPI
2388 RevertToSelf( void )
2390 HANDLE Token = NULL;
2391 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2392 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2395 /******************************************************************************
2396 * ImpersonateSelf [ADVAPI32.@]
2398 * Makes an impersonation token that represents the process user and assigns
2399 * to the current thread.
2401 * PARAMS
2402 * ImpersonationLevel [I] Level at which to impersonate.
2404 * RETURNS
2405 * Success: TRUE.
2406 * Failure: FALSE.
2408 BOOL WINAPI
2409 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2411 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2414 /******************************************************************************
2415 * ImpersonateLoggedOnUser [ADVAPI32.@]
2417 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2419 DWORD size;
2420 NTSTATUS Status;
2421 HANDLE ImpersonationToken;
2422 TOKEN_TYPE Type;
2423 static BOOL warn = TRUE;
2425 if (warn)
2427 FIXME( "(%p)\n", hToken );
2428 warn = FALSE;
2430 if (!GetTokenInformation( hToken, TokenType, &Type,
2431 sizeof(TOKEN_TYPE), &size ))
2432 return FALSE;
2434 if (Type == TokenPrimary)
2436 OBJECT_ATTRIBUTES ObjectAttributes;
2438 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2440 Status = NtDuplicateToken( hToken,
2441 TOKEN_IMPERSONATE | TOKEN_QUERY,
2442 &ObjectAttributes,
2443 SecurityImpersonation,
2444 TokenImpersonation,
2445 &ImpersonationToken );
2446 if (Status != STATUS_SUCCESS)
2448 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2449 SetLastError( RtlNtStatusToDosError( Status ) );
2450 return FALSE;
2453 else
2454 ImpersonationToken = hToken;
2456 Status = NtSetInformationThread( GetCurrentThread(),
2457 ThreadImpersonationToken,
2458 &ImpersonationToken,
2459 sizeof(ImpersonationToken) );
2461 if (Type == TokenPrimary)
2462 NtClose( ImpersonationToken );
2464 if (Status != STATUS_SUCCESS)
2466 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2467 SetLastError( RtlNtStatusToDosError( Status ) );
2468 return FALSE;
2471 return TRUE;
2474 /******************************************************************************
2475 * AccessCheck [ADVAPI32.@]
2477 BOOL WINAPI
2478 AccessCheck(
2479 PSECURITY_DESCRIPTOR SecurityDescriptor,
2480 HANDLE ClientToken,
2481 DWORD DesiredAccess,
2482 PGENERIC_MAPPING GenericMapping,
2483 PPRIVILEGE_SET PrivilegeSet,
2484 LPDWORD PrivilegeSetLength,
2485 LPDWORD GrantedAccess,
2486 LPBOOL AccessStatus)
2488 NTSTATUS access_status;
2489 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2490 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2491 GrantedAccess, &access_status) );
2492 if (ret) *AccessStatus = set_ntstatus( access_status );
2493 return ret;
2497 /******************************************************************************
2498 * AccessCheckByType [ADVAPI32.@]
2500 BOOL WINAPI AccessCheckByType(
2501 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2502 PSID PrincipalSelfSid,
2503 HANDLE ClientToken,
2504 DWORD DesiredAccess,
2505 POBJECT_TYPE_LIST ObjectTypeList,
2506 DWORD ObjectTypeListLength,
2507 PGENERIC_MAPPING GenericMapping,
2508 PPRIVILEGE_SET PrivilegeSet,
2509 LPDWORD PrivilegeSetLength,
2510 LPDWORD GrantedAccess,
2511 LPBOOL AccessStatus)
2513 FIXME("stub\n");
2515 *AccessStatus = TRUE;
2517 return !*AccessStatus;
2520 /******************************************************************************
2521 * MapGenericMask [ADVAPI32.@]
2523 * Maps generic access rights into specific access rights according to the
2524 * supplied mapping.
2526 * PARAMS
2527 * AccessMask [I/O] Access rights.
2528 * GenericMapping [I] The mapping between generic and specific rights.
2530 * RETURNS
2531 * Nothing.
2533 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2535 RtlMapGenericMask( AccessMask, GenericMapping );
2538 /*************************************************************************
2539 * SetKernelObjectSecurity [ADVAPI32.@]
2541 BOOL WINAPI SetKernelObjectSecurity (
2542 IN HANDLE Handle,
2543 IN SECURITY_INFORMATION SecurityInformation,
2544 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2546 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2550 /******************************************************************************
2551 * AddAuditAccessAce [ADVAPI32.@]
2553 BOOL WINAPI AddAuditAccessAce(
2554 IN OUT PACL pAcl,
2555 IN DWORD dwAceRevision,
2556 IN DWORD dwAccessMask,
2557 IN PSID pSid,
2558 IN BOOL bAuditSuccess,
2559 IN BOOL bAuditFailure)
2561 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2562 bAuditSuccess, bAuditFailure) );
2565 /******************************************************************************
2566 * AddAuditAccessAce [ADVAPI32.@]
2568 BOOL WINAPI AddAuditAccessAceEx(
2569 IN OUT PACL pAcl,
2570 IN DWORD dwAceRevision,
2571 IN DWORD dwAceFlags,
2572 IN DWORD dwAccessMask,
2573 IN PSID pSid,
2574 IN BOOL bAuditSuccess,
2575 IN BOOL bAuditFailure)
2577 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2578 bAuditSuccess, bAuditFailure) );
2581 /******************************************************************************
2582 * LookupAccountNameA [ADVAPI32.@]
2584 BOOL WINAPI
2585 LookupAccountNameA(
2586 IN LPCSTR system,
2587 IN LPCSTR account,
2588 OUT PSID sid,
2589 OUT LPDWORD cbSid,
2590 LPSTR ReferencedDomainName,
2591 IN OUT LPDWORD cbReferencedDomainName,
2592 OUT PSID_NAME_USE name_use )
2594 BOOL ret;
2595 UNICODE_STRING lpSystemW;
2596 UNICODE_STRING lpAccountW;
2597 LPWSTR lpReferencedDomainNameW = NULL;
2599 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2600 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2602 if (ReferencedDomainName)
2603 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2605 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2606 cbReferencedDomainName, name_use);
2608 if (ret && lpReferencedDomainNameW)
2610 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2611 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2614 RtlFreeUnicodeString(&lpSystemW);
2615 RtlFreeUnicodeString(&lpAccountW);
2616 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2618 return ret;
2621 /******************************************************************************
2622 * lookup_user_account_name
2624 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2625 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2627 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2628 DWORD len = sizeof(buffer);
2629 HANDLE token;
2630 BOOL ret;
2631 PSID pSid;
2632 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2633 DWORD nameLen;
2635 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2637 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2638 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2641 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2642 CloseHandle( token );
2644 if (!ret) return FALSE;
2646 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2648 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2649 CopySid(*cbSid, Sid, pSid);
2650 if (*cbSid < GetLengthSid(pSid))
2652 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2653 ret = FALSE;
2655 *cbSid = GetLengthSid(pSid);
2657 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2658 if (!GetComputerNameW(domainName, &nameLen))
2660 domainName[0] = 0;
2661 nameLen = 0;
2663 if (*cchReferencedDomainName <= nameLen || !ret)
2665 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2666 nameLen += 1;
2667 ret = FALSE;
2669 else if (ReferencedDomainName)
2670 strcpyW(ReferencedDomainName, domainName);
2672 *cchReferencedDomainName = nameLen;
2674 if (ret)
2675 *peUse = SidTypeUser;
2677 return ret;
2680 /******************************************************************************
2681 * lookup_computer_account_name
2683 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2684 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2686 MAX_SID local;
2687 BOOL ret;
2688 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2689 DWORD nameLen;
2691 if ((ret = ADVAPI_GetComputerSid(&local)))
2693 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2694 CopySid(*cbSid, Sid, &local);
2695 if (*cbSid < GetLengthSid(&local))
2697 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2698 ret = FALSE;
2700 *cbSid = GetLengthSid(&local);
2703 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2704 if (!GetComputerNameW(domainName, &nameLen))
2706 domainName[0] = 0;
2707 nameLen = 0;
2709 if (*cchReferencedDomainName <= nameLen || !ret)
2711 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2712 nameLen += 1;
2713 ret = FALSE;
2715 else if (ReferencedDomainName)
2716 strcpyW(ReferencedDomainName, domainName);
2718 *cchReferencedDomainName = nameLen;
2720 if (ret)
2721 *peUse = SidTypeDomain;
2723 return ret;
2726 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2727 LSA_UNICODE_STRING *domain )
2729 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2731 while (p > str->Buffer && *p != '\\') p--;
2733 if (*p == '\\')
2735 domain->Buffer = str->Buffer;
2736 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2738 account->Buffer = p + 1;
2739 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2741 else
2743 domain->Buffer = NULL;
2744 domain->Length = 0;
2746 account->Buffer = str->Buffer;
2747 account->Length = str->Length;
2751 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2753 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2755 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2756 return TRUE;
2758 return FALSE;
2761 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2763 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2765 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2766 return TRUE;
2768 if (ACCOUNT_SIDS[idx].alias)
2770 len = strlenW( ACCOUNT_SIDS[idx].alias );
2771 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2772 return TRUE;
2774 return FALSE;
2778 * Helper function for LookupAccountNameW
2780 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2781 PSID Sid, LPDWORD cbSid,
2782 LPWSTR ReferencedDomainName,
2783 LPDWORD cchReferencedDomainName,
2784 PSID_NAME_USE peUse, BOOL *handled )
2786 PSID pSid;
2787 LSA_UNICODE_STRING account, domain;
2788 BOOL ret = TRUE;
2789 ULONG i;
2791 *handled = FALSE;
2792 split_domain_account( account_and_domain, &account, &domain );
2794 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2796 /* check domain first */
2797 if (domain.Buffer && !match_domain( i, &domain )) continue;
2799 if (match_account( i, &account ))
2801 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2803 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2805 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2807 if (*cbSid < sidLen)
2809 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2810 ret = FALSE;
2812 else if (Sid)
2814 CopySid(*cbSid, Sid, pSid);
2816 *cbSid = sidLen;
2819 len = strlenW( ACCOUNT_SIDS[i].domain );
2820 if (*cchReferencedDomainName <= len || !ret)
2822 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2823 len++;
2824 ret = FALSE;
2826 else if (ReferencedDomainName)
2828 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2831 *cchReferencedDomainName = len;
2832 if (ret)
2833 *peUse = ACCOUNT_SIDS[i].name_use;
2835 HeapFree(GetProcessHeap(), 0, pSid);
2836 *handled = TRUE;
2837 return ret;
2840 return ret;
2843 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2844 PSID Sid, LPDWORD cbSid,
2845 LPWSTR ReferencedDomainName,
2846 LPDWORD cchReferencedDomainName,
2847 PSID_NAME_USE peUse, BOOL *handled )
2849 DWORD nameLen;
2850 LPWSTR userName = NULL;
2851 LSA_UNICODE_STRING account, domain;
2852 BOOL ret = TRUE;
2854 *handled = FALSE;
2855 split_domain_account( account_and_domain, &account, &domain );
2857 /* Let the current Unix user id masquerade as first Windows user account */
2859 nameLen = UNLEN + 1;
2860 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2862 if (domain.Buffer)
2864 /* check to make sure this account is on this computer */
2865 if (GetComputerNameW( userName, &nameLen ) &&
2866 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2868 SetLastError(ERROR_NONE_MAPPED);
2869 ret = FALSE;
2871 nameLen = UNLEN + 1;
2874 if (GetUserNameW( userName, &nameLen ) &&
2875 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2877 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2878 *handled = TRUE;
2880 else
2882 nameLen = UNLEN + 1;
2883 if (GetComputerNameW( userName, &nameLen ) &&
2884 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2886 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2887 *handled = TRUE;
2891 HeapFree(GetProcessHeap(), 0, userName);
2892 return ret;
2895 /******************************************************************************
2896 * LookupAccountNameW [ADVAPI32.@]
2898 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2899 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2900 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2902 BOOL ret, handled;
2903 LSA_UNICODE_STRING account;
2905 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2906 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2908 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2910 FIXME("remote computer not supported\n");
2911 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2912 return FALSE;
2915 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2917 lpAccountName = BUILTIN;
2920 RtlInitUnicodeString( &account, lpAccountName );
2922 /* Check well known SIDs first */
2923 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2924 cchReferencedDomainName, peUse, &handled );
2925 if (handled)
2926 return ret;
2928 /* Check user names */
2929 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2930 cchReferencedDomainName, peUse, &handled);
2931 if (handled)
2932 return ret;
2934 SetLastError( ERROR_NONE_MAPPED );
2935 return FALSE;
2938 /******************************************************************************
2939 * PrivilegeCheck [ADVAPI32.@]
2941 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2943 BOOL ret;
2944 BOOLEAN Result;
2946 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2948 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2949 if (ret)
2950 *pfResult = Result;
2951 return ret;
2954 /******************************************************************************
2955 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2957 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2958 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2959 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2960 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2962 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2963 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2964 SecurityDescriptor, DesiredAccess, GenericMapping,
2965 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2966 return TRUE;
2969 /******************************************************************************
2970 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2972 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2973 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2974 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2975 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2977 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2978 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2979 SecurityDescriptor, DesiredAccess, GenericMapping,
2980 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2981 return TRUE;
2984 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2986 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2988 return TRUE;
2991 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2993 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2995 return TRUE;
2998 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3000 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3002 return TRUE;
3005 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3006 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3007 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3008 LPBOOL GenerateOnClose)
3010 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3011 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3012 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3013 GenerateOnClose);
3015 return TRUE;
3018 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3019 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3020 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3021 LPBOOL GenerateOnClose)
3023 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3024 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3025 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3026 GenerateOnClose);
3028 return TRUE;
3031 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3032 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3034 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3035 DesiredAccess, Privileges, AccessGranted);
3037 return TRUE;
3040 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3041 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3043 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3044 DesiredAccess, Privileges, AccessGranted);
3046 return TRUE;
3049 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3050 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3052 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3053 ClientToken, Privileges, AccessGranted);
3055 return TRUE;
3058 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3059 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3061 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3062 ClientToken, Privileges, AccessGranted);
3064 return TRUE;
3067 /******************************************************************************
3068 * GetSecurityInfo [ADVAPI32.@]
3070 * Retrieves a copy of the security descriptor associated with an object.
3072 * PARAMS
3073 * hObject [I] A handle for the object.
3074 * ObjectType [I] The type of object.
3075 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3076 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3077 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3078 * ppDacl [O] If non-null, receives a pointer to the DACL.
3079 * ppSacl [O] If non-null, receives a pointer to the SACL.
3080 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3081 * which must be freed with LocalFree.
3083 * RETURNS
3084 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3086 DWORD WINAPI GetSecurityInfo(
3087 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3088 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3089 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3090 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3093 PSECURITY_DESCRIPTOR sd;
3094 NTSTATUS status;
3095 ULONG n1, n2;
3096 BOOL present, defaulted;
3098 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3099 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3100 return RtlNtStatusToDosError(status);
3102 sd = LocalAlloc(0, n1);
3103 if (!sd)
3104 return ERROR_NOT_ENOUGH_MEMORY;
3106 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3107 if (status != STATUS_SUCCESS)
3109 LocalFree(sd);
3110 return RtlNtStatusToDosError(status);
3113 if (ppsidOwner)
3115 *ppsidOwner = NULL;
3116 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3118 if (ppsidGroup)
3120 *ppsidGroup = NULL;
3121 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3123 if (ppDacl)
3125 *ppDacl = NULL;
3126 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3128 if (ppSacl)
3130 *ppSacl = NULL;
3131 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3133 if (ppSecurityDescriptor)
3134 *ppSecurityDescriptor = sd;
3136 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3137 * NULL, because native happily returns the SIDs and ACLs that are requested
3138 * in this case.
3141 return ERROR_SUCCESS;
3144 /******************************************************************************
3145 * GetSecurityInfoExA [ADVAPI32.@]
3147 DWORD WINAPI GetSecurityInfoExA(
3148 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3149 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3150 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3151 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3154 FIXME("stub!\n");
3155 return ERROR_BAD_PROVIDER;
3158 /******************************************************************************
3159 * GetSecurityInfoExW [ADVAPI32.@]
3161 DWORD WINAPI GetSecurityInfoExW(
3162 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3163 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3164 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3165 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3168 FIXME("stub!\n");
3169 return ERROR_BAD_PROVIDER;
3172 /******************************************************************************
3173 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3175 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3176 LPSTR pTrusteeName, DWORD AccessPermissions,
3177 ACCESS_MODE AccessMode, DWORD Inheritance )
3179 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3180 AccessPermissions, AccessMode, Inheritance);
3182 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3183 pExplicitAccess->grfAccessMode = AccessMode;
3184 pExplicitAccess->grfInheritance = Inheritance;
3186 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3187 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3188 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3189 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3190 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3193 /******************************************************************************
3194 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3196 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3197 LPWSTR pTrusteeName, DWORD AccessPermissions,
3198 ACCESS_MODE AccessMode, DWORD Inheritance )
3200 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3201 AccessPermissions, AccessMode, Inheritance);
3203 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3204 pExplicitAccess->grfAccessMode = AccessMode;
3205 pExplicitAccess->grfInheritance = Inheritance;
3207 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3208 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3209 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3210 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3211 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3214 /******************************************************************************
3215 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3217 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3218 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3219 LPSTR InheritedObjectTypeName, LPSTR Name )
3221 DWORD ObjectsPresent = 0;
3223 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3224 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3226 /* Fill the OBJECTS_AND_NAME structure */
3227 pObjName->ObjectType = ObjectType;
3228 if (ObjectTypeName != NULL)
3230 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3233 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3234 if (InheritedObjectTypeName != NULL)
3236 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3239 pObjName->ObjectsPresent = ObjectsPresent;
3240 pObjName->ptstrName = Name;
3242 /* Fill the TRUSTEE structure */
3243 pTrustee->pMultipleTrustee = NULL;
3244 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3245 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3246 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3247 pTrustee->ptstrName = (LPSTR)pObjName;
3250 /******************************************************************************
3251 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3253 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3254 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3255 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3257 DWORD ObjectsPresent = 0;
3259 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3260 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3262 /* Fill the OBJECTS_AND_NAME structure */
3263 pObjName->ObjectType = ObjectType;
3264 if (ObjectTypeName != NULL)
3266 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3269 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3270 if (InheritedObjectTypeName != NULL)
3272 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3275 pObjName->ObjectsPresent = ObjectsPresent;
3276 pObjName->ptstrName = Name;
3278 /* Fill the TRUSTEE structure */
3279 pTrustee->pMultipleTrustee = NULL;
3280 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3281 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3282 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3283 pTrustee->ptstrName = (LPWSTR)pObjName;
3286 /******************************************************************************
3287 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3289 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3290 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3292 DWORD ObjectsPresent = 0;
3294 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3296 /* Fill the OBJECTS_AND_SID structure */
3297 if (pObjectGuid != NULL)
3299 pObjSid->ObjectTypeGuid = *pObjectGuid;
3300 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3302 else
3304 ZeroMemory(&pObjSid->ObjectTypeGuid,
3305 sizeof(GUID));
3308 if (pInheritedObjectGuid != NULL)
3310 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3311 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3313 else
3315 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3316 sizeof(GUID));
3319 pObjSid->ObjectsPresent = ObjectsPresent;
3320 pObjSid->pSid = pSid;
3322 /* Fill the TRUSTEE structure */
3323 pTrustee->pMultipleTrustee = NULL;
3324 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3325 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3326 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3327 pTrustee->ptstrName = (LPSTR) pObjSid;
3330 /******************************************************************************
3331 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3333 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3334 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3336 DWORD ObjectsPresent = 0;
3338 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3340 /* Fill the OBJECTS_AND_SID structure */
3341 if (pObjectGuid != NULL)
3343 pObjSid->ObjectTypeGuid = *pObjectGuid;
3344 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3346 else
3348 ZeroMemory(&pObjSid->ObjectTypeGuid,
3349 sizeof(GUID));
3352 if (pInheritedObjectGuid != NULL)
3354 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3355 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3357 else
3359 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3360 sizeof(GUID));
3363 pObjSid->ObjectsPresent = ObjectsPresent;
3364 pObjSid->pSid = pSid;
3366 /* Fill the TRUSTEE structure */
3367 pTrustee->pMultipleTrustee = NULL;
3368 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3369 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3370 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3371 pTrustee->ptstrName = (LPWSTR) pObjSid;
3374 /******************************************************************************
3375 * BuildTrusteeWithSidA [ADVAPI32.@]
3377 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3379 TRACE("%p %p\n", pTrustee, pSid);
3381 pTrustee->pMultipleTrustee = NULL;
3382 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3383 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3384 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3385 pTrustee->ptstrName = pSid;
3388 /******************************************************************************
3389 * BuildTrusteeWithSidW [ADVAPI32.@]
3391 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3393 TRACE("%p %p\n", pTrustee, pSid);
3395 pTrustee->pMultipleTrustee = NULL;
3396 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3397 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3398 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3399 pTrustee->ptstrName = pSid;
3402 /******************************************************************************
3403 * BuildTrusteeWithNameA [ADVAPI32.@]
3405 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3407 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3409 pTrustee->pMultipleTrustee = NULL;
3410 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3411 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3412 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3413 pTrustee->ptstrName = name;
3416 /******************************************************************************
3417 * BuildTrusteeWithNameW [ADVAPI32.@]
3419 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3421 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3423 pTrustee->pMultipleTrustee = NULL;
3424 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3425 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3426 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3427 pTrustee->ptstrName = name;
3430 /******************************************************************************
3431 * GetTrusteeFormA [ADVAPI32.@]
3433 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3435 TRACE("(%p)\n", pTrustee);
3437 if (!pTrustee)
3438 return TRUSTEE_BAD_FORM;
3440 return pTrustee->TrusteeForm;
3443 /******************************************************************************
3444 * GetTrusteeFormW [ADVAPI32.@]
3446 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3448 TRACE("(%p)\n", pTrustee);
3450 if (!pTrustee)
3451 return TRUSTEE_BAD_FORM;
3453 return pTrustee->TrusteeForm;
3456 /******************************************************************************
3457 * GetTrusteeNameA [ADVAPI32.@]
3459 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3461 TRACE("(%p)\n", pTrustee);
3463 if (!pTrustee)
3464 return NULL;
3466 return pTrustee->ptstrName;
3469 /******************************************************************************
3470 * GetTrusteeNameW [ADVAPI32.@]
3472 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3474 TRACE("(%p)\n", pTrustee);
3476 if (!pTrustee)
3477 return NULL;
3479 return pTrustee->ptstrName;
3482 /******************************************************************************
3483 * GetTrusteeTypeA [ADVAPI32.@]
3485 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3487 TRACE("(%p)\n", pTrustee);
3489 if (!pTrustee)
3490 return TRUSTEE_IS_UNKNOWN;
3492 return pTrustee->TrusteeType;
3495 /******************************************************************************
3496 * GetTrusteeTypeW [ADVAPI32.@]
3498 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3500 TRACE("(%p)\n", pTrustee);
3502 if (!pTrustee)
3503 return TRUSTEE_IS_UNKNOWN;
3505 return pTrustee->TrusteeType;
3508 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3509 DWORD nAclInformationLength,
3510 ACL_INFORMATION_CLASS dwAclInformationClass )
3512 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3513 nAclInformationLength, dwAclInformationClass);
3515 return TRUE;
3518 DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3520 DWORD len;
3522 switch (form)
3524 case TRUSTEE_IS_NAME:
3526 WCHAR *wstr = NULL;
3528 if (trustee_nameA)
3530 len = MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, NULL, 0 );
3531 if (!(wstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3532 return ERROR_NOT_ENOUGH_MEMORY;
3534 MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, wstr, len );
3537 *ptrustee_nameW = wstr;
3538 return ERROR_SUCCESS;
3540 case TRUSTEE_IS_OBJECTS_AND_NAME:
3542 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3543 OBJECTS_AND_NAME_W *objW = NULL;
3545 if (objA)
3547 if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3548 return ERROR_NOT_ENOUGH_MEMORY;
3550 objW->ObjectsPresent = objA->ObjectsPresent;
3551 objW->ObjectType = objA->ObjectType;
3552 objW->ObjectTypeName = NULL;
3553 objW->InheritedObjectTypeName = NULL;
3554 objW->ptstrName = NULL;
3556 if (objA->ObjectTypeName)
3558 len = MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, NULL, 0 );
3559 if (!(objW->ObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3560 goto error;
3561 MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, objW->ObjectTypeName, len );
3564 if (objA->InheritedObjectTypeName)
3566 len = MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, NULL, 0 );
3567 if (!(objW->InheritedObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3568 goto error;
3569 MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, objW->InheritedObjectTypeName, len );
3572 if (objA->ptstrName)
3574 len = MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, NULL, 0 );
3575 if (!(objW->ptstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3576 goto error;
3577 MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, objW->ptstrName, len );
3581 *ptrustee_nameW = (WCHAR *)objW;
3582 return ERROR_SUCCESS;
3583 error:
3584 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3585 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3586 HeapFree( GetProcessHeap(), 0, objW );
3587 return ERROR_NOT_ENOUGH_MEMORY;
3589 /* These forms do not require conversion. */
3590 case TRUSTEE_IS_SID:
3591 case TRUSTEE_IS_OBJECTS_AND_SID:
3592 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3593 return ERROR_SUCCESS;
3594 default:
3595 return ERROR_INVALID_PARAMETER;
3599 void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3601 switch (form)
3603 case TRUSTEE_IS_NAME:
3604 HeapFree( GetProcessHeap(), 0, trustee_nameW );
3605 break;
3606 case TRUSTEE_IS_OBJECTS_AND_NAME:
3608 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3610 if (objW)
3612 HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3613 HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3614 HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3615 HeapFree( GetProcessHeap(), 0, objW );
3618 break;
3620 /* Other forms did not require allocation, so no freeing is necessary. */
3621 default:
3622 break;
3626 /******************************************************************************
3627 * SetEntriesInAclA [ADVAPI32.@]
3629 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3630 PACL OldAcl, PACL* NewAcl )
3632 DWORD err = ERROR_SUCCESS;
3633 EXPLICIT_ACCESSW *pEntriesW;
3634 int alloc_index, free_index;
3636 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3638 if (NewAcl)
3639 *NewAcl = NULL;
3641 if (!count && !OldAcl)
3642 return ERROR_SUCCESS;
3644 pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3645 if (!pEntriesW)
3646 return ERROR_NOT_ENOUGH_MEMORY;
3648 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3650 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3651 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3652 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3653 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3654 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3655 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3656 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3658 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3659 pEntries[alloc_index].Trustee.ptstrName,
3660 &pEntriesW[alloc_index].Trustee.ptstrName );
3661 if (err != ERROR_SUCCESS)
3663 if (err == ERROR_INVALID_PARAMETER)
3664 WARN("bad trustee form %d for trustee %d\n",
3665 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3667 goto cleanup;
3671 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3673 cleanup:
3674 /* Free any previously allocated trustee name buffers, taking into account
3675 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3676 * list. */
3677 for (free_index = 0; free_index < alloc_index; ++free_index)
3678 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3680 HeapFree( GetProcessHeap(), 0, pEntriesW );
3681 return err;
3684 /******************************************************************************
3685 * SetEntriesInAclW [ADVAPI32.@]
3687 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3688 PACL OldAcl, PACL* NewAcl )
3690 ULONG i;
3691 PSID *ppsid;
3692 DWORD ret = ERROR_SUCCESS;
3693 DWORD acl_size = sizeof(ACL);
3694 NTSTATUS status;
3696 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3698 if (NewAcl)
3699 *NewAcl = NULL;
3701 if (!count && !OldAcl)
3702 return ERROR_SUCCESS;
3704 /* allocate array of maximum sized sids allowed */
3705 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3706 if (!ppsid)
3707 return ERROR_OUTOFMEMORY;
3709 for (i = 0; i < count; i++)
3711 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3713 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3714 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3715 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3716 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3717 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3718 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3719 pEntries[i].Trustee.ptstrName);
3721 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3723 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3724 ret = ERROR_INVALID_PARAMETER;
3725 goto exit;
3728 switch (pEntries[i].Trustee.TrusteeForm)
3730 case TRUSTEE_IS_SID:
3731 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3732 ppsid[i], pEntries[i].Trustee.ptstrName))
3734 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3735 ret = ERROR_INVALID_PARAMETER;
3736 goto exit;
3738 break;
3739 case TRUSTEE_IS_NAME:
3741 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3742 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3743 SID_NAME_USE use;
3744 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3746 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3748 ret = GetLastError();
3749 goto exit;
3752 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3754 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3755 ret = ERROR_INVALID_PARAMETER;
3756 goto exit;
3758 break;
3760 case TRUSTEE_IS_OBJECTS_AND_SID:
3761 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3762 break;
3763 case TRUSTEE_IS_OBJECTS_AND_NAME:
3764 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3765 break;
3766 default:
3767 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3768 ret = ERROR_INVALID_PARAMETER;
3769 goto exit;
3772 /* Note: we overestimate the ACL size here as a tradeoff between
3773 * instructions (simplicity) and memory */
3774 switch (pEntries[i].grfAccessMode)
3776 case GRANT_ACCESS:
3777 case SET_ACCESS:
3778 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3779 break;
3780 case DENY_ACCESS:
3781 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3782 break;
3783 case SET_AUDIT_SUCCESS:
3784 case SET_AUDIT_FAILURE:
3785 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3786 break;
3787 case REVOKE_ACCESS:
3788 break;
3789 default:
3790 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3791 ret = ERROR_INVALID_PARAMETER;
3792 goto exit;
3796 if (OldAcl)
3798 ACL_SIZE_INFORMATION size_info;
3800 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3801 if (status != STATUS_SUCCESS)
3803 ret = RtlNtStatusToDosError(status);
3804 goto exit;
3806 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3809 *NewAcl = LocalAlloc(0, acl_size);
3810 if (!*NewAcl)
3812 ret = ERROR_OUTOFMEMORY;
3813 goto exit;
3816 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3817 if (status != STATUS_SUCCESS)
3819 ret = RtlNtStatusToDosError(status);
3820 goto exit;
3823 for (i = 0; i < count; i++)
3825 switch (pEntries[i].grfAccessMode)
3827 case GRANT_ACCESS:
3828 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3829 pEntries[i].grfInheritance,
3830 pEntries[i].grfAccessPermissions,
3831 ppsid[i]);
3832 break;
3833 case SET_ACCESS:
3835 ULONG j;
3836 BOOL add = TRUE;
3837 if (OldAcl)
3839 for (j = 0; ; j++)
3841 const ACE_HEADER *existing_ace_header;
3842 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3843 if (status != STATUS_SUCCESS)
3844 break;
3845 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3846 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3847 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3849 add = FALSE;
3850 break;
3854 if (add)
3855 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3856 pEntries[i].grfInheritance,
3857 pEntries[i].grfAccessPermissions,
3858 ppsid[i]);
3859 break;
3861 case DENY_ACCESS:
3862 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3863 pEntries[i].grfInheritance,
3864 pEntries[i].grfAccessPermissions,
3865 ppsid[i]);
3866 break;
3867 case SET_AUDIT_SUCCESS:
3868 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3869 pEntries[i].grfInheritance,
3870 pEntries[i].grfAccessPermissions,
3871 ppsid[i], TRUE, FALSE);
3872 break;
3873 case SET_AUDIT_FAILURE:
3874 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3875 pEntries[i].grfInheritance,
3876 pEntries[i].grfAccessPermissions,
3877 ppsid[i], FALSE, TRUE);
3878 break;
3879 default:
3880 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3884 if (OldAcl)
3886 for (i = 0; ; i++)
3888 BOOL add = TRUE;
3889 ULONG j;
3890 const ACE_HEADER *old_ace_header;
3891 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3892 if (status != STATUS_SUCCESS) break;
3893 for (j = 0; j < count; j++)
3895 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3896 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3897 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3899 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3900 add = FALSE;
3901 break;
3903 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3905 switch (old_ace_header->AceType)
3907 case ACCESS_ALLOWED_ACE_TYPE:
3908 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3909 add = FALSE;
3910 break;
3911 case ACCESS_DENIED_ACE_TYPE:
3912 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3913 add = FALSE;
3914 break;
3915 case SYSTEM_AUDIT_ACE_TYPE:
3916 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3917 add = FALSE;
3918 break;
3919 case SYSTEM_ALARM_ACE_TYPE:
3920 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3921 add = FALSE;
3922 break;
3923 default:
3924 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3927 if (!add)
3928 break;
3931 if (add)
3932 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3933 if (status != STATUS_SUCCESS)
3935 WARN("RtlAddAce failed with error 0x%08x\n", status);
3936 ret = RtlNtStatusToDosError(status);
3937 break;
3942 exit:
3943 HeapFree(GetProcessHeap(), 0, ppsid);
3944 return ret;
3947 /******************************************************************************
3948 * SetNamedSecurityInfoA [ADVAPI32.@]
3950 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3951 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3952 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3954 DWORD len;
3955 LPWSTR wstr = NULL;
3956 DWORD r;
3958 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3959 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3961 if( pObjectName )
3963 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3964 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3965 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3968 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3969 psidGroup, pDacl, pSacl );
3971 HeapFree( GetProcessHeap(), 0, wstr );
3973 return r;
3976 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3977 PSECURITY_DESCRIPTOR ModificationDescriptor,
3978 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3979 PGENERIC_MAPPING GenericMapping,
3980 HANDLE Token )
3982 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3983 ObjectsSecurityDescriptor, GenericMapping, Token);
3985 return TRUE;
3988 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3990 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3993 /******************************************************************************
3994 * AreAnyAccessesGranted [ADVAPI32.@]
3996 * Determines whether or not any of a set of specified access permissions have
3997 * been granted or not.
3999 * PARAMS
4000 * GrantedAccess [I] The permissions that have been granted.
4001 * DesiredAccess [I] The permissions that you want to have.
4003 * RETURNS
4004 * Nonzero if any of the permissions have been granted, zero if none of the
4005 * permissions have been granted.
4008 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4010 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4013 /******************************************************************************
4014 * SetNamedSecurityInfoW [ADVAPI32.@]
4016 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4017 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4018 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4020 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4021 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4022 return ERROR_SUCCESS;
4025 /******************************************************************************
4026 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4028 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4029 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4031 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4032 return ERROR_CALL_NOT_IMPLEMENTED;
4035 /******************************************************************************
4036 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4038 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4039 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4041 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4042 return ERROR_CALL_NOT_IMPLEMENTED;
4045 /******************************************************************************
4046 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4048 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4049 PACCESS_MASK pFailedAuditRights)
4051 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4052 return ERROR_CALL_NOT_IMPLEMENTED;
4056 /******************************************************************************
4057 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4059 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4060 PACCESS_MASK pFailedAuditRights)
4062 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4063 return ERROR_CALL_NOT_IMPLEMENTED;
4067 /******************************************************************************
4068 * ParseAclStringFlags
4070 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4072 DWORD flags = 0;
4073 LPCWSTR szAcl = *StringAcl;
4075 while (*szAcl != '(')
4077 if (*szAcl == 'P')
4079 flags |= SE_DACL_PROTECTED;
4081 else if (*szAcl == 'A')
4083 szAcl++;
4084 if (*szAcl == 'R')
4085 flags |= SE_DACL_AUTO_INHERIT_REQ;
4086 else if (*szAcl == 'I')
4087 flags |= SE_DACL_AUTO_INHERITED;
4089 szAcl++;
4092 *StringAcl = szAcl;
4093 return flags;
4096 /******************************************************************************
4097 * ParseAceStringType
4099 static const ACEFLAG AceType[] =
4101 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4102 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4103 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4104 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4106 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4107 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4108 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4109 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4111 { NULL, 0 },
4114 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4116 UINT len = 0;
4117 LPCWSTR szAcl = *StringAcl;
4118 const ACEFLAG *lpaf = AceType;
4120 while (*szAcl == ' ')
4121 szAcl++;
4123 while (lpaf->wstr &&
4124 (len = strlenW(lpaf->wstr)) &&
4125 strncmpW(lpaf->wstr, szAcl, len))
4126 lpaf++;
4128 if (!lpaf->wstr)
4129 return 0;
4131 *StringAcl = szAcl + len;
4132 return lpaf->value;
4136 /******************************************************************************
4137 * ParseAceStringFlags
4139 static const ACEFLAG AceFlags[] =
4141 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4142 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4143 { SDDL_INHERITED, INHERITED_ACE },
4144 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4145 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4146 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4147 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4148 { NULL, 0 },
4151 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4153 UINT len = 0;
4154 BYTE flags = 0;
4155 LPCWSTR szAcl = *StringAcl;
4157 while (*szAcl == ' ')
4158 szAcl++;
4160 while (*szAcl != ';')
4162 const ACEFLAG *lpaf = AceFlags;
4164 while (lpaf->wstr &&
4165 (len = strlenW(lpaf->wstr)) &&
4166 strncmpW(lpaf->wstr, szAcl, len))
4167 lpaf++;
4169 if (!lpaf->wstr)
4170 return 0;
4172 flags |= lpaf->value;
4173 szAcl += len;
4176 *StringAcl = szAcl;
4177 return flags;
4181 /******************************************************************************
4182 * ParseAceStringRights
4184 static const ACEFLAG AceRights[] =
4186 { SDDL_GENERIC_ALL, GENERIC_ALL },
4187 { SDDL_GENERIC_READ, GENERIC_READ },
4188 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4189 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4191 { SDDL_READ_CONTROL, READ_CONTROL },
4192 { SDDL_STANDARD_DELETE, DELETE },
4193 { SDDL_WRITE_DAC, WRITE_DAC },
4194 { SDDL_WRITE_OWNER, WRITE_OWNER },
4196 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4197 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4198 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4199 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4200 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4201 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4202 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4203 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4204 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4206 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4207 { SDDL_FILE_READ, FILE_GENERIC_READ },
4208 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4209 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4211 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4212 { SDDL_KEY_READ, KEY_READ },
4213 { SDDL_KEY_WRITE, KEY_WRITE },
4214 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4215 { NULL, 0 },
4218 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4220 UINT len = 0;
4221 DWORD rights = 0;
4222 LPCWSTR szAcl = *StringAcl;
4224 while (*szAcl == ' ')
4225 szAcl++;
4227 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4229 LPCWSTR p = szAcl;
4231 while (*p && *p != ';')
4232 p++;
4234 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4236 rights = strtoulW(szAcl, NULL, 16);
4237 szAcl = p;
4239 else
4240 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4242 else
4244 while (*szAcl != ';')
4246 const ACEFLAG *lpaf = AceRights;
4248 while (lpaf->wstr &&
4249 (len = strlenW(lpaf->wstr)) &&
4250 strncmpW(lpaf->wstr, szAcl, len))
4252 lpaf++;
4255 if (!lpaf->wstr)
4256 return 0;
4258 rights |= lpaf->value;
4259 szAcl += len;
4263 *StringAcl = szAcl;
4264 return rights;
4268 /******************************************************************************
4269 * ParseStringAclToAcl
4271 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4273 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4274 PACL pAcl, LPDWORD cBytes)
4276 DWORD val;
4277 DWORD sidlen;
4278 DWORD length = sizeof(ACL);
4279 DWORD acesize = 0;
4280 DWORD acecount = 0;
4281 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4282 DWORD error = ERROR_INVALID_ACL;
4284 TRACE("%s\n", debugstr_w(StringAcl));
4286 if (!StringAcl)
4287 return FALSE;
4289 if (pAcl) /* pAce is only useful if we're setting values */
4290 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4292 /* Parse ACL flags */
4293 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4295 /* Parse ACE */
4296 while (*StringAcl == '(')
4298 StringAcl++;
4300 /* Parse ACE type */
4301 val = ParseAceStringType(&StringAcl);
4302 if (pAce)
4303 pAce->Header.AceType = (BYTE) val;
4304 if (*StringAcl != ';')
4306 error = RPC_S_INVALID_STRING_UUID;
4307 goto lerr;
4309 StringAcl++;
4311 /* Parse ACE flags */
4312 val = ParseAceStringFlags(&StringAcl);
4313 if (pAce)
4314 pAce->Header.AceFlags = (BYTE) val;
4315 if (*StringAcl != ';')
4316 goto lerr;
4317 StringAcl++;
4319 /* Parse ACE rights */
4320 val = ParseAceStringRights(&StringAcl);
4321 if (pAce)
4322 pAce->Mask = val;
4323 if (*StringAcl != ';')
4324 goto lerr;
4325 StringAcl++;
4327 /* Parse ACE object guid */
4328 while (*StringAcl == ' ')
4329 StringAcl++;
4330 if (*StringAcl != ';')
4332 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4333 goto lerr;
4335 StringAcl++;
4337 /* Parse ACE inherit object guid */
4338 while (*StringAcl == ' ')
4339 StringAcl++;
4340 if (*StringAcl != ';')
4342 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4343 goto lerr;
4345 StringAcl++;
4347 /* Parse ACE account sid */
4348 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4350 while (*StringAcl && *StringAcl != ')')
4351 StringAcl++;
4354 if (*StringAcl != ')')
4355 goto lerr;
4356 StringAcl++;
4358 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4359 length += acesize;
4360 if (pAce)
4362 pAce->Header.AceSize = acesize;
4363 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4365 acecount++;
4368 *cBytes = length;
4370 if (length > 0xffff)
4372 ERR("ACL too large\n");
4373 goto lerr;
4376 if (pAcl)
4378 pAcl->AclRevision = ACL_REVISION;
4379 pAcl->Sbz1 = 0;
4380 pAcl->AclSize = length;
4381 pAcl->AceCount = acecount++;
4382 pAcl->Sbz2 = 0;
4384 return TRUE;
4386 lerr:
4387 SetLastError(error);
4388 WARN("Invalid ACE string format\n");
4389 return FALSE;
4393 /******************************************************************************
4394 * ParseStringSecurityDescriptorToSecurityDescriptor
4396 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4397 LPCWSTR StringSecurityDescriptor,
4398 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4399 LPDWORD cBytes)
4401 BOOL bret = FALSE;
4402 WCHAR toktype;
4403 WCHAR tok[MAX_PATH];
4404 LPCWSTR lptoken;
4405 LPBYTE lpNext = NULL;
4406 DWORD len;
4408 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4410 if (SecurityDescriptor)
4411 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4413 while (*StringSecurityDescriptor == ' ')
4414 StringSecurityDescriptor++;
4416 while (*StringSecurityDescriptor)
4418 toktype = *StringSecurityDescriptor;
4420 /* Expect char identifier followed by ':' */
4421 StringSecurityDescriptor++;
4422 if (*StringSecurityDescriptor != ':')
4424 SetLastError(ERROR_INVALID_PARAMETER);
4425 goto lend;
4427 StringSecurityDescriptor++;
4429 /* Extract token */
4430 lptoken = StringSecurityDescriptor;
4431 while (*lptoken && *lptoken != ':')
4432 lptoken++;
4434 if (*lptoken)
4435 lptoken--;
4437 len = lptoken - StringSecurityDescriptor;
4438 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4439 tok[len] = 0;
4441 switch (toktype)
4443 case 'O':
4445 DWORD bytes;
4447 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4448 goto lend;
4450 if (SecurityDescriptor)
4452 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4453 lpNext += bytes; /* Advance to next token */
4456 *cBytes += bytes;
4458 break;
4461 case 'G':
4463 DWORD bytes;
4465 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4466 goto lend;
4468 if (SecurityDescriptor)
4470 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4471 lpNext += bytes; /* Advance to next token */
4474 *cBytes += bytes;
4476 break;
4479 case 'D':
4481 DWORD flags;
4482 DWORD bytes;
4484 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4485 goto lend;
4487 if (SecurityDescriptor)
4489 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4490 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4491 lpNext += bytes; /* Advance to next token */
4494 *cBytes += bytes;
4496 break;
4499 case 'S':
4501 DWORD flags;
4502 DWORD bytes;
4504 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4505 goto lend;
4507 if (SecurityDescriptor)
4509 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4510 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4511 lpNext += bytes; /* Advance to next token */
4514 *cBytes += bytes;
4516 break;
4519 default:
4520 FIXME("Unknown token\n");
4521 SetLastError(ERROR_INVALID_PARAMETER);
4522 goto lend;
4525 StringSecurityDescriptor = lptoken;
4528 bret = TRUE;
4530 lend:
4531 return bret;
4534 /******************************************************************************
4535 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4537 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4538 LPCSTR StringSecurityDescriptor,
4539 DWORD StringSDRevision,
4540 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4541 PULONG SecurityDescriptorSize)
4543 UINT len;
4544 BOOL ret = FALSE;
4545 LPWSTR StringSecurityDescriptorW;
4547 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4548 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4550 if (StringSecurityDescriptorW)
4552 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4554 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4555 StringSDRevision, SecurityDescriptor,
4556 SecurityDescriptorSize);
4557 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4560 return ret;
4563 /******************************************************************************
4564 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4566 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4567 LPCWSTR StringSecurityDescriptor,
4568 DWORD StringSDRevision,
4569 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4570 PULONG SecurityDescriptorSize)
4572 DWORD cBytes;
4573 SECURITY_DESCRIPTOR* psd;
4574 BOOL bret = FALSE;
4576 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4578 if (GetVersion() & 0x80000000)
4580 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4581 goto lend;
4583 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4585 SetLastError(ERROR_INVALID_PARAMETER);
4586 goto lend;
4588 else if (StringSDRevision != SID_REVISION)
4590 SetLastError(ERROR_UNKNOWN_REVISION);
4591 goto lend;
4594 /* Compute security descriptor length */
4595 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4596 NULL, &cBytes))
4597 goto lend;
4599 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4600 if (!psd) goto lend;
4602 psd->Revision = SID_REVISION;
4603 psd->Control |= SE_SELF_RELATIVE;
4605 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4606 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4608 LocalFree(psd);
4609 goto lend;
4612 if (SecurityDescriptorSize)
4613 *SecurityDescriptorSize = cBytes;
4615 bret = TRUE;
4617 lend:
4618 TRACE(" ret=%d\n", bret);
4619 return bret;
4622 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4624 if (cch == -1)
4625 cch = strlenW(string);
4627 if (plen)
4628 *plen += cch;
4630 if (pwptr)
4632 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4633 *pwptr += cch;
4637 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4639 DWORD i;
4640 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4641 WCHAR subauthfmt[] = { '-','%','u',0 };
4642 WCHAR buf[26];
4643 SID *pisid = psid;
4645 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4647 SetLastError(ERROR_INVALID_SID);
4648 return FALSE;
4651 if (pisid->IdentifierAuthority.Value[0] ||
4652 pisid->IdentifierAuthority.Value[1])
4654 FIXME("not matching MS' bugs\n");
4655 SetLastError(ERROR_INVALID_SID);
4656 return FALSE;
4659 sprintfW( buf, fmt, pisid->Revision,
4660 MAKELONG(
4661 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4662 pisid->IdentifierAuthority.Value[4] ),
4663 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4664 pisid->IdentifierAuthority.Value[2] )
4665 ) );
4666 DumpString(buf, -1, pwptr, plen);
4668 for( i=0; i<pisid->SubAuthorityCount; i++ )
4670 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4671 DumpString(buf, -1, pwptr, plen);
4673 return TRUE;
4676 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4678 size_t i;
4679 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4681 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4683 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4684 return TRUE;
4688 return DumpSidNumeric(psid, pwptr, plen);
4691 static const LPCWSTR AceRightBitNames[32] = {
4692 SDDL_CREATE_CHILD, /* 0 */
4693 SDDL_DELETE_CHILD,
4694 SDDL_LIST_CHILDREN,
4695 SDDL_SELF_WRITE,
4696 SDDL_READ_PROPERTY, /* 4 */
4697 SDDL_WRITE_PROPERTY,
4698 SDDL_DELETE_TREE,
4699 SDDL_LIST_OBJECT,
4700 SDDL_CONTROL_ACCESS, /* 8 */
4701 NULL,
4702 NULL,
4703 NULL,
4704 NULL, /* 12 */
4705 NULL,
4706 NULL,
4707 NULL,
4708 SDDL_STANDARD_DELETE, /* 16 */
4709 SDDL_READ_CONTROL,
4710 SDDL_WRITE_DAC,
4711 SDDL_WRITE_OWNER,
4712 NULL, /* 20 */
4713 NULL,
4714 NULL,
4715 NULL,
4716 NULL, /* 24 */
4717 NULL,
4718 NULL,
4719 NULL,
4720 SDDL_GENERIC_ALL, /* 28 */
4721 SDDL_GENERIC_EXECUTE,
4722 SDDL_GENERIC_WRITE,
4723 SDDL_GENERIC_READ
4726 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4728 static const WCHAR fmtW[] = {'0','x','%','x',0};
4729 WCHAR buf[15];
4730 size_t i;
4732 if (mask == 0)
4733 return;
4735 /* first check if the right have name */
4736 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4738 if (AceRights[i].wstr == NULL)
4739 break;
4740 if (mask == AceRights[i].value)
4742 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4743 return;
4747 /* then check if it can be built from bit names */
4748 for (i = 0; i < 32; i++)
4750 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4752 /* can't be built from bit names */
4753 sprintfW(buf, fmtW, mask);
4754 DumpString(buf, -1, pwptr, plen);
4755 return;
4759 /* build from bit names */
4760 for (i = 0; i < 32; i++)
4761 if (mask & (1 << i))
4762 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4765 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4767 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4768 static const WCHAR openbr = '(';
4769 static const WCHAR closebr = ')';
4770 static const WCHAR semicolon = ';';
4772 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4774 SetLastError(ERROR_INVALID_ACL);
4775 return FALSE;
4778 piace = pace;
4779 DumpString(&openbr, 1, pwptr, plen);
4780 switch (piace->Header.AceType)
4782 case ACCESS_ALLOWED_ACE_TYPE:
4783 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4784 break;
4785 case ACCESS_DENIED_ACE_TYPE:
4786 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4787 break;
4788 case SYSTEM_AUDIT_ACE_TYPE:
4789 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4790 break;
4791 case SYSTEM_ALARM_ACE_TYPE:
4792 DumpString(SDDL_ALARM, -1, pwptr, plen);
4793 break;
4795 DumpString(&semicolon, 1, pwptr, plen);
4797 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4798 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4799 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4800 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4801 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4802 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4803 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4804 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4805 if (piace->Header.AceFlags & INHERITED_ACE)
4806 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4807 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4808 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4809 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4810 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4811 DumpString(&semicolon, 1, pwptr, plen);
4812 DumpRights(piace->Mask, pwptr, plen);
4813 DumpString(&semicolon, 1, pwptr, plen);
4814 /* objects not supported */
4815 DumpString(&semicolon, 1, pwptr, plen);
4816 /* objects not supported */
4817 DumpString(&semicolon, 1, pwptr, plen);
4818 if (!DumpSid(&piace->SidStart, pwptr, plen))
4819 return FALSE;
4820 DumpString(&closebr, 1, pwptr, plen);
4821 return TRUE;
4824 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4826 WORD count;
4827 int i;
4829 if (protected)
4830 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4831 if (autoInheritReq)
4832 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4833 if (autoInherited)
4834 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4836 if (pacl == NULL)
4837 return TRUE;
4839 if (!IsValidAcl(pacl))
4840 return FALSE;
4842 count = pacl->AceCount;
4843 for (i = 0; i < count; i++)
4845 LPVOID ace;
4846 if (!GetAce(pacl, i, &ace))
4847 return FALSE;
4848 if (!DumpAce(ace, pwptr, plen))
4849 return FALSE;
4852 return TRUE;
4855 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4857 static const WCHAR prefix[] = {'O',':',0};
4858 BOOL bDefaulted;
4859 PSID psid;
4861 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4862 return FALSE;
4864 if (psid == NULL)
4865 return TRUE;
4867 DumpString(prefix, -1, pwptr, plen);
4868 if (!DumpSid(psid, pwptr, plen))
4869 return FALSE;
4870 return TRUE;
4873 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4875 static const WCHAR prefix[] = {'G',':',0};
4876 BOOL bDefaulted;
4877 PSID psid;
4879 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4880 return FALSE;
4882 if (psid == NULL)
4883 return TRUE;
4885 DumpString(prefix, -1, pwptr, plen);
4886 if (!DumpSid(psid, pwptr, plen))
4887 return FALSE;
4888 return TRUE;
4891 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4893 static const WCHAR dacl[] = {'D',':',0};
4894 SECURITY_DESCRIPTOR_CONTROL control;
4895 BOOL present, defaulted;
4896 DWORD revision;
4897 PACL pacl;
4899 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4900 return FALSE;
4902 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4903 return FALSE;
4905 if (!present)
4906 return TRUE;
4908 DumpString(dacl, 2, pwptr, plen);
4909 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4910 return FALSE;
4911 return TRUE;
4914 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4916 static const WCHAR sacl[] = {'S',':',0};
4917 SECURITY_DESCRIPTOR_CONTROL control;
4918 BOOL present, defaulted;
4919 DWORD revision;
4920 PACL pacl;
4922 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4923 return FALSE;
4925 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4926 return FALSE;
4928 if (!present)
4929 return TRUE;
4931 DumpString(sacl, 2, pwptr, plen);
4932 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4933 return FALSE;
4934 return TRUE;
4937 /******************************************************************************
4938 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4940 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4942 ULONG len;
4943 WCHAR *wptr, *wstr;
4945 if (SDRevision != SDDL_REVISION_1)
4947 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4948 SetLastError(ERROR_UNKNOWN_REVISION);
4949 return FALSE;
4952 len = 0;
4953 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4954 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4955 return FALSE;
4956 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4957 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4958 return FALSE;
4959 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4960 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4961 return FALSE;
4962 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4963 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4964 return FALSE;
4966 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4967 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4968 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4969 return FALSE;
4970 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4971 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4972 return FALSE;
4973 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4974 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4975 return FALSE;
4976 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4977 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4978 return FALSE;
4979 *wptr = 0;
4981 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4982 *OutputString = wstr;
4983 if (OutputLen)
4984 *OutputLen = strlenW(*OutputString)+1;
4985 return TRUE;
4988 /******************************************************************************
4989 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4991 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4993 LPWSTR wstr;
4994 ULONG len;
4995 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4997 int lenA;
4999 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5000 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
5001 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5002 LocalFree(wstr);
5004 if (OutputLen != NULL)
5005 *OutputLen = lenA;
5006 return TRUE;
5008 else
5010 *OutputString = NULL;
5011 if (OutputLen)
5012 *OutputLen = 0;
5013 return FALSE;
5017 /******************************************************************************
5018 * ConvertStringSidToSidW [ADVAPI32.@]
5020 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5022 BOOL bret = FALSE;
5023 DWORD cBytes;
5025 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5026 if (GetVersion() & 0x80000000)
5027 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5028 else if (!StringSid || !Sid)
5029 SetLastError(ERROR_INVALID_PARAMETER);
5030 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5032 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5034 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5035 if (!bret)
5036 LocalFree(*Sid);
5038 return bret;
5041 /******************************************************************************
5042 * ConvertStringSidToSidA [ADVAPI32.@]
5044 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5046 BOOL bret = FALSE;
5048 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5049 if (GetVersion() & 0x80000000)
5050 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5051 else if (!StringSid || !Sid)
5052 SetLastError(ERROR_INVALID_PARAMETER);
5053 else
5055 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
5056 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
5057 len * sizeof(WCHAR));
5059 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
5060 bret = ConvertStringSidToSidW(wStringSid, Sid);
5061 HeapFree(GetProcessHeap(), 0, wStringSid);
5063 return bret;
5066 /******************************************************************************
5067 * ConvertSidToStringSidW [ADVAPI32.@]
5069 * format of SID string is:
5070 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5071 * where
5072 * <rev> is the revision of the SID encoded as decimal
5073 * <auth> is the identifier authority encoded as hex
5074 * <subauthN> is the subauthority id encoded as decimal
5076 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5078 DWORD len = 0;
5079 LPWSTR wstr, wptr;
5081 TRACE("%p %p\n", pSid, pstr );
5083 len = 0;
5084 if (!DumpSidNumeric(pSid, NULL, &len))
5085 return FALSE;
5086 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5087 DumpSidNumeric(pSid, &wptr, NULL);
5088 *wptr = 0;
5090 *pstr = wstr;
5091 return TRUE;
5094 /******************************************************************************
5095 * ConvertSidToStringSidA [ADVAPI32.@]
5097 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5099 LPWSTR wstr = NULL;
5100 LPSTR str;
5101 UINT len;
5103 TRACE("%p %p\n", pSid, pstr );
5105 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5106 return FALSE;
5108 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5109 str = LocalAlloc( 0, len );
5110 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5111 LocalFree( wstr );
5113 *pstr = str;
5115 return TRUE;
5118 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5119 PSECURITY_DESCRIPTOR pdesc,
5120 PSECURITY_DESCRIPTOR cdesc,
5121 PSECURITY_DESCRIPTOR* ndesc,
5122 GUID* objtype,
5123 BOOL isdir,
5124 PGENERIC_MAPPING genmap )
5126 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5128 return FALSE;
5131 BOOL WINAPI CreatePrivateObjectSecurity(
5132 PSECURITY_DESCRIPTOR ParentDescriptor,
5133 PSECURITY_DESCRIPTOR CreatorDescriptor,
5134 PSECURITY_DESCRIPTOR* NewDescriptor,
5135 BOOL IsDirectoryObject,
5136 HANDLE Token,
5137 PGENERIC_MAPPING GenericMapping )
5139 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
5140 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5142 return FALSE;
5145 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5147 FIXME("%p - stub\n", ObjectDescriptor);
5149 return TRUE;
5152 BOOL WINAPI CreateProcessAsUserA(
5153 HANDLE hToken,
5154 LPCSTR lpApplicationName,
5155 LPSTR lpCommandLine,
5156 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5157 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5158 BOOL bInheritHandles,
5159 DWORD dwCreationFlags,
5160 LPVOID lpEnvironment,
5161 LPCSTR lpCurrentDirectory,
5162 LPSTARTUPINFOA lpStartupInfo,
5163 LPPROCESS_INFORMATION lpProcessInformation )
5165 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
5166 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5167 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5169 return FALSE;
5172 BOOL WINAPI CreateProcessAsUserW(
5173 HANDLE hToken,
5174 LPCWSTR lpApplicationName,
5175 LPWSTR lpCommandLine,
5176 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5177 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5178 BOOL bInheritHandles,
5179 DWORD dwCreationFlags,
5180 LPVOID lpEnvironment,
5181 LPCWSTR lpCurrentDirectory,
5182 LPSTARTUPINFOW lpStartupInfo,
5183 LPPROCESS_INFORMATION lpProcessInformation )
5185 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5186 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5187 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5188 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5190 /* We should create the process with a suspended main thread */
5191 if (!CreateProcessW (lpApplicationName,
5192 lpCommandLine,
5193 lpProcessAttributes,
5194 lpThreadAttributes,
5195 bInheritHandles,
5196 dwCreationFlags, /* CREATE_SUSPENDED */
5197 lpEnvironment,
5198 lpCurrentDirectory,
5199 lpStartupInfo,
5200 lpProcessInformation))
5202 return FALSE;
5205 return TRUE;
5208 /******************************************************************************
5209 * CreateProcessWithLogonW
5211 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5212 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5213 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5215 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5216 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5217 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5218 lpStartupInfo, lpProcessInformation);
5220 return FALSE;
5223 /******************************************************************************
5224 * DuplicateTokenEx [ADVAPI32.@]
5226 BOOL WINAPI DuplicateTokenEx(
5227 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5228 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5229 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5230 TOKEN_TYPE TokenType,
5231 PHANDLE DuplicateTokenHandle )
5233 OBJECT_ATTRIBUTES ObjectAttributes;
5235 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5236 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5238 InitializeObjectAttributes(
5239 &ObjectAttributes,
5240 NULL,
5241 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5242 NULL,
5243 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5245 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5246 dwDesiredAccess,
5247 &ObjectAttributes,
5248 ImpersonationLevel,
5249 TokenType,
5250 DuplicateTokenHandle ) );
5253 BOOL WINAPI DuplicateToken(
5254 HANDLE ExistingTokenHandle,
5255 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5256 PHANDLE DuplicateTokenHandle )
5258 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5259 NULL, ImpersonationLevel, TokenImpersonation,
5260 DuplicateTokenHandle );
5263 /******************************************************************************
5264 * ComputeStringSidSize
5266 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5268 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5270 int ctok = 0;
5271 while (*StringSid)
5273 if (*StringSid == '-')
5274 ctok++;
5275 StringSid++;
5278 if (ctok >= 3)
5279 return GetSidLengthRequired(ctok - 2);
5281 else /* String constant format - Only available in winxp and above */
5283 unsigned int i;
5285 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5286 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5287 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5290 return GetSidLengthRequired(0);
5293 /******************************************************************************
5294 * ParseStringSidToSid
5296 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5298 BOOL bret = FALSE;
5299 SID* pisid=pSid;
5301 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5302 if (!StringSid)
5304 SetLastError(ERROR_INVALID_PARAMETER);
5305 TRACE("StringSid is NULL, returning FALSE\n");
5306 return FALSE;
5309 while (*StringSid == ' ')
5310 StringSid++;
5312 *cBytes = ComputeStringSidSize(StringSid);
5313 if (!pisid) /* Simply compute the size */
5315 TRACE("only size requested, returning TRUE\n");
5316 return TRUE;
5319 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5321 DWORD i = 0, identAuth;
5322 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5324 StringSid += 2; /* Advance to Revision */
5325 pisid->Revision = atoiW(StringSid);
5327 if (pisid->Revision != SDDL_REVISION)
5329 TRACE("Revision %d is unknown\n", pisid->Revision);
5330 goto lend; /* ERROR_INVALID_SID */
5332 if (csubauth == 0)
5334 TRACE("SubAuthorityCount is 0\n");
5335 goto lend; /* ERROR_INVALID_SID */
5338 pisid->SubAuthorityCount = csubauth;
5340 /* Advance to identifier authority */
5341 while (*StringSid && *StringSid != '-')
5342 StringSid++;
5343 if (*StringSid == '-')
5344 StringSid++;
5346 /* MS' implementation can't handle values greater than 2^32 - 1, so
5347 * we don't either; assume most significant bytes are always 0
5349 pisid->IdentifierAuthority.Value[0] = 0;
5350 pisid->IdentifierAuthority.Value[1] = 0;
5351 identAuth = atoiW(StringSid);
5352 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5353 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5354 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5355 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5357 /* Advance to first sub authority */
5358 while (*StringSid && *StringSid != '-')
5359 StringSid++;
5360 if (*StringSid == '-')
5361 StringSid++;
5363 while (*StringSid)
5365 pisid->SubAuthority[i++] = atoiW(StringSid);
5367 while (*StringSid && *StringSid != '-')
5368 StringSid++;
5369 if (*StringSid == '-')
5370 StringSid++;
5373 if (i != pisid->SubAuthorityCount)
5374 goto lend; /* ERROR_INVALID_SID */
5376 bret = TRUE;
5378 else /* String constant format - Only available in winxp and above */
5380 unsigned int i;
5381 pisid->Revision = SDDL_REVISION;
5383 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5384 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5386 DWORD j;
5387 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5388 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5389 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5390 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5391 bret = TRUE;
5394 if (!bret)
5395 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5398 lend:
5399 if (!bret)
5400 SetLastError(ERROR_INVALID_SID);
5402 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5403 return bret;
5406 /******************************************************************************
5407 * GetNamedSecurityInfoA [ADVAPI32.@]
5409 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5410 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5411 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5412 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5414 DWORD len;
5415 LPWSTR wstr = NULL;
5416 DWORD r;
5418 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5419 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5421 if( pObjectName )
5423 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5424 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5425 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5428 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5429 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5431 HeapFree( GetProcessHeap(), 0, wstr );
5433 return r;
5436 /******************************************************************************
5437 * GetNamedSecurityInfoW [ADVAPI32.@]
5439 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5440 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5441 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5443 DWORD needed, offset;
5444 SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
5445 BYTE *buffer;
5447 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5448 group, dacl, sacl, descriptor );
5450 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5451 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5453 /* If no descriptor, we have to check that there's a pointer for the requested information */
5454 if( !descriptor && (
5455 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5456 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5457 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5458 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5459 return ERROR_INVALID_PARAMETER;
5461 needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5462 if (info & OWNER_SECURITY_INFORMATION)
5463 needed += sizeof(sidWorld);
5464 if (info & GROUP_SECURITY_INFORMATION)
5465 needed += sizeof(sidWorld);
5466 if (info & DACL_SECURITY_INFORMATION)
5467 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5468 if (info & SACL_SECURITY_INFORMATION)
5469 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5471 if(descriptor)
5473 /* must be freed by caller */
5474 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5475 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5477 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5479 HeapFree( GetProcessHeap(), 0, *descriptor );
5480 return ERROR_INVALID_SECURITY_DESCR;
5483 relative = *descriptor;
5484 relative->Control |= SE_SELF_RELATIVE;
5486 buffer = (BYTE *)relative;
5487 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5489 else
5491 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
5492 if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
5493 offset = 0;
5496 if (info & OWNER_SECURITY_INFORMATION)
5498 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5499 if(relative)
5500 relative->Owner = offset;
5501 if (owner)
5502 *owner = buffer + offset;
5503 offset += sizeof(sidWorld);
5505 if (info & GROUP_SECURITY_INFORMATION)
5507 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5508 if(relative)
5509 relative->Group = offset;
5510 if (group)
5511 *group = buffer + offset;
5512 offset += sizeof(sidWorld);
5514 if (info & DACL_SECURITY_INFORMATION)
5516 GetWorldAccessACL( (PACL)(buffer + offset) );
5517 if(relative)
5519 relative->Control |= SE_DACL_PRESENT;
5520 relative->Dacl = offset;
5522 if (dacl)
5523 *dacl = (PACL)(buffer + offset);
5524 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5526 if (info & SACL_SECURITY_INFORMATION)
5528 GetWorldAccessACL( (PACL)(buffer + offset) );
5529 if(relative)
5531 relative->Control |= SE_SACL_PRESENT;
5532 relative->Sacl = offset;
5534 if (sacl)
5535 *sacl = (PACL)(buffer + offset);
5538 return ERROR_SUCCESS;
5541 /******************************************************************************
5542 * DecryptFileW [ADVAPI32.@]
5544 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5546 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5547 return TRUE;
5550 /******************************************************************************
5551 * DecryptFileA [ADVAPI32.@]
5553 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5555 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5556 return TRUE;
5559 /******************************************************************************
5560 * EncryptFileW [ADVAPI32.@]
5562 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5564 FIXME("%s\n", debugstr_w(lpFileName));
5565 return TRUE;
5568 /******************************************************************************
5569 * EncryptFileA [ADVAPI32.@]
5571 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5573 FIXME("%s\n", debugstr_a(lpFileName));
5574 return TRUE;
5577 /******************************************************************************
5578 * FileEncryptionStatusW [ADVAPI32.@]
5580 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5582 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5583 if (!lpStatus)
5584 return FALSE;
5585 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5586 return TRUE;
5589 /******************************************************************************
5590 * FileEncryptionStatusA [ADVAPI32.@]
5592 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5594 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5595 if (!lpStatus)
5596 return FALSE;
5597 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5598 return TRUE;
5601 /******************************************************************************
5602 * SetSecurityInfo [ADVAPI32.@]
5604 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5605 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5606 PSID psidGroup, PACL pDacl, PACL pSacl) {
5607 FIXME("stub\n");
5608 return ERROR_SUCCESS;
5611 /******************************************************************************
5612 * SaferCreateLevel [ADVAPI32.@]
5614 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5615 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5617 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5619 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5620 return TRUE;
5623 /******************************************************************************
5624 * SaferComputeTokenFromLevel [ADVAPI32.@]
5626 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5627 DWORD flags, LPVOID reserved)
5629 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5631 *access_token = (HANDLE)0xdeadbeef;
5632 return TRUE;
5635 /******************************************************************************
5636 * SaferCloseLevel [ADVAPI32.@]
5638 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5640 FIXME("(%p) stub\n", handle);
5641 return TRUE;
5644 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5645 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5646 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5647 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5648 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5650 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5651 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5652 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5654 return ERROR_SUCCESS;
5657 /******************************************************************************
5658 * SaferGetPolicyInformation [ADVAPI32.@]
5660 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5661 PVOID buffer, PDWORD required, LPVOID lpReserved)
5663 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5664 return FALSE;