push 5bc4839baba05cc4333240c25295b8dd6e351557
[wine/hacks.git] / dlls / advapi32 / security.c
blob7dd39a4a75d8902d01fc6d81604fe65c42145fd2
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 return RtlEqualSid( pSid1, pSid2 );
1061 /******************************************************************************
1062 * EqualPrefixSid [ADVAPI32.@]
1064 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1066 return RtlEqualPrefixSid(pSid1, pSid2);
1069 /******************************************************************************
1070 * GetSidLengthRequired [ADVAPI32.@]
1072 * PARAMS
1073 * nSubAuthorityCount []
1075 DWORD WINAPI
1076 GetSidLengthRequired( BYTE nSubAuthorityCount )
1078 return RtlLengthRequiredSid(nSubAuthorityCount);
1081 /******************************************************************************
1082 * InitializeSid [ADVAPI32.@]
1084 * PARAMS
1085 * pIdentifierAuthority []
1087 BOOL WINAPI
1088 InitializeSid (
1089 PSID pSid,
1090 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1091 BYTE nSubAuthorityCount)
1093 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1096 DWORD WINAPI
1097 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1099 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1101 return 1;
1104 DWORD WINAPI
1105 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1107 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1109 return 1;
1112 /******************************************************************************
1113 * GetSidIdentifierAuthority [ADVAPI32.@]
1115 * PARAMS
1116 * pSid []
1118 PSID_IDENTIFIER_AUTHORITY WINAPI
1119 GetSidIdentifierAuthority( PSID pSid )
1121 return RtlIdentifierAuthoritySid(pSid);
1124 /******************************************************************************
1125 * GetSidSubAuthority [ADVAPI32.@]
1127 * PARAMS
1128 * pSid []
1129 * nSubAuthority []
1131 PDWORD WINAPI
1132 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1134 SetLastError(ERROR_SUCCESS);
1135 return RtlSubAuthoritySid(pSid, nSubAuthority);
1138 /******************************************************************************
1139 * GetSidSubAuthorityCount [ADVAPI32.@]
1141 * PARAMS
1142 * pSid []
1144 PUCHAR WINAPI
1145 GetSidSubAuthorityCount (PSID pSid)
1147 SetLastError(ERROR_SUCCESS);
1148 return RtlSubAuthorityCountSid(pSid);
1151 /******************************************************************************
1152 * GetLengthSid [ADVAPI32.@]
1154 * PARAMS
1155 * pSid []
1157 DWORD WINAPI
1158 GetLengthSid (PSID pSid)
1160 return RtlLengthSid(pSid);
1163 /* ##############################################
1164 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1165 ##############################################
1168 /******************************************************************************
1169 * BuildSecurityDescriptorA [ADVAPI32.@]
1171 * Builds a SD from
1173 * PARAMS
1174 * pOwner [I]
1175 * pGroup [I]
1176 * cCountOfAccessEntries [I]
1177 * pListOfAccessEntries [I]
1178 * cCountOfAuditEntries [I]
1179 * pListofAuditEntries [I]
1180 * pOldSD [I]
1181 * lpdwBufferLength [I/O]
1182 * pNewSD [O]
1184 * RETURNS
1185 * Success: ERROR_SUCCESS
1186 * Failure: nonzero error code from Winerror.h
1188 DWORD WINAPI BuildSecurityDescriptorA(
1189 IN PTRUSTEEA pOwner,
1190 IN PTRUSTEEA pGroup,
1191 IN ULONG cCountOfAccessEntries,
1192 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1193 IN ULONG cCountOfAuditEntries,
1194 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1195 IN PSECURITY_DESCRIPTOR pOldSD,
1196 IN OUT PULONG lpdwBufferLength,
1197 OUT PSECURITY_DESCRIPTOR* pNewSD)
1199 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1200 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1201 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1203 return ERROR_CALL_NOT_IMPLEMENTED;
1206 /******************************************************************************
1207 * BuildSecurityDescriptorW [ADVAPI32.@]
1209 * See BuildSecurityDescriptorA.
1211 DWORD WINAPI BuildSecurityDescriptorW(
1212 IN PTRUSTEEW pOwner,
1213 IN PTRUSTEEW pGroup,
1214 IN ULONG cCountOfAccessEntries,
1215 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1216 IN ULONG cCountOfAuditEntries,
1217 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1218 IN PSECURITY_DESCRIPTOR pOldSD,
1219 IN OUT PULONG lpdwBufferLength,
1220 OUT PSECURITY_DESCRIPTOR* pNewSD)
1222 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1223 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1224 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1226 return ERROR_CALL_NOT_IMPLEMENTED;
1229 /******************************************************************************
1230 * InitializeSecurityDescriptor [ADVAPI32.@]
1232 * PARAMS
1233 * pDescr []
1234 * revision []
1236 BOOL WINAPI
1237 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1239 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1243 /******************************************************************************
1244 * MakeAbsoluteSD [ADVAPI32.@]
1246 BOOL WINAPI MakeAbsoluteSD (
1247 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1248 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1249 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1250 OUT PACL pDacl,
1251 OUT LPDWORD lpdwDaclSize,
1252 OUT PACL pSacl,
1253 OUT LPDWORD lpdwSaclSize,
1254 OUT PSID pOwner,
1255 OUT LPDWORD lpdwOwnerSize,
1256 OUT PSID pPrimaryGroup,
1257 OUT LPDWORD lpdwPrimaryGroupSize)
1259 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1260 pAbsoluteSecurityDescriptor,
1261 lpdwAbsoluteSecurityDescriptorSize,
1262 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1263 pOwner, lpdwOwnerSize,
1264 pPrimaryGroup, lpdwPrimaryGroupSize));
1267 /******************************************************************************
1268 * GetKernelObjectSecurity [ADVAPI32.@]
1270 BOOL WINAPI GetKernelObjectSecurity(
1271 HANDLE Handle,
1272 SECURITY_INFORMATION RequestedInformation,
1273 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1274 DWORD nLength,
1275 LPDWORD lpnLengthNeeded )
1277 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1278 pSecurityDescriptor, nLength, lpnLengthNeeded);
1280 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1281 nLength, lpnLengthNeeded ));
1284 /******************************************************************************
1285 * GetPrivateObjectSecurity [ADVAPI32.@]
1287 BOOL WINAPI GetPrivateObjectSecurity(
1288 PSECURITY_DESCRIPTOR ObjectDescriptor,
1289 SECURITY_INFORMATION SecurityInformation,
1290 PSECURITY_DESCRIPTOR ResultantDescriptor,
1291 DWORD DescriptorLength,
1292 PDWORD ReturnLength )
1294 SECURITY_DESCRIPTOR desc;
1295 BOOL defaulted, present;
1296 PACL pacl;
1297 PSID psid;
1299 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1300 ResultantDescriptor, DescriptorLength, ReturnLength);
1302 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1303 return FALSE;
1305 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1307 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1308 return FALSE;
1309 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1312 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1314 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1315 return FALSE;
1316 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1319 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1321 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1322 return FALSE;
1323 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1326 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1328 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1329 return FALSE;
1330 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1333 *ReturnLength = DescriptorLength;
1334 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1337 /******************************************************************************
1338 * GetSecurityDescriptorLength [ADVAPI32.@]
1340 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1342 return RtlLengthSecurityDescriptor(pDescr);
1345 /******************************************************************************
1346 * GetSecurityDescriptorOwner [ADVAPI32.@]
1348 * PARAMS
1349 * pOwner []
1350 * lpbOwnerDefaulted []
1352 BOOL WINAPI
1353 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1354 LPBOOL lpbOwnerDefaulted )
1356 BOOLEAN defaulted;
1357 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1358 *lpbOwnerDefaulted = defaulted;
1359 return ret;
1362 /******************************************************************************
1363 * SetSecurityDescriptorOwner [ADVAPI32.@]
1365 * PARAMS
1367 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1368 PSID pOwner, BOOL bOwnerDefaulted)
1370 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1372 /******************************************************************************
1373 * GetSecurityDescriptorGroup [ADVAPI32.@]
1375 BOOL WINAPI GetSecurityDescriptorGroup(
1376 PSECURITY_DESCRIPTOR SecurityDescriptor,
1377 PSID *Group,
1378 LPBOOL GroupDefaulted)
1380 BOOLEAN defaulted;
1381 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1382 *GroupDefaulted = defaulted;
1383 return ret;
1385 /******************************************************************************
1386 * SetSecurityDescriptorGroup [ADVAPI32.@]
1388 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1389 PSID Group, BOOL GroupDefaulted)
1391 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1394 /******************************************************************************
1395 * IsValidSecurityDescriptor [ADVAPI32.@]
1397 * PARAMS
1398 * lpsecdesc []
1400 BOOL WINAPI
1401 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1403 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1406 /******************************************************************************
1407 * GetSecurityDescriptorDacl [ADVAPI32.@]
1409 BOOL WINAPI GetSecurityDescriptorDacl(
1410 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 OUT LPBOOL lpbDaclPresent,
1412 OUT PACL *pDacl,
1413 OUT LPBOOL lpbDaclDefaulted)
1415 BOOLEAN present, defaulted;
1416 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1417 *lpbDaclPresent = present;
1418 *lpbDaclDefaulted = defaulted;
1419 return ret;
1422 /******************************************************************************
1423 * SetSecurityDescriptorDacl [ADVAPI32.@]
1425 BOOL WINAPI
1426 SetSecurityDescriptorDacl (
1427 PSECURITY_DESCRIPTOR lpsd,
1428 BOOL daclpresent,
1429 PACL dacl,
1430 BOOL dacldefaulted )
1432 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1434 /******************************************************************************
1435 * GetSecurityDescriptorSacl [ADVAPI32.@]
1437 BOOL WINAPI GetSecurityDescriptorSacl(
1438 IN PSECURITY_DESCRIPTOR lpsd,
1439 OUT LPBOOL lpbSaclPresent,
1440 OUT PACL *pSacl,
1441 OUT LPBOOL lpbSaclDefaulted)
1443 BOOLEAN present, defaulted;
1444 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1445 *lpbSaclPresent = present;
1446 *lpbSaclDefaulted = defaulted;
1447 return ret;
1450 /**************************************************************************
1451 * SetSecurityDescriptorSacl [ADVAPI32.@]
1453 BOOL WINAPI SetSecurityDescriptorSacl (
1454 PSECURITY_DESCRIPTOR lpsd,
1455 BOOL saclpresent,
1456 PACL lpsacl,
1457 BOOL sacldefaulted)
1459 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1461 /******************************************************************************
1462 * MakeSelfRelativeSD [ADVAPI32.@]
1464 * PARAMS
1465 * lpabssecdesc []
1466 * lpselfsecdesc []
1467 * lpbuflen []
1469 BOOL WINAPI
1470 MakeSelfRelativeSD(
1471 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1472 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1473 IN OUT LPDWORD lpdwBufferLength)
1475 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1476 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1479 /******************************************************************************
1480 * GetSecurityDescriptorControl [ADVAPI32.@]
1483 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1484 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1486 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1489 /******************************************************************************
1490 * SetSecurityDescriptorControl [ADVAPI32.@]
1492 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1493 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1494 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1496 return set_ntstatus( RtlSetControlSecurityDescriptor(
1497 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1500 /* ##############################
1501 ###### ACL FUNCTIONS ######
1502 ##############################
1505 /*************************************************************************
1506 * InitializeAcl [ADVAPI32.@]
1508 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1510 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1513 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1515 IO_STATUS_BLOCK io_block;
1517 TRACE("(%p)\n", hNamedPipe);
1519 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1520 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1523 /******************************************************************************
1524 * AddAccessAllowedAce [ADVAPI32.@]
1526 BOOL WINAPI AddAccessAllowedAce(
1527 IN OUT PACL pAcl,
1528 IN DWORD dwAceRevision,
1529 IN DWORD AccessMask,
1530 IN PSID pSid)
1532 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1535 /******************************************************************************
1536 * AddAccessAllowedAceEx [ADVAPI32.@]
1538 BOOL WINAPI AddAccessAllowedAceEx(
1539 IN OUT PACL pAcl,
1540 IN DWORD dwAceRevision,
1541 IN DWORD AceFlags,
1542 IN DWORD AccessMask,
1543 IN PSID pSid)
1545 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1548 /******************************************************************************
1549 * AddAccessDeniedAce [ADVAPI32.@]
1551 BOOL WINAPI AddAccessDeniedAce(
1552 IN OUT PACL pAcl,
1553 IN DWORD dwAceRevision,
1554 IN DWORD AccessMask,
1555 IN PSID pSid)
1557 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1560 /******************************************************************************
1561 * AddAccessDeniedAceEx [ADVAPI32.@]
1563 BOOL WINAPI AddAccessDeniedAceEx(
1564 IN OUT PACL pAcl,
1565 IN DWORD dwAceRevision,
1566 IN DWORD AceFlags,
1567 IN DWORD AccessMask,
1568 IN PSID pSid)
1570 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1573 /******************************************************************************
1574 * AddAce [ADVAPI32.@]
1576 BOOL WINAPI AddAce(
1577 IN OUT PACL pAcl,
1578 IN DWORD dwAceRevision,
1579 IN DWORD dwStartingAceIndex,
1580 LPVOID pAceList,
1581 DWORD nAceListLength)
1583 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1586 /******************************************************************************
1587 * DeleteAce [ADVAPI32.@]
1589 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1591 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1594 /******************************************************************************
1595 * FindFirstFreeAce [ADVAPI32.@]
1597 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1599 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1602 /******************************************************************************
1603 * GetAce [ADVAPI32.@]
1605 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1607 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1610 /******************************************************************************
1611 * GetAclInformation [ADVAPI32.@]
1613 BOOL WINAPI GetAclInformation(
1614 PACL pAcl,
1615 LPVOID pAclInformation,
1616 DWORD nAclInformationLength,
1617 ACL_INFORMATION_CLASS dwAclInformationClass)
1619 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1620 nAclInformationLength, dwAclInformationClass));
1623 /******************************************************************************
1624 * IsValidAcl [ADVAPI32.@]
1626 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1628 return RtlValidAcl(pAcl);
1631 /* ##############################
1632 ###### MISC FUNCTIONS ######
1633 ##############################
1636 /******************************************************************************
1637 * AllocateLocallyUniqueId [ADVAPI32.@]
1639 * PARAMS
1640 * lpLuid []
1642 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1644 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1647 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1648 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1649 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1650 { '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 };
1651 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1652 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1653 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1654 { '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 };
1655 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1656 { '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 };
1657 static const WCHAR SE_TCB_NAME_W[] =
1658 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1659 static const WCHAR SE_SECURITY_NAME_W[] =
1660 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1661 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1662 { '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 };
1663 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1664 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1665 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1666 { '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 };
1667 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1668 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1669 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1670 { '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 };
1671 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1672 { '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 };
1673 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1674 { '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 };
1675 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1676 { '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 };
1677 static const WCHAR SE_BACKUP_NAME_W[] =
1678 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1679 static const WCHAR SE_RESTORE_NAME_W[] =
1680 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1681 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1682 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1683 static const WCHAR SE_DEBUG_NAME_W[] =
1684 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1685 static const WCHAR SE_AUDIT_NAME_W[] =
1686 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1687 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1688 { '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 };
1689 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1690 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1691 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1692 { '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 };
1693 static const WCHAR SE_UNDOCK_NAME_W[] =
1694 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1695 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1696 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1697 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1698 { '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 };
1699 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1700 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1701 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1702 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1703 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1704 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1706 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1708 NULL,
1709 NULL,
1710 SE_CREATE_TOKEN_NAME_W,
1711 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1712 SE_LOCK_MEMORY_NAME_W,
1713 SE_INCREASE_QUOTA_NAME_W,
1714 SE_MACHINE_ACCOUNT_NAME_W,
1715 SE_TCB_NAME_W,
1716 SE_SECURITY_NAME_W,
1717 SE_TAKE_OWNERSHIP_NAME_W,
1718 SE_LOAD_DRIVER_NAME_W,
1719 SE_SYSTEM_PROFILE_NAME_W,
1720 SE_SYSTEMTIME_NAME_W,
1721 SE_PROF_SINGLE_PROCESS_NAME_W,
1722 SE_INC_BASE_PRIORITY_NAME_W,
1723 SE_CREATE_PAGEFILE_NAME_W,
1724 SE_CREATE_PERMANENT_NAME_W,
1725 SE_BACKUP_NAME_W,
1726 SE_RESTORE_NAME_W,
1727 SE_SHUTDOWN_NAME_W,
1728 SE_DEBUG_NAME_W,
1729 SE_AUDIT_NAME_W,
1730 SE_SYSTEM_ENVIRONMENT_NAME_W,
1731 SE_CHANGE_NOTIFY_NAME_W,
1732 SE_REMOTE_SHUTDOWN_NAME_W,
1733 SE_UNDOCK_NAME_W,
1734 SE_SYNC_AGENT_NAME_W,
1735 SE_ENABLE_DELEGATION_NAME_W,
1736 SE_MANAGE_VOLUME_NAME_W,
1737 SE_IMPERSONATE_NAME_W,
1738 SE_CREATE_GLOBAL_NAME_W,
1741 /******************************************************************************
1742 * LookupPrivilegeValueW [ADVAPI32.@]
1744 * See LookupPrivilegeValueA.
1746 BOOL WINAPI
1747 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1749 UINT i;
1751 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1753 if (!ADVAPI_IsLocalComputer(lpSystemName))
1755 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1756 return FALSE;
1758 if (!lpName)
1760 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1761 return FALSE;
1763 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1765 if( !WellKnownPrivNames[i] )
1766 continue;
1767 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1768 continue;
1769 lpLuid->LowPart = i;
1770 lpLuid->HighPart = 0;
1771 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1772 lpLuid->HighPart, lpLuid->LowPart );
1773 return TRUE;
1775 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1776 return FALSE;
1779 /******************************************************************************
1780 * LookupPrivilegeValueA [ADVAPI32.@]
1782 * Retrieves LUID used on a system to represent the privilege name.
1784 * PARAMS
1785 * lpSystemName [I] Name of the system
1786 * lpName [I] Name of the privilege
1787 * lpLuid [O] Destination for the resulting LUID
1789 * RETURNS
1790 * Success: TRUE. lpLuid contains the requested LUID.
1791 * Failure: FALSE.
1793 BOOL WINAPI
1794 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1796 UNICODE_STRING lpSystemNameW;
1797 UNICODE_STRING lpNameW;
1798 BOOL ret;
1800 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1801 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1802 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1803 RtlFreeUnicodeString(&lpNameW);
1804 RtlFreeUnicodeString(&lpSystemNameW);
1805 return ret;
1808 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1809 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1811 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1812 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1814 return FALSE;
1817 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1818 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1820 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1821 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1823 return FALSE;
1826 /******************************************************************************
1827 * LookupPrivilegeNameA [ADVAPI32.@]
1829 * See LookupPrivilegeNameW.
1831 BOOL WINAPI
1832 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1833 LPDWORD cchName)
1835 UNICODE_STRING lpSystemNameW;
1836 BOOL ret;
1837 DWORD wLen = 0;
1839 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1841 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1842 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1843 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1845 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1847 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1848 &wLen);
1849 if (ret)
1851 /* Windows crashes if cchName is NULL, so will I */
1852 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1853 *cchName, NULL, NULL);
1855 if (len == 0)
1857 /* WideCharToMultiByte failed */
1858 ret = FALSE;
1860 else if (len > *cchName)
1862 *cchName = len;
1863 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1864 ret = FALSE;
1866 else
1868 /* WideCharToMultiByte succeeded, output length needs to be
1869 * length not including NULL terminator
1871 *cchName = len - 1;
1874 HeapFree(GetProcessHeap(), 0, lpNameW);
1876 RtlFreeUnicodeString(&lpSystemNameW);
1877 return ret;
1880 /******************************************************************************
1881 * LookupPrivilegeNameW [ADVAPI32.@]
1883 * Retrieves the privilege name referred to by the LUID lpLuid.
1885 * PARAMS
1886 * lpSystemName [I] Name of the system
1887 * lpLuid [I] Privilege value
1888 * lpName [O] Name of the privilege
1889 * cchName [I/O] Number of characters in lpName.
1891 * RETURNS
1892 * Success: TRUE. lpName contains the name of the privilege whose value is
1893 * *lpLuid.
1894 * Failure: FALSE.
1896 * REMARKS
1897 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1898 * using this function.
1899 * If the length of lpName is too small, on return *cchName will contain the
1900 * number of WCHARs needed to contain the privilege, including the NULL
1901 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1902 * On success, *cchName will contain the number of characters stored in
1903 * lpName, NOT including the NULL terminator.
1905 BOOL WINAPI
1906 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1907 LPDWORD cchName)
1909 size_t privNameLen;
1911 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1913 if (!ADVAPI_IsLocalComputer(lpSystemName))
1915 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1916 return FALSE;
1918 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1919 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1921 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1922 return FALSE;
1924 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1925 /* Windows crashes if cchName is NULL, so will I */
1926 if (*cchName <= privNameLen)
1928 *cchName = privNameLen + 1;
1929 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1930 return FALSE;
1932 else
1934 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1935 *cchName = privNameLen;
1936 return TRUE;
1940 /******************************************************************************
1941 * GetFileSecurityA [ADVAPI32.@]
1943 * Obtains Specified information about the security of a file or directory.
1945 * PARAMS
1946 * lpFileName [I] Name of the file to get info for
1947 * RequestedInformation [I] SE_ flags from "winnt.h"
1948 * pSecurityDescriptor [O] Destination for security information
1949 * nLength [I] Length of pSecurityDescriptor
1950 * lpnLengthNeeded [O] Destination for length of returned security information
1952 * RETURNS
1953 * Success: TRUE. pSecurityDescriptor contains the requested information.
1954 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1956 * NOTES
1957 * The information returned is constrained by the callers access rights and
1958 * privileges.
1960 BOOL WINAPI
1961 GetFileSecurityA( LPCSTR lpFileName,
1962 SECURITY_INFORMATION RequestedInformation,
1963 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1964 DWORD nLength, LPDWORD lpnLengthNeeded )
1966 DWORD len;
1967 BOOL r;
1968 LPWSTR name = NULL;
1970 if( lpFileName )
1972 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1973 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1974 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1977 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1978 nLength, lpnLengthNeeded );
1979 HeapFree( GetProcessHeap(), 0, name );
1981 return r;
1984 /******************************************************************************
1985 * GetFileSecurityW [ADVAPI32.@]
1987 * See GetFileSecurityA.
1989 BOOL WINAPI
1990 GetFileSecurityW( LPCWSTR lpFileName,
1991 SECURITY_INFORMATION RequestedInformation,
1992 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1993 DWORD nLength, LPDWORD lpnLengthNeeded )
1995 HANDLE hfile;
1996 NTSTATUS status;
1997 DWORD access = 0;
1999 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2000 RequestedInformation, pSecurityDescriptor,
2001 nLength, lpnLengthNeeded);
2003 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2004 DACL_SECURITY_INFORMATION))
2005 access |= READ_CONTROL;
2006 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2007 access |= ACCESS_SYSTEM_SECURITY;
2009 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2010 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2011 if ( hfile == INVALID_HANDLE_VALUE )
2012 return FALSE;
2014 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2015 nLength, lpnLengthNeeded );
2016 CloseHandle( hfile );
2017 return set_ntstatus( status );
2021 /******************************************************************************
2022 * LookupAccountSidA [ADVAPI32.@]
2024 BOOL WINAPI
2025 LookupAccountSidA(
2026 IN LPCSTR system,
2027 IN PSID sid,
2028 OUT LPSTR account,
2029 IN OUT LPDWORD accountSize,
2030 OUT LPSTR domain,
2031 IN OUT LPDWORD domainSize,
2032 OUT PSID_NAME_USE name_use )
2034 DWORD len;
2035 BOOL r;
2036 LPWSTR systemW = NULL;
2037 LPWSTR accountW = NULL;
2038 LPWSTR domainW = NULL;
2039 DWORD accountSizeW = *accountSize;
2040 DWORD domainSizeW = *domainSize;
2042 if (system) {
2043 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2044 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2045 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2047 if (account)
2048 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2049 if (domain)
2050 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2052 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2054 if (r) {
2055 if (accountW && *accountSize) {
2056 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2057 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2058 *accountSize = len;
2059 } else
2060 *accountSize = accountSizeW + 1;
2062 if (domainW && *domainSize) {
2063 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2064 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2065 *domainSize = len;
2066 } else
2067 *domainSize = domainSizeW + 1;
2070 HeapFree( GetProcessHeap(), 0, systemW );
2071 HeapFree( GetProcessHeap(), 0, accountW );
2072 HeapFree( GetProcessHeap(), 0, domainW );
2074 return r;
2077 /******************************************************************************
2078 * LookupAccountSidW [ADVAPI32.@]
2080 * PARAMS
2081 * system []
2082 * sid []
2083 * account []
2084 * accountSize []
2085 * domain []
2086 * domainSize []
2087 * name_use []
2090 BOOL WINAPI
2091 LookupAccountSidW(
2092 IN LPCWSTR system,
2093 IN PSID sid,
2094 OUT LPWSTR account,
2095 IN OUT LPDWORD accountSize,
2096 OUT LPWSTR domain,
2097 IN OUT LPDWORD domainSize,
2098 OUT PSID_NAME_USE name_use )
2100 unsigned int i, j;
2101 const WCHAR * ac = NULL;
2102 const WCHAR * dm = NULL;
2103 SID_NAME_USE use = 0;
2104 LPWSTR computer_name = NULL;
2105 LPWSTR account_name = NULL;
2107 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2108 debugstr_w(system),debugstr_sid(sid),
2109 account,accountSize,accountSize?*accountSize:0,
2110 domain,domainSize,domainSize?*domainSize:0,
2111 name_use);
2113 if (!ADVAPI_IsLocalComputer(system)) {
2114 FIXME("Only local computer supported!\n");
2115 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2116 return FALSE;
2119 /* check the well known SIDs first */
2120 for (i = 0; i <= 60; i++) {
2121 if (IsWellKnownSid(sid, i)) {
2122 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2123 if (ACCOUNT_SIDS[j].type == i) {
2124 ac = ACCOUNT_SIDS[j].account;
2125 dm = ACCOUNT_SIDS[j].domain;
2126 use = ACCOUNT_SIDS[j].name_use;
2129 break;
2133 if (dm == NULL) {
2134 MAX_SID local;
2136 /* check for the local computer next */
2137 if (ADVAPI_GetComputerSid(&local)) {
2138 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2139 BOOL result;
2141 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2142 result = GetComputerNameW(computer_name, &size);
2144 if (result) {
2145 if (EqualSid(sid, &local)) {
2146 dm = computer_name;
2147 ac = Blank;
2148 use = 3;
2149 } else {
2150 local.SubAuthorityCount++;
2152 if (EqualPrefixSid(sid, &local)) {
2153 dm = computer_name;
2154 use = 1;
2155 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2156 case DOMAIN_USER_RID_ADMIN:
2157 ac = Administrator;
2158 break;
2159 case DOMAIN_USER_RID_GUEST:
2160 ac = Guest;
2161 break;
2162 case DOMAIN_GROUP_RID_ADMINS:
2163 ac = Domain_Admins;
2164 break;
2165 case DOMAIN_GROUP_RID_USERS:
2166 ac = Domain_Users;
2167 break;
2168 case DOMAIN_GROUP_RID_GUESTS:
2169 ac = Domain_Guests;
2170 break;
2171 case DOMAIN_GROUP_RID_COMPUTERS:
2172 ac = Domain_Computers;
2173 break;
2174 case DOMAIN_GROUP_RID_CONTROLLERS:
2175 ac = Domain_Controllers;
2176 break;
2177 case DOMAIN_GROUP_RID_CERT_ADMINS:
2178 ac = Cert_Publishers;
2179 break;
2180 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2181 ac = Schema_Admins;
2182 break;
2183 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2184 ac = Enterprise_Admins;
2185 break;
2186 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2187 ac = Group_Policy_Creator_Owners;
2188 break;
2189 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2190 ac = RAS_and_IAS_Servers;
2191 break;
2192 case 1000: /* first user account */
2193 size = UNLEN + 1;
2194 account_name = HeapAlloc(
2195 GetProcessHeap(), 0, size * sizeof(WCHAR));
2196 if (GetUserNameW(account_name, &size))
2197 ac = account_name;
2198 else
2199 dm = NULL;
2201 break;
2202 default:
2203 dm = NULL;
2204 break;
2212 if (dm) {
2213 DWORD ac_len = lstrlenW(ac);
2214 DWORD dm_len = lstrlenW(dm);
2215 BOOL status = TRUE;
2217 if (*accountSize > ac_len) {
2218 if (account)
2219 lstrcpyW(account, ac);
2221 if (*domainSize > dm_len) {
2222 if (domain)
2223 lstrcpyW(domain, dm);
2225 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2226 ((*domainSize != 0) && (*domainSize < dm_len))) {
2227 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2228 status = FALSE;
2230 if (*domainSize)
2231 *domainSize = dm_len;
2232 else
2233 *domainSize = dm_len + 1;
2234 if (*accountSize)
2235 *accountSize = ac_len;
2236 else
2237 *accountSize = ac_len + 1;
2238 *name_use = use;
2239 HeapFree(GetProcessHeap(), 0, account_name);
2240 HeapFree(GetProcessHeap(), 0, computer_name);
2241 return status;
2244 HeapFree(GetProcessHeap(), 0, account_name);
2245 HeapFree(GetProcessHeap(), 0, computer_name);
2246 SetLastError(ERROR_NONE_MAPPED);
2247 return FALSE;
2250 /******************************************************************************
2251 * SetFileSecurityA [ADVAPI32.@]
2253 * See SetFileSecurityW.
2255 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2256 SECURITY_INFORMATION RequestedInformation,
2257 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2259 DWORD len;
2260 BOOL r;
2261 LPWSTR name = NULL;
2263 if( lpFileName )
2265 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2266 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2267 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2270 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2271 HeapFree( GetProcessHeap(), 0, name );
2273 return r;
2276 /******************************************************************************
2277 * SetFileSecurityW [ADVAPI32.@]
2279 * Sets the security of a file or directory.
2281 * PARAMS
2282 * lpFileName []
2283 * RequestedInformation []
2284 * pSecurityDescriptor []
2286 * RETURNS
2287 * Success: TRUE.
2288 * Failure: FALSE.
2290 BOOL WINAPI
2291 SetFileSecurityW( LPCWSTR lpFileName,
2292 SECURITY_INFORMATION RequestedInformation,
2293 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2295 HANDLE file;
2296 DWORD access = 0;
2297 NTSTATUS status;
2299 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2300 pSecurityDescriptor );
2302 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2303 RequestedInformation & GROUP_SECURITY_INFORMATION)
2304 access |= WRITE_OWNER;
2305 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2306 access |= ACCESS_SYSTEM_SECURITY;
2307 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2308 access |= WRITE_DAC;
2310 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2311 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2312 if (file == INVALID_HANDLE_VALUE)
2313 return FALSE;
2315 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2316 CloseHandle( file );
2317 return set_ntstatus( status );
2320 /******************************************************************************
2321 * QueryWindows31FilesMigration [ADVAPI32.@]
2323 * PARAMS
2324 * x1 []
2326 BOOL WINAPI
2327 QueryWindows31FilesMigration( DWORD x1 )
2329 FIXME("(%d):stub\n",x1);
2330 return TRUE;
2333 /******************************************************************************
2334 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2336 * PARAMS
2337 * x1 []
2338 * x2 []
2339 * x3 []
2340 * x4 []
2342 BOOL WINAPI
2343 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2344 DWORD x4 )
2346 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2347 return TRUE;
2350 /******************************************************************************
2351 * NotifyBootConfigStatus [ADVAPI32.@]
2353 * PARAMS
2354 * x1 []
2356 BOOL WINAPI
2357 NotifyBootConfigStatus( BOOL x1 )
2359 FIXME("(0x%08d):stub\n",x1);
2360 return 1;
2363 /******************************************************************************
2364 * RevertToSelf [ADVAPI32.@]
2366 * Ends the impersonation of a user.
2368 * PARAMS
2369 * void []
2371 * RETURNS
2372 * Success: TRUE.
2373 * Failure: FALSE.
2375 BOOL WINAPI
2376 RevertToSelf( void )
2378 HANDLE Token = NULL;
2379 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2380 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2383 /******************************************************************************
2384 * ImpersonateSelf [ADVAPI32.@]
2386 * Makes an impersonation token that represents the process user and assigns
2387 * to the current thread.
2389 * PARAMS
2390 * ImpersonationLevel [I] Level at which to impersonate.
2392 * RETURNS
2393 * Success: TRUE.
2394 * Failure: FALSE.
2396 BOOL WINAPI
2397 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2399 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2402 /******************************************************************************
2403 * ImpersonateLoggedOnUser [ADVAPI32.@]
2405 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2407 DWORD size;
2408 NTSTATUS Status;
2409 HANDLE ImpersonationToken;
2410 TOKEN_TYPE Type;
2411 static BOOL warn = TRUE;
2413 if (warn)
2415 FIXME( "(%p)\n", hToken );
2416 warn = FALSE;
2418 if (!GetTokenInformation( hToken, TokenType, &Type,
2419 sizeof(TOKEN_TYPE), &size ))
2420 return FALSE;
2422 if (Type == TokenPrimary)
2424 OBJECT_ATTRIBUTES ObjectAttributes;
2426 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2428 Status = NtDuplicateToken( hToken,
2429 TOKEN_IMPERSONATE | TOKEN_QUERY,
2430 &ObjectAttributes,
2431 SecurityImpersonation,
2432 TokenImpersonation,
2433 &ImpersonationToken );
2434 if (Status != STATUS_SUCCESS)
2436 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2437 SetLastError( RtlNtStatusToDosError( Status ) );
2438 return FALSE;
2441 else
2442 ImpersonationToken = hToken;
2444 Status = NtSetInformationThread( GetCurrentThread(),
2445 ThreadImpersonationToken,
2446 &ImpersonationToken,
2447 sizeof(ImpersonationToken) );
2449 if (Type == TokenPrimary)
2450 NtClose( ImpersonationToken );
2452 if (Status != STATUS_SUCCESS)
2454 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2455 SetLastError( RtlNtStatusToDosError( Status ) );
2456 return FALSE;
2459 return TRUE;
2462 /******************************************************************************
2463 * AccessCheck [ADVAPI32.@]
2465 BOOL WINAPI
2466 AccessCheck(
2467 PSECURITY_DESCRIPTOR SecurityDescriptor,
2468 HANDLE ClientToken,
2469 DWORD DesiredAccess,
2470 PGENERIC_MAPPING GenericMapping,
2471 PPRIVILEGE_SET PrivilegeSet,
2472 LPDWORD PrivilegeSetLength,
2473 LPDWORD GrantedAccess,
2474 LPBOOL AccessStatus)
2476 NTSTATUS access_status;
2477 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2478 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2479 GrantedAccess, &access_status) );
2480 if (ret) *AccessStatus = set_ntstatus( access_status );
2481 return ret;
2485 /******************************************************************************
2486 * AccessCheckByType [ADVAPI32.@]
2488 BOOL WINAPI AccessCheckByType(
2489 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2490 PSID PrincipalSelfSid,
2491 HANDLE ClientToken,
2492 DWORD DesiredAccess,
2493 POBJECT_TYPE_LIST ObjectTypeList,
2494 DWORD ObjectTypeListLength,
2495 PGENERIC_MAPPING GenericMapping,
2496 PPRIVILEGE_SET PrivilegeSet,
2497 LPDWORD PrivilegeSetLength,
2498 LPDWORD GrantedAccess,
2499 LPBOOL AccessStatus)
2501 FIXME("stub\n");
2503 *AccessStatus = TRUE;
2505 return !*AccessStatus;
2508 /******************************************************************************
2509 * MapGenericMask [ADVAPI32.@]
2511 * Maps generic access rights into specific access rights according to the
2512 * supplied mapping.
2514 * PARAMS
2515 * AccessMask [I/O] Access rights.
2516 * GenericMapping [I] The mapping between generic and specific rights.
2518 * RETURNS
2519 * Nothing.
2521 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2523 RtlMapGenericMask( AccessMask, GenericMapping );
2526 /*************************************************************************
2527 * SetKernelObjectSecurity [ADVAPI32.@]
2529 BOOL WINAPI SetKernelObjectSecurity (
2530 IN HANDLE Handle,
2531 IN SECURITY_INFORMATION SecurityInformation,
2532 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2534 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2538 /******************************************************************************
2539 * AddAuditAccessAce [ADVAPI32.@]
2541 BOOL WINAPI AddAuditAccessAce(
2542 IN OUT PACL pAcl,
2543 IN DWORD dwAceRevision,
2544 IN DWORD dwAccessMask,
2545 IN PSID pSid,
2546 IN BOOL bAuditSuccess,
2547 IN BOOL bAuditFailure)
2549 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2550 bAuditSuccess, bAuditFailure) );
2553 /******************************************************************************
2554 * AddAuditAccessAce [ADVAPI32.@]
2556 BOOL WINAPI AddAuditAccessAceEx(
2557 IN OUT PACL pAcl,
2558 IN DWORD dwAceRevision,
2559 IN DWORD dwAceFlags,
2560 IN DWORD dwAccessMask,
2561 IN PSID pSid,
2562 IN BOOL bAuditSuccess,
2563 IN BOOL bAuditFailure)
2565 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2566 bAuditSuccess, bAuditFailure) );
2569 /******************************************************************************
2570 * LookupAccountNameA [ADVAPI32.@]
2572 BOOL WINAPI
2573 LookupAccountNameA(
2574 IN LPCSTR system,
2575 IN LPCSTR account,
2576 OUT PSID sid,
2577 OUT LPDWORD cbSid,
2578 LPSTR ReferencedDomainName,
2579 IN OUT LPDWORD cbReferencedDomainName,
2580 OUT PSID_NAME_USE name_use )
2582 BOOL ret;
2583 UNICODE_STRING lpSystemW;
2584 UNICODE_STRING lpAccountW;
2585 LPWSTR lpReferencedDomainNameW = NULL;
2587 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2588 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2590 if (ReferencedDomainName)
2591 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2593 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2594 cbReferencedDomainName, name_use);
2596 if (ret && lpReferencedDomainNameW)
2598 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2599 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2602 RtlFreeUnicodeString(&lpSystemW);
2603 RtlFreeUnicodeString(&lpAccountW);
2604 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2606 return ret;
2609 /******************************************************************************
2610 * lookup_user_account_name
2612 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2613 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2615 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2616 DWORD len = sizeof(buffer);
2617 HANDLE token;
2618 BOOL ret;
2619 PSID pSid;
2620 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2621 DWORD nameLen;
2622 LPCWSTR domainName;
2624 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2626 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2627 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2630 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2631 CloseHandle( token );
2633 if (!ret) return FALSE;
2635 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2637 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2638 CopySid(*cbSid, Sid, pSid);
2639 if (*cbSid < GetLengthSid(pSid))
2641 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2642 ret = FALSE;
2644 *cbSid = GetLengthSid(pSid);
2646 domainName = dm;
2647 nameLen = strlenW(domainName);
2649 if (*cchReferencedDomainName <= nameLen || !ret)
2651 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2652 nameLen += 1;
2653 ret = FALSE;
2655 else if (ReferencedDomainName)
2656 strcpyW(ReferencedDomainName, domainName);
2658 *cchReferencedDomainName = nameLen;
2660 if (ret)
2661 *peUse = SidTypeUser;
2663 return ret;
2666 /******************************************************************************
2667 * lookup_computer_account_name
2669 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2670 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2672 MAX_SID local;
2673 BOOL ret;
2674 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2675 DWORD nameLen;
2676 LPCWSTR domainName;
2678 if ((ret = ADVAPI_GetComputerSid(&local)))
2680 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2681 CopySid(*cbSid, Sid, &local);
2682 if (*cbSid < GetLengthSid(&local))
2684 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2685 ret = FALSE;
2687 *cbSid = GetLengthSid(&local);
2690 domainName = dm;
2691 nameLen = strlenW(domainName);
2693 if (*cchReferencedDomainName <= nameLen || !ret)
2695 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2696 nameLen += 1;
2697 ret = FALSE;
2699 else if (ReferencedDomainName)
2700 strcpyW(ReferencedDomainName, domainName);
2702 *cchReferencedDomainName = nameLen;
2704 if (ret)
2705 *peUse = SidTypeDomain;
2707 return ret;
2710 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2711 LSA_UNICODE_STRING *domain )
2713 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2715 while (p > str->Buffer && *p != '\\') p--;
2717 if (*p == '\\')
2719 domain->Buffer = str->Buffer;
2720 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2722 account->Buffer = p + 1;
2723 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2725 else
2727 domain->Buffer = NULL;
2728 domain->Length = 0;
2730 account->Buffer = str->Buffer;
2731 account->Length = str->Length;
2735 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2737 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2739 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2740 return TRUE;
2742 return FALSE;
2745 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2747 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2749 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2750 return TRUE;
2752 if (ACCOUNT_SIDS[idx].alias)
2754 len = strlenW( ACCOUNT_SIDS[idx].alias );
2755 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2756 return TRUE;
2758 return FALSE;
2762 * Helper function for LookupAccountNameW
2764 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2765 PSID Sid, LPDWORD cbSid,
2766 LPWSTR ReferencedDomainName,
2767 LPDWORD cchReferencedDomainName,
2768 PSID_NAME_USE peUse, BOOL *handled )
2770 PSID pSid;
2771 LSA_UNICODE_STRING account, domain;
2772 BOOL ret = TRUE;
2773 ULONG i;
2775 *handled = FALSE;
2776 split_domain_account( account_and_domain, &account, &domain );
2778 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2780 /* check domain first */
2781 if (domain.Buffer && !match_domain( i, &domain )) continue;
2783 if (match_account( i, &account ))
2785 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2787 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2789 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2791 if (*cbSid < sidLen)
2793 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2794 ret = FALSE;
2796 else if (Sid)
2798 CopySid(*cbSid, Sid, pSid);
2800 *cbSid = sidLen;
2803 len = strlenW( ACCOUNT_SIDS[i].domain );
2804 if (*cchReferencedDomainName <= len || !ret)
2806 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2807 len++;
2808 ret = FALSE;
2810 else if (ReferencedDomainName)
2812 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2815 *cchReferencedDomainName = len;
2816 if (ret)
2817 *peUse = ACCOUNT_SIDS[i].name_use;
2819 HeapFree(GetProcessHeap(), 0, pSid);
2820 *handled = TRUE;
2821 return ret;
2824 return ret;
2827 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2828 PSID Sid, LPDWORD cbSid,
2829 LPWSTR ReferencedDomainName,
2830 LPDWORD cchReferencedDomainName,
2831 PSID_NAME_USE peUse, BOOL *handled )
2833 DWORD nameLen;
2834 LPWSTR userName = NULL;
2835 LSA_UNICODE_STRING account, domain;
2836 BOOL ret = TRUE;
2838 *handled = FALSE;
2839 split_domain_account( account_and_domain, &account, &domain );
2841 /* Let the current Unix user id masquerade as first Windows user account */
2843 nameLen = UNLEN + 1;
2844 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2846 if (domain.Buffer)
2848 /* check to make sure this account is on this computer */
2849 if (GetComputerNameW( userName, &nameLen ) &&
2850 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2852 SetLastError(ERROR_NONE_MAPPED);
2853 ret = FALSE;
2855 nameLen = UNLEN + 1;
2858 if (GetUserNameW( userName, &nameLen ) &&
2859 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2861 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2862 *handled = TRUE;
2864 else
2866 nameLen = UNLEN + 1;
2867 if (GetComputerNameW( userName, &nameLen ) &&
2868 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2870 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2871 *handled = TRUE;
2875 HeapFree(GetProcessHeap(), 0, userName);
2876 return ret;
2879 /******************************************************************************
2880 * LookupAccountNameW [ADVAPI32.@]
2882 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2883 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2884 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2886 BOOL ret, handled;
2887 LSA_UNICODE_STRING account;
2889 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2890 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2892 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2894 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2895 return FALSE;
2898 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2900 lpAccountName = BUILTIN;
2903 RtlInitUnicodeString( &account, lpAccountName );
2905 /* Check well known SIDs first */
2906 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2907 cchReferencedDomainName, peUse, &handled );
2908 if (handled)
2909 return ret;
2911 /* Check user names */
2912 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2913 cchReferencedDomainName, peUse, &handled);
2914 if (handled)
2915 return ret;
2917 SetLastError( ERROR_NONE_MAPPED );
2918 return FALSE;
2921 /******************************************************************************
2922 * PrivilegeCheck [ADVAPI32.@]
2924 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2926 BOOL ret;
2927 BOOLEAN Result;
2929 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2931 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2932 if (ret)
2933 *pfResult = Result;
2934 return ret;
2937 /******************************************************************************
2938 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2940 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2941 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2942 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2943 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2945 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2946 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2947 SecurityDescriptor, DesiredAccess, GenericMapping,
2948 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2949 return TRUE;
2952 /******************************************************************************
2953 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2955 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2956 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2957 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2958 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2960 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2961 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2962 SecurityDescriptor, DesiredAccess, GenericMapping,
2963 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2964 return TRUE;
2967 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2969 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2971 return TRUE;
2974 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2976 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2978 return TRUE;
2981 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2983 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2985 return TRUE;
2988 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2989 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2990 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2991 LPBOOL GenerateOnClose)
2993 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2994 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2995 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2996 GenerateOnClose);
2998 return TRUE;
3001 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3002 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3003 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3004 LPBOOL GenerateOnClose)
3006 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3007 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3008 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3009 GenerateOnClose);
3011 return TRUE;
3014 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3015 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3017 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3018 DesiredAccess, Privileges, AccessGranted);
3020 return TRUE;
3023 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3024 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3026 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3027 DesiredAccess, Privileges, AccessGranted);
3029 return TRUE;
3032 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3033 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3035 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3036 ClientToken, Privileges, AccessGranted);
3038 return TRUE;
3041 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3042 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3044 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3045 ClientToken, Privileges, AccessGranted);
3047 return TRUE;
3050 /******************************************************************************
3051 * GetSecurityInfo [ADVAPI32.@]
3053 * Retrieves a copy of the security descriptor associated with an object.
3055 * PARAMS
3056 * hObject [I] A handle for the object.
3057 * ObjectType [I] The type of object.
3058 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3059 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3060 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3061 * ppDacl [O] If non-null, receives a pointer to the DACL.
3062 * ppSacl [O] If non-null, receives a pointer to the SACL.
3063 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3064 * which must be freed with LocalFree.
3066 * RETURNS
3067 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3069 DWORD WINAPI GetSecurityInfo(
3070 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3071 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3072 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3073 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3076 PSECURITY_DESCRIPTOR sd;
3077 NTSTATUS status;
3078 ULONG n1, n2;
3079 BOOL present, defaulted;
3081 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3082 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3083 return RtlNtStatusToDosError(status);
3085 sd = LocalAlloc(0, n1);
3086 if (!sd)
3087 return ERROR_NOT_ENOUGH_MEMORY;
3089 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3090 if (status != STATUS_SUCCESS)
3092 LocalFree(sd);
3093 return RtlNtStatusToDosError(status);
3096 if (ppsidOwner)
3098 *ppsidOwner = NULL;
3099 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3101 if (ppsidGroup)
3103 *ppsidGroup = NULL;
3104 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3106 if (ppDacl)
3108 *ppDacl = NULL;
3109 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3111 if (ppSacl)
3113 *ppSacl = NULL;
3114 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3116 if (ppSecurityDescriptor)
3117 *ppSecurityDescriptor = sd;
3119 return ERROR_SUCCESS;
3122 /******************************************************************************
3123 * GetSecurityInfoExA [ADVAPI32.@]
3125 DWORD WINAPI GetSecurityInfoExA(
3126 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3127 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3128 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3129 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3132 FIXME("stub!\n");
3133 return ERROR_BAD_PROVIDER;
3136 /******************************************************************************
3137 * GetSecurityInfoExW [ADVAPI32.@]
3139 DWORD WINAPI GetSecurityInfoExW(
3140 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3141 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3142 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3143 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3146 FIXME("stub!\n");
3147 return ERROR_BAD_PROVIDER;
3150 /******************************************************************************
3151 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3153 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3154 LPSTR pTrusteeName, DWORD AccessPermissions,
3155 ACCESS_MODE AccessMode, DWORD Inheritance )
3157 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3158 AccessPermissions, AccessMode, Inheritance);
3160 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3161 pExplicitAccess->grfAccessMode = AccessMode;
3162 pExplicitAccess->grfInheritance = Inheritance;
3164 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3165 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3166 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3167 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3168 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3171 /******************************************************************************
3172 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3174 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3175 LPWSTR pTrusteeName, DWORD AccessPermissions,
3176 ACCESS_MODE AccessMode, DWORD Inheritance )
3178 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3179 AccessPermissions, AccessMode, Inheritance);
3181 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3182 pExplicitAccess->grfAccessMode = AccessMode;
3183 pExplicitAccess->grfInheritance = Inheritance;
3185 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3186 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3187 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3188 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3189 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3192 /******************************************************************************
3193 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3195 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3196 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3197 LPSTR InheritedObjectTypeName, LPSTR Name )
3199 DWORD ObjectsPresent = 0;
3201 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3202 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3204 /* Fill the OBJECTS_AND_NAME structure */
3205 pObjName->ObjectType = ObjectType;
3206 if (ObjectTypeName != NULL)
3208 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3211 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3212 if (InheritedObjectTypeName != NULL)
3214 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3217 pObjName->ObjectsPresent = ObjectsPresent;
3218 pObjName->ptstrName = Name;
3220 /* Fill the TRUSTEE structure */
3221 pTrustee->pMultipleTrustee = NULL;
3222 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3223 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3224 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3225 pTrustee->ptstrName = (LPSTR)pObjName;
3228 /******************************************************************************
3229 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3231 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3232 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3233 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3235 DWORD ObjectsPresent = 0;
3237 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3238 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3240 /* Fill the OBJECTS_AND_NAME structure */
3241 pObjName->ObjectType = ObjectType;
3242 if (ObjectTypeName != NULL)
3244 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3247 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3248 if (InheritedObjectTypeName != NULL)
3250 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3253 pObjName->ObjectsPresent = ObjectsPresent;
3254 pObjName->ptstrName = Name;
3256 /* Fill the TRUSTEE structure */
3257 pTrustee->pMultipleTrustee = NULL;
3258 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3259 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3260 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3261 pTrustee->ptstrName = (LPWSTR)pObjName;
3264 /******************************************************************************
3265 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3267 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3268 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3270 DWORD ObjectsPresent = 0;
3272 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3274 /* Fill the OBJECTS_AND_SID structure */
3275 if (pObjectGuid != NULL)
3277 pObjSid->ObjectTypeGuid = *pObjectGuid;
3278 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3280 else
3282 ZeroMemory(&pObjSid->ObjectTypeGuid,
3283 sizeof(GUID));
3286 if (pInheritedObjectGuid != NULL)
3288 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3289 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3291 else
3293 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3294 sizeof(GUID));
3297 pObjSid->ObjectsPresent = ObjectsPresent;
3298 pObjSid->pSid = pSid;
3300 /* Fill the TRUSTEE structure */
3301 pTrustee->pMultipleTrustee = NULL;
3302 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3303 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3304 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3305 pTrustee->ptstrName = (LPSTR) pObjSid;
3308 /******************************************************************************
3309 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3311 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3312 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3314 DWORD ObjectsPresent = 0;
3316 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3318 /* Fill the OBJECTS_AND_SID structure */
3319 if (pObjectGuid != NULL)
3321 pObjSid->ObjectTypeGuid = *pObjectGuid;
3322 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3324 else
3326 ZeroMemory(&pObjSid->ObjectTypeGuid,
3327 sizeof(GUID));
3330 if (pInheritedObjectGuid != NULL)
3332 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3333 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3335 else
3337 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3338 sizeof(GUID));
3341 pObjSid->ObjectsPresent = ObjectsPresent;
3342 pObjSid->pSid = pSid;
3344 /* Fill the TRUSTEE structure */
3345 pTrustee->pMultipleTrustee = NULL;
3346 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3347 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3348 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3349 pTrustee->ptstrName = (LPWSTR) pObjSid;
3352 /******************************************************************************
3353 * BuildTrusteeWithSidA [ADVAPI32.@]
3355 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3357 TRACE("%p %p\n", pTrustee, pSid);
3359 pTrustee->pMultipleTrustee = NULL;
3360 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3361 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3362 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3363 pTrustee->ptstrName = pSid;
3366 /******************************************************************************
3367 * BuildTrusteeWithSidW [ADVAPI32.@]
3369 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3371 TRACE("%p %p\n", pTrustee, pSid);
3373 pTrustee->pMultipleTrustee = NULL;
3374 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3375 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3376 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3377 pTrustee->ptstrName = pSid;
3380 /******************************************************************************
3381 * BuildTrusteeWithNameA [ADVAPI32.@]
3383 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3385 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3387 pTrustee->pMultipleTrustee = NULL;
3388 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3389 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3390 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3391 pTrustee->ptstrName = name;
3394 /******************************************************************************
3395 * BuildTrusteeWithNameW [ADVAPI32.@]
3397 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3399 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3401 pTrustee->pMultipleTrustee = NULL;
3402 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3403 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3404 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3405 pTrustee->ptstrName = name;
3408 /******************************************************************************
3409 * GetTrusteeFormA [ADVAPI32.@]
3411 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3413 TRACE("(%p)\n", pTrustee);
3415 if (!pTrustee)
3416 return TRUSTEE_BAD_FORM;
3418 return pTrustee->TrusteeForm;
3421 /******************************************************************************
3422 * GetTrusteeFormW [ADVAPI32.@]
3424 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3426 TRACE("(%p)\n", pTrustee);
3428 if (!pTrustee)
3429 return TRUSTEE_BAD_FORM;
3431 return pTrustee->TrusteeForm;
3434 /******************************************************************************
3435 * GetTrusteeNameA [ADVAPI32.@]
3437 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3439 TRACE("(%p)\n", pTrustee);
3441 if (!pTrustee)
3442 return NULL;
3444 return pTrustee->ptstrName;
3447 /******************************************************************************
3448 * GetTrusteeNameW [ADVAPI32.@]
3450 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3452 TRACE("(%p)\n", pTrustee);
3454 if (!pTrustee)
3455 return NULL;
3457 return pTrustee->ptstrName;
3460 /******************************************************************************
3461 * GetTrusteeTypeA [ADVAPI32.@]
3463 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3465 TRACE("(%p)\n", pTrustee);
3467 if (!pTrustee)
3468 return TRUSTEE_IS_UNKNOWN;
3470 return pTrustee->TrusteeType;
3473 /******************************************************************************
3474 * GetTrusteeTypeW [ADVAPI32.@]
3476 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3478 TRACE("(%p)\n", pTrustee);
3480 if (!pTrustee)
3481 return TRUSTEE_IS_UNKNOWN;
3483 return pTrustee->TrusteeType;
3486 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3487 DWORD nAclInformationLength,
3488 ACL_INFORMATION_CLASS dwAclInformationClass )
3490 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3491 nAclInformationLength, dwAclInformationClass);
3493 return TRUE;
3496 /******************************************************************************
3497 * SetEntriesInAclA [ADVAPI32.@]
3499 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3500 PACL OldAcl, PACL* NewAcl )
3502 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3503 if (NewAcl)
3504 *NewAcl = NULL;
3505 return ERROR_SUCCESS;
3508 /******************************************************************************
3509 * SetEntriesInAclW [ADVAPI32.@]
3511 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3512 PACL OldAcl, PACL* NewAcl )
3514 ULONG i;
3515 PSID *ppsid;
3516 DWORD ret = ERROR_SUCCESS;
3517 DWORD acl_size = sizeof(ACL);
3518 NTSTATUS status;
3520 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3522 *NewAcl = NULL;
3524 if (!count && !OldAcl)
3525 return ERROR_SUCCESS;
3527 /* allocate array of maximum sized sids allowed */
3528 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3529 if (!ppsid)
3530 return ERROR_OUTOFMEMORY;
3532 for (i = 0; i < count; i++)
3534 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3536 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3537 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3538 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3539 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3540 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3541 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3542 pEntries[i].Trustee.ptstrName);
3544 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3546 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3547 ret = ERROR_INVALID_PARAMETER;
3548 goto exit;
3551 switch (pEntries[i].Trustee.TrusteeForm)
3553 case TRUSTEE_IS_SID:
3554 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3555 ppsid[i], pEntries[i].Trustee.ptstrName))
3557 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3558 ret = ERROR_INVALID_PARAMETER;
3559 goto exit;
3561 break;
3562 case TRUSTEE_IS_NAME:
3564 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3565 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3566 SID_NAME_USE use;
3567 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3569 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3571 ret = GetLastError();
3572 goto exit;
3575 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3577 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3578 ret = ERROR_INVALID_PARAMETER;
3579 goto exit;
3581 break;
3583 case TRUSTEE_IS_OBJECTS_AND_SID:
3584 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3585 break;
3586 case TRUSTEE_IS_OBJECTS_AND_NAME:
3587 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3588 break;
3589 default:
3590 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3591 ret = ERROR_INVALID_PARAMETER;
3592 goto exit;
3595 /* Note: we overestimate the ACL size here as a tradeoff between
3596 * instructions (simplicity) and memory */
3597 switch (pEntries[i].grfAccessMode)
3599 case GRANT_ACCESS:
3600 case SET_ACCESS:
3601 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3602 break;
3603 case DENY_ACCESS:
3604 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3605 break;
3606 case SET_AUDIT_SUCCESS:
3607 case SET_AUDIT_FAILURE:
3608 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3609 break;
3610 case REVOKE_ACCESS:
3611 break;
3612 default:
3613 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3614 ret = ERROR_INVALID_PARAMETER;
3615 goto exit;
3619 if (OldAcl)
3621 ACL_SIZE_INFORMATION size_info;
3623 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3624 if (status != STATUS_SUCCESS)
3626 ret = RtlNtStatusToDosError(status);
3627 goto exit;
3629 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3632 *NewAcl = LocalAlloc(0, acl_size);
3633 if (!*NewAcl)
3635 ret = ERROR_OUTOFMEMORY;
3636 goto exit;
3639 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3640 if (status != STATUS_SUCCESS)
3642 ret = RtlNtStatusToDosError(status);
3643 goto exit;
3646 for (i = 0; i < count; i++)
3648 switch (pEntries[i].grfAccessMode)
3650 case GRANT_ACCESS:
3651 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3652 pEntries[i].grfInheritance,
3653 pEntries[i].grfAccessPermissions,
3654 ppsid[i]);
3655 break;
3656 case SET_ACCESS:
3658 ULONG j;
3659 BOOL add = TRUE;
3660 if (OldAcl)
3662 for (j = 0; ; j++)
3664 const ACE_HEADER *existing_ace_header;
3665 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3666 if (status != STATUS_SUCCESS)
3667 break;
3668 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3669 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3670 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3672 add = FALSE;
3673 break;
3677 if (add)
3678 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3679 pEntries[i].grfInheritance,
3680 pEntries[i].grfAccessPermissions,
3681 ppsid[i]);
3682 break;
3684 case DENY_ACCESS:
3685 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3686 pEntries[i].grfInheritance,
3687 pEntries[i].grfAccessPermissions,
3688 ppsid[i]);
3689 break;
3690 case SET_AUDIT_SUCCESS:
3691 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3692 pEntries[i].grfInheritance,
3693 pEntries[i].grfAccessPermissions,
3694 ppsid[i], TRUE, FALSE);
3695 break;
3696 case SET_AUDIT_FAILURE:
3697 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3698 pEntries[i].grfInheritance,
3699 pEntries[i].grfAccessPermissions,
3700 ppsid[i], FALSE, TRUE);
3701 break;
3702 default:
3703 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3707 if (OldAcl)
3709 for (i = 0; ; i++)
3711 BOOL add = TRUE;
3712 ULONG j;
3713 const ACE_HEADER *old_ace_header;
3714 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3715 if (status != STATUS_SUCCESS) break;
3716 for (j = 0; j < count; j++)
3718 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3719 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3720 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3722 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3723 add = FALSE;
3724 break;
3726 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3728 switch (old_ace_header->AceType)
3730 case ACCESS_ALLOWED_ACE_TYPE:
3731 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3732 add = FALSE;
3733 break;
3734 case ACCESS_DENIED_ACE_TYPE:
3735 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3736 add = FALSE;
3737 break;
3738 case SYSTEM_AUDIT_ACE_TYPE:
3739 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3740 add = FALSE;
3741 break;
3742 case SYSTEM_ALARM_ACE_TYPE:
3743 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3744 add = FALSE;
3745 break;
3746 default:
3747 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3750 if (!add)
3751 break;
3754 if (add)
3755 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3756 if (status != STATUS_SUCCESS)
3758 WARN("RtlAddAce failed with error 0x%08x\n", status);
3759 ret = RtlNtStatusToDosError(status);
3760 break;
3765 exit:
3766 HeapFree(GetProcessHeap(), 0, ppsid);
3767 return ret;
3770 /******************************************************************************
3771 * SetNamedSecurityInfoA [ADVAPI32.@]
3773 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3774 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3775 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3777 DWORD len;
3778 LPWSTR wstr = NULL;
3779 DWORD r;
3781 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3782 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3784 if( pObjectName )
3786 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3787 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3788 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3791 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3792 psidGroup, pDacl, pSacl );
3794 HeapFree( GetProcessHeap(), 0, wstr );
3796 return r;
3799 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3800 PSECURITY_DESCRIPTOR ModificationDescriptor,
3801 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3802 PGENERIC_MAPPING GenericMapping,
3803 HANDLE Token )
3805 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3806 ObjectsSecurityDescriptor, GenericMapping, Token);
3808 return TRUE;
3811 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3813 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3816 /******************************************************************************
3817 * AreAnyAccessesGranted [ADVAPI32.@]
3819 * Determines whether or not any of a set of specified access permissions have
3820 * been granted or not.
3822 * PARAMS
3823 * GrantedAccess [I] The permissions that have been granted.
3824 * DesiredAccess [I] The permissions that you want to have.
3826 * RETURNS
3827 * Nonzero if any of the permissions have been granted, zero if none of the
3828 * permissions have been granted.
3831 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3833 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3836 /******************************************************************************
3837 * SetNamedSecurityInfoW [ADVAPI32.@]
3839 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3840 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3841 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3843 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3844 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3845 return ERROR_SUCCESS;
3848 /******************************************************************************
3849 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3851 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3852 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3854 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3855 return ERROR_CALL_NOT_IMPLEMENTED;
3858 /******************************************************************************
3859 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3861 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3862 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3864 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3865 return ERROR_CALL_NOT_IMPLEMENTED;
3868 /******************************************************************************
3869 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3871 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3872 PACCESS_MASK pFailedAuditRights)
3874 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3875 return ERROR_CALL_NOT_IMPLEMENTED;
3879 /******************************************************************************
3880 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3882 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3883 PACCESS_MASK pFailedAuditRights)
3885 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3886 return ERROR_CALL_NOT_IMPLEMENTED;
3890 /******************************************************************************
3891 * ParseAclStringFlags
3893 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3895 DWORD flags = 0;
3896 LPCWSTR szAcl = *StringAcl;
3898 while (*szAcl != '(')
3900 if (*szAcl == 'P')
3902 flags |= SE_DACL_PROTECTED;
3904 else if (*szAcl == 'A')
3906 szAcl++;
3907 if (*szAcl == 'R')
3908 flags |= SE_DACL_AUTO_INHERIT_REQ;
3909 else if (*szAcl == 'I')
3910 flags |= SE_DACL_AUTO_INHERITED;
3912 szAcl++;
3915 *StringAcl = szAcl;
3916 return flags;
3919 /******************************************************************************
3920 * ParseAceStringType
3922 static const ACEFLAG AceType[] =
3924 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3925 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3926 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3927 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3929 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3930 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3931 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3932 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3934 { NULL, 0 },
3937 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3939 UINT len = 0;
3940 LPCWSTR szAcl = *StringAcl;
3941 const ACEFLAG *lpaf = AceType;
3943 while (*szAcl == ' ')
3944 szAcl++;
3946 while (lpaf->wstr &&
3947 (len = strlenW(lpaf->wstr)) &&
3948 strncmpW(lpaf->wstr, szAcl, len))
3949 lpaf++;
3951 if (!lpaf->wstr)
3952 return 0;
3954 *StringAcl = szAcl + len;
3955 return lpaf->value;
3959 /******************************************************************************
3960 * ParseAceStringFlags
3962 static const ACEFLAG AceFlags[] =
3964 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3965 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3966 { SDDL_INHERITED, INHERITED_ACE },
3967 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3968 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3969 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3970 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3971 { NULL, 0 },
3974 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3976 UINT len = 0;
3977 BYTE flags = 0;
3978 LPCWSTR szAcl = *StringAcl;
3980 while (*szAcl == ' ')
3981 szAcl++;
3983 while (*szAcl != ';')
3985 const ACEFLAG *lpaf = AceFlags;
3987 while (lpaf->wstr &&
3988 (len = strlenW(lpaf->wstr)) &&
3989 strncmpW(lpaf->wstr, szAcl, len))
3990 lpaf++;
3992 if (!lpaf->wstr)
3993 return 0;
3995 flags |= lpaf->value;
3996 szAcl += len;
3999 *StringAcl = szAcl;
4000 return flags;
4004 /******************************************************************************
4005 * ParseAceStringRights
4007 static const ACEFLAG AceRights[] =
4009 { SDDL_GENERIC_ALL, GENERIC_ALL },
4010 { SDDL_GENERIC_READ, GENERIC_READ },
4011 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4012 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4014 { SDDL_READ_CONTROL, READ_CONTROL },
4015 { SDDL_STANDARD_DELETE, DELETE },
4016 { SDDL_WRITE_DAC, WRITE_DAC },
4017 { SDDL_WRITE_OWNER, WRITE_OWNER },
4019 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4020 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4021 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4022 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4023 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4024 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4025 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4026 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4027 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4029 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4030 { SDDL_FILE_READ, FILE_GENERIC_READ },
4031 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4032 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4034 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4035 { SDDL_KEY_READ, KEY_READ },
4036 { SDDL_KEY_WRITE, KEY_WRITE },
4037 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4038 { NULL, 0 },
4041 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4043 UINT len = 0;
4044 DWORD rights = 0;
4045 LPCWSTR szAcl = *StringAcl;
4047 while (*szAcl == ' ')
4048 szAcl++;
4050 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4052 LPCWSTR p = szAcl;
4054 while (*p && *p != ';')
4055 p++;
4057 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4059 rights = strtoulW(szAcl, NULL, 16);
4060 szAcl = p;
4062 else
4063 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4065 else
4067 while (*szAcl != ';')
4069 const ACEFLAG *lpaf = AceRights;
4071 while (lpaf->wstr &&
4072 (len = strlenW(lpaf->wstr)) &&
4073 strncmpW(lpaf->wstr, szAcl, len))
4075 lpaf++;
4078 if (!lpaf->wstr)
4079 return 0;
4081 rights |= lpaf->value;
4082 szAcl += len;
4086 *StringAcl = szAcl;
4087 return rights;
4091 /******************************************************************************
4092 * ParseStringAclToAcl
4094 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4096 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4097 PACL pAcl, LPDWORD cBytes)
4099 DWORD val;
4100 DWORD sidlen;
4101 DWORD length = sizeof(ACL);
4102 DWORD acesize = 0;
4103 DWORD acecount = 0;
4104 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4105 DWORD error = ERROR_INVALID_ACL;
4107 TRACE("%s\n", debugstr_w(StringAcl));
4109 if (!StringAcl)
4110 return FALSE;
4112 if (pAcl) /* pAce is only useful if we're setting values */
4113 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4115 /* Parse ACL flags */
4116 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4118 /* Parse ACE */
4119 while (*StringAcl == '(')
4121 StringAcl++;
4123 /* Parse ACE type */
4124 val = ParseAceStringType(&StringAcl);
4125 if (pAce)
4126 pAce->Header.AceType = (BYTE) val;
4127 if (*StringAcl != ';')
4129 error = RPC_S_INVALID_STRING_UUID;
4130 goto lerr;
4132 StringAcl++;
4134 /* Parse ACE flags */
4135 val = ParseAceStringFlags(&StringAcl);
4136 if (pAce)
4137 pAce->Header.AceFlags = (BYTE) val;
4138 if (*StringAcl != ';')
4139 goto lerr;
4140 StringAcl++;
4142 /* Parse ACE rights */
4143 val = ParseAceStringRights(&StringAcl);
4144 if (pAce)
4145 pAce->Mask = val;
4146 if (*StringAcl != ';')
4147 goto lerr;
4148 StringAcl++;
4150 /* Parse ACE object guid */
4151 while (*StringAcl == ' ')
4152 StringAcl++;
4153 if (*StringAcl != ';')
4155 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4156 goto lerr;
4158 StringAcl++;
4160 /* Parse ACE inherit object guid */
4161 while (*StringAcl == ' ')
4162 StringAcl++;
4163 if (*StringAcl != ';')
4165 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4166 goto lerr;
4168 StringAcl++;
4170 /* Parse ACE account sid */
4171 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4173 while (*StringAcl && *StringAcl != ')')
4174 StringAcl++;
4177 if (*StringAcl != ')')
4178 goto lerr;
4179 StringAcl++;
4181 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4182 length += acesize;
4183 if (pAce)
4185 pAce->Header.AceSize = acesize;
4186 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4188 acecount++;
4191 *cBytes = length;
4193 if (length > 0xffff)
4195 ERR("ACL too large\n");
4196 goto lerr;
4199 if (pAcl)
4201 pAcl->AclRevision = ACL_REVISION;
4202 pAcl->Sbz1 = 0;
4203 pAcl->AclSize = length;
4204 pAcl->AceCount = acecount++;
4205 pAcl->Sbz2 = 0;
4207 return TRUE;
4209 lerr:
4210 SetLastError(error);
4211 WARN("Invalid ACE string format\n");
4212 return FALSE;
4216 /******************************************************************************
4217 * ParseStringSecurityDescriptorToSecurityDescriptor
4219 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4220 LPCWSTR StringSecurityDescriptor,
4221 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4222 LPDWORD cBytes)
4224 BOOL bret = FALSE;
4225 WCHAR toktype;
4226 WCHAR tok[MAX_PATH];
4227 LPCWSTR lptoken;
4228 LPBYTE lpNext = NULL;
4229 DWORD len;
4231 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4233 if (SecurityDescriptor)
4234 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4236 while (*StringSecurityDescriptor == ' ')
4237 StringSecurityDescriptor++;
4239 while (*StringSecurityDescriptor)
4241 toktype = *StringSecurityDescriptor;
4243 /* Expect char identifier followed by ':' */
4244 StringSecurityDescriptor++;
4245 if (*StringSecurityDescriptor != ':')
4247 SetLastError(ERROR_INVALID_PARAMETER);
4248 goto lend;
4250 StringSecurityDescriptor++;
4252 /* Extract token */
4253 lptoken = StringSecurityDescriptor;
4254 while (*lptoken && *lptoken != ':')
4255 lptoken++;
4257 if (*lptoken)
4258 lptoken--;
4260 len = lptoken - StringSecurityDescriptor;
4261 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4262 tok[len] = 0;
4264 switch (toktype)
4266 case 'O':
4268 DWORD bytes;
4270 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4271 goto lend;
4273 if (SecurityDescriptor)
4275 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4276 lpNext += bytes; /* Advance to next token */
4279 *cBytes += bytes;
4281 break;
4284 case 'G':
4286 DWORD bytes;
4288 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4289 goto lend;
4291 if (SecurityDescriptor)
4293 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4294 lpNext += bytes; /* Advance to next token */
4297 *cBytes += bytes;
4299 break;
4302 case 'D':
4304 DWORD flags;
4305 DWORD bytes;
4307 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4308 goto lend;
4310 if (SecurityDescriptor)
4312 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4313 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4314 lpNext += bytes; /* Advance to next token */
4317 *cBytes += bytes;
4319 break;
4322 case 'S':
4324 DWORD flags;
4325 DWORD bytes;
4327 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4328 goto lend;
4330 if (SecurityDescriptor)
4332 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4333 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4334 lpNext += bytes; /* Advance to next token */
4337 *cBytes += bytes;
4339 break;
4342 default:
4343 FIXME("Unknown token\n");
4344 SetLastError(ERROR_INVALID_PARAMETER);
4345 goto lend;
4348 StringSecurityDescriptor = lptoken;
4351 bret = TRUE;
4353 lend:
4354 return bret;
4357 /******************************************************************************
4358 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4360 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4361 LPCSTR StringSecurityDescriptor,
4362 DWORD StringSDRevision,
4363 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4364 PULONG SecurityDescriptorSize)
4366 UINT len;
4367 BOOL ret = FALSE;
4368 LPWSTR StringSecurityDescriptorW;
4370 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4371 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4373 if (StringSecurityDescriptorW)
4375 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4377 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4378 StringSDRevision, SecurityDescriptor,
4379 SecurityDescriptorSize);
4380 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4383 return ret;
4386 /******************************************************************************
4387 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4389 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4390 LPCWSTR StringSecurityDescriptor,
4391 DWORD StringSDRevision,
4392 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4393 PULONG SecurityDescriptorSize)
4395 DWORD cBytes;
4396 SECURITY_DESCRIPTOR* psd;
4397 BOOL bret = FALSE;
4399 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4401 if (GetVersion() & 0x80000000)
4403 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4404 goto lend;
4406 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4408 SetLastError(ERROR_INVALID_PARAMETER);
4409 goto lend;
4411 else if (StringSDRevision != SID_REVISION)
4413 SetLastError(ERROR_UNKNOWN_REVISION);
4414 goto lend;
4417 /* Compute security descriptor length */
4418 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4419 NULL, &cBytes))
4420 goto lend;
4422 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4423 if (!psd) goto lend;
4425 psd->Revision = SID_REVISION;
4426 psd->Control |= SE_SELF_RELATIVE;
4428 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4429 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4431 LocalFree(psd);
4432 goto lend;
4435 if (SecurityDescriptorSize)
4436 *SecurityDescriptorSize = cBytes;
4438 bret = TRUE;
4440 lend:
4441 TRACE(" ret=%d\n", bret);
4442 return bret;
4445 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4447 if (cch == -1)
4448 cch = strlenW(string);
4450 if (plen)
4451 *plen += cch;
4453 if (pwptr)
4455 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4456 *pwptr += cch;
4460 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4462 DWORD i;
4463 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4464 WCHAR subauthfmt[] = { '-','%','u',0 };
4465 WCHAR buf[26];
4466 SID *pisid = psid;
4468 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4470 SetLastError(ERROR_INVALID_SID);
4471 return FALSE;
4474 if (pisid->IdentifierAuthority.Value[0] ||
4475 pisid->IdentifierAuthority.Value[1])
4477 FIXME("not matching MS' bugs\n");
4478 SetLastError(ERROR_INVALID_SID);
4479 return FALSE;
4482 sprintfW( buf, fmt, pisid->Revision,
4483 MAKELONG(
4484 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4485 pisid->IdentifierAuthority.Value[4] ),
4486 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4487 pisid->IdentifierAuthority.Value[2] )
4488 ) );
4489 DumpString(buf, -1, pwptr, plen);
4491 for( i=0; i<pisid->SubAuthorityCount; i++ )
4493 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4494 DumpString(buf, -1, pwptr, plen);
4496 return TRUE;
4499 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4501 size_t i;
4502 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4504 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4506 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4507 return TRUE;
4511 return DumpSidNumeric(psid, pwptr, plen);
4514 static const LPCWSTR AceRightBitNames[32] = {
4515 SDDL_CREATE_CHILD, /* 0 */
4516 SDDL_DELETE_CHILD,
4517 SDDL_LIST_CHILDREN,
4518 SDDL_SELF_WRITE,
4519 SDDL_READ_PROPERTY, /* 4 */
4520 SDDL_WRITE_PROPERTY,
4521 SDDL_DELETE_TREE,
4522 SDDL_LIST_OBJECT,
4523 SDDL_CONTROL_ACCESS, /* 8 */
4524 NULL,
4525 NULL,
4526 NULL,
4527 NULL, /* 12 */
4528 NULL,
4529 NULL,
4530 NULL,
4531 SDDL_STANDARD_DELETE, /* 16 */
4532 SDDL_READ_CONTROL,
4533 SDDL_WRITE_DAC,
4534 SDDL_WRITE_OWNER,
4535 NULL, /* 20 */
4536 NULL,
4537 NULL,
4538 NULL,
4539 NULL, /* 24 */
4540 NULL,
4541 NULL,
4542 NULL,
4543 SDDL_GENERIC_ALL, /* 28 */
4544 SDDL_GENERIC_EXECUTE,
4545 SDDL_GENERIC_WRITE,
4546 SDDL_GENERIC_READ
4549 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4551 static const WCHAR fmtW[] = {'0','x','%','x',0};
4552 WCHAR buf[15];
4553 size_t i;
4555 if (mask == 0)
4556 return;
4558 /* first check if the right have name */
4559 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4561 if (AceRights[i].wstr == NULL)
4562 break;
4563 if (mask == AceRights[i].value)
4565 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4566 return;
4570 /* then check if it can be built from bit names */
4571 for (i = 0; i < 32; i++)
4573 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4575 /* can't be built from bit names */
4576 sprintfW(buf, fmtW, mask);
4577 DumpString(buf, -1, pwptr, plen);
4578 return;
4582 /* build from bit names */
4583 for (i = 0; i < 32; i++)
4584 if (mask & (1 << i))
4585 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4588 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4590 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4591 static const WCHAR openbr = '(';
4592 static const WCHAR closebr = ')';
4593 static const WCHAR semicolon = ';';
4595 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4597 SetLastError(ERROR_INVALID_ACL);
4598 return FALSE;
4601 piace = pace;
4602 DumpString(&openbr, 1, pwptr, plen);
4603 switch (piace->Header.AceType)
4605 case ACCESS_ALLOWED_ACE_TYPE:
4606 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4607 break;
4608 case ACCESS_DENIED_ACE_TYPE:
4609 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4610 break;
4611 case SYSTEM_AUDIT_ACE_TYPE:
4612 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4613 break;
4614 case SYSTEM_ALARM_ACE_TYPE:
4615 DumpString(SDDL_ALARM, -1, pwptr, plen);
4616 break;
4618 DumpString(&semicolon, 1, pwptr, plen);
4620 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4621 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4622 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4623 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4624 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4625 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4626 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4627 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4628 if (piace->Header.AceFlags & INHERITED_ACE)
4629 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4630 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4631 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4632 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4633 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4634 DumpString(&semicolon, 1, pwptr, plen);
4635 DumpRights(piace->Mask, pwptr, plen);
4636 DumpString(&semicolon, 1, pwptr, plen);
4637 /* objects not supported */
4638 DumpString(&semicolon, 1, pwptr, plen);
4639 /* objects not supported */
4640 DumpString(&semicolon, 1, pwptr, plen);
4641 if (!DumpSid(&piace->SidStart, pwptr, plen))
4642 return FALSE;
4643 DumpString(&closebr, 1, pwptr, plen);
4644 return TRUE;
4647 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4649 WORD count;
4650 int i;
4652 if (protected)
4653 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4654 if (autoInheritReq)
4655 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4656 if (autoInherited)
4657 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4659 if (pacl == NULL)
4660 return TRUE;
4662 if (!IsValidAcl(pacl))
4663 return FALSE;
4665 count = pacl->AceCount;
4666 for (i = 0; i < count; i++)
4668 LPVOID ace;
4669 if (!GetAce(pacl, i, &ace))
4670 return FALSE;
4671 if (!DumpAce(ace, pwptr, plen))
4672 return FALSE;
4675 return TRUE;
4678 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4680 static const WCHAR prefix[] = {'O',':',0};
4681 BOOL bDefaulted;
4682 PSID psid;
4684 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4685 return FALSE;
4687 if (psid == NULL)
4688 return TRUE;
4690 DumpString(prefix, -1, pwptr, plen);
4691 if (!DumpSid(psid, pwptr, plen))
4692 return FALSE;
4693 return TRUE;
4696 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4698 static const WCHAR prefix[] = {'G',':',0};
4699 BOOL bDefaulted;
4700 PSID psid;
4702 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4703 return FALSE;
4705 if (psid == NULL)
4706 return TRUE;
4708 DumpString(prefix, -1, pwptr, plen);
4709 if (!DumpSid(psid, pwptr, plen))
4710 return FALSE;
4711 return TRUE;
4714 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4716 static const WCHAR dacl[] = {'D',':',0};
4717 SECURITY_DESCRIPTOR_CONTROL control;
4718 BOOL present, defaulted;
4719 DWORD revision;
4720 PACL pacl;
4722 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4723 return FALSE;
4725 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4726 return FALSE;
4728 if (!present)
4729 return TRUE;
4731 DumpString(dacl, 2, pwptr, plen);
4732 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4733 return FALSE;
4734 return TRUE;
4737 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4739 static const WCHAR sacl[] = {'S',':',0};
4740 SECURITY_DESCRIPTOR_CONTROL control;
4741 BOOL present, defaulted;
4742 DWORD revision;
4743 PACL pacl;
4745 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4746 return FALSE;
4748 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4749 return FALSE;
4751 if (!present)
4752 return TRUE;
4754 DumpString(sacl, 2, pwptr, plen);
4755 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4756 return FALSE;
4757 return TRUE;
4760 /******************************************************************************
4761 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4763 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4765 ULONG len;
4766 WCHAR *wptr, *wstr;
4768 if (SDRevision != SDDL_REVISION_1)
4770 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4771 SetLastError(ERROR_UNKNOWN_REVISION);
4772 return FALSE;
4775 len = 0;
4776 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4777 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4778 return FALSE;
4779 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4780 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4781 return FALSE;
4782 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4783 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4784 return FALSE;
4785 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4786 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4787 return FALSE;
4789 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4790 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4791 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4792 return FALSE;
4793 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4794 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4795 return FALSE;
4796 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4797 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4798 return FALSE;
4799 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4800 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4801 return FALSE;
4802 *wptr = 0;
4804 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4805 *OutputString = wstr;
4806 if (OutputLen)
4807 *OutputLen = strlenW(*OutputString)+1;
4808 return TRUE;
4811 /******************************************************************************
4812 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4814 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4816 LPWSTR wstr;
4817 ULONG len;
4818 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4820 int lenA;
4822 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4823 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4824 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4825 LocalFree(wstr);
4827 if (OutputLen != NULL)
4828 *OutputLen = lenA;
4829 return TRUE;
4831 else
4833 *OutputString = NULL;
4834 if (OutputLen)
4835 *OutputLen = 0;
4836 return FALSE;
4840 /******************************************************************************
4841 * ConvertStringSidToSidW [ADVAPI32.@]
4843 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4845 BOOL bret = FALSE;
4846 DWORD cBytes;
4848 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4849 if (GetVersion() & 0x80000000)
4850 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4851 else if (!StringSid || !Sid)
4852 SetLastError(ERROR_INVALID_PARAMETER);
4853 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4855 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4857 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4858 if (!bret)
4859 LocalFree(*Sid);
4861 return bret;
4864 /******************************************************************************
4865 * ConvertStringSidToSidA [ADVAPI32.@]
4867 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4869 BOOL bret = FALSE;
4871 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4872 if (GetVersion() & 0x80000000)
4873 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4874 else if (!StringSid || !Sid)
4875 SetLastError(ERROR_INVALID_PARAMETER);
4876 else
4878 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4879 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4880 len * sizeof(WCHAR));
4882 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4883 bret = ConvertStringSidToSidW(wStringSid, Sid);
4884 HeapFree(GetProcessHeap(), 0, wStringSid);
4886 return bret;
4889 /******************************************************************************
4890 * ConvertSidToStringSidW [ADVAPI32.@]
4892 * format of SID string is:
4893 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4894 * where
4895 * <rev> is the revision of the SID encoded as decimal
4896 * <auth> is the identifier authority encoded as hex
4897 * <subauthN> is the subauthority id encoded as decimal
4899 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4901 DWORD len = 0;
4902 LPWSTR wstr, wptr;
4904 TRACE("%p %p\n", pSid, pstr );
4906 len = 0;
4907 if (!DumpSidNumeric(pSid, NULL, &len))
4908 return FALSE;
4909 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4910 DumpSidNumeric(pSid, &wptr, NULL);
4911 *wptr = 0;
4913 *pstr = wstr;
4914 return TRUE;
4917 /******************************************************************************
4918 * ConvertSidToStringSidA [ADVAPI32.@]
4920 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4922 LPWSTR wstr = NULL;
4923 LPSTR str;
4924 UINT len;
4926 TRACE("%p %p\n", pSid, pstr );
4928 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4929 return FALSE;
4931 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4932 str = LocalAlloc( 0, len );
4933 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4934 LocalFree( wstr );
4936 *pstr = str;
4938 return TRUE;
4941 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4942 PSECURITY_DESCRIPTOR pdesc,
4943 PSECURITY_DESCRIPTOR cdesc,
4944 PSECURITY_DESCRIPTOR* ndesc,
4945 GUID* objtype,
4946 BOOL isdir,
4947 PGENERIC_MAPPING genmap )
4949 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4951 return FALSE;
4954 BOOL WINAPI CreatePrivateObjectSecurity(
4955 PSECURITY_DESCRIPTOR ParentDescriptor,
4956 PSECURITY_DESCRIPTOR CreatorDescriptor,
4957 PSECURITY_DESCRIPTOR* NewDescriptor,
4958 BOOL IsDirectoryObject,
4959 HANDLE Token,
4960 PGENERIC_MAPPING GenericMapping )
4962 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4963 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4965 return FALSE;
4968 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4970 FIXME("%p - stub\n", ObjectDescriptor);
4972 return TRUE;
4975 BOOL WINAPI CreateProcessAsUserA(
4976 HANDLE hToken,
4977 LPCSTR lpApplicationName,
4978 LPSTR lpCommandLine,
4979 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4980 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4981 BOOL bInheritHandles,
4982 DWORD dwCreationFlags,
4983 LPVOID lpEnvironment,
4984 LPCSTR lpCurrentDirectory,
4985 LPSTARTUPINFOA lpStartupInfo,
4986 LPPROCESS_INFORMATION lpProcessInformation )
4988 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4989 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4990 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4992 return FALSE;
4995 BOOL WINAPI CreateProcessAsUserW(
4996 HANDLE hToken,
4997 LPCWSTR lpApplicationName,
4998 LPWSTR lpCommandLine,
4999 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5000 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5001 BOOL bInheritHandles,
5002 DWORD dwCreationFlags,
5003 LPVOID lpEnvironment,
5004 LPCWSTR lpCurrentDirectory,
5005 LPSTARTUPINFOW lpStartupInfo,
5006 LPPROCESS_INFORMATION lpProcessInformation )
5008 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5009 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5010 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5011 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5013 /* We should create the process with a suspended main thread */
5014 if (!CreateProcessW (lpApplicationName,
5015 lpCommandLine,
5016 lpProcessAttributes,
5017 lpThreadAttributes,
5018 bInheritHandles,
5019 dwCreationFlags, /* CREATE_SUSPENDED */
5020 lpEnvironment,
5021 lpCurrentDirectory,
5022 lpStartupInfo,
5023 lpProcessInformation))
5025 return FALSE;
5028 return TRUE;
5031 /******************************************************************************
5032 * CreateProcessWithLogonW
5034 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5035 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5036 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5038 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5039 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5040 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5041 lpStartupInfo, lpProcessInformation);
5043 return FALSE;
5046 /******************************************************************************
5047 * DuplicateTokenEx [ADVAPI32.@]
5049 BOOL WINAPI DuplicateTokenEx(
5050 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5051 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5052 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5053 TOKEN_TYPE TokenType,
5054 PHANDLE DuplicateTokenHandle )
5056 OBJECT_ATTRIBUTES ObjectAttributes;
5058 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5059 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5061 InitializeObjectAttributes(
5062 &ObjectAttributes,
5063 NULL,
5064 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5065 NULL,
5066 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5068 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5069 dwDesiredAccess,
5070 &ObjectAttributes,
5071 ImpersonationLevel,
5072 TokenType,
5073 DuplicateTokenHandle ) );
5076 BOOL WINAPI DuplicateToken(
5077 HANDLE ExistingTokenHandle,
5078 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5079 PHANDLE DuplicateTokenHandle )
5081 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5082 NULL, ImpersonationLevel, TokenImpersonation,
5083 DuplicateTokenHandle );
5086 /******************************************************************************
5087 * ComputeStringSidSize
5089 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5091 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5093 int ctok = 0;
5094 while (*StringSid)
5096 if (*StringSid == '-')
5097 ctok++;
5098 StringSid++;
5101 if (ctok >= 3)
5102 return GetSidLengthRequired(ctok - 2);
5104 else /* String constant format - Only available in winxp and above */
5106 unsigned int i;
5108 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5109 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5110 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5113 return GetSidLengthRequired(0);
5116 /******************************************************************************
5117 * ParseStringSidToSid
5119 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5121 BOOL bret = FALSE;
5122 SID* pisid=pSid;
5124 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5125 if (!StringSid)
5127 SetLastError(ERROR_INVALID_PARAMETER);
5128 TRACE("StringSid is NULL, returning FALSE\n");
5129 return FALSE;
5132 while (*StringSid == ' ')
5133 StringSid++;
5135 *cBytes = ComputeStringSidSize(StringSid);
5136 if (!pisid) /* Simply compute the size */
5138 TRACE("only size requested, returning TRUE\n");
5139 return TRUE;
5142 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5144 DWORD i = 0, identAuth;
5145 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5147 StringSid += 2; /* Advance to Revision */
5148 pisid->Revision = atoiW(StringSid);
5150 if (pisid->Revision != SDDL_REVISION)
5152 TRACE("Revision %d is unknown\n", pisid->Revision);
5153 goto lend; /* ERROR_INVALID_SID */
5155 if (csubauth == 0)
5157 TRACE("SubAuthorityCount is 0\n");
5158 goto lend; /* ERROR_INVALID_SID */
5161 pisid->SubAuthorityCount = csubauth;
5163 /* Advance to identifier authority */
5164 while (*StringSid && *StringSid != '-')
5165 StringSid++;
5166 if (*StringSid == '-')
5167 StringSid++;
5169 /* MS' implementation can't handle values greater than 2^32 - 1, so
5170 * we don't either; assume most significant bytes are always 0
5172 pisid->IdentifierAuthority.Value[0] = 0;
5173 pisid->IdentifierAuthority.Value[1] = 0;
5174 identAuth = atoiW(StringSid);
5175 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5176 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5177 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5178 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5180 /* Advance to first sub authority */
5181 while (*StringSid && *StringSid != '-')
5182 StringSid++;
5183 if (*StringSid == '-')
5184 StringSid++;
5186 while (*StringSid)
5188 pisid->SubAuthority[i++] = atoiW(StringSid);
5190 while (*StringSid && *StringSid != '-')
5191 StringSid++;
5192 if (*StringSid == '-')
5193 StringSid++;
5196 if (i != pisid->SubAuthorityCount)
5197 goto lend; /* ERROR_INVALID_SID */
5199 bret = TRUE;
5201 else /* String constant format - Only available in winxp and above */
5203 unsigned int i;
5204 pisid->Revision = SDDL_REVISION;
5206 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5207 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5209 DWORD j;
5210 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5211 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5212 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5213 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5214 bret = TRUE;
5217 if (!bret)
5218 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5221 lend:
5222 if (!bret)
5223 SetLastError(ERROR_INVALID_SID);
5225 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5226 return bret;
5229 /******************************************************************************
5230 * GetNamedSecurityInfoA [ADVAPI32.@]
5232 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5233 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5234 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5235 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5237 DWORD len;
5238 LPWSTR wstr = NULL;
5239 DWORD r;
5241 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5242 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5244 if( pObjectName )
5246 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5247 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5248 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5251 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5252 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5254 HeapFree( GetProcessHeap(), 0, wstr );
5256 return r;
5259 /******************************************************************************
5260 * GetNamedSecurityInfoW [ADVAPI32.@]
5262 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5263 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5264 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5266 DWORD needed, offset;
5267 SECURITY_DESCRIPTOR_RELATIVE *relative;
5268 BYTE *buffer;
5270 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5271 group, dacl, sacl, descriptor );
5273 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5275 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5276 if (info & OWNER_SECURITY_INFORMATION)
5277 needed += sizeof(sidWorld);
5278 if (info & GROUP_SECURITY_INFORMATION)
5279 needed += sizeof(sidWorld);
5280 if (info & DACL_SECURITY_INFORMATION)
5281 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5282 if (info & SACL_SECURITY_INFORMATION)
5283 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5285 /* must be freed by caller */
5286 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5287 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5289 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5291 HeapFree( GetProcessHeap(), 0, *descriptor );
5292 return ERROR_INVALID_SECURITY_DESCR;
5295 relative = *descriptor;
5296 relative->Control |= SE_SELF_RELATIVE;
5297 buffer = (BYTE *)relative;
5298 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5300 if (info & OWNER_SECURITY_INFORMATION)
5302 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5303 relative->Owner = offset;
5304 if (owner)
5305 *owner = buffer + offset;
5306 offset += sizeof(sidWorld);
5308 if (info & GROUP_SECURITY_INFORMATION)
5310 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5311 relative->Group = offset;
5312 if (group)
5313 *group = buffer + offset;
5314 offset += sizeof(sidWorld);
5316 if (info & DACL_SECURITY_INFORMATION)
5318 relative->Control |= SE_DACL_PRESENT;
5319 GetWorldAccessACL( (PACL)(buffer + offset) );
5320 relative->Dacl = offset;
5321 if (dacl)
5322 *dacl = (PACL)(buffer + offset);
5323 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5325 if (info & SACL_SECURITY_INFORMATION)
5327 relative->Control |= SE_SACL_PRESENT;
5328 GetWorldAccessACL( (PACL)(buffer + offset) );
5329 relative->Sacl = offset;
5330 if (sacl)
5331 *sacl = (PACL)(buffer + offset);
5333 return ERROR_SUCCESS;
5336 /******************************************************************************
5337 * DecryptFileW [ADVAPI32.@]
5339 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5341 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5342 return TRUE;
5345 /******************************************************************************
5346 * DecryptFileA [ADVAPI32.@]
5348 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5350 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5351 return TRUE;
5354 /******************************************************************************
5355 * EncryptFileW [ADVAPI32.@]
5357 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5359 FIXME("%s\n", debugstr_w(lpFileName));
5360 return TRUE;
5363 /******************************************************************************
5364 * EncryptFileA [ADVAPI32.@]
5366 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5368 FIXME("%s\n", debugstr_a(lpFileName));
5369 return TRUE;
5372 /******************************************************************************
5373 * FileEncryptionStatusW [ADVAPI32.@]
5375 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5377 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5378 if (!lpStatus)
5379 return FALSE;
5380 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5381 return TRUE;
5384 /******************************************************************************
5385 * FileEncryptionStatusA [ADVAPI32.@]
5387 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5389 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5390 if (!lpStatus)
5391 return FALSE;
5392 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5393 return TRUE;
5396 /******************************************************************************
5397 * SetSecurityInfo [ADVAPI32.@]
5399 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5400 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5401 PSID psidGroup, PACL pDacl, PACL pSacl) {
5402 FIXME("stub\n");
5403 return ERROR_SUCCESS;
5406 /******************************************************************************
5407 * SaferCreateLevel [ADVAPI32.@]
5409 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5410 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5412 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5413 return FALSE;
5416 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5417 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5418 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5419 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5420 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5422 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5423 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5424 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5426 return ERROR_SUCCESS;
5429 /******************************************************************************
5430 * SaferGetPolicyInformation [ADVAPI32.@]
5432 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5433 PVOID buffer, PDWORD required, LPVOID lpReserved)
5435 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5436 return FALSE;