advapi32: EqualSid should set last error to ERROR_SUCCESS.
[wine/multimedia.git] / dlls / advapi32 / security.c
blob3e79a6142919d7f9b53e45c29acfdf6ce707051b
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 return 1;
1106 DWORD WINAPI
1107 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1109 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1111 return 1;
1114 /******************************************************************************
1115 * GetSidIdentifierAuthority [ADVAPI32.@]
1117 * PARAMS
1118 * pSid []
1120 PSID_IDENTIFIER_AUTHORITY WINAPI
1121 GetSidIdentifierAuthority( PSID pSid )
1123 return RtlIdentifierAuthoritySid(pSid);
1126 /******************************************************************************
1127 * GetSidSubAuthority [ADVAPI32.@]
1129 * PARAMS
1130 * pSid []
1131 * nSubAuthority []
1133 PDWORD WINAPI
1134 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1136 SetLastError(ERROR_SUCCESS);
1137 return RtlSubAuthoritySid(pSid, nSubAuthority);
1140 /******************************************************************************
1141 * GetSidSubAuthorityCount [ADVAPI32.@]
1143 * PARAMS
1144 * pSid []
1146 PUCHAR WINAPI
1147 GetSidSubAuthorityCount (PSID pSid)
1149 SetLastError(ERROR_SUCCESS);
1150 return RtlSubAuthorityCountSid(pSid);
1153 /******************************************************************************
1154 * GetLengthSid [ADVAPI32.@]
1156 * PARAMS
1157 * pSid []
1159 DWORD WINAPI
1160 GetLengthSid (PSID pSid)
1162 return RtlLengthSid(pSid);
1165 /* ##############################################
1166 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1167 ##############################################
1170 /******************************************************************************
1171 * BuildSecurityDescriptorA [ADVAPI32.@]
1173 * Builds a SD from
1175 * PARAMS
1176 * pOwner [I]
1177 * pGroup [I]
1178 * cCountOfAccessEntries [I]
1179 * pListOfAccessEntries [I]
1180 * cCountOfAuditEntries [I]
1181 * pListofAuditEntries [I]
1182 * pOldSD [I]
1183 * lpdwBufferLength [I/O]
1184 * pNewSD [O]
1186 * RETURNS
1187 * Success: ERROR_SUCCESS
1188 * Failure: nonzero error code from Winerror.h
1190 DWORD WINAPI BuildSecurityDescriptorA(
1191 IN PTRUSTEEA pOwner,
1192 IN PTRUSTEEA pGroup,
1193 IN ULONG cCountOfAccessEntries,
1194 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1195 IN ULONG cCountOfAuditEntries,
1196 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1197 IN PSECURITY_DESCRIPTOR pOldSD,
1198 IN OUT PULONG lpdwBufferLength,
1199 OUT PSECURITY_DESCRIPTOR* pNewSD)
1201 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1202 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1203 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1205 return ERROR_CALL_NOT_IMPLEMENTED;
1208 /******************************************************************************
1209 * BuildSecurityDescriptorW [ADVAPI32.@]
1211 * See BuildSecurityDescriptorA.
1213 DWORD WINAPI BuildSecurityDescriptorW(
1214 IN PTRUSTEEW pOwner,
1215 IN PTRUSTEEW pGroup,
1216 IN ULONG cCountOfAccessEntries,
1217 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1218 IN ULONG cCountOfAuditEntries,
1219 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1220 IN PSECURITY_DESCRIPTOR pOldSD,
1221 IN OUT PULONG lpdwBufferLength,
1222 OUT PSECURITY_DESCRIPTOR* pNewSD)
1224 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1225 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1226 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1228 return ERROR_CALL_NOT_IMPLEMENTED;
1231 /******************************************************************************
1232 * InitializeSecurityDescriptor [ADVAPI32.@]
1234 * PARAMS
1235 * pDescr []
1236 * revision []
1238 BOOL WINAPI
1239 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1241 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1245 /******************************************************************************
1246 * MakeAbsoluteSD [ADVAPI32.@]
1248 BOOL WINAPI MakeAbsoluteSD (
1249 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1250 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1251 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1252 OUT PACL pDacl,
1253 OUT LPDWORD lpdwDaclSize,
1254 OUT PACL pSacl,
1255 OUT LPDWORD lpdwSaclSize,
1256 OUT PSID pOwner,
1257 OUT LPDWORD lpdwOwnerSize,
1258 OUT PSID pPrimaryGroup,
1259 OUT LPDWORD lpdwPrimaryGroupSize)
1261 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1262 pAbsoluteSecurityDescriptor,
1263 lpdwAbsoluteSecurityDescriptorSize,
1264 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1265 pOwner, lpdwOwnerSize,
1266 pPrimaryGroup, lpdwPrimaryGroupSize));
1269 /******************************************************************************
1270 * GetKernelObjectSecurity [ADVAPI32.@]
1272 BOOL WINAPI GetKernelObjectSecurity(
1273 HANDLE Handle,
1274 SECURITY_INFORMATION RequestedInformation,
1275 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1276 DWORD nLength,
1277 LPDWORD lpnLengthNeeded )
1279 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1280 pSecurityDescriptor, nLength, lpnLengthNeeded);
1282 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1283 nLength, lpnLengthNeeded ));
1286 /******************************************************************************
1287 * GetPrivateObjectSecurity [ADVAPI32.@]
1289 BOOL WINAPI GetPrivateObjectSecurity(
1290 PSECURITY_DESCRIPTOR ObjectDescriptor,
1291 SECURITY_INFORMATION SecurityInformation,
1292 PSECURITY_DESCRIPTOR ResultantDescriptor,
1293 DWORD DescriptorLength,
1294 PDWORD ReturnLength )
1296 SECURITY_DESCRIPTOR desc;
1297 BOOL defaulted, present;
1298 PACL pacl;
1299 PSID psid;
1301 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1302 ResultantDescriptor, DescriptorLength, ReturnLength);
1304 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1305 return FALSE;
1307 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1309 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1310 return FALSE;
1311 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1314 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1316 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1317 return FALSE;
1318 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1321 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1323 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1324 return FALSE;
1325 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1328 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1330 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1331 return FALSE;
1332 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1335 *ReturnLength = DescriptorLength;
1336 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1339 /******************************************************************************
1340 * GetSecurityDescriptorLength [ADVAPI32.@]
1342 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1344 return RtlLengthSecurityDescriptor(pDescr);
1347 /******************************************************************************
1348 * GetSecurityDescriptorOwner [ADVAPI32.@]
1350 * PARAMS
1351 * pOwner []
1352 * lpbOwnerDefaulted []
1354 BOOL WINAPI
1355 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1356 LPBOOL lpbOwnerDefaulted )
1358 BOOLEAN defaulted;
1359 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1360 *lpbOwnerDefaulted = defaulted;
1361 return ret;
1364 /******************************************************************************
1365 * SetSecurityDescriptorOwner [ADVAPI32.@]
1367 * PARAMS
1369 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1370 PSID pOwner, BOOL bOwnerDefaulted)
1372 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1374 /******************************************************************************
1375 * GetSecurityDescriptorGroup [ADVAPI32.@]
1377 BOOL WINAPI GetSecurityDescriptorGroup(
1378 PSECURITY_DESCRIPTOR SecurityDescriptor,
1379 PSID *Group,
1380 LPBOOL GroupDefaulted)
1382 BOOLEAN defaulted;
1383 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1384 *GroupDefaulted = defaulted;
1385 return ret;
1387 /******************************************************************************
1388 * SetSecurityDescriptorGroup [ADVAPI32.@]
1390 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1391 PSID Group, BOOL GroupDefaulted)
1393 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1396 /******************************************************************************
1397 * IsValidSecurityDescriptor [ADVAPI32.@]
1399 * PARAMS
1400 * lpsecdesc []
1402 BOOL WINAPI
1403 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1405 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1408 /******************************************************************************
1409 * GetSecurityDescriptorDacl [ADVAPI32.@]
1411 BOOL WINAPI GetSecurityDescriptorDacl(
1412 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1413 OUT LPBOOL lpbDaclPresent,
1414 OUT PACL *pDacl,
1415 OUT LPBOOL lpbDaclDefaulted)
1417 BOOLEAN present, defaulted;
1418 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1419 *lpbDaclPresent = present;
1420 *lpbDaclDefaulted = defaulted;
1421 return ret;
1424 /******************************************************************************
1425 * SetSecurityDescriptorDacl [ADVAPI32.@]
1427 BOOL WINAPI
1428 SetSecurityDescriptorDacl (
1429 PSECURITY_DESCRIPTOR lpsd,
1430 BOOL daclpresent,
1431 PACL dacl,
1432 BOOL dacldefaulted )
1434 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1436 /******************************************************************************
1437 * GetSecurityDescriptorSacl [ADVAPI32.@]
1439 BOOL WINAPI GetSecurityDescriptorSacl(
1440 IN PSECURITY_DESCRIPTOR lpsd,
1441 OUT LPBOOL lpbSaclPresent,
1442 OUT PACL *pSacl,
1443 OUT LPBOOL lpbSaclDefaulted)
1445 BOOLEAN present, defaulted;
1446 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1447 *lpbSaclPresent = present;
1448 *lpbSaclDefaulted = defaulted;
1449 return ret;
1452 /**************************************************************************
1453 * SetSecurityDescriptorSacl [ADVAPI32.@]
1455 BOOL WINAPI SetSecurityDescriptorSacl (
1456 PSECURITY_DESCRIPTOR lpsd,
1457 BOOL saclpresent,
1458 PACL lpsacl,
1459 BOOL sacldefaulted)
1461 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1463 /******************************************************************************
1464 * MakeSelfRelativeSD [ADVAPI32.@]
1466 * PARAMS
1467 * lpabssecdesc []
1468 * lpselfsecdesc []
1469 * lpbuflen []
1471 BOOL WINAPI
1472 MakeSelfRelativeSD(
1473 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1474 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1475 IN OUT LPDWORD lpdwBufferLength)
1477 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1478 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1481 /******************************************************************************
1482 * GetSecurityDescriptorControl [ADVAPI32.@]
1485 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1486 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1488 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1491 /******************************************************************************
1492 * SetSecurityDescriptorControl [ADVAPI32.@]
1494 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1495 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1496 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1498 return set_ntstatus( RtlSetControlSecurityDescriptor(
1499 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1502 /* ##############################
1503 ###### ACL FUNCTIONS ######
1504 ##############################
1507 /*************************************************************************
1508 * InitializeAcl [ADVAPI32.@]
1510 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1512 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1515 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1517 IO_STATUS_BLOCK io_block;
1519 TRACE("(%p)\n", hNamedPipe);
1521 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1522 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1525 /******************************************************************************
1526 * AddAccessAllowedAce [ADVAPI32.@]
1528 BOOL WINAPI AddAccessAllowedAce(
1529 IN OUT PACL pAcl,
1530 IN DWORD dwAceRevision,
1531 IN DWORD AccessMask,
1532 IN PSID pSid)
1534 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1537 /******************************************************************************
1538 * AddAccessAllowedAceEx [ADVAPI32.@]
1540 BOOL WINAPI AddAccessAllowedAceEx(
1541 IN OUT PACL pAcl,
1542 IN DWORD dwAceRevision,
1543 IN DWORD AceFlags,
1544 IN DWORD AccessMask,
1545 IN PSID pSid)
1547 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1550 /******************************************************************************
1551 * AddAccessDeniedAce [ADVAPI32.@]
1553 BOOL WINAPI AddAccessDeniedAce(
1554 IN OUT PACL pAcl,
1555 IN DWORD dwAceRevision,
1556 IN DWORD AccessMask,
1557 IN PSID pSid)
1559 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1562 /******************************************************************************
1563 * AddAccessDeniedAceEx [ADVAPI32.@]
1565 BOOL WINAPI AddAccessDeniedAceEx(
1566 IN OUT PACL pAcl,
1567 IN DWORD dwAceRevision,
1568 IN DWORD AceFlags,
1569 IN DWORD AccessMask,
1570 IN PSID pSid)
1572 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1575 /******************************************************************************
1576 * AddAce [ADVAPI32.@]
1578 BOOL WINAPI AddAce(
1579 IN OUT PACL pAcl,
1580 IN DWORD dwAceRevision,
1581 IN DWORD dwStartingAceIndex,
1582 LPVOID pAceList,
1583 DWORD nAceListLength)
1585 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1588 /******************************************************************************
1589 * DeleteAce [ADVAPI32.@]
1591 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1593 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1596 /******************************************************************************
1597 * FindFirstFreeAce [ADVAPI32.@]
1599 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1601 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1604 /******************************************************************************
1605 * GetAce [ADVAPI32.@]
1607 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1609 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1612 /******************************************************************************
1613 * GetAclInformation [ADVAPI32.@]
1615 BOOL WINAPI GetAclInformation(
1616 PACL pAcl,
1617 LPVOID pAclInformation,
1618 DWORD nAclInformationLength,
1619 ACL_INFORMATION_CLASS dwAclInformationClass)
1621 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1622 nAclInformationLength, dwAclInformationClass));
1625 /******************************************************************************
1626 * IsValidAcl [ADVAPI32.@]
1628 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1630 return RtlValidAcl(pAcl);
1633 /* ##############################
1634 ###### MISC FUNCTIONS ######
1635 ##############################
1638 /******************************************************************************
1639 * AllocateLocallyUniqueId [ADVAPI32.@]
1641 * PARAMS
1642 * lpLuid []
1644 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1646 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1649 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1650 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1651 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1652 { '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 };
1653 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1654 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1655 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1656 { '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 };
1657 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1658 { '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 };
1659 static const WCHAR SE_TCB_NAME_W[] =
1660 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1661 static const WCHAR SE_SECURITY_NAME_W[] =
1662 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1663 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1664 { '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 };
1665 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1666 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1667 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1668 { '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 };
1669 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1670 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1671 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1672 { '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 };
1673 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1674 { '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 };
1675 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1676 { '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 };
1677 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1678 { '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 };
1679 static const WCHAR SE_BACKUP_NAME_W[] =
1680 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1681 static const WCHAR SE_RESTORE_NAME_W[] =
1682 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1683 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1684 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1685 static const WCHAR SE_DEBUG_NAME_W[] =
1686 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1687 static const WCHAR SE_AUDIT_NAME_W[] =
1688 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1689 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1690 { '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 };
1691 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1692 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1693 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1694 { '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 };
1695 static const WCHAR SE_UNDOCK_NAME_W[] =
1696 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1697 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1698 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1699 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1700 { '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 };
1701 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1702 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1703 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1704 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1705 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1706 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1708 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1710 NULL,
1711 NULL,
1712 SE_CREATE_TOKEN_NAME_W,
1713 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1714 SE_LOCK_MEMORY_NAME_W,
1715 SE_INCREASE_QUOTA_NAME_W,
1716 SE_MACHINE_ACCOUNT_NAME_W,
1717 SE_TCB_NAME_W,
1718 SE_SECURITY_NAME_W,
1719 SE_TAKE_OWNERSHIP_NAME_W,
1720 SE_LOAD_DRIVER_NAME_W,
1721 SE_SYSTEM_PROFILE_NAME_W,
1722 SE_SYSTEMTIME_NAME_W,
1723 SE_PROF_SINGLE_PROCESS_NAME_W,
1724 SE_INC_BASE_PRIORITY_NAME_W,
1725 SE_CREATE_PAGEFILE_NAME_W,
1726 SE_CREATE_PERMANENT_NAME_W,
1727 SE_BACKUP_NAME_W,
1728 SE_RESTORE_NAME_W,
1729 SE_SHUTDOWN_NAME_W,
1730 SE_DEBUG_NAME_W,
1731 SE_AUDIT_NAME_W,
1732 SE_SYSTEM_ENVIRONMENT_NAME_W,
1733 SE_CHANGE_NOTIFY_NAME_W,
1734 SE_REMOTE_SHUTDOWN_NAME_W,
1735 SE_UNDOCK_NAME_W,
1736 SE_SYNC_AGENT_NAME_W,
1737 SE_ENABLE_DELEGATION_NAME_W,
1738 SE_MANAGE_VOLUME_NAME_W,
1739 SE_IMPERSONATE_NAME_W,
1740 SE_CREATE_GLOBAL_NAME_W,
1743 /******************************************************************************
1744 * LookupPrivilegeValueW [ADVAPI32.@]
1746 * See LookupPrivilegeValueA.
1748 BOOL WINAPI
1749 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1751 UINT i;
1753 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1755 if (!ADVAPI_IsLocalComputer(lpSystemName))
1757 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1758 return FALSE;
1760 if (!lpName)
1762 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1763 return FALSE;
1765 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1767 if( !WellKnownPrivNames[i] )
1768 continue;
1769 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1770 continue;
1771 lpLuid->LowPart = i;
1772 lpLuid->HighPart = 0;
1773 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1774 lpLuid->HighPart, lpLuid->LowPart );
1775 return TRUE;
1777 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1778 return FALSE;
1781 /******************************************************************************
1782 * LookupPrivilegeValueA [ADVAPI32.@]
1784 * Retrieves LUID used on a system to represent the privilege name.
1786 * PARAMS
1787 * lpSystemName [I] Name of the system
1788 * lpName [I] Name of the privilege
1789 * lpLuid [O] Destination for the resulting LUID
1791 * RETURNS
1792 * Success: TRUE. lpLuid contains the requested LUID.
1793 * Failure: FALSE.
1795 BOOL WINAPI
1796 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1798 UNICODE_STRING lpSystemNameW;
1799 UNICODE_STRING lpNameW;
1800 BOOL ret;
1802 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1803 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1804 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1805 RtlFreeUnicodeString(&lpNameW);
1806 RtlFreeUnicodeString(&lpSystemNameW);
1807 return ret;
1810 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1811 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1813 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1814 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1816 return FALSE;
1819 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1820 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1822 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1823 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1825 return FALSE;
1828 /******************************************************************************
1829 * LookupPrivilegeNameA [ADVAPI32.@]
1831 * See LookupPrivilegeNameW.
1833 BOOL WINAPI
1834 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1835 LPDWORD cchName)
1837 UNICODE_STRING lpSystemNameW;
1838 BOOL ret;
1839 DWORD wLen = 0;
1841 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1843 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1844 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1845 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1847 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1849 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1850 &wLen);
1851 if (ret)
1853 /* Windows crashes if cchName is NULL, so will I */
1854 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1855 *cchName, NULL, NULL);
1857 if (len == 0)
1859 /* WideCharToMultiByte failed */
1860 ret = FALSE;
1862 else if (len > *cchName)
1864 *cchName = len;
1865 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1866 ret = FALSE;
1868 else
1870 /* WideCharToMultiByte succeeded, output length needs to be
1871 * length not including NULL terminator
1873 *cchName = len - 1;
1876 HeapFree(GetProcessHeap(), 0, lpNameW);
1878 RtlFreeUnicodeString(&lpSystemNameW);
1879 return ret;
1882 /******************************************************************************
1883 * LookupPrivilegeNameW [ADVAPI32.@]
1885 * Retrieves the privilege name referred to by the LUID lpLuid.
1887 * PARAMS
1888 * lpSystemName [I] Name of the system
1889 * lpLuid [I] Privilege value
1890 * lpName [O] Name of the privilege
1891 * cchName [I/O] Number of characters in lpName.
1893 * RETURNS
1894 * Success: TRUE. lpName contains the name of the privilege whose value is
1895 * *lpLuid.
1896 * Failure: FALSE.
1898 * REMARKS
1899 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1900 * using this function.
1901 * If the length of lpName is too small, on return *cchName will contain the
1902 * number of WCHARs needed to contain the privilege, including the NULL
1903 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1904 * On success, *cchName will contain the number of characters stored in
1905 * lpName, NOT including the NULL terminator.
1907 BOOL WINAPI
1908 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1909 LPDWORD cchName)
1911 size_t privNameLen;
1913 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1915 if (!ADVAPI_IsLocalComputer(lpSystemName))
1917 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1918 return FALSE;
1920 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1921 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1923 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1924 return FALSE;
1926 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1927 /* Windows crashes if cchName is NULL, so will I */
1928 if (*cchName <= privNameLen)
1930 *cchName = privNameLen + 1;
1931 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1932 return FALSE;
1934 else
1936 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1937 *cchName = privNameLen;
1938 return TRUE;
1942 /******************************************************************************
1943 * GetFileSecurityA [ADVAPI32.@]
1945 * Obtains Specified information about the security of a file or directory.
1947 * PARAMS
1948 * lpFileName [I] Name of the file to get info for
1949 * RequestedInformation [I] SE_ flags from "winnt.h"
1950 * pSecurityDescriptor [O] Destination for security information
1951 * nLength [I] Length of pSecurityDescriptor
1952 * lpnLengthNeeded [O] Destination for length of returned security information
1954 * RETURNS
1955 * Success: TRUE. pSecurityDescriptor contains the requested information.
1956 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1958 * NOTES
1959 * The information returned is constrained by the callers access rights and
1960 * privileges.
1962 BOOL WINAPI
1963 GetFileSecurityA( LPCSTR lpFileName,
1964 SECURITY_INFORMATION RequestedInformation,
1965 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1966 DWORD nLength, LPDWORD lpnLengthNeeded )
1968 DWORD len;
1969 BOOL r;
1970 LPWSTR name = NULL;
1972 if( lpFileName )
1974 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1975 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1976 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1979 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1980 nLength, lpnLengthNeeded );
1981 HeapFree( GetProcessHeap(), 0, name );
1983 return r;
1986 /******************************************************************************
1987 * GetFileSecurityW [ADVAPI32.@]
1989 * See GetFileSecurityA.
1991 BOOL WINAPI
1992 GetFileSecurityW( LPCWSTR lpFileName,
1993 SECURITY_INFORMATION RequestedInformation,
1994 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1995 DWORD nLength, LPDWORD lpnLengthNeeded )
1997 HANDLE hfile;
1998 NTSTATUS status;
1999 DWORD access = 0;
2001 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2002 RequestedInformation, pSecurityDescriptor,
2003 nLength, lpnLengthNeeded);
2005 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2006 DACL_SECURITY_INFORMATION))
2007 access |= READ_CONTROL;
2008 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2009 access |= ACCESS_SYSTEM_SECURITY;
2011 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2012 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2013 if ( hfile == INVALID_HANDLE_VALUE )
2014 return FALSE;
2016 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2017 nLength, lpnLengthNeeded );
2018 CloseHandle( hfile );
2019 return set_ntstatus( status );
2023 /******************************************************************************
2024 * LookupAccountSidA [ADVAPI32.@]
2026 BOOL WINAPI
2027 LookupAccountSidA(
2028 IN LPCSTR system,
2029 IN PSID sid,
2030 OUT LPSTR account,
2031 IN OUT LPDWORD accountSize,
2032 OUT LPSTR domain,
2033 IN OUT LPDWORD domainSize,
2034 OUT PSID_NAME_USE name_use )
2036 DWORD len;
2037 BOOL r;
2038 LPWSTR systemW = NULL;
2039 LPWSTR accountW = NULL;
2040 LPWSTR domainW = NULL;
2041 DWORD accountSizeW = *accountSize;
2042 DWORD domainSizeW = *domainSize;
2044 if (system) {
2045 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2046 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2047 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2049 if (account)
2050 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2051 if (domain)
2052 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2054 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2056 if (r) {
2057 if (accountW && *accountSize) {
2058 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2059 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2060 *accountSize = len;
2061 } else
2062 *accountSize = accountSizeW + 1;
2064 if (domainW && *domainSize) {
2065 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2066 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2067 *domainSize = len;
2068 } else
2069 *domainSize = domainSizeW + 1;
2072 HeapFree( GetProcessHeap(), 0, systemW );
2073 HeapFree( GetProcessHeap(), 0, accountW );
2074 HeapFree( GetProcessHeap(), 0, domainW );
2076 return r;
2079 /******************************************************************************
2080 * LookupAccountSidW [ADVAPI32.@]
2082 * PARAMS
2083 * system []
2084 * sid []
2085 * account []
2086 * accountSize []
2087 * domain []
2088 * domainSize []
2089 * name_use []
2092 BOOL WINAPI
2093 LookupAccountSidW(
2094 IN LPCWSTR system,
2095 IN PSID sid,
2096 OUT LPWSTR account,
2097 IN OUT LPDWORD accountSize,
2098 OUT LPWSTR domain,
2099 IN OUT LPDWORD domainSize,
2100 OUT PSID_NAME_USE name_use )
2102 unsigned int i, j;
2103 const WCHAR * ac = NULL;
2104 const WCHAR * dm = NULL;
2105 SID_NAME_USE use = 0;
2106 LPWSTR computer_name = NULL;
2107 LPWSTR account_name = NULL;
2109 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2110 debugstr_w(system),debugstr_sid(sid),
2111 account,accountSize,accountSize?*accountSize:0,
2112 domain,domainSize,domainSize?*domainSize:0,
2113 name_use);
2115 if (!ADVAPI_IsLocalComputer(system)) {
2116 FIXME("Only local computer supported!\n");
2117 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2118 return FALSE;
2121 /* check the well known SIDs first */
2122 for (i = 0; i <= 60; i++) {
2123 if (IsWellKnownSid(sid, i)) {
2124 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2125 if (ACCOUNT_SIDS[j].type == i) {
2126 ac = ACCOUNT_SIDS[j].account;
2127 dm = ACCOUNT_SIDS[j].domain;
2128 use = ACCOUNT_SIDS[j].name_use;
2131 break;
2135 if (dm == NULL) {
2136 MAX_SID local;
2138 /* check for the local computer next */
2139 if (ADVAPI_GetComputerSid(&local)) {
2140 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2141 BOOL result;
2143 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2144 result = GetComputerNameW(computer_name, &size);
2146 if (result) {
2147 if (EqualSid(sid, &local)) {
2148 dm = computer_name;
2149 ac = Blank;
2150 use = 3;
2151 } else {
2152 local.SubAuthorityCount++;
2154 if (EqualPrefixSid(sid, &local)) {
2155 dm = computer_name;
2156 use = 1;
2157 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2158 case DOMAIN_USER_RID_ADMIN:
2159 ac = Administrator;
2160 break;
2161 case DOMAIN_USER_RID_GUEST:
2162 ac = Guest;
2163 break;
2164 case DOMAIN_GROUP_RID_ADMINS:
2165 ac = Domain_Admins;
2166 break;
2167 case DOMAIN_GROUP_RID_USERS:
2168 ac = Domain_Users;
2169 break;
2170 case DOMAIN_GROUP_RID_GUESTS:
2171 ac = Domain_Guests;
2172 break;
2173 case DOMAIN_GROUP_RID_COMPUTERS:
2174 ac = Domain_Computers;
2175 break;
2176 case DOMAIN_GROUP_RID_CONTROLLERS:
2177 ac = Domain_Controllers;
2178 break;
2179 case DOMAIN_GROUP_RID_CERT_ADMINS:
2180 ac = Cert_Publishers;
2181 break;
2182 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2183 ac = Schema_Admins;
2184 break;
2185 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2186 ac = Enterprise_Admins;
2187 break;
2188 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2189 ac = Group_Policy_Creator_Owners;
2190 break;
2191 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2192 ac = RAS_and_IAS_Servers;
2193 break;
2194 case 1000: /* first user account */
2195 size = UNLEN + 1;
2196 account_name = HeapAlloc(
2197 GetProcessHeap(), 0, size * sizeof(WCHAR));
2198 if (GetUserNameW(account_name, &size))
2199 ac = account_name;
2200 else
2201 dm = NULL;
2203 break;
2204 default:
2205 dm = NULL;
2206 break;
2214 if (dm) {
2215 DWORD ac_len = lstrlenW(ac);
2216 DWORD dm_len = lstrlenW(dm);
2217 BOOL status = TRUE;
2219 if (*accountSize > ac_len) {
2220 if (account)
2221 lstrcpyW(account, ac);
2223 if (*domainSize > dm_len) {
2224 if (domain)
2225 lstrcpyW(domain, dm);
2227 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2228 ((*domainSize != 0) && (*domainSize < dm_len))) {
2229 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2230 status = FALSE;
2232 if (*domainSize)
2233 *domainSize = dm_len;
2234 else
2235 *domainSize = dm_len + 1;
2236 if (*accountSize)
2237 *accountSize = ac_len;
2238 else
2239 *accountSize = ac_len + 1;
2240 *name_use = use;
2241 HeapFree(GetProcessHeap(), 0, account_name);
2242 HeapFree(GetProcessHeap(), 0, computer_name);
2243 return status;
2246 HeapFree(GetProcessHeap(), 0, account_name);
2247 HeapFree(GetProcessHeap(), 0, computer_name);
2248 SetLastError(ERROR_NONE_MAPPED);
2249 return FALSE;
2252 /******************************************************************************
2253 * SetFileSecurityA [ADVAPI32.@]
2255 * See SetFileSecurityW.
2257 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2258 SECURITY_INFORMATION RequestedInformation,
2259 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2261 DWORD len;
2262 BOOL r;
2263 LPWSTR name = NULL;
2265 if( lpFileName )
2267 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2268 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2269 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2272 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2273 HeapFree( GetProcessHeap(), 0, name );
2275 return r;
2278 /******************************************************************************
2279 * SetFileSecurityW [ADVAPI32.@]
2281 * Sets the security of a file or directory.
2283 * PARAMS
2284 * lpFileName []
2285 * RequestedInformation []
2286 * pSecurityDescriptor []
2288 * RETURNS
2289 * Success: TRUE.
2290 * Failure: FALSE.
2292 BOOL WINAPI
2293 SetFileSecurityW( LPCWSTR lpFileName,
2294 SECURITY_INFORMATION RequestedInformation,
2295 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2297 HANDLE file;
2298 DWORD access = 0;
2299 NTSTATUS status;
2301 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2302 pSecurityDescriptor );
2304 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2305 RequestedInformation & GROUP_SECURITY_INFORMATION)
2306 access |= WRITE_OWNER;
2307 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2308 access |= ACCESS_SYSTEM_SECURITY;
2309 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2310 access |= WRITE_DAC;
2312 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2313 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2314 if (file == INVALID_HANDLE_VALUE)
2315 return FALSE;
2317 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2318 CloseHandle( file );
2319 return set_ntstatus( status );
2322 /******************************************************************************
2323 * QueryWindows31FilesMigration [ADVAPI32.@]
2325 * PARAMS
2326 * x1 []
2328 BOOL WINAPI
2329 QueryWindows31FilesMigration( DWORD x1 )
2331 FIXME("(%d):stub\n",x1);
2332 return TRUE;
2335 /******************************************************************************
2336 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2338 * PARAMS
2339 * x1 []
2340 * x2 []
2341 * x3 []
2342 * x4 []
2344 BOOL WINAPI
2345 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2346 DWORD x4 )
2348 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2349 return TRUE;
2352 /******************************************************************************
2353 * NotifyBootConfigStatus [ADVAPI32.@]
2355 * PARAMS
2356 * x1 []
2358 BOOL WINAPI
2359 NotifyBootConfigStatus( BOOL x1 )
2361 FIXME("(0x%08d):stub\n",x1);
2362 return 1;
2365 /******************************************************************************
2366 * RevertToSelf [ADVAPI32.@]
2368 * Ends the impersonation of a user.
2370 * PARAMS
2371 * void []
2373 * RETURNS
2374 * Success: TRUE.
2375 * Failure: FALSE.
2377 BOOL WINAPI
2378 RevertToSelf( void )
2380 HANDLE Token = NULL;
2381 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2382 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2385 /******************************************************************************
2386 * ImpersonateSelf [ADVAPI32.@]
2388 * Makes an impersonation token that represents the process user and assigns
2389 * to the current thread.
2391 * PARAMS
2392 * ImpersonationLevel [I] Level at which to impersonate.
2394 * RETURNS
2395 * Success: TRUE.
2396 * Failure: FALSE.
2398 BOOL WINAPI
2399 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2401 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2404 /******************************************************************************
2405 * ImpersonateLoggedOnUser [ADVAPI32.@]
2407 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2409 DWORD size;
2410 NTSTATUS Status;
2411 HANDLE ImpersonationToken;
2412 TOKEN_TYPE Type;
2413 static BOOL warn = TRUE;
2415 if (warn)
2417 FIXME( "(%p)\n", hToken );
2418 warn = FALSE;
2420 if (!GetTokenInformation( hToken, TokenType, &Type,
2421 sizeof(TOKEN_TYPE), &size ))
2422 return FALSE;
2424 if (Type == TokenPrimary)
2426 OBJECT_ATTRIBUTES ObjectAttributes;
2428 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2430 Status = NtDuplicateToken( hToken,
2431 TOKEN_IMPERSONATE | TOKEN_QUERY,
2432 &ObjectAttributes,
2433 SecurityImpersonation,
2434 TokenImpersonation,
2435 &ImpersonationToken );
2436 if (Status != STATUS_SUCCESS)
2438 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2439 SetLastError( RtlNtStatusToDosError( Status ) );
2440 return FALSE;
2443 else
2444 ImpersonationToken = hToken;
2446 Status = NtSetInformationThread( GetCurrentThread(),
2447 ThreadImpersonationToken,
2448 &ImpersonationToken,
2449 sizeof(ImpersonationToken) );
2451 if (Type == TokenPrimary)
2452 NtClose( ImpersonationToken );
2454 if (Status != STATUS_SUCCESS)
2456 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2457 SetLastError( RtlNtStatusToDosError( Status ) );
2458 return FALSE;
2461 return TRUE;
2464 /******************************************************************************
2465 * AccessCheck [ADVAPI32.@]
2467 BOOL WINAPI
2468 AccessCheck(
2469 PSECURITY_DESCRIPTOR SecurityDescriptor,
2470 HANDLE ClientToken,
2471 DWORD DesiredAccess,
2472 PGENERIC_MAPPING GenericMapping,
2473 PPRIVILEGE_SET PrivilegeSet,
2474 LPDWORD PrivilegeSetLength,
2475 LPDWORD GrantedAccess,
2476 LPBOOL AccessStatus)
2478 NTSTATUS access_status;
2479 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2480 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2481 GrantedAccess, &access_status) );
2482 if (ret) *AccessStatus = set_ntstatus( access_status );
2483 return ret;
2487 /******************************************************************************
2488 * AccessCheckByType [ADVAPI32.@]
2490 BOOL WINAPI AccessCheckByType(
2491 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2492 PSID PrincipalSelfSid,
2493 HANDLE ClientToken,
2494 DWORD DesiredAccess,
2495 POBJECT_TYPE_LIST ObjectTypeList,
2496 DWORD ObjectTypeListLength,
2497 PGENERIC_MAPPING GenericMapping,
2498 PPRIVILEGE_SET PrivilegeSet,
2499 LPDWORD PrivilegeSetLength,
2500 LPDWORD GrantedAccess,
2501 LPBOOL AccessStatus)
2503 FIXME("stub\n");
2505 *AccessStatus = TRUE;
2507 return !*AccessStatus;
2510 /******************************************************************************
2511 * MapGenericMask [ADVAPI32.@]
2513 * Maps generic access rights into specific access rights according to the
2514 * supplied mapping.
2516 * PARAMS
2517 * AccessMask [I/O] Access rights.
2518 * GenericMapping [I] The mapping between generic and specific rights.
2520 * RETURNS
2521 * Nothing.
2523 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2525 RtlMapGenericMask( AccessMask, GenericMapping );
2528 /*************************************************************************
2529 * SetKernelObjectSecurity [ADVAPI32.@]
2531 BOOL WINAPI SetKernelObjectSecurity (
2532 IN HANDLE Handle,
2533 IN SECURITY_INFORMATION SecurityInformation,
2534 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2536 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2540 /******************************************************************************
2541 * AddAuditAccessAce [ADVAPI32.@]
2543 BOOL WINAPI AddAuditAccessAce(
2544 IN OUT PACL pAcl,
2545 IN DWORD dwAceRevision,
2546 IN DWORD dwAccessMask,
2547 IN PSID pSid,
2548 IN BOOL bAuditSuccess,
2549 IN BOOL bAuditFailure)
2551 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2552 bAuditSuccess, bAuditFailure) );
2555 /******************************************************************************
2556 * AddAuditAccessAce [ADVAPI32.@]
2558 BOOL WINAPI AddAuditAccessAceEx(
2559 IN OUT PACL pAcl,
2560 IN DWORD dwAceRevision,
2561 IN DWORD dwAceFlags,
2562 IN DWORD dwAccessMask,
2563 IN PSID pSid,
2564 IN BOOL bAuditSuccess,
2565 IN BOOL bAuditFailure)
2567 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2568 bAuditSuccess, bAuditFailure) );
2571 /******************************************************************************
2572 * LookupAccountNameA [ADVAPI32.@]
2574 BOOL WINAPI
2575 LookupAccountNameA(
2576 IN LPCSTR system,
2577 IN LPCSTR account,
2578 OUT PSID sid,
2579 OUT LPDWORD cbSid,
2580 LPSTR ReferencedDomainName,
2581 IN OUT LPDWORD cbReferencedDomainName,
2582 OUT PSID_NAME_USE name_use )
2584 BOOL ret;
2585 UNICODE_STRING lpSystemW;
2586 UNICODE_STRING lpAccountW;
2587 LPWSTR lpReferencedDomainNameW = NULL;
2589 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2590 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2592 if (ReferencedDomainName)
2593 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2595 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2596 cbReferencedDomainName, name_use);
2598 if (ret && lpReferencedDomainNameW)
2600 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2601 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2604 RtlFreeUnicodeString(&lpSystemW);
2605 RtlFreeUnicodeString(&lpAccountW);
2606 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2608 return ret;
2611 /******************************************************************************
2612 * lookup_user_account_name
2614 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2615 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2617 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2618 DWORD len = sizeof(buffer);
2619 HANDLE token;
2620 BOOL ret;
2621 PSID pSid;
2622 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2623 DWORD nameLen;
2624 LPCWSTR domainName;
2626 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2628 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2629 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2632 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2633 CloseHandle( token );
2635 if (!ret) return FALSE;
2637 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2639 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2640 CopySid(*cbSid, Sid, pSid);
2641 if (*cbSid < GetLengthSid(pSid))
2643 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2644 ret = FALSE;
2646 *cbSid = GetLengthSid(pSid);
2648 domainName = dm;
2649 nameLen = strlenW(domainName);
2651 if (*cchReferencedDomainName <= nameLen || !ret)
2653 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2654 nameLen += 1;
2655 ret = FALSE;
2657 else if (ReferencedDomainName)
2658 strcpyW(ReferencedDomainName, domainName);
2660 *cchReferencedDomainName = nameLen;
2662 if (ret)
2663 *peUse = SidTypeUser;
2665 return ret;
2668 /******************************************************************************
2669 * lookup_computer_account_name
2671 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2672 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2674 MAX_SID local;
2675 BOOL ret;
2676 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2677 DWORD nameLen;
2678 LPCWSTR domainName;
2680 if ((ret = ADVAPI_GetComputerSid(&local)))
2682 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2683 CopySid(*cbSid, Sid, &local);
2684 if (*cbSid < GetLengthSid(&local))
2686 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2687 ret = FALSE;
2689 *cbSid = GetLengthSid(&local);
2692 domainName = dm;
2693 nameLen = strlenW(domainName);
2695 if (*cchReferencedDomainName <= nameLen || !ret)
2697 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2698 nameLen += 1;
2699 ret = FALSE;
2701 else if (ReferencedDomainName)
2702 strcpyW(ReferencedDomainName, domainName);
2704 *cchReferencedDomainName = nameLen;
2706 if (ret)
2707 *peUse = SidTypeDomain;
2709 return ret;
2712 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2713 LSA_UNICODE_STRING *domain )
2715 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2717 while (p > str->Buffer && *p != '\\') p--;
2719 if (*p == '\\')
2721 domain->Buffer = str->Buffer;
2722 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2724 account->Buffer = p + 1;
2725 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2727 else
2729 domain->Buffer = NULL;
2730 domain->Length = 0;
2732 account->Buffer = str->Buffer;
2733 account->Length = str->Length;
2737 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2739 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2741 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2742 return TRUE;
2744 return FALSE;
2747 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2749 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2751 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2752 return TRUE;
2754 if (ACCOUNT_SIDS[idx].alias)
2756 len = strlenW( ACCOUNT_SIDS[idx].alias );
2757 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2758 return TRUE;
2760 return FALSE;
2764 * Helper function for LookupAccountNameW
2766 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2767 PSID Sid, LPDWORD cbSid,
2768 LPWSTR ReferencedDomainName,
2769 LPDWORD cchReferencedDomainName,
2770 PSID_NAME_USE peUse, BOOL *handled )
2772 PSID pSid;
2773 LSA_UNICODE_STRING account, domain;
2774 BOOL ret = TRUE;
2775 ULONG i;
2777 *handled = FALSE;
2778 split_domain_account( account_and_domain, &account, &domain );
2780 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2782 /* check domain first */
2783 if (domain.Buffer && !match_domain( i, &domain )) continue;
2785 if (match_account( i, &account ))
2787 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2789 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2791 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2793 if (*cbSid < sidLen)
2795 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2796 ret = FALSE;
2798 else if (Sid)
2800 CopySid(*cbSid, Sid, pSid);
2802 *cbSid = sidLen;
2805 len = strlenW( ACCOUNT_SIDS[i].domain );
2806 if (*cchReferencedDomainName <= len || !ret)
2808 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2809 len++;
2810 ret = FALSE;
2812 else if (ReferencedDomainName)
2814 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2817 *cchReferencedDomainName = len;
2818 if (ret)
2819 *peUse = ACCOUNT_SIDS[i].name_use;
2821 HeapFree(GetProcessHeap(), 0, pSid);
2822 *handled = TRUE;
2823 return ret;
2826 return ret;
2829 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2830 PSID Sid, LPDWORD cbSid,
2831 LPWSTR ReferencedDomainName,
2832 LPDWORD cchReferencedDomainName,
2833 PSID_NAME_USE peUse, BOOL *handled )
2835 DWORD nameLen;
2836 LPWSTR userName = NULL;
2837 LSA_UNICODE_STRING account, domain;
2838 BOOL ret = TRUE;
2840 *handled = FALSE;
2841 split_domain_account( account_and_domain, &account, &domain );
2843 /* Let the current Unix user id masquerade as first Windows user account */
2845 nameLen = UNLEN + 1;
2846 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2848 if (domain.Buffer)
2850 /* check to make sure this account is on this computer */
2851 if (GetComputerNameW( userName, &nameLen ) &&
2852 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2854 SetLastError(ERROR_NONE_MAPPED);
2855 ret = FALSE;
2857 nameLen = UNLEN + 1;
2860 if (GetUserNameW( userName, &nameLen ) &&
2861 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2863 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2864 *handled = TRUE;
2866 else
2868 nameLen = UNLEN + 1;
2869 if (GetComputerNameW( userName, &nameLen ) &&
2870 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2872 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2873 *handled = TRUE;
2877 HeapFree(GetProcessHeap(), 0, userName);
2878 return ret;
2881 /******************************************************************************
2882 * LookupAccountNameW [ADVAPI32.@]
2884 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2885 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2886 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2888 BOOL ret, handled;
2889 LSA_UNICODE_STRING account;
2891 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2892 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2894 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2896 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2897 return FALSE;
2900 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2902 lpAccountName = BUILTIN;
2905 RtlInitUnicodeString( &account, lpAccountName );
2907 /* Check well known SIDs first */
2908 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2909 cchReferencedDomainName, peUse, &handled );
2910 if (handled)
2911 return ret;
2913 /* Check user names */
2914 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2915 cchReferencedDomainName, peUse, &handled);
2916 if (handled)
2917 return ret;
2919 SetLastError( ERROR_NONE_MAPPED );
2920 return FALSE;
2923 /******************************************************************************
2924 * PrivilegeCheck [ADVAPI32.@]
2926 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2928 BOOL ret;
2929 BOOLEAN Result;
2931 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2933 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2934 if (ret)
2935 *pfResult = Result;
2936 return ret;
2939 /******************************************************************************
2940 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2942 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2943 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2944 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2945 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2947 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2948 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2949 SecurityDescriptor, DesiredAccess, GenericMapping,
2950 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2951 return TRUE;
2954 /******************************************************************************
2955 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2957 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2958 LPWSTR 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_w(Subsystem),
2963 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2964 SecurityDescriptor, DesiredAccess, GenericMapping,
2965 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2966 return TRUE;
2969 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2971 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2973 return TRUE;
2976 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2978 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2980 return TRUE;
2983 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2985 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2987 return TRUE;
2990 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2991 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2992 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2993 LPBOOL GenerateOnClose)
2995 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2996 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2997 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2998 GenerateOnClose);
3000 return TRUE;
3003 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3004 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3005 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3006 LPBOOL GenerateOnClose)
3008 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3009 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3010 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3011 GenerateOnClose);
3013 return TRUE;
3016 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3017 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3019 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3020 DesiredAccess, Privileges, AccessGranted);
3022 return TRUE;
3025 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3026 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3028 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3029 DesiredAccess, Privileges, AccessGranted);
3031 return TRUE;
3034 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3035 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3037 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3038 ClientToken, Privileges, AccessGranted);
3040 return TRUE;
3043 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3044 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3046 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3047 ClientToken, Privileges, AccessGranted);
3049 return TRUE;
3052 /******************************************************************************
3053 * GetSecurityInfo [ADVAPI32.@]
3055 * Retrieves a copy of the security descriptor associated with an object.
3057 * PARAMS
3058 * hObject [I] A handle for the object.
3059 * ObjectType [I] The type of object.
3060 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3061 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3062 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3063 * ppDacl [O] If non-null, receives a pointer to the DACL.
3064 * ppSacl [O] If non-null, receives a pointer to the SACL.
3065 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3066 * which must be freed with LocalFree.
3068 * RETURNS
3069 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3071 DWORD WINAPI GetSecurityInfo(
3072 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3073 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3074 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3075 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3078 PSECURITY_DESCRIPTOR sd;
3079 NTSTATUS status;
3080 ULONG n1, n2;
3081 BOOL present, defaulted;
3083 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3084 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3085 return RtlNtStatusToDosError(status);
3087 sd = LocalAlloc(0, n1);
3088 if (!sd)
3089 return ERROR_NOT_ENOUGH_MEMORY;
3091 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3092 if (status != STATUS_SUCCESS)
3094 LocalFree(sd);
3095 return RtlNtStatusToDosError(status);
3098 if (ppsidOwner)
3100 *ppsidOwner = NULL;
3101 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3103 if (ppsidGroup)
3105 *ppsidGroup = NULL;
3106 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3108 if (ppDacl)
3110 *ppDacl = NULL;
3111 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3113 if (ppSacl)
3115 *ppSacl = NULL;
3116 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3118 if (ppSecurityDescriptor)
3119 *ppSecurityDescriptor = sd;
3121 return ERROR_SUCCESS;
3124 /******************************************************************************
3125 * GetSecurityInfoExA [ADVAPI32.@]
3127 DWORD WINAPI GetSecurityInfoExA(
3128 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3129 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3130 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3131 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3134 FIXME("stub!\n");
3135 return ERROR_BAD_PROVIDER;
3138 /******************************************************************************
3139 * GetSecurityInfoExW [ADVAPI32.@]
3141 DWORD WINAPI GetSecurityInfoExW(
3142 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3143 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3144 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3145 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3148 FIXME("stub!\n");
3149 return ERROR_BAD_PROVIDER;
3152 /******************************************************************************
3153 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3155 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3156 LPSTR pTrusteeName, DWORD AccessPermissions,
3157 ACCESS_MODE AccessMode, DWORD Inheritance )
3159 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3160 AccessPermissions, AccessMode, Inheritance);
3162 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3163 pExplicitAccess->grfAccessMode = AccessMode;
3164 pExplicitAccess->grfInheritance = Inheritance;
3166 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3167 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3168 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3169 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3170 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3173 /******************************************************************************
3174 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3176 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3177 LPWSTR pTrusteeName, DWORD AccessPermissions,
3178 ACCESS_MODE AccessMode, DWORD Inheritance )
3180 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3181 AccessPermissions, AccessMode, Inheritance);
3183 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3184 pExplicitAccess->grfAccessMode = AccessMode;
3185 pExplicitAccess->grfInheritance = Inheritance;
3187 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3188 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3189 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3190 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3191 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3194 /******************************************************************************
3195 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3197 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3198 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3199 LPSTR InheritedObjectTypeName, LPSTR Name )
3201 DWORD ObjectsPresent = 0;
3203 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3204 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3206 /* Fill the OBJECTS_AND_NAME structure */
3207 pObjName->ObjectType = ObjectType;
3208 if (ObjectTypeName != NULL)
3210 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3213 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3214 if (InheritedObjectTypeName != NULL)
3216 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3219 pObjName->ObjectsPresent = ObjectsPresent;
3220 pObjName->ptstrName = Name;
3222 /* Fill the TRUSTEE structure */
3223 pTrustee->pMultipleTrustee = NULL;
3224 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3225 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3226 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3227 pTrustee->ptstrName = (LPSTR)pObjName;
3230 /******************************************************************************
3231 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3233 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3234 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3235 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3237 DWORD ObjectsPresent = 0;
3239 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3240 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3242 /* Fill the OBJECTS_AND_NAME structure */
3243 pObjName->ObjectType = ObjectType;
3244 if (ObjectTypeName != NULL)
3246 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3249 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3250 if (InheritedObjectTypeName != NULL)
3252 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3255 pObjName->ObjectsPresent = ObjectsPresent;
3256 pObjName->ptstrName = Name;
3258 /* Fill the TRUSTEE structure */
3259 pTrustee->pMultipleTrustee = NULL;
3260 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3261 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3262 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3263 pTrustee->ptstrName = (LPWSTR)pObjName;
3266 /******************************************************************************
3267 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3269 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3270 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3272 DWORD ObjectsPresent = 0;
3274 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3276 /* Fill the OBJECTS_AND_SID structure */
3277 if (pObjectGuid != NULL)
3279 pObjSid->ObjectTypeGuid = *pObjectGuid;
3280 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3282 else
3284 ZeroMemory(&pObjSid->ObjectTypeGuid,
3285 sizeof(GUID));
3288 if (pInheritedObjectGuid != NULL)
3290 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3291 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3293 else
3295 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3296 sizeof(GUID));
3299 pObjSid->ObjectsPresent = ObjectsPresent;
3300 pObjSid->pSid = pSid;
3302 /* Fill the TRUSTEE structure */
3303 pTrustee->pMultipleTrustee = NULL;
3304 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3305 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3306 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3307 pTrustee->ptstrName = (LPSTR) pObjSid;
3310 /******************************************************************************
3311 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3313 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3314 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3316 DWORD ObjectsPresent = 0;
3318 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3320 /* Fill the OBJECTS_AND_SID structure */
3321 if (pObjectGuid != NULL)
3323 pObjSid->ObjectTypeGuid = *pObjectGuid;
3324 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3326 else
3328 ZeroMemory(&pObjSid->ObjectTypeGuid,
3329 sizeof(GUID));
3332 if (pInheritedObjectGuid != NULL)
3334 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3335 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3337 else
3339 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3340 sizeof(GUID));
3343 pObjSid->ObjectsPresent = ObjectsPresent;
3344 pObjSid->pSid = pSid;
3346 /* Fill the TRUSTEE structure */
3347 pTrustee->pMultipleTrustee = NULL;
3348 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3349 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3350 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3351 pTrustee->ptstrName = (LPWSTR) pObjSid;
3354 /******************************************************************************
3355 * BuildTrusteeWithSidA [ADVAPI32.@]
3357 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3359 TRACE("%p %p\n", pTrustee, pSid);
3361 pTrustee->pMultipleTrustee = NULL;
3362 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3363 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3364 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3365 pTrustee->ptstrName = pSid;
3368 /******************************************************************************
3369 * BuildTrusteeWithSidW [ADVAPI32.@]
3371 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3373 TRACE("%p %p\n", pTrustee, pSid);
3375 pTrustee->pMultipleTrustee = NULL;
3376 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3377 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3378 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3379 pTrustee->ptstrName = pSid;
3382 /******************************************************************************
3383 * BuildTrusteeWithNameA [ADVAPI32.@]
3385 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3387 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3389 pTrustee->pMultipleTrustee = NULL;
3390 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3391 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3392 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3393 pTrustee->ptstrName = name;
3396 /******************************************************************************
3397 * BuildTrusteeWithNameW [ADVAPI32.@]
3399 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3401 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3403 pTrustee->pMultipleTrustee = NULL;
3404 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3405 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3406 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3407 pTrustee->ptstrName = name;
3410 /******************************************************************************
3411 * GetTrusteeFormA [ADVAPI32.@]
3413 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3415 TRACE("(%p)\n", pTrustee);
3417 if (!pTrustee)
3418 return TRUSTEE_BAD_FORM;
3420 return pTrustee->TrusteeForm;
3423 /******************************************************************************
3424 * GetTrusteeFormW [ADVAPI32.@]
3426 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3428 TRACE("(%p)\n", pTrustee);
3430 if (!pTrustee)
3431 return TRUSTEE_BAD_FORM;
3433 return pTrustee->TrusteeForm;
3436 /******************************************************************************
3437 * GetTrusteeNameA [ADVAPI32.@]
3439 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3441 TRACE("(%p)\n", pTrustee);
3443 if (!pTrustee)
3444 return NULL;
3446 return pTrustee->ptstrName;
3449 /******************************************************************************
3450 * GetTrusteeNameW [ADVAPI32.@]
3452 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3454 TRACE("(%p)\n", pTrustee);
3456 if (!pTrustee)
3457 return NULL;
3459 return pTrustee->ptstrName;
3462 /******************************************************************************
3463 * GetTrusteeTypeA [ADVAPI32.@]
3465 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3467 TRACE("(%p)\n", pTrustee);
3469 if (!pTrustee)
3470 return TRUSTEE_IS_UNKNOWN;
3472 return pTrustee->TrusteeType;
3475 /******************************************************************************
3476 * GetTrusteeTypeW [ADVAPI32.@]
3478 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3480 TRACE("(%p)\n", pTrustee);
3482 if (!pTrustee)
3483 return TRUSTEE_IS_UNKNOWN;
3485 return pTrustee->TrusteeType;
3488 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3489 DWORD nAclInformationLength,
3490 ACL_INFORMATION_CLASS dwAclInformationClass )
3492 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3493 nAclInformationLength, dwAclInformationClass);
3495 return TRUE;
3498 /******************************************************************************
3499 * SetEntriesInAclA [ADVAPI32.@]
3501 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3502 PACL OldAcl, PACL* NewAcl )
3504 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3505 if (NewAcl)
3506 *NewAcl = NULL;
3507 return ERROR_SUCCESS;
3510 /******************************************************************************
3511 * SetEntriesInAclW [ADVAPI32.@]
3513 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3514 PACL OldAcl, PACL* NewAcl )
3516 ULONG i;
3517 PSID *ppsid;
3518 DWORD ret = ERROR_SUCCESS;
3519 DWORD acl_size = sizeof(ACL);
3520 NTSTATUS status;
3522 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3524 *NewAcl = NULL;
3526 if (!count && !OldAcl)
3527 return ERROR_SUCCESS;
3529 /* allocate array of maximum sized sids allowed */
3530 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3531 if (!ppsid)
3532 return ERROR_OUTOFMEMORY;
3534 for (i = 0; i < count; i++)
3536 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3538 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3539 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3540 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3541 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3542 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3543 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3544 pEntries[i].Trustee.ptstrName);
3546 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3548 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3549 ret = ERROR_INVALID_PARAMETER;
3550 goto exit;
3553 switch (pEntries[i].Trustee.TrusteeForm)
3555 case TRUSTEE_IS_SID:
3556 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3557 ppsid[i], pEntries[i].Trustee.ptstrName))
3559 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3560 ret = ERROR_INVALID_PARAMETER;
3561 goto exit;
3563 break;
3564 case TRUSTEE_IS_NAME:
3566 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3567 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3568 SID_NAME_USE use;
3569 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3571 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3573 ret = GetLastError();
3574 goto exit;
3577 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3579 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3580 ret = ERROR_INVALID_PARAMETER;
3581 goto exit;
3583 break;
3585 case TRUSTEE_IS_OBJECTS_AND_SID:
3586 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3587 break;
3588 case TRUSTEE_IS_OBJECTS_AND_NAME:
3589 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3590 break;
3591 default:
3592 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3593 ret = ERROR_INVALID_PARAMETER;
3594 goto exit;
3597 /* Note: we overestimate the ACL size here as a tradeoff between
3598 * instructions (simplicity) and memory */
3599 switch (pEntries[i].grfAccessMode)
3601 case GRANT_ACCESS:
3602 case SET_ACCESS:
3603 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3604 break;
3605 case DENY_ACCESS:
3606 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3607 break;
3608 case SET_AUDIT_SUCCESS:
3609 case SET_AUDIT_FAILURE:
3610 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3611 break;
3612 case REVOKE_ACCESS:
3613 break;
3614 default:
3615 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3616 ret = ERROR_INVALID_PARAMETER;
3617 goto exit;
3621 if (OldAcl)
3623 ACL_SIZE_INFORMATION size_info;
3625 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3626 if (status != STATUS_SUCCESS)
3628 ret = RtlNtStatusToDosError(status);
3629 goto exit;
3631 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3634 *NewAcl = LocalAlloc(0, acl_size);
3635 if (!*NewAcl)
3637 ret = ERROR_OUTOFMEMORY;
3638 goto exit;
3641 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3642 if (status != STATUS_SUCCESS)
3644 ret = RtlNtStatusToDosError(status);
3645 goto exit;
3648 for (i = 0; i < count; i++)
3650 switch (pEntries[i].grfAccessMode)
3652 case GRANT_ACCESS:
3653 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3654 pEntries[i].grfInheritance,
3655 pEntries[i].grfAccessPermissions,
3656 ppsid[i]);
3657 break;
3658 case SET_ACCESS:
3660 ULONG j;
3661 BOOL add = TRUE;
3662 if (OldAcl)
3664 for (j = 0; ; j++)
3666 const ACE_HEADER *existing_ace_header;
3667 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3668 if (status != STATUS_SUCCESS)
3669 break;
3670 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3671 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3672 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3674 add = FALSE;
3675 break;
3679 if (add)
3680 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3681 pEntries[i].grfInheritance,
3682 pEntries[i].grfAccessPermissions,
3683 ppsid[i]);
3684 break;
3686 case DENY_ACCESS:
3687 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3688 pEntries[i].grfInheritance,
3689 pEntries[i].grfAccessPermissions,
3690 ppsid[i]);
3691 break;
3692 case SET_AUDIT_SUCCESS:
3693 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3694 pEntries[i].grfInheritance,
3695 pEntries[i].grfAccessPermissions,
3696 ppsid[i], TRUE, FALSE);
3697 break;
3698 case SET_AUDIT_FAILURE:
3699 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3700 pEntries[i].grfInheritance,
3701 pEntries[i].grfAccessPermissions,
3702 ppsid[i], FALSE, TRUE);
3703 break;
3704 default:
3705 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3709 if (OldAcl)
3711 for (i = 0; ; i++)
3713 BOOL add = TRUE;
3714 ULONG j;
3715 const ACE_HEADER *old_ace_header;
3716 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3717 if (status != STATUS_SUCCESS) break;
3718 for (j = 0; j < count; j++)
3720 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3721 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3722 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3724 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3725 add = FALSE;
3726 break;
3728 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3730 switch (old_ace_header->AceType)
3732 case ACCESS_ALLOWED_ACE_TYPE:
3733 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3734 add = FALSE;
3735 break;
3736 case ACCESS_DENIED_ACE_TYPE:
3737 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3738 add = FALSE;
3739 break;
3740 case SYSTEM_AUDIT_ACE_TYPE:
3741 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3742 add = FALSE;
3743 break;
3744 case SYSTEM_ALARM_ACE_TYPE:
3745 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3746 add = FALSE;
3747 break;
3748 default:
3749 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3752 if (!add)
3753 break;
3756 if (add)
3757 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3758 if (status != STATUS_SUCCESS)
3760 WARN("RtlAddAce failed with error 0x%08x\n", status);
3761 ret = RtlNtStatusToDosError(status);
3762 break;
3767 exit:
3768 HeapFree(GetProcessHeap(), 0, ppsid);
3769 return ret;
3772 /******************************************************************************
3773 * SetNamedSecurityInfoA [ADVAPI32.@]
3775 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3776 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3777 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3779 DWORD len;
3780 LPWSTR wstr = NULL;
3781 DWORD r;
3783 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3784 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3786 if( pObjectName )
3788 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3789 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3790 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3793 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3794 psidGroup, pDacl, pSacl );
3796 HeapFree( GetProcessHeap(), 0, wstr );
3798 return r;
3801 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3802 PSECURITY_DESCRIPTOR ModificationDescriptor,
3803 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3804 PGENERIC_MAPPING GenericMapping,
3805 HANDLE Token )
3807 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3808 ObjectsSecurityDescriptor, GenericMapping, Token);
3810 return TRUE;
3813 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3815 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3818 /******************************************************************************
3819 * AreAnyAccessesGranted [ADVAPI32.@]
3821 * Determines whether or not any of a set of specified access permissions have
3822 * been granted or not.
3824 * PARAMS
3825 * GrantedAccess [I] The permissions that have been granted.
3826 * DesiredAccess [I] The permissions that you want to have.
3828 * RETURNS
3829 * Nonzero if any of the permissions have been granted, zero if none of the
3830 * permissions have been granted.
3833 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3835 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3838 /******************************************************************************
3839 * SetNamedSecurityInfoW [ADVAPI32.@]
3841 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3842 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3843 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3845 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3846 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3847 return ERROR_SUCCESS;
3850 /******************************************************************************
3851 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3853 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3854 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3856 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3857 return ERROR_CALL_NOT_IMPLEMENTED;
3860 /******************************************************************************
3861 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3863 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3864 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3866 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3867 return ERROR_CALL_NOT_IMPLEMENTED;
3870 /******************************************************************************
3871 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3873 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3874 PACCESS_MASK pFailedAuditRights)
3876 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3877 return ERROR_CALL_NOT_IMPLEMENTED;
3881 /******************************************************************************
3882 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3884 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3885 PACCESS_MASK pFailedAuditRights)
3887 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3888 return ERROR_CALL_NOT_IMPLEMENTED;
3892 /******************************************************************************
3893 * ParseAclStringFlags
3895 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3897 DWORD flags = 0;
3898 LPCWSTR szAcl = *StringAcl;
3900 while (*szAcl != '(')
3902 if (*szAcl == 'P')
3904 flags |= SE_DACL_PROTECTED;
3906 else if (*szAcl == 'A')
3908 szAcl++;
3909 if (*szAcl == 'R')
3910 flags |= SE_DACL_AUTO_INHERIT_REQ;
3911 else if (*szAcl == 'I')
3912 flags |= SE_DACL_AUTO_INHERITED;
3914 szAcl++;
3917 *StringAcl = szAcl;
3918 return flags;
3921 /******************************************************************************
3922 * ParseAceStringType
3924 static const ACEFLAG AceType[] =
3926 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3927 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3928 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3929 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3931 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3932 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3933 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3934 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3936 { NULL, 0 },
3939 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3941 UINT len = 0;
3942 LPCWSTR szAcl = *StringAcl;
3943 const ACEFLAG *lpaf = AceType;
3945 while (*szAcl == ' ')
3946 szAcl++;
3948 while (lpaf->wstr &&
3949 (len = strlenW(lpaf->wstr)) &&
3950 strncmpW(lpaf->wstr, szAcl, len))
3951 lpaf++;
3953 if (!lpaf->wstr)
3954 return 0;
3956 *StringAcl = szAcl + len;
3957 return lpaf->value;
3961 /******************************************************************************
3962 * ParseAceStringFlags
3964 static const ACEFLAG AceFlags[] =
3966 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3967 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3968 { SDDL_INHERITED, INHERITED_ACE },
3969 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3970 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3971 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3972 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3973 { NULL, 0 },
3976 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3978 UINT len = 0;
3979 BYTE flags = 0;
3980 LPCWSTR szAcl = *StringAcl;
3982 while (*szAcl == ' ')
3983 szAcl++;
3985 while (*szAcl != ';')
3987 const ACEFLAG *lpaf = AceFlags;
3989 while (lpaf->wstr &&
3990 (len = strlenW(lpaf->wstr)) &&
3991 strncmpW(lpaf->wstr, szAcl, len))
3992 lpaf++;
3994 if (!lpaf->wstr)
3995 return 0;
3997 flags |= lpaf->value;
3998 szAcl += len;
4001 *StringAcl = szAcl;
4002 return flags;
4006 /******************************************************************************
4007 * ParseAceStringRights
4009 static const ACEFLAG AceRights[] =
4011 { SDDL_GENERIC_ALL, GENERIC_ALL },
4012 { SDDL_GENERIC_READ, GENERIC_READ },
4013 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4014 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4016 { SDDL_READ_CONTROL, READ_CONTROL },
4017 { SDDL_STANDARD_DELETE, DELETE },
4018 { SDDL_WRITE_DAC, WRITE_DAC },
4019 { SDDL_WRITE_OWNER, WRITE_OWNER },
4021 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4022 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4023 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4024 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4025 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4026 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4027 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4028 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4029 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4031 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4032 { SDDL_FILE_READ, FILE_GENERIC_READ },
4033 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4034 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4036 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4037 { SDDL_KEY_READ, KEY_READ },
4038 { SDDL_KEY_WRITE, KEY_WRITE },
4039 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4040 { NULL, 0 },
4043 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4045 UINT len = 0;
4046 DWORD rights = 0;
4047 LPCWSTR szAcl = *StringAcl;
4049 while (*szAcl == ' ')
4050 szAcl++;
4052 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4054 LPCWSTR p = szAcl;
4056 while (*p && *p != ';')
4057 p++;
4059 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4061 rights = strtoulW(szAcl, NULL, 16);
4062 szAcl = p;
4064 else
4065 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4067 else
4069 while (*szAcl != ';')
4071 const ACEFLAG *lpaf = AceRights;
4073 while (lpaf->wstr &&
4074 (len = strlenW(lpaf->wstr)) &&
4075 strncmpW(lpaf->wstr, szAcl, len))
4077 lpaf++;
4080 if (!lpaf->wstr)
4081 return 0;
4083 rights |= lpaf->value;
4084 szAcl += len;
4088 *StringAcl = szAcl;
4089 return rights;
4093 /******************************************************************************
4094 * ParseStringAclToAcl
4096 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4098 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4099 PACL pAcl, LPDWORD cBytes)
4101 DWORD val;
4102 DWORD sidlen;
4103 DWORD length = sizeof(ACL);
4104 DWORD acesize = 0;
4105 DWORD acecount = 0;
4106 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4107 DWORD error = ERROR_INVALID_ACL;
4109 TRACE("%s\n", debugstr_w(StringAcl));
4111 if (!StringAcl)
4112 return FALSE;
4114 if (pAcl) /* pAce is only useful if we're setting values */
4115 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4117 /* Parse ACL flags */
4118 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4120 /* Parse ACE */
4121 while (*StringAcl == '(')
4123 StringAcl++;
4125 /* Parse ACE type */
4126 val = ParseAceStringType(&StringAcl);
4127 if (pAce)
4128 pAce->Header.AceType = (BYTE) val;
4129 if (*StringAcl != ';')
4131 error = RPC_S_INVALID_STRING_UUID;
4132 goto lerr;
4134 StringAcl++;
4136 /* Parse ACE flags */
4137 val = ParseAceStringFlags(&StringAcl);
4138 if (pAce)
4139 pAce->Header.AceFlags = (BYTE) val;
4140 if (*StringAcl != ';')
4141 goto lerr;
4142 StringAcl++;
4144 /* Parse ACE rights */
4145 val = ParseAceStringRights(&StringAcl);
4146 if (pAce)
4147 pAce->Mask = val;
4148 if (*StringAcl != ';')
4149 goto lerr;
4150 StringAcl++;
4152 /* Parse ACE object guid */
4153 while (*StringAcl == ' ')
4154 StringAcl++;
4155 if (*StringAcl != ';')
4157 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4158 goto lerr;
4160 StringAcl++;
4162 /* Parse ACE inherit object guid */
4163 while (*StringAcl == ' ')
4164 StringAcl++;
4165 if (*StringAcl != ';')
4167 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4168 goto lerr;
4170 StringAcl++;
4172 /* Parse ACE account sid */
4173 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4175 while (*StringAcl && *StringAcl != ')')
4176 StringAcl++;
4179 if (*StringAcl != ')')
4180 goto lerr;
4181 StringAcl++;
4183 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4184 length += acesize;
4185 if (pAce)
4187 pAce->Header.AceSize = acesize;
4188 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4190 acecount++;
4193 *cBytes = length;
4195 if (length > 0xffff)
4197 ERR("ACL too large\n");
4198 goto lerr;
4201 if (pAcl)
4203 pAcl->AclRevision = ACL_REVISION;
4204 pAcl->Sbz1 = 0;
4205 pAcl->AclSize = length;
4206 pAcl->AceCount = acecount++;
4207 pAcl->Sbz2 = 0;
4209 return TRUE;
4211 lerr:
4212 SetLastError(error);
4213 WARN("Invalid ACE string format\n");
4214 return FALSE;
4218 /******************************************************************************
4219 * ParseStringSecurityDescriptorToSecurityDescriptor
4221 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4222 LPCWSTR StringSecurityDescriptor,
4223 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4224 LPDWORD cBytes)
4226 BOOL bret = FALSE;
4227 WCHAR toktype;
4228 WCHAR tok[MAX_PATH];
4229 LPCWSTR lptoken;
4230 LPBYTE lpNext = NULL;
4231 DWORD len;
4233 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4235 if (SecurityDescriptor)
4236 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4238 while (*StringSecurityDescriptor == ' ')
4239 StringSecurityDescriptor++;
4241 while (*StringSecurityDescriptor)
4243 toktype = *StringSecurityDescriptor;
4245 /* Expect char identifier followed by ':' */
4246 StringSecurityDescriptor++;
4247 if (*StringSecurityDescriptor != ':')
4249 SetLastError(ERROR_INVALID_PARAMETER);
4250 goto lend;
4252 StringSecurityDescriptor++;
4254 /* Extract token */
4255 lptoken = StringSecurityDescriptor;
4256 while (*lptoken && *lptoken != ':')
4257 lptoken++;
4259 if (*lptoken)
4260 lptoken--;
4262 len = lptoken - StringSecurityDescriptor;
4263 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4264 tok[len] = 0;
4266 switch (toktype)
4268 case 'O':
4270 DWORD bytes;
4272 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4273 goto lend;
4275 if (SecurityDescriptor)
4277 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4278 lpNext += bytes; /* Advance to next token */
4281 *cBytes += bytes;
4283 break;
4286 case 'G':
4288 DWORD bytes;
4290 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4291 goto lend;
4293 if (SecurityDescriptor)
4295 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4296 lpNext += bytes; /* Advance to next token */
4299 *cBytes += bytes;
4301 break;
4304 case 'D':
4306 DWORD flags;
4307 DWORD bytes;
4309 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4310 goto lend;
4312 if (SecurityDescriptor)
4314 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4315 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4316 lpNext += bytes; /* Advance to next token */
4319 *cBytes += bytes;
4321 break;
4324 case 'S':
4326 DWORD flags;
4327 DWORD bytes;
4329 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4330 goto lend;
4332 if (SecurityDescriptor)
4334 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4335 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4336 lpNext += bytes; /* Advance to next token */
4339 *cBytes += bytes;
4341 break;
4344 default:
4345 FIXME("Unknown token\n");
4346 SetLastError(ERROR_INVALID_PARAMETER);
4347 goto lend;
4350 StringSecurityDescriptor = lptoken;
4353 bret = TRUE;
4355 lend:
4356 return bret;
4359 /******************************************************************************
4360 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4362 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4363 LPCSTR StringSecurityDescriptor,
4364 DWORD StringSDRevision,
4365 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4366 PULONG SecurityDescriptorSize)
4368 UINT len;
4369 BOOL ret = FALSE;
4370 LPWSTR StringSecurityDescriptorW;
4372 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4373 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4375 if (StringSecurityDescriptorW)
4377 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4379 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4380 StringSDRevision, SecurityDescriptor,
4381 SecurityDescriptorSize);
4382 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4385 return ret;
4388 /******************************************************************************
4389 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4391 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4392 LPCWSTR StringSecurityDescriptor,
4393 DWORD StringSDRevision,
4394 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4395 PULONG SecurityDescriptorSize)
4397 DWORD cBytes;
4398 SECURITY_DESCRIPTOR* psd;
4399 BOOL bret = FALSE;
4401 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4403 if (GetVersion() & 0x80000000)
4405 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4406 goto lend;
4408 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4410 SetLastError(ERROR_INVALID_PARAMETER);
4411 goto lend;
4413 else if (StringSDRevision != SID_REVISION)
4415 SetLastError(ERROR_UNKNOWN_REVISION);
4416 goto lend;
4419 /* Compute security descriptor length */
4420 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4421 NULL, &cBytes))
4422 goto lend;
4424 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4425 if (!psd) goto lend;
4427 psd->Revision = SID_REVISION;
4428 psd->Control |= SE_SELF_RELATIVE;
4430 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4431 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4433 LocalFree(psd);
4434 goto lend;
4437 if (SecurityDescriptorSize)
4438 *SecurityDescriptorSize = cBytes;
4440 bret = TRUE;
4442 lend:
4443 TRACE(" ret=%d\n", bret);
4444 return bret;
4447 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4449 if (cch == -1)
4450 cch = strlenW(string);
4452 if (plen)
4453 *plen += cch;
4455 if (pwptr)
4457 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4458 *pwptr += cch;
4462 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4464 DWORD i;
4465 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4466 WCHAR subauthfmt[] = { '-','%','u',0 };
4467 WCHAR buf[26];
4468 SID *pisid = psid;
4470 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4472 SetLastError(ERROR_INVALID_SID);
4473 return FALSE;
4476 if (pisid->IdentifierAuthority.Value[0] ||
4477 pisid->IdentifierAuthority.Value[1])
4479 FIXME("not matching MS' bugs\n");
4480 SetLastError(ERROR_INVALID_SID);
4481 return FALSE;
4484 sprintfW( buf, fmt, pisid->Revision,
4485 MAKELONG(
4486 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4487 pisid->IdentifierAuthority.Value[4] ),
4488 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4489 pisid->IdentifierAuthority.Value[2] )
4490 ) );
4491 DumpString(buf, -1, pwptr, plen);
4493 for( i=0; i<pisid->SubAuthorityCount; i++ )
4495 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4496 DumpString(buf, -1, pwptr, plen);
4498 return TRUE;
4501 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4503 size_t i;
4504 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4506 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4508 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4509 return TRUE;
4513 return DumpSidNumeric(psid, pwptr, plen);
4516 static const LPCWSTR AceRightBitNames[32] = {
4517 SDDL_CREATE_CHILD, /* 0 */
4518 SDDL_DELETE_CHILD,
4519 SDDL_LIST_CHILDREN,
4520 SDDL_SELF_WRITE,
4521 SDDL_READ_PROPERTY, /* 4 */
4522 SDDL_WRITE_PROPERTY,
4523 SDDL_DELETE_TREE,
4524 SDDL_LIST_OBJECT,
4525 SDDL_CONTROL_ACCESS, /* 8 */
4526 NULL,
4527 NULL,
4528 NULL,
4529 NULL, /* 12 */
4530 NULL,
4531 NULL,
4532 NULL,
4533 SDDL_STANDARD_DELETE, /* 16 */
4534 SDDL_READ_CONTROL,
4535 SDDL_WRITE_DAC,
4536 SDDL_WRITE_OWNER,
4537 NULL, /* 20 */
4538 NULL,
4539 NULL,
4540 NULL,
4541 NULL, /* 24 */
4542 NULL,
4543 NULL,
4544 NULL,
4545 SDDL_GENERIC_ALL, /* 28 */
4546 SDDL_GENERIC_EXECUTE,
4547 SDDL_GENERIC_WRITE,
4548 SDDL_GENERIC_READ
4551 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4553 static const WCHAR fmtW[] = {'0','x','%','x',0};
4554 WCHAR buf[15];
4555 size_t i;
4557 if (mask == 0)
4558 return;
4560 /* first check if the right have name */
4561 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4563 if (AceRights[i].wstr == NULL)
4564 break;
4565 if (mask == AceRights[i].value)
4567 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4568 return;
4572 /* then check if it can be built from bit names */
4573 for (i = 0; i < 32; i++)
4575 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4577 /* can't be built from bit names */
4578 sprintfW(buf, fmtW, mask);
4579 DumpString(buf, -1, pwptr, plen);
4580 return;
4584 /* build from bit names */
4585 for (i = 0; i < 32; i++)
4586 if (mask & (1 << i))
4587 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4590 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4592 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4593 static const WCHAR openbr = '(';
4594 static const WCHAR closebr = ')';
4595 static const WCHAR semicolon = ';';
4597 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4599 SetLastError(ERROR_INVALID_ACL);
4600 return FALSE;
4603 piace = pace;
4604 DumpString(&openbr, 1, pwptr, plen);
4605 switch (piace->Header.AceType)
4607 case ACCESS_ALLOWED_ACE_TYPE:
4608 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4609 break;
4610 case ACCESS_DENIED_ACE_TYPE:
4611 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4612 break;
4613 case SYSTEM_AUDIT_ACE_TYPE:
4614 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4615 break;
4616 case SYSTEM_ALARM_ACE_TYPE:
4617 DumpString(SDDL_ALARM, -1, pwptr, plen);
4618 break;
4620 DumpString(&semicolon, 1, pwptr, plen);
4622 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4623 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4624 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4625 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4626 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4627 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4628 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4629 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4630 if (piace->Header.AceFlags & INHERITED_ACE)
4631 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4632 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4633 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4634 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4635 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4636 DumpString(&semicolon, 1, pwptr, plen);
4637 DumpRights(piace->Mask, pwptr, plen);
4638 DumpString(&semicolon, 1, pwptr, plen);
4639 /* objects not supported */
4640 DumpString(&semicolon, 1, pwptr, plen);
4641 /* objects not supported */
4642 DumpString(&semicolon, 1, pwptr, plen);
4643 if (!DumpSid(&piace->SidStart, pwptr, plen))
4644 return FALSE;
4645 DumpString(&closebr, 1, pwptr, plen);
4646 return TRUE;
4649 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4651 WORD count;
4652 int i;
4654 if (protected)
4655 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4656 if (autoInheritReq)
4657 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4658 if (autoInherited)
4659 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4661 if (pacl == NULL)
4662 return TRUE;
4664 if (!IsValidAcl(pacl))
4665 return FALSE;
4667 count = pacl->AceCount;
4668 for (i = 0; i < count; i++)
4670 LPVOID ace;
4671 if (!GetAce(pacl, i, &ace))
4672 return FALSE;
4673 if (!DumpAce(ace, pwptr, plen))
4674 return FALSE;
4677 return TRUE;
4680 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4682 static const WCHAR prefix[] = {'O',':',0};
4683 BOOL bDefaulted;
4684 PSID psid;
4686 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4687 return FALSE;
4689 if (psid == NULL)
4690 return TRUE;
4692 DumpString(prefix, -1, pwptr, plen);
4693 if (!DumpSid(psid, pwptr, plen))
4694 return FALSE;
4695 return TRUE;
4698 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4700 static const WCHAR prefix[] = {'G',':',0};
4701 BOOL bDefaulted;
4702 PSID psid;
4704 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4705 return FALSE;
4707 if (psid == NULL)
4708 return TRUE;
4710 DumpString(prefix, -1, pwptr, plen);
4711 if (!DumpSid(psid, pwptr, plen))
4712 return FALSE;
4713 return TRUE;
4716 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4718 static const WCHAR dacl[] = {'D',':',0};
4719 SECURITY_DESCRIPTOR_CONTROL control;
4720 BOOL present, defaulted;
4721 DWORD revision;
4722 PACL pacl;
4724 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4725 return FALSE;
4727 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4728 return FALSE;
4730 if (!present)
4731 return TRUE;
4733 DumpString(dacl, 2, pwptr, plen);
4734 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4735 return FALSE;
4736 return TRUE;
4739 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4741 static const WCHAR sacl[] = {'S',':',0};
4742 SECURITY_DESCRIPTOR_CONTROL control;
4743 BOOL present, defaulted;
4744 DWORD revision;
4745 PACL pacl;
4747 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4748 return FALSE;
4750 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4751 return FALSE;
4753 if (!present)
4754 return TRUE;
4756 DumpString(sacl, 2, pwptr, plen);
4757 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4758 return FALSE;
4759 return TRUE;
4762 /******************************************************************************
4763 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4765 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4767 ULONG len;
4768 WCHAR *wptr, *wstr;
4770 if (SDRevision != SDDL_REVISION_1)
4772 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4773 SetLastError(ERROR_UNKNOWN_REVISION);
4774 return FALSE;
4777 len = 0;
4778 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4779 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4780 return FALSE;
4781 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4782 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4783 return FALSE;
4784 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4785 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4786 return FALSE;
4787 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4788 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4789 return FALSE;
4791 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4792 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4793 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4794 return FALSE;
4795 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4796 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4797 return FALSE;
4798 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4799 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4800 return FALSE;
4801 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4802 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4803 return FALSE;
4804 *wptr = 0;
4806 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4807 *OutputString = wstr;
4808 if (OutputLen)
4809 *OutputLen = strlenW(*OutputString)+1;
4810 return TRUE;
4813 /******************************************************************************
4814 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4816 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4818 LPWSTR wstr;
4819 ULONG len;
4820 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4822 int lenA;
4824 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4825 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4826 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4827 LocalFree(wstr);
4829 if (OutputLen != NULL)
4830 *OutputLen = lenA;
4831 return TRUE;
4833 else
4835 *OutputString = NULL;
4836 if (OutputLen)
4837 *OutputLen = 0;
4838 return FALSE;
4842 /******************************************************************************
4843 * ConvertStringSidToSidW [ADVAPI32.@]
4845 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4847 BOOL bret = FALSE;
4848 DWORD cBytes;
4850 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4851 if (GetVersion() & 0x80000000)
4852 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4853 else if (!StringSid || !Sid)
4854 SetLastError(ERROR_INVALID_PARAMETER);
4855 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4857 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4859 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4860 if (!bret)
4861 LocalFree(*Sid);
4863 return bret;
4866 /******************************************************************************
4867 * ConvertStringSidToSidA [ADVAPI32.@]
4869 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4871 BOOL bret = FALSE;
4873 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4874 if (GetVersion() & 0x80000000)
4875 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4876 else if (!StringSid || !Sid)
4877 SetLastError(ERROR_INVALID_PARAMETER);
4878 else
4880 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4881 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4882 len * sizeof(WCHAR));
4884 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4885 bret = ConvertStringSidToSidW(wStringSid, Sid);
4886 HeapFree(GetProcessHeap(), 0, wStringSid);
4888 return bret;
4891 /******************************************************************************
4892 * ConvertSidToStringSidW [ADVAPI32.@]
4894 * format of SID string is:
4895 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4896 * where
4897 * <rev> is the revision of the SID encoded as decimal
4898 * <auth> is the identifier authority encoded as hex
4899 * <subauthN> is the subauthority id encoded as decimal
4901 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4903 DWORD len = 0;
4904 LPWSTR wstr, wptr;
4906 TRACE("%p %p\n", pSid, pstr );
4908 len = 0;
4909 if (!DumpSidNumeric(pSid, NULL, &len))
4910 return FALSE;
4911 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4912 DumpSidNumeric(pSid, &wptr, NULL);
4913 *wptr = 0;
4915 *pstr = wstr;
4916 return TRUE;
4919 /******************************************************************************
4920 * ConvertSidToStringSidA [ADVAPI32.@]
4922 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4924 LPWSTR wstr = NULL;
4925 LPSTR str;
4926 UINT len;
4928 TRACE("%p %p\n", pSid, pstr );
4930 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4931 return FALSE;
4933 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4934 str = LocalAlloc( 0, len );
4935 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4936 LocalFree( wstr );
4938 *pstr = str;
4940 return TRUE;
4943 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4944 PSECURITY_DESCRIPTOR pdesc,
4945 PSECURITY_DESCRIPTOR cdesc,
4946 PSECURITY_DESCRIPTOR* ndesc,
4947 GUID* objtype,
4948 BOOL isdir,
4949 PGENERIC_MAPPING genmap )
4951 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4953 return FALSE;
4956 BOOL WINAPI CreatePrivateObjectSecurity(
4957 PSECURITY_DESCRIPTOR ParentDescriptor,
4958 PSECURITY_DESCRIPTOR CreatorDescriptor,
4959 PSECURITY_DESCRIPTOR* NewDescriptor,
4960 BOOL IsDirectoryObject,
4961 HANDLE Token,
4962 PGENERIC_MAPPING GenericMapping )
4964 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4965 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4967 return FALSE;
4970 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4972 FIXME("%p - stub\n", ObjectDescriptor);
4974 return TRUE;
4977 BOOL WINAPI CreateProcessAsUserA(
4978 HANDLE hToken,
4979 LPCSTR lpApplicationName,
4980 LPSTR lpCommandLine,
4981 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4982 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4983 BOOL bInheritHandles,
4984 DWORD dwCreationFlags,
4985 LPVOID lpEnvironment,
4986 LPCSTR lpCurrentDirectory,
4987 LPSTARTUPINFOA lpStartupInfo,
4988 LPPROCESS_INFORMATION lpProcessInformation )
4990 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4991 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4992 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4994 return FALSE;
4997 BOOL WINAPI CreateProcessAsUserW(
4998 HANDLE hToken,
4999 LPCWSTR lpApplicationName,
5000 LPWSTR lpCommandLine,
5001 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5002 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5003 BOOL bInheritHandles,
5004 DWORD dwCreationFlags,
5005 LPVOID lpEnvironment,
5006 LPCWSTR lpCurrentDirectory,
5007 LPSTARTUPINFOW lpStartupInfo,
5008 LPPROCESS_INFORMATION lpProcessInformation )
5010 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5011 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5012 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5013 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5015 /* We should create the process with a suspended main thread */
5016 if (!CreateProcessW (lpApplicationName,
5017 lpCommandLine,
5018 lpProcessAttributes,
5019 lpThreadAttributes,
5020 bInheritHandles,
5021 dwCreationFlags, /* CREATE_SUSPENDED */
5022 lpEnvironment,
5023 lpCurrentDirectory,
5024 lpStartupInfo,
5025 lpProcessInformation))
5027 return FALSE;
5030 return TRUE;
5033 /******************************************************************************
5034 * CreateProcessWithLogonW
5036 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5037 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5038 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5040 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5041 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5042 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5043 lpStartupInfo, lpProcessInformation);
5045 return FALSE;
5048 /******************************************************************************
5049 * DuplicateTokenEx [ADVAPI32.@]
5051 BOOL WINAPI DuplicateTokenEx(
5052 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5053 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5054 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5055 TOKEN_TYPE TokenType,
5056 PHANDLE DuplicateTokenHandle )
5058 OBJECT_ATTRIBUTES ObjectAttributes;
5060 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5061 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5063 InitializeObjectAttributes(
5064 &ObjectAttributes,
5065 NULL,
5066 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5067 NULL,
5068 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5070 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5071 dwDesiredAccess,
5072 &ObjectAttributes,
5073 ImpersonationLevel,
5074 TokenType,
5075 DuplicateTokenHandle ) );
5078 BOOL WINAPI DuplicateToken(
5079 HANDLE ExistingTokenHandle,
5080 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5081 PHANDLE DuplicateTokenHandle )
5083 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5084 NULL, ImpersonationLevel, TokenImpersonation,
5085 DuplicateTokenHandle );
5088 /******************************************************************************
5089 * ComputeStringSidSize
5091 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5093 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5095 int ctok = 0;
5096 while (*StringSid)
5098 if (*StringSid == '-')
5099 ctok++;
5100 StringSid++;
5103 if (ctok >= 3)
5104 return GetSidLengthRequired(ctok - 2);
5106 else /* String constant format - Only available in winxp and above */
5108 unsigned int i;
5110 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5111 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5112 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5115 return GetSidLengthRequired(0);
5118 /******************************************************************************
5119 * ParseStringSidToSid
5121 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5123 BOOL bret = FALSE;
5124 SID* pisid=pSid;
5126 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5127 if (!StringSid)
5129 SetLastError(ERROR_INVALID_PARAMETER);
5130 TRACE("StringSid is NULL, returning FALSE\n");
5131 return FALSE;
5134 while (*StringSid == ' ')
5135 StringSid++;
5137 *cBytes = ComputeStringSidSize(StringSid);
5138 if (!pisid) /* Simply compute the size */
5140 TRACE("only size requested, returning TRUE\n");
5141 return TRUE;
5144 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5146 DWORD i = 0, identAuth;
5147 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5149 StringSid += 2; /* Advance to Revision */
5150 pisid->Revision = atoiW(StringSid);
5152 if (pisid->Revision != SDDL_REVISION)
5154 TRACE("Revision %d is unknown\n", pisid->Revision);
5155 goto lend; /* ERROR_INVALID_SID */
5157 if (csubauth == 0)
5159 TRACE("SubAuthorityCount is 0\n");
5160 goto lend; /* ERROR_INVALID_SID */
5163 pisid->SubAuthorityCount = csubauth;
5165 /* Advance to identifier authority */
5166 while (*StringSid && *StringSid != '-')
5167 StringSid++;
5168 if (*StringSid == '-')
5169 StringSid++;
5171 /* MS' implementation can't handle values greater than 2^32 - 1, so
5172 * we don't either; assume most significant bytes are always 0
5174 pisid->IdentifierAuthority.Value[0] = 0;
5175 pisid->IdentifierAuthority.Value[1] = 0;
5176 identAuth = atoiW(StringSid);
5177 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5178 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5179 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5180 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5182 /* Advance to first sub authority */
5183 while (*StringSid && *StringSid != '-')
5184 StringSid++;
5185 if (*StringSid == '-')
5186 StringSid++;
5188 while (*StringSid)
5190 pisid->SubAuthority[i++] = atoiW(StringSid);
5192 while (*StringSid && *StringSid != '-')
5193 StringSid++;
5194 if (*StringSid == '-')
5195 StringSid++;
5198 if (i != pisid->SubAuthorityCount)
5199 goto lend; /* ERROR_INVALID_SID */
5201 bret = TRUE;
5203 else /* String constant format - Only available in winxp and above */
5205 unsigned int i;
5206 pisid->Revision = SDDL_REVISION;
5208 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5209 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5211 DWORD j;
5212 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5213 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5214 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5215 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5216 bret = TRUE;
5219 if (!bret)
5220 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5223 lend:
5224 if (!bret)
5225 SetLastError(ERROR_INVALID_SID);
5227 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5228 return bret;
5231 /******************************************************************************
5232 * GetNamedSecurityInfoA [ADVAPI32.@]
5234 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5235 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5236 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5237 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5239 DWORD len;
5240 LPWSTR wstr = NULL;
5241 DWORD r;
5243 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5244 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5246 if( pObjectName )
5248 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5249 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5250 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5253 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5254 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5256 HeapFree( GetProcessHeap(), 0, wstr );
5258 return r;
5261 /******************************************************************************
5262 * GetNamedSecurityInfoW [ADVAPI32.@]
5264 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5265 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5266 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5268 DWORD needed, offset;
5269 SECURITY_DESCRIPTOR_RELATIVE *relative;
5270 BYTE *buffer;
5272 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5273 group, dacl, sacl, descriptor );
5275 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5277 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5278 if (info & OWNER_SECURITY_INFORMATION)
5279 needed += sizeof(sidWorld);
5280 if (info & GROUP_SECURITY_INFORMATION)
5281 needed += sizeof(sidWorld);
5282 if (info & DACL_SECURITY_INFORMATION)
5283 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5284 if (info & SACL_SECURITY_INFORMATION)
5285 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5287 /* must be freed by caller */
5288 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5289 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5291 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5293 HeapFree( GetProcessHeap(), 0, *descriptor );
5294 return ERROR_INVALID_SECURITY_DESCR;
5297 relative = *descriptor;
5298 relative->Control |= SE_SELF_RELATIVE;
5299 buffer = (BYTE *)relative;
5300 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5302 if (info & OWNER_SECURITY_INFORMATION)
5304 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5305 relative->Owner = offset;
5306 if (owner)
5307 *owner = buffer + offset;
5308 offset += sizeof(sidWorld);
5310 if (info & GROUP_SECURITY_INFORMATION)
5312 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5313 relative->Group = offset;
5314 if (group)
5315 *group = buffer + offset;
5316 offset += sizeof(sidWorld);
5318 if (info & DACL_SECURITY_INFORMATION)
5320 relative->Control |= SE_DACL_PRESENT;
5321 GetWorldAccessACL( (PACL)(buffer + offset) );
5322 relative->Dacl = offset;
5323 if (dacl)
5324 *dacl = (PACL)(buffer + offset);
5325 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5327 if (info & SACL_SECURITY_INFORMATION)
5329 relative->Control |= SE_SACL_PRESENT;
5330 GetWorldAccessACL( (PACL)(buffer + offset) );
5331 relative->Sacl = offset;
5332 if (sacl)
5333 *sacl = (PACL)(buffer + offset);
5335 return ERROR_SUCCESS;
5338 /******************************************************************************
5339 * DecryptFileW [ADVAPI32.@]
5341 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5343 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5344 return TRUE;
5347 /******************************************************************************
5348 * DecryptFileA [ADVAPI32.@]
5350 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5352 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5353 return TRUE;
5356 /******************************************************************************
5357 * EncryptFileW [ADVAPI32.@]
5359 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5361 FIXME("%s\n", debugstr_w(lpFileName));
5362 return TRUE;
5365 /******************************************************************************
5366 * EncryptFileA [ADVAPI32.@]
5368 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5370 FIXME("%s\n", debugstr_a(lpFileName));
5371 return TRUE;
5374 /******************************************************************************
5375 * FileEncryptionStatusW [ADVAPI32.@]
5377 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5379 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5380 if (!lpStatus)
5381 return FALSE;
5382 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5383 return TRUE;
5386 /******************************************************************************
5387 * FileEncryptionStatusA [ADVAPI32.@]
5389 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5391 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5392 if (!lpStatus)
5393 return FALSE;
5394 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5395 return TRUE;
5398 /******************************************************************************
5399 * SetSecurityInfo [ADVAPI32.@]
5401 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5402 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5403 PSID psidGroup, PACL pDacl, PACL pSacl) {
5404 FIXME("stub\n");
5405 return ERROR_SUCCESS;
5408 /******************************************************************************
5409 * SaferCreateLevel [ADVAPI32.@]
5411 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5412 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5414 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5415 return FALSE;
5418 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5419 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5420 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5421 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5422 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5424 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5425 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5426 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5428 return ERROR_SUCCESS;
5431 /******************************************************************************
5432 * SaferGetPolicyInformation [ADVAPI32.@]
5434 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5435 PVOID buffer, PDWORD required, LPVOID lpReserved)
5437 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5438 return FALSE;