wined3d: Pass a wined3d_gl_info structure to send_attribute().
[wine/multimedia.git] / dlls / advapi32 / security.c
blob0458033cf978bc630eda7b91773e86754a0988a1
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <string.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
51 PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56 LPCWSTR StringSecurityDescriptor,
57 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
58 LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
61 typedef struct _ACEFLAG
63 LPCWSTR wstr;
64 DWORD value;
65 } ACEFLAG, *LPACEFLAG;
67 typedef struct _MAX_SID
69 /* same fields as struct _SID */
70 BYTE Revision;
71 BYTE SubAuthorityCount;
72 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
76 typedef struct WELLKNOWNSID
78 WCHAR wstr[2];
79 WELL_KNOWN_SID_TYPE Type;
80 MAX_SID Sid;
81 } WELLKNOWNSID;
83 static const WELLKNOWNSID WellKnownSids[] =
85 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
128 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
142 WELL_KNOWN_SID_TYPE Type;
143 DWORD Rid;
144 } WELLKNOWNRID;
146 static const WELLKNOWNRID WellKnownRids[] = {
147 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
148 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
149 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
150 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
151 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
152 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
153 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
154 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
155 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
156 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
159 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
165 typedef struct _AccountSid {
166 WELL_KNOWN_SID_TYPE type;
167 LPCWSTR account;
168 LPCWSTR domain;
169 SID_NAME_USE name_use;
170 LPCWSTR alias;
171 } AccountSid;
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
216 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
223 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
236 static const AccountSid ACCOUNT_SIDS[] = {
237 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
283 * ACE access rights
285 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
290 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
300 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
305 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
310 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
335 * ACE flags
337 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
345 const char * debugstr_sid(PSID sid)
347 int auth = 0;
348 SID * psid = sid;
350 if (psid == NULL)
351 return "(null)";
353 auth = psid->IdentifierAuthority.Value[5] +
354 (psid->IdentifierAuthority.Value[4] << 8) +
355 (psid->IdentifierAuthority.Value[3] << 16) +
356 (psid->IdentifierAuthority.Value[2] << 24);
358 switch (psid->SubAuthorityCount) {
359 case 0:
360 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361 case 1:
362 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363 psid->SubAuthority[0]);
364 case 2:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1]);
367 case 3:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370 case 4:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3]);
374 case 5:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[3], psid->SubAuthority[4]);
378 case 6:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382 case 7:
383 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386 psid->SubAuthority[6]);
387 case 8:
388 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391 psid->SubAuthority[6], psid->SubAuthority[7]);
393 return "(too-big)";
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
400 if (status) SetLastError( RtlNtStatusToDosError( status ));
401 return !status;
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
406 static void GetWorldAccessACL(PACL pACL)
408 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
410 pACL->AclRevision = ACL_REVISION;
411 pACL->Sbz1 = 0;
412 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413 pACL->AceCount = 1;
414 pACL->Sbz2 = 0;
416 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
423 /************************************************************
424 * ADVAPI_IsLocalComputer
426 * Checks whether the server name indicates local machine.
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
430 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431 BOOL Result;
432 LPWSTR buf;
434 if (!ServerName || !ServerName[0])
435 return TRUE;
437 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438 Result = GetComputerNameW(buf, &dwSize);
439 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440 ServerName += 2;
441 Result = Result && !lstrcmpW(ServerName, buf);
442 HeapFree(GetProcessHeap(), 0, buf);
444 return Result;
447 /************************************************************
448 * ADVAPI_GetComputerSid
450 * Reads the computer SID from the registry.
452 BOOL ADVAPI_GetComputerSid(PSID sid)
454 HKEY key;
455 LONG ret;
456 BOOL retval = FALSE;
457 static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
458 static const WCHAR V[] = { 'V',0 };
460 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461 KEY_READ, &key)) == ERROR_SUCCESS)
463 DWORD size = 0;
464 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
467 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468 if (data)
470 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471 data, &size)) == ERROR_SUCCESS)
473 /* the SID is in the last 24 bytes of the binary data */
474 CopyMemory(sid, &data[size-24], 24);
475 retval = TRUE;
477 HeapFree(GetProcessHeap(), 0, data);
480 RegCloseKey(key);
483 if(retval == TRUE) return retval;
485 /* create a new random SID */
486 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
489 PSID new_sid;
490 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491 DWORD id[3];
493 if (RtlGenRandom(id, sizeof(id)))
495 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
497 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
500 FreeSid(new_sid);
503 RegCloseKey(key);
506 return retval;
509 /* ##############################
510 ###### TOKEN FUNCTIONS ######
511 ##############################
514 /******************************************************************************
515 * OpenProcessToken [ADVAPI32.@]
516 * Opens the access token associated with a process handle.
518 * PARAMS
519 * ProcessHandle [I] Handle to process
520 * DesiredAccess [I] Desired access to process
521 * TokenHandle [O] Pointer to handle of open access token
523 * RETURNS
524 * Success: TRUE. TokenHandle contains the access token.
525 * Failure: FALSE.
527 * NOTES
528 * See NtOpenProcessToken.
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532 HANDLE *TokenHandle )
534 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
537 /******************************************************************************
538 * OpenThreadToken [ADVAPI32.@]
540 * Opens the access token associated with a thread handle.
542 * PARAMS
543 * ThreadHandle [I] Handle to process
544 * DesiredAccess [I] Desired access to the thread
545 * OpenAsSelf [I] ???
546 * TokenHandle [O] Destination for the token handle
548 * RETURNS
549 * Success: TRUE. TokenHandle contains the access token.
550 * Failure: FALSE.
552 * NOTES
553 * See NtOpenThreadToken.
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557 BOOL OpenAsSelf, HANDLE *TokenHandle)
559 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
566 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567 PreviousState, ReturnLength));
570 /******************************************************************************
571 * AdjustTokenPrivileges [ADVAPI32.@]
573 * Adjust the privileges of an open token handle.
575 * PARAMS
576 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
577 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
578 * NewState [I] Desired new privileges of the token
579 * BufferLength [I] Length of NewState
580 * PreviousState [O] Destination for the previous state
581 * ReturnLength [I/O] Size of PreviousState
584 * RETURNS
585 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586 * Failure: FALSE.
588 * NOTES
589 * See NtAdjustPrivilegesToken.
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
596 NTSTATUS status;
598 TRACE("\n");
600 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601 NewState, BufferLength, PreviousState,
602 ReturnLength);
603 SetLastError( RtlNtStatusToDosError( status ));
604 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605 return TRUE;
606 else
607 return FALSE;
610 /******************************************************************************
611 * CheckTokenMembership [ADVAPI32.@]
613 * Determine if an access token is a member of a SID.
615 * PARAMS
616 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617 * SidToCheck [I] SID that possibly contains the token
618 * IsMember [O] Destination for result.
620 * RETURNS
621 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622 * Failure: FALSE.
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE token, PSID sid_to_check,
626 PBOOL is_member )
628 PTOKEN_GROUPS token_groups = NULL;
629 HANDLE thread_token = NULL;
630 DWORD size, i;
631 BOOL ret;
633 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
635 *is_member = FALSE;
637 if (!token)
639 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
641 HANDLE process_token;
642 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
643 if (!ret)
644 goto exit;
645 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
646 NULL, SecurityImpersonation, TokenImpersonation,
647 &thread_token);
648 CloseHandle(process_token);
649 if (!ret)
650 goto exit;
652 token = thread_token;
655 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
656 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
657 goto exit;
659 token_groups = HeapAlloc(GetProcessHeap(), 0, size);
660 if (!token_groups)
662 ret = FALSE;
663 goto exit;
666 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
667 if (!ret)
668 goto exit;
670 for (i = 0; i < token_groups->GroupCount; i++)
672 TRACE("Groups[%d]: {0x%x, %s}\n", i,
673 token_groups->Groups[i].Attributes,
674 debugstr_sid(token_groups->Groups[i].Sid));
675 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
676 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
678 *is_member = TRUE;
679 TRACE("sid enabled and found in token\n");
680 break;
684 exit:
685 HeapFree(GetProcessHeap(), 0, token_groups);
686 if (thread_token != NULL) CloseHandle(thread_token);
688 return ret;
691 /******************************************************************************
692 * GetTokenInformation [ADVAPI32.@]
694 * Get a type of information about an access token.
696 * PARAMS
697 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
698 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
699 * tokeninfo [O] Destination for token information
700 * tokeninfolength [I] Length of tokeninfo
701 * retlen [O] Destination for returned token information length
703 * RETURNS
704 * Success: TRUE. tokeninfo contains retlen bytes of token information
705 * Failure: FALSE.
707 * NOTES
708 * See NtQueryInformationToken.
710 BOOL WINAPI
711 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
712 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
714 TRACE("(%p, %s, %p, %d, %p):\n",
715 token,
716 (tokeninfoclass == TokenUser) ? "TokenUser" :
717 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
718 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
719 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
720 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
721 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
722 (tokeninfoclass == TokenSource) ? "TokenSource" :
723 (tokeninfoclass == TokenType) ? "TokenType" :
724 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
725 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
726 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
727 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
728 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
729 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
730 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
731 "Unknown",
732 tokeninfo, tokeninfolength, retlen);
733 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
734 tokeninfolength, retlen));
737 /******************************************************************************
738 * SetTokenInformation [ADVAPI32.@]
740 * Set information for an access token.
742 * PARAMS
743 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
744 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
745 * tokeninfo [I] Token information to set
746 * tokeninfolength [I] Length of tokeninfo
748 * RETURNS
749 * Success: TRUE. The information for the token is set to tokeninfo.
750 * Failure: FALSE.
752 BOOL WINAPI
753 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
754 LPVOID tokeninfo, DWORD tokeninfolength )
756 TRACE("(%p, %s, %p, %d): stub\n",
757 token,
758 (tokeninfoclass == TokenUser) ? "TokenUser" :
759 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
760 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
761 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
762 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
763 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
764 (tokeninfoclass == TokenSource) ? "TokenSource" :
765 (tokeninfoclass == TokenType) ? "TokenType" :
766 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
767 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
768 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
769 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
770 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
771 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
772 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
773 "Unknown",
774 tokeninfo, tokeninfolength);
776 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
779 /*************************************************************************
780 * SetThreadToken [ADVAPI32.@]
782 * Assigns an 'impersonation token' to a thread so it can assume the
783 * security privileges of another thread or process. Can also remove
784 * a previously assigned token.
786 * PARAMS
787 * thread [O] Handle to thread to set the token for
788 * token [I] Token to set
790 * RETURNS
791 * Success: TRUE. The threads access token is set to token
792 * Failure: FALSE.
794 * NOTES
795 * Only supported on NT or higher. On Win9X this function does nothing.
796 * See SetTokenInformation.
798 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
800 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
801 ThreadImpersonationToken, &token, sizeof token ));
804 /*************************************************************************
805 * CreateRestrictedToken [ADVAPI32.@]
807 * Create a new more restricted token from an existing token.
809 * PARAMS
810 * baseToken [I] Token to base the new restricted token on
811 * flags [I] Options
812 * nDisableSids [I] Length of disableSids array
813 * disableSids [I] Array of SIDs to disable in the new token
814 * nDeletePrivs [I] Length of deletePrivs array
815 * deletePrivs [I] Array of privileges to delete in the new token
816 * nRestrictSids [I] Length of restrictSids array
817 * restrictSids [I] Array of SIDs to restrict in the new token
818 * newToken [O] Address where the new token is stored
820 * RETURNS
821 * Success: TRUE
822 * Failure: FALSE
824 BOOL WINAPI CreateRestrictedToken(
825 HANDLE baseToken,
826 DWORD flags,
827 DWORD nDisableSids,
828 PSID_AND_ATTRIBUTES disableSids,
829 DWORD nDeletePrivs,
830 PLUID_AND_ATTRIBUTES deletePrivs,
831 DWORD nRestrictSids,
832 PSID_AND_ATTRIBUTES restrictSids,
833 PHANDLE newToken)
835 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
836 baseToken, flags, nDisableSids, disableSids,
837 nDeletePrivs, deletePrivs,
838 nRestrictSids, restrictSids,
839 newToken);
840 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
841 return FALSE;
844 /* ##############################
845 ###### SID FUNCTIONS ######
846 ##############################
849 /******************************************************************************
850 * AllocateAndInitializeSid [ADVAPI32.@]
852 * PARAMS
853 * pIdentifierAuthority []
854 * nSubAuthorityCount []
855 * nSubAuthority0 []
856 * nSubAuthority1 []
857 * nSubAuthority2 []
858 * nSubAuthority3 []
859 * nSubAuthority4 []
860 * nSubAuthority5 []
861 * nSubAuthority6 []
862 * nSubAuthority7 []
863 * pSid []
865 BOOL WINAPI
866 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
867 BYTE nSubAuthorityCount,
868 DWORD nSubAuthority0, DWORD nSubAuthority1,
869 DWORD nSubAuthority2, DWORD nSubAuthority3,
870 DWORD nSubAuthority4, DWORD nSubAuthority5,
871 DWORD nSubAuthority6, DWORD nSubAuthority7,
872 PSID *pSid )
874 return set_ntstatus( RtlAllocateAndInitializeSid(
875 pIdentifierAuthority, nSubAuthorityCount,
876 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
877 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
878 pSid ));
881 /******************************************************************************
882 * FreeSid [ADVAPI32.@]
884 * PARAMS
885 * pSid []
887 PVOID WINAPI
888 FreeSid( PSID pSid )
890 RtlFreeSid(pSid);
891 return NULL; /* is documented like this */
894 /******************************************************************************
895 * CopySid [ADVAPI32.@]
897 * PARAMS
898 * nDestinationSidLength []
899 * pDestinationSid []
900 * pSourceSid []
902 BOOL WINAPI
903 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
905 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
908 /******************************************************************************
909 * CreateWellKnownSid [ADVAPI32.@]
911 BOOL WINAPI
912 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
913 PSID DomainSid,
914 PSID pSid,
915 DWORD* cbSid)
917 unsigned int i;
918 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
920 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
922 SetLastError(ERROR_INVALID_PARAMETER);
923 return FALSE;
926 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
927 if (WellKnownSids[i].Type == WellKnownSidType) {
928 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
930 if (*cbSid < length)
932 *cbSid = length;
933 SetLastError(ERROR_INSUFFICIENT_BUFFER);
934 return FALSE;
936 if (!pSid)
938 SetLastError(ERROR_INVALID_PARAMETER);
939 return FALSE;
941 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
942 *cbSid = length;
943 return TRUE;
947 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return FALSE;
953 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
954 if (WellKnownRids[i].Type == WellKnownSidType) {
955 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
956 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
957 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
959 if (*cbSid < output_sid_length)
961 *cbSid = output_sid_length;
962 SetLastError(ERROR_INSUFFICIENT_BUFFER);
963 return FALSE;
965 if (!pSid)
967 SetLastError(ERROR_INVALID_PARAMETER);
968 return FALSE;
970 CopyMemory(pSid, DomainSid, domain_sid_length);
971 (*GetSidSubAuthorityCount(pSid))++;
972 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
973 *cbSid = output_sid_length;
974 return TRUE;
977 SetLastError(ERROR_INVALID_PARAMETER);
978 return FALSE;
981 /******************************************************************************
982 * IsWellKnownSid [ADVAPI32.@]
984 BOOL WINAPI
985 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
987 unsigned int i;
988 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
990 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
991 if (WellKnownSids[i].Type == WellKnownSidType)
992 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
993 return TRUE;
995 return FALSE;
998 BOOL WINAPI
999 IsTokenRestricted( HANDLE TokenHandle )
1001 TOKEN_GROUPS *groups;
1002 DWORD size;
1003 NTSTATUS status;
1004 BOOL restricted;
1006 TRACE("(%p)\n", TokenHandle);
1008 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1009 if (status != STATUS_BUFFER_TOO_SMALL)
1010 return FALSE;
1012 groups = HeapAlloc(GetProcessHeap(), 0, size);
1013 if (!groups)
1015 SetLastError(ERROR_OUTOFMEMORY);
1016 return FALSE;
1019 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1020 if (status != STATUS_SUCCESS)
1022 HeapFree(GetProcessHeap(), 0, groups);
1023 return set_ntstatus(status);
1026 if (groups->GroupCount)
1027 restricted = TRUE;
1028 else
1029 restricted = FALSE;
1031 HeapFree(GetProcessHeap(), 0, groups);
1033 return restricted;
1036 /******************************************************************************
1037 * IsValidSid [ADVAPI32.@]
1039 * PARAMS
1040 * pSid []
1042 BOOL WINAPI
1043 IsValidSid( PSID pSid )
1045 return RtlValidSid( pSid );
1048 /******************************************************************************
1049 * EqualSid [ADVAPI32.@]
1051 * PARAMS
1052 * pSid1 []
1053 * pSid2 []
1055 BOOL WINAPI
1056 EqualSid( PSID pSid1, PSID pSid2 )
1058 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1059 SetLastError(ERROR_SUCCESS);
1060 return ret;
1063 /******************************************************************************
1064 * EqualPrefixSid [ADVAPI32.@]
1066 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1068 return RtlEqualPrefixSid(pSid1, pSid2);
1071 /******************************************************************************
1072 * GetSidLengthRequired [ADVAPI32.@]
1074 * PARAMS
1075 * nSubAuthorityCount []
1077 DWORD WINAPI
1078 GetSidLengthRequired( BYTE nSubAuthorityCount )
1080 return RtlLengthRequiredSid(nSubAuthorityCount);
1083 /******************************************************************************
1084 * InitializeSid [ADVAPI32.@]
1086 * PARAMS
1087 * pIdentifierAuthority []
1089 BOOL WINAPI
1090 InitializeSid (
1091 PSID pSid,
1092 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1093 BYTE nSubAuthorityCount)
1095 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1098 DWORD WINAPI
1099 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1101 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1103 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1104 return 0;
1107 DWORD WINAPI
1108 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1110 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1112 return 1;
1115 /******************************************************************************
1116 * GetSidIdentifierAuthority [ADVAPI32.@]
1118 * PARAMS
1119 * pSid []
1121 PSID_IDENTIFIER_AUTHORITY WINAPI
1122 GetSidIdentifierAuthority( PSID pSid )
1124 return RtlIdentifierAuthoritySid(pSid);
1127 /******************************************************************************
1128 * GetSidSubAuthority [ADVAPI32.@]
1130 * PARAMS
1131 * pSid []
1132 * nSubAuthority []
1134 PDWORD WINAPI
1135 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1137 SetLastError(ERROR_SUCCESS);
1138 return RtlSubAuthoritySid(pSid, nSubAuthority);
1141 /******************************************************************************
1142 * GetSidSubAuthorityCount [ADVAPI32.@]
1144 * PARAMS
1145 * pSid []
1147 PUCHAR WINAPI
1148 GetSidSubAuthorityCount (PSID pSid)
1150 SetLastError(ERROR_SUCCESS);
1151 return RtlSubAuthorityCountSid(pSid);
1154 /******************************************************************************
1155 * GetLengthSid [ADVAPI32.@]
1157 * PARAMS
1158 * pSid []
1160 DWORD WINAPI
1161 GetLengthSid (PSID pSid)
1163 return RtlLengthSid(pSid);
1166 /* ##############################################
1167 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1168 ##############################################
1171 /******************************************************************************
1172 * BuildSecurityDescriptorA [ADVAPI32.@]
1174 * Builds a SD from
1176 * PARAMS
1177 * pOwner [I]
1178 * pGroup [I]
1179 * cCountOfAccessEntries [I]
1180 * pListOfAccessEntries [I]
1181 * cCountOfAuditEntries [I]
1182 * pListofAuditEntries [I]
1183 * pOldSD [I]
1184 * lpdwBufferLength [I/O]
1185 * pNewSD [O]
1187 * RETURNS
1188 * Success: ERROR_SUCCESS
1189 * Failure: nonzero error code from Winerror.h
1191 DWORD WINAPI BuildSecurityDescriptorA(
1192 IN PTRUSTEEA pOwner,
1193 IN PTRUSTEEA pGroup,
1194 IN ULONG cCountOfAccessEntries,
1195 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1196 IN ULONG cCountOfAuditEntries,
1197 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1198 IN PSECURITY_DESCRIPTOR pOldSD,
1199 IN OUT PULONG lpdwBufferLength,
1200 OUT PSECURITY_DESCRIPTOR* pNewSD)
1202 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1203 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1204 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1206 return ERROR_CALL_NOT_IMPLEMENTED;
1209 /******************************************************************************
1210 * BuildSecurityDescriptorW [ADVAPI32.@]
1212 * See BuildSecurityDescriptorA.
1214 DWORD WINAPI BuildSecurityDescriptorW(
1215 IN PTRUSTEEW pOwner,
1216 IN PTRUSTEEW pGroup,
1217 IN ULONG cCountOfAccessEntries,
1218 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1219 IN ULONG cCountOfAuditEntries,
1220 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1221 IN PSECURITY_DESCRIPTOR pOldSD,
1222 IN OUT PULONG lpdwBufferLength,
1223 OUT PSECURITY_DESCRIPTOR* pNewSD)
1225 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1226 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1227 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1229 return ERROR_CALL_NOT_IMPLEMENTED;
1232 /******************************************************************************
1233 * InitializeSecurityDescriptor [ADVAPI32.@]
1235 * PARAMS
1236 * pDescr []
1237 * revision []
1239 BOOL WINAPI
1240 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1242 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1246 /******************************************************************************
1247 * MakeAbsoluteSD [ADVAPI32.@]
1249 BOOL WINAPI MakeAbsoluteSD (
1250 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1251 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1252 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1253 OUT PACL pDacl,
1254 OUT LPDWORD lpdwDaclSize,
1255 OUT PACL pSacl,
1256 OUT LPDWORD lpdwSaclSize,
1257 OUT PSID pOwner,
1258 OUT LPDWORD lpdwOwnerSize,
1259 OUT PSID pPrimaryGroup,
1260 OUT LPDWORD lpdwPrimaryGroupSize)
1262 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1263 pAbsoluteSecurityDescriptor,
1264 lpdwAbsoluteSecurityDescriptorSize,
1265 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1266 pOwner, lpdwOwnerSize,
1267 pPrimaryGroup, lpdwPrimaryGroupSize));
1270 /******************************************************************************
1271 * GetKernelObjectSecurity [ADVAPI32.@]
1273 BOOL WINAPI GetKernelObjectSecurity(
1274 HANDLE Handle,
1275 SECURITY_INFORMATION RequestedInformation,
1276 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1277 DWORD nLength,
1278 LPDWORD lpnLengthNeeded )
1280 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1281 pSecurityDescriptor, nLength, lpnLengthNeeded);
1283 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1284 nLength, lpnLengthNeeded ));
1287 /******************************************************************************
1288 * GetPrivateObjectSecurity [ADVAPI32.@]
1290 BOOL WINAPI GetPrivateObjectSecurity(
1291 PSECURITY_DESCRIPTOR ObjectDescriptor,
1292 SECURITY_INFORMATION SecurityInformation,
1293 PSECURITY_DESCRIPTOR ResultantDescriptor,
1294 DWORD DescriptorLength,
1295 PDWORD ReturnLength )
1297 SECURITY_DESCRIPTOR desc;
1298 BOOL defaulted, present;
1299 PACL pacl;
1300 PSID psid;
1302 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1303 ResultantDescriptor, DescriptorLength, ReturnLength);
1305 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1306 return FALSE;
1308 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1310 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1311 return FALSE;
1312 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1315 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1317 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1318 return FALSE;
1319 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1322 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1324 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1325 return FALSE;
1326 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1329 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1331 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1332 return FALSE;
1333 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1336 *ReturnLength = DescriptorLength;
1337 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1340 /******************************************************************************
1341 * GetSecurityDescriptorLength [ADVAPI32.@]
1343 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1345 return RtlLengthSecurityDescriptor(pDescr);
1348 /******************************************************************************
1349 * GetSecurityDescriptorOwner [ADVAPI32.@]
1351 * PARAMS
1352 * pOwner []
1353 * lpbOwnerDefaulted []
1355 BOOL WINAPI
1356 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1357 LPBOOL lpbOwnerDefaulted )
1359 BOOLEAN defaulted;
1360 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1361 *lpbOwnerDefaulted = defaulted;
1362 return ret;
1365 /******************************************************************************
1366 * SetSecurityDescriptorOwner [ADVAPI32.@]
1368 * PARAMS
1370 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1371 PSID pOwner, BOOL bOwnerDefaulted)
1373 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1375 /******************************************************************************
1376 * GetSecurityDescriptorGroup [ADVAPI32.@]
1378 BOOL WINAPI GetSecurityDescriptorGroup(
1379 PSECURITY_DESCRIPTOR SecurityDescriptor,
1380 PSID *Group,
1381 LPBOOL GroupDefaulted)
1383 BOOLEAN defaulted;
1384 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1385 *GroupDefaulted = defaulted;
1386 return ret;
1388 /******************************************************************************
1389 * SetSecurityDescriptorGroup [ADVAPI32.@]
1391 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1392 PSID Group, BOOL GroupDefaulted)
1394 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1397 /******************************************************************************
1398 * IsValidSecurityDescriptor [ADVAPI32.@]
1400 * PARAMS
1401 * lpsecdesc []
1403 BOOL WINAPI
1404 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1406 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1409 /******************************************************************************
1410 * GetSecurityDescriptorDacl [ADVAPI32.@]
1412 BOOL WINAPI GetSecurityDescriptorDacl(
1413 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1414 OUT LPBOOL lpbDaclPresent,
1415 OUT PACL *pDacl,
1416 OUT LPBOOL lpbDaclDefaulted)
1418 BOOLEAN present, defaulted;
1419 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1420 *lpbDaclPresent = present;
1421 *lpbDaclDefaulted = defaulted;
1422 return ret;
1425 /******************************************************************************
1426 * SetSecurityDescriptorDacl [ADVAPI32.@]
1428 BOOL WINAPI
1429 SetSecurityDescriptorDacl (
1430 PSECURITY_DESCRIPTOR lpsd,
1431 BOOL daclpresent,
1432 PACL dacl,
1433 BOOL dacldefaulted )
1435 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1437 /******************************************************************************
1438 * GetSecurityDescriptorSacl [ADVAPI32.@]
1440 BOOL WINAPI GetSecurityDescriptorSacl(
1441 IN PSECURITY_DESCRIPTOR lpsd,
1442 OUT LPBOOL lpbSaclPresent,
1443 OUT PACL *pSacl,
1444 OUT LPBOOL lpbSaclDefaulted)
1446 BOOLEAN present, defaulted;
1447 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1448 *lpbSaclPresent = present;
1449 *lpbSaclDefaulted = defaulted;
1450 return ret;
1453 /**************************************************************************
1454 * SetSecurityDescriptorSacl [ADVAPI32.@]
1456 BOOL WINAPI SetSecurityDescriptorSacl (
1457 PSECURITY_DESCRIPTOR lpsd,
1458 BOOL saclpresent,
1459 PACL lpsacl,
1460 BOOL sacldefaulted)
1462 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1464 /******************************************************************************
1465 * MakeSelfRelativeSD [ADVAPI32.@]
1467 * PARAMS
1468 * lpabssecdesc []
1469 * lpselfsecdesc []
1470 * lpbuflen []
1472 BOOL WINAPI
1473 MakeSelfRelativeSD(
1474 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1475 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1476 IN OUT LPDWORD lpdwBufferLength)
1478 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1479 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1482 /******************************************************************************
1483 * GetSecurityDescriptorControl [ADVAPI32.@]
1486 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1487 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1489 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1492 /******************************************************************************
1493 * SetSecurityDescriptorControl [ADVAPI32.@]
1495 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1496 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1497 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1499 return set_ntstatus( RtlSetControlSecurityDescriptor(
1500 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1503 /* ##############################
1504 ###### ACL FUNCTIONS ######
1505 ##############################
1508 /*************************************************************************
1509 * InitializeAcl [ADVAPI32.@]
1511 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1513 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1516 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1518 IO_STATUS_BLOCK io_block;
1520 TRACE("(%p)\n", hNamedPipe);
1522 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1523 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1526 /******************************************************************************
1527 * AddAccessAllowedAce [ADVAPI32.@]
1529 BOOL WINAPI AddAccessAllowedAce(
1530 IN OUT PACL pAcl,
1531 IN DWORD dwAceRevision,
1532 IN DWORD AccessMask,
1533 IN PSID pSid)
1535 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1538 /******************************************************************************
1539 * AddAccessAllowedAceEx [ADVAPI32.@]
1541 BOOL WINAPI AddAccessAllowedAceEx(
1542 IN OUT PACL pAcl,
1543 IN DWORD dwAceRevision,
1544 IN DWORD AceFlags,
1545 IN DWORD AccessMask,
1546 IN PSID pSid)
1548 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1551 /******************************************************************************
1552 * AddAccessDeniedAce [ADVAPI32.@]
1554 BOOL WINAPI AddAccessDeniedAce(
1555 IN OUT PACL pAcl,
1556 IN DWORD dwAceRevision,
1557 IN DWORD AccessMask,
1558 IN PSID pSid)
1560 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1563 /******************************************************************************
1564 * AddAccessDeniedAceEx [ADVAPI32.@]
1566 BOOL WINAPI AddAccessDeniedAceEx(
1567 IN OUT PACL pAcl,
1568 IN DWORD dwAceRevision,
1569 IN DWORD AceFlags,
1570 IN DWORD AccessMask,
1571 IN PSID pSid)
1573 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1576 /******************************************************************************
1577 * AddAce [ADVAPI32.@]
1579 BOOL WINAPI AddAce(
1580 IN OUT PACL pAcl,
1581 IN DWORD dwAceRevision,
1582 IN DWORD dwStartingAceIndex,
1583 LPVOID pAceList,
1584 DWORD nAceListLength)
1586 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1589 /******************************************************************************
1590 * DeleteAce [ADVAPI32.@]
1592 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1594 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1597 /******************************************************************************
1598 * FindFirstFreeAce [ADVAPI32.@]
1600 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1602 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1605 /******************************************************************************
1606 * GetAce [ADVAPI32.@]
1608 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1610 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1613 /******************************************************************************
1614 * GetAclInformation [ADVAPI32.@]
1616 BOOL WINAPI GetAclInformation(
1617 PACL pAcl,
1618 LPVOID pAclInformation,
1619 DWORD nAclInformationLength,
1620 ACL_INFORMATION_CLASS dwAclInformationClass)
1622 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1623 nAclInformationLength, dwAclInformationClass));
1626 /******************************************************************************
1627 * IsValidAcl [ADVAPI32.@]
1629 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1631 return RtlValidAcl(pAcl);
1634 /* ##############################
1635 ###### MISC FUNCTIONS ######
1636 ##############################
1639 /******************************************************************************
1640 * AllocateLocallyUniqueId [ADVAPI32.@]
1642 * PARAMS
1643 * lpLuid []
1645 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1647 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1650 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1651 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1652 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1653 { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1654 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1655 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1656 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1657 { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1658 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1659 { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1660 static const WCHAR SE_TCB_NAME_W[] =
1661 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1662 static const WCHAR SE_SECURITY_NAME_W[] =
1663 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1664 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1665 { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1666 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1667 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1668 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1669 { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1670 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1671 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1672 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1673 { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1674 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1675 { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1676 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1677 { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1678 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1679 { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1680 static const WCHAR SE_BACKUP_NAME_W[] =
1681 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1682 static const WCHAR SE_RESTORE_NAME_W[] =
1683 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1684 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1685 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1686 static const WCHAR SE_DEBUG_NAME_W[] =
1687 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1688 static const WCHAR SE_AUDIT_NAME_W[] =
1689 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1690 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1691 { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1692 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1693 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1694 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1695 { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1696 static const WCHAR SE_UNDOCK_NAME_W[] =
1697 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1698 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1699 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1700 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1701 { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1702 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1703 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1704 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1705 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1706 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1707 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1709 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1711 NULL,
1712 NULL,
1713 SE_CREATE_TOKEN_NAME_W,
1714 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1715 SE_LOCK_MEMORY_NAME_W,
1716 SE_INCREASE_QUOTA_NAME_W,
1717 SE_MACHINE_ACCOUNT_NAME_W,
1718 SE_TCB_NAME_W,
1719 SE_SECURITY_NAME_W,
1720 SE_TAKE_OWNERSHIP_NAME_W,
1721 SE_LOAD_DRIVER_NAME_W,
1722 SE_SYSTEM_PROFILE_NAME_W,
1723 SE_SYSTEMTIME_NAME_W,
1724 SE_PROF_SINGLE_PROCESS_NAME_W,
1725 SE_INC_BASE_PRIORITY_NAME_W,
1726 SE_CREATE_PAGEFILE_NAME_W,
1727 SE_CREATE_PERMANENT_NAME_W,
1728 SE_BACKUP_NAME_W,
1729 SE_RESTORE_NAME_W,
1730 SE_SHUTDOWN_NAME_W,
1731 SE_DEBUG_NAME_W,
1732 SE_AUDIT_NAME_W,
1733 SE_SYSTEM_ENVIRONMENT_NAME_W,
1734 SE_CHANGE_NOTIFY_NAME_W,
1735 SE_REMOTE_SHUTDOWN_NAME_W,
1736 SE_UNDOCK_NAME_W,
1737 SE_SYNC_AGENT_NAME_W,
1738 SE_ENABLE_DELEGATION_NAME_W,
1739 SE_MANAGE_VOLUME_NAME_W,
1740 SE_IMPERSONATE_NAME_W,
1741 SE_CREATE_GLOBAL_NAME_W,
1744 /******************************************************************************
1745 * LookupPrivilegeValueW [ADVAPI32.@]
1747 * See LookupPrivilegeValueA.
1749 BOOL WINAPI
1750 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1752 UINT i;
1754 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1756 if (!ADVAPI_IsLocalComputer(lpSystemName))
1758 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1759 return FALSE;
1761 if (!lpName)
1763 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1764 return FALSE;
1766 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1768 if( !WellKnownPrivNames[i] )
1769 continue;
1770 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1771 continue;
1772 lpLuid->LowPart = i;
1773 lpLuid->HighPart = 0;
1774 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1775 lpLuid->HighPart, lpLuid->LowPart );
1776 return TRUE;
1778 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1779 return FALSE;
1782 /******************************************************************************
1783 * LookupPrivilegeValueA [ADVAPI32.@]
1785 * Retrieves LUID used on a system to represent the privilege name.
1787 * PARAMS
1788 * lpSystemName [I] Name of the system
1789 * lpName [I] Name of the privilege
1790 * lpLuid [O] Destination for the resulting LUID
1792 * RETURNS
1793 * Success: TRUE. lpLuid contains the requested LUID.
1794 * Failure: FALSE.
1796 BOOL WINAPI
1797 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1799 UNICODE_STRING lpSystemNameW;
1800 UNICODE_STRING lpNameW;
1801 BOOL ret;
1803 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1804 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1805 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1806 RtlFreeUnicodeString(&lpNameW);
1807 RtlFreeUnicodeString(&lpSystemNameW);
1808 return ret;
1811 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1812 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1814 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1815 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1817 return FALSE;
1820 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1821 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1823 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1824 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1826 return FALSE;
1829 /******************************************************************************
1830 * LookupPrivilegeNameA [ADVAPI32.@]
1832 * See LookupPrivilegeNameW.
1834 BOOL WINAPI
1835 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1836 LPDWORD cchName)
1838 UNICODE_STRING lpSystemNameW;
1839 BOOL ret;
1840 DWORD wLen = 0;
1842 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1844 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1845 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1846 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1848 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1850 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1851 &wLen);
1852 if (ret)
1854 /* Windows crashes if cchName is NULL, so will I */
1855 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1856 *cchName, NULL, NULL);
1858 if (len == 0)
1860 /* WideCharToMultiByte failed */
1861 ret = FALSE;
1863 else if (len > *cchName)
1865 *cchName = len;
1866 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1867 ret = FALSE;
1869 else
1871 /* WideCharToMultiByte succeeded, output length needs to be
1872 * length not including NULL terminator
1874 *cchName = len - 1;
1877 HeapFree(GetProcessHeap(), 0, lpNameW);
1879 RtlFreeUnicodeString(&lpSystemNameW);
1880 return ret;
1883 /******************************************************************************
1884 * LookupPrivilegeNameW [ADVAPI32.@]
1886 * Retrieves the privilege name referred to by the LUID lpLuid.
1888 * PARAMS
1889 * lpSystemName [I] Name of the system
1890 * lpLuid [I] Privilege value
1891 * lpName [O] Name of the privilege
1892 * cchName [I/O] Number of characters in lpName.
1894 * RETURNS
1895 * Success: TRUE. lpName contains the name of the privilege whose value is
1896 * *lpLuid.
1897 * Failure: FALSE.
1899 * REMARKS
1900 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1901 * using this function.
1902 * If the length of lpName is too small, on return *cchName will contain the
1903 * number of WCHARs needed to contain the privilege, including the NULL
1904 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1905 * On success, *cchName will contain the number of characters stored in
1906 * lpName, NOT including the NULL terminator.
1908 BOOL WINAPI
1909 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1910 LPDWORD cchName)
1912 size_t privNameLen;
1914 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1916 if (!ADVAPI_IsLocalComputer(lpSystemName))
1918 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1919 return FALSE;
1921 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1922 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1924 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1925 return FALSE;
1927 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1928 /* Windows crashes if cchName is NULL, so will I */
1929 if (*cchName <= privNameLen)
1931 *cchName = privNameLen + 1;
1932 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1933 return FALSE;
1935 else
1937 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1938 *cchName = privNameLen;
1939 return TRUE;
1943 /******************************************************************************
1944 * GetFileSecurityA [ADVAPI32.@]
1946 * Obtains Specified information about the security of a file or directory.
1948 * PARAMS
1949 * lpFileName [I] Name of the file to get info for
1950 * RequestedInformation [I] SE_ flags from "winnt.h"
1951 * pSecurityDescriptor [O] Destination for security information
1952 * nLength [I] Length of pSecurityDescriptor
1953 * lpnLengthNeeded [O] Destination for length of returned security information
1955 * RETURNS
1956 * Success: TRUE. pSecurityDescriptor contains the requested information.
1957 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1959 * NOTES
1960 * The information returned is constrained by the callers access rights and
1961 * privileges.
1963 BOOL WINAPI
1964 GetFileSecurityA( LPCSTR lpFileName,
1965 SECURITY_INFORMATION RequestedInformation,
1966 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1967 DWORD nLength, LPDWORD lpnLengthNeeded )
1969 DWORD len;
1970 BOOL r;
1971 LPWSTR name = NULL;
1973 if( lpFileName )
1975 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1976 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1977 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1980 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1981 nLength, lpnLengthNeeded );
1982 HeapFree( GetProcessHeap(), 0, name );
1984 return r;
1987 /******************************************************************************
1988 * GetFileSecurityW [ADVAPI32.@]
1990 * See GetFileSecurityA.
1992 BOOL WINAPI
1993 GetFileSecurityW( LPCWSTR lpFileName,
1994 SECURITY_INFORMATION RequestedInformation,
1995 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1996 DWORD nLength, LPDWORD lpnLengthNeeded )
1998 HANDLE hfile;
1999 NTSTATUS status;
2000 DWORD access = 0;
2002 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2003 RequestedInformation, pSecurityDescriptor,
2004 nLength, lpnLengthNeeded);
2006 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2007 DACL_SECURITY_INFORMATION))
2008 access |= READ_CONTROL;
2009 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2010 access |= ACCESS_SYSTEM_SECURITY;
2012 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2013 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2014 if ( hfile == INVALID_HANDLE_VALUE )
2015 return FALSE;
2017 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2018 nLength, lpnLengthNeeded );
2019 CloseHandle( hfile );
2020 return set_ntstatus( status );
2024 /******************************************************************************
2025 * LookupAccountSidA [ADVAPI32.@]
2027 BOOL WINAPI
2028 LookupAccountSidA(
2029 IN LPCSTR system,
2030 IN PSID sid,
2031 OUT LPSTR account,
2032 IN OUT LPDWORD accountSize,
2033 OUT LPSTR domain,
2034 IN OUT LPDWORD domainSize,
2035 OUT PSID_NAME_USE name_use )
2037 DWORD len;
2038 BOOL r;
2039 LPWSTR systemW = NULL;
2040 LPWSTR accountW = NULL;
2041 LPWSTR domainW = NULL;
2042 DWORD accountSizeW = *accountSize;
2043 DWORD domainSizeW = *domainSize;
2045 if (system) {
2046 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2047 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2048 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2050 if (account)
2051 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2052 if (domain)
2053 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2055 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2057 if (r) {
2058 if (accountW && *accountSize) {
2059 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2060 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2061 *accountSize = len;
2062 } else
2063 *accountSize = accountSizeW + 1;
2065 if (domainW && *domainSize) {
2066 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2067 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2068 *domainSize = len;
2069 } else
2070 *domainSize = domainSizeW + 1;
2072 else
2074 *accountSize = accountSizeW + 1;
2075 *domainSize = domainSizeW + 1;
2078 HeapFree( GetProcessHeap(), 0, systemW );
2079 HeapFree( GetProcessHeap(), 0, accountW );
2080 HeapFree( GetProcessHeap(), 0, domainW );
2082 return r;
2085 /******************************************************************************
2086 * LookupAccountSidW [ADVAPI32.@]
2088 * PARAMS
2089 * system []
2090 * sid []
2091 * account []
2092 * accountSize []
2093 * domain []
2094 * domainSize []
2095 * name_use []
2098 BOOL WINAPI
2099 LookupAccountSidW(
2100 IN LPCWSTR system,
2101 IN PSID sid,
2102 OUT LPWSTR account,
2103 IN OUT LPDWORD accountSize,
2104 OUT LPWSTR domain,
2105 IN OUT LPDWORD domainSize,
2106 OUT PSID_NAME_USE name_use )
2108 unsigned int i, j;
2109 const WCHAR * ac = NULL;
2110 const WCHAR * dm = NULL;
2111 SID_NAME_USE use = 0;
2112 LPWSTR computer_name = NULL;
2113 LPWSTR account_name = NULL;
2115 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2116 debugstr_w(system),debugstr_sid(sid),
2117 account,accountSize,accountSize?*accountSize:0,
2118 domain,domainSize,domainSize?*domainSize:0,
2119 name_use);
2121 if (!ADVAPI_IsLocalComputer(system)) {
2122 FIXME("Only local computer supported!\n");
2123 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2124 return FALSE;
2127 /* check the well known SIDs first */
2128 for (i = 0; i <= 60; i++) {
2129 if (IsWellKnownSid(sid, i)) {
2130 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2131 if (ACCOUNT_SIDS[j].type == i) {
2132 ac = ACCOUNT_SIDS[j].account;
2133 dm = ACCOUNT_SIDS[j].domain;
2134 use = ACCOUNT_SIDS[j].name_use;
2137 break;
2141 if (dm == NULL) {
2142 MAX_SID local;
2144 /* check for the local computer next */
2145 if (ADVAPI_GetComputerSid(&local)) {
2146 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2147 BOOL result;
2149 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2150 result = GetComputerNameW(computer_name, &size);
2152 if (result) {
2153 if (EqualSid(sid, &local)) {
2154 dm = computer_name;
2155 ac = Blank;
2156 use = 3;
2157 } else {
2158 local.SubAuthorityCount++;
2160 if (EqualPrefixSid(sid, &local)) {
2161 dm = computer_name;
2162 use = 1;
2163 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2164 case DOMAIN_USER_RID_ADMIN:
2165 ac = Administrator;
2166 break;
2167 case DOMAIN_USER_RID_GUEST:
2168 ac = Guest;
2169 break;
2170 case DOMAIN_GROUP_RID_ADMINS:
2171 ac = Domain_Admins;
2172 break;
2173 case DOMAIN_GROUP_RID_USERS:
2174 ac = Domain_Users;
2175 break;
2176 case DOMAIN_GROUP_RID_GUESTS:
2177 ac = Domain_Guests;
2178 break;
2179 case DOMAIN_GROUP_RID_COMPUTERS:
2180 ac = Domain_Computers;
2181 break;
2182 case DOMAIN_GROUP_RID_CONTROLLERS:
2183 ac = Domain_Controllers;
2184 break;
2185 case DOMAIN_GROUP_RID_CERT_ADMINS:
2186 ac = Cert_Publishers;
2187 break;
2188 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2189 ac = Schema_Admins;
2190 break;
2191 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2192 ac = Enterprise_Admins;
2193 break;
2194 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2195 ac = Group_Policy_Creator_Owners;
2196 break;
2197 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2198 ac = RAS_and_IAS_Servers;
2199 break;
2200 case 1000: /* first user account */
2201 size = UNLEN + 1;
2202 account_name = HeapAlloc(
2203 GetProcessHeap(), 0, size * sizeof(WCHAR));
2204 if (GetUserNameW(account_name, &size))
2205 ac = account_name;
2206 else
2207 dm = NULL;
2209 break;
2210 default:
2211 dm = NULL;
2212 break;
2220 if (dm) {
2221 DWORD ac_len = lstrlenW(ac);
2222 DWORD dm_len = lstrlenW(dm);
2223 BOOL status = TRUE;
2225 if (*accountSize > ac_len) {
2226 if (account)
2227 lstrcpyW(account, ac);
2229 if (*domainSize > dm_len) {
2230 if (domain)
2231 lstrcpyW(domain, dm);
2233 if ((*accountSize && *accountSize < ac_len) ||
2234 (!account && !*accountSize && ac_len) ||
2235 (*domainSize && *domainSize < dm_len) ||
2236 (!domain && !*domainSize && dm_len))
2238 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2239 status = FALSE;
2241 if (*domainSize)
2242 *domainSize = dm_len;
2243 else
2244 *domainSize = dm_len + 1;
2245 if (*accountSize)
2246 *accountSize = ac_len;
2247 else
2248 *accountSize = ac_len + 1;
2250 HeapFree(GetProcessHeap(), 0, account_name);
2251 HeapFree(GetProcessHeap(), 0, computer_name);
2252 if (status) *name_use = use;
2253 return status;
2256 HeapFree(GetProcessHeap(), 0, account_name);
2257 HeapFree(GetProcessHeap(), 0, computer_name);
2258 SetLastError(ERROR_NONE_MAPPED);
2259 return FALSE;
2262 /******************************************************************************
2263 * SetFileSecurityA [ADVAPI32.@]
2265 * See SetFileSecurityW.
2267 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2268 SECURITY_INFORMATION RequestedInformation,
2269 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2271 DWORD len;
2272 BOOL r;
2273 LPWSTR name = NULL;
2275 if( lpFileName )
2277 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2278 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2279 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2282 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2283 HeapFree( GetProcessHeap(), 0, name );
2285 return r;
2288 /******************************************************************************
2289 * SetFileSecurityW [ADVAPI32.@]
2291 * Sets the security of a file or directory.
2293 * PARAMS
2294 * lpFileName []
2295 * RequestedInformation []
2296 * pSecurityDescriptor []
2298 * RETURNS
2299 * Success: TRUE.
2300 * Failure: FALSE.
2302 BOOL WINAPI
2303 SetFileSecurityW( LPCWSTR lpFileName,
2304 SECURITY_INFORMATION RequestedInformation,
2305 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2307 HANDLE file;
2308 DWORD access = 0;
2309 NTSTATUS status;
2311 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2312 pSecurityDescriptor );
2314 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2315 RequestedInformation & GROUP_SECURITY_INFORMATION)
2316 access |= WRITE_OWNER;
2317 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2318 access |= ACCESS_SYSTEM_SECURITY;
2319 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2320 access |= WRITE_DAC;
2322 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2323 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2324 if (file == INVALID_HANDLE_VALUE)
2325 return FALSE;
2327 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2328 CloseHandle( file );
2329 return set_ntstatus( status );
2332 /******************************************************************************
2333 * QueryWindows31FilesMigration [ADVAPI32.@]
2335 * PARAMS
2336 * x1 []
2338 BOOL WINAPI
2339 QueryWindows31FilesMigration( DWORD x1 )
2341 FIXME("(%d):stub\n",x1);
2342 return TRUE;
2345 /******************************************************************************
2346 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2348 * PARAMS
2349 * x1 []
2350 * x2 []
2351 * x3 []
2352 * x4 []
2354 BOOL WINAPI
2355 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2356 DWORD x4 )
2358 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2359 return TRUE;
2362 /******************************************************************************
2363 * NotifyBootConfigStatus [ADVAPI32.@]
2365 * PARAMS
2366 * x1 []
2368 BOOL WINAPI
2369 NotifyBootConfigStatus( BOOL x1 )
2371 FIXME("(0x%08d):stub\n",x1);
2372 return 1;
2375 /******************************************************************************
2376 * RevertToSelf [ADVAPI32.@]
2378 * Ends the impersonation of a user.
2380 * PARAMS
2381 * void []
2383 * RETURNS
2384 * Success: TRUE.
2385 * Failure: FALSE.
2387 BOOL WINAPI
2388 RevertToSelf( void )
2390 HANDLE Token = NULL;
2391 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2392 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2395 /******************************************************************************
2396 * ImpersonateSelf [ADVAPI32.@]
2398 * Makes an impersonation token that represents the process user and assigns
2399 * to the current thread.
2401 * PARAMS
2402 * ImpersonationLevel [I] Level at which to impersonate.
2404 * RETURNS
2405 * Success: TRUE.
2406 * Failure: FALSE.
2408 BOOL WINAPI
2409 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2411 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2414 /******************************************************************************
2415 * ImpersonateLoggedOnUser [ADVAPI32.@]
2417 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2419 DWORD size;
2420 NTSTATUS Status;
2421 HANDLE ImpersonationToken;
2422 TOKEN_TYPE Type;
2423 static BOOL warn = TRUE;
2425 if (warn)
2427 FIXME( "(%p)\n", hToken );
2428 warn = FALSE;
2430 if (!GetTokenInformation( hToken, TokenType, &Type,
2431 sizeof(TOKEN_TYPE), &size ))
2432 return FALSE;
2434 if (Type == TokenPrimary)
2436 OBJECT_ATTRIBUTES ObjectAttributes;
2438 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2440 Status = NtDuplicateToken( hToken,
2441 TOKEN_IMPERSONATE | TOKEN_QUERY,
2442 &ObjectAttributes,
2443 SecurityImpersonation,
2444 TokenImpersonation,
2445 &ImpersonationToken );
2446 if (Status != STATUS_SUCCESS)
2448 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2449 SetLastError( RtlNtStatusToDosError( Status ) );
2450 return FALSE;
2453 else
2454 ImpersonationToken = hToken;
2456 Status = NtSetInformationThread( GetCurrentThread(),
2457 ThreadImpersonationToken,
2458 &ImpersonationToken,
2459 sizeof(ImpersonationToken) );
2461 if (Type == TokenPrimary)
2462 NtClose( ImpersonationToken );
2464 if (Status != STATUS_SUCCESS)
2466 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2467 SetLastError( RtlNtStatusToDosError( Status ) );
2468 return FALSE;
2471 return TRUE;
2474 /******************************************************************************
2475 * AccessCheck [ADVAPI32.@]
2477 BOOL WINAPI
2478 AccessCheck(
2479 PSECURITY_DESCRIPTOR SecurityDescriptor,
2480 HANDLE ClientToken,
2481 DWORD DesiredAccess,
2482 PGENERIC_MAPPING GenericMapping,
2483 PPRIVILEGE_SET PrivilegeSet,
2484 LPDWORD PrivilegeSetLength,
2485 LPDWORD GrantedAccess,
2486 LPBOOL AccessStatus)
2488 NTSTATUS access_status;
2489 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2490 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2491 GrantedAccess, &access_status) );
2492 if (ret) *AccessStatus = set_ntstatus( access_status );
2493 return ret;
2497 /******************************************************************************
2498 * AccessCheckByType [ADVAPI32.@]
2500 BOOL WINAPI AccessCheckByType(
2501 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2502 PSID PrincipalSelfSid,
2503 HANDLE ClientToken,
2504 DWORD DesiredAccess,
2505 POBJECT_TYPE_LIST ObjectTypeList,
2506 DWORD ObjectTypeListLength,
2507 PGENERIC_MAPPING GenericMapping,
2508 PPRIVILEGE_SET PrivilegeSet,
2509 LPDWORD PrivilegeSetLength,
2510 LPDWORD GrantedAccess,
2511 LPBOOL AccessStatus)
2513 FIXME("stub\n");
2515 *AccessStatus = TRUE;
2517 return !*AccessStatus;
2520 /******************************************************************************
2521 * MapGenericMask [ADVAPI32.@]
2523 * Maps generic access rights into specific access rights according to the
2524 * supplied mapping.
2526 * PARAMS
2527 * AccessMask [I/O] Access rights.
2528 * GenericMapping [I] The mapping between generic and specific rights.
2530 * RETURNS
2531 * Nothing.
2533 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2535 RtlMapGenericMask( AccessMask, GenericMapping );
2538 /*************************************************************************
2539 * SetKernelObjectSecurity [ADVAPI32.@]
2541 BOOL WINAPI SetKernelObjectSecurity (
2542 IN HANDLE Handle,
2543 IN SECURITY_INFORMATION SecurityInformation,
2544 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2546 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2550 /******************************************************************************
2551 * AddAuditAccessAce [ADVAPI32.@]
2553 BOOL WINAPI AddAuditAccessAce(
2554 IN OUT PACL pAcl,
2555 IN DWORD dwAceRevision,
2556 IN DWORD dwAccessMask,
2557 IN PSID pSid,
2558 IN BOOL bAuditSuccess,
2559 IN BOOL bAuditFailure)
2561 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2562 bAuditSuccess, bAuditFailure) );
2565 /******************************************************************************
2566 * AddAuditAccessAce [ADVAPI32.@]
2568 BOOL WINAPI AddAuditAccessAceEx(
2569 IN OUT PACL pAcl,
2570 IN DWORD dwAceRevision,
2571 IN DWORD dwAceFlags,
2572 IN DWORD dwAccessMask,
2573 IN PSID pSid,
2574 IN BOOL bAuditSuccess,
2575 IN BOOL bAuditFailure)
2577 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2578 bAuditSuccess, bAuditFailure) );
2581 /******************************************************************************
2582 * LookupAccountNameA [ADVAPI32.@]
2584 BOOL WINAPI
2585 LookupAccountNameA(
2586 IN LPCSTR system,
2587 IN LPCSTR account,
2588 OUT PSID sid,
2589 OUT LPDWORD cbSid,
2590 LPSTR ReferencedDomainName,
2591 IN OUT LPDWORD cbReferencedDomainName,
2592 OUT PSID_NAME_USE name_use )
2594 BOOL ret;
2595 UNICODE_STRING lpSystemW;
2596 UNICODE_STRING lpAccountW;
2597 LPWSTR lpReferencedDomainNameW = NULL;
2599 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2600 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2602 if (ReferencedDomainName)
2603 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2605 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2606 cbReferencedDomainName, name_use);
2608 if (ret && lpReferencedDomainNameW)
2610 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2611 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2614 RtlFreeUnicodeString(&lpSystemW);
2615 RtlFreeUnicodeString(&lpAccountW);
2616 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2618 return ret;
2621 /******************************************************************************
2622 * lookup_user_account_name
2624 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2625 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2627 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2628 DWORD len = sizeof(buffer);
2629 HANDLE token;
2630 BOOL ret;
2631 PSID pSid;
2632 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2633 DWORD nameLen;
2634 LPCWSTR domainName;
2636 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2638 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2639 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2642 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2643 CloseHandle( token );
2645 if (!ret) return FALSE;
2647 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2649 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2650 CopySid(*cbSid, Sid, pSid);
2651 if (*cbSid < GetLengthSid(pSid))
2653 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2654 ret = FALSE;
2656 *cbSid = GetLengthSid(pSid);
2658 domainName = dm;
2659 nameLen = strlenW(domainName);
2661 if (*cchReferencedDomainName <= nameLen || !ret)
2663 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2664 nameLen += 1;
2665 ret = FALSE;
2667 else if (ReferencedDomainName)
2668 strcpyW(ReferencedDomainName, domainName);
2670 *cchReferencedDomainName = nameLen;
2672 if (ret)
2673 *peUse = SidTypeUser;
2675 return ret;
2678 /******************************************************************************
2679 * lookup_computer_account_name
2681 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2682 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2684 MAX_SID local;
2685 BOOL ret;
2686 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2687 DWORD nameLen;
2688 LPCWSTR domainName;
2690 if ((ret = ADVAPI_GetComputerSid(&local)))
2692 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2693 CopySid(*cbSid, Sid, &local);
2694 if (*cbSid < GetLengthSid(&local))
2696 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2697 ret = FALSE;
2699 *cbSid = GetLengthSid(&local);
2702 domainName = dm;
2703 nameLen = strlenW(domainName);
2705 if (*cchReferencedDomainName <= nameLen || !ret)
2707 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2708 nameLen += 1;
2709 ret = FALSE;
2711 else if (ReferencedDomainName)
2712 strcpyW(ReferencedDomainName, domainName);
2714 *cchReferencedDomainName = nameLen;
2716 if (ret)
2717 *peUse = SidTypeDomain;
2719 return ret;
2722 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2723 LSA_UNICODE_STRING *domain )
2725 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2727 while (p > str->Buffer && *p != '\\') p--;
2729 if (*p == '\\')
2731 domain->Buffer = str->Buffer;
2732 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2734 account->Buffer = p + 1;
2735 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2737 else
2739 domain->Buffer = NULL;
2740 domain->Length = 0;
2742 account->Buffer = str->Buffer;
2743 account->Length = str->Length;
2747 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2749 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2751 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2752 return TRUE;
2754 return FALSE;
2757 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2759 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2761 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2762 return TRUE;
2764 if (ACCOUNT_SIDS[idx].alias)
2766 len = strlenW( ACCOUNT_SIDS[idx].alias );
2767 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2768 return TRUE;
2770 return FALSE;
2774 * Helper function for LookupAccountNameW
2776 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2777 PSID Sid, LPDWORD cbSid,
2778 LPWSTR ReferencedDomainName,
2779 LPDWORD cchReferencedDomainName,
2780 PSID_NAME_USE peUse, BOOL *handled )
2782 PSID pSid;
2783 LSA_UNICODE_STRING account, domain;
2784 BOOL ret = TRUE;
2785 ULONG i;
2787 *handled = FALSE;
2788 split_domain_account( account_and_domain, &account, &domain );
2790 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2792 /* check domain first */
2793 if (domain.Buffer && !match_domain( i, &domain )) continue;
2795 if (match_account( i, &account ))
2797 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2799 if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2801 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2803 if (*cbSid < sidLen)
2805 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2806 ret = FALSE;
2808 else if (Sid)
2810 CopySid(*cbSid, Sid, pSid);
2812 *cbSid = sidLen;
2815 len = strlenW( ACCOUNT_SIDS[i].domain );
2816 if (*cchReferencedDomainName <= len || !ret)
2818 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2819 len++;
2820 ret = FALSE;
2822 else if (ReferencedDomainName)
2824 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2827 *cchReferencedDomainName = len;
2828 if (ret)
2829 *peUse = ACCOUNT_SIDS[i].name_use;
2831 HeapFree(GetProcessHeap(), 0, pSid);
2832 *handled = TRUE;
2833 return ret;
2836 return ret;
2839 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2840 PSID Sid, LPDWORD cbSid,
2841 LPWSTR ReferencedDomainName,
2842 LPDWORD cchReferencedDomainName,
2843 PSID_NAME_USE peUse, BOOL *handled )
2845 DWORD nameLen;
2846 LPWSTR userName = NULL;
2847 LSA_UNICODE_STRING account, domain;
2848 BOOL ret = TRUE;
2850 *handled = FALSE;
2851 split_domain_account( account_and_domain, &account, &domain );
2853 /* Let the current Unix user id masquerade as first Windows user account */
2855 nameLen = UNLEN + 1;
2856 if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2858 if (domain.Buffer)
2860 /* check to make sure this account is on this computer */
2861 if (GetComputerNameW( userName, &nameLen ) &&
2862 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2864 SetLastError(ERROR_NONE_MAPPED);
2865 ret = FALSE;
2867 nameLen = UNLEN + 1;
2870 if (GetUserNameW( userName, &nameLen ) &&
2871 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2873 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2874 *handled = TRUE;
2876 else
2878 nameLen = UNLEN + 1;
2879 if (GetComputerNameW( userName, &nameLen ) &&
2880 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2882 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2883 *handled = TRUE;
2887 HeapFree(GetProcessHeap(), 0, userName);
2888 return ret;
2891 /******************************************************************************
2892 * LookupAccountNameW [ADVAPI32.@]
2894 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2895 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2896 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2898 BOOL ret, handled;
2899 LSA_UNICODE_STRING account;
2901 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2902 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2904 if (!ADVAPI_IsLocalComputer( lpSystemName ))
2906 SetLastError( RPC_S_SERVER_UNAVAILABLE );
2907 return FALSE;
2910 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2912 lpAccountName = BUILTIN;
2915 RtlInitUnicodeString( &account, lpAccountName );
2917 /* Check well known SIDs first */
2918 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2919 cchReferencedDomainName, peUse, &handled );
2920 if (handled)
2921 return ret;
2923 /* Check user names */
2924 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2925 cchReferencedDomainName, peUse, &handled);
2926 if (handled)
2927 return ret;
2929 SetLastError( ERROR_NONE_MAPPED );
2930 return FALSE;
2933 /******************************************************************************
2934 * PrivilegeCheck [ADVAPI32.@]
2936 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2938 BOOL ret;
2939 BOOLEAN Result;
2941 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2943 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2944 if (ret)
2945 *pfResult = Result;
2946 return ret;
2949 /******************************************************************************
2950 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2952 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2953 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2954 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2955 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2957 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2958 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2959 SecurityDescriptor, DesiredAccess, GenericMapping,
2960 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2961 return TRUE;
2964 /******************************************************************************
2965 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2967 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2968 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2969 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2970 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2972 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2973 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2974 SecurityDescriptor, DesiredAccess, GenericMapping,
2975 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2976 return TRUE;
2979 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2981 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2983 return TRUE;
2986 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2988 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2990 return TRUE;
2993 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2995 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2997 return TRUE;
3000 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3001 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3002 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3003 LPBOOL GenerateOnClose)
3005 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3006 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3007 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3008 GenerateOnClose);
3010 return TRUE;
3013 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3014 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3015 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3016 LPBOOL GenerateOnClose)
3018 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3019 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3020 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3021 GenerateOnClose);
3023 return TRUE;
3026 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3027 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3029 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3030 DesiredAccess, Privileges, AccessGranted);
3032 return TRUE;
3035 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3036 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3038 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3039 DesiredAccess, Privileges, AccessGranted);
3041 return TRUE;
3044 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3045 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3047 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3048 ClientToken, Privileges, AccessGranted);
3050 return TRUE;
3053 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3054 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3056 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3057 ClientToken, Privileges, AccessGranted);
3059 return TRUE;
3062 /******************************************************************************
3063 * GetSecurityInfo [ADVAPI32.@]
3065 * Retrieves a copy of the security descriptor associated with an object.
3067 * PARAMS
3068 * hObject [I] A handle for the object.
3069 * ObjectType [I] The type of object.
3070 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3071 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3072 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3073 * ppDacl [O] If non-null, receives a pointer to the DACL.
3074 * ppSacl [O] If non-null, receives a pointer to the SACL.
3075 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3076 * which must be freed with LocalFree.
3078 * RETURNS
3079 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3081 DWORD WINAPI GetSecurityInfo(
3082 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3083 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3084 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3085 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3088 PSECURITY_DESCRIPTOR sd;
3089 NTSTATUS status;
3090 ULONG n1, n2;
3091 BOOL present, defaulted;
3093 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3094 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3095 return RtlNtStatusToDosError(status);
3097 sd = LocalAlloc(0, n1);
3098 if (!sd)
3099 return ERROR_NOT_ENOUGH_MEMORY;
3101 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3102 if (status != STATUS_SUCCESS)
3104 LocalFree(sd);
3105 return RtlNtStatusToDosError(status);
3108 if (ppsidOwner)
3110 *ppsidOwner = NULL;
3111 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3113 if (ppsidGroup)
3115 *ppsidGroup = NULL;
3116 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3118 if (ppDacl)
3120 *ppDacl = NULL;
3121 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3123 if (ppSacl)
3125 *ppSacl = NULL;
3126 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3128 if (ppSecurityDescriptor)
3129 *ppSecurityDescriptor = sd;
3131 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3132 * NULL, because native happily returns the SIDs and ACLs that are requested
3133 * in this case.
3136 return ERROR_SUCCESS;
3139 /******************************************************************************
3140 * GetSecurityInfoExA [ADVAPI32.@]
3142 DWORD WINAPI GetSecurityInfoExA(
3143 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3144 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3145 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3146 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3149 FIXME("stub!\n");
3150 return ERROR_BAD_PROVIDER;
3153 /******************************************************************************
3154 * GetSecurityInfoExW [ADVAPI32.@]
3156 DWORD WINAPI GetSecurityInfoExW(
3157 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3158 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3159 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3160 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3163 FIXME("stub!\n");
3164 return ERROR_BAD_PROVIDER;
3167 /******************************************************************************
3168 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3170 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3171 LPSTR pTrusteeName, DWORD AccessPermissions,
3172 ACCESS_MODE AccessMode, DWORD Inheritance )
3174 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3175 AccessPermissions, AccessMode, Inheritance);
3177 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3178 pExplicitAccess->grfAccessMode = AccessMode;
3179 pExplicitAccess->grfInheritance = Inheritance;
3181 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3182 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3183 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3184 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3185 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3188 /******************************************************************************
3189 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3191 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3192 LPWSTR pTrusteeName, DWORD AccessPermissions,
3193 ACCESS_MODE AccessMode, DWORD Inheritance )
3195 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3196 AccessPermissions, AccessMode, Inheritance);
3198 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3199 pExplicitAccess->grfAccessMode = AccessMode;
3200 pExplicitAccess->grfInheritance = Inheritance;
3202 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3203 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3204 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3205 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3206 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3209 /******************************************************************************
3210 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3212 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3213 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3214 LPSTR InheritedObjectTypeName, LPSTR Name )
3216 DWORD ObjectsPresent = 0;
3218 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3219 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3221 /* Fill the OBJECTS_AND_NAME structure */
3222 pObjName->ObjectType = ObjectType;
3223 if (ObjectTypeName != NULL)
3225 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3228 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3229 if (InheritedObjectTypeName != NULL)
3231 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3234 pObjName->ObjectsPresent = ObjectsPresent;
3235 pObjName->ptstrName = Name;
3237 /* Fill the TRUSTEE structure */
3238 pTrustee->pMultipleTrustee = NULL;
3239 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3240 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3241 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3242 pTrustee->ptstrName = (LPSTR)pObjName;
3245 /******************************************************************************
3246 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3248 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3249 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3250 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3252 DWORD ObjectsPresent = 0;
3254 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3255 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3257 /* Fill the OBJECTS_AND_NAME structure */
3258 pObjName->ObjectType = ObjectType;
3259 if (ObjectTypeName != NULL)
3261 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3264 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3265 if (InheritedObjectTypeName != NULL)
3267 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3270 pObjName->ObjectsPresent = ObjectsPresent;
3271 pObjName->ptstrName = Name;
3273 /* Fill the TRUSTEE structure */
3274 pTrustee->pMultipleTrustee = NULL;
3275 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3276 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3277 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3278 pTrustee->ptstrName = (LPWSTR)pObjName;
3281 /******************************************************************************
3282 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3284 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3285 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3287 DWORD ObjectsPresent = 0;
3289 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3291 /* Fill the OBJECTS_AND_SID structure */
3292 if (pObjectGuid != NULL)
3294 pObjSid->ObjectTypeGuid = *pObjectGuid;
3295 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3297 else
3299 ZeroMemory(&pObjSid->ObjectTypeGuid,
3300 sizeof(GUID));
3303 if (pInheritedObjectGuid != NULL)
3305 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3306 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3308 else
3310 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3311 sizeof(GUID));
3314 pObjSid->ObjectsPresent = ObjectsPresent;
3315 pObjSid->pSid = pSid;
3317 /* Fill the TRUSTEE structure */
3318 pTrustee->pMultipleTrustee = NULL;
3319 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3320 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3321 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3322 pTrustee->ptstrName = (LPSTR) pObjSid;
3325 /******************************************************************************
3326 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3328 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3329 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3331 DWORD ObjectsPresent = 0;
3333 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3335 /* Fill the OBJECTS_AND_SID structure */
3336 if (pObjectGuid != NULL)
3338 pObjSid->ObjectTypeGuid = *pObjectGuid;
3339 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3341 else
3343 ZeroMemory(&pObjSid->ObjectTypeGuid,
3344 sizeof(GUID));
3347 if (pInheritedObjectGuid != NULL)
3349 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3350 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3352 else
3354 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3355 sizeof(GUID));
3358 pObjSid->ObjectsPresent = ObjectsPresent;
3359 pObjSid->pSid = pSid;
3361 /* Fill the TRUSTEE structure */
3362 pTrustee->pMultipleTrustee = NULL;
3363 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3364 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3365 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3366 pTrustee->ptstrName = (LPWSTR) pObjSid;
3369 /******************************************************************************
3370 * BuildTrusteeWithSidA [ADVAPI32.@]
3372 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3374 TRACE("%p %p\n", pTrustee, pSid);
3376 pTrustee->pMultipleTrustee = NULL;
3377 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3378 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3379 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3380 pTrustee->ptstrName = pSid;
3383 /******************************************************************************
3384 * BuildTrusteeWithSidW [ADVAPI32.@]
3386 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3388 TRACE("%p %p\n", pTrustee, pSid);
3390 pTrustee->pMultipleTrustee = NULL;
3391 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3392 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3393 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3394 pTrustee->ptstrName = pSid;
3397 /******************************************************************************
3398 * BuildTrusteeWithNameA [ADVAPI32.@]
3400 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3402 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3404 pTrustee->pMultipleTrustee = NULL;
3405 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3406 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3407 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3408 pTrustee->ptstrName = name;
3411 /******************************************************************************
3412 * BuildTrusteeWithNameW [ADVAPI32.@]
3414 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3416 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3418 pTrustee->pMultipleTrustee = NULL;
3419 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3420 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3421 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3422 pTrustee->ptstrName = name;
3425 /******************************************************************************
3426 * GetTrusteeFormA [ADVAPI32.@]
3428 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3430 TRACE("(%p)\n", pTrustee);
3432 if (!pTrustee)
3433 return TRUSTEE_BAD_FORM;
3435 return pTrustee->TrusteeForm;
3438 /******************************************************************************
3439 * GetTrusteeFormW [ADVAPI32.@]
3441 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3443 TRACE("(%p)\n", pTrustee);
3445 if (!pTrustee)
3446 return TRUSTEE_BAD_FORM;
3448 return pTrustee->TrusteeForm;
3451 /******************************************************************************
3452 * GetTrusteeNameA [ADVAPI32.@]
3454 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3456 TRACE("(%p)\n", pTrustee);
3458 if (!pTrustee)
3459 return NULL;
3461 return pTrustee->ptstrName;
3464 /******************************************************************************
3465 * GetTrusteeNameW [ADVAPI32.@]
3467 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3469 TRACE("(%p)\n", pTrustee);
3471 if (!pTrustee)
3472 return NULL;
3474 return pTrustee->ptstrName;
3477 /******************************************************************************
3478 * GetTrusteeTypeA [ADVAPI32.@]
3480 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3482 TRACE("(%p)\n", pTrustee);
3484 if (!pTrustee)
3485 return TRUSTEE_IS_UNKNOWN;
3487 return pTrustee->TrusteeType;
3490 /******************************************************************************
3491 * GetTrusteeTypeW [ADVAPI32.@]
3493 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3495 TRACE("(%p)\n", pTrustee);
3497 if (!pTrustee)
3498 return TRUSTEE_IS_UNKNOWN;
3500 return pTrustee->TrusteeType;
3503 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3504 DWORD nAclInformationLength,
3505 ACL_INFORMATION_CLASS dwAclInformationClass )
3507 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3508 nAclInformationLength, dwAclInformationClass);
3510 return TRUE;
3513 /******************************************************************************
3514 * SetEntriesInAclA [ADVAPI32.@]
3516 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3517 PACL OldAcl, PACL* NewAcl )
3519 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3520 if (NewAcl)
3521 *NewAcl = NULL;
3522 return ERROR_SUCCESS;
3525 /******************************************************************************
3526 * SetEntriesInAclW [ADVAPI32.@]
3528 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3529 PACL OldAcl, PACL* NewAcl )
3531 ULONG i;
3532 PSID *ppsid;
3533 DWORD ret = ERROR_SUCCESS;
3534 DWORD acl_size = sizeof(ACL);
3535 NTSTATUS status;
3537 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3539 *NewAcl = NULL;
3541 if (!count && !OldAcl)
3542 return ERROR_SUCCESS;
3544 /* allocate array of maximum sized sids allowed */
3545 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3546 if (!ppsid)
3547 return ERROR_OUTOFMEMORY;
3549 for (i = 0; i < count; i++)
3551 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3553 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3554 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3555 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3556 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3557 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3558 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3559 pEntries[i].Trustee.ptstrName);
3561 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3563 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3564 ret = ERROR_INVALID_PARAMETER;
3565 goto exit;
3568 switch (pEntries[i].Trustee.TrusteeForm)
3570 case TRUSTEE_IS_SID:
3571 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3572 ppsid[i], pEntries[i].Trustee.ptstrName))
3574 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3575 ret = ERROR_INVALID_PARAMETER;
3576 goto exit;
3578 break;
3579 case TRUSTEE_IS_NAME:
3581 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3582 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3583 SID_NAME_USE use;
3584 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3586 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3588 ret = GetLastError();
3589 goto exit;
3592 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3594 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3595 ret = ERROR_INVALID_PARAMETER;
3596 goto exit;
3598 break;
3600 case TRUSTEE_IS_OBJECTS_AND_SID:
3601 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3602 break;
3603 case TRUSTEE_IS_OBJECTS_AND_NAME:
3604 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3605 break;
3606 default:
3607 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3608 ret = ERROR_INVALID_PARAMETER;
3609 goto exit;
3612 /* Note: we overestimate the ACL size here as a tradeoff between
3613 * instructions (simplicity) and memory */
3614 switch (pEntries[i].grfAccessMode)
3616 case GRANT_ACCESS:
3617 case SET_ACCESS:
3618 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3619 break;
3620 case DENY_ACCESS:
3621 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3622 break;
3623 case SET_AUDIT_SUCCESS:
3624 case SET_AUDIT_FAILURE:
3625 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3626 break;
3627 case REVOKE_ACCESS:
3628 break;
3629 default:
3630 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3631 ret = ERROR_INVALID_PARAMETER;
3632 goto exit;
3636 if (OldAcl)
3638 ACL_SIZE_INFORMATION size_info;
3640 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3641 if (status != STATUS_SUCCESS)
3643 ret = RtlNtStatusToDosError(status);
3644 goto exit;
3646 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3649 *NewAcl = LocalAlloc(0, acl_size);
3650 if (!*NewAcl)
3652 ret = ERROR_OUTOFMEMORY;
3653 goto exit;
3656 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3657 if (status != STATUS_SUCCESS)
3659 ret = RtlNtStatusToDosError(status);
3660 goto exit;
3663 for (i = 0; i < count; i++)
3665 switch (pEntries[i].grfAccessMode)
3667 case GRANT_ACCESS:
3668 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3669 pEntries[i].grfInheritance,
3670 pEntries[i].grfAccessPermissions,
3671 ppsid[i]);
3672 break;
3673 case SET_ACCESS:
3675 ULONG j;
3676 BOOL add = TRUE;
3677 if (OldAcl)
3679 for (j = 0; ; j++)
3681 const ACE_HEADER *existing_ace_header;
3682 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3683 if (status != STATUS_SUCCESS)
3684 break;
3685 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3686 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3687 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3689 add = FALSE;
3690 break;
3694 if (add)
3695 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3696 pEntries[i].grfInheritance,
3697 pEntries[i].grfAccessPermissions,
3698 ppsid[i]);
3699 break;
3701 case DENY_ACCESS:
3702 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3703 pEntries[i].grfInheritance,
3704 pEntries[i].grfAccessPermissions,
3705 ppsid[i]);
3706 break;
3707 case SET_AUDIT_SUCCESS:
3708 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3709 pEntries[i].grfInheritance,
3710 pEntries[i].grfAccessPermissions,
3711 ppsid[i], TRUE, FALSE);
3712 break;
3713 case SET_AUDIT_FAILURE:
3714 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3715 pEntries[i].grfInheritance,
3716 pEntries[i].grfAccessPermissions,
3717 ppsid[i], FALSE, TRUE);
3718 break;
3719 default:
3720 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3724 if (OldAcl)
3726 for (i = 0; ; i++)
3728 BOOL add = TRUE;
3729 ULONG j;
3730 const ACE_HEADER *old_ace_header;
3731 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3732 if (status != STATUS_SUCCESS) break;
3733 for (j = 0; j < count; j++)
3735 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3736 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3737 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3739 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3740 add = FALSE;
3741 break;
3743 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3745 switch (old_ace_header->AceType)
3747 case ACCESS_ALLOWED_ACE_TYPE:
3748 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3749 add = FALSE;
3750 break;
3751 case ACCESS_DENIED_ACE_TYPE:
3752 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3753 add = FALSE;
3754 break;
3755 case SYSTEM_AUDIT_ACE_TYPE:
3756 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3757 add = FALSE;
3758 break;
3759 case SYSTEM_ALARM_ACE_TYPE:
3760 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3761 add = FALSE;
3762 break;
3763 default:
3764 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3767 if (!add)
3768 break;
3771 if (add)
3772 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3773 if (status != STATUS_SUCCESS)
3775 WARN("RtlAddAce failed with error 0x%08x\n", status);
3776 ret = RtlNtStatusToDosError(status);
3777 break;
3782 exit:
3783 HeapFree(GetProcessHeap(), 0, ppsid);
3784 return ret;
3787 /******************************************************************************
3788 * SetNamedSecurityInfoA [ADVAPI32.@]
3790 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3791 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3792 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3794 DWORD len;
3795 LPWSTR wstr = NULL;
3796 DWORD r;
3798 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3799 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3801 if( pObjectName )
3803 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3804 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3805 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3808 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3809 psidGroup, pDacl, pSacl );
3811 HeapFree( GetProcessHeap(), 0, wstr );
3813 return r;
3816 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3817 PSECURITY_DESCRIPTOR ModificationDescriptor,
3818 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3819 PGENERIC_MAPPING GenericMapping,
3820 HANDLE Token )
3822 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3823 ObjectsSecurityDescriptor, GenericMapping, Token);
3825 return TRUE;
3828 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3830 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3833 /******************************************************************************
3834 * AreAnyAccessesGranted [ADVAPI32.@]
3836 * Determines whether or not any of a set of specified access permissions have
3837 * been granted or not.
3839 * PARAMS
3840 * GrantedAccess [I] The permissions that have been granted.
3841 * DesiredAccess [I] The permissions that you want to have.
3843 * RETURNS
3844 * Nonzero if any of the permissions have been granted, zero if none of the
3845 * permissions have been granted.
3848 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3850 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3853 /******************************************************************************
3854 * SetNamedSecurityInfoW [ADVAPI32.@]
3856 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3857 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3858 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3860 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3861 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3862 return ERROR_SUCCESS;
3865 /******************************************************************************
3866 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3868 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3869 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3871 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3872 return ERROR_CALL_NOT_IMPLEMENTED;
3875 /******************************************************************************
3876 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3878 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3879 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3881 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3882 return ERROR_CALL_NOT_IMPLEMENTED;
3885 /******************************************************************************
3886 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3888 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3889 PACCESS_MASK pFailedAuditRights)
3891 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3892 return ERROR_CALL_NOT_IMPLEMENTED;
3896 /******************************************************************************
3897 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3899 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3900 PACCESS_MASK pFailedAuditRights)
3902 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3903 return ERROR_CALL_NOT_IMPLEMENTED;
3907 /******************************************************************************
3908 * ParseAclStringFlags
3910 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3912 DWORD flags = 0;
3913 LPCWSTR szAcl = *StringAcl;
3915 while (*szAcl != '(')
3917 if (*szAcl == 'P')
3919 flags |= SE_DACL_PROTECTED;
3921 else if (*szAcl == 'A')
3923 szAcl++;
3924 if (*szAcl == 'R')
3925 flags |= SE_DACL_AUTO_INHERIT_REQ;
3926 else if (*szAcl == 'I')
3927 flags |= SE_DACL_AUTO_INHERITED;
3929 szAcl++;
3932 *StringAcl = szAcl;
3933 return flags;
3936 /******************************************************************************
3937 * ParseAceStringType
3939 static const ACEFLAG AceType[] =
3941 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3942 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3943 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3944 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3946 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3947 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3948 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3949 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3951 { NULL, 0 },
3954 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3956 UINT len = 0;
3957 LPCWSTR szAcl = *StringAcl;
3958 const ACEFLAG *lpaf = AceType;
3960 while (*szAcl == ' ')
3961 szAcl++;
3963 while (lpaf->wstr &&
3964 (len = strlenW(lpaf->wstr)) &&
3965 strncmpW(lpaf->wstr, szAcl, len))
3966 lpaf++;
3968 if (!lpaf->wstr)
3969 return 0;
3971 *StringAcl = szAcl + len;
3972 return lpaf->value;
3976 /******************************************************************************
3977 * ParseAceStringFlags
3979 static const ACEFLAG AceFlags[] =
3981 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3982 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3983 { SDDL_INHERITED, INHERITED_ACE },
3984 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3985 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3986 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3987 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3988 { NULL, 0 },
3991 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3993 UINT len = 0;
3994 BYTE flags = 0;
3995 LPCWSTR szAcl = *StringAcl;
3997 while (*szAcl == ' ')
3998 szAcl++;
4000 while (*szAcl != ';')
4002 const ACEFLAG *lpaf = AceFlags;
4004 while (lpaf->wstr &&
4005 (len = strlenW(lpaf->wstr)) &&
4006 strncmpW(lpaf->wstr, szAcl, len))
4007 lpaf++;
4009 if (!lpaf->wstr)
4010 return 0;
4012 flags |= lpaf->value;
4013 szAcl += len;
4016 *StringAcl = szAcl;
4017 return flags;
4021 /******************************************************************************
4022 * ParseAceStringRights
4024 static const ACEFLAG AceRights[] =
4026 { SDDL_GENERIC_ALL, GENERIC_ALL },
4027 { SDDL_GENERIC_READ, GENERIC_READ },
4028 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4029 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4031 { SDDL_READ_CONTROL, READ_CONTROL },
4032 { SDDL_STANDARD_DELETE, DELETE },
4033 { SDDL_WRITE_DAC, WRITE_DAC },
4034 { SDDL_WRITE_OWNER, WRITE_OWNER },
4036 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4037 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4038 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4039 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4040 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4041 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4042 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4043 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4044 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4046 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4047 { SDDL_FILE_READ, FILE_GENERIC_READ },
4048 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4049 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4051 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4052 { SDDL_KEY_READ, KEY_READ },
4053 { SDDL_KEY_WRITE, KEY_WRITE },
4054 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4055 { NULL, 0 },
4058 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4060 UINT len = 0;
4061 DWORD rights = 0;
4062 LPCWSTR szAcl = *StringAcl;
4064 while (*szAcl == ' ')
4065 szAcl++;
4067 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4069 LPCWSTR p = szAcl;
4071 while (*p && *p != ';')
4072 p++;
4074 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4076 rights = strtoulW(szAcl, NULL, 16);
4077 szAcl = p;
4079 else
4080 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4082 else
4084 while (*szAcl != ';')
4086 const ACEFLAG *lpaf = AceRights;
4088 while (lpaf->wstr &&
4089 (len = strlenW(lpaf->wstr)) &&
4090 strncmpW(lpaf->wstr, szAcl, len))
4092 lpaf++;
4095 if (!lpaf->wstr)
4096 return 0;
4098 rights |= lpaf->value;
4099 szAcl += len;
4103 *StringAcl = szAcl;
4104 return rights;
4108 /******************************************************************************
4109 * ParseStringAclToAcl
4111 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4113 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4114 PACL pAcl, LPDWORD cBytes)
4116 DWORD val;
4117 DWORD sidlen;
4118 DWORD length = sizeof(ACL);
4119 DWORD acesize = 0;
4120 DWORD acecount = 0;
4121 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4122 DWORD error = ERROR_INVALID_ACL;
4124 TRACE("%s\n", debugstr_w(StringAcl));
4126 if (!StringAcl)
4127 return FALSE;
4129 if (pAcl) /* pAce is only useful if we're setting values */
4130 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4132 /* Parse ACL flags */
4133 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4135 /* Parse ACE */
4136 while (*StringAcl == '(')
4138 StringAcl++;
4140 /* Parse ACE type */
4141 val = ParseAceStringType(&StringAcl);
4142 if (pAce)
4143 pAce->Header.AceType = (BYTE) val;
4144 if (*StringAcl != ';')
4146 error = RPC_S_INVALID_STRING_UUID;
4147 goto lerr;
4149 StringAcl++;
4151 /* Parse ACE flags */
4152 val = ParseAceStringFlags(&StringAcl);
4153 if (pAce)
4154 pAce->Header.AceFlags = (BYTE) val;
4155 if (*StringAcl != ';')
4156 goto lerr;
4157 StringAcl++;
4159 /* Parse ACE rights */
4160 val = ParseAceStringRights(&StringAcl);
4161 if (pAce)
4162 pAce->Mask = val;
4163 if (*StringAcl != ';')
4164 goto lerr;
4165 StringAcl++;
4167 /* Parse ACE object guid */
4168 while (*StringAcl == ' ')
4169 StringAcl++;
4170 if (*StringAcl != ';')
4172 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4173 goto lerr;
4175 StringAcl++;
4177 /* Parse ACE inherit object guid */
4178 while (*StringAcl == ' ')
4179 StringAcl++;
4180 if (*StringAcl != ';')
4182 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4183 goto lerr;
4185 StringAcl++;
4187 /* Parse ACE account sid */
4188 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4190 while (*StringAcl && *StringAcl != ')')
4191 StringAcl++;
4194 if (*StringAcl != ')')
4195 goto lerr;
4196 StringAcl++;
4198 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4199 length += acesize;
4200 if (pAce)
4202 pAce->Header.AceSize = acesize;
4203 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4205 acecount++;
4208 *cBytes = length;
4210 if (length > 0xffff)
4212 ERR("ACL too large\n");
4213 goto lerr;
4216 if (pAcl)
4218 pAcl->AclRevision = ACL_REVISION;
4219 pAcl->Sbz1 = 0;
4220 pAcl->AclSize = length;
4221 pAcl->AceCount = acecount++;
4222 pAcl->Sbz2 = 0;
4224 return TRUE;
4226 lerr:
4227 SetLastError(error);
4228 WARN("Invalid ACE string format\n");
4229 return FALSE;
4233 /******************************************************************************
4234 * ParseStringSecurityDescriptorToSecurityDescriptor
4236 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4237 LPCWSTR StringSecurityDescriptor,
4238 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4239 LPDWORD cBytes)
4241 BOOL bret = FALSE;
4242 WCHAR toktype;
4243 WCHAR tok[MAX_PATH];
4244 LPCWSTR lptoken;
4245 LPBYTE lpNext = NULL;
4246 DWORD len;
4248 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4250 if (SecurityDescriptor)
4251 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4253 while (*StringSecurityDescriptor == ' ')
4254 StringSecurityDescriptor++;
4256 while (*StringSecurityDescriptor)
4258 toktype = *StringSecurityDescriptor;
4260 /* Expect char identifier followed by ':' */
4261 StringSecurityDescriptor++;
4262 if (*StringSecurityDescriptor != ':')
4264 SetLastError(ERROR_INVALID_PARAMETER);
4265 goto lend;
4267 StringSecurityDescriptor++;
4269 /* Extract token */
4270 lptoken = StringSecurityDescriptor;
4271 while (*lptoken && *lptoken != ':')
4272 lptoken++;
4274 if (*lptoken)
4275 lptoken--;
4277 len = lptoken - StringSecurityDescriptor;
4278 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4279 tok[len] = 0;
4281 switch (toktype)
4283 case 'O':
4285 DWORD bytes;
4287 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4288 goto lend;
4290 if (SecurityDescriptor)
4292 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4293 lpNext += bytes; /* Advance to next token */
4296 *cBytes += bytes;
4298 break;
4301 case 'G':
4303 DWORD bytes;
4305 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4306 goto lend;
4308 if (SecurityDescriptor)
4310 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4311 lpNext += bytes; /* Advance to next token */
4314 *cBytes += bytes;
4316 break;
4319 case 'D':
4321 DWORD flags;
4322 DWORD bytes;
4324 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4325 goto lend;
4327 if (SecurityDescriptor)
4329 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4330 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4331 lpNext += bytes; /* Advance to next token */
4334 *cBytes += bytes;
4336 break;
4339 case 'S':
4341 DWORD flags;
4342 DWORD bytes;
4344 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4345 goto lend;
4347 if (SecurityDescriptor)
4349 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4350 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4351 lpNext += bytes; /* Advance to next token */
4354 *cBytes += bytes;
4356 break;
4359 default:
4360 FIXME("Unknown token\n");
4361 SetLastError(ERROR_INVALID_PARAMETER);
4362 goto lend;
4365 StringSecurityDescriptor = lptoken;
4368 bret = TRUE;
4370 lend:
4371 return bret;
4374 /******************************************************************************
4375 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4377 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4378 LPCSTR StringSecurityDescriptor,
4379 DWORD StringSDRevision,
4380 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4381 PULONG SecurityDescriptorSize)
4383 UINT len;
4384 BOOL ret = FALSE;
4385 LPWSTR StringSecurityDescriptorW;
4387 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4388 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4390 if (StringSecurityDescriptorW)
4392 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4394 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4395 StringSDRevision, SecurityDescriptor,
4396 SecurityDescriptorSize);
4397 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4400 return ret;
4403 /******************************************************************************
4404 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4406 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4407 LPCWSTR StringSecurityDescriptor,
4408 DWORD StringSDRevision,
4409 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4410 PULONG SecurityDescriptorSize)
4412 DWORD cBytes;
4413 SECURITY_DESCRIPTOR* psd;
4414 BOOL bret = FALSE;
4416 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4418 if (GetVersion() & 0x80000000)
4420 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4421 goto lend;
4423 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4425 SetLastError(ERROR_INVALID_PARAMETER);
4426 goto lend;
4428 else if (StringSDRevision != SID_REVISION)
4430 SetLastError(ERROR_UNKNOWN_REVISION);
4431 goto lend;
4434 /* Compute security descriptor length */
4435 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4436 NULL, &cBytes))
4437 goto lend;
4439 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4440 if (!psd) goto lend;
4442 psd->Revision = SID_REVISION;
4443 psd->Control |= SE_SELF_RELATIVE;
4445 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4446 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4448 LocalFree(psd);
4449 goto lend;
4452 if (SecurityDescriptorSize)
4453 *SecurityDescriptorSize = cBytes;
4455 bret = TRUE;
4457 lend:
4458 TRACE(" ret=%d\n", bret);
4459 return bret;
4462 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4464 if (cch == -1)
4465 cch = strlenW(string);
4467 if (plen)
4468 *plen += cch;
4470 if (pwptr)
4472 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4473 *pwptr += cch;
4477 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4479 DWORD i;
4480 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4481 WCHAR subauthfmt[] = { '-','%','u',0 };
4482 WCHAR buf[26];
4483 SID *pisid = psid;
4485 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4487 SetLastError(ERROR_INVALID_SID);
4488 return FALSE;
4491 if (pisid->IdentifierAuthority.Value[0] ||
4492 pisid->IdentifierAuthority.Value[1])
4494 FIXME("not matching MS' bugs\n");
4495 SetLastError(ERROR_INVALID_SID);
4496 return FALSE;
4499 sprintfW( buf, fmt, pisid->Revision,
4500 MAKELONG(
4501 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4502 pisid->IdentifierAuthority.Value[4] ),
4503 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4504 pisid->IdentifierAuthority.Value[2] )
4505 ) );
4506 DumpString(buf, -1, pwptr, plen);
4508 for( i=0; i<pisid->SubAuthorityCount; i++ )
4510 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4511 DumpString(buf, -1, pwptr, plen);
4513 return TRUE;
4516 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4518 size_t i;
4519 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4521 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4523 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4524 return TRUE;
4528 return DumpSidNumeric(psid, pwptr, plen);
4531 static const LPCWSTR AceRightBitNames[32] = {
4532 SDDL_CREATE_CHILD, /* 0 */
4533 SDDL_DELETE_CHILD,
4534 SDDL_LIST_CHILDREN,
4535 SDDL_SELF_WRITE,
4536 SDDL_READ_PROPERTY, /* 4 */
4537 SDDL_WRITE_PROPERTY,
4538 SDDL_DELETE_TREE,
4539 SDDL_LIST_OBJECT,
4540 SDDL_CONTROL_ACCESS, /* 8 */
4541 NULL,
4542 NULL,
4543 NULL,
4544 NULL, /* 12 */
4545 NULL,
4546 NULL,
4547 NULL,
4548 SDDL_STANDARD_DELETE, /* 16 */
4549 SDDL_READ_CONTROL,
4550 SDDL_WRITE_DAC,
4551 SDDL_WRITE_OWNER,
4552 NULL, /* 20 */
4553 NULL,
4554 NULL,
4555 NULL,
4556 NULL, /* 24 */
4557 NULL,
4558 NULL,
4559 NULL,
4560 SDDL_GENERIC_ALL, /* 28 */
4561 SDDL_GENERIC_EXECUTE,
4562 SDDL_GENERIC_WRITE,
4563 SDDL_GENERIC_READ
4566 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4568 static const WCHAR fmtW[] = {'0','x','%','x',0};
4569 WCHAR buf[15];
4570 size_t i;
4572 if (mask == 0)
4573 return;
4575 /* first check if the right have name */
4576 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4578 if (AceRights[i].wstr == NULL)
4579 break;
4580 if (mask == AceRights[i].value)
4582 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4583 return;
4587 /* then check if it can be built from bit names */
4588 for (i = 0; i < 32; i++)
4590 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4592 /* can't be built from bit names */
4593 sprintfW(buf, fmtW, mask);
4594 DumpString(buf, -1, pwptr, plen);
4595 return;
4599 /* build from bit names */
4600 for (i = 0; i < 32; i++)
4601 if (mask & (1 << i))
4602 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4605 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4607 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4608 static const WCHAR openbr = '(';
4609 static const WCHAR closebr = ')';
4610 static const WCHAR semicolon = ';';
4612 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4614 SetLastError(ERROR_INVALID_ACL);
4615 return FALSE;
4618 piace = pace;
4619 DumpString(&openbr, 1, pwptr, plen);
4620 switch (piace->Header.AceType)
4622 case ACCESS_ALLOWED_ACE_TYPE:
4623 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4624 break;
4625 case ACCESS_DENIED_ACE_TYPE:
4626 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4627 break;
4628 case SYSTEM_AUDIT_ACE_TYPE:
4629 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4630 break;
4631 case SYSTEM_ALARM_ACE_TYPE:
4632 DumpString(SDDL_ALARM, -1, pwptr, plen);
4633 break;
4635 DumpString(&semicolon, 1, pwptr, plen);
4637 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4638 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4639 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4640 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4641 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4642 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4643 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4644 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4645 if (piace->Header.AceFlags & INHERITED_ACE)
4646 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4647 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4648 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4649 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4650 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4651 DumpString(&semicolon, 1, pwptr, plen);
4652 DumpRights(piace->Mask, pwptr, plen);
4653 DumpString(&semicolon, 1, pwptr, plen);
4654 /* objects not supported */
4655 DumpString(&semicolon, 1, pwptr, plen);
4656 /* objects not supported */
4657 DumpString(&semicolon, 1, pwptr, plen);
4658 if (!DumpSid(&piace->SidStart, pwptr, plen))
4659 return FALSE;
4660 DumpString(&closebr, 1, pwptr, plen);
4661 return TRUE;
4664 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4666 WORD count;
4667 int i;
4669 if (protected)
4670 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4671 if (autoInheritReq)
4672 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4673 if (autoInherited)
4674 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4676 if (pacl == NULL)
4677 return TRUE;
4679 if (!IsValidAcl(pacl))
4680 return FALSE;
4682 count = pacl->AceCount;
4683 for (i = 0; i < count; i++)
4685 LPVOID ace;
4686 if (!GetAce(pacl, i, &ace))
4687 return FALSE;
4688 if (!DumpAce(ace, pwptr, plen))
4689 return FALSE;
4692 return TRUE;
4695 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4697 static const WCHAR prefix[] = {'O',':',0};
4698 BOOL bDefaulted;
4699 PSID psid;
4701 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4702 return FALSE;
4704 if (psid == NULL)
4705 return TRUE;
4707 DumpString(prefix, -1, pwptr, plen);
4708 if (!DumpSid(psid, pwptr, plen))
4709 return FALSE;
4710 return TRUE;
4713 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4715 static const WCHAR prefix[] = {'G',':',0};
4716 BOOL bDefaulted;
4717 PSID psid;
4719 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4720 return FALSE;
4722 if (psid == NULL)
4723 return TRUE;
4725 DumpString(prefix, -1, pwptr, plen);
4726 if (!DumpSid(psid, pwptr, plen))
4727 return FALSE;
4728 return TRUE;
4731 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4733 static const WCHAR dacl[] = {'D',':',0};
4734 SECURITY_DESCRIPTOR_CONTROL control;
4735 BOOL present, defaulted;
4736 DWORD revision;
4737 PACL pacl;
4739 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4740 return FALSE;
4742 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4743 return FALSE;
4745 if (!present)
4746 return TRUE;
4748 DumpString(dacl, 2, pwptr, plen);
4749 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4750 return FALSE;
4751 return TRUE;
4754 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4756 static const WCHAR sacl[] = {'S',':',0};
4757 SECURITY_DESCRIPTOR_CONTROL control;
4758 BOOL present, defaulted;
4759 DWORD revision;
4760 PACL pacl;
4762 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4763 return FALSE;
4765 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4766 return FALSE;
4768 if (!present)
4769 return TRUE;
4771 DumpString(sacl, 2, pwptr, plen);
4772 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4773 return FALSE;
4774 return TRUE;
4777 /******************************************************************************
4778 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4780 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4782 ULONG len;
4783 WCHAR *wptr, *wstr;
4785 if (SDRevision != SDDL_REVISION_1)
4787 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4788 SetLastError(ERROR_UNKNOWN_REVISION);
4789 return FALSE;
4792 len = 0;
4793 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4794 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4795 return FALSE;
4796 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4797 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4798 return FALSE;
4799 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4800 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4801 return FALSE;
4802 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4803 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4804 return FALSE;
4806 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4807 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4808 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4809 return FALSE;
4810 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4811 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4812 return FALSE;
4813 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4814 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4815 return FALSE;
4816 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4817 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4818 return FALSE;
4819 *wptr = 0;
4821 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4822 *OutputString = wstr;
4823 if (OutputLen)
4824 *OutputLen = strlenW(*OutputString)+1;
4825 return TRUE;
4828 /******************************************************************************
4829 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4831 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4833 LPWSTR wstr;
4834 ULONG len;
4835 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4837 int lenA;
4839 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4840 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4841 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4842 LocalFree(wstr);
4844 if (OutputLen != NULL)
4845 *OutputLen = lenA;
4846 return TRUE;
4848 else
4850 *OutputString = NULL;
4851 if (OutputLen)
4852 *OutputLen = 0;
4853 return FALSE;
4857 /******************************************************************************
4858 * ConvertStringSidToSidW [ADVAPI32.@]
4860 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4862 BOOL bret = FALSE;
4863 DWORD cBytes;
4865 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4866 if (GetVersion() & 0x80000000)
4867 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4868 else if (!StringSid || !Sid)
4869 SetLastError(ERROR_INVALID_PARAMETER);
4870 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4872 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4874 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4875 if (!bret)
4876 LocalFree(*Sid);
4878 return bret;
4881 /******************************************************************************
4882 * ConvertStringSidToSidA [ADVAPI32.@]
4884 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4886 BOOL bret = FALSE;
4888 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4889 if (GetVersion() & 0x80000000)
4890 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4891 else if (!StringSid || !Sid)
4892 SetLastError(ERROR_INVALID_PARAMETER);
4893 else
4895 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4896 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4897 len * sizeof(WCHAR));
4899 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4900 bret = ConvertStringSidToSidW(wStringSid, Sid);
4901 HeapFree(GetProcessHeap(), 0, wStringSid);
4903 return bret;
4906 /******************************************************************************
4907 * ConvertSidToStringSidW [ADVAPI32.@]
4909 * format of SID string is:
4910 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4911 * where
4912 * <rev> is the revision of the SID encoded as decimal
4913 * <auth> is the identifier authority encoded as hex
4914 * <subauthN> is the subauthority id encoded as decimal
4916 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4918 DWORD len = 0;
4919 LPWSTR wstr, wptr;
4921 TRACE("%p %p\n", pSid, pstr );
4923 len = 0;
4924 if (!DumpSidNumeric(pSid, NULL, &len))
4925 return FALSE;
4926 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4927 DumpSidNumeric(pSid, &wptr, NULL);
4928 *wptr = 0;
4930 *pstr = wstr;
4931 return TRUE;
4934 /******************************************************************************
4935 * ConvertSidToStringSidA [ADVAPI32.@]
4937 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4939 LPWSTR wstr = NULL;
4940 LPSTR str;
4941 UINT len;
4943 TRACE("%p %p\n", pSid, pstr );
4945 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4946 return FALSE;
4948 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4949 str = LocalAlloc( 0, len );
4950 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4951 LocalFree( wstr );
4953 *pstr = str;
4955 return TRUE;
4958 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4959 PSECURITY_DESCRIPTOR pdesc,
4960 PSECURITY_DESCRIPTOR cdesc,
4961 PSECURITY_DESCRIPTOR* ndesc,
4962 GUID* objtype,
4963 BOOL isdir,
4964 PGENERIC_MAPPING genmap )
4966 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4968 return FALSE;
4971 BOOL WINAPI CreatePrivateObjectSecurity(
4972 PSECURITY_DESCRIPTOR ParentDescriptor,
4973 PSECURITY_DESCRIPTOR CreatorDescriptor,
4974 PSECURITY_DESCRIPTOR* NewDescriptor,
4975 BOOL IsDirectoryObject,
4976 HANDLE Token,
4977 PGENERIC_MAPPING GenericMapping )
4979 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4980 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4982 return FALSE;
4985 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4987 FIXME("%p - stub\n", ObjectDescriptor);
4989 return TRUE;
4992 BOOL WINAPI CreateProcessAsUserA(
4993 HANDLE hToken,
4994 LPCSTR lpApplicationName,
4995 LPSTR lpCommandLine,
4996 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4997 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4998 BOOL bInheritHandles,
4999 DWORD dwCreationFlags,
5000 LPVOID lpEnvironment,
5001 LPCSTR lpCurrentDirectory,
5002 LPSTARTUPINFOA lpStartupInfo,
5003 LPPROCESS_INFORMATION lpProcessInformation )
5005 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
5006 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5007 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5009 return FALSE;
5012 BOOL WINAPI CreateProcessAsUserW(
5013 HANDLE hToken,
5014 LPCWSTR lpApplicationName,
5015 LPWSTR lpCommandLine,
5016 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5017 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5018 BOOL bInheritHandles,
5019 DWORD dwCreationFlags,
5020 LPVOID lpEnvironment,
5021 LPCWSTR lpCurrentDirectory,
5022 LPSTARTUPINFOW lpStartupInfo,
5023 LPPROCESS_INFORMATION lpProcessInformation )
5025 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
5026 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5027 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5028 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5030 /* We should create the process with a suspended main thread */
5031 if (!CreateProcessW (lpApplicationName,
5032 lpCommandLine,
5033 lpProcessAttributes,
5034 lpThreadAttributes,
5035 bInheritHandles,
5036 dwCreationFlags, /* CREATE_SUSPENDED */
5037 lpEnvironment,
5038 lpCurrentDirectory,
5039 lpStartupInfo,
5040 lpProcessInformation))
5042 return FALSE;
5045 return TRUE;
5048 /******************************************************************************
5049 * CreateProcessWithLogonW
5051 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5052 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5053 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5055 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5056 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5057 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5058 lpStartupInfo, lpProcessInformation);
5060 return FALSE;
5063 /******************************************************************************
5064 * DuplicateTokenEx [ADVAPI32.@]
5066 BOOL WINAPI DuplicateTokenEx(
5067 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5068 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5069 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5070 TOKEN_TYPE TokenType,
5071 PHANDLE DuplicateTokenHandle )
5073 OBJECT_ATTRIBUTES ObjectAttributes;
5075 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5076 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5078 InitializeObjectAttributes(
5079 &ObjectAttributes,
5080 NULL,
5081 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5082 NULL,
5083 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5085 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5086 dwDesiredAccess,
5087 &ObjectAttributes,
5088 ImpersonationLevel,
5089 TokenType,
5090 DuplicateTokenHandle ) );
5093 BOOL WINAPI DuplicateToken(
5094 HANDLE ExistingTokenHandle,
5095 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5096 PHANDLE DuplicateTokenHandle )
5098 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5099 NULL, ImpersonationLevel, TokenImpersonation,
5100 DuplicateTokenHandle );
5103 /******************************************************************************
5104 * ComputeStringSidSize
5106 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5108 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5110 int ctok = 0;
5111 while (*StringSid)
5113 if (*StringSid == '-')
5114 ctok++;
5115 StringSid++;
5118 if (ctok >= 3)
5119 return GetSidLengthRequired(ctok - 2);
5121 else /* String constant format - Only available in winxp and above */
5123 unsigned int i;
5125 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5126 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5127 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5130 return GetSidLengthRequired(0);
5133 /******************************************************************************
5134 * ParseStringSidToSid
5136 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5138 BOOL bret = FALSE;
5139 SID* pisid=pSid;
5141 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5142 if (!StringSid)
5144 SetLastError(ERROR_INVALID_PARAMETER);
5145 TRACE("StringSid is NULL, returning FALSE\n");
5146 return FALSE;
5149 while (*StringSid == ' ')
5150 StringSid++;
5152 *cBytes = ComputeStringSidSize(StringSid);
5153 if (!pisid) /* Simply compute the size */
5155 TRACE("only size requested, returning TRUE\n");
5156 return TRUE;
5159 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5161 DWORD i = 0, identAuth;
5162 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5164 StringSid += 2; /* Advance to Revision */
5165 pisid->Revision = atoiW(StringSid);
5167 if (pisid->Revision != SDDL_REVISION)
5169 TRACE("Revision %d is unknown\n", pisid->Revision);
5170 goto lend; /* ERROR_INVALID_SID */
5172 if (csubauth == 0)
5174 TRACE("SubAuthorityCount is 0\n");
5175 goto lend; /* ERROR_INVALID_SID */
5178 pisid->SubAuthorityCount = csubauth;
5180 /* Advance to identifier authority */
5181 while (*StringSid && *StringSid != '-')
5182 StringSid++;
5183 if (*StringSid == '-')
5184 StringSid++;
5186 /* MS' implementation can't handle values greater than 2^32 - 1, so
5187 * we don't either; assume most significant bytes are always 0
5189 pisid->IdentifierAuthority.Value[0] = 0;
5190 pisid->IdentifierAuthority.Value[1] = 0;
5191 identAuth = atoiW(StringSid);
5192 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5193 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5194 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5195 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5197 /* Advance to first sub authority */
5198 while (*StringSid && *StringSid != '-')
5199 StringSid++;
5200 if (*StringSid == '-')
5201 StringSid++;
5203 while (*StringSid)
5205 pisid->SubAuthority[i++] = atoiW(StringSid);
5207 while (*StringSid && *StringSid != '-')
5208 StringSid++;
5209 if (*StringSid == '-')
5210 StringSid++;
5213 if (i != pisid->SubAuthorityCount)
5214 goto lend; /* ERROR_INVALID_SID */
5216 bret = TRUE;
5218 else /* String constant format - Only available in winxp and above */
5220 unsigned int i;
5221 pisid->Revision = SDDL_REVISION;
5223 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5224 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5226 DWORD j;
5227 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5228 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5229 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5230 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5231 bret = TRUE;
5234 if (!bret)
5235 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5238 lend:
5239 if (!bret)
5240 SetLastError(ERROR_INVALID_SID);
5242 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5243 return bret;
5246 /******************************************************************************
5247 * GetNamedSecurityInfoA [ADVAPI32.@]
5249 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5250 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5251 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5252 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5254 DWORD len;
5255 LPWSTR wstr = NULL;
5256 DWORD r;
5258 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5259 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5261 if( pObjectName )
5263 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5264 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5265 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5268 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5269 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5271 HeapFree( GetProcessHeap(), 0, wstr );
5273 return r;
5276 /******************************************************************************
5277 * GetNamedSecurityInfoW [ADVAPI32.@]
5279 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5280 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5281 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5283 DWORD needed, offset;
5284 SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
5285 BYTE *buffer;
5287 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5288 group, dacl, sacl, descriptor );
5290 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5291 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5293 /* If no descriptor, we have to check that there's a pointer for the requested information */
5294 if( !descriptor && (
5295 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5296 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5297 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5298 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5299 return ERROR_INVALID_PARAMETER;
5301 needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5302 if (info & OWNER_SECURITY_INFORMATION)
5303 needed += sizeof(sidWorld);
5304 if (info & GROUP_SECURITY_INFORMATION)
5305 needed += sizeof(sidWorld);
5306 if (info & DACL_SECURITY_INFORMATION)
5307 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5308 if (info & SACL_SECURITY_INFORMATION)
5309 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5311 if(descriptor)
5313 /* must be freed by caller */
5314 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5315 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5317 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5319 HeapFree( GetProcessHeap(), 0, *descriptor );
5320 return ERROR_INVALID_SECURITY_DESCR;
5323 relative = *descriptor;
5324 relative->Control |= SE_SELF_RELATIVE;
5326 buffer = (BYTE *)relative;
5327 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5329 else
5331 buffer = HeapAlloc( GetProcessHeap(), 0, needed );
5332 if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
5333 offset = 0;
5336 if (info & OWNER_SECURITY_INFORMATION)
5338 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5339 if(relative)
5340 relative->Owner = offset;
5341 if (owner)
5342 *owner = buffer + offset;
5343 offset += sizeof(sidWorld);
5345 if (info & GROUP_SECURITY_INFORMATION)
5347 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5348 if(relative)
5349 relative->Group = offset;
5350 if (group)
5351 *group = buffer + offset;
5352 offset += sizeof(sidWorld);
5354 if (info & DACL_SECURITY_INFORMATION)
5356 GetWorldAccessACL( (PACL)(buffer + offset) );
5357 if(relative)
5359 relative->Control |= SE_DACL_PRESENT;
5360 relative->Dacl = offset;
5362 if (dacl)
5363 *dacl = (PACL)(buffer + offset);
5364 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5366 if (info & SACL_SECURITY_INFORMATION)
5368 GetWorldAccessACL( (PACL)(buffer + offset) );
5369 if(relative)
5371 relative->Control |= SE_SACL_PRESENT;
5372 relative->Sacl = offset;
5374 if (sacl)
5375 *sacl = (PACL)(buffer + offset);
5378 return ERROR_SUCCESS;
5381 /******************************************************************************
5382 * DecryptFileW [ADVAPI32.@]
5384 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5386 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5387 return TRUE;
5390 /******************************************************************************
5391 * DecryptFileA [ADVAPI32.@]
5393 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5395 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5396 return TRUE;
5399 /******************************************************************************
5400 * EncryptFileW [ADVAPI32.@]
5402 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5404 FIXME("%s\n", debugstr_w(lpFileName));
5405 return TRUE;
5408 /******************************************************************************
5409 * EncryptFileA [ADVAPI32.@]
5411 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5413 FIXME("%s\n", debugstr_a(lpFileName));
5414 return TRUE;
5417 /******************************************************************************
5418 * FileEncryptionStatusW [ADVAPI32.@]
5420 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5422 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5423 if (!lpStatus)
5424 return FALSE;
5425 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5426 return TRUE;
5429 /******************************************************************************
5430 * FileEncryptionStatusA [ADVAPI32.@]
5432 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5434 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5435 if (!lpStatus)
5436 return FALSE;
5437 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5438 return TRUE;
5441 /******************************************************************************
5442 * SetSecurityInfo [ADVAPI32.@]
5444 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5445 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5446 PSID psidGroup, PACL pDacl, PACL pSacl) {
5447 FIXME("stub\n");
5448 return ERROR_SUCCESS;
5451 /******************************************************************************
5452 * SaferCreateLevel [ADVAPI32.@]
5454 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5455 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5457 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5459 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5460 return TRUE;
5463 /******************************************************************************
5464 * SaferComputeTokenFromLevel [ADVAPI32.@]
5466 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5467 DWORD flags, LPVOID reserved)
5469 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5471 *access_token = (HANDLE)0xdeadbeef;
5472 return TRUE;
5475 /******************************************************************************
5476 * SaferCloseLevel [ADVAPI32.@]
5478 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5480 FIXME("(%p) stub\n", handle);
5481 return TRUE;
5484 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5485 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5486 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5487 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5488 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5490 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p Stub\n",
5491 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5492 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5494 return ERROR_SUCCESS;
5497 /******************************************************************************
5498 * SaferGetPolicyInformation [ADVAPI32.@]
5500 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5501 PVOID buffer, PDWORD required, LPVOID lpReserved)
5503 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5504 return FALSE;