dpwsockx: Implementation of SPInit
[wine/gsoc_dplay.git] / dlls / advapi32 / security.c
blob9bb76d569ad9a21ca3d6f9ae6244305305fd685c
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 TokenHandle, PSID SidToCheck,
626 PBOOL IsMember )
628 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
630 *IsMember = TRUE;
631 return(TRUE);
634 /******************************************************************************
635 * GetTokenInformation [ADVAPI32.@]
637 * Get a type of information about an access token.
639 * PARAMS
640 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
641 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
642 * tokeninfo [O] Destination for token information
643 * tokeninfolength [I] Length of tokeninfo
644 * retlen [O] Destination for returned token information length
646 * RETURNS
647 * Success: TRUE. tokeninfo contains retlen bytes of token information
648 * Failure: FALSE.
650 * NOTES
651 * See NtQueryInformationToken.
653 BOOL WINAPI
654 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
655 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
657 TRACE("(%p, %s, %p, %d, %p):\n",
658 token,
659 (tokeninfoclass == TokenUser) ? "TokenUser" :
660 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
661 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
662 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
663 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
664 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
665 (tokeninfoclass == TokenSource) ? "TokenSource" :
666 (tokeninfoclass == TokenType) ? "TokenType" :
667 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
668 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
669 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
670 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
671 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
672 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
673 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
674 "Unknown",
675 tokeninfo, tokeninfolength, retlen);
676 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
677 tokeninfolength, retlen));
680 /******************************************************************************
681 * SetTokenInformation [ADVAPI32.@]
683 * Set information for an access token.
685 * PARAMS
686 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
687 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
688 * tokeninfo [I] Token information to set
689 * tokeninfolength [I] Length of tokeninfo
691 * RETURNS
692 * Success: TRUE. The information for the token is set to tokeninfo.
693 * Failure: FALSE.
695 BOOL WINAPI
696 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
697 LPVOID tokeninfo, DWORD tokeninfolength )
699 TRACE("(%p, %s, %p, %d): stub\n",
700 token,
701 (tokeninfoclass == TokenUser) ? "TokenUser" :
702 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
703 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
704 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
705 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
706 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
707 (tokeninfoclass == TokenSource) ? "TokenSource" :
708 (tokeninfoclass == TokenType) ? "TokenType" :
709 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
710 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
711 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
712 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
713 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
714 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
715 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
716 "Unknown",
717 tokeninfo, tokeninfolength);
719 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
722 /*************************************************************************
723 * SetThreadToken [ADVAPI32.@]
725 * Assigns an 'impersonation token' to a thread so it can assume the
726 * security privileges of another thread or process. Can also remove
727 * a previously assigned token.
729 * PARAMS
730 * thread [O] Handle to thread to set the token for
731 * token [I] Token to set
733 * RETURNS
734 * Success: TRUE. The threads access token is set to token
735 * Failure: FALSE.
737 * NOTES
738 * Only supported on NT or higher. On Win9X this function does nothing.
739 * See SetTokenInformation.
741 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
743 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
744 ThreadImpersonationToken, &token, sizeof token ));
747 /*************************************************************************
748 * CreateRestrictedToken [ADVAPI32.@]
750 * Create a new more restricted token from an existing token.
752 * PARAMS
753 * baseToken [I] Token to base the new restricted token on
754 * flags [I] Options
755 * nDisableSids [I] Length of disableSids array
756 * disableSids [I] Array of SIDs to disable in the new token
757 * nDeletePrivs [I] Length of deletePrivs array
758 * deletePrivs [I] Array of privileges to delete in the new token
759 * nRestrictSids [I] Length of restrictSids array
760 * restrictSids [I] Array of SIDs to restrict in the new token
761 * newToken [O] Address where the new token is stored
763 * RETURNS
764 * Success: TRUE
765 * Failure: FALSE
767 BOOL WINAPI CreateRestrictedToken(
768 HANDLE baseToken,
769 DWORD flags,
770 DWORD nDisableSids,
771 PSID_AND_ATTRIBUTES disableSids,
772 DWORD nDeletePrivs,
773 PLUID_AND_ATTRIBUTES deletePrivs,
774 DWORD nRestrictSids,
775 PSID_AND_ATTRIBUTES restrictSids,
776 PHANDLE newToken)
778 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
779 baseToken, flags, nDisableSids, disableSids,
780 nDeletePrivs, deletePrivs,
781 nRestrictSids, restrictSids,
782 newToken);
783 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
784 return FALSE;
787 /* ##############################
788 ###### SID FUNCTIONS ######
789 ##############################
792 /******************************************************************************
793 * AllocateAndInitializeSid [ADVAPI32.@]
795 * PARAMS
796 * pIdentifierAuthority []
797 * nSubAuthorityCount []
798 * nSubAuthority0 []
799 * nSubAuthority1 []
800 * nSubAuthority2 []
801 * nSubAuthority3 []
802 * nSubAuthority4 []
803 * nSubAuthority5 []
804 * nSubAuthority6 []
805 * nSubAuthority7 []
806 * pSid []
808 BOOL WINAPI
809 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
810 BYTE nSubAuthorityCount,
811 DWORD nSubAuthority0, DWORD nSubAuthority1,
812 DWORD nSubAuthority2, DWORD nSubAuthority3,
813 DWORD nSubAuthority4, DWORD nSubAuthority5,
814 DWORD nSubAuthority6, DWORD nSubAuthority7,
815 PSID *pSid )
817 return set_ntstatus( RtlAllocateAndInitializeSid(
818 pIdentifierAuthority, nSubAuthorityCount,
819 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
820 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
821 pSid ));
824 /******************************************************************************
825 * FreeSid [ADVAPI32.@]
827 * PARAMS
828 * pSid []
830 PVOID WINAPI
831 FreeSid( PSID pSid )
833 RtlFreeSid(pSid);
834 return NULL; /* is documented like this */
837 /******************************************************************************
838 * CopySid [ADVAPI32.@]
840 * PARAMS
841 * nDestinationSidLength []
842 * pDestinationSid []
843 * pSourceSid []
845 BOOL WINAPI
846 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
848 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
851 /******************************************************************************
852 * CreateWellKnownSid [ADVAPI32.@]
854 BOOL WINAPI
855 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
856 PSID DomainSid,
857 PSID pSid,
858 DWORD* cbSid)
860 unsigned int i;
861 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
863 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
865 SetLastError(ERROR_INVALID_PARAMETER);
866 return FALSE;
869 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
870 if (WellKnownSids[i].Type == WellKnownSidType) {
871 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
873 if (*cbSid < length)
875 *cbSid = length;
876 SetLastError(ERROR_INSUFFICIENT_BUFFER);
877 return FALSE;
879 if (!pSid)
881 SetLastError(ERROR_INVALID_PARAMETER);
882 return FALSE;
884 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
885 *cbSid = length;
886 return TRUE;
890 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
892 SetLastError(ERROR_INVALID_PARAMETER);
893 return FALSE;
896 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
897 if (WellKnownRids[i].Type == WellKnownSidType) {
898 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
899 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
900 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
902 if (*cbSid < output_sid_length)
904 *cbSid = output_sid_length;
905 SetLastError(ERROR_INSUFFICIENT_BUFFER);
906 return FALSE;
908 if (!pSid)
910 SetLastError(ERROR_INVALID_PARAMETER);
911 return FALSE;
913 CopyMemory(pSid, DomainSid, domain_sid_length);
914 (*GetSidSubAuthorityCount(pSid))++;
915 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
916 *cbSid = output_sid_length;
917 return TRUE;
920 SetLastError(ERROR_INVALID_PARAMETER);
921 return FALSE;
924 /******************************************************************************
925 * IsWellKnownSid [ADVAPI32.@]
927 BOOL WINAPI
928 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
930 unsigned int i;
931 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
933 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
934 if (WellKnownSids[i].Type == WellKnownSidType)
935 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
936 return TRUE;
938 return FALSE;
941 BOOL WINAPI
942 IsTokenRestricted( HANDLE TokenHandle )
944 TOKEN_GROUPS *groups;
945 DWORD size;
946 NTSTATUS status;
947 BOOL restricted;
949 TRACE("(%p)\n", TokenHandle);
951 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
952 if (status != STATUS_BUFFER_TOO_SMALL)
953 return FALSE;
955 groups = HeapAlloc(GetProcessHeap(), 0, size);
956 if (!groups)
958 SetLastError(ERROR_OUTOFMEMORY);
959 return FALSE;
962 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
963 if (status != STATUS_SUCCESS)
965 HeapFree(GetProcessHeap(), 0, groups);
966 return set_ntstatus(status);
969 if (groups->GroupCount)
970 restricted = TRUE;
971 else
972 restricted = FALSE;
974 HeapFree(GetProcessHeap(), 0, groups);
976 return restricted;
979 /******************************************************************************
980 * IsValidSid [ADVAPI32.@]
982 * PARAMS
983 * pSid []
985 BOOL WINAPI
986 IsValidSid( PSID pSid )
988 return RtlValidSid( pSid );
991 /******************************************************************************
992 * EqualSid [ADVAPI32.@]
994 * PARAMS
995 * pSid1 []
996 * pSid2 []
998 BOOL WINAPI
999 EqualSid( PSID pSid1, PSID pSid2 )
1001 return RtlEqualSid( pSid1, pSid2 );
1004 /******************************************************************************
1005 * EqualPrefixSid [ADVAPI32.@]
1007 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1009 return RtlEqualPrefixSid(pSid1, pSid2);
1012 /******************************************************************************
1013 * GetSidLengthRequired [ADVAPI32.@]
1015 * PARAMS
1016 * nSubAuthorityCount []
1018 DWORD WINAPI
1019 GetSidLengthRequired( BYTE nSubAuthorityCount )
1021 return RtlLengthRequiredSid(nSubAuthorityCount);
1024 /******************************************************************************
1025 * InitializeSid [ADVAPI32.@]
1027 * PARAMS
1028 * pIdentifierAuthority []
1030 BOOL WINAPI
1031 InitializeSid (
1032 PSID pSid,
1033 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1034 BYTE nSubAuthorityCount)
1036 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1039 DWORD WINAPI
1040 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1042 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1044 return 1;
1047 DWORD WINAPI
1048 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1050 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1052 return 1;
1055 /******************************************************************************
1056 * GetSidIdentifierAuthority [ADVAPI32.@]
1058 * PARAMS
1059 * pSid []
1061 PSID_IDENTIFIER_AUTHORITY WINAPI
1062 GetSidIdentifierAuthority( PSID pSid )
1064 return RtlIdentifierAuthoritySid(pSid);
1067 /******************************************************************************
1068 * GetSidSubAuthority [ADVAPI32.@]
1070 * PARAMS
1071 * pSid []
1072 * nSubAuthority []
1074 PDWORD WINAPI
1075 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1077 SetLastError(ERROR_SUCCESS);
1078 return RtlSubAuthoritySid(pSid, nSubAuthority);
1081 /******************************************************************************
1082 * GetSidSubAuthorityCount [ADVAPI32.@]
1084 * PARAMS
1085 * pSid []
1087 PUCHAR WINAPI
1088 GetSidSubAuthorityCount (PSID pSid)
1090 SetLastError(ERROR_SUCCESS);
1091 return RtlSubAuthorityCountSid(pSid);
1094 /******************************************************************************
1095 * GetLengthSid [ADVAPI32.@]
1097 * PARAMS
1098 * pSid []
1100 DWORD WINAPI
1101 GetLengthSid (PSID pSid)
1103 return RtlLengthSid(pSid);
1106 /* ##############################################
1107 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1108 ##############################################
1111 /******************************************************************************
1112 * BuildSecurityDescriptorA [ADVAPI32.@]
1114 * Builds a SD from
1116 * PARAMS
1117 * pOwner [I]
1118 * pGroup [I]
1119 * cCountOfAccessEntries [I]
1120 * pListOfAccessEntries [I]
1121 * cCountOfAuditEntries [I]
1122 * pListofAuditEntries [I]
1123 * pOldSD [I]
1124 * lpdwBufferLength [I/O]
1125 * pNewSD [O]
1127 * RETURNS
1128 * Success: ERROR_SUCCESS
1129 * Failure: nonzero error code from Winerror.h
1131 DWORD WINAPI BuildSecurityDescriptorA(
1132 IN PTRUSTEEA pOwner,
1133 IN PTRUSTEEA pGroup,
1134 IN ULONG cCountOfAccessEntries,
1135 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1136 IN ULONG cCountOfAuditEntries,
1137 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1138 IN PSECURITY_DESCRIPTOR pOldSD,
1139 IN OUT PULONG lpdwBufferLength,
1140 OUT PSECURITY_DESCRIPTOR* pNewSD)
1142 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1146 return ERROR_CALL_NOT_IMPLEMENTED;
1149 /******************************************************************************
1150 * BuildSecurityDescriptorW [ADVAPI32.@]
1152 * See BuildSecurityDescriptorA.
1154 DWORD WINAPI BuildSecurityDescriptorW(
1155 IN PTRUSTEEW pOwner,
1156 IN PTRUSTEEW pGroup,
1157 IN ULONG cCountOfAccessEntries,
1158 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1159 IN ULONG cCountOfAuditEntries,
1160 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1161 IN PSECURITY_DESCRIPTOR pOldSD,
1162 IN OUT PULONG lpdwBufferLength,
1163 OUT PSECURITY_DESCRIPTOR* pNewSD)
1165 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1166 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1167 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1169 return ERROR_CALL_NOT_IMPLEMENTED;
1172 /******************************************************************************
1173 * InitializeSecurityDescriptor [ADVAPI32.@]
1175 * PARAMS
1176 * pDescr []
1177 * revision []
1179 BOOL WINAPI
1180 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1182 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1186 /******************************************************************************
1187 * MakeAbsoluteSD [ADVAPI32.@]
1189 BOOL WINAPI MakeAbsoluteSD (
1190 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1191 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1192 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1193 OUT PACL pDacl,
1194 OUT LPDWORD lpdwDaclSize,
1195 OUT PACL pSacl,
1196 OUT LPDWORD lpdwSaclSize,
1197 OUT PSID pOwner,
1198 OUT LPDWORD lpdwOwnerSize,
1199 OUT PSID pPrimaryGroup,
1200 OUT LPDWORD lpdwPrimaryGroupSize)
1202 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1203 pAbsoluteSecurityDescriptor,
1204 lpdwAbsoluteSecurityDescriptorSize,
1205 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1206 pOwner, lpdwOwnerSize,
1207 pPrimaryGroup, lpdwPrimaryGroupSize));
1210 /******************************************************************************
1211 * GetKernelObjectSecurity [ADVAPI32.@]
1213 BOOL WINAPI GetKernelObjectSecurity(
1214 HANDLE Handle,
1215 SECURITY_INFORMATION RequestedInformation,
1216 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1217 DWORD nLength,
1218 LPDWORD lpnLengthNeeded )
1220 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1221 pSecurityDescriptor, nLength, lpnLengthNeeded);
1223 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1224 nLength, lpnLengthNeeded ));
1227 /******************************************************************************
1228 * GetPrivateObjectSecurity [ADVAPI32.@]
1230 BOOL WINAPI GetPrivateObjectSecurity(
1231 PSECURITY_DESCRIPTOR ObjectDescriptor,
1232 SECURITY_INFORMATION SecurityInformation,
1233 PSECURITY_DESCRIPTOR ResultantDescriptor,
1234 DWORD DescriptorLength,
1235 PDWORD ReturnLength )
1237 SECURITY_DESCRIPTOR desc;
1238 BOOL defaulted, present;
1239 PACL pacl;
1240 PSID psid;
1242 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1243 ResultantDescriptor, DescriptorLength, ReturnLength);
1245 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1246 return FALSE;
1248 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1250 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1251 return FALSE;
1252 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1255 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1257 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1258 return FALSE;
1259 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1262 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1264 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1265 return FALSE;
1266 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1269 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1271 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1272 return FALSE;
1273 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1276 *ReturnLength = DescriptorLength;
1277 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1280 /******************************************************************************
1281 * GetSecurityDescriptorLength [ADVAPI32.@]
1283 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1285 return RtlLengthSecurityDescriptor(pDescr);
1288 /******************************************************************************
1289 * GetSecurityDescriptorOwner [ADVAPI32.@]
1291 * PARAMS
1292 * pOwner []
1293 * lpbOwnerDefaulted []
1295 BOOL WINAPI
1296 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1297 LPBOOL lpbOwnerDefaulted )
1299 BOOLEAN defaulted;
1300 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1301 *lpbOwnerDefaulted = defaulted;
1302 return ret;
1305 /******************************************************************************
1306 * SetSecurityDescriptorOwner [ADVAPI32.@]
1308 * PARAMS
1310 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1311 PSID pOwner, BOOL bOwnerDefaulted)
1313 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1315 /******************************************************************************
1316 * GetSecurityDescriptorGroup [ADVAPI32.@]
1318 BOOL WINAPI GetSecurityDescriptorGroup(
1319 PSECURITY_DESCRIPTOR SecurityDescriptor,
1320 PSID *Group,
1321 LPBOOL GroupDefaulted)
1323 BOOLEAN defaulted;
1324 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1325 *GroupDefaulted = defaulted;
1326 return ret;
1328 /******************************************************************************
1329 * SetSecurityDescriptorGroup [ADVAPI32.@]
1331 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1332 PSID Group, BOOL GroupDefaulted)
1334 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1337 /******************************************************************************
1338 * IsValidSecurityDescriptor [ADVAPI32.@]
1340 * PARAMS
1341 * lpsecdesc []
1343 BOOL WINAPI
1344 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1346 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1349 /******************************************************************************
1350 * GetSecurityDescriptorDacl [ADVAPI32.@]
1352 BOOL WINAPI GetSecurityDescriptorDacl(
1353 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1354 OUT LPBOOL lpbDaclPresent,
1355 OUT PACL *pDacl,
1356 OUT LPBOOL lpbDaclDefaulted)
1358 BOOLEAN present, defaulted;
1359 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1360 *lpbDaclPresent = present;
1361 *lpbDaclDefaulted = defaulted;
1362 return ret;
1365 /******************************************************************************
1366 * SetSecurityDescriptorDacl [ADVAPI32.@]
1368 BOOL WINAPI
1369 SetSecurityDescriptorDacl (
1370 PSECURITY_DESCRIPTOR lpsd,
1371 BOOL daclpresent,
1372 PACL dacl,
1373 BOOL dacldefaulted )
1375 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1377 /******************************************************************************
1378 * GetSecurityDescriptorSacl [ADVAPI32.@]
1380 BOOL WINAPI GetSecurityDescriptorSacl(
1381 IN PSECURITY_DESCRIPTOR lpsd,
1382 OUT LPBOOL lpbSaclPresent,
1383 OUT PACL *pSacl,
1384 OUT LPBOOL lpbSaclDefaulted)
1386 BOOLEAN present, defaulted;
1387 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1388 *lpbSaclPresent = present;
1389 *lpbSaclDefaulted = defaulted;
1390 return ret;
1393 /**************************************************************************
1394 * SetSecurityDescriptorSacl [ADVAPI32.@]
1396 BOOL WINAPI SetSecurityDescriptorSacl (
1397 PSECURITY_DESCRIPTOR lpsd,
1398 BOOL saclpresent,
1399 PACL lpsacl,
1400 BOOL sacldefaulted)
1402 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1404 /******************************************************************************
1405 * MakeSelfRelativeSD [ADVAPI32.@]
1407 * PARAMS
1408 * lpabssecdesc []
1409 * lpselfsecdesc []
1410 * lpbuflen []
1412 BOOL WINAPI
1413 MakeSelfRelativeSD(
1414 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1415 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1416 IN OUT LPDWORD lpdwBufferLength)
1418 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1419 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1422 /******************************************************************************
1423 * GetSecurityDescriptorControl [ADVAPI32.@]
1426 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1427 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1429 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1432 /******************************************************************************
1433 * SetSecurityDescriptorControl [ADVAPI32.@]
1435 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1436 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1437 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1439 return set_ntstatus( RtlSetControlSecurityDescriptor(
1440 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1443 /* ##############################
1444 ###### ACL FUNCTIONS ######
1445 ##############################
1448 /*************************************************************************
1449 * InitializeAcl [ADVAPI32.@]
1451 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1453 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1456 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1458 IO_STATUS_BLOCK io_block;
1460 TRACE("(%p)\n", hNamedPipe);
1462 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1463 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1466 /******************************************************************************
1467 * AddAccessAllowedAce [ADVAPI32.@]
1469 BOOL WINAPI AddAccessAllowedAce(
1470 IN OUT PACL pAcl,
1471 IN DWORD dwAceRevision,
1472 IN DWORD AccessMask,
1473 IN PSID pSid)
1475 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1478 /******************************************************************************
1479 * AddAccessAllowedAceEx [ADVAPI32.@]
1481 BOOL WINAPI AddAccessAllowedAceEx(
1482 IN OUT PACL pAcl,
1483 IN DWORD dwAceRevision,
1484 IN DWORD AceFlags,
1485 IN DWORD AccessMask,
1486 IN PSID pSid)
1488 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1491 /******************************************************************************
1492 * AddAccessDeniedAce [ADVAPI32.@]
1494 BOOL WINAPI AddAccessDeniedAce(
1495 IN OUT PACL pAcl,
1496 IN DWORD dwAceRevision,
1497 IN DWORD AccessMask,
1498 IN PSID pSid)
1500 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1503 /******************************************************************************
1504 * AddAccessDeniedAceEx [ADVAPI32.@]
1506 BOOL WINAPI AddAccessDeniedAceEx(
1507 IN OUT PACL pAcl,
1508 IN DWORD dwAceRevision,
1509 IN DWORD AceFlags,
1510 IN DWORD AccessMask,
1511 IN PSID pSid)
1513 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1516 /******************************************************************************
1517 * AddAce [ADVAPI32.@]
1519 BOOL WINAPI AddAce(
1520 IN OUT PACL pAcl,
1521 IN DWORD dwAceRevision,
1522 IN DWORD dwStartingAceIndex,
1523 LPVOID pAceList,
1524 DWORD nAceListLength)
1526 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1529 /******************************************************************************
1530 * DeleteAce [ADVAPI32.@]
1532 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1534 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1537 /******************************************************************************
1538 * FindFirstFreeAce [ADVAPI32.@]
1540 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1542 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1545 /******************************************************************************
1546 * GetAce [ADVAPI32.@]
1548 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1550 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1553 /******************************************************************************
1554 * GetAclInformation [ADVAPI32.@]
1556 BOOL WINAPI GetAclInformation(
1557 PACL pAcl,
1558 LPVOID pAclInformation,
1559 DWORD nAclInformationLength,
1560 ACL_INFORMATION_CLASS dwAclInformationClass)
1562 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1563 nAclInformationLength, dwAclInformationClass));
1566 /******************************************************************************
1567 * IsValidAcl [ADVAPI32.@]
1569 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1571 return RtlValidAcl(pAcl);
1574 /* ##############################
1575 ###### MISC FUNCTIONS ######
1576 ##############################
1579 /******************************************************************************
1580 * AllocateLocallyUniqueId [ADVAPI32.@]
1582 * PARAMS
1583 * lpLuid []
1585 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1587 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1590 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1591 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1593 { '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 };
1594 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1595 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1597 { '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 };
1598 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1599 { '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 };
1600 static const WCHAR SE_TCB_NAME_W[] =
1601 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_SECURITY_NAME_W[] =
1603 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1605 { '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 };
1606 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1607 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1609 { '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 };
1610 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1611 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1613 { '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 };
1614 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1615 { '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 };
1616 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1617 { '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 };
1618 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1619 { '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 };
1620 static const WCHAR SE_BACKUP_NAME_W[] =
1621 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_RESTORE_NAME_W[] =
1623 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1625 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1626 static const WCHAR SE_DEBUG_NAME_W[] =
1627 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_AUDIT_NAME_W[] =
1629 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1631 { '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 };
1632 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1633 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1634 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1635 { '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 };
1636 static const WCHAR SE_UNDOCK_NAME_W[] =
1637 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1638 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1639 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1640 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1641 { '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 };
1642 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1643 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1644 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1645 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1647 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1649 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1651 NULL,
1652 NULL,
1653 SE_CREATE_TOKEN_NAME_W,
1654 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1655 SE_LOCK_MEMORY_NAME_W,
1656 SE_INCREASE_QUOTA_NAME_W,
1657 SE_MACHINE_ACCOUNT_NAME_W,
1658 SE_TCB_NAME_W,
1659 SE_SECURITY_NAME_W,
1660 SE_TAKE_OWNERSHIP_NAME_W,
1661 SE_LOAD_DRIVER_NAME_W,
1662 SE_SYSTEM_PROFILE_NAME_W,
1663 SE_SYSTEMTIME_NAME_W,
1664 SE_PROF_SINGLE_PROCESS_NAME_W,
1665 SE_INC_BASE_PRIORITY_NAME_W,
1666 SE_CREATE_PAGEFILE_NAME_W,
1667 SE_CREATE_PERMANENT_NAME_W,
1668 SE_BACKUP_NAME_W,
1669 SE_RESTORE_NAME_W,
1670 SE_SHUTDOWN_NAME_W,
1671 SE_DEBUG_NAME_W,
1672 SE_AUDIT_NAME_W,
1673 SE_SYSTEM_ENVIRONMENT_NAME_W,
1674 SE_CHANGE_NOTIFY_NAME_W,
1675 SE_REMOTE_SHUTDOWN_NAME_W,
1676 SE_UNDOCK_NAME_W,
1677 SE_SYNC_AGENT_NAME_W,
1678 SE_ENABLE_DELEGATION_NAME_W,
1679 SE_MANAGE_VOLUME_NAME_W,
1680 SE_IMPERSONATE_NAME_W,
1681 SE_CREATE_GLOBAL_NAME_W,
1684 /******************************************************************************
1685 * LookupPrivilegeValueW [ADVAPI32.@]
1687 * See LookupPrivilegeValueA.
1689 BOOL WINAPI
1690 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1692 UINT i;
1694 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1696 if (!ADVAPI_IsLocalComputer(lpSystemName))
1698 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1699 return FALSE;
1701 if (!lpName)
1703 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1704 return FALSE;
1706 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1708 if( !WellKnownPrivNames[i] )
1709 continue;
1710 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1711 continue;
1712 lpLuid->LowPart = i;
1713 lpLuid->HighPart = 0;
1714 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1715 lpLuid->HighPart, lpLuid->LowPart );
1716 return TRUE;
1718 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1719 return FALSE;
1722 /******************************************************************************
1723 * LookupPrivilegeValueA [ADVAPI32.@]
1725 * Retrieves LUID used on a system to represent the privilege name.
1727 * PARAMS
1728 * lpSystemName [I] Name of the system
1729 * lpName [I] Name of the privilege
1730 * lpLuid [O] Destination for the resulting LUID
1732 * RETURNS
1733 * Success: TRUE. lpLuid contains the requested LUID.
1734 * Failure: FALSE.
1736 BOOL WINAPI
1737 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1739 UNICODE_STRING lpSystemNameW;
1740 UNICODE_STRING lpNameW;
1741 BOOL ret;
1743 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1744 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1745 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1746 RtlFreeUnicodeString(&lpNameW);
1747 RtlFreeUnicodeString(&lpSystemNameW);
1748 return ret;
1751 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1752 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1754 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1755 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1757 return FALSE;
1760 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1761 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1763 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1764 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1766 return FALSE;
1769 /******************************************************************************
1770 * LookupPrivilegeNameA [ADVAPI32.@]
1772 * See LookupPrivilegeNameW.
1774 BOOL WINAPI
1775 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1776 LPDWORD cchName)
1778 UNICODE_STRING lpSystemNameW;
1779 BOOL ret;
1780 DWORD wLen = 0;
1782 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1784 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1785 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1786 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1788 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1790 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1791 &wLen);
1792 if (ret)
1794 /* Windows crashes if cchName is NULL, so will I */
1795 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1796 *cchName, NULL, NULL);
1798 if (len == 0)
1800 /* WideCharToMultiByte failed */
1801 ret = FALSE;
1803 else if (len > *cchName)
1805 *cchName = len;
1806 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1807 ret = FALSE;
1809 else
1811 /* WideCharToMultiByte succeeded, output length needs to be
1812 * length not including NULL terminator
1814 *cchName = len - 1;
1817 HeapFree(GetProcessHeap(), 0, lpNameW);
1819 RtlFreeUnicodeString(&lpSystemNameW);
1820 return ret;
1823 /******************************************************************************
1824 * LookupPrivilegeNameW [ADVAPI32.@]
1826 * Retrieves the privilege name referred to by the LUID lpLuid.
1828 * PARAMS
1829 * lpSystemName [I] Name of the system
1830 * lpLuid [I] Privilege value
1831 * lpName [O] Name of the privilege
1832 * cchName [I/O] Number of characters in lpName.
1834 * RETURNS
1835 * Success: TRUE. lpName contains the name of the privilege whose value is
1836 * *lpLuid.
1837 * Failure: FALSE.
1839 * REMARKS
1840 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1841 * using this function.
1842 * If the length of lpName is too small, on return *cchName will contain the
1843 * number of WCHARs needed to contain the privilege, including the NULL
1844 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1845 * On success, *cchName will contain the number of characters stored in
1846 * lpName, NOT including the NULL terminator.
1848 BOOL WINAPI
1849 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1850 LPDWORD cchName)
1852 size_t privNameLen;
1854 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1856 if (!ADVAPI_IsLocalComputer(lpSystemName))
1858 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1859 return FALSE;
1861 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1862 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1864 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1865 return FALSE;
1867 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1868 /* Windows crashes if cchName is NULL, so will I */
1869 if (*cchName <= privNameLen)
1871 *cchName = privNameLen + 1;
1872 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1873 return FALSE;
1875 else
1877 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1878 *cchName = privNameLen;
1879 return TRUE;
1883 /******************************************************************************
1884 * GetFileSecurityA [ADVAPI32.@]
1886 * Obtains Specified information about the security of a file or directory.
1888 * PARAMS
1889 * lpFileName [I] Name of the file to get info for
1890 * RequestedInformation [I] SE_ flags from "winnt.h"
1891 * pSecurityDescriptor [O] Destination for security information
1892 * nLength [I] Length of pSecurityDescriptor
1893 * lpnLengthNeeded [O] Destination for length of returned security information
1895 * RETURNS
1896 * Success: TRUE. pSecurityDescriptor contains the requested information.
1897 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1899 * NOTES
1900 * The information returned is constrained by the callers access rights and
1901 * privileges.
1903 BOOL WINAPI
1904 GetFileSecurityA( LPCSTR lpFileName,
1905 SECURITY_INFORMATION RequestedInformation,
1906 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1907 DWORD nLength, LPDWORD lpnLengthNeeded )
1909 DWORD len;
1910 BOOL r;
1911 LPWSTR name = NULL;
1913 if( lpFileName )
1915 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1916 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1917 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1920 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1921 nLength, lpnLengthNeeded );
1922 HeapFree( GetProcessHeap(), 0, name );
1924 return r;
1927 /******************************************************************************
1928 * GetFileSecurityW [ADVAPI32.@]
1930 * See GetFileSecurityA.
1932 BOOL WINAPI
1933 GetFileSecurityW( LPCWSTR lpFileName,
1934 SECURITY_INFORMATION RequestedInformation,
1935 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936 DWORD nLength, LPDWORD lpnLengthNeeded )
1938 HANDLE hfile;
1939 NTSTATUS status;
1940 DWORD access = 0;
1942 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1943 RequestedInformation, pSecurityDescriptor,
1944 nLength, lpnLengthNeeded);
1946 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1947 DACL_SECURITY_INFORMATION))
1948 access |= READ_CONTROL;
1949 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1950 access |= ACCESS_SYSTEM_SECURITY;
1952 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1953 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1954 if ( hfile == INVALID_HANDLE_VALUE )
1955 return FALSE;
1957 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1958 nLength, lpnLengthNeeded );
1959 CloseHandle( hfile );
1960 return set_ntstatus( status );
1964 /******************************************************************************
1965 * LookupAccountSidA [ADVAPI32.@]
1967 BOOL WINAPI
1968 LookupAccountSidA(
1969 IN LPCSTR system,
1970 IN PSID sid,
1971 OUT LPSTR account,
1972 IN OUT LPDWORD accountSize,
1973 OUT LPSTR domain,
1974 IN OUT LPDWORD domainSize,
1975 OUT PSID_NAME_USE name_use )
1977 DWORD len;
1978 BOOL r;
1979 LPWSTR systemW = NULL;
1980 LPWSTR accountW = NULL;
1981 LPWSTR domainW = NULL;
1982 DWORD accountSizeW = *accountSize;
1983 DWORD domainSizeW = *domainSize;
1985 if (system) {
1986 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1987 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1988 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1990 if (account)
1991 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1992 if (domain)
1993 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1995 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1997 if (r) {
1998 if (accountW && *accountSize) {
1999 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2000 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2001 *accountSize = len;
2002 } else
2003 *accountSize = accountSizeW + 1;
2005 if (domainW && *domainSize) {
2006 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2007 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2008 *domainSize = len;
2009 } else
2010 *domainSize = domainSizeW + 1;
2013 HeapFree( GetProcessHeap(), 0, systemW );
2014 HeapFree( GetProcessHeap(), 0, accountW );
2015 HeapFree( GetProcessHeap(), 0, domainW );
2017 return r;
2020 /******************************************************************************
2021 * LookupAccountSidW [ADVAPI32.@]
2023 * PARAMS
2024 * system []
2025 * sid []
2026 * account []
2027 * accountSize []
2028 * domain []
2029 * domainSize []
2030 * name_use []
2033 BOOL WINAPI
2034 LookupAccountSidW(
2035 IN LPCWSTR system,
2036 IN PSID sid,
2037 OUT LPWSTR account,
2038 IN OUT LPDWORD accountSize,
2039 OUT LPWSTR domain,
2040 IN OUT LPDWORD domainSize,
2041 OUT PSID_NAME_USE name_use )
2043 unsigned int i, j;
2044 const WCHAR * ac = NULL;
2045 const WCHAR * dm = NULL;
2046 SID_NAME_USE use = 0;
2047 LPWSTR computer_name = NULL;
2048 LPWSTR account_name = NULL;
2050 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2051 debugstr_w(system),debugstr_sid(sid),
2052 account,accountSize,accountSize?*accountSize:0,
2053 domain,domainSize,domainSize?*domainSize:0,
2054 name_use);
2056 if (!ADVAPI_IsLocalComputer(system)) {
2057 FIXME("Only local computer supported!\n");
2058 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2059 return FALSE;
2062 /* check the well known SIDs first */
2063 for (i = 0; i <= 60; i++) {
2064 if (IsWellKnownSid(sid, i)) {
2065 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2066 if (ACCOUNT_SIDS[j].type == i) {
2067 ac = ACCOUNT_SIDS[j].account;
2068 dm = ACCOUNT_SIDS[j].domain;
2069 use = ACCOUNT_SIDS[j].name_use;
2072 break;
2076 if (dm == NULL) {
2077 MAX_SID local;
2079 /* check for the local computer next */
2080 if (ADVAPI_GetComputerSid(&local)) {
2081 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2082 BOOL result;
2084 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2085 result = GetComputerNameW(computer_name, &size);
2087 if (result) {
2088 if (EqualSid(sid, &local)) {
2089 dm = computer_name;
2090 ac = Blank;
2091 use = 3;
2092 } else {
2093 local.SubAuthorityCount++;
2095 if (EqualPrefixSid(sid, &local)) {
2096 dm = computer_name;
2097 use = 1;
2098 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2099 case DOMAIN_USER_RID_ADMIN:
2100 ac = Administrator;
2101 break;
2102 case DOMAIN_USER_RID_GUEST:
2103 ac = Guest;
2104 break;
2105 case DOMAIN_GROUP_RID_ADMINS:
2106 ac = Domain_Admins;
2107 break;
2108 case DOMAIN_GROUP_RID_USERS:
2109 ac = Domain_Users;
2110 break;
2111 case DOMAIN_GROUP_RID_GUESTS:
2112 ac = Domain_Guests;
2113 break;
2114 case DOMAIN_GROUP_RID_COMPUTERS:
2115 ac = Domain_Computers;
2116 break;
2117 case DOMAIN_GROUP_RID_CONTROLLERS:
2118 ac = Domain_Controllers;
2119 break;
2120 case DOMAIN_GROUP_RID_CERT_ADMINS:
2121 ac = Cert_Publishers;
2122 break;
2123 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2124 ac = Schema_Admins;
2125 break;
2126 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2127 ac = Enterprise_Admins;
2128 break;
2129 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2130 ac = Group_Policy_Creator_Owners;
2131 break;
2132 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2133 ac = RAS_and_IAS_Servers;
2134 break;
2135 case 1000: /* first user account */
2136 size = UNLEN + 1;
2137 account_name = HeapAlloc(
2138 GetProcessHeap(), 0, size * sizeof(WCHAR));
2139 if (GetUserNameW(account_name, &size))
2140 ac = account_name;
2141 else
2142 dm = NULL;
2144 break;
2145 default:
2146 dm = NULL;
2147 break;
2155 if (dm) {
2156 DWORD ac_len = lstrlenW(ac);
2157 DWORD dm_len = lstrlenW(dm);
2158 BOOL status = TRUE;
2160 if (*accountSize > ac_len) {
2161 if (account)
2162 lstrcpyW(account, ac);
2164 if (*domainSize > dm_len) {
2165 if (domain)
2166 lstrcpyW(domain, dm);
2168 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2169 ((*domainSize != 0) && (*domainSize < dm_len))) {
2170 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2171 status = FALSE;
2173 if (*domainSize)
2174 *domainSize = dm_len;
2175 else
2176 *domainSize = dm_len + 1;
2177 if (*accountSize)
2178 *accountSize = ac_len;
2179 else
2180 *accountSize = ac_len + 1;
2181 *name_use = use;
2182 HeapFree(GetProcessHeap(), 0, account_name);
2183 HeapFree(GetProcessHeap(), 0, computer_name);
2184 return status;
2187 HeapFree(GetProcessHeap(), 0, account_name);
2188 HeapFree(GetProcessHeap(), 0, computer_name);
2189 SetLastError(ERROR_NONE_MAPPED);
2190 return FALSE;
2193 /******************************************************************************
2194 * SetFileSecurityA [ADVAPI32.@]
2196 * See SetFileSecurityW.
2198 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2199 SECURITY_INFORMATION RequestedInformation,
2200 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2202 DWORD len;
2203 BOOL r;
2204 LPWSTR name = NULL;
2206 if( lpFileName )
2208 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2209 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2210 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2213 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2214 HeapFree( GetProcessHeap(), 0, name );
2216 return r;
2219 /******************************************************************************
2220 * SetFileSecurityW [ADVAPI32.@]
2222 * Sets the security of a file or directory.
2224 * PARAMS
2225 * lpFileName []
2226 * RequestedInformation []
2227 * pSecurityDescriptor []
2229 * RETURNS
2230 * Success: TRUE.
2231 * Failure: FALSE.
2233 BOOL WINAPI
2234 SetFileSecurityW( LPCWSTR lpFileName,
2235 SECURITY_INFORMATION RequestedInformation,
2236 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2238 HANDLE file;
2239 DWORD access = 0;
2240 NTSTATUS status;
2242 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2243 pSecurityDescriptor );
2245 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2246 RequestedInformation & GROUP_SECURITY_INFORMATION)
2247 access |= WRITE_OWNER;
2248 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2249 access |= ACCESS_SYSTEM_SECURITY;
2250 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2251 access |= WRITE_DAC;
2253 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2254 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2255 if (file == INVALID_HANDLE_VALUE)
2256 return FALSE;
2258 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2259 CloseHandle( file );
2260 return set_ntstatus( status );
2263 /******************************************************************************
2264 * QueryWindows31FilesMigration [ADVAPI32.@]
2266 * PARAMS
2267 * x1 []
2269 BOOL WINAPI
2270 QueryWindows31FilesMigration( DWORD x1 )
2272 FIXME("(%d):stub\n",x1);
2273 return TRUE;
2276 /******************************************************************************
2277 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2279 * PARAMS
2280 * x1 []
2281 * x2 []
2282 * x3 []
2283 * x4 []
2285 BOOL WINAPI
2286 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2287 DWORD x4 )
2289 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2290 return TRUE;
2293 /******************************************************************************
2294 * NotifyBootConfigStatus [ADVAPI32.@]
2296 * PARAMS
2297 * x1 []
2299 BOOL WINAPI
2300 NotifyBootConfigStatus( BOOL x1 )
2302 FIXME("(0x%08d):stub\n",x1);
2303 return 1;
2306 /******************************************************************************
2307 * RevertToSelf [ADVAPI32.@]
2309 * Ends the impersonation of a user.
2311 * PARAMS
2312 * void []
2314 * RETURNS
2315 * Success: TRUE.
2316 * Failure: FALSE.
2318 BOOL WINAPI
2319 RevertToSelf( void )
2321 HANDLE Token = NULL;
2322 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2323 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2326 /******************************************************************************
2327 * ImpersonateSelf [ADVAPI32.@]
2329 * Makes an impersonation token that represents the process user and assigns
2330 * to the current thread.
2332 * PARAMS
2333 * ImpersonationLevel [I] Level at which to impersonate.
2335 * RETURNS
2336 * Success: TRUE.
2337 * Failure: FALSE.
2339 BOOL WINAPI
2340 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2342 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2345 /******************************************************************************
2346 * ImpersonateLoggedOnUser [ADVAPI32.@]
2348 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2350 DWORD size;
2351 NTSTATUS Status;
2352 HANDLE ImpersonationToken;
2353 TOKEN_TYPE Type;
2354 static BOOL warn = TRUE;
2356 if (warn)
2358 FIXME( "(%p)\n", hToken );
2359 warn = FALSE;
2361 if (!GetTokenInformation( hToken, TokenType, &Type,
2362 sizeof(TOKEN_TYPE), &size ))
2363 return FALSE;
2365 if (Type == TokenPrimary)
2367 OBJECT_ATTRIBUTES ObjectAttributes;
2369 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2371 Status = NtDuplicateToken( hToken,
2372 TOKEN_IMPERSONATE | TOKEN_QUERY,
2373 &ObjectAttributes,
2374 SecurityImpersonation,
2375 TokenImpersonation,
2376 &ImpersonationToken );
2377 if (Status != STATUS_SUCCESS)
2379 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2380 SetLastError( RtlNtStatusToDosError( Status ) );
2381 return FALSE;
2384 else
2385 ImpersonationToken = hToken;
2387 Status = NtSetInformationThread( GetCurrentThread(),
2388 ThreadImpersonationToken,
2389 &ImpersonationToken,
2390 sizeof(ImpersonationToken) );
2392 if (Type == TokenPrimary)
2393 NtClose( ImpersonationToken );
2395 if (Status != STATUS_SUCCESS)
2397 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2398 SetLastError( RtlNtStatusToDosError( Status ) );
2399 return FALSE;
2402 return TRUE;
2405 /******************************************************************************
2406 * AccessCheck [ADVAPI32.@]
2408 BOOL WINAPI
2409 AccessCheck(
2410 PSECURITY_DESCRIPTOR SecurityDescriptor,
2411 HANDLE ClientToken,
2412 DWORD DesiredAccess,
2413 PGENERIC_MAPPING GenericMapping,
2414 PPRIVILEGE_SET PrivilegeSet,
2415 LPDWORD PrivilegeSetLength,
2416 LPDWORD GrantedAccess,
2417 LPBOOL AccessStatus)
2419 NTSTATUS access_status;
2420 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2421 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2422 GrantedAccess, &access_status) );
2423 if (ret) *AccessStatus = set_ntstatus( access_status );
2424 return ret;
2428 /******************************************************************************
2429 * AccessCheckByType [ADVAPI32.@]
2431 BOOL WINAPI AccessCheckByType(
2432 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2433 PSID PrincipalSelfSid,
2434 HANDLE ClientToken,
2435 DWORD DesiredAccess,
2436 POBJECT_TYPE_LIST ObjectTypeList,
2437 DWORD ObjectTypeListLength,
2438 PGENERIC_MAPPING GenericMapping,
2439 PPRIVILEGE_SET PrivilegeSet,
2440 LPDWORD PrivilegeSetLength,
2441 LPDWORD GrantedAccess,
2442 LPBOOL AccessStatus)
2444 FIXME("stub\n");
2446 *AccessStatus = TRUE;
2448 return !*AccessStatus;
2451 /******************************************************************************
2452 * MapGenericMask [ADVAPI32.@]
2454 * Maps generic access rights into specific access rights according to the
2455 * supplied mapping.
2457 * PARAMS
2458 * AccessMask [I/O] Access rights.
2459 * GenericMapping [I] The mapping between generic and specific rights.
2461 * RETURNS
2462 * Nothing.
2464 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2466 RtlMapGenericMask( AccessMask, GenericMapping );
2469 /*************************************************************************
2470 * SetKernelObjectSecurity [ADVAPI32.@]
2472 BOOL WINAPI SetKernelObjectSecurity (
2473 IN HANDLE Handle,
2474 IN SECURITY_INFORMATION SecurityInformation,
2475 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2477 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2481 /******************************************************************************
2482 * AddAuditAccessAce [ADVAPI32.@]
2484 BOOL WINAPI AddAuditAccessAce(
2485 IN OUT PACL pAcl,
2486 IN DWORD dwAceRevision,
2487 IN DWORD dwAccessMask,
2488 IN PSID pSid,
2489 IN BOOL bAuditSuccess,
2490 IN BOOL bAuditFailure)
2492 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2493 bAuditSuccess, bAuditFailure) );
2496 /******************************************************************************
2497 * AddAuditAccessAce [ADVAPI32.@]
2499 BOOL WINAPI AddAuditAccessAceEx(
2500 IN OUT PACL pAcl,
2501 IN DWORD dwAceRevision,
2502 IN DWORD dwAceFlags,
2503 IN DWORD dwAccessMask,
2504 IN PSID pSid,
2505 IN BOOL bAuditSuccess,
2506 IN BOOL bAuditFailure)
2508 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2509 bAuditSuccess, bAuditFailure) );
2512 /******************************************************************************
2513 * LookupAccountNameA [ADVAPI32.@]
2515 BOOL WINAPI
2516 LookupAccountNameA(
2517 IN LPCSTR system,
2518 IN LPCSTR account,
2519 OUT PSID sid,
2520 OUT LPDWORD cbSid,
2521 LPSTR ReferencedDomainName,
2522 IN OUT LPDWORD cbReferencedDomainName,
2523 OUT PSID_NAME_USE name_use )
2525 BOOL ret;
2526 UNICODE_STRING lpSystemW;
2527 UNICODE_STRING lpAccountW;
2528 LPWSTR lpReferencedDomainNameW = NULL;
2530 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2531 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2533 if (ReferencedDomainName)
2534 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2536 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2537 cbReferencedDomainName, name_use);
2539 if (ret && lpReferencedDomainNameW)
2541 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2542 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2545 RtlFreeUnicodeString(&lpSystemW);
2546 RtlFreeUnicodeString(&lpAccountW);
2547 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2549 return ret;
2552 /******************************************************************************
2553 * lookup_user_account_name
2555 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2556 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2558 /* Default implementation: Always return a default SID */
2559 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2560 BOOL ret;
2561 PSID pSid;
2562 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2563 DWORD nameLen;
2564 LPCWSTR domainName;
2566 ret = AllocateAndInitializeSid(&identifierAuthority,
2568 SECURITY_BUILTIN_DOMAIN_RID,
2569 DOMAIN_ALIAS_RID_ADMINS,
2570 0, 0, 0, 0, 0, 0,
2571 &pSid);
2573 if (!ret)
2574 return FALSE;
2576 if (!RtlValidSid(pSid))
2578 FreeSid(pSid);
2579 return FALSE;
2582 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2583 CopySid(*cbSid, Sid, pSid);
2584 if (*cbSid < GetLengthSid(pSid))
2586 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2587 ret = FALSE;
2589 *cbSid = GetLengthSid(pSid);
2591 domainName = dm;
2592 nameLen = strlenW(domainName);
2594 if (*cchReferencedDomainName <= nameLen || !ret)
2596 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2597 nameLen += 1;
2598 ret = FALSE;
2600 else if (ReferencedDomainName)
2601 strcpyW(ReferencedDomainName, domainName);
2603 *cchReferencedDomainName = nameLen;
2605 if (ret)
2606 *peUse = SidTypeUser;
2608 FreeSid(pSid);
2610 return ret;
2613 /******************************************************************************
2614 * lookup_computer_account_name
2616 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2617 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2619 MAX_SID local;
2620 BOOL ret;
2621 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2622 DWORD nameLen;
2623 LPCWSTR domainName;
2625 if ((ret = ADVAPI_GetComputerSid(&local)))
2627 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2628 CopySid(*cbSid, Sid, &local);
2629 if (*cbSid < GetLengthSid(&local))
2631 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2632 ret = FALSE;
2634 *cbSid = GetLengthSid(&local);
2637 domainName = dm;
2638 nameLen = strlenW(domainName);
2640 if (*cchReferencedDomainName <= nameLen || !ret)
2642 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2643 nameLen += 1;
2644 ret = FALSE;
2646 else if (ReferencedDomainName)
2647 strcpyW(ReferencedDomainName, domainName);
2649 *cchReferencedDomainName = nameLen;
2651 if (ret)
2652 *peUse = SidTypeDomain;
2654 return ret;
2657 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2658 LSA_UNICODE_STRING *domain )
2660 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2662 while (p > str->Buffer && *p != '\\') p--;
2664 if (*p == '\\')
2666 domain->Buffer = str->Buffer;
2667 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2669 account->Buffer = p + 1;
2670 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2672 else
2674 domain->Buffer = NULL;
2675 domain->Length = 0;
2677 account->Buffer = str->Buffer;
2678 account->Length = str->Length;
2682 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2684 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2686 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2687 return TRUE;
2689 return FALSE;
2692 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2694 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2696 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2697 return TRUE;
2699 if (ACCOUNT_SIDS[idx].alias)
2701 len = strlenW( ACCOUNT_SIDS[idx].alias );
2702 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2703 return TRUE;
2705 return FALSE;
2709 * Helper function for LookupAccountNameW
2711 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2712 PSID Sid, LPDWORD cbSid,
2713 LPWSTR ReferencedDomainName,
2714 LPDWORD cchReferencedDomainName,
2715 PSID_NAME_USE peUse, BOOL *handled )
2717 PSID pSid;
2718 LSA_UNICODE_STRING account, domain;
2719 BOOL ret = TRUE;
2720 ULONG i;
2722 *handled = FALSE;
2723 split_domain_account( account_and_domain, &account, &domain );
2725 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2727 /* check domain first */
2728 if (domain.Buffer && !match_domain( i, &domain )) continue;
2730 if (match_account( i, &account ))
2732 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2734 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2736 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2738 if (*cbSid < sidLen)
2740 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2741 ret = FALSE;
2743 else if (Sid)
2745 CopySid(*cbSid, Sid, pSid);
2747 *cbSid = sidLen;
2750 len = strlenW( ACCOUNT_SIDS[i].domain );
2751 if (*cchReferencedDomainName <= len || !ret)
2753 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2754 len++;
2755 ret = FALSE;
2757 else if (ReferencedDomainName)
2759 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2762 *cchReferencedDomainName = len;
2763 if (ret)
2764 *peUse = ACCOUNT_SIDS[i].name_use;
2766 HeapFree(GetProcessHeap(), 0, pSid);
2767 *handled = TRUE;
2768 return ret;
2771 return ret;
2774 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2775 PSID Sid, LPDWORD cbSid,
2776 LPWSTR ReferencedDomainName,
2777 LPDWORD cchReferencedDomainName,
2778 PSID_NAME_USE peUse, BOOL *handled )
2780 DWORD nameLen;
2781 LPWSTR userName = NULL;
2782 LSA_UNICODE_STRING account, domain;
2783 BOOL ret = TRUE;
2785 *handled = FALSE;
2786 split_domain_account( account_and_domain, &account, &domain );
2788 /* Let the current Unix user id masquerade as first Windows user account */
2790 nameLen = UNLEN + 1;
2791 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2793 if (domain.Buffer)
2795 /* check to make sure this account is on this computer */
2796 if (GetComputerNameW( userName, &nameLen ) &&
2797 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2799 SetLastError(ERROR_NONE_MAPPED);
2800 ret = FALSE;
2802 nameLen = UNLEN + 1;
2805 if (GetUserNameW( userName, &nameLen ) &&
2806 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2808 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2809 *handled = TRUE;
2811 else
2813 nameLen = UNLEN + 1;
2814 if (GetComputerNameW( userName, &nameLen ) &&
2815 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2817 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2818 *handled = TRUE;
2822 HeapFree(GetProcessHeap(), 0, userName);
2823 return ret;
2826 /******************************************************************************
2827 * LookupAccountNameW [ADVAPI32.@]
2829 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2830 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2831 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2833 BOOL ret, handled;
2834 LSA_UNICODE_STRING account;
2836 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2837 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2839 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2841 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2842 return FALSE;
2845 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2847 lpAccountName = BUILTIN;
2850 RtlInitUnicodeString( &account, lpAccountName );
2852 /* Check well known SIDs first */
2853 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2854 cchReferencedDomainName, peUse, &handled );
2855 if (handled)
2856 return ret;
2858 /* Check user names */
2859 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2860 cchReferencedDomainName, peUse, &handled);
2861 if (handled)
2862 return ret;
2864 SetLastError( ERROR_NONE_MAPPED );
2865 return FALSE;
2868 /******************************************************************************
2869 * PrivilegeCheck [ADVAPI32.@]
2871 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2873 BOOL ret;
2874 BOOLEAN Result;
2876 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2878 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2879 if (ret)
2880 *pfResult = Result;
2881 return ret;
2884 /******************************************************************************
2885 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2887 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2888 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2889 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2890 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2892 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2893 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2894 SecurityDescriptor, DesiredAccess, GenericMapping,
2895 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2896 return TRUE;
2899 /******************************************************************************
2900 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2902 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2903 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2904 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2905 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2907 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2908 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2909 SecurityDescriptor, DesiredAccess, GenericMapping,
2910 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2911 return TRUE;
2914 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2916 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2918 return TRUE;
2921 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2923 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2925 return TRUE;
2928 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2930 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2932 return TRUE;
2935 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2936 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2937 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2938 LPBOOL GenerateOnClose)
2940 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2941 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2942 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2943 GenerateOnClose);
2945 return TRUE;
2948 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2949 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2950 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2951 LPBOOL GenerateOnClose)
2953 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2954 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2955 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2956 GenerateOnClose);
2958 return TRUE;
2961 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2962 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2964 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2965 DesiredAccess, Privileges, AccessGranted);
2967 return TRUE;
2970 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2971 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2973 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2974 DesiredAccess, Privileges, AccessGranted);
2976 return TRUE;
2979 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2980 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2982 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2983 ClientToken, Privileges, AccessGranted);
2985 return TRUE;
2988 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2989 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2991 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2992 ClientToken, Privileges, AccessGranted);
2994 return TRUE;
2997 /******************************************************************************
2998 * GetSecurityInfo [ADVAPI32.@]
3000 * Retrieves a copy of the security descriptor associated with an object.
3002 * PARAMS
3003 * hObject [I] A handle for the object.
3004 * ObjectType [I] The type of object.
3005 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3006 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3007 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3008 * ppDacl [O] If non-null, receives a pointer to the DACL.
3009 * ppSacl [O] If non-null, receives a pointer to the SACL.
3010 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3011 * which must be freed with LocalFree.
3013 * RETURNS
3014 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3016 DWORD WINAPI GetSecurityInfo(
3017 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3018 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3019 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3020 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3023 PSECURITY_DESCRIPTOR sd;
3024 NTSTATUS status;
3025 ULONG n1, n2;
3026 BOOL present, defaulted;
3028 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3029 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3030 return RtlNtStatusToDosError(status);
3032 sd = LocalAlloc(0, n1);
3033 if (!sd)
3034 return ERROR_NOT_ENOUGH_MEMORY;
3036 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3037 if (status != STATUS_SUCCESS)
3039 LocalFree(sd);
3040 return RtlNtStatusToDosError(status);
3043 if (ppsidOwner)
3045 *ppsidOwner = NULL;
3046 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3048 if (ppsidGroup)
3050 *ppsidGroup = NULL;
3051 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3053 if (ppDacl)
3055 *ppDacl = NULL;
3056 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3058 if (ppSacl)
3060 *ppSacl = NULL;
3061 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3063 if (ppSecurityDescriptor)
3064 *ppSecurityDescriptor = sd;
3066 return ERROR_SUCCESS;
3069 /******************************************************************************
3070 * GetSecurityInfoExA [ADVAPI32.@]
3072 DWORD WINAPI GetSecurityInfoExA(
3073 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3074 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3075 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3076 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3079 FIXME("stub!\n");
3080 return ERROR_BAD_PROVIDER;
3083 /******************************************************************************
3084 * GetSecurityInfoExW [ADVAPI32.@]
3086 DWORD WINAPI GetSecurityInfoExW(
3087 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3088 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3089 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3090 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3093 FIXME("stub!\n");
3094 return ERROR_BAD_PROVIDER;
3097 /******************************************************************************
3098 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3100 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3101 LPSTR pTrusteeName, DWORD AccessPermissions,
3102 ACCESS_MODE AccessMode, DWORD Inheritance )
3104 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3105 AccessPermissions, AccessMode, Inheritance);
3107 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3108 pExplicitAccess->grfAccessMode = AccessMode;
3109 pExplicitAccess->grfInheritance = Inheritance;
3111 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3112 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3113 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3114 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3115 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3118 /******************************************************************************
3119 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3121 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3122 LPWSTR pTrusteeName, DWORD AccessPermissions,
3123 ACCESS_MODE AccessMode, DWORD Inheritance )
3125 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3126 AccessPermissions, AccessMode, Inheritance);
3128 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3129 pExplicitAccess->grfAccessMode = AccessMode;
3130 pExplicitAccess->grfInheritance = Inheritance;
3132 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3133 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3134 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3135 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3136 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3139 /******************************************************************************
3140 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3142 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3143 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3144 LPSTR InheritedObjectTypeName, LPSTR Name )
3146 DWORD ObjectsPresent = 0;
3148 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3149 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3151 /* Fill the OBJECTS_AND_NAME structure */
3152 pObjName->ObjectType = ObjectType;
3153 if (ObjectTypeName != NULL)
3155 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3158 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3159 if (InheritedObjectTypeName != NULL)
3161 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3164 pObjName->ObjectsPresent = ObjectsPresent;
3165 pObjName->ptstrName = Name;
3167 /* Fill the TRUSTEE structure */
3168 pTrustee->pMultipleTrustee = NULL;
3169 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3170 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3171 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3172 pTrustee->ptstrName = (LPSTR)pObjName;
3175 /******************************************************************************
3176 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3178 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3179 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3180 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3182 DWORD ObjectsPresent = 0;
3184 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3185 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3187 /* Fill the OBJECTS_AND_NAME structure */
3188 pObjName->ObjectType = ObjectType;
3189 if (ObjectTypeName != NULL)
3191 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3194 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3195 if (InheritedObjectTypeName != NULL)
3197 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3200 pObjName->ObjectsPresent = ObjectsPresent;
3201 pObjName->ptstrName = Name;
3203 /* Fill the TRUSTEE structure */
3204 pTrustee->pMultipleTrustee = NULL;
3205 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3206 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3207 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3208 pTrustee->ptstrName = (LPWSTR)pObjName;
3211 /******************************************************************************
3212 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3214 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3215 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3217 DWORD ObjectsPresent = 0;
3219 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3221 /* Fill the OBJECTS_AND_SID structure */
3222 if (pObjectGuid != NULL)
3224 pObjSid->ObjectTypeGuid = *pObjectGuid;
3225 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3227 else
3229 ZeroMemory(&pObjSid->ObjectTypeGuid,
3230 sizeof(GUID));
3233 if (pInheritedObjectGuid != NULL)
3235 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3236 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3238 else
3240 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3241 sizeof(GUID));
3244 pObjSid->ObjectsPresent = ObjectsPresent;
3245 pObjSid->pSid = pSid;
3247 /* Fill the TRUSTEE structure */
3248 pTrustee->pMultipleTrustee = NULL;
3249 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3250 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3251 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3252 pTrustee->ptstrName = (LPSTR) pObjSid;
3255 /******************************************************************************
3256 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3258 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3259 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3261 DWORD ObjectsPresent = 0;
3263 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3265 /* Fill the OBJECTS_AND_SID structure */
3266 if (pObjectGuid != NULL)
3268 pObjSid->ObjectTypeGuid = *pObjectGuid;
3269 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3271 else
3273 ZeroMemory(&pObjSid->ObjectTypeGuid,
3274 sizeof(GUID));
3277 if (pInheritedObjectGuid != NULL)
3279 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3280 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3282 else
3284 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3285 sizeof(GUID));
3288 pObjSid->ObjectsPresent = ObjectsPresent;
3289 pObjSid->pSid = pSid;
3291 /* Fill the TRUSTEE structure */
3292 pTrustee->pMultipleTrustee = NULL;
3293 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3294 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3295 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3296 pTrustee->ptstrName = (LPWSTR) pObjSid;
3299 /******************************************************************************
3300 * BuildTrusteeWithSidA [ADVAPI32.@]
3302 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3304 TRACE("%p %p\n", pTrustee, pSid);
3306 pTrustee->pMultipleTrustee = NULL;
3307 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3308 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3309 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3310 pTrustee->ptstrName = pSid;
3313 /******************************************************************************
3314 * BuildTrusteeWithSidW [ADVAPI32.@]
3316 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3318 TRACE("%p %p\n", pTrustee, pSid);
3320 pTrustee->pMultipleTrustee = NULL;
3321 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3322 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3323 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3324 pTrustee->ptstrName = pSid;
3327 /******************************************************************************
3328 * BuildTrusteeWithNameA [ADVAPI32.@]
3330 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3332 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3334 pTrustee->pMultipleTrustee = NULL;
3335 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3336 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3337 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3338 pTrustee->ptstrName = name;
3341 /******************************************************************************
3342 * BuildTrusteeWithNameW [ADVAPI32.@]
3344 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3346 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3348 pTrustee->pMultipleTrustee = NULL;
3349 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3350 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3351 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3352 pTrustee->ptstrName = name;
3355 /******************************************************************************
3356 * GetTrusteeFormA [ADVAPI32.@]
3358 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3360 TRACE("(%p)\n", pTrustee);
3362 if (!pTrustee)
3363 return TRUSTEE_BAD_FORM;
3365 return pTrustee->TrusteeForm;
3368 /******************************************************************************
3369 * GetTrusteeFormW [ADVAPI32.@]
3371 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3373 TRACE("(%p)\n", pTrustee);
3375 if (!pTrustee)
3376 return TRUSTEE_BAD_FORM;
3378 return pTrustee->TrusteeForm;
3381 /******************************************************************************
3382 * GetTrusteeNameA [ADVAPI32.@]
3384 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3386 TRACE("(%p)\n", pTrustee);
3388 if (!pTrustee)
3389 return NULL;
3391 return pTrustee->ptstrName;
3394 /******************************************************************************
3395 * GetTrusteeNameW [ADVAPI32.@]
3397 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3399 TRACE("(%p)\n", pTrustee);
3401 if (!pTrustee)
3402 return NULL;
3404 return pTrustee->ptstrName;
3407 /******************************************************************************
3408 * GetTrusteeTypeA [ADVAPI32.@]
3410 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3412 TRACE("(%p)\n", pTrustee);
3414 if (!pTrustee)
3415 return TRUSTEE_IS_UNKNOWN;
3417 return pTrustee->TrusteeType;
3420 /******************************************************************************
3421 * GetTrusteeTypeW [ADVAPI32.@]
3423 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3425 TRACE("(%p)\n", pTrustee);
3427 if (!pTrustee)
3428 return TRUSTEE_IS_UNKNOWN;
3430 return pTrustee->TrusteeType;
3433 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3434 DWORD nAclInformationLength,
3435 ACL_INFORMATION_CLASS dwAclInformationClass )
3437 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3438 nAclInformationLength, dwAclInformationClass);
3440 return TRUE;
3443 /******************************************************************************
3444 * SetEntriesInAclA [ADVAPI32.@]
3446 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3447 PACL OldAcl, PACL* NewAcl )
3449 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3450 if (NewAcl)
3451 *NewAcl = NULL;
3452 return ERROR_SUCCESS;
3455 /******************************************************************************
3456 * SetEntriesInAclW [ADVAPI32.@]
3458 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3459 PACL OldAcl, PACL* NewAcl )
3461 ULONG i;
3462 PSID *ppsid;
3463 DWORD ret = ERROR_SUCCESS;
3464 DWORD acl_size = sizeof(ACL);
3465 NTSTATUS status;
3467 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3469 *NewAcl = NULL;
3471 if (!count && !OldAcl)
3472 return ERROR_SUCCESS;
3474 /* allocate array of maximum sized sids allowed */
3475 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3476 if (!ppsid)
3477 return ERROR_OUTOFMEMORY;
3479 for (i = 0; i < count; i++)
3481 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3483 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3484 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3485 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3486 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3487 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3488 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3489 pEntries[i].Trustee.ptstrName);
3491 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3493 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3494 ret = ERROR_INVALID_PARAMETER;
3495 goto exit;
3498 switch (pEntries[i].Trustee.TrusteeForm)
3500 case TRUSTEE_IS_SID:
3501 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3502 ppsid[i], pEntries[i].Trustee.ptstrName))
3504 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3505 ret = ERROR_INVALID_PARAMETER;
3506 goto exit;
3508 break;
3509 case TRUSTEE_IS_NAME:
3511 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3512 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3513 SID_NAME_USE use;
3514 if ( strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ) &&
3515 !LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3517 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3518 ret = ERROR_INVALID_PARAMETER;
3519 goto exit;
3521 break;
3523 case TRUSTEE_IS_OBJECTS_AND_SID:
3524 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3525 break;
3526 case TRUSTEE_IS_OBJECTS_AND_NAME:
3527 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3528 break;
3529 default:
3530 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3531 ret = ERROR_INVALID_PARAMETER;
3532 goto exit;
3535 /* Note: we overestimate the ACL size here as a tradeoff between
3536 * instructions (simplicity) and memory */
3537 switch (pEntries[i].grfAccessMode)
3539 case GRANT_ACCESS:
3540 case SET_ACCESS:
3541 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3542 break;
3543 case DENY_ACCESS:
3544 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3545 break;
3546 case SET_AUDIT_SUCCESS:
3547 case SET_AUDIT_FAILURE:
3548 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3549 break;
3550 case REVOKE_ACCESS:
3551 break;
3552 default:
3553 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3554 ret = ERROR_INVALID_PARAMETER;
3555 goto exit;
3559 if (OldAcl)
3561 ACL_SIZE_INFORMATION size_info;
3563 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3564 if (status != STATUS_SUCCESS)
3566 ret = RtlNtStatusToDosError(status);
3567 goto exit;
3569 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3572 *NewAcl = LocalAlloc(0, acl_size);
3573 if (!*NewAcl)
3575 ret = ERROR_OUTOFMEMORY;
3576 goto exit;
3579 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3580 if (status != STATUS_SUCCESS)
3582 ret = RtlNtStatusToDosError(status);
3583 goto exit;
3586 for (i = 0; i < count; i++)
3588 switch (pEntries[i].grfAccessMode)
3590 case GRANT_ACCESS:
3591 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3592 pEntries[i].grfInheritance,
3593 pEntries[i].grfAccessPermissions,
3594 ppsid[i]);
3595 break;
3596 case SET_ACCESS:
3598 ULONG j;
3599 BOOL add = TRUE;
3600 if (OldAcl)
3602 for (j = 0; ; j++)
3604 const ACE_HEADER *existing_ace_header;
3605 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3606 if (status != STATUS_SUCCESS)
3607 break;
3608 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3609 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3610 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3612 add = FALSE;
3613 break;
3617 if (add)
3618 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3619 pEntries[i].grfInheritance,
3620 pEntries[i].grfAccessPermissions,
3621 ppsid[i]);
3622 break;
3624 case DENY_ACCESS:
3625 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3626 pEntries[i].grfInheritance,
3627 pEntries[i].grfAccessPermissions,
3628 ppsid[i]);
3629 break;
3630 case SET_AUDIT_SUCCESS:
3631 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3632 pEntries[i].grfInheritance,
3633 pEntries[i].grfAccessPermissions,
3634 ppsid[i], TRUE, FALSE);
3635 break;
3636 case SET_AUDIT_FAILURE:
3637 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3638 pEntries[i].grfInheritance,
3639 pEntries[i].grfAccessPermissions,
3640 ppsid[i], FALSE, TRUE);
3641 break;
3642 default:
3643 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3647 if (OldAcl)
3649 for (i = 0; ; i++)
3651 BOOL add = TRUE;
3652 ULONG j;
3653 const ACE_HEADER *old_ace_header;
3654 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3655 if (status != STATUS_SUCCESS) break;
3656 for (j = 0; j < count; j++)
3658 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3659 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3660 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3662 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3663 add = FALSE;
3664 break;
3666 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3668 switch (old_ace_header->AceType)
3670 case ACCESS_ALLOWED_ACE_TYPE:
3671 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3672 add = FALSE;
3673 break;
3674 case ACCESS_DENIED_ACE_TYPE:
3675 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3676 add = FALSE;
3677 break;
3678 case SYSTEM_AUDIT_ACE_TYPE:
3679 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3680 add = FALSE;
3681 break;
3682 case SYSTEM_ALARM_ACE_TYPE:
3683 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3684 add = FALSE;
3685 break;
3686 default:
3687 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3690 if (!add)
3691 break;
3694 if (add)
3695 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3696 if (status != STATUS_SUCCESS)
3698 WARN("RtlAddAce failed with error 0x%08x\n", status);
3699 ret = RtlNtStatusToDosError(status);
3700 break;
3705 exit:
3706 HeapFree(GetProcessHeap(), 0, ppsid);
3707 return ret;
3710 /******************************************************************************
3711 * SetNamedSecurityInfoA [ADVAPI32.@]
3713 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3714 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3715 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3717 DWORD len;
3718 LPWSTR wstr = NULL;
3719 DWORD r;
3721 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3722 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3724 if( pObjectName )
3726 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3727 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3728 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3731 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3732 psidGroup, pDacl, pSacl );
3734 HeapFree( GetProcessHeap(), 0, wstr );
3736 return r;
3739 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3740 PSECURITY_DESCRIPTOR ModificationDescriptor,
3741 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3742 PGENERIC_MAPPING GenericMapping,
3743 HANDLE Token )
3745 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3746 ObjectsSecurityDescriptor, GenericMapping, Token);
3748 return TRUE;
3751 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3753 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3756 /******************************************************************************
3757 * AreAnyAccessesGranted [ADVAPI32.@]
3759 * Determines whether or not any of a set of specified access permissions have
3760 * been granted or not.
3762 * PARAMS
3763 * GrantedAccess [I] The permissions that have been granted.
3764 * DesiredAccess [I] The permissions that you want to have.
3766 * RETURNS
3767 * Nonzero if any of the permissions have been granted, zero if none of the
3768 * permissions have been granted.
3771 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3773 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3776 /******************************************************************************
3777 * SetNamedSecurityInfoW [ADVAPI32.@]
3779 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3780 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3781 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3783 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3784 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3785 return ERROR_SUCCESS;
3788 /******************************************************************************
3789 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3791 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3792 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3794 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3795 return ERROR_CALL_NOT_IMPLEMENTED;
3798 /******************************************************************************
3799 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3801 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3802 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3804 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3805 return ERROR_CALL_NOT_IMPLEMENTED;
3808 /******************************************************************************
3809 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3811 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3812 PACCESS_MASK pFailedAuditRights)
3814 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3815 return ERROR_CALL_NOT_IMPLEMENTED;
3819 /******************************************************************************
3820 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3822 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3823 PACCESS_MASK pFailedAuditRights)
3825 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3826 return ERROR_CALL_NOT_IMPLEMENTED;
3830 /******************************************************************************
3831 * ParseAclStringFlags
3833 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3835 DWORD flags = 0;
3836 LPCWSTR szAcl = *StringAcl;
3838 while (*szAcl != '(')
3840 if (*szAcl == 'P')
3842 flags |= SE_DACL_PROTECTED;
3844 else if (*szAcl == 'A')
3846 szAcl++;
3847 if (*szAcl == 'R')
3848 flags |= SE_DACL_AUTO_INHERIT_REQ;
3849 else if (*szAcl == 'I')
3850 flags |= SE_DACL_AUTO_INHERITED;
3852 szAcl++;
3855 *StringAcl = szAcl;
3856 return flags;
3859 /******************************************************************************
3860 * ParseAceStringType
3862 static const ACEFLAG AceType[] =
3864 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3865 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3866 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3867 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3869 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3870 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3871 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3872 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3874 { NULL, 0 },
3877 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3879 UINT len = 0;
3880 LPCWSTR szAcl = *StringAcl;
3881 const ACEFLAG *lpaf = AceType;
3883 while (lpaf->wstr &&
3884 (len = strlenW(lpaf->wstr)) &&
3885 strncmpW(lpaf->wstr, szAcl, len))
3886 lpaf++;
3888 if (!lpaf->wstr)
3889 return 0;
3891 *StringAcl += len;
3892 return lpaf->value;
3896 /******************************************************************************
3897 * ParseAceStringFlags
3899 static const ACEFLAG AceFlags[] =
3901 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3902 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3903 { SDDL_INHERITED, INHERITED_ACE },
3904 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3905 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3906 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3907 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3908 { NULL, 0 },
3911 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3913 UINT len = 0;
3914 BYTE flags = 0;
3915 LPCWSTR szAcl = *StringAcl;
3917 while (*szAcl != ';')
3919 const ACEFLAG *lpaf = AceFlags;
3921 while (lpaf->wstr &&
3922 (len = strlenW(lpaf->wstr)) &&
3923 strncmpW(lpaf->wstr, szAcl, len))
3924 lpaf++;
3926 if (!lpaf->wstr)
3927 return 0;
3929 flags |= lpaf->value;
3930 szAcl += len;
3933 *StringAcl = szAcl;
3934 return flags;
3938 /******************************************************************************
3939 * ParseAceStringRights
3941 static const ACEFLAG AceRights[] =
3943 { SDDL_GENERIC_ALL, GENERIC_ALL },
3944 { SDDL_GENERIC_READ, GENERIC_READ },
3945 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3946 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3948 { SDDL_READ_CONTROL, READ_CONTROL },
3949 { SDDL_STANDARD_DELETE, DELETE },
3950 { SDDL_WRITE_DAC, WRITE_DAC },
3951 { SDDL_WRITE_OWNER, WRITE_OWNER },
3953 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3954 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3955 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3956 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3957 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3958 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3959 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3960 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3961 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3963 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3964 { SDDL_FILE_READ, FILE_GENERIC_READ },
3965 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3966 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3968 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3969 { SDDL_KEY_READ, KEY_READ },
3970 { SDDL_KEY_WRITE, KEY_WRITE },
3971 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3972 { NULL, 0 },
3975 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3977 UINT len = 0;
3978 DWORD rights = 0;
3979 LPCWSTR szAcl = *StringAcl;
3981 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3983 LPCWSTR p = szAcl;
3985 while (*p && *p != ';')
3986 p++;
3988 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3990 rights = strtoulW(szAcl, NULL, 16);
3991 szAcl = p;
3993 else
3994 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3996 else
3998 while (*szAcl != ';')
4000 const ACEFLAG *lpaf = AceRights;
4002 while (lpaf->wstr &&
4003 (len = strlenW(lpaf->wstr)) &&
4004 strncmpW(lpaf->wstr, szAcl, len))
4006 lpaf++;
4009 if (!lpaf->wstr)
4010 return 0;
4012 rights |= lpaf->value;
4013 szAcl += len;
4017 *StringAcl = szAcl;
4018 return rights;
4022 /******************************************************************************
4023 * ParseStringAclToAcl
4025 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4027 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4028 PACL pAcl, LPDWORD cBytes)
4030 DWORD val;
4031 DWORD sidlen;
4032 DWORD length = sizeof(ACL);
4033 DWORD acesize = 0;
4034 DWORD acecount = 0;
4035 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4037 TRACE("%s\n", debugstr_w(StringAcl));
4039 if (!StringAcl)
4040 return FALSE;
4042 if (pAcl) /* pAce is only useful if we're setting values */
4043 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4045 /* Parse ACL flags */
4046 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4048 /* Parse ACE */
4049 while (*StringAcl == '(')
4051 StringAcl++;
4053 /* Parse ACE type */
4054 val = ParseAceStringType(&StringAcl);
4055 if (pAce)
4056 pAce->Header.AceType = (BYTE) val;
4057 if (*StringAcl != ';')
4058 goto lerr;
4059 StringAcl++;
4061 /* Parse ACE flags */
4062 val = ParseAceStringFlags(&StringAcl);
4063 if (pAce)
4064 pAce->Header.AceFlags = (BYTE) val;
4065 if (*StringAcl != ';')
4066 goto lerr;
4067 StringAcl++;
4069 /* Parse ACE rights */
4070 val = ParseAceStringRights(&StringAcl);
4071 if (pAce)
4072 pAce->Mask = val;
4073 if (*StringAcl != ';')
4074 goto lerr;
4075 StringAcl++;
4077 /* Parse ACE object guid */
4078 if (*StringAcl != ';')
4080 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4081 goto lerr;
4083 StringAcl++;
4085 /* Parse ACE inherit object guid */
4086 if (*StringAcl != ';')
4088 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4089 goto lerr;
4091 StringAcl++;
4093 /* Parse ACE account sid */
4094 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4096 while (*StringAcl && *StringAcl != ')')
4097 StringAcl++;
4100 if (*StringAcl != ')')
4101 goto lerr;
4102 StringAcl++;
4104 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4105 length += acesize;
4106 if (pAce)
4108 pAce->Header.AceSize = acesize;
4109 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4111 acecount++;
4114 *cBytes = length;
4116 if (length > 0xffff)
4118 ERR("ACL too large\n");
4119 goto lerr;
4122 if (pAcl)
4124 pAcl->AclRevision = ACL_REVISION;
4125 pAcl->Sbz1 = 0;
4126 pAcl->AclSize = length;
4127 pAcl->AceCount = acecount++;
4128 pAcl->Sbz2 = 0;
4130 return TRUE;
4132 lerr:
4133 SetLastError(ERROR_INVALID_ACL);
4134 WARN("Invalid ACE string format\n");
4135 return FALSE;
4139 /******************************************************************************
4140 * ParseStringSecurityDescriptorToSecurityDescriptor
4142 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4143 LPCWSTR StringSecurityDescriptor,
4144 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4145 LPDWORD cBytes)
4147 BOOL bret = FALSE;
4148 WCHAR toktype;
4149 WCHAR tok[MAX_PATH];
4150 LPCWSTR lptoken;
4151 LPBYTE lpNext = NULL;
4152 DWORD len;
4154 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4156 if (SecurityDescriptor)
4157 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4159 while (*StringSecurityDescriptor)
4161 toktype = *StringSecurityDescriptor;
4163 /* Expect char identifier followed by ':' */
4164 StringSecurityDescriptor++;
4165 if (*StringSecurityDescriptor != ':')
4167 SetLastError(ERROR_INVALID_PARAMETER);
4168 goto lend;
4170 StringSecurityDescriptor++;
4172 /* Extract token */
4173 lptoken = StringSecurityDescriptor;
4174 while (*lptoken && *lptoken != ':')
4175 lptoken++;
4177 if (*lptoken)
4178 lptoken--;
4180 len = lptoken - StringSecurityDescriptor;
4181 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4182 tok[len] = 0;
4184 switch (toktype)
4186 case 'O':
4188 DWORD bytes;
4190 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4191 goto lend;
4193 if (SecurityDescriptor)
4195 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4196 lpNext += bytes; /* Advance to next token */
4199 *cBytes += bytes;
4201 break;
4204 case 'G':
4206 DWORD bytes;
4208 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4209 goto lend;
4211 if (SecurityDescriptor)
4213 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4214 lpNext += bytes; /* Advance to next token */
4217 *cBytes += bytes;
4219 break;
4222 case 'D':
4224 DWORD flags;
4225 DWORD bytes;
4227 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4228 goto lend;
4230 if (SecurityDescriptor)
4232 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4233 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4234 lpNext += bytes; /* Advance to next token */
4237 *cBytes += bytes;
4239 break;
4242 case 'S':
4244 DWORD flags;
4245 DWORD bytes;
4247 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4248 goto lend;
4250 if (SecurityDescriptor)
4252 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4253 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4254 lpNext += bytes; /* Advance to next token */
4257 *cBytes += bytes;
4259 break;
4262 default:
4263 FIXME("Unknown token\n");
4264 SetLastError(ERROR_INVALID_PARAMETER);
4265 goto lend;
4268 StringSecurityDescriptor = lptoken;
4271 bret = TRUE;
4273 lend:
4274 return bret;
4277 /******************************************************************************
4278 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4280 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4281 LPCSTR StringSecurityDescriptor,
4282 DWORD StringSDRevision,
4283 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4284 PULONG SecurityDescriptorSize)
4286 UINT len;
4287 BOOL ret = FALSE;
4288 LPWSTR StringSecurityDescriptorW;
4290 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4291 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4293 if (StringSecurityDescriptorW)
4295 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4297 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4298 StringSDRevision, SecurityDescriptor,
4299 SecurityDescriptorSize);
4300 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4303 return ret;
4306 /******************************************************************************
4307 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4309 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4310 LPCWSTR StringSecurityDescriptor,
4311 DWORD StringSDRevision,
4312 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4313 PULONG SecurityDescriptorSize)
4315 DWORD cBytes;
4316 SECURITY_DESCRIPTOR* psd;
4317 BOOL bret = FALSE;
4319 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4321 if (GetVersion() & 0x80000000)
4323 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4324 goto lend;
4326 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4328 SetLastError(ERROR_INVALID_PARAMETER);
4329 goto lend;
4331 else if (StringSDRevision != SID_REVISION)
4333 SetLastError(ERROR_UNKNOWN_REVISION);
4334 goto lend;
4337 /* Compute security descriptor length */
4338 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4339 NULL, &cBytes))
4340 goto lend;
4342 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4343 if (!psd) goto lend;
4345 psd->Revision = SID_REVISION;
4346 psd->Control |= SE_SELF_RELATIVE;
4348 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4349 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4351 LocalFree(psd);
4352 goto lend;
4355 if (SecurityDescriptorSize)
4356 *SecurityDescriptorSize = cBytes;
4358 bret = TRUE;
4360 lend:
4361 TRACE(" ret=%d\n", bret);
4362 return bret;
4365 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4367 if (cch == -1)
4368 cch = strlenW(string);
4370 if (plen)
4371 *plen += cch;
4373 if (pwptr)
4375 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4376 *pwptr += cch;
4380 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4382 DWORD i;
4383 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4384 WCHAR subauthfmt[] = { '-','%','u',0 };
4385 WCHAR buf[26];
4386 SID *pisid = psid;
4388 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4390 SetLastError(ERROR_INVALID_SID);
4391 return FALSE;
4394 if (pisid->IdentifierAuthority.Value[0] ||
4395 pisid->IdentifierAuthority.Value[1])
4397 FIXME("not matching MS' bugs\n");
4398 SetLastError(ERROR_INVALID_SID);
4399 return FALSE;
4402 sprintfW( buf, fmt, pisid->Revision,
4403 MAKELONG(
4404 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4405 pisid->IdentifierAuthority.Value[4] ),
4406 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4407 pisid->IdentifierAuthority.Value[2] )
4408 ) );
4409 DumpString(buf, -1, pwptr, plen);
4411 for( i=0; i<pisid->SubAuthorityCount; i++ )
4413 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4414 DumpString(buf, -1, pwptr, plen);
4416 return TRUE;
4419 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4421 size_t i;
4422 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4424 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4426 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4427 return TRUE;
4431 return DumpSidNumeric(psid, pwptr, plen);
4434 static const LPCWSTR AceRightBitNames[32] = {
4435 SDDL_CREATE_CHILD, /* 0 */
4436 SDDL_DELETE_CHILD,
4437 SDDL_LIST_CHILDREN,
4438 SDDL_SELF_WRITE,
4439 SDDL_READ_PROPERTY, /* 4 */
4440 SDDL_WRITE_PROPERTY,
4441 SDDL_DELETE_TREE,
4442 SDDL_LIST_OBJECT,
4443 SDDL_CONTROL_ACCESS, /* 8 */
4444 NULL,
4445 NULL,
4446 NULL,
4447 NULL, /* 12 */
4448 NULL,
4449 NULL,
4450 NULL,
4451 SDDL_STANDARD_DELETE, /* 16 */
4452 SDDL_READ_CONTROL,
4453 SDDL_WRITE_DAC,
4454 SDDL_WRITE_OWNER,
4455 NULL, /* 20 */
4456 NULL,
4457 NULL,
4458 NULL,
4459 NULL, /* 24 */
4460 NULL,
4461 NULL,
4462 NULL,
4463 SDDL_GENERIC_ALL, /* 28 */
4464 SDDL_GENERIC_EXECUTE,
4465 SDDL_GENERIC_WRITE,
4466 SDDL_GENERIC_READ
4469 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4471 static const WCHAR fmtW[] = {'0','x','%','x',0};
4472 WCHAR buf[15];
4473 size_t i;
4475 if (mask == 0)
4476 return;
4478 /* first check if the right have name */
4479 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4481 if (AceRights[i].wstr == NULL)
4482 break;
4483 if (mask == AceRights[i].value)
4485 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4486 return;
4490 /* then check if it can be built from bit names */
4491 for (i = 0; i < 32; i++)
4493 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4495 /* can't be built from bit names */
4496 sprintfW(buf, fmtW, mask);
4497 DumpString(buf, -1, pwptr, plen);
4498 return;
4502 /* build from bit names */
4503 for (i = 0; i < 32; i++)
4504 if (mask & (1 << i))
4505 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4508 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4510 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4511 static const WCHAR openbr = '(';
4512 static const WCHAR closebr = ')';
4513 static const WCHAR semicolon = ';';
4515 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4517 SetLastError(ERROR_INVALID_ACL);
4518 return FALSE;
4521 piace = pace;
4522 DumpString(&openbr, 1, pwptr, plen);
4523 switch (piace->Header.AceType)
4525 case ACCESS_ALLOWED_ACE_TYPE:
4526 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4527 break;
4528 case ACCESS_DENIED_ACE_TYPE:
4529 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4530 break;
4531 case SYSTEM_AUDIT_ACE_TYPE:
4532 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4533 break;
4534 case SYSTEM_ALARM_ACE_TYPE:
4535 DumpString(SDDL_ALARM, -1, pwptr, plen);
4536 break;
4538 DumpString(&semicolon, 1, pwptr, plen);
4540 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4541 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4542 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4543 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4544 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4545 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4546 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4547 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4548 if (piace->Header.AceFlags & INHERITED_ACE)
4549 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4550 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4551 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4552 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4553 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4554 DumpString(&semicolon, 1, pwptr, plen);
4555 DumpRights(piace->Mask, pwptr, plen);
4556 DumpString(&semicolon, 1, pwptr, plen);
4557 /* objects not supported */
4558 DumpString(&semicolon, 1, pwptr, plen);
4559 /* objects not supported */
4560 DumpString(&semicolon, 1, pwptr, plen);
4561 if (!DumpSid(&piace->SidStart, pwptr, plen))
4562 return FALSE;
4563 DumpString(&closebr, 1, pwptr, plen);
4564 return TRUE;
4567 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4569 WORD count;
4570 int i;
4572 if (protected)
4573 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4574 if (autoInheritReq)
4575 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4576 if (autoInherited)
4577 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4579 if (pacl == NULL)
4580 return TRUE;
4582 if (!IsValidAcl(pacl))
4583 return FALSE;
4585 count = pacl->AceCount;
4586 for (i = 0; i < count; i++)
4588 LPVOID ace;
4589 if (!GetAce(pacl, i, &ace))
4590 return FALSE;
4591 if (!DumpAce(ace, pwptr, plen))
4592 return FALSE;
4595 return TRUE;
4598 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4600 static const WCHAR prefix[] = {'O',':',0};
4601 BOOL bDefaulted;
4602 PSID psid;
4604 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4605 return FALSE;
4607 if (psid == NULL)
4608 return TRUE;
4610 DumpString(prefix, -1, pwptr, plen);
4611 if (!DumpSid(psid, pwptr, plen))
4612 return FALSE;
4613 return TRUE;
4616 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4618 static const WCHAR prefix[] = {'G',':',0};
4619 BOOL bDefaulted;
4620 PSID psid;
4622 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4623 return FALSE;
4625 if (psid == NULL)
4626 return TRUE;
4628 DumpString(prefix, -1, pwptr, plen);
4629 if (!DumpSid(psid, pwptr, plen))
4630 return FALSE;
4631 return TRUE;
4634 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4636 static const WCHAR dacl[] = {'D',':',0};
4637 SECURITY_DESCRIPTOR_CONTROL control;
4638 BOOL present, defaulted;
4639 DWORD revision;
4640 PACL pacl;
4642 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4643 return FALSE;
4645 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4646 return FALSE;
4648 if (!present)
4649 return TRUE;
4651 DumpString(dacl, 2, pwptr, plen);
4652 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4653 return FALSE;
4654 return TRUE;
4657 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4659 static const WCHAR sacl[] = {'S',':',0};
4660 SECURITY_DESCRIPTOR_CONTROL control;
4661 BOOL present, defaulted;
4662 DWORD revision;
4663 PACL pacl;
4665 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4666 return FALSE;
4668 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4669 return FALSE;
4671 if (!present)
4672 return TRUE;
4674 DumpString(sacl, 2, pwptr, plen);
4675 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4676 return FALSE;
4677 return TRUE;
4680 /******************************************************************************
4681 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4683 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4685 ULONG len;
4686 WCHAR *wptr, *wstr;
4688 if (SDRevision != SDDL_REVISION_1)
4690 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4691 SetLastError(ERROR_UNKNOWN_REVISION);
4692 return FALSE;
4695 len = 0;
4696 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4697 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4698 return FALSE;
4699 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4700 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4701 return FALSE;
4702 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4703 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4704 return FALSE;
4705 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4706 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4707 return FALSE;
4709 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4710 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4711 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4712 return FALSE;
4713 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4714 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4715 return FALSE;
4716 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4717 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4718 return FALSE;
4719 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4720 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4721 return FALSE;
4722 *wptr = 0;
4724 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4725 *OutputString = wstr;
4726 if (OutputLen)
4727 *OutputLen = strlenW(*OutputString)+1;
4728 return TRUE;
4731 /******************************************************************************
4732 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4734 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4736 LPWSTR wstr;
4737 ULONG len;
4738 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4740 int lenA;
4742 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4743 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4744 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4745 LocalFree(wstr);
4747 if (OutputLen != NULL)
4748 *OutputLen = lenA;
4749 return TRUE;
4751 else
4753 *OutputString = NULL;
4754 if (OutputLen)
4755 *OutputLen = 0;
4756 return FALSE;
4760 /******************************************************************************
4761 * ConvertStringSidToSidW [ADVAPI32.@]
4763 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4765 BOOL bret = FALSE;
4766 DWORD cBytes;
4768 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4769 if (GetVersion() & 0x80000000)
4770 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4771 else if (!StringSid || !Sid)
4772 SetLastError(ERROR_INVALID_PARAMETER);
4773 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4775 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4777 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4778 if (!bret)
4779 LocalFree(*Sid);
4781 return bret;
4784 /******************************************************************************
4785 * ConvertStringSidToSidA [ADVAPI32.@]
4787 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4789 BOOL bret = FALSE;
4791 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4792 if (GetVersion() & 0x80000000)
4793 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4794 else if (!StringSid || !Sid)
4795 SetLastError(ERROR_INVALID_PARAMETER);
4796 else
4798 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4799 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4800 len * sizeof(WCHAR));
4802 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4803 bret = ConvertStringSidToSidW(wStringSid, Sid);
4804 HeapFree(GetProcessHeap(), 0, wStringSid);
4806 return bret;
4809 /******************************************************************************
4810 * ConvertSidToStringSidW [ADVAPI32.@]
4812 * format of SID string is:
4813 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4814 * where
4815 * <rev> is the revision of the SID encoded as decimal
4816 * <auth> is the identifier authority encoded as hex
4817 * <subauthN> is the subauthority id encoded as decimal
4819 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4821 DWORD len = 0;
4822 LPWSTR wstr, wptr;
4824 TRACE("%p %p\n", pSid, pstr );
4826 len = 0;
4827 if (!DumpSidNumeric(pSid, NULL, &len))
4828 return FALSE;
4829 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4830 DumpSidNumeric(pSid, &wptr, NULL);
4831 *wptr = 0;
4833 *pstr = wstr;
4834 return TRUE;
4837 /******************************************************************************
4838 * ConvertSidToStringSidA [ADVAPI32.@]
4840 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4842 LPWSTR wstr = NULL;
4843 LPSTR str;
4844 UINT len;
4846 TRACE("%p %p\n", pSid, pstr );
4848 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4849 return FALSE;
4851 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4852 str = LocalAlloc( 0, len );
4853 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4854 LocalFree( wstr );
4856 *pstr = str;
4858 return TRUE;
4861 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4862 PSECURITY_DESCRIPTOR pdesc,
4863 PSECURITY_DESCRIPTOR cdesc,
4864 PSECURITY_DESCRIPTOR* ndesc,
4865 GUID* objtype,
4866 BOOL isdir,
4867 PGENERIC_MAPPING genmap )
4869 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4871 return FALSE;
4874 BOOL WINAPI CreatePrivateObjectSecurity(
4875 PSECURITY_DESCRIPTOR ParentDescriptor,
4876 PSECURITY_DESCRIPTOR CreatorDescriptor,
4877 PSECURITY_DESCRIPTOR* NewDescriptor,
4878 BOOL IsDirectoryObject,
4879 HANDLE Token,
4880 PGENERIC_MAPPING GenericMapping )
4882 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4883 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4885 return FALSE;
4888 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4890 FIXME("%p - stub\n", ObjectDescriptor);
4892 return TRUE;
4895 BOOL WINAPI CreateProcessAsUserA(
4896 HANDLE hToken,
4897 LPCSTR lpApplicationName,
4898 LPSTR lpCommandLine,
4899 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4900 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4901 BOOL bInheritHandles,
4902 DWORD dwCreationFlags,
4903 LPVOID lpEnvironment,
4904 LPCSTR lpCurrentDirectory,
4905 LPSTARTUPINFOA lpStartupInfo,
4906 LPPROCESS_INFORMATION lpProcessInformation )
4908 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4909 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4910 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4912 return FALSE;
4915 BOOL WINAPI CreateProcessAsUserW(
4916 HANDLE hToken,
4917 LPCWSTR lpApplicationName,
4918 LPWSTR lpCommandLine,
4919 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4920 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4921 BOOL bInheritHandles,
4922 DWORD dwCreationFlags,
4923 LPVOID lpEnvironment,
4924 LPCWSTR lpCurrentDirectory,
4925 LPSTARTUPINFOW lpStartupInfo,
4926 LPPROCESS_INFORMATION lpProcessInformation )
4928 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4929 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4930 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4931 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4933 /* We should create the process with a suspended main thread */
4934 if (!CreateProcessW (lpApplicationName,
4935 lpCommandLine,
4936 lpProcessAttributes,
4937 lpThreadAttributes,
4938 bInheritHandles,
4939 dwCreationFlags, /* CREATE_SUSPENDED */
4940 lpEnvironment,
4941 lpCurrentDirectory,
4942 lpStartupInfo,
4943 lpProcessInformation))
4945 return FALSE;
4948 return TRUE;
4951 /******************************************************************************
4952 * CreateProcessWithLogonW
4954 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4955 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4956 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4958 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4959 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4960 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4961 lpStartupInfo, lpProcessInformation);
4963 return FALSE;
4966 /******************************************************************************
4967 * DuplicateTokenEx [ADVAPI32.@]
4969 BOOL WINAPI DuplicateTokenEx(
4970 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4971 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4972 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4973 TOKEN_TYPE TokenType,
4974 PHANDLE DuplicateTokenHandle )
4976 OBJECT_ATTRIBUTES ObjectAttributes;
4978 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4979 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4981 InitializeObjectAttributes(
4982 &ObjectAttributes,
4983 NULL,
4984 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4985 NULL,
4986 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4988 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4989 dwDesiredAccess,
4990 &ObjectAttributes,
4991 ImpersonationLevel,
4992 TokenType,
4993 DuplicateTokenHandle ) );
4996 BOOL WINAPI DuplicateToken(
4997 HANDLE ExistingTokenHandle,
4998 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4999 PHANDLE DuplicateTokenHandle )
5001 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5002 NULL, ImpersonationLevel, TokenImpersonation,
5003 DuplicateTokenHandle );
5006 /******************************************************************************
5007 * ComputeStringSidSize
5009 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5011 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5013 int ctok = 0;
5014 while (*StringSid)
5016 if (*StringSid == '-')
5017 ctok++;
5018 StringSid++;
5021 if (ctok >= 3)
5022 return GetSidLengthRequired(ctok - 2);
5024 else /* String constant format - Only available in winxp and above */
5026 unsigned int i;
5028 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5029 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5030 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5033 return GetSidLengthRequired(0);
5036 /******************************************************************************
5037 * ParseStringSidToSid
5039 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5041 BOOL bret = FALSE;
5042 SID* pisid=pSid;
5044 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5045 if (!StringSid)
5047 SetLastError(ERROR_INVALID_PARAMETER);
5048 TRACE("StringSid is NULL, returning FALSE\n");
5049 return FALSE;
5052 *cBytes = ComputeStringSidSize(StringSid);
5053 if (!pisid) /* Simply compute the size */
5055 TRACE("only size requested, returning TRUE\n");
5056 return TRUE;
5059 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5061 DWORD i = 0, identAuth;
5062 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5064 StringSid += 2; /* Advance to Revision */
5065 pisid->Revision = atoiW(StringSid);
5067 if (pisid->Revision != SDDL_REVISION)
5069 TRACE("Revision %d is unknown\n", pisid->Revision);
5070 goto lend; /* ERROR_INVALID_SID */
5072 if (csubauth == 0)
5074 TRACE("SubAuthorityCount is 0\n");
5075 goto lend; /* ERROR_INVALID_SID */
5078 pisid->SubAuthorityCount = csubauth;
5080 /* Advance to identifier authority */
5081 while (*StringSid && *StringSid != '-')
5082 StringSid++;
5083 if (*StringSid == '-')
5084 StringSid++;
5086 /* MS' implementation can't handle values greater than 2^32 - 1, so
5087 * we don't either; assume most significant bytes are always 0
5089 pisid->IdentifierAuthority.Value[0] = 0;
5090 pisid->IdentifierAuthority.Value[1] = 0;
5091 identAuth = atoiW(StringSid);
5092 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5093 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5094 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5095 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5097 /* Advance to first sub authority */
5098 while (*StringSid && *StringSid != '-')
5099 StringSid++;
5100 if (*StringSid == '-')
5101 StringSid++;
5103 while (*StringSid)
5105 pisid->SubAuthority[i++] = atoiW(StringSid);
5107 while (*StringSid && *StringSid != '-')
5108 StringSid++;
5109 if (*StringSid == '-')
5110 StringSid++;
5113 if (i != pisid->SubAuthorityCount)
5114 goto lend; /* ERROR_INVALID_SID */
5116 bret = TRUE;
5118 else /* String constant format - Only available in winxp and above */
5120 unsigned int i;
5121 pisid->Revision = SDDL_REVISION;
5123 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5124 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5126 DWORD j;
5127 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5128 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5129 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5130 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5131 bret = TRUE;
5134 if (!bret)
5135 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5138 lend:
5139 if (!bret)
5140 SetLastError(ERROR_INVALID_SID);
5142 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5143 return bret;
5146 /******************************************************************************
5147 * GetNamedSecurityInfoA [ADVAPI32.@]
5149 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5150 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5151 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5152 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5154 DWORD len;
5155 LPWSTR wstr = NULL;
5156 DWORD r;
5158 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5159 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5161 if( pObjectName )
5163 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5164 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5165 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5168 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5169 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5171 HeapFree( GetProcessHeap(), 0, wstr );
5173 return r;
5176 /******************************************************************************
5177 * GetNamedSecurityInfoW [ADVAPI32.@]
5179 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5180 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5181 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5183 DWORD needed, offset;
5184 SECURITY_DESCRIPTOR_RELATIVE *relative;
5185 BYTE *buffer;
5187 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5188 group, dacl, sacl, descriptor );
5190 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5192 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5193 if (info & OWNER_SECURITY_INFORMATION)
5194 needed += sizeof(sidWorld);
5195 if (info & GROUP_SECURITY_INFORMATION)
5196 needed += sizeof(sidWorld);
5197 if (info & DACL_SECURITY_INFORMATION)
5198 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5199 if (info & SACL_SECURITY_INFORMATION)
5200 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5202 /* must be freed by caller */
5203 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5204 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5206 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5208 HeapFree( GetProcessHeap(), 0, *descriptor );
5209 return ERROR_INVALID_SECURITY_DESCR;
5212 relative = *descriptor;
5213 relative->Control |= SE_SELF_RELATIVE;
5214 buffer = (BYTE *)relative;
5215 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5217 if (info & OWNER_SECURITY_INFORMATION)
5219 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5220 relative->Owner = offset;
5221 if (owner)
5222 *owner = buffer + offset;
5223 offset += sizeof(sidWorld);
5225 if (info & GROUP_SECURITY_INFORMATION)
5227 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5228 relative->Group = offset;
5229 if (group)
5230 *group = buffer + offset;
5231 offset += sizeof(sidWorld);
5233 if (info & DACL_SECURITY_INFORMATION)
5235 relative->Control |= SE_DACL_PRESENT;
5236 GetWorldAccessACL( (PACL)(buffer + offset) );
5237 relative->Dacl = offset;
5238 if (dacl)
5239 *dacl = (PACL)(buffer + offset);
5240 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5242 if (info & SACL_SECURITY_INFORMATION)
5244 relative->Control |= SE_SACL_PRESENT;
5245 GetWorldAccessACL( (PACL)(buffer + offset) );
5246 relative->Sacl = offset;
5247 if (sacl)
5248 *sacl = (PACL)(buffer + offset);
5250 return ERROR_SUCCESS;
5253 /******************************************************************************
5254 * DecryptFileW [ADVAPI32.@]
5256 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5258 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5259 return TRUE;
5262 /******************************************************************************
5263 * DecryptFileA [ADVAPI32.@]
5265 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5267 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5268 return TRUE;
5271 /******************************************************************************
5272 * EncryptFileW [ADVAPI32.@]
5274 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5276 FIXME("%s\n", debugstr_w(lpFileName));
5277 return TRUE;
5280 /******************************************************************************
5281 * EncryptFileA [ADVAPI32.@]
5283 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5285 FIXME("%s\n", debugstr_a(lpFileName));
5286 return TRUE;
5289 /******************************************************************************
5290 * FileEncryptionStatusW [ADVAPI32.@]
5292 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5294 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5295 if (!lpStatus)
5296 return FALSE;
5297 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5298 return TRUE;
5301 /******************************************************************************
5302 * FileEncryptionStatusA [ADVAPI32.@]
5304 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5306 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5307 if (!lpStatus)
5308 return FALSE;
5309 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5310 return TRUE;
5313 /******************************************************************************
5314 * SetSecurityInfo [ADVAPI32.@]
5316 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5317 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5318 PSID psidGroup, PACL pDacl, PACL pSacl) {
5319 FIXME("stub\n");
5320 return ERROR_SUCCESS;
5323 /******************************************************************************
5324 * SaferCreateLevel [ADVAPI32.@]
5326 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5327 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5329 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5330 return FALSE;
5333 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5334 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5335 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5336 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5337 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5339 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5340 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5341 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5343 return ERROR_SUCCESS;
5346 /******************************************************************************
5347 * SaferGetPolicyInformation [ADVAPI32.@]
5349 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5350 PVOID buffer, PDWORD required, LPVOID lpReserved)
5352 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5353 return FALSE;