configure: Changes from running autconf after previous patch.
[wine/hacks.git] / dlls / advapi32 / security.c
blob821fb869e554fe3f3c1621c9efbf307e5b86d092
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
216 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
223 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 * Reads the computer SID from the registry.
452 BOOL ADVAPI_GetComputerSid(PSID sid)
454 HKEY key;
455 LONG ret;
456 BOOL retval = FALSE;
457 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
458 static const WCHAR V[] = { 'V',0 };
460 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461 KEY_READ, &key)) == ERROR_SUCCESS)
463 DWORD size = 0;
464 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
467 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468 if (data)
470 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471 data, &size)) == ERROR_SUCCESS)
473 /* the SID is in the last 24 bytes of the binary data */
474 CopyMemory(sid, &data[size-24], 24);
475 retval = TRUE;
477 HeapFree(GetProcessHeap(), 0, data);
480 RegCloseKey(key);
483 if(retval == TRUE) return retval;
485 /* create a new random SID */
486 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
489 PSID new_sid;
490 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491 DWORD id[3];
493 if (RtlGenRandom(id, sizeof(id)))
495 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
497 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
500 FreeSid(new_sid);
503 RegCloseKey(key);
506 return retval;
509 /* ##############################
510 ###### TOKEN FUNCTIONS ######
511 ##############################
514 /******************************************************************************
515 * OpenProcessToken [ADVAPI32.@]
516 * Opens the access token associated with a process handle.
518 * PARAMS
519 * ProcessHandle [I] Handle to process
520 * DesiredAccess [I] Desired access to process
521 * TokenHandle [O] Pointer to handle of open access token
523 * RETURNS
524 * Success: TRUE. TokenHandle contains the access token.
525 * Failure: FALSE.
527 * NOTES
528 * See NtOpenProcessToken.
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532 HANDLE *TokenHandle )
534 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
537 /******************************************************************************
538 * OpenThreadToken [ADVAPI32.@]
540 * Opens the access token associated with a thread handle.
542 * PARAMS
543 * ThreadHandle [I] Handle to process
544 * DesiredAccess [I] Desired access to the thread
545 * OpenAsSelf [I] ???
546 * TokenHandle [O] Destination for the token handle
548 * RETURNS
549 * Success: TRUE. TokenHandle contains the access token.
550 * Failure: FALSE.
552 * NOTES
553 * See NtOpenThreadToken.
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557 BOOL OpenAsSelf, HANDLE *TokenHandle)
559 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
566 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567 PreviousState, ReturnLength));
570 /******************************************************************************
571 * AdjustTokenPrivileges [ADVAPI32.@]
573 * Adjust the privileges of an open token handle.
575 * PARAMS
576 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
577 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
578 * NewState [I] Desired new privileges of the token
579 * BufferLength [I] Length of NewState
580 * PreviousState [O] Destination for the previous state
581 * ReturnLength [I/O] Size of PreviousState
584 * RETURNS
585 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586 * Failure: FALSE.
588 * NOTES
589 * See NtAdjustPrivilegesToken.
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
596 NTSTATUS status;
598 TRACE("\n");
600 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601 NewState, BufferLength, PreviousState,
602 ReturnLength);
603 SetLastError( RtlNtStatusToDosError( status ));
604 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605 return TRUE;
606 else
607 return FALSE;
610 /******************************************************************************
611 * CheckTokenMembership [ADVAPI32.@]
613 * Determine if an access token is a member of a SID.
615 * PARAMS
616 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617 * SidToCheck [I] SID that possibly contains the token
618 * IsMember [O] Destination for result.
620 * RETURNS
621 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622 * Failure: FALSE.
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE token, PSID sid_to_check,
626 PBOOL is_member )
628 PTOKEN_GROUPS token_groups = NULL;
629 HANDLE thread_token = NULL;
630 DWORD size, i;
631 BOOL ret;
633 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
635 *is_member = FALSE;
637 if (!token)
639 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
641 HANDLE process_token;
642 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
643 if (!ret)
644 goto exit;
645 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
646 NULL, SecurityImpersonation, TokenImpersonation,
647 &thread_token);
648 CloseHandle(process_token);
649 if (!ret)
650 goto exit;
652 token = thread_token;
655 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
656 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
657 goto exit;
659 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
660 if (!token_groups)
662 ret = FALSE;
663 goto exit;
666 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
667 if (!ret)
668 goto exit;
670 for (i = 0; i < token_groups->GroupCount; i++)
672 TRACE("Groups[%d]: {0x%x, %s}\n", i,
673 token_groups->Groups[i].Attributes,
674 debugstr_sid(token_groups->Groups[i].Sid));
675 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
676 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
678 *is_member = TRUE;
679 TRACE("sid enabled and found in token\n");
680 break;
684 exit:
685 HeapFree(GetProcessHeap(), 0, token_groups);
686 if (thread_token != NULL) CloseHandle(thread_token);
688 return ret;
691 /******************************************************************************
692 * GetTokenInformation [ADVAPI32.@]
694 * Get a type of information about an access token.
696 * PARAMS
697 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
698 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
699 * tokeninfo [O] Destination for token information
700 * tokeninfolength [I] Length of tokeninfo
701 * retlen [O] Destination for returned token information length
703 * RETURNS
704 * Success: TRUE. tokeninfo contains retlen bytes of token information
705 * Failure: FALSE.
707 * NOTES
708 * See NtQueryInformationToken.
710 BOOL WINAPI
711 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
712 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
714 TRACE("(%p, %s, %p, %d, %p):\n",
715 token,
716 (tokeninfoclass == TokenUser) ? "TokenUser" :
717 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
718 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
719 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
720 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
721 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
722 (tokeninfoclass == TokenSource) ? "TokenSource" :
723 (tokeninfoclass == TokenType) ? "TokenType" :
724 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
725 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
726 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
727 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
728 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
729 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
730 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
731 "Unknown",
732 tokeninfo, tokeninfolength, retlen);
733 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
734 tokeninfolength, retlen));
737 /******************************************************************************
738 * SetTokenInformation [ADVAPI32.@]
740 * Set information for an access token.
742 * PARAMS
743 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
744 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
745 * tokeninfo [I] Token information to set
746 * tokeninfolength [I] Length of tokeninfo
748 * RETURNS
749 * Success: TRUE. The information for the token is set to tokeninfo.
750 * Failure: FALSE.
752 BOOL WINAPI
753 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
754 LPVOID tokeninfo, DWORD tokeninfolength )
756 TRACE("(%p, %s, %p, %d): stub\n",
757 token,
758 (tokeninfoclass == TokenUser) ? "TokenUser" :
759 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
760 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
761 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
762 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
763 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
764 (tokeninfoclass == TokenSource) ? "TokenSource" :
765 (tokeninfoclass == TokenType) ? "TokenType" :
766 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
767 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
768 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
769 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
770 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
771 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
772 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
773 "Unknown",
774 tokeninfo, tokeninfolength);
776 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
779 /*************************************************************************
780 * SetThreadToken [ADVAPI32.@]
782 * Assigns an 'impersonation token' to a thread so it can assume the
783 * security privileges of another thread or process. Can also remove
784 * a previously assigned token.
786 * PARAMS
787 * thread [O] Handle to thread to set the token for
788 * token [I] Token to set
790 * RETURNS
791 * Success: TRUE. The threads access token is set to token
792 * Failure: FALSE.
794 * NOTES
795 * Only supported on NT or higher. On Win9X this function does nothing.
796 * See SetTokenInformation.
798 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
800 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
801 ThreadImpersonationToken, &token, sizeof token ));
804 /*************************************************************************
805 * CreateRestrictedToken [ADVAPI32.@]
807 * Create a new more restricted token from an existing token.
809 * PARAMS
810 * baseToken [I] Token to base the new restricted token on
811 * flags [I] Options
812 * nDisableSids [I] Length of disableSids array
813 * disableSids [I] Array of SIDs to disable in the new token
814 * nDeletePrivs [I] Length of deletePrivs array
815 * deletePrivs [I] Array of privileges to delete in the new token
816 * nRestrictSids [I] Length of restrictSids array
817 * restrictSids [I] Array of SIDs to restrict in the new token
818 * newToken [O] Address where the new token is stored
820 * RETURNS
821 * Success: TRUE
822 * Failure: FALSE
824 BOOL WINAPI CreateRestrictedToken(
825 HANDLE baseToken,
826 DWORD flags,
827 DWORD nDisableSids,
828 PSID_AND_ATTRIBUTES disableSids,
829 DWORD nDeletePrivs,
830 PLUID_AND_ATTRIBUTES deletePrivs,
831 DWORD nRestrictSids,
832 PSID_AND_ATTRIBUTES restrictSids,
833 PHANDLE newToken)
835 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
836 baseToken, flags, nDisableSids, disableSids,
837 nDeletePrivs, deletePrivs,
838 nRestrictSids, restrictSids,
839 newToken);
840 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
841 return FALSE;
844 /* ##############################
845 ###### SID FUNCTIONS ######
846 ##############################
849 /******************************************************************************
850 * AllocateAndInitializeSid [ADVAPI32.@]
852 * PARAMS
853 * pIdentifierAuthority []
854 * nSubAuthorityCount []
855 * nSubAuthority0 []
856 * nSubAuthority1 []
857 * nSubAuthority2 []
858 * nSubAuthority3 []
859 * nSubAuthority4 []
860 * nSubAuthority5 []
861 * nSubAuthority6 []
862 * nSubAuthority7 []
863 * pSid []
865 BOOL WINAPI
866 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
867 BYTE nSubAuthorityCount,
868 DWORD nSubAuthority0, DWORD nSubAuthority1,
869 DWORD nSubAuthority2, DWORD nSubAuthority3,
870 DWORD nSubAuthority4, DWORD nSubAuthority5,
871 DWORD nSubAuthority6, DWORD nSubAuthority7,
872 PSID *pSid )
874 return set_ntstatus( RtlAllocateAndInitializeSid(
875 pIdentifierAuthority, nSubAuthorityCount,
876 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
877 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
878 pSid ));
881 /******************************************************************************
882 * FreeSid [ADVAPI32.@]
884 * PARAMS
885 * pSid []
887 PVOID WINAPI
888 FreeSid( PSID pSid )
890 RtlFreeSid(pSid);
891 return NULL; /* is documented like this */
894 /******************************************************************************
895 * CopySid [ADVAPI32.@]
897 * PARAMS
898 * nDestinationSidLength []
899 * pDestinationSid []
900 * pSourceSid []
902 BOOL WINAPI
903 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
905 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
908 /******************************************************************************
909 * CreateWellKnownSid [ADVAPI32.@]
911 BOOL WINAPI
912 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
913 PSID DomainSid,
914 PSID pSid,
915 DWORD* cbSid)
917 unsigned int i;
918 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
920 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
922 SetLastError(ERROR_INVALID_PARAMETER);
923 return FALSE;
926 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
927 if (WellKnownSids[i].Type == WellKnownSidType) {
928 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
930 if (*cbSid < length)
932 *cbSid = length;
933 SetLastError(ERROR_INSUFFICIENT_BUFFER);
934 return FALSE;
936 if (!pSid)
938 SetLastError(ERROR_INVALID_PARAMETER);
939 return FALSE;
941 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
942 *cbSid = length;
943 return TRUE;
947 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return FALSE;
953 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
954 if (WellKnownRids[i].Type == WellKnownSidType) {
955 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
956 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
957 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
959 if (*cbSid < output_sid_length)
961 *cbSid = output_sid_length;
962 SetLastError(ERROR_INSUFFICIENT_BUFFER);
963 return FALSE;
965 if (!pSid)
967 SetLastError(ERROR_INVALID_PARAMETER);
968 return FALSE;
970 CopyMemory(pSid, DomainSid, domain_sid_length);
971 (*GetSidSubAuthorityCount(pSid))++;
972 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
973 *cbSid = output_sid_length;
974 return TRUE;
977 SetLastError(ERROR_INVALID_PARAMETER);
978 return FALSE;
981 /******************************************************************************
982 * IsWellKnownSid [ADVAPI32.@]
984 BOOL WINAPI
985 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
987 unsigned int i;
988 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
990 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
991 if (WellKnownSids[i].Type == WellKnownSidType)
992 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
993 return TRUE;
995 return FALSE;
998 BOOL WINAPI
999 IsTokenRestricted( HANDLE TokenHandle )
1001 TOKEN_GROUPS *groups;
1002 DWORD size;
1003 NTSTATUS status;
1004 BOOL restricted;
1006 TRACE("(%p)\n", TokenHandle);
1008 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1009 if (status != STATUS_BUFFER_TOO_SMALL)
1010 return FALSE;
1012 groups = HeapAlloc(GetProcessHeap(), 0, size);
1013 if (!groups)
1015 SetLastError(ERROR_OUTOFMEMORY);
1016 return FALSE;
1019 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1020 if (status != STATUS_SUCCESS)
1022 HeapFree(GetProcessHeap(), 0, groups);
1023 return set_ntstatus(status);
1026 if (groups->GroupCount)
1027 restricted = TRUE;
1028 else
1029 restricted = FALSE;
1031 HeapFree(GetProcessHeap(), 0, groups);
1033 return restricted;
1036 /******************************************************************************
1037 * IsValidSid [ADVAPI32.@]
1039 * PARAMS
1040 * pSid []
1042 BOOL WINAPI
1043 IsValidSid( PSID pSid )
1045 return RtlValidSid( pSid );
1048 /******************************************************************************
1049 * EqualSid [ADVAPI32.@]
1051 * PARAMS
1052 * pSid1 []
1053 * pSid2 []
1055 BOOL WINAPI
1056 EqualSid( PSID pSid1, PSID pSid2 )
1058 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1059 SetLastError(ERROR_SUCCESS);
1060 return ret;
1063 /******************************************************************************
1064 * EqualPrefixSid [ADVAPI32.@]
1066 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1068 return RtlEqualPrefixSid(pSid1, pSid2);
1071 /******************************************************************************
1072 * GetSidLengthRequired [ADVAPI32.@]
1074 * PARAMS
1075 * nSubAuthorityCount []
1077 DWORD WINAPI
1078 GetSidLengthRequired( BYTE nSubAuthorityCount )
1080 return RtlLengthRequiredSid(nSubAuthorityCount);
1083 /******************************************************************************
1084 * InitializeSid [ADVAPI32.@]
1086 * PARAMS
1087 * pIdentifierAuthority []
1089 BOOL WINAPI
1090 InitializeSid (
1091 PSID pSid,
1092 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1093 BYTE nSubAuthorityCount)
1095 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1098 DWORD WINAPI
1099 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1101 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1103 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1104 return 0;
1107 DWORD WINAPI
1108 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1110 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1112 return 1;
1115 /******************************************************************************
1116 * GetSidIdentifierAuthority [ADVAPI32.@]
1118 * PARAMS
1119 * pSid []
1121 PSID_IDENTIFIER_AUTHORITY WINAPI
1122 GetSidIdentifierAuthority( PSID pSid )
1124 return RtlIdentifierAuthoritySid(pSid);
1127 /******************************************************************************
1128 * GetSidSubAuthority [ADVAPI32.@]
1130 * PARAMS
1131 * pSid []
1132 * nSubAuthority []
1134 PDWORD WINAPI
1135 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1137 SetLastError(ERROR_SUCCESS);
1138 return RtlSubAuthoritySid(pSid, nSubAuthority);
1141 /******************************************************************************
1142 * GetSidSubAuthorityCount [ADVAPI32.@]
1144 * PARAMS
1145 * pSid []
1147 PUCHAR WINAPI
1148 GetSidSubAuthorityCount (PSID pSid)
1150 SetLastError(ERROR_SUCCESS);
1151 return RtlSubAuthorityCountSid(pSid);
1154 /******************************************************************************
1155 * GetLengthSid [ADVAPI32.@]
1157 * PARAMS
1158 * pSid []
1160 DWORD WINAPI
1161 GetLengthSid (PSID pSid)
1163 return RtlLengthSid(pSid);
1166 /* ##############################################
1167 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1168 ##############################################
1171 /******************************************************************************
1172 * BuildSecurityDescriptorA [ADVAPI32.@]
1174 * Builds a SD from
1176 * PARAMS
1177 * pOwner [I]
1178 * pGroup [I]
1179 * cCountOfAccessEntries [I]
1180 * pListOfAccessEntries [I]
1181 * cCountOfAuditEntries [I]
1182 * pListofAuditEntries [I]
1183 * pOldSD [I]
1184 * lpdwBufferLength [I/O]
1185 * pNewSD [O]
1187 * RETURNS
1188 * Success: ERROR_SUCCESS
1189 * Failure: nonzero error code from Winerror.h
1191 DWORD WINAPI BuildSecurityDescriptorA(
1192 IN PTRUSTEEA pOwner,
1193 IN PTRUSTEEA pGroup,
1194 IN ULONG cCountOfAccessEntries,
1195 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1196 IN ULONG cCountOfAuditEntries,
1197 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1198 IN PSECURITY_DESCRIPTOR pOldSD,
1199 IN OUT PULONG lpdwBufferLength,
1200 OUT PSECURITY_DESCRIPTOR* pNewSD)
1202 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1203 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1204 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1206 return ERROR_CALL_NOT_IMPLEMENTED;
1209 /******************************************************************************
1210 * BuildSecurityDescriptorW [ADVAPI32.@]
1212 * See BuildSecurityDescriptorA.
1214 DWORD WINAPI BuildSecurityDescriptorW(
1215 IN PTRUSTEEW pOwner,
1216 IN PTRUSTEEW pGroup,
1217 IN ULONG cCountOfAccessEntries,
1218 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1219 IN ULONG cCountOfAuditEntries,
1220 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1221 IN PSECURITY_DESCRIPTOR pOldSD,
1222 IN OUT PULONG lpdwBufferLength,
1223 OUT PSECURITY_DESCRIPTOR* pNewSD)
1225 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1226 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1227 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1229 return ERROR_CALL_NOT_IMPLEMENTED;
1232 /******************************************************************************
1233 * InitializeSecurityDescriptor [ADVAPI32.@]
1235 * PARAMS
1236 * pDescr []
1237 * revision []
1239 BOOL WINAPI
1240 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1242 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1246 /******************************************************************************
1247 * MakeAbsoluteSD [ADVAPI32.@]
1249 BOOL WINAPI MakeAbsoluteSD (
1250 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1251 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1252 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1253 OUT PACL pDacl,
1254 OUT LPDWORD lpdwDaclSize,
1255 OUT PACL pSacl,
1256 OUT LPDWORD lpdwSaclSize,
1257 OUT PSID pOwner,
1258 OUT LPDWORD lpdwOwnerSize,
1259 OUT PSID pPrimaryGroup,
1260 OUT LPDWORD lpdwPrimaryGroupSize)
1262 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1263 pAbsoluteSecurityDescriptor,
1264 lpdwAbsoluteSecurityDescriptorSize,
1265 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1266 pOwner, lpdwOwnerSize,
1267 pPrimaryGroup, lpdwPrimaryGroupSize));
1270 /******************************************************************************
1271 * GetKernelObjectSecurity [ADVAPI32.@]
1273 BOOL WINAPI GetKernelObjectSecurity(
1274 HANDLE Handle,
1275 SECURITY_INFORMATION RequestedInformation,
1276 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1277 DWORD nLength,
1278 LPDWORD lpnLengthNeeded )
1280 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1281 pSecurityDescriptor, nLength, lpnLengthNeeded);
1283 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1284 nLength, lpnLengthNeeded ));
1287 /******************************************************************************
1288 * GetPrivateObjectSecurity [ADVAPI32.@]
1290 BOOL WINAPI GetPrivateObjectSecurity(
1291 PSECURITY_DESCRIPTOR ObjectDescriptor,
1292 SECURITY_INFORMATION SecurityInformation,
1293 PSECURITY_DESCRIPTOR ResultantDescriptor,
1294 DWORD DescriptorLength,
1295 PDWORD ReturnLength )
1297 SECURITY_DESCRIPTOR desc;
1298 BOOL defaulted, present;
1299 PACL pacl;
1300 PSID psid;
1302 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1303 ResultantDescriptor, DescriptorLength, ReturnLength);
1305 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1306 return FALSE;
1308 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1310 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1311 return FALSE;
1312 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1315 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1317 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1318 return FALSE;
1319 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1322 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1324 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1325 return FALSE;
1326 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1329 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1331 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1332 return FALSE;
1333 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1336 *ReturnLength = DescriptorLength;
1337 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1340 /******************************************************************************
1341 * GetSecurityDescriptorLength [ADVAPI32.@]
1343 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1345 return RtlLengthSecurityDescriptor(pDescr);
1348 /******************************************************************************
1349 * GetSecurityDescriptorOwner [ADVAPI32.@]
1351 * PARAMS
1352 * pOwner []
1353 * lpbOwnerDefaulted []
1355 BOOL WINAPI
1356 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1357 LPBOOL lpbOwnerDefaulted )
1359 BOOLEAN defaulted;
1360 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1361 *lpbOwnerDefaulted = defaulted;
1362 return ret;
1365 /******************************************************************************
1366 * SetSecurityDescriptorOwner [ADVAPI32.@]
1368 * PARAMS
1370 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1371 PSID pOwner, BOOL bOwnerDefaulted)
1373 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1375 /******************************************************************************
1376 * GetSecurityDescriptorGroup [ADVAPI32.@]
1378 BOOL WINAPI GetSecurityDescriptorGroup(
1379 PSECURITY_DESCRIPTOR SecurityDescriptor,
1380 PSID *Group,
1381 LPBOOL GroupDefaulted)
1383 BOOLEAN defaulted;
1384 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1385 *GroupDefaulted = defaulted;
1386 return ret;
1388 /******************************************************************************
1389 * SetSecurityDescriptorGroup [ADVAPI32.@]
1391 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1392 PSID Group, BOOL GroupDefaulted)
1394 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1397 /******************************************************************************
1398 * IsValidSecurityDescriptor [ADVAPI32.@]
1400 * PARAMS
1401 * lpsecdesc []
1403 BOOL WINAPI
1404 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1406 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1409 /******************************************************************************
1410 * GetSecurityDescriptorDacl [ADVAPI32.@]
1412 BOOL WINAPI GetSecurityDescriptorDacl(
1413 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1414 OUT LPBOOL lpbDaclPresent,
1415 OUT PACL *pDacl,
1416 OUT LPBOOL lpbDaclDefaulted)
1418 BOOLEAN present, defaulted;
1419 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1420 *lpbDaclPresent = present;
1421 *lpbDaclDefaulted = defaulted;
1422 return ret;
1425 /******************************************************************************
1426 * SetSecurityDescriptorDacl [ADVAPI32.@]
1428 BOOL WINAPI
1429 SetSecurityDescriptorDacl (
1430 PSECURITY_DESCRIPTOR lpsd,
1431 BOOL daclpresent,
1432 PACL dacl,
1433 BOOL dacldefaulted )
1435 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1437 /******************************************************************************
1438 * GetSecurityDescriptorSacl [ADVAPI32.@]
1440 BOOL WINAPI GetSecurityDescriptorSacl(
1441 IN PSECURITY_DESCRIPTOR lpsd,
1442 OUT LPBOOL lpbSaclPresent,
1443 OUT PACL *pSacl,
1444 OUT LPBOOL lpbSaclDefaulted)
1446 BOOLEAN present, defaulted;
1447 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1448 *lpbSaclPresent = present;
1449 *lpbSaclDefaulted = defaulted;
1450 return ret;
1453 /**************************************************************************
1454 * SetSecurityDescriptorSacl [ADVAPI32.@]
1456 BOOL WINAPI SetSecurityDescriptorSacl (
1457 PSECURITY_DESCRIPTOR lpsd,
1458 BOOL saclpresent,
1459 PACL lpsacl,
1460 BOOL sacldefaulted)
1462 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1464 /******************************************************************************
1465 * MakeSelfRelativeSD [ADVAPI32.@]
1467 * PARAMS
1468 * lpabssecdesc []
1469 * lpselfsecdesc []
1470 * lpbuflen []
1472 BOOL WINAPI
1473 MakeSelfRelativeSD(
1474 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1475 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1476 IN OUT LPDWORD lpdwBufferLength)
1478 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1479 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1482 /******************************************************************************
1483 * GetSecurityDescriptorControl [ADVAPI32.@]
1486 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1487 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1489 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1492 /******************************************************************************
1493 * SetSecurityDescriptorControl [ADVAPI32.@]
1495 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1496 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1497 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1499 return set_ntstatus( RtlSetControlSecurityDescriptor(
1500 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1503 /* ##############################
1504 ###### ACL FUNCTIONS ######
1505 ##############################
1508 /*************************************************************************
1509 * InitializeAcl [ADVAPI32.@]
1511 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1513 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1516 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1518 IO_STATUS_BLOCK io_block;
1520 TRACE("(%p)\n", hNamedPipe);
1522 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1523 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1526 /******************************************************************************
1527 * AddAccessAllowedAce [ADVAPI32.@]
1529 BOOL WINAPI AddAccessAllowedAce(
1530 IN OUT PACL pAcl,
1531 IN DWORD dwAceRevision,
1532 IN DWORD AccessMask,
1533 IN PSID pSid)
1535 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1538 /******************************************************************************
1539 * AddAccessAllowedAceEx [ADVAPI32.@]
1541 BOOL WINAPI AddAccessAllowedAceEx(
1542 IN OUT PACL pAcl,
1543 IN DWORD dwAceRevision,
1544 IN DWORD AceFlags,
1545 IN DWORD AccessMask,
1546 IN PSID pSid)
1548 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1551 /******************************************************************************
1552 * AddAccessDeniedAce [ADVAPI32.@]
1554 BOOL WINAPI AddAccessDeniedAce(
1555 IN OUT PACL pAcl,
1556 IN DWORD dwAceRevision,
1557 IN DWORD AccessMask,
1558 IN PSID pSid)
1560 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1563 /******************************************************************************
1564 * AddAccessDeniedAceEx [ADVAPI32.@]
1566 BOOL WINAPI AddAccessDeniedAceEx(
1567 IN OUT PACL pAcl,
1568 IN DWORD dwAceRevision,
1569 IN DWORD AceFlags,
1570 IN DWORD AccessMask,
1571 IN PSID pSid)
1573 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1576 /******************************************************************************
1577 * AddAce [ADVAPI32.@]
1579 BOOL WINAPI AddAce(
1580 IN OUT PACL pAcl,
1581 IN DWORD dwAceRevision,
1582 IN DWORD dwStartingAceIndex,
1583 LPVOID pAceList,
1584 DWORD nAceListLength)
1586 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1589 /******************************************************************************
1590 * DeleteAce [ADVAPI32.@]
1592 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1594 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1597 /******************************************************************************
1598 * FindFirstFreeAce [ADVAPI32.@]
1600 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1602 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1605 /******************************************************************************
1606 * GetAce [ADVAPI32.@]
1608 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1610 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1613 /******************************************************************************
1614 * GetAclInformation [ADVAPI32.@]
1616 BOOL WINAPI GetAclInformation(
1617 PACL pAcl,
1618 LPVOID pAclInformation,
1619 DWORD nAclInformationLength,
1620 ACL_INFORMATION_CLASS dwAclInformationClass)
1622 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1623 nAclInformationLength, dwAclInformationClass));
1626 /******************************************************************************
1627 * IsValidAcl [ADVAPI32.@]
1629 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1631 return RtlValidAcl(pAcl);
1634 /* ##############################
1635 ###### MISC FUNCTIONS ######
1636 ##############################
1639 /******************************************************************************
1640 * AllocateLocallyUniqueId [ADVAPI32.@]
1642 * PARAMS
1643 * lpLuid []
1645 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1647 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1650 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1651 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1652 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1653 { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1654 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1655 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1656 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1657 { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1658 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1659 { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1660 static const WCHAR SE_TCB_NAME_W[] =
1661 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1662 static const WCHAR SE_SECURITY_NAME_W[] =
1663 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1664 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1665 { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1666 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1667 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1668 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1669 { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1670 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1671 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1672 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1673 { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1674 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1675 { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1676 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1677 { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1678 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1679 { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1680 static const WCHAR SE_BACKUP_NAME_W[] =
1681 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1682 static const WCHAR SE_RESTORE_NAME_W[] =
1683 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1684 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1685 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1686 static const WCHAR SE_DEBUG_NAME_W[] =
1687 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1688 static const WCHAR SE_AUDIT_NAME_W[] =
1689 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1690 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1691 { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1692 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1693 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1694 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1695 { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1696 static const WCHAR SE_UNDOCK_NAME_W[] =
1697 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1698 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1699 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1700 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1701 { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1702 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1703 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1704 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1705 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1706 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1707 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1709 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1711 NULL,
1712 NULL,
1713 SE_CREATE_TOKEN_NAME_W,
1714 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1715 SE_LOCK_MEMORY_NAME_W,
1716 SE_INCREASE_QUOTA_NAME_W,
1717 SE_MACHINE_ACCOUNT_NAME_W,
1718 SE_TCB_NAME_W,
1719 SE_SECURITY_NAME_W,
1720 SE_TAKE_OWNERSHIP_NAME_W,
1721 SE_LOAD_DRIVER_NAME_W,
1722 SE_SYSTEM_PROFILE_NAME_W,
1723 SE_SYSTEMTIME_NAME_W,
1724 SE_PROF_SINGLE_PROCESS_NAME_W,
1725 SE_INC_BASE_PRIORITY_NAME_W,
1726 SE_CREATE_PAGEFILE_NAME_W,
1727 SE_CREATE_PERMANENT_NAME_W,
1728 SE_BACKUP_NAME_W,
1729 SE_RESTORE_NAME_W,
1730 SE_SHUTDOWN_NAME_W,
1731 SE_DEBUG_NAME_W,
1732 SE_AUDIT_NAME_W,
1733 SE_SYSTEM_ENVIRONMENT_NAME_W,
1734 SE_CHANGE_NOTIFY_NAME_W,
1735 SE_REMOTE_SHUTDOWN_NAME_W,
1736 SE_UNDOCK_NAME_W,
1737 SE_SYNC_AGENT_NAME_W,
1738 SE_ENABLE_DELEGATION_NAME_W,
1739 SE_MANAGE_VOLUME_NAME_W,
1740 SE_IMPERSONATE_NAME_W,
1741 SE_CREATE_GLOBAL_NAME_W,
1744 /******************************************************************************
1745 * LookupPrivilegeValueW [ADVAPI32.@]
1747 * See LookupPrivilegeValueA.
1749 BOOL WINAPI
1750 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1752 UINT i;
1754 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1756 if (!ADVAPI_IsLocalComputer(lpSystemName))
1758 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1759 return FALSE;
1761 if (!lpName)
1763 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1764 return FALSE;
1766 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1768 if( !WellKnownPrivNames[i] )
1769 continue;
1770 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1771 continue;
1772 lpLuid->LowPart = i;
1773 lpLuid->HighPart = 0;
1774 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1775 lpLuid->HighPart, lpLuid->LowPart );
1776 return TRUE;
1778 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1779 return FALSE;
1782 /******************************************************************************
1783 * LookupPrivilegeValueA [ADVAPI32.@]
1785 * Retrieves LUID used on a system to represent the privilege name.
1787 * PARAMS
1788 * lpSystemName [I] Name of the system
1789 * lpName [I] Name of the privilege
1790 * lpLuid [O] Destination for the resulting LUID
1792 * RETURNS
1793 * Success: TRUE. lpLuid contains the requested LUID.
1794 * Failure: FALSE.
1796 BOOL WINAPI
1797 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1799 UNICODE_STRING lpSystemNameW;
1800 UNICODE_STRING lpNameW;
1801 BOOL ret;
1803 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1804 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1805 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1806 RtlFreeUnicodeString(&lpNameW);
1807 RtlFreeUnicodeString(&lpSystemNameW);
1808 return ret;
1811 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1812 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1814 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1815 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1817 return FALSE;
1820 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1821 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1823 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1824 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1826 return FALSE;
1829 /******************************************************************************
1830 * LookupPrivilegeNameA [ADVAPI32.@]
1832 * See LookupPrivilegeNameW.
1834 BOOL WINAPI
1835 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1836 LPDWORD cchName)
1838 UNICODE_STRING lpSystemNameW;
1839 BOOL ret;
1840 DWORD wLen = 0;
1842 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1844 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1845 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1846 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1848 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1850 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1851 &wLen);
1852 if (ret)
1854 /* Windows crashes if cchName is NULL, so will I */
1855 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1856 *cchName, NULL, NULL);
1858 if (len == 0)
1860 /* WideCharToMultiByte failed */
1861 ret = FALSE;
1863 else if (len > *cchName)
1865 *cchName = len;
1866 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1867 ret = FALSE;
1869 else
1871 /* WideCharToMultiByte succeeded, output length needs to be
1872 * length not including NULL terminator
1874 *cchName = len - 1;
1877 HeapFree(GetProcessHeap(), 0, lpNameW);
1879 RtlFreeUnicodeString(&lpSystemNameW);
1880 return ret;
1883 /******************************************************************************
1884 * LookupPrivilegeNameW [ADVAPI32.@]
1886 * Retrieves the privilege name referred to by the LUID lpLuid.
1888 * PARAMS
1889 * lpSystemName [I] Name of the system
1890 * lpLuid [I] Privilege value
1891 * lpName [O] Name of the privilege
1892 * cchName [I/O] Number of characters in lpName.
1894 * RETURNS
1895 * Success: TRUE. lpName contains the name of the privilege whose value is
1896 * *lpLuid.
1897 * Failure: FALSE.
1899 * REMARKS
1900 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1901 * using this function.
1902 * If the length of lpName is too small, on return *cchName will contain the
1903 * number of WCHARs needed to contain the privilege, including the NULL
1904 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1905 * On success, *cchName will contain the number of characters stored in
1906 * lpName, NOT including the NULL terminator.
1908 BOOL WINAPI
1909 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1910 LPDWORD cchName)
1912 size_t privNameLen;
1914 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1916 if (!ADVAPI_IsLocalComputer(lpSystemName))
1918 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1919 return FALSE;
1921 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1922 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1924 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1925 return FALSE;
1927 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1928 /* Windows crashes if cchName is NULL, so will I */
1929 if (*cchName <= privNameLen)
1931 *cchName = privNameLen + 1;
1932 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1933 return FALSE;
1935 else
1937 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1938 *cchName = privNameLen;
1939 return TRUE;
1943 /******************************************************************************
1944 * GetFileSecurityA [ADVAPI32.@]
1946 * Obtains Specified information about the security of a file or directory.
1948 * PARAMS
1949 * lpFileName [I] Name of the file to get info for
1950 * RequestedInformation [I] SE_ flags from "winnt.h"
1951 * pSecurityDescriptor [O] Destination for security information
1952 * nLength [I] Length of pSecurityDescriptor
1953 * lpnLengthNeeded [O] Destination for length of returned security information
1955 * RETURNS
1956 * Success: TRUE. pSecurityDescriptor contains the requested information.
1957 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1959 * NOTES
1960 * The information returned is constrained by the callers access rights and
1961 * privileges.
1963 BOOL WINAPI
1964 GetFileSecurityA( LPCSTR lpFileName,
1965 SECURITY_INFORMATION RequestedInformation,
1966 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1967 DWORD nLength, LPDWORD lpnLengthNeeded )
1969 DWORD len;
1970 BOOL r;
1971 LPWSTR name = NULL;
1973 if( lpFileName )
1975 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1976 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1977 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1980 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1981 nLength, lpnLengthNeeded );
1982 HeapFree( GetProcessHeap(), 0, name );
1984 return r;
1987 /******************************************************************************
1988 * GetFileSecurityW [ADVAPI32.@]
1990 * See GetFileSecurityA.
1992 BOOL WINAPI
1993 GetFileSecurityW( LPCWSTR lpFileName,
1994 SECURITY_INFORMATION RequestedInformation,
1995 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1996 DWORD nLength, LPDWORD lpnLengthNeeded )
1998 HANDLE hfile;
1999 NTSTATUS status;
2000 DWORD access = 0;
2002 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2003 RequestedInformation, pSecurityDescriptor,
2004 nLength, lpnLengthNeeded);
2006 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2007 DACL_SECURITY_INFORMATION))
2008 access |= READ_CONTROL;
2009 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2010 access |= ACCESS_SYSTEM_SECURITY;
2012 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2013 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2014 if ( hfile == INVALID_HANDLE_VALUE )
2015 return FALSE;
2017 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2018 nLength, lpnLengthNeeded );
2019 CloseHandle( hfile );
2020 return set_ntstatus( status );
2024 /******************************************************************************
2025 * LookupAccountSidA [ADVAPI32.@]
2027 BOOL WINAPI
2028 LookupAccountSidA(
2029 IN LPCSTR system,
2030 IN PSID sid,
2031 OUT LPSTR account,
2032 IN OUT LPDWORD accountSize,
2033 OUT LPSTR domain,
2034 IN OUT LPDWORD domainSize,
2035 OUT PSID_NAME_USE name_use )
2037 DWORD len;
2038 BOOL r;
2039 LPWSTR systemW = NULL;
2040 LPWSTR accountW = NULL;
2041 LPWSTR domainW = NULL;
2042 DWORD accountSizeW = *accountSize;
2043 DWORD domainSizeW = *domainSize;
2045 if (system) {
2046 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2047 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2048 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2050 if (account)
2051 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2052 if (domain)
2053 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2055 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2057 if (r) {
2058 if (accountW && *accountSize) {
2059 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2060 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2061 *accountSize = len;
2062 } else
2063 *accountSize = accountSizeW + 1;
2065 if (domainW && *domainSize) {
2066 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2067 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2068 *domainSize = len;
2069 } else
2070 *domainSize = domainSizeW + 1;
2073 HeapFree( GetProcessHeap(), 0, systemW );
2074 HeapFree( GetProcessHeap(), 0, accountW );
2075 HeapFree( GetProcessHeap(), 0, domainW );
2077 return r;
2080 /******************************************************************************
2081 * LookupAccountSidW [ADVAPI32.@]
2083 * PARAMS
2084 * system []
2085 * sid []
2086 * account []
2087 * accountSize []
2088 * domain []
2089 * domainSize []
2090 * name_use []
2093 BOOL WINAPI
2094 LookupAccountSidW(
2095 IN LPCWSTR system,
2096 IN PSID sid,
2097 OUT LPWSTR account,
2098 IN OUT LPDWORD accountSize,
2099 OUT LPWSTR domain,
2100 IN OUT LPDWORD domainSize,
2101 OUT PSID_NAME_USE name_use )
2103 unsigned int i, j;
2104 const WCHAR * ac = NULL;
2105 const WCHAR * dm = NULL;
2106 SID_NAME_USE use = 0;
2107 LPWSTR computer_name = NULL;
2108 LPWSTR account_name = NULL;
2110 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2111 debugstr_w(system),debugstr_sid(sid),
2112 account,accountSize,accountSize?*accountSize:0,
2113 domain,domainSize,domainSize?*domainSize:0,
2114 name_use);
2116 if (!ADVAPI_IsLocalComputer(system)) {
2117 FIXME("Only local computer supported!\n");
2118 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2119 return FALSE;
2122 /* check the well known SIDs first */
2123 for (i = 0; i <= 60; i++) {
2124 if (IsWellKnownSid(sid, i)) {
2125 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2126 if (ACCOUNT_SIDS[j].type == i) {
2127 ac = ACCOUNT_SIDS[j].account;
2128 dm = ACCOUNT_SIDS[j].domain;
2129 use = ACCOUNT_SIDS[j].name_use;
2132 break;
2136 if (dm == NULL) {
2137 MAX_SID local;
2139 /* check for the local computer next */
2140 if (ADVAPI_GetComputerSid(&local)) {
2141 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2142 BOOL result;
2144 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2145 result = GetComputerNameW(computer_name, &size);
2147 if (result) {
2148 if (EqualSid(sid, &local)) {
2149 dm = computer_name;
2150 ac = Blank;
2151 use = 3;
2152 } else {
2153 local.SubAuthorityCount++;
2155 if (EqualPrefixSid(sid, &local)) {
2156 dm = computer_name;
2157 use = 1;
2158 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2159 case DOMAIN_USER_RID_ADMIN:
2160 ac = Administrator;
2161 break;
2162 case DOMAIN_USER_RID_GUEST:
2163 ac = Guest;
2164 break;
2165 case DOMAIN_GROUP_RID_ADMINS:
2166 ac = Domain_Admins;
2167 break;
2168 case DOMAIN_GROUP_RID_USERS:
2169 ac = Domain_Users;
2170 break;
2171 case DOMAIN_GROUP_RID_GUESTS:
2172 ac = Domain_Guests;
2173 break;
2174 case DOMAIN_GROUP_RID_COMPUTERS:
2175 ac = Domain_Computers;
2176 break;
2177 case DOMAIN_GROUP_RID_CONTROLLERS:
2178 ac = Domain_Controllers;
2179 break;
2180 case DOMAIN_GROUP_RID_CERT_ADMINS:
2181 ac = Cert_Publishers;
2182 break;
2183 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2184 ac = Schema_Admins;
2185 break;
2186 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2187 ac = Enterprise_Admins;
2188 break;
2189 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2190 ac = Group_Policy_Creator_Owners;
2191 break;
2192 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2193 ac = RAS_and_IAS_Servers;
2194 break;
2195 case 1000: /* first user account */
2196 size = UNLEN + 1;
2197 account_name = HeapAlloc(
2198 GetProcessHeap(), 0, size * sizeof(WCHAR));
2199 if (GetUserNameW(account_name, &size))
2200 ac = account_name;
2201 else
2202 dm = NULL;
2204 break;
2205 default:
2206 dm = NULL;
2207 break;
2215 if (dm) {
2216 DWORD ac_len = lstrlenW(ac);
2217 DWORD dm_len = lstrlenW(dm);
2218 BOOL status = TRUE;
2220 if (*accountSize > ac_len) {
2221 if (account)
2222 lstrcpyW(account, ac);
2224 if (*domainSize > dm_len) {
2225 if (domain)
2226 lstrcpyW(domain, dm);
2228 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2229 ((*domainSize != 0) && (*domainSize < dm_len))) {
2230 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2231 status = FALSE;
2233 if (*domainSize)
2234 *domainSize = dm_len;
2235 else
2236 *domainSize = dm_len + 1;
2237 if (*accountSize)
2238 *accountSize = ac_len;
2239 else
2240 *accountSize = ac_len + 1;
2241 *name_use = use;
2242 HeapFree(GetProcessHeap(), 0, account_name);
2243 HeapFree(GetProcessHeap(), 0, computer_name);
2244 return status;
2247 HeapFree(GetProcessHeap(), 0, account_name);
2248 HeapFree(GetProcessHeap(), 0, computer_name);
2249 SetLastError(ERROR_NONE_MAPPED);
2250 return FALSE;
2253 /******************************************************************************
2254 * SetFileSecurityA [ADVAPI32.@]
2256 * See SetFileSecurityW.
2258 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2259 SECURITY_INFORMATION RequestedInformation,
2260 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2262 DWORD len;
2263 BOOL r;
2264 LPWSTR name = NULL;
2266 if( lpFileName )
2268 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2269 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2270 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2273 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2274 HeapFree( GetProcessHeap(), 0, name );
2276 return r;
2279 /******************************************************************************
2280 * SetFileSecurityW [ADVAPI32.@]
2282 * Sets the security of a file or directory.
2284 * PARAMS
2285 * lpFileName []
2286 * RequestedInformation []
2287 * pSecurityDescriptor []
2289 * RETURNS
2290 * Success: TRUE.
2291 * Failure: FALSE.
2293 BOOL WINAPI
2294 SetFileSecurityW( LPCWSTR lpFileName,
2295 SECURITY_INFORMATION RequestedInformation,
2296 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2298 HANDLE file;
2299 DWORD access = 0;
2300 NTSTATUS status;
2302 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2303 pSecurityDescriptor );
2305 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2306 RequestedInformation & GROUP_SECURITY_INFORMATION)
2307 access |= WRITE_OWNER;
2308 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2309 access |= ACCESS_SYSTEM_SECURITY;
2310 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2311 access |= WRITE_DAC;
2313 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2314 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2315 if (file == INVALID_HANDLE_VALUE)
2316 return FALSE;
2318 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2319 CloseHandle( file );
2320 return set_ntstatus( status );
2323 /******************************************************************************
2324 * QueryWindows31FilesMigration [ADVAPI32.@]
2326 * PARAMS
2327 * x1 []
2329 BOOL WINAPI
2330 QueryWindows31FilesMigration( DWORD x1 )
2332 FIXME("(%d):stub\n",x1);
2333 return TRUE;
2336 /******************************************************************************
2337 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2339 * PARAMS
2340 * x1 []
2341 * x2 []
2342 * x3 []
2343 * x4 []
2345 BOOL WINAPI
2346 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2347 DWORD x4 )
2349 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2350 return TRUE;
2353 /******************************************************************************
2354 * NotifyBootConfigStatus [ADVAPI32.@]
2356 * PARAMS
2357 * x1 []
2359 BOOL WINAPI
2360 NotifyBootConfigStatus( BOOL x1 )
2362 FIXME("(0x%08d):stub\n",x1);
2363 return 1;
2366 /******************************************************************************
2367 * RevertToSelf [ADVAPI32.@]
2369 * Ends the impersonation of a user.
2371 * PARAMS
2372 * void []
2374 * RETURNS
2375 * Success: TRUE.
2376 * Failure: FALSE.
2378 BOOL WINAPI
2379 RevertToSelf( void )
2381 HANDLE Token = NULL;
2382 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2383 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2386 /******************************************************************************
2387 * ImpersonateSelf [ADVAPI32.@]
2389 * Makes an impersonation token that represents the process user and assigns
2390 * to the current thread.
2392 * PARAMS
2393 * ImpersonationLevel [I] Level at which to impersonate.
2395 * RETURNS
2396 * Success: TRUE.
2397 * Failure: FALSE.
2399 BOOL WINAPI
2400 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2402 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2405 /******************************************************************************
2406 * ImpersonateLoggedOnUser [ADVAPI32.@]
2408 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2410 DWORD size;
2411 NTSTATUS Status;
2412 HANDLE ImpersonationToken;
2413 TOKEN_TYPE Type;
2414 static BOOL warn = TRUE;
2416 if (warn)
2418 FIXME( "(%p)\n", hToken );
2419 warn = FALSE;
2421 if (!GetTokenInformation( hToken, TokenType, &Type,
2422 sizeof(TOKEN_TYPE), &size ))
2423 return FALSE;
2425 if (Type == TokenPrimary)
2427 OBJECT_ATTRIBUTES ObjectAttributes;
2429 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2431 Status = NtDuplicateToken( hToken,
2432 TOKEN_IMPERSONATE | TOKEN_QUERY,
2433 &ObjectAttributes,
2434 SecurityImpersonation,
2435 TokenImpersonation,
2436 &ImpersonationToken );
2437 if (Status != STATUS_SUCCESS)
2439 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2440 SetLastError( RtlNtStatusToDosError( Status ) );
2441 return FALSE;
2444 else
2445 ImpersonationToken = hToken;
2447 Status = NtSetInformationThread( GetCurrentThread(),
2448 ThreadImpersonationToken,
2449 &ImpersonationToken,
2450 sizeof(ImpersonationToken) );
2452 if (Type == TokenPrimary)
2453 NtClose( ImpersonationToken );
2455 if (Status != STATUS_SUCCESS)
2457 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2458 SetLastError( RtlNtStatusToDosError( Status ) );
2459 return FALSE;
2462 return TRUE;
2465 /******************************************************************************
2466 * AccessCheck [ADVAPI32.@]
2468 BOOL WINAPI
2469 AccessCheck(
2470 PSECURITY_DESCRIPTOR SecurityDescriptor,
2471 HANDLE ClientToken,
2472 DWORD DesiredAccess,
2473 PGENERIC_MAPPING GenericMapping,
2474 PPRIVILEGE_SET PrivilegeSet,
2475 LPDWORD PrivilegeSetLength,
2476 LPDWORD GrantedAccess,
2477 LPBOOL AccessStatus)
2479 NTSTATUS access_status;
2480 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2481 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2482 GrantedAccess, &access_status) );
2483 if (ret) *AccessStatus = set_ntstatus( access_status );
2484 return ret;
2488 /******************************************************************************
2489 * AccessCheckByType [ADVAPI32.@]
2491 BOOL WINAPI AccessCheckByType(
2492 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2493 PSID PrincipalSelfSid,
2494 HANDLE ClientToken,
2495 DWORD DesiredAccess,
2496 POBJECT_TYPE_LIST ObjectTypeList,
2497 DWORD ObjectTypeListLength,
2498 PGENERIC_MAPPING GenericMapping,
2499 PPRIVILEGE_SET PrivilegeSet,
2500 LPDWORD PrivilegeSetLength,
2501 LPDWORD GrantedAccess,
2502 LPBOOL AccessStatus)
2504 FIXME("stub\n");
2506 *AccessStatus = TRUE;
2508 return !*AccessStatus;
2511 /******************************************************************************
2512 * MapGenericMask [ADVAPI32.@]
2514 * Maps generic access rights into specific access rights according to the
2515 * supplied mapping.
2517 * PARAMS
2518 * AccessMask [I/O] Access rights.
2519 * GenericMapping [I] The mapping between generic and specific rights.
2521 * RETURNS
2522 * Nothing.
2524 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2526 RtlMapGenericMask( AccessMask, GenericMapping );
2529 /*************************************************************************
2530 * SetKernelObjectSecurity [ADVAPI32.@]
2532 BOOL WINAPI SetKernelObjectSecurity (
2533 IN HANDLE Handle,
2534 IN SECURITY_INFORMATION SecurityInformation,
2535 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2537 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2541 /******************************************************************************
2542 * AddAuditAccessAce [ADVAPI32.@]
2544 BOOL WINAPI AddAuditAccessAce(
2545 IN OUT PACL pAcl,
2546 IN DWORD dwAceRevision,
2547 IN DWORD dwAccessMask,
2548 IN PSID pSid,
2549 IN BOOL bAuditSuccess,
2550 IN BOOL bAuditFailure)
2552 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2553 bAuditSuccess, bAuditFailure) );
2556 /******************************************************************************
2557 * AddAuditAccessAce [ADVAPI32.@]
2559 BOOL WINAPI AddAuditAccessAceEx(
2560 IN OUT PACL pAcl,
2561 IN DWORD dwAceRevision,
2562 IN DWORD dwAceFlags,
2563 IN DWORD dwAccessMask,
2564 IN PSID pSid,
2565 IN BOOL bAuditSuccess,
2566 IN BOOL bAuditFailure)
2568 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2569 bAuditSuccess, bAuditFailure) );
2572 /******************************************************************************
2573 * LookupAccountNameA [ADVAPI32.@]
2575 BOOL WINAPI
2576 LookupAccountNameA(
2577 IN LPCSTR system,
2578 IN LPCSTR account,
2579 OUT PSID sid,
2580 OUT LPDWORD cbSid,
2581 LPSTR ReferencedDomainName,
2582 IN OUT LPDWORD cbReferencedDomainName,
2583 OUT PSID_NAME_USE name_use )
2585 BOOL ret;
2586 UNICODE_STRING lpSystemW;
2587 UNICODE_STRING lpAccountW;
2588 LPWSTR lpReferencedDomainNameW = NULL;
2590 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2591 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2593 if (ReferencedDomainName)
2594 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2596 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2597 cbReferencedDomainName, name_use);
2599 if (ret && lpReferencedDomainNameW)
2601 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2602 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2605 RtlFreeUnicodeString(&lpSystemW);
2606 RtlFreeUnicodeString(&lpAccountW);
2607 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2609 return ret;
2612 /******************************************************************************
2613 * lookup_user_account_name
2615 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2616 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2618 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2619 DWORD len = sizeof(buffer);
2620 HANDLE token;
2621 BOOL ret;
2622 PSID pSid;
2623 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2624 DWORD nameLen;
2625 LPCWSTR domainName;
2627 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2629 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2630 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2633 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2634 CloseHandle( token );
2636 if (!ret) return FALSE;
2638 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2640 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2641 CopySid(*cbSid, Sid, pSid);
2642 if (*cbSid < GetLengthSid(pSid))
2644 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2645 ret = FALSE;
2647 *cbSid = GetLengthSid(pSid);
2649 domainName = dm;
2650 nameLen = strlenW(domainName);
2652 if (*cchReferencedDomainName <= nameLen || !ret)
2654 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2655 nameLen += 1;
2656 ret = FALSE;
2658 else if (ReferencedDomainName)
2659 strcpyW(ReferencedDomainName, domainName);
2661 *cchReferencedDomainName = nameLen;
2663 if (ret)
2664 *peUse = SidTypeUser;
2666 return ret;
2669 /******************************************************************************
2670 * lookup_computer_account_name
2672 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2673 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2675 MAX_SID local;
2676 BOOL ret;
2677 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2678 DWORD nameLen;
2679 LPCWSTR domainName;
2681 if ((ret = ADVAPI_GetComputerSid(&local)))
2683 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2684 CopySid(*cbSid, Sid, &local);
2685 if (*cbSid < GetLengthSid(&local))
2687 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2688 ret = FALSE;
2690 *cbSid = GetLengthSid(&local);
2693 domainName = dm;
2694 nameLen = strlenW(domainName);
2696 if (*cchReferencedDomainName <= nameLen || !ret)
2698 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2699 nameLen += 1;
2700 ret = FALSE;
2702 else if (ReferencedDomainName)
2703 strcpyW(ReferencedDomainName, domainName);
2705 *cchReferencedDomainName = nameLen;
2707 if (ret)
2708 *peUse = SidTypeDomain;
2710 return ret;
2713 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2714 LSA_UNICODE_STRING *domain )
2716 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2718 while (p > str->Buffer && *p != '\\') p--;
2720 if (*p == '\\')
2722 domain->Buffer = str->Buffer;
2723 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2725 account->Buffer = p + 1;
2726 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2728 else
2730 domain->Buffer = NULL;
2731 domain->Length = 0;
2733 account->Buffer = str->Buffer;
2734 account->Length = str->Length;
2738 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2740 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2742 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2743 return TRUE;
2745 return FALSE;
2748 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2750 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2752 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2753 return TRUE;
2755 if (ACCOUNT_SIDS[idx].alias)
2757 len = strlenW( ACCOUNT_SIDS[idx].alias );
2758 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2759 return TRUE;
2761 return FALSE;
2765 * Helper function for LookupAccountNameW
2767 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2768 PSID Sid, LPDWORD cbSid,
2769 LPWSTR ReferencedDomainName,
2770 LPDWORD cchReferencedDomainName,
2771 PSID_NAME_USE peUse, BOOL *handled )
2773 PSID pSid;
2774 LSA_UNICODE_STRING account, domain;
2775 BOOL ret = TRUE;
2776 ULONG i;
2778 *handled = FALSE;
2779 split_domain_account( account_and_domain, &account, &domain );
2781 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2783 /* check domain first */
2784 if (domain.Buffer && !match_domain( i, &domain )) continue;
2786 if (match_account( i, &account ))
2788 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2790 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2792 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2794 if (*cbSid < sidLen)
2796 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2797 ret = FALSE;
2799 else if (Sid)
2801 CopySid(*cbSid, Sid, pSid);
2803 *cbSid = sidLen;
2806 len = strlenW( ACCOUNT_SIDS[i].domain );
2807 if (*cchReferencedDomainName <= len || !ret)
2809 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2810 len++;
2811 ret = FALSE;
2813 else if (ReferencedDomainName)
2815 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2818 *cchReferencedDomainName = len;
2819 if (ret)
2820 *peUse = ACCOUNT_SIDS[i].name_use;
2822 HeapFree(GetProcessHeap(), 0, pSid);
2823 *handled = TRUE;
2824 return ret;
2827 return ret;
2830 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2831 PSID Sid, LPDWORD cbSid,
2832 LPWSTR ReferencedDomainName,
2833 LPDWORD cchReferencedDomainName,
2834 PSID_NAME_USE peUse, BOOL *handled )
2836 DWORD nameLen;
2837 LPWSTR userName = NULL;
2838 LSA_UNICODE_STRING account, domain;
2839 BOOL ret = TRUE;
2841 *handled = FALSE;
2842 split_domain_account( account_and_domain, &account, &domain );
2844 /* Let the current Unix user id masquerade as first Windows user account */
2846 nameLen = UNLEN + 1;
2847 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2849 if (domain.Buffer)
2851 /* check to make sure this account is on this computer */
2852 if (GetComputerNameW( userName, &nameLen ) &&
2853 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2855 SetLastError(ERROR_NONE_MAPPED);
2856 ret = FALSE;
2858 nameLen = UNLEN + 1;
2861 if (GetUserNameW( userName, &nameLen ) &&
2862 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2864 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2865 *handled = TRUE;
2867 else
2869 nameLen = UNLEN + 1;
2870 if (GetComputerNameW( userName, &nameLen ) &&
2871 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2873 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2874 *handled = TRUE;
2878 HeapFree(GetProcessHeap(), 0, userName);
2879 return ret;
2882 /******************************************************************************
2883 * LookupAccountNameW [ADVAPI32.@]
2885 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2886 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2887 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2889 BOOL ret, handled;
2890 LSA_UNICODE_STRING account;
2892 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2893 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2895 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2897 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2898 return FALSE;
2901 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2903 lpAccountName = BUILTIN;
2906 RtlInitUnicodeString( &account, lpAccountName );
2908 /* Check well known SIDs first */
2909 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2910 cchReferencedDomainName, peUse, &handled );
2911 if (handled)
2912 return ret;
2914 /* Check user names */
2915 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2916 cchReferencedDomainName, peUse, &handled);
2917 if (handled)
2918 return ret;
2920 SetLastError( ERROR_NONE_MAPPED );
2921 return FALSE;
2924 /******************************************************************************
2925 * PrivilegeCheck [ADVAPI32.@]
2927 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2929 BOOL ret;
2930 BOOLEAN Result;
2932 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2934 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2935 if (ret)
2936 *pfResult = Result;
2937 return ret;
2940 /******************************************************************************
2941 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2943 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2944 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2945 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2946 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2948 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2949 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2950 SecurityDescriptor, DesiredAccess, GenericMapping,
2951 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2952 return TRUE;
2955 /******************************************************************************
2956 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2958 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2959 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2960 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2961 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2963 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2964 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2965 SecurityDescriptor, DesiredAccess, GenericMapping,
2966 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2967 return TRUE;
2970 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2972 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2974 return TRUE;
2977 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2979 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2981 return TRUE;
2984 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2986 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2988 return TRUE;
2991 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2992 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2993 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2994 LPBOOL GenerateOnClose)
2996 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2997 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2998 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2999 GenerateOnClose);
3001 return TRUE;
3004 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3005 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3006 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3007 LPBOOL GenerateOnClose)
3009 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3010 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3011 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3012 GenerateOnClose);
3014 return TRUE;
3017 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3018 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3020 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3021 DesiredAccess, Privileges, AccessGranted);
3023 return TRUE;
3026 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3027 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3029 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3030 DesiredAccess, Privileges, AccessGranted);
3032 return TRUE;
3035 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3036 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3038 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3039 ClientToken, Privileges, AccessGranted);
3041 return TRUE;
3044 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3045 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3047 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3048 ClientToken, Privileges, AccessGranted);
3050 return TRUE;
3053 /******************************************************************************
3054 * GetSecurityInfo [ADVAPI32.@]
3056 * Retrieves a copy of the security descriptor associated with an object.
3058 * PARAMS
3059 * hObject [I] A handle for the object.
3060 * ObjectType [I] The type of object.
3061 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3062 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3063 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3064 * ppDacl [O] If non-null, receives a pointer to the DACL.
3065 * ppSacl [O] If non-null, receives a pointer to the SACL.
3066 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3067 * which must be freed with LocalFree.
3069 * RETURNS
3070 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3072 DWORD WINAPI GetSecurityInfo(
3073 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3074 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3075 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3076 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3079 PSECURITY_DESCRIPTOR sd;
3080 NTSTATUS status;
3081 ULONG n1, n2;
3082 BOOL present, defaulted;
3084 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3085 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3086 return RtlNtStatusToDosError(status);
3088 sd = LocalAlloc(0, n1);
3089 if (!sd)
3090 return ERROR_NOT_ENOUGH_MEMORY;
3092 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3093 if (status != STATUS_SUCCESS)
3095 LocalFree(sd);
3096 return RtlNtStatusToDosError(status);
3099 if (ppsidOwner)
3101 *ppsidOwner = NULL;
3102 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3104 if (ppsidGroup)
3106 *ppsidGroup = NULL;
3107 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3109 if (ppDacl)
3111 *ppDacl = NULL;
3112 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3114 if (ppSacl)
3116 *ppSacl = NULL;
3117 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3119 if (ppSecurityDescriptor)
3120 *ppSecurityDescriptor = sd;
3122 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3123 * NULL, because native happily returns the SIDs and ACLs that are requested
3124 * in this case.
3127 return ERROR_SUCCESS;
3130 /******************************************************************************
3131 * GetSecurityInfoExA [ADVAPI32.@]
3133 DWORD WINAPI GetSecurityInfoExA(
3134 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3135 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3136 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3137 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3140 FIXME("stub!\n");
3141 return ERROR_BAD_PROVIDER;
3144 /******************************************************************************
3145 * GetSecurityInfoExW [ADVAPI32.@]
3147 DWORD WINAPI GetSecurityInfoExW(
3148 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3149 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3150 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3151 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3154 FIXME("stub!\n");
3155 return ERROR_BAD_PROVIDER;
3158 /******************************************************************************
3159 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3161 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3162 LPSTR pTrusteeName, DWORD AccessPermissions,
3163 ACCESS_MODE AccessMode, DWORD Inheritance )
3165 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3166 AccessPermissions, AccessMode, Inheritance);
3168 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3169 pExplicitAccess->grfAccessMode = AccessMode;
3170 pExplicitAccess->grfInheritance = Inheritance;
3172 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3173 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3174 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3175 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3176 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3179 /******************************************************************************
3180 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3182 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3183 LPWSTR pTrusteeName, DWORD AccessPermissions,
3184 ACCESS_MODE AccessMode, DWORD Inheritance )
3186 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3187 AccessPermissions, AccessMode, Inheritance);
3189 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3190 pExplicitAccess->grfAccessMode = AccessMode;
3191 pExplicitAccess->grfInheritance = Inheritance;
3193 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3194 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3195 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3196 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3197 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3200 /******************************************************************************
3201 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3203 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3204 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3205 LPSTR InheritedObjectTypeName, LPSTR Name )
3207 DWORD ObjectsPresent = 0;
3209 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3210 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3212 /* Fill the OBJECTS_AND_NAME structure */
3213 pObjName->ObjectType = ObjectType;
3214 if (ObjectTypeName != NULL)
3216 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3219 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3220 if (InheritedObjectTypeName != NULL)
3222 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3225 pObjName->ObjectsPresent = ObjectsPresent;
3226 pObjName->ptstrName = Name;
3228 /* Fill the TRUSTEE structure */
3229 pTrustee->pMultipleTrustee = NULL;
3230 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3231 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3232 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3233 pTrustee->ptstrName = (LPSTR)pObjName;
3236 /******************************************************************************
3237 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3239 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3240 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3241 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3243 DWORD ObjectsPresent = 0;
3245 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3246 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3248 /* Fill the OBJECTS_AND_NAME structure */
3249 pObjName->ObjectType = ObjectType;
3250 if (ObjectTypeName != NULL)
3252 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3255 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3256 if (InheritedObjectTypeName != NULL)
3258 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3261 pObjName->ObjectsPresent = ObjectsPresent;
3262 pObjName->ptstrName = Name;
3264 /* Fill the TRUSTEE structure */
3265 pTrustee->pMultipleTrustee = NULL;
3266 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3267 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3268 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3269 pTrustee->ptstrName = (LPWSTR)pObjName;
3272 /******************************************************************************
3273 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3275 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3276 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3278 DWORD ObjectsPresent = 0;
3280 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3282 /* Fill the OBJECTS_AND_SID structure */
3283 if (pObjectGuid != NULL)
3285 pObjSid->ObjectTypeGuid = *pObjectGuid;
3286 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3288 else
3290 ZeroMemory(&pObjSid->ObjectTypeGuid,
3291 sizeof(GUID));
3294 if (pInheritedObjectGuid != NULL)
3296 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3297 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3299 else
3301 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3302 sizeof(GUID));
3305 pObjSid->ObjectsPresent = ObjectsPresent;
3306 pObjSid->pSid = pSid;
3308 /* Fill the TRUSTEE structure */
3309 pTrustee->pMultipleTrustee = NULL;
3310 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3311 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3312 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3313 pTrustee->ptstrName = (LPSTR) pObjSid;
3316 /******************************************************************************
3317 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3319 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3320 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3322 DWORD ObjectsPresent = 0;
3324 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3326 /* Fill the OBJECTS_AND_SID structure */
3327 if (pObjectGuid != NULL)
3329 pObjSid->ObjectTypeGuid = *pObjectGuid;
3330 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3332 else
3334 ZeroMemory(&pObjSid->ObjectTypeGuid,
3335 sizeof(GUID));
3338 if (pInheritedObjectGuid != NULL)
3340 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3341 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3343 else
3345 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3346 sizeof(GUID));
3349 pObjSid->ObjectsPresent = ObjectsPresent;
3350 pObjSid->pSid = pSid;
3352 /* Fill the TRUSTEE structure */
3353 pTrustee->pMultipleTrustee = NULL;
3354 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3355 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3356 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3357 pTrustee->ptstrName = (LPWSTR) pObjSid;
3360 /******************************************************************************
3361 * BuildTrusteeWithSidA [ADVAPI32.@]
3363 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3365 TRACE("%p %p\n", pTrustee, pSid);
3367 pTrustee->pMultipleTrustee = NULL;
3368 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3369 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3370 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3371 pTrustee->ptstrName = pSid;
3374 /******************************************************************************
3375 * BuildTrusteeWithSidW [ADVAPI32.@]
3377 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3379 TRACE("%p %p\n", pTrustee, pSid);
3381 pTrustee->pMultipleTrustee = NULL;
3382 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3383 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3384 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3385 pTrustee->ptstrName = pSid;
3388 /******************************************************************************
3389 * BuildTrusteeWithNameA [ADVAPI32.@]
3391 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3393 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3395 pTrustee->pMultipleTrustee = NULL;
3396 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3397 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3398 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3399 pTrustee->ptstrName = name;
3402 /******************************************************************************
3403 * BuildTrusteeWithNameW [ADVAPI32.@]
3405 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3407 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3409 pTrustee->pMultipleTrustee = NULL;
3410 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3411 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3412 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3413 pTrustee->ptstrName = name;
3416 /******************************************************************************
3417 * GetTrusteeFormA [ADVAPI32.@]
3419 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3421 TRACE("(%p)\n", pTrustee);
3423 if (!pTrustee)
3424 return TRUSTEE_BAD_FORM;
3426 return pTrustee->TrusteeForm;
3429 /******************************************************************************
3430 * GetTrusteeFormW [ADVAPI32.@]
3432 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3434 TRACE("(%p)\n", pTrustee);
3436 if (!pTrustee)
3437 return TRUSTEE_BAD_FORM;
3439 return pTrustee->TrusteeForm;
3442 /******************************************************************************
3443 * GetTrusteeNameA [ADVAPI32.@]
3445 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3447 TRACE("(%p)\n", pTrustee);
3449 if (!pTrustee)
3450 return NULL;
3452 return pTrustee->ptstrName;
3455 /******************************************************************************
3456 * GetTrusteeNameW [ADVAPI32.@]
3458 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3460 TRACE("(%p)\n", pTrustee);
3462 if (!pTrustee)
3463 return NULL;
3465 return pTrustee->ptstrName;
3468 /******************************************************************************
3469 * GetTrusteeTypeA [ADVAPI32.@]
3471 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3473 TRACE("(%p)\n", pTrustee);
3475 if (!pTrustee)
3476 return TRUSTEE_IS_UNKNOWN;
3478 return pTrustee->TrusteeType;
3481 /******************************************************************************
3482 * GetTrusteeTypeW [ADVAPI32.@]
3484 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3486 TRACE("(%p)\n", pTrustee);
3488 if (!pTrustee)
3489 return TRUSTEE_IS_UNKNOWN;
3491 return pTrustee->TrusteeType;
3494 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3495 DWORD nAclInformationLength,
3496 ACL_INFORMATION_CLASS dwAclInformationClass )
3498 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3499 nAclInformationLength, dwAclInformationClass);
3501 return TRUE;
3504 /******************************************************************************
3505 * SetEntriesInAclA [ADVAPI32.@]
3507 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3508 PACL OldAcl, PACL* NewAcl )
3510 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3511 if (NewAcl)
3512 *NewAcl = NULL;
3513 return ERROR_SUCCESS;
3516 /******************************************************************************
3517 * SetEntriesInAclW [ADVAPI32.@]
3519 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3520 PACL OldAcl, PACL* NewAcl )
3522 ULONG i;
3523 PSID *ppsid;
3524 DWORD ret = ERROR_SUCCESS;
3525 DWORD acl_size = sizeof(ACL);
3526 NTSTATUS status;
3528 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3530 *NewAcl = NULL;
3532 if (!count && !OldAcl)
3533 return ERROR_SUCCESS;
3535 /* allocate array of maximum sized sids allowed */
3536 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3537 if (!ppsid)
3538 return ERROR_OUTOFMEMORY;
3540 for (i = 0; i < count; i++)
3542 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3544 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3545 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3546 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3547 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3548 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3549 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3550 pEntries[i].Trustee.ptstrName);
3552 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3554 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3555 ret = ERROR_INVALID_PARAMETER;
3556 goto exit;
3559 switch (pEntries[i].Trustee.TrusteeForm)
3561 case TRUSTEE_IS_SID:
3562 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3563 ppsid[i], pEntries[i].Trustee.ptstrName))
3565 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3566 ret = ERROR_INVALID_PARAMETER;
3567 goto exit;
3569 break;
3570 case TRUSTEE_IS_NAME:
3572 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3573 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3574 SID_NAME_USE use;
3575 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3577 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3579 ret = GetLastError();
3580 goto exit;
3583 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3585 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3586 ret = ERROR_INVALID_PARAMETER;
3587 goto exit;
3589 break;
3591 case TRUSTEE_IS_OBJECTS_AND_SID:
3592 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3593 break;
3594 case TRUSTEE_IS_OBJECTS_AND_NAME:
3595 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3596 break;
3597 default:
3598 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3599 ret = ERROR_INVALID_PARAMETER;
3600 goto exit;
3603 /* Note: we overestimate the ACL size here as a tradeoff between
3604 * instructions (simplicity) and memory */
3605 switch (pEntries[i].grfAccessMode)
3607 case GRANT_ACCESS:
3608 case SET_ACCESS:
3609 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3610 break;
3611 case DENY_ACCESS:
3612 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3613 break;
3614 case SET_AUDIT_SUCCESS:
3615 case SET_AUDIT_FAILURE:
3616 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3617 break;
3618 case REVOKE_ACCESS:
3619 break;
3620 default:
3621 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3622 ret = ERROR_INVALID_PARAMETER;
3623 goto exit;
3627 if (OldAcl)
3629 ACL_SIZE_INFORMATION size_info;
3631 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3632 if (status != STATUS_SUCCESS)
3634 ret = RtlNtStatusToDosError(status);
3635 goto exit;
3637 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3640 *NewAcl = LocalAlloc(0, acl_size);
3641 if (!*NewAcl)
3643 ret = ERROR_OUTOFMEMORY;
3644 goto exit;
3647 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3648 if (status != STATUS_SUCCESS)
3650 ret = RtlNtStatusToDosError(status);
3651 goto exit;
3654 for (i = 0; i < count; i++)
3656 switch (pEntries[i].grfAccessMode)
3658 case GRANT_ACCESS:
3659 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3660 pEntries[i].grfInheritance,
3661 pEntries[i].grfAccessPermissions,
3662 ppsid[i]);
3663 break;
3664 case SET_ACCESS:
3666 ULONG j;
3667 BOOL add = TRUE;
3668 if (OldAcl)
3670 for (j = 0; ; j++)
3672 const ACE_HEADER *existing_ace_header;
3673 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3674 if (status != STATUS_SUCCESS)
3675 break;
3676 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3677 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3678 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3680 add = FALSE;
3681 break;
3685 if (add)
3686 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3687 pEntries[i].grfInheritance,
3688 pEntries[i].grfAccessPermissions,
3689 ppsid[i]);
3690 break;
3692 case DENY_ACCESS:
3693 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3694 pEntries[i].grfInheritance,
3695 pEntries[i].grfAccessPermissions,
3696 ppsid[i]);
3697 break;
3698 case SET_AUDIT_SUCCESS:
3699 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3700 pEntries[i].grfInheritance,
3701 pEntries[i].grfAccessPermissions,
3702 ppsid[i], TRUE, FALSE);
3703 break;
3704 case SET_AUDIT_FAILURE:
3705 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3706 pEntries[i].grfInheritance,
3707 pEntries[i].grfAccessPermissions,
3708 ppsid[i], FALSE, TRUE);
3709 break;
3710 default:
3711 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3715 if (OldAcl)
3717 for (i = 0; ; i++)
3719 BOOL add = TRUE;
3720 ULONG j;
3721 const ACE_HEADER *old_ace_header;
3722 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3723 if (status != STATUS_SUCCESS) break;
3724 for (j = 0; j < count; j++)
3726 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3727 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3728 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3730 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3731 add = FALSE;
3732 break;
3734 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3736 switch (old_ace_header->AceType)
3738 case ACCESS_ALLOWED_ACE_TYPE:
3739 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3740 add = FALSE;
3741 break;
3742 case ACCESS_DENIED_ACE_TYPE:
3743 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3744 add = FALSE;
3745 break;
3746 case SYSTEM_AUDIT_ACE_TYPE:
3747 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3748 add = FALSE;
3749 break;
3750 case SYSTEM_ALARM_ACE_TYPE:
3751 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3752 add = FALSE;
3753 break;
3754 default:
3755 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3758 if (!add)
3759 break;
3762 if (add)
3763 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3764 if (status != STATUS_SUCCESS)
3766 WARN("RtlAddAce failed with error 0x%08x\n", status);
3767 ret = RtlNtStatusToDosError(status);
3768 break;
3773 exit:
3774 HeapFree(GetProcessHeap(), 0, ppsid);
3775 return ret;
3778 /******************************************************************************
3779 * SetNamedSecurityInfoA [ADVAPI32.@]
3781 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3782 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3783 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3785 DWORD len;
3786 LPWSTR wstr = NULL;
3787 DWORD r;
3789 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3790 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3792 if( pObjectName )
3794 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3795 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3796 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3799 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3800 psidGroup, pDacl, pSacl );
3802 HeapFree( GetProcessHeap(), 0, wstr );
3804 return r;
3807 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3808 PSECURITY_DESCRIPTOR ModificationDescriptor,
3809 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3810 PGENERIC_MAPPING GenericMapping,
3811 HANDLE Token )
3813 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3814 ObjectsSecurityDescriptor, GenericMapping, Token);
3816 return TRUE;
3819 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3821 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3824 /******************************************************************************
3825 * AreAnyAccessesGranted [ADVAPI32.@]
3827 * Determines whether or not any of a set of specified access permissions have
3828 * been granted or not.
3830 * PARAMS
3831 * GrantedAccess [I] The permissions that have been granted.
3832 * DesiredAccess [I] The permissions that you want to have.
3834 * RETURNS
3835 * Nonzero if any of the permissions have been granted, zero if none of the
3836 * permissions have been granted.
3839 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3841 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3844 /******************************************************************************
3845 * SetNamedSecurityInfoW [ADVAPI32.@]
3847 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3848 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3849 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3851 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3852 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3853 return ERROR_SUCCESS;
3856 /******************************************************************************
3857 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3859 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3860 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3862 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3863 return ERROR_CALL_NOT_IMPLEMENTED;
3866 /******************************************************************************
3867 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3869 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3870 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3872 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3873 return ERROR_CALL_NOT_IMPLEMENTED;
3876 /******************************************************************************
3877 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3879 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3880 PACCESS_MASK pFailedAuditRights)
3882 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3883 return ERROR_CALL_NOT_IMPLEMENTED;
3887 /******************************************************************************
3888 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3890 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3891 PACCESS_MASK pFailedAuditRights)
3893 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3894 return ERROR_CALL_NOT_IMPLEMENTED;
3898 /******************************************************************************
3899 * ParseAclStringFlags
3901 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3903 DWORD flags = 0;
3904 LPCWSTR szAcl = *StringAcl;
3906 while (*szAcl != '(')
3908 if (*szAcl == 'P')
3910 flags |= SE_DACL_PROTECTED;
3912 else if (*szAcl == 'A')
3914 szAcl++;
3915 if (*szAcl == 'R')
3916 flags |= SE_DACL_AUTO_INHERIT_REQ;
3917 else if (*szAcl == 'I')
3918 flags |= SE_DACL_AUTO_INHERITED;
3920 szAcl++;
3923 *StringAcl = szAcl;
3924 return flags;
3927 /******************************************************************************
3928 * ParseAceStringType
3930 static const ACEFLAG AceType[] =
3932 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3933 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3934 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3935 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3937 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3938 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3939 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3940 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3942 { NULL, 0 },
3945 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3947 UINT len = 0;
3948 LPCWSTR szAcl = *StringAcl;
3949 const ACEFLAG *lpaf = AceType;
3951 while (*szAcl == ' ')
3952 szAcl++;
3954 while (lpaf->wstr &&
3955 (len = strlenW(lpaf->wstr)) &&
3956 strncmpW(lpaf->wstr, szAcl, len))
3957 lpaf++;
3959 if (!lpaf->wstr)
3960 return 0;
3962 *StringAcl = szAcl + len;
3963 return lpaf->value;
3967 /******************************************************************************
3968 * ParseAceStringFlags
3970 static const ACEFLAG AceFlags[] =
3972 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3973 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3974 { SDDL_INHERITED, INHERITED_ACE },
3975 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3976 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3977 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3978 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3979 { NULL, 0 },
3982 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3984 UINT len = 0;
3985 BYTE flags = 0;
3986 LPCWSTR szAcl = *StringAcl;
3988 while (*szAcl == ' ')
3989 szAcl++;
3991 while (*szAcl != ';')
3993 const ACEFLAG *lpaf = AceFlags;
3995 while (lpaf->wstr &&
3996 (len = strlenW(lpaf->wstr)) &&
3997 strncmpW(lpaf->wstr, szAcl, len))
3998 lpaf++;
4000 if (!lpaf->wstr)
4001 return 0;
4003 flags |= lpaf->value;
4004 szAcl += len;
4007 *StringAcl = szAcl;
4008 return flags;
4012 /******************************************************************************
4013 * ParseAceStringRights
4015 static const ACEFLAG AceRights[] =
4017 { SDDL_GENERIC_ALL, GENERIC_ALL },
4018 { SDDL_GENERIC_READ, GENERIC_READ },
4019 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4020 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4022 { SDDL_READ_CONTROL, READ_CONTROL },
4023 { SDDL_STANDARD_DELETE, DELETE },
4024 { SDDL_WRITE_DAC, WRITE_DAC },
4025 { SDDL_WRITE_OWNER, WRITE_OWNER },
4027 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4028 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4029 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4030 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4031 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4032 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4033 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4034 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4035 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4037 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4038 { SDDL_FILE_READ, FILE_GENERIC_READ },
4039 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4040 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4042 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4043 { SDDL_KEY_READ, KEY_READ },
4044 { SDDL_KEY_WRITE, KEY_WRITE },
4045 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4046 { NULL, 0 },
4049 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4051 UINT len = 0;
4052 DWORD rights = 0;
4053 LPCWSTR szAcl = *StringAcl;
4055 while (*szAcl == ' ')
4056 szAcl++;
4058 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4060 LPCWSTR p = szAcl;
4062 while (*p && *p != ';')
4063 p++;
4065 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4067 rights = strtoulW(szAcl, NULL, 16);
4068 szAcl = p;
4070 else
4071 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4073 else
4075 while (*szAcl != ';')
4077 const ACEFLAG *lpaf = AceRights;
4079 while (lpaf->wstr &&
4080 (len = strlenW(lpaf->wstr)) &&
4081 strncmpW(lpaf->wstr, szAcl, len))
4083 lpaf++;
4086 if (!lpaf->wstr)
4087 return 0;
4089 rights |= lpaf->value;
4090 szAcl += len;
4094 *StringAcl = szAcl;
4095 return rights;
4099 /******************************************************************************
4100 * ParseStringAclToAcl
4102 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4104 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4105 PACL pAcl, LPDWORD cBytes)
4107 DWORD val;
4108 DWORD sidlen;
4109 DWORD length = sizeof(ACL);
4110 DWORD acesize = 0;
4111 DWORD acecount = 0;
4112 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4113 DWORD error = ERROR_INVALID_ACL;
4115 TRACE("%s\n", debugstr_w(StringAcl));
4117 if (!StringAcl)
4118 return FALSE;
4120 if (pAcl) /* pAce is only useful if we're setting values */
4121 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4123 /* Parse ACL flags */
4124 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4126 /* Parse ACE */
4127 while (*StringAcl == '(')
4129 StringAcl++;
4131 /* Parse ACE type */
4132 val = ParseAceStringType(&StringAcl);
4133 if (pAce)
4134 pAce->Header.AceType = (BYTE) val;
4135 if (*StringAcl != ';')
4137 error = RPC_S_INVALID_STRING_UUID;
4138 goto lerr;
4140 StringAcl++;
4142 /* Parse ACE flags */
4143 val = ParseAceStringFlags(&StringAcl);
4144 if (pAce)
4145 pAce->Header.AceFlags = (BYTE) val;
4146 if (*StringAcl != ';')
4147 goto lerr;
4148 StringAcl++;
4150 /* Parse ACE rights */
4151 val = ParseAceStringRights(&StringAcl);
4152 if (pAce)
4153 pAce->Mask = val;
4154 if (*StringAcl != ';')
4155 goto lerr;
4156 StringAcl++;
4158 /* Parse ACE object guid */
4159 while (*StringAcl == ' ')
4160 StringAcl++;
4161 if (*StringAcl != ';')
4163 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4164 goto lerr;
4166 StringAcl++;
4168 /* Parse ACE inherit object guid */
4169 while (*StringAcl == ' ')
4170 StringAcl++;
4171 if (*StringAcl != ';')
4173 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4174 goto lerr;
4176 StringAcl++;
4178 /* Parse ACE account sid */
4179 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4181 while (*StringAcl && *StringAcl != ')')
4182 StringAcl++;
4185 if (*StringAcl != ')')
4186 goto lerr;
4187 StringAcl++;
4189 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4190 length += acesize;
4191 if (pAce)
4193 pAce->Header.AceSize = acesize;
4194 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4196 acecount++;
4199 *cBytes = length;
4201 if (length > 0xffff)
4203 ERR("ACL too large\n");
4204 goto lerr;
4207 if (pAcl)
4209 pAcl->AclRevision = ACL_REVISION;
4210 pAcl->Sbz1 = 0;
4211 pAcl->AclSize = length;
4212 pAcl->AceCount = acecount++;
4213 pAcl->Sbz2 = 0;
4215 return TRUE;
4217 lerr:
4218 SetLastError(error);
4219 WARN("Invalid ACE string format\n");
4220 return FALSE;
4224 /******************************************************************************
4225 * ParseStringSecurityDescriptorToSecurityDescriptor
4227 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4228 LPCWSTR StringSecurityDescriptor,
4229 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4230 LPDWORD cBytes)
4232 BOOL bret = FALSE;
4233 WCHAR toktype;
4234 WCHAR tok[MAX_PATH];
4235 LPCWSTR lptoken;
4236 LPBYTE lpNext = NULL;
4237 DWORD len;
4239 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4241 if (SecurityDescriptor)
4242 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4244 while (*StringSecurityDescriptor == ' ')
4245 StringSecurityDescriptor++;
4247 while (*StringSecurityDescriptor)
4249 toktype = *StringSecurityDescriptor;
4251 /* Expect char identifier followed by ':' */
4252 StringSecurityDescriptor++;
4253 if (*StringSecurityDescriptor != ':')
4255 SetLastError(ERROR_INVALID_PARAMETER);
4256 goto lend;
4258 StringSecurityDescriptor++;
4260 /* Extract token */
4261 lptoken = StringSecurityDescriptor;
4262 while (*lptoken && *lptoken != ':')
4263 lptoken++;
4265 if (*lptoken)
4266 lptoken--;
4268 len = lptoken - StringSecurityDescriptor;
4269 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4270 tok[len] = 0;
4272 switch (toktype)
4274 case 'O':
4276 DWORD bytes;
4278 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4279 goto lend;
4281 if (SecurityDescriptor)
4283 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4284 lpNext += bytes; /* Advance to next token */
4287 *cBytes += bytes;
4289 break;
4292 case 'G':
4294 DWORD bytes;
4296 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4297 goto lend;
4299 if (SecurityDescriptor)
4301 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4302 lpNext += bytes; /* Advance to next token */
4305 *cBytes += bytes;
4307 break;
4310 case 'D':
4312 DWORD flags;
4313 DWORD bytes;
4315 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4316 goto lend;
4318 if (SecurityDescriptor)
4320 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4321 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4322 lpNext += bytes; /* Advance to next token */
4325 *cBytes += bytes;
4327 break;
4330 case 'S':
4332 DWORD flags;
4333 DWORD bytes;
4335 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4336 goto lend;
4338 if (SecurityDescriptor)
4340 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4341 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4342 lpNext += bytes; /* Advance to next token */
4345 *cBytes += bytes;
4347 break;
4350 default:
4351 FIXME("Unknown token\n");
4352 SetLastError(ERROR_INVALID_PARAMETER);
4353 goto lend;
4356 StringSecurityDescriptor = lptoken;
4359 bret = TRUE;
4361 lend:
4362 return bret;
4365 /******************************************************************************
4366 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4368 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4369 LPCSTR StringSecurityDescriptor,
4370 DWORD StringSDRevision,
4371 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4372 PULONG SecurityDescriptorSize)
4374 UINT len;
4375 BOOL ret = FALSE;
4376 LPWSTR StringSecurityDescriptorW;
4378 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4379 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4381 if (StringSecurityDescriptorW)
4383 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4385 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4386 StringSDRevision, SecurityDescriptor,
4387 SecurityDescriptorSize);
4388 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4391 return ret;
4394 /******************************************************************************
4395 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4397 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4398 LPCWSTR StringSecurityDescriptor,
4399 DWORD StringSDRevision,
4400 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4401 PULONG SecurityDescriptorSize)
4403 DWORD cBytes;
4404 SECURITY_DESCRIPTOR* psd;
4405 BOOL bret = FALSE;
4407 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4409 if (GetVersion() & 0x80000000)
4411 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4412 goto lend;
4414 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4416 SetLastError(ERROR_INVALID_PARAMETER);
4417 goto lend;
4419 else if (StringSDRevision != SID_REVISION)
4421 SetLastError(ERROR_UNKNOWN_REVISION);
4422 goto lend;
4425 /* Compute security descriptor length */
4426 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4427 NULL, &cBytes))
4428 goto lend;
4430 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4431 if (!psd) goto lend;
4433 psd->Revision = SID_REVISION;
4434 psd->Control |= SE_SELF_RELATIVE;
4436 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4437 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4439 LocalFree(psd);
4440 goto lend;
4443 if (SecurityDescriptorSize)
4444 *SecurityDescriptorSize = cBytes;
4446 bret = TRUE;
4448 lend:
4449 TRACE(" ret=%d\n", bret);
4450 return bret;
4453 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4455 if (cch == -1)
4456 cch = strlenW(string);
4458 if (plen)
4459 *plen += cch;
4461 if (pwptr)
4463 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4464 *pwptr += cch;
4468 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4470 DWORD i;
4471 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4472 WCHAR subauthfmt[] = { '-','%','u',0 };
4473 WCHAR buf[26];
4474 SID *pisid = psid;
4476 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4478 SetLastError(ERROR_INVALID_SID);
4479 return FALSE;
4482 if (pisid->IdentifierAuthority.Value[0] ||
4483 pisid->IdentifierAuthority.Value[1])
4485 FIXME("not matching MS' bugs\n");
4486 SetLastError(ERROR_INVALID_SID);
4487 return FALSE;
4490 sprintfW( buf, fmt, pisid->Revision,
4491 MAKELONG(
4492 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4493 pisid->IdentifierAuthority.Value[4] ),
4494 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4495 pisid->IdentifierAuthority.Value[2] )
4496 ) );
4497 DumpString(buf, -1, pwptr, plen);
4499 for( i=0; i<pisid->SubAuthorityCount; i++ )
4501 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4502 DumpString(buf, -1, pwptr, plen);
4504 return TRUE;
4507 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4509 size_t i;
4510 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4512 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4514 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4515 return TRUE;
4519 return DumpSidNumeric(psid, pwptr, plen);
4522 static const LPCWSTR AceRightBitNames[32] = {
4523 SDDL_CREATE_CHILD, /* 0 */
4524 SDDL_DELETE_CHILD,
4525 SDDL_LIST_CHILDREN,
4526 SDDL_SELF_WRITE,
4527 SDDL_READ_PROPERTY, /* 4 */
4528 SDDL_WRITE_PROPERTY,
4529 SDDL_DELETE_TREE,
4530 SDDL_LIST_OBJECT,
4531 SDDL_CONTROL_ACCESS, /* 8 */
4532 NULL,
4533 NULL,
4534 NULL,
4535 NULL, /* 12 */
4536 NULL,
4537 NULL,
4538 NULL,
4539 SDDL_STANDARD_DELETE, /* 16 */
4540 SDDL_READ_CONTROL,
4541 SDDL_WRITE_DAC,
4542 SDDL_WRITE_OWNER,
4543 NULL, /* 20 */
4544 NULL,
4545 NULL,
4546 NULL,
4547 NULL, /* 24 */
4548 NULL,
4549 NULL,
4550 NULL,
4551 SDDL_GENERIC_ALL, /* 28 */
4552 SDDL_GENERIC_EXECUTE,
4553 SDDL_GENERIC_WRITE,
4554 SDDL_GENERIC_READ
4557 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4559 static const WCHAR fmtW[] = {'0','x','%','x',0};
4560 WCHAR buf[15];
4561 size_t i;
4563 if (mask == 0)
4564 return;
4566 /* first check if the right have name */
4567 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4569 if (AceRights[i].wstr == NULL)
4570 break;
4571 if (mask == AceRights[i].value)
4573 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4574 return;
4578 /* then check if it can be built from bit names */
4579 for (i = 0; i < 32; i++)
4581 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4583 /* can't be built from bit names */
4584 sprintfW(buf, fmtW, mask);
4585 DumpString(buf, -1, pwptr, plen);
4586 return;
4590 /* build from bit names */
4591 for (i = 0; i < 32; i++)
4592 if (mask & (1 << i))
4593 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4596 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4598 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4599 static const WCHAR openbr = '(';
4600 static const WCHAR closebr = ')';
4601 static const WCHAR semicolon = ';';
4603 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4605 SetLastError(ERROR_INVALID_ACL);
4606 return FALSE;
4609 piace = pace;
4610 DumpString(&openbr, 1, pwptr, plen);
4611 switch (piace->Header.AceType)
4613 case ACCESS_ALLOWED_ACE_TYPE:
4614 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4615 break;
4616 case ACCESS_DENIED_ACE_TYPE:
4617 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4618 break;
4619 case SYSTEM_AUDIT_ACE_TYPE:
4620 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4621 break;
4622 case SYSTEM_ALARM_ACE_TYPE:
4623 DumpString(SDDL_ALARM, -1, pwptr, plen);
4624 break;
4626 DumpString(&semicolon, 1, pwptr, plen);
4628 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4629 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4630 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4631 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4632 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4633 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4634 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4635 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4636 if (piace->Header.AceFlags & INHERITED_ACE)
4637 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4638 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4639 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4640 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4641 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4642 DumpString(&semicolon, 1, pwptr, plen);
4643 DumpRights(piace->Mask, pwptr, plen);
4644 DumpString(&semicolon, 1, pwptr, plen);
4645 /* objects not supported */
4646 DumpString(&semicolon, 1, pwptr, plen);
4647 /* objects not supported */
4648 DumpString(&semicolon, 1, pwptr, plen);
4649 if (!DumpSid(&piace->SidStart, pwptr, plen))
4650 return FALSE;
4651 DumpString(&closebr, 1, pwptr, plen);
4652 return TRUE;
4655 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4657 WORD count;
4658 int i;
4660 if (protected)
4661 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4662 if (autoInheritReq)
4663 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4664 if (autoInherited)
4665 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4667 if (pacl == NULL)
4668 return TRUE;
4670 if (!IsValidAcl(pacl))
4671 return FALSE;
4673 count = pacl->AceCount;
4674 for (i = 0; i < count; i++)
4676 LPVOID ace;
4677 if (!GetAce(pacl, i, &ace))
4678 return FALSE;
4679 if (!DumpAce(ace, pwptr, plen))
4680 return FALSE;
4683 return TRUE;
4686 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4688 static const WCHAR prefix[] = {'O',':',0};
4689 BOOL bDefaulted;
4690 PSID psid;
4692 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4693 return FALSE;
4695 if (psid == NULL)
4696 return TRUE;
4698 DumpString(prefix, -1, pwptr, plen);
4699 if (!DumpSid(psid, pwptr, plen))
4700 return FALSE;
4701 return TRUE;
4704 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4706 static const WCHAR prefix[] = {'G',':',0};
4707 BOOL bDefaulted;
4708 PSID psid;
4710 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4711 return FALSE;
4713 if (psid == NULL)
4714 return TRUE;
4716 DumpString(prefix, -1, pwptr, plen);
4717 if (!DumpSid(psid, pwptr, plen))
4718 return FALSE;
4719 return TRUE;
4722 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4724 static const WCHAR dacl[] = {'D',':',0};
4725 SECURITY_DESCRIPTOR_CONTROL control;
4726 BOOL present, defaulted;
4727 DWORD revision;
4728 PACL pacl;
4730 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4731 return FALSE;
4733 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4734 return FALSE;
4736 if (!present)
4737 return TRUE;
4739 DumpString(dacl, 2, pwptr, plen);
4740 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4741 return FALSE;
4742 return TRUE;
4745 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4747 static const WCHAR sacl[] = {'S',':',0};
4748 SECURITY_DESCRIPTOR_CONTROL control;
4749 BOOL present, defaulted;
4750 DWORD revision;
4751 PACL pacl;
4753 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4754 return FALSE;
4756 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4757 return FALSE;
4759 if (!present)
4760 return TRUE;
4762 DumpString(sacl, 2, pwptr, plen);
4763 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4764 return FALSE;
4765 return TRUE;
4768 /******************************************************************************
4769 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4771 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4773 ULONG len;
4774 WCHAR *wptr, *wstr;
4776 if (SDRevision != SDDL_REVISION_1)
4778 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4779 SetLastError(ERROR_UNKNOWN_REVISION);
4780 return FALSE;
4783 len = 0;
4784 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4785 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4786 return FALSE;
4787 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4788 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4789 return FALSE;
4790 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4791 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4792 return FALSE;
4793 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4794 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4795 return FALSE;
4797 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4798 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4799 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4800 return FALSE;
4801 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4802 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4803 return FALSE;
4804 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4805 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4806 return FALSE;
4807 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4808 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4809 return FALSE;
4810 *wptr = 0;
4812 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4813 *OutputString = wstr;
4814 if (OutputLen)
4815 *OutputLen = strlenW(*OutputString)+1;
4816 return TRUE;
4819 /******************************************************************************
4820 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4822 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4824 LPWSTR wstr;
4825 ULONG len;
4826 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4828 int lenA;
4830 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4831 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4832 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4833 LocalFree(wstr);
4835 if (OutputLen != NULL)
4836 *OutputLen = lenA;
4837 return TRUE;
4839 else
4841 *OutputString = NULL;
4842 if (OutputLen)
4843 *OutputLen = 0;
4844 return FALSE;
4848 /******************************************************************************
4849 * ConvertStringSidToSidW [ADVAPI32.@]
4851 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4853 BOOL bret = FALSE;
4854 DWORD cBytes;
4856 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4857 if (GetVersion() & 0x80000000)
4858 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4859 else if (!StringSid || !Sid)
4860 SetLastError(ERROR_INVALID_PARAMETER);
4861 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4863 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4865 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4866 if (!bret)
4867 LocalFree(*Sid);
4869 return bret;
4872 /******************************************************************************
4873 * ConvertStringSidToSidA [ADVAPI32.@]
4875 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4877 BOOL bret = FALSE;
4879 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4880 if (GetVersion() & 0x80000000)
4881 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4882 else if (!StringSid || !Sid)
4883 SetLastError(ERROR_INVALID_PARAMETER);
4884 else
4886 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4887 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4888 len * sizeof(WCHAR));
4890 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4891 bret = ConvertStringSidToSidW(wStringSid, Sid);
4892 HeapFree(GetProcessHeap(), 0, wStringSid);
4894 return bret;
4897 /******************************************************************************
4898 * ConvertSidToStringSidW [ADVAPI32.@]
4900 * format of SID string is:
4901 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4902 * where
4903 * <rev> is the revision of the SID encoded as decimal
4904 * <auth> is the identifier authority encoded as hex
4905 * <subauthN> is the subauthority id encoded as decimal
4907 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4909 DWORD len = 0;
4910 LPWSTR wstr, wptr;
4912 TRACE("%p %p\n", pSid, pstr );
4914 len = 0;
4915 if (!DumpSidNumeric(pSid, NULL, &len))
4916 return FALSE;
4917 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4918 DumpSidNumeric(pSid, &wptr, NULL);
4919 *wptr = 0;
4921 *pstr = wstr;
4922 return TRUE;
4925 /******************************************************************************
4926 * ConvertSidToStringSidA [ADVAPI32.@]
4928 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4930 LPWSTR wstr = NULL;
4931 LPSTR str;
4932 UINT len;
4934 TRACE("%p %p\n", pSid, pstr );
4936 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4937 return FALSE;
4939 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4940 str = LocalAlloc( 0, len );
4941 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4942 LocalFree( wstr );
4944 *pstr = str;
4946 return TRUE;
4949 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4950 PSECURITY_DESCRIPTOR pdesc,
4951 PSECURITY_DESCRIPTOR cdesc,
4952 PSECURITY_DESCRIPTOR* ndesc,
4953 GUID* objtype,
4954 BOOL isdir,
4955 PGENERIC_MAPPING genmap )
4957 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4959 return FALSE;
4962 BOOL WINAPI CreatePrivateObjectSecurity(
4963 PSECURITY_DESCRIPTOR ParentDescriptor,
4964 PSECURITY_DESCRIPTOR CreatorDescriptor,
4965 PSECURITY_DESCRIPTOR* NewDescriptor,
4966 BOOL IsDirectoryObject,
4967 HANDLE Token,
4968 PGENERIC_MAPPING GenericMapping )
4970 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4971 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4973 return FALSE;
4976 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4978 FIXME("%p - stub\n", ObjectDescriptor);
4980 return TRUE;
4983 BOOL WINAPI CreateProcessAsUserA(
4984 HANDLE hToken,
4985 LPCSTR lpApplicationName,
4986 LPSTR lpCommandLine,
4987 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4988 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4989 BOOL bInheritHandles,
4990 DWORD dwCreationFlags,
4991 LPVOID lpEnvironment,
4992 LPCSTR lpCurrentDirectory,
4993 LPSTARTUPINFOA lpStartupInfo,
4994 LPPROCESS_INFORMATION lpProcessInformation )
4996 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4997 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4998 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5000 return FALSE;
5003 BOOL WINAPI CreateProcessAsUserW(
5004 HANDLE hToken,
5005 LPCWSTR lpApplicationName,
5006 LPWSTR lpCommandLine,
5007 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5008 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5009 BOOL bInheritHandles,
5010 DWORD dwCreationFlags,
5011 LPVOID lpEnvironment,
5012 LPCWSTR lpCurrentDirectory,
5013 LPSTARTUPINFOW lpStartupInfo,
5014 LPPROCESS_INFORMATION lpProcessInformation )
5016 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5017 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5018 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5019 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5021 /* We should create the process with a suspended main thread */
5022 if (!CreateProcessW (lpApplicationName,
5023 lpCommandLine,
5024 lpProcessAttributes,
5025 lpThreadAttributes,
5026 bInheritHandles,
5027 dwCreationFlags, /* CREATE_SUSPENDED */
5028 lpEnvironment,
5029 lpCurrentDirectory,
5030 lpStartupInfo,
5031 lpProcessInformation))
5033 return FALSE;
5036 return TRUE;
5039 /******************************************************************************
5040 * CreateProcessWithLogonW
5042 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5043 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5044 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5046 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5047 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5048 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5049 lpStartupInfo, lpProcessInformation);
5051 return FALSE;
5054 /******************************************************************************
5055 * DuplicateTokenEx [ADVAPI32.@]
5057 BOOL WINAPI DuplicateTokenEx(
5058 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5059 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5060 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5061 TOKEN_TYPE TokenType,
5062 PHANDLE DuplicateTokenHandle )
5064 OBJECT_ATTRIBUTES ObjectAttributes;
5066 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5067 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5069 InitializeObjectAttributes(
5070 &ObjectAttributes,
5071 NULL,
5072 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5073 NULL,
5074 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5076 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5077 dwDesiredAccess,
5078 &ObjectAttributes,
5079 ImpersonationLevel,
5080 TokenType,
5081 DuplicateTokenHandle ) );
5084 BOOL WINAPI DuplicateToken(
5085 HANDLE ExistingTokenHandle,
5086 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5087 PHANDLE DuplicateTokenHandle )
5089 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5090 NULL, ImpersonationLevel, TokenImpersonation,
5091 DuplicateTokenHandle );
5094 /******************************************************************************
5095 * ComputeStringSidSize
5097 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5099 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5101 int ctok = 0;
5102 while (*StringSid)
5104 if (*StringSid == '-')
5105 ctok++;
5106 StringSid++;
5109 if (ctok >= 3)
5110 return GetSidLengthRequired(ctok - 2);
5112 else /* String constant format - Only available in winxp and above */
5114 unsigned int i;
5116 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5117 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5118 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5121 return GetSidLengthRequired(0);
5124 /******************************************************************************
5125 * ParseStringSidToSid
5127 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5129 BOOL bret = FALSE;
5130 SID* pisid=pSid;
5132 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5133 if (!StringSid)
5135 SetLastError(ERROR_INVALID_PARAMETER);
5136 TRACE("StringSid is NULL, returning FALSE\n");
5137 return FALSE;
5140 while (*StringSid == ' ')
5141 StringSid++;
5143 *cBytes = ComputeStringSidSize(StringSid);
5144 if (!pisid) /* Simply compute the size */
5146 TRACE("only size requested, returning TRUE\n");
5147 return TRUE;
5150 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5152 DWORD i = 0, identAuth;
5153 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5155 StringSid += 2; /* Advance to Revision */
5156 pisid->Revision = atoiW(StringSid);
5158 if (pisid->Revision != SDDL_REVISION)
5160 TRACE("Revision %d is unknown\n", pisid->Revision);
5161 goto lend; /* ERROR_INVALID_SID */
5163 if (csubauth == 0)
5165 TRACE("SubAuthorityCount is 0\n");
5166 goto lend; /* ERROR_INVALID_SID */
5169 pisid->SubAuthorityCount = csubauth;
5171 /* Advance to identifier authority */
5172 while (*StringSid && *StringSid != '-')
5173 StringSid++;
5174 if (*StringSid == '-')
5175 StringSid++;
5177 /* MS' implementation can't handle values greater than 2^32 - 1, so
5178 * we don't either; assume most significant bytes are always 0
5180 pisid->IdentifierAuthority.Value[0] = 0;
5181 pisid->IdentifierAuthority.Value[1] = 0;
5182 identAuth = atoiW(StringSid);
5183 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5184 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5185 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5186 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5188 /* Advance to first sub authority */
5189 while (*StringSid && *StringSid != '-')
5190 StringSid++;
5191 if (*StringSid == '-')
5192 StringSid++;
5194 while (*StringSid)
5196 pisid->SubAuthority[i++] = atoiW(StringSid);
5198 while (*StringSid && *StringSid != '-')
5199 StringSid++;
5200 if (*StringSid == '-')
5201 StringSid++;
5204 if (i != pisid->SubAuthorityCount)
5205 goto lend; /* ERROR_INVALID_SID */
5207 bret = TRUE;
5209 else /* String constant format - Only available in winxp and above */
5211 unsigned int i;
5212 pisid->Revision = SDDL_REVISION;
5214 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5215 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5217 DWORD j;
5218 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5219 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5220 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5221 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5222 bret = TRUE;
5225 if (!bret)
5226 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5229 lend:
5230 if (!bret)
5231 SetLastError(ERROR_INVALID_SID);
5233 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5234 return bret;
5237 /******************************************************************************
5238 * GetNamedSecurityInfoA [ADVAPI32.@]
5240 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5241 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5242 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5243 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5245 DWORD len;
5246 LPWSTR wstr = NULL;
5247 DWORD r;
5249 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5250 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5252 if( pObjectName )
5254 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5255 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5256 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5259 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5260 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5262 HeapFree( GetProcessHeap(), 0, wstr );
5264 return r;
5267 /******************************************************************************
5268 * GetNamedSecurityInfoW [ADVAPI32.@]
5270 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5271 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5272 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5274 DWORD needed, offset;
5275 SECURITY_DESCRIPTOR_RELATIVE *relative;
5276 BYTE *buffer;
5278 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5279 group, dacl, sacl, descriptor );
5281 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5283 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5284 if (info & OWNER_SECURITY_INFORMATION)
5285 needed += sizeof(sidWorld);
5286 if (info & GROUP_SECURITY_INFORMATION)
5287 needed += sizeof(sidWorld);
5288 if (info & DACL_SECURITY_INFORMATION)
5289 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5290 if (info & SACL_SECURITY_INFORMATION)
5291 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5293 /* must be freed by caller */
5294 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5295 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5297 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5299 HeapFree( GetProcessHeap(), 0, *descriptor );
5300 return ERROR_INVALID_SECURITY_DESCR;
5303 relative = *descriptor;
5304 relative->Control |= SE_SELF_RELATIVE;
5305 buffer = (BYTE *)relative;
5306 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5308 if (info & OWNER_SECURITY_INFORMATION)
5310 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5311 relative->Owner = offset;
5312 if (owner)
5313 *owner = buffer + offset;
5314 offset += sizeof(sidWorld);
5316 if (info & GROUP_SECURITY_INFORMATION)
5318 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5319 relative->Group = offset;
5320 if (group)
5321 *group = buffer + offset;
5322 offset += sizeof(sidWorld);
5324 if (info & DACL_SECURITY_INFORMATION)
5326 relative->Control |= SE_DACL_PRESENT;
5327 GetWorldAccessACL( (PACL)(buffer + offset) );
5328 relative->Dacl = offset;
5329 if (dacl)
5330 *dacl = (PACL)(buffer + offset);
5331 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5333 if (info & SACL_SECURITY_INFORMATION)
5335 relative->Control |= SE_SACL_PRESENT;
5336 GetWorldAccessACL( (PACL)(buffer + offset) );
5337 relative->Sacl = offset;
5338 if (sacl)
5339 *sacl = (PACL)(buffer + offset);
5341 return ERROR_SUCCESS;
5344 /******************************************************************************
5345 * DecryptFileW [ADVAPI32.@]
5347 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5349 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5350 return TRUE;
5353 /******************************************************************************
5354 * DecryptFileA [ADVAPI32.@]
5356 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5358 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5359 return TRUE;
5362 /******************************************************************************
5363 * EncryptFileW [ADVAPI32.@]
5365 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5367 FIXME("%s\n", debugstr_w(lpFileName));
5368 return TRUE;
5371 /******************************************************************************
5372 * EncryptFileA [ADVAPI32.@]
5374 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5376 FIXME("%s\n", debugstr_a(lpFileName));
5377 return TRUE;
5380 /******************************************************************************
5381 * FileEncryptionStatusW [ADVAPI32.@]
5383 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5385 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5386 if (!lpStatus)
5387 return FALSE;
5388 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5389 return TRUE;
5392 /******************************************************************************
5393 * FileEncryptionStatusA [ADVAPI32.@]
5395 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5397 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5398 if (!lpStatus)
5399 return FALSE;
5400 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5401 return TRUE;
5404 /******************************************************************************
5405 * SetSecurityInfo [ADVAPI32.@]
5407 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5408 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5409 PSID psidGroup, PACL pDacl, PACL pSacl) {
5410 FIXME("stub\n");
5411 return ERROR_SUCCESS;
5414 /******************************************************************************
5415 * SaferCreateLevel [ADVAPI32.@]
5417 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5418 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5420 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5421 return FALSE;
5424 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5425 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5426 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5427 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5428 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5430 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5431 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5432 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5434 return ERROR_SUCCESS;
5437 /******************************************************************************
5438 * SaferGetPolicyInformation [ADVAPI32.@]
5440 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5441 PVOID buffer, PDWORD required, LPVOID lpReserved)
5443 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5444 return FALSE;