push c669110d8ebd04a85775e86a8310fabd7dc4466e
[wine/hacks.git] / dlls / advapi32 / security.c
blob4153d934f5dc976bbb09a1392ff614df2a0ad45f
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* 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 } AccountSid;
172 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
173 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
174 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
175 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
176 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
177 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
178 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
179 static const WCHAR Blank[] = { 0 };
180 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
181 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
182 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
183 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 };
184 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
185 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 };
186 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
187 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 };
188 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
189 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
190 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
191 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
192 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
193 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
194 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
195 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 };
196 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
197 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 };
198 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
199 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
200 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
201 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
202 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
203 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
204 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 };
205 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
206 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
207 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
208 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
209 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
210 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
211 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 };
212 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 };
213 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
214 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 };
215 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
216 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
217 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
218 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 };
219 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 };
220 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
221 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
222 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 };
223 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
224 static const WCHAR SELF[] = { 'S','E','L','F',0 };
225 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
226 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
227 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
228 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 };
229 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
230 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
232 static const AccountSid ACCOUNT_SIDS[] = {
233 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
234 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
235 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
236 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
237 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
238 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
239 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
240 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
241 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
258 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
259 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
260 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
261 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
262 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
263 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
264 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
265 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
267 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
268 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
269 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
270 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
271 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
272 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
273 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
276 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
279 * ACE access rights
281 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
282 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
283 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
284 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
286 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
287 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
288 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
289 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
290 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
291 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
292 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
293 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
294 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
296 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
297 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
298 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
299 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
301 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
302 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
303 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
304 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
306 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
307 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
308 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
309 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
312 * ACL flags
314 static const WCHAR SDDL_PROTECTED[] = {'P',0};
315 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
316 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
319 * ACE types
321 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
322 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
323 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
324 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
325 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
326 static const WCHAR SDDL_ALARM[] = {'A','L',0};
327 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
328 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
331 * ACE flags
333 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
334 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
335 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
336 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
337 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
338 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
339 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
341 const char * debugstr_sid(PSID sid)
343 int auth = 0;
344 SID * psid = (SID *)sid;
346 if (psid == NULL)
347 return "(null)";
349 auth = psid->IdentifierAuthority.Value[5] +
350 (psid->IdentifierAuthority.Value[4] << 8) +
351 (psid->IdentifierAuthority.Value[3] << 16) +
352 (psid->IdentifierAuthority.Value[2] << 24);
354 switch (psid->SubAuthorityCount) {
355 case 0:
356 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
357 case 1:
358 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
359 psid->SubAuthority[0]);
360 case 2:
361 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
362 psid->SubAuthority[0], psid->SubAuthority[1]);
363 case 3:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
366 case 4:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
369 psid->SubAuthority[3]);
370 case 5:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373 psid->SubAuthority[3], psid->SubAuthority[4]);
374 case 6:
375 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
376 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
377 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
378 case 7:
379 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
381 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
382 psid->SubAuthority[6]);
383 case 8:
384 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
385 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
386 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
387 psid->SubAuthority[6], psid->SubAuthority[7]);
389 return "(too-big)";
392 /* set last error code from NT status and get the proper boolean return value */
393 /* used for functions that are a simple wrapper around the corresponding ntdll API */
394 static inline BOOL set_ntstatus( NTSTATUS status )
396 if (status) SetLastError( RtlNtStatusToDosError( status ));
397 return !status;
400 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
402 static void GetWorldAccessACL(PACL pACL)
404 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
406 pACL->AclRevision = ACL_REVISION;
407 pACL->Sbz1 = 0;
408 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
409 pACL->AceCount = 1;
410 pACL->Sbz2 = 0;
412 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
413 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
414 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
415 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
416 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
419 /************************************************************
420 * ADVAPI_IsLocalComputer
422 * Checks whether the server name indicates local machine.
424 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
426 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
427 BOOL Result;
428 LPWSTR buf;
430 if (!ServerName || !ServerName[0])
431 return TRUE;
433 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
434 Result = GetComputerNameW(buf, &dwSize);
435 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
436 ServerName += 2;
437 Result = Result && !lstrcmpW(ServerName, buf);
438 HeapFree(GetProcessHeap(), 0, buf);
440 return Result;
443 /************************************************************
444 * ADVAPI_GetComputerSid
446 * Reads the computer SID from the registry.
448 BOOL ADVAPI_GetComputerSid(PSID sid)
450 HKEY key;
451 LONG ret;
452 BOOL retval = FALSE;
453 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 };
454 static const WCHAR V[] = { 'V',0 };
456 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
457 KEY_READ, &key)) == ERROR_SUCCESS)
459 DWORD size = 0;
460 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
461 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
463 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
464 if (data)
466 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
467 data, &size)) == ERROR_SUCCESS)
469 /* the SID is in the last 24 bytes of the binary data */
470 CopyMemory(sid, &data[size-24], 24);
471 retval = TRUE;
473 HeapFree(GetProcessHeap(), 0, data);
476 RegCloseKey(key);
479 if(retval == TRUE) return retval;
481 /* create a new random SID */
482 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
483 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
485 PSID new_sid;
486 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
487 DWORD id[3];
489 if (RtlGenRandom(id, sizeof(id)))
491 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
493 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
494 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
496 FreeSid(new_sid);
499 RegCloseKey(key);
502 return retval;
505 /* ##############################
506 ###### TOKEN FUNCTIONS ######
507 ##############################
510 /******************************************************************************
511 * OpenProcessToken [ADVAPI32.@]
512 * Opens the access token associated with a process handle.
514 * PARAMS
515 * ProcessHandle [I] Handle to process
516 * DesiredAccess [I] Desired access to process
517 * TokenHandle [O] Pointer to handle of open access token
519 * RETURNS
520 * Success: TRUE. TokenHandle contains the access token.
521 * Failure: FALSE.
523 * NOTES
524 * See NtOpenProcessToken.
526 BOOL WINAPI
527 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
528 HANDLE *TokenHandle )
530 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
533 /******************************************************************************
534 * OpenThreadToken [ADVAPI32.@]
536 * Opens the access token associated with a thread handle.
538 * PARAMS
539 * ThreadHandle [I] Handle to process
540 * DesiredAccess [I] Desired access to the thread
541 * OpenAsSelf [I] ???
542 * TokenHandle [O] Destination for the token handle
544 * RETURNS
545 * Success: TRUE. TokenHandle contains the access token.
546 * Failure: FALSE.
548 * NOTES
549 * See NtOpenThreadToken.
551 BOOL WINAPI
552 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
553 BOOL OpenAsSelf, HANDLE *TokenHandle)
555 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
558 BOOL WINAPI
559 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
560 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
562 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
563 PreviousState, ReturnLength));
566 /******************************************************************************
567 * AdjustTokenPrivileges [ADVAPI32.@]
569 * Adjust the privileges of an open token handle.
571 * PARAMS
572 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
574 * NewState [I] Desired new privileges of the token
575 * BufferLength [I] Length of NewState
576 * PreviousState [O] Destination for the previous state
577 * ReturnLength [I/O] Size of PreviousState
580 * RETURNS
581 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
582 * Failure: FALSE.
584 * NOTES
585 * See NtAdjustPrivilegesToken.
587 BOOL WINAPI
588 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
589 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
590 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
592 NTSTATUS status;
594 TRACE("\n");
596 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
597 NewState, BufferLength, PreviousState,
598 ReturnLength);
599 SetLastError( RtlNtStatusToDosError( status ));
600 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
601 return TRUE;
602 else
603 return FALSE;
606 /******************************************************************************
607 * CheckTokenMembership [ADVAPI32.@]
609 * Determine if an access token is a member of a SID.
611 * PARAMS
612 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
613 * SidToCheck [I] SID that possibly contains the token
614 * IsMember [O] Destination for result.
616 * RETURNS
617 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
618 * Failure: FALSE.
620 BOOL WINAPI
621 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
622 PBOOL IsMember )
624 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
626 *IsMember = TRUE;
627 return(TRUE);
630 /******************************************************************************
631 * GetTokenInformation [ADVAPI32.@]
633 * Get a type of information about an access token.
635 * PARAMS
636 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
637 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
638 * tokeninfo [O] Destination for token information
639 * tokeninfolength [I] Length of tokeninfo
640 * retlen [O] Destination for returned token information length
642 * RETURNS
643 * Success: TRUE. tokeninfo contains retlen bytes of token information
644 * Failure: FALSE.
646 * NOTES
647 * See NtQueryInformationToken.
649 BOOL WINAPI
650 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
651 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
653 TRACE("(%p, %s, %p, %d, %p):\n",
654 token,
655 (tokeninfoclass == TokenUser) ? "TokenUser" :
656 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
657 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
658 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
659 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
660 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
661 (tokeninfoclass == TokenSource) ? "TokenSource" :
662 (tokeninfoclass == TokenType) ? "TokenType" :
663 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
664 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
665 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
666 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
667 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
668 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
669 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
670 "Unknown",
671 tokeninfo, tokeninfolength, retlen);
672 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
673 tokeninfolength, retlen));
676 /******************************************************************************
677 * SetTokenInformation [ADVAPI32.@]
679 * Set information for an access token.
681 * PARAMS
682 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
683 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
684 * tokeninfo [I] Token information to set
685 * tokeninfolength [I] Length of tokeninfo
687 * RETURNS
688 * Success: TRUE. The information for the token is set to tokeninfo.
689 * Failure: FALSE.
691 BOOL WINAPI
692 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
693 LPVOID tokeninfo, DWORD tokeninfolength )
695 TRACE("(%p, %s, %p, %d): stub\n",
696 token,
697 (tokeninfoclass == TokenUser) ? "TokenUser" :
698 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
699 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
700 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
701 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
702 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
703 (tokeninfoclass == TokenSource) ? "TokenSource" :
704 (tokeninfoclass == TokenType) ? "TokenType" :
705 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
706 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
707 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
708 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
709 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
710 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
711 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
712 "Unknown",
713 tokeninfo, tokeninfolength);
715 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
718 /*************************************************************************
719 * SetThreadToken [ADVAPI32.@]
721 * Assigns an 'impersonation token' to a thread so it can assume the
722 * security privileges of another thread or process. Can also remove
723 * a previously assigned token.
725 * PARAMS
726 * thread [O] Handle to thread to set the token for
727 * token [I] Token to set
729 * RETURNS
730 * Success: TRUE. The threads access token is set to token
731 * Failure: FALSE.
733 * NOTES
734 * Only supported on NT or higher. On Win9X this function does nothing.
735 * See SetTokenInformation.
737 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
739 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
740 ThreadImpersonationToken, &token, sizeof token ));
743 /*************************************************************************
744 * CreateRestrictedToken [ADVAPI32.@]
746 * Create a new more restricted token from an existing token.
748 * PARAMS
749 * baseToken [I] Token to base the new restricted token on
750 * flags [I] Options
751 * nDisableSids [I] Length of disableSids array
752 * disableSids [I] Array of SIDs to disable in the new token
753 * nDeletePrivs [I] Length of deletePrivs array
754 * deletePrivs [I] Array of privileges to delete in the new token
755 * nRestrictSids [I] Length of restrictSids array
756 * restrictSids [I] Array of SIDs to restrict in the new token
757 * newToken [O] Address where the new token is stored
759 * RETURNS
760 * Success: TRUE
761 * Failure: FALSE
763 BOOL WINAPI CreateRestrictedToken(
764 HANDLE baseToken,
765 DWORD flags,
766 DWORD nDisableSids,
767 PSID_AND_ATTRIBUTES disableSids,
768 DWORD nDeletePrivs,
769 PLUID_AND_ATTRIBUTES deletePrivs,
770 DWORD nRestrictSids,
771 PSID_AND_ATTRIBUTES restrictSids,
772 PHANDLE newToken)
774 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
775 baseToken, flags, nDisableSids, disableSids,
776 nDeletePrivs, deletePrivs,
777 nRestrictSids, restrictSids,
778 newToken);
779 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
780 return FALSE;
783 /* ##############################
784 ###### SID FUNCTIONS ######
785 ##############################
788 /******************************************************************************
789 * AllocateAndInitializeSid [ADVAPI32.@]
791 * PARAMS
792 * pIdentifierAuthority []
793 * nSubAuthorityCount []
794 * nSubAuthority0 []
795 * nSubAuthority1 []
796 * nSubAuthority2 []
797 * nSubAuthority3 []
798 * nSubAuthority4 []
799 * nSubAuthority5 []
800 * nSubAuthority6 []
801 * nSubAuthority7 []
802 * pSid []
804 BOOL WINAPI
805 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
806 BYTE nSubAuthorityCount,
807 DWORD nSubAuthority0, DWORD nSubAuthority1,
808 DWORD nSubAuthority2, DWORD nSubAuthority3,
809 DWORD nSubAuthority4, DWORD nSubAuthority5,
810 DWORD nSubAuthority6, DWORD nSubAuthority7,
811 PSID *pSid )
813 return set_ntstatus( RtlAllocateAndInitializeSid(
814 pIdentifierAuthority, nSubAuthorityCount,
815 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
816 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
817 pSid ));
820 /******************************************************************************
821 * FreeSid [ADVAPI32.@]
823 * PARAMS
824 * pSid []
826 PVOID WINAPI
827 FreeSid( PSID pSid )
829 RtlFreeSid(pSid);
830 return NULL; /* is documented like this */
833 /******************************************************************************
834 * CopySid [ADVAPI32.@]
836 * PARAMS
837 * nDestinationSidLength []
838 * pDestinationSid []
839 * pSourceSid []
841 BOOL WINAPI
842 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
844 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
847 /******************************************************************************
848 * CreateWellKnownSid [ADVAPI32.@]
850 BOOL WINAPI
851 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
852 PSID DomainSid,
853 PSID pSid,
854 DWORD* cbSid)
856 unsigned int i;
857 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
859 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
860 SetLastError(ERROR_INVALID_PARAMETER);
861 return FALSE;
864 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
865 if (WellKnownSids[i].Type == WellKnownSidType) {
866 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
868 if (*cbSid < length) {
869 SetLastError(ERROR_INSUFFICIENT_BUFFER);
870 return FALSE;
873 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
874 *cbSid = length;
875 return TRUE;
879 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
881 SetLastError(ERROR_INVALID_PARAMETER);
882 return FALSE;
885 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
886 if (WellKnownRids[i].Type == WellKnownSidType) {
887 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
888 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
889 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
891 if (*cbSid < output_sid_length) {
892 SetLastError(ERROR_INSUFFICIENT_BUFFER);
893 return FALSE;
896 CopyMemory(pSid, DomainSid, domain_sid_length);
897 (*GetSidSubAuthorityCount(pSid))++;
898 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
899 *cbSid = output_sid_length;
900 return TRUE;
903 SetLastError(ERROR_INVALID_PARAMETER);
904 return FALSE;
907 /******************************************************************************
908 * IsWellKnownSid [ADVAPI32.@]
910 BOOL WINAPI
911 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
913 unsigned int i;
914 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
916 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
917 if (WellKnownSids[i].Type == WellKnownSidType)
918 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
919 return TRUE;
921 return FALSE;
924 BOOL WINAPI
925 IsTokenRestricted( HANDLE TokenHandle )
927 TOKEN_GROUPS *groups;
928 DWORD size;
929 NTSTATUS status;
930 BOOL restricted;
932 TRACE("(%p)\n", TokenHandle);
934 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
935 if (status != STATUS_BUFFER_TOO_SMALL)
936 return FALSE;
938 groups = HeapAlloc(GetProcessHeap(), 0, size);
939 if (!groups)
941 SetLastError(ERROR_OUTOFMEMORY);
942 return FALSE;
945 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
946 if (status != STATUS_SUCCESS)
948 HeapFree(GetProcessHeap(), 0, groups);
949 return set_ntstatus(status);
952 if (groups->GroupCount)
953 restricted = TRUE;
954 else
955 restricted = FALSE;
957 HeapFree(GetProcessHeap(), 0, groups);
959 return restricted;
962 /******************************************************************************
963 * IsValidSid [ADVAPI32.@]
965 * PARAMS
966 * pSid []
968 BOOL WINAPI
969 IsValidSid( PSID pSid )
971 return RtlValidSid( pSid );
974 /******************************************************************************
975 * EqualSid [ADVAPI32.@]
977 * PARAMS
978 * pSid1 []
979 * pSid2 []
981 BOOL WINAPI
982 EqualSid( PSID pSid1, PSID pSid2 )
984 return RtlEqualSid( pSid1, pSid2 );
987 /******************************************************************************
988 * EqualPrefixSid [ADVAPI32.@]
990 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
992 return RtlEqualPrefixSid(pSid1, pSid2);
995 /******************************************************************************
996 * GetSidLengthRequired [ADVAPI32.@]
998 * PARAMS
999 * nSubAuthorityCount []
1001 DWORD WINAPI
1002 GetSidLengthRequired( BYTE nSubAuthorityCount )
1004 return RtlLengthRequiredSid(nSubAuthorityCount);
1007 /******************************************************************************
1008 * InitializeSid [ADVAPI32.@]
1010 * PARAMS
1011 * pIdentifierAuthority []
1013 BOOL WINAPI
1014 InitializeSid (
1015 PSID pSid,
1016 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1017 BYTE nSubAuthorityCount)
1019 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1022 DWORD WINAPI
1023 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1025 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1027 return 1;
1030 DWORD WINAPI
1031 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1033 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1035 return 1;
1038 /******************************************************************************
1039 * GetSidIdentifierAuthority [ADVAPI32.@]
1041 * PARAMS
1042 * pSid []
1044 PSID_IDENTIFIER_AUTHORITY WINAPI
1045 GetSidIdentifierAuthority( PSID pSid )
1047 return RtlIdentifierAuthoritySid(pSid);
1050 /******************************************************************************
1051 * GetSidSubAuthority [ADVAPI32.@]
1053 * PARAMS
1054 * pSid []
1055 * nSubAuthority []
1057 PDWORD WINAPI
1058 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1060 return RtlSubAuthoritySid(pSid, nSubAuthority);
1063 /******************************************************************************
1064 * GetSidSubAuthorityCount [ADVAPI32.@]
1066 * PARAMS
1067 * pSid []
1069 PUCHAR WINAPI
1070 GetSidSubAuthorityCount (PSID pSid)
1072 return RtlSubAuthorityCountSid(pSid);
1075 /******************************************************************************
1076 * GetLengthSid [ADVAPI32.@]
1078 * PARAMS
1079 * pSid []
1081 DWORD WINAPI
1082 GetLengthSid (PSID pSid)
1084 return RtlLengthSid(pSid);
1087 /* ##############################################
1088 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1089 ##############################################
1092 /******************************************************************************
1093 * BuildSecurityDescriptorA [ADVAPI32.@]
1095 * Builds a SD from
1097 * PARAMS
1098 * pOwner [I]
1099 * pGroup [I]
1100 * cCountOfAccessEntries [I]
1101 * pListOfAccessEntries [I]
1102 * cCountOfAuditEntries [I]
1103 * pListofAuditEntries [I]
1104 * pOldSD [I]
1105 * lpdwBufferLength [I/O]
1106 * pNewSD [O]
1108 * RETURNS
1109 * Success: ERROR_SUCCESS
1110 * Failure: nonzero error code from Winerror.h
1112 DWORD WINAPI BuildSecurityDescriptorA(
1113 IN PTRUSTEEA pOwner,
1114 IN PTRUSTEEA pGroup,
1115 IN ULONG cCountOfAccessEntries,
1116 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1117 IN ULONG cCountOfAuditEntries,
1118 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1119 IN PSECURITY_DESCRIPTOR pOldSD,
1120 IN OUT PULONG lpdwBufferLength,
1121 OUT PSECURITY_DESCRIPTOR* pNewSD)
1123 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1124 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1125 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1127 return ERROR_CALL_NOT_IMPLEMENTED;
1130 /******************************************************************************
1131 * BuildSecurityDescriptorW [ADVAPI32.@]
1133 * See BuildSecurityDescriptorA.
1135 DWORD WINAPI BuildSecurityDescriptorW(
1136 IN PTRUSTEEW pOwner,
1137 IN PTRUSTEEW pGroup,
1138 IN ULONG cCountOfAccessEntries,
1139 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1140 IN ULONG cCountOfAuditEntries,
1141 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1142 IN PSECURITY_DESCRIPTOR pOldSD,
1143 IN OUT PULONG lpdwBufferLength,
1144 OUT PSECURITY_DESCRIPTOR* pNewSD)
1146 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1147 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1148 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1150 return ERROR_CALL_NOT_IMPLEMENTED;
1153 /******************************************************************************
1154 * InitializeSecurityDescriptor [ADVAPI32.@]
1156 * PARAMS
1157 * pDescr []
1158 * revision []
1160 BOOL WINAPI
1161 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1163 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1167 /******************************************************************************
1168 * MakeAbsoluteSD [ADVAPI32.@]
1170 BOOL WINAPI MakeAbsoluteSD (
1171 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1172 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1173 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1174 OUT PACL pDacl,
1175 OUT LPDWORD lpdwDaclSize,
1176 OUT PACL pSacl,
1177 OUT LPDWORD lpdwSaclSize,
1178 OUT PSID pOwner,
1179 OUT LPDWORD lpdwOwnerSize,
1180 OUT PSID pPrimaryGroup,
1181 OUT LPDWORD lpdwPrimaryGroupSize)
1183 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1184 pAbsoluteSecurityDescriptor,
1185 lpdwAbsoluteSecurityDescriptorSize,
1186 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1187 pOwner, lpdwOwnerSize,
1188 pPrimaryGroup, lpdwPrimaryGroupSize));
1191 /******************************************************************************
1192 * GetKernelObjectSecurity [ADVAPI32.@]
1194 BOOL WINAPI GetKernelObjectSecurity(
1195 HANDLE Handle,
1196 SECURITY_INFORMATION RequestedInformation,
1197 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1198 DWORD nLength,
1199 LPDWORD lpnLengthNeeded )
1201 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1202 pSecurityDescriptor, nLength, lpnLengthNeeded);
1204 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1205 nLength, lpnLengthNeeded ));
1208 /******************************************************************************
1209 * GetPrivateObjectSecurity [ADVAPI32.@]
1211 BOOL WINAPI GetPrivateObjectSecurity(
1212 PSECURITY_DESCRIPTOR ObjectDescriptor,
1213 SECURITY_INFORMATION SecurityInformation,
1214 PSECURITY_DESCRIPTOR ResultantDescriptor,
1215 DWORD DescriptorLength,
1216 PDWORD ReturnLength )
1218 SECURITY_DESCRIPTOR desc;
1219 BOOL defaulted, present;
1220 PACL pacl;
1221 PSID psid;
1223 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1224 ResultantDescriptor, DescriptorLength, ReturnLength);
1226 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1227 return FALSE;
1229 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1231 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1232 return FALSE;
1233 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1236 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1238 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1239 return FALSE;
1240 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1243 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1245 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1246 return FALSE;
1247 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1250 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1252 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1253 return FALSE;
1254 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1257 *ReturnLength = DescriptorLength;
1258 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1261 /******************************************************************************
1262 * GetSecurityDescriptorLength [ADVAPI32.@]
1264 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1266 return RtlLengthSecurityDescriptor(pDescr);
1269 /******************************************************************************
1270 * GetSecurityDescriptorOwner [ADVAPI32.@]
1272 * PARAMS
1273 * pOwner []
1274 * lpbOwnerDefaulted []
1276 BOOL WINAPI
1277 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1278 LPBOOL lpbOwnerDefaulted )
1280 BOOLEAN defaulted;
1281 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1282 *lpbOwnerDefaulted = defaulted;
1283 return ret;
1286 /******************************************************************************
1287 * SetSecurityDescriptorOwner [ADVAPI32.@]
1289 * PARAMS
1291 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1292 PSID pOwner, BOOL bOwnerDefaulted)
1294 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1296 /******************************************************************************
1297 * GetSecurityDescriptorGroup [ADVAPI32.@]
1299 BOOL WINAPI GetSecurityDescriptorGroup(
1300 PSECURITY_DESCRIPTOR SecurityDescriptor,
1301 PSID *Group,
1302 LPBOOL GroupDefaulted)
1304 BOOLEAN defaulted;
1305 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1306 *GroupDefaulted = defaulted;
1307 return ret;
1309 /******************************************************************************
1310 * SetSecurityDescriptorGroup [ADVAPI32.@]
1312 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1313 PSID Group, BOOL GroupDefaulted)
1315 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1318 /******************************************************************************
1319 * IsValidSecurityDescriptor [ADVAPI32.@]
1321 * PARAMS
1322 * lpsecdesc []
1324 BOOL WINAPI
1325 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1327 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1330 /******************************************************************************
1331 * GetSecurityDescriptorDacl [ADVAPI32.@]
1333 BOOL WINAPI GetSecurityDescriptorDacl(
1334 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1335 OUT LPBOOL lpbDaclPresent,
1336 OUT PACL *pDacl,
1337 OUT LPBOOL lpbDaclDefaulted)
1339 BOOLEAN present, defaulted;
1340 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1341 *lpbDaclPresent = present;
1342 *lpbDaclDefaulted = defaulted;
1343 return ret;
1346 /******************************************************************************
1347 * SetSecurityDescriptorDacl [ADVAPI32.@]
1349 BOOL WINAPI
1350 SetSecurityDescriptorDacl (
1351 PSECURITY_DESCRIPTOR lpsd,
1352 BOOL daclpresent,
1353 PACL dacl,
1354 BOOL dacldefaulted )
1356 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1358 /******************************************************************************
1359 * GetSecurityDescriptorSacl [ADVAPI32.@]
1361 BOOL WINAPI GetSecurityDescriptorSacl(
1362 IN PSECURITY_DESCRIPTOR lpsd,
1363 OUT LPBOOL lpbSaclPresent,
1364 OUT PACL *pSacl,
1365 OUT LPBOOL lpbSaclDefaulted)
1367 BOOLEAN present, defaulted;
1368 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1369 *lpbSaclPresent = present;
1370 *lpbSaclDefaulted = defaulted;
1371 return ret;
1374 /**************************************************************************
1375 * SetSecurityDescriptorSacl [ADVAPI32.@]
1377 BOOL WINAPI SetSecurityDescriptorSacl (
1378 PSECURITY_DESCRIPTOR lpsd,
1379 BOOL saclpresent,
1380 PACL lpsacl,
1381 BOOL sacldefaulted)
1383 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1385 /******************************************************************************
1386 * MakeSelfRelativeSD [ADVAPI32.@]
1388 * PARAMS
1389 * lpabssecdesc []
1390 * lpselfsecdesc []
1391 * lpbuflen []
1393 BOOL WINAPI
1394 MakeSelfRelativeSD(
1395 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1396 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1397 IN OUT LPDWORD lpdwBufferLength)
1399 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1400 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1403 /******************************************************************************
1404 * GetSecurityDescriptorControl [ADVAPI32.@]
1407 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1408 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1410 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1413 /******************************************************************************
1414 * SetSecurityDescriptorControl [ADVAPI32.@]
1416 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1417 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1418 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1420 return set_ntstatus( RtlSetControlSecurityDescriptor(
1421 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1424 /* ##############################
1425 ###### ACL FUNCTIONS ######
1426 ##############################
1429 /*************************************************************************
1430 * InitializeAcl [ADVAPI32.@]
1432 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1434 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1437 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1439 IO_STATUS_BLOCK io_block;
1441 TRACE("(%p)\n", hNamedPipe);
1443 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1444 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1447 /******************************************************************************
1448 * AddAccessAllowedAce [ADVAPI32.@]
1450 BOOL WINAPI AddAccessAllowedAce(
1451 IN OUT PACL pAcl,
1452 IN DWORD dwAceRevision,
1453 IN DWORD AccessMask,
1454 IN PSID pSid)
1456 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1459 /******************************************************************************
1460 * AddAccessAllowedAceEx [ADVAPI32.@]
1462 BOOL WINAPI AddAccessAllowedAceEx(
1463 IN OUT PACL pAcl,
1464 IN DWORD dwAceRevision,
1465 IN DWORD AceFlags,
1466 IN DWORD AccessMask,
1467 IN PSID pSid)
1469 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1472 /******************************************************************************
1473 * AddAccessDeniedAce [ADVAPI32.@]
1475 BOOL WINAPI AddAccessDeniedAce(
1476 IN OUT PACL pAcl,
1477 IN DWORD dwAceRevision,
1478 IN DWORD AccessMask,
1479 IN PSID pSid)
1481 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1484 /******************************************************************************
1485 * AddAccessDeniedAceEx [ADVAPI32.@]
1487 BOOL WINAPI AddAccessDeniedAceEx(
1488 IN OUT PACL pAcl,
1489 IN DWORD dwAceRevision,
1490 IN DWORD AceFlags,
1491 IN DWORD AccessMask,
1492 IN PSID pSid)
1494 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1497 /******************************************************************************
1498 * AddAce [ADVAPI32.@]
1500 BOOL WINAPI AddAce(
1501 IN OUT PACL pAcl,
1502 IN DWORD dwAceRevision,
1503 IN DWORD dwStartingAceIndex,
1504 LPVOID pAceList,
1505 DWORD nAceListLength)
1507 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1510 /******************************************************************************
1511 * DeleteAce [ADVAPI32.@]
1513 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1515 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1518 /******************************************************************************
1519 * FindFirstFreeAce [ADVAPI32.@]
1521 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1523 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1526 /******************************************************************************
1527 * GetAce [ADVAPI32.@]
1529 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1531 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1534 /******************************************************************************
1535 * GetAclInformation [ADVAPI32.@]
1537 BOOL WINAPI GetAclInformation(
1538 PACL pAcl,
1539 LPVOID pAclInformation,
1540 DWORD nAclInformationLength,
1541 ACL_INFORMATION_CLASS dwAclInformationClass)
1543 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1544 nAclInformationLength, dwAclInformationClass));
1547 /******************************************************************************
1548 * IsValidAcl [ADVAPI32.@]
1550 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1552 return RtlValidAcl(pAcl);
1555 /* ##############################
1556 ###### MISC FUNCTIONS ######
1557 ##############################
1560 /******************************************************************************
1561 * AllocateLocallyUniqueId [ADVAPI32.@]
1563 * PARAMS
1564 * lpLuid []
1566 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1568 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1571 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1572 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1573 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1574 { '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 };
1575 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1576 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1578 { '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 };
1579 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1580 { '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 };
1581 static const WCHAR SE_TCB_NAME_W[] =
1582 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_SECURITY_NAME_W[] =
1584 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1585 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1586 { '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 };
1587 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1588 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1589 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1592 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1593 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1596 { '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 };
1597 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1598 { '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 };
1599 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1600 { '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 };
1601 static const WCHAR SE_BACKUP_NAME_W[] =
1602 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_RESTORE_NAME_W[] =
1604 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1606 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1607 static const WCHAR SE_DEBUG_NAME_W[] =
1608 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_AUDIT_NAME_W[] =
1610 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1611 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1612 { '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 };
1613 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1614 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_UNDOCK_NAME_W[] =
1618 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1620 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1622 { '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 };
1623 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1624 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1626 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1627 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1628 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1632 NULL,
1633 NULL,
1634 SE_CREATE_TOKEN_NAME_W,
1635 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1636 SE_LOCK_MEMORY_NAME_W,
1637 SE_INCREASE_QUOTA_NAME_W,
1638 SE_MACHINE_ACCOUNT_NAME_W,
1639 SE_TCB_NAME_W,
1640 SE_SECURITY_NAME_W,
1641 SE_TAKE_OWNERSHIP_NAME_W,
1642 SE_LOAD_DRIVER_NAME_W,
1643 SE_SYSTEM_PROFILE_NAME_W,
1644 SE_SYSTEMTIME_NAME_W,
1645 SE_PROF_SINGLE_PROCESS_NAME_W,
1646 SE_INC_BASE_PRIORITY_NAME_W,
1647 SE_CREATE_PAGEFILE_NAME_W,
1648 SE_CREATE_PERMANENT_NAME_W,
1649 SE_BACKUP_NAME_W,
1650 SE_RESTORE_NAME_W,
1651 SE_SHUTDOWN_NAME_W,
1652 SE_DEBUG_NAME_W,
1653 SE_AUDIT_NAME_W,
1654 SE_SYSTEM_ENVIRONMENT_NAME_W,
1655 SE_CHANGE_NOTIFY_NAME_W,
1656 SE_REMOTE_SHUTDOWN_NAME_W,
1657 SE_UNDOCK_NAME_W,
1658 SE_SYNC_AGENT_NAME_W,
1659 SE_ENABLE_DELEGATION_NAME_W,
1660 SE_MANAGE_VOLUME_NAME_W,
1661 SE_IMPERSONATE_NAME_W,
1662 SE_CREATE_GLOBAL_NAME_W,
1665 /******************************************************************************
1666 * LookupPrivilegeValueW [ADVAPI32.@]
1668 * See LookupPrivilegeValueA.
1670 BOOL WINAPI
1671 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1673 UINT i;
1675 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1677 if (!ADVAPI_IsLocalComputer(lpSystemName))
1679 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1680 return FALSE;
1682 if (!lpName)
1684 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1685 return FALSE;
1687 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1689 if( !WellKnownPrivNames[i] )
1690 continue;
1691 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1692 continue;
1693 lpLuid->LowPart = i;
1694 lpLuid->HighPart = 0;
1695 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1696 lpLuid->HighPart, lpLuid->LowPart );
1697 return TRUE;
1699 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1700 return FALSE;
1703 /******************************************************************************
1704 * LookupPrivilegeValueA [ADVAPI32.@]
1706 * Retrieves LUID used on a system to represent the privilege name.
1708 * PARAMS
1709 * lpSystemName [I] Name of the system
1710 * lpName [I] Name of the privilege
1711 * lpLuid [O] Destination for the resulting LUID
1713 * RETURNS
1714 * Success: TRUE. lpLuid contains the requested LUID.
1715 * Failure: FALSE.
1717 BOOL WINAPI
1718 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1720 UNICODE_STRING lpSystemNameW;
1721 UNICODE_STRING lpNameW;
1722 BOOL ret;
1724 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1725 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1726 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1727 RtlFreeUnicodeString(&lpNameW);
1728 RtlFreeUnicodeString(&lpSystemNameW);
1729 return ret;
1732 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1733 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1735 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1736 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1738 return FALSE;
1741 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1742 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1744 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1745 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1747 return FALSE;
1750 /******************************************************************************
1751 * LookupPrivilegeNameA [ADVAPI32.@]
1753 * See LookupPrivilegeNameW.
1755 BOOL WINAPI
1756 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1757 LPDWORD cchName)
1759 UNICODE_STRING lpSystemNameW;
1760 BOOL ret;
1761 DWORD wLen = 0;
1763 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1765 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1766 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1767 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1769 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1771 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1772 &wLen);
1773 if (ret)
1775 /* Windows crashes if cchName is NULL, so will I */
1776 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1777 *cchName, NULL, NULL);
1779 if (len == 0)
1781 /* WideCharToMultiByte failed */
1782 ret = FALSE;
1784 else if (len > *cchName)
1786 *cchName = len;
1787 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1788 ret = FALSE;
1790 else
1792 /* WideCharToMultiByte succeeded, output length needs to be
1793 * length not including NULL terminator
1795 *cchName = len - 1;
1798 HeapFree(GetProcessHeap(), 0, lpNameW);
1800 RtlFreeUnicodeString(&lpSystemNameW);
1801 return ret;
1804 /******************************************************************************
1805 * LookupPrivilegeNameW [ADVAPI32.@]
1807 * Retrieves the privilege name referred to by the LUID lpLuid.
1809 * PARAMS
1810 * lpSystemName [I] Name of the system
1811 * lpLuid [I] Privilege value
1812 * lpName [O] Name of the privilege
1813 * cchName [I/O] Number of characters in lpName.
1815 * RETURNS
1816 * Success: TRUE. lpName contains the name of the privilege whose value is
1817 * *lpLuid.
1818 * Failure: FALSE.
1820 * REMARKS
1821 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1822 * using this function.
1823 * If the length of lpName is too small, on return *cchName will contain the
1824 * number of WCHARs needed to contain the privilege, including the NULL
1825 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1826 * On success, *cchName will contain the number of characters stored in
1827 * lpName, NOT including the NULL terminator.
1829 BOOL WINAPI
1830 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1831 LPDWORD cchName)
1833 size_t privNameLen;
1835 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1837 if (!ADVAPI_IsLocalComputer(lpSystemName))
1839 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1840 return FALSE;
1842 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1843 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1845 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1846 return FALSE;
1848 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1849 /* Windows crashes if cchName is NULL, so will I */
1850 if (*cchName <= privNameLen)
1852 *cchName = privNameLen + 1;
1853 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1854 return FALSE;
1856 else
1858 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1859 *cchName = privNameLen;
1860 return TRUE;
1864 /******************************************************************************
1865 * GetFileSecurityA [ADVAPI32.@]
1867 * Obtains Specified information about the security of a file or directory.
1869 * PARAMS
1870 * lpFileName [I] Name of the file to get info for
1871 * RequestedInformation [I] SE_ flags from "winnt.h"
1872 * pSecurityDescriptor [O] Destination for security information
1873 * nLength [I] Length of pSecurityDescriptor
1874 * lpnLengthNeeded [O] Destination for length of returned security information
1876 * RETURNS
1877 * Success: TRUE. pSecurityDescriptor contains the requested information.
1878 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1880 * NOTES
1881 * The information returned is constrained by the callers access rights and
1882 * privileges.
1884 BOOL WINAPI
1885 GetFileSecurityA( LPCSTR lpFileName,
1886 SECURITY_INFORMATION RequestedInformation,
1887 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1888 DWORD nLength, LPDWORD lpnLengthNeeded )
1890 DWORD len;
1891 BOOL r;
1892 LPWSTR name = NULL;
1894 if( lpFileName )
1896 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1897 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1898 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1901 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1902 nLength, lpnLengthNeeded );
1903 HeapFree( GetProcessHeap(), 0, name );
1905 return r;
1908 /******************************************************************************
1909 * GetFileSecurityW [ADVAPI32.@]
1911 * See GetFileSecurityA.
1913 BOOL WINAPI
1914 GetFileSecurityW( LPCWSTR lpFileName,
1915 SECURITY_INFORMATION RequestedInformation,
1916 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1917 DWORD nLength, LPDWORD lpnLengthNeeded )
1919 HANDLE hfile;
1920 NTSTATUS status;
1921 DWORD access = 0;
1923 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1924 RequestedInformation, pSecurityDescriptor,
1925 nLength, lpnLengthNeeded);
1927 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1928 DACL_SECURITY_INFORMATION))
1929 access |= READ_CONTROL;
1930 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1931 access |= ACCESS_SYSTEM_SECURITY;
1933 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1934 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1935 if ( hfile == INVALID_HANDLE_VALUE )
1936 return FALSE;
1938 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1939 nLength, lpnLengthNeeded );
1940 CloseHandle( hfile );
1941 return set_ntstatus( status );
1945 /******************************************************************************
1946 * LookupAccountSidA [ADVAPI32.@]
1948 BOOL WINAPI
1949 LookupAccountSidA(
1950 IN LPCSTR system,
1951 IN PSID sid,
1952 OUT LPSTR account,
1953 IN OUT LPDWORD accountSize,
1954 OUT LPSTR domain,
1955 IN OUT LPDWORD domainSize,
1956 OUT PSID_NAME_USE name_use )
1958 DWORD len;
1959 BOOL r;
1960 LPWSTR systemW = NULL;
1961 LPWSTR accountW = NULL;
1962 LPWSTR domainW = NULL;
1963 DWORD accountSizeW = *accountSize;
1964 DWORD domainSizeW = *domainSize;
1966 if (system) {
1967 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1968 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1969 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1971 if (account)
1972 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1973 if (domain)
1974 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1976 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1978 if (r) {
1979 if (accountW && *accountSize) {
1980 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1981 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1982 *accountSize = len;
1983 } else
1984 *accountSize = accountSizeW + 1;
1986 if (domainW && *domainSize) {
1987 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1988 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1989 *domainSize = len;
1990 } else
1991 *domainSize = domainSizeW + 1;
1994 HeapFree( GetProcessHeap(), 0, systemW );
1995 HeapFree( GetProcessHeap(), 0, accountW );
1996 HeapFree( GetProcessHeap(), 0, domainW );
1998 return r;
2001 /******************************************************************************
2002 * LookupAccountSidW [ADVAPI32.@]
2004 * PARAMS
2005 * system []
2006 * sid []
2007 * account []
2008 * accountSize []
2009 * domain []
2010 * domainSize []
2011 * name_use []
2014 BOOL WINAPI
2015 LookupAccountSidW(
2016 IN LPCWSTR system,
2017 IN PSID sid,
2018 OUT LPWSTR account,
2019 IN OUT LPDWORD accountSize,
2020 OUT LPWSTR domain,
2021 IN OUT LPDWORD domainSize,
2022 OUT PSID_NAME_USE name_use )
2024 unsigned int i, j;
2025 const WCHAR * ac = NULL;
2026 const WCHAR * dm = NULL;
2027 SID_NAME_USE use = 0;
2028 LPWSTR computer_name = NULL;
2029 LPWSTR account_name = NULL;
2031 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2032 debugstr_w(system),debugstr_sid(sid),
2033 account,accountSize,accountSize?*accountSize:0,
2034 domain,domainSize,domainSize?*domainSize:0,
2035 name_use);
2037 if (!ADVAPI_IsLocalComputer(system)) {
2038 FIXME("Only local computer supported!\n");
2039 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2040 return FALSE;
2043 /* check the well known SIDs first */
2044 for (i = 0; i <= 60; i++) {
2045 if (IsWellKnownSid(sid, i)) {
2046 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2047 if (ACCOUNT_SIDS[j].type == i) {
2048 ac = ACCOUNT_SIDS[j].account;
2049 dm = ACCOUNT_SIDS[j].domain;
2050 use = ACCOUNT_SIDS[j].name_use;
2053 break;
2057 if (dm == NULL) {
2058 MAX_SID local;
2060 /* check for the local computer next */
2061 if (ADVAPI_GetComputerSid(&local)) {
2062 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2063 BOOL result;
2065 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2066 result = GetComputerNameW(computer_name, &size);
2068 if (result) {
2069 if (EqualSid(sid, &local)) {
2070 dm = computer_name;
2071 ac = Blank;
2072 use = 3;
2073 } else {
2074 local.SubAuthorityCount++;
2076 if (EqualPrefixSid(sid, &local)) {
2077 dm = computer_name;
2078 use = 1;
2079 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2080 case DOMAIN_USER_RID_ADMIN:
2081 ac = Administrator;
2082 break;
2083 case DOMAIN_USER_RID_GUEST:
2084 ac = Guest;
2085 break;
2086 case DOMAIN_GROUP_RID_ADMINS:
2087 ac = Domain_Admins;
2088 break;
2089 case DOMAIN_GROUP_RID_USERS:
2090 ac = Domain_Users;
2091 break;
2092 case DOMAIN_GROUP_RID_GUESTS:
2093 ac = Domain_Guests;
2094 break;
2095 case DOMAIN_GROUP_RID_COMPUTERS:
2096 ac = Domain_Computers;
2097 break;
2098 case DOMAIN_GROUP_RID_CONTROLLERS:
2099 ac = Domain_Controllers;
2100 break;
2101 case DOMAIN_GROUP_RID_CERT_ADMINS:
2102 ac = Cert_Publishers;
2103 break;
2104 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2105 ac = Schema_Admins;
2106 break;
2107 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2108 ac = Enterprise_Admins;
2109 break;
2110 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2111 ac = Group_Policy_Creator_Owners;
2112 break;
2113 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2114 ac = RAS_and_IAS_Servers;
2115 break;
2116 case 1000: /* first user account */
2117 size = UNLEN + 1;
2118 account_name = HeapAlloc(
2119 GetProcessHeap(), 0, size * sizeof(WCHAR));
2120 if (GetUserNameW(account_name, &size))
2121 ac = account_name;
2122 else
2123 dm = NULL;
2125 break;
2126 default:
2127 dm = NULL;
2128 break;
2136 if (dm) {
2137 DWORD ac_len = lstrlenW(ac);
2138 DWORD dm_len = lstrlenW(dm);
2139 BOOL status = TRUE;
2141 if (*accountSize > ac_len) {
2142 if (account)
2143 lstrcpyW(account, ac);
2145 if (*domainSize > dm_len) {
2146 if (domain)
2147 lstrcpyW(domain, dm);
2149 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2150 ((*domainSize != 0) && (*domainSize < dm_len))) {
2151 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2152 status = FALSE;
2154 if (*domainSize)
2155 *domainSize = dm_len;
2156 else
2157 *domainSize = dm_len + 1;
2158 if (*accountSize)
2159 *accountSize = ac_len;
2160 else
2161 *accountSize = ac_len + 1;
2162 *name_use = use;
2163 HeapFree(GetProcessHeap(), 0, account_name);
2164 HeapFree(GetProcessHeap(), 0, computer_name);
2165 return status;
2168 HeapFree(GetProcessHeap(), 0, account_name);
2169 HeapFree(GetProcessHeap(), 0, computer_name);
2170 SetLastError(ERROR_NONE_MAPPED);
2171 return FALSE;
2174 /******************************************************************************
2175 * SetFileSecurityA [ADVAPI32.@]
2177 * See SetFileSecurityW.
2179 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2180 SECURITY_INFORMATION RequestedInformation,
2181 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2183 DWORD len;
2184 BOOL r;
2185 LPWSTR name = NULL;
2187 if( lpFileName )
2189 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2190 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2191 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2194 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2195 HeapFree( GetProcessHeap(), 0, name );
2197 return r;
2200 /******************************************************************************
2201 * SetFileSecurityW [ADVAPI32.@]
2203 * Sets the security of a file or directory.
2205 * PARAMS
2206 * lpFileName []
2207 * RequestedInformation []
2208 * pSecurityDescriptor []
2210 * RETURNS
2211 * Success: TRUE.
2212 * Failure: FALSE.
2214 BOOL WINAPI
2215 SetFileSecurityW( LPCWSTR lpFileName,
2216 SECURITY_INFORMATION RequestedInformation,
2217 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2219 HANDLE file;
2220 DWORD access = 0;
2221 NTSTATUS status;
2223 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2224 pSecurityDescriptor );
2226 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2227 RequestedInformation & GROUP_SECURITY_INFORMATION)
2228 access |= WRITE_OWNER;
2229 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2230 access |= ACCESS_SYSTEM_SECURITY;
2231 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2232 access |= WRITE_DAC;
2234 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2235 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2236 if (file == INVALID_HANDLE_VALUE)
2237 return FALSE;
2239 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2240 CloseHandle( file );
2241 return set_ntstatus( status );
2244 /******************************************************************************
2245 * QueryWindows31FilesMigration [ADVAPI32.@]
2247 * PARAMS
2248 * x1 []
2250 BOOL WINAPI
2251 QueryWindows31FilesMigration( DWORD x1 )
2253 FIXME("(%d):stub\n",x1);
2254 return TRUE;
2257 /******************************************************************************
2258 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2260 * PARAMS
2261 * x1 []
2262 * x2 []
2263 * x3 []
2264 * x4 []
2266 BOOL WINAPI
2267 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2268 DWORD x4 )
2270 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2271 return TRUE;
2274 /******************************************************************************
2275 * NotifyBootConfigStatus [ADVAPI32.@]
2277 * PARAMS
2278 * x1 []
2280 BOOL WINAPI
2281 NotifyBootConfigStatus( BOOL x1 )
2283 FIXME("(0x%08d):stub\n",x1);
2284 return 1;
2287 /******************************************************************************
2288 * RevertToSelf [ADVAPI32.@]
2290 * Ends the impersonation of a user.
2292 * PARAMS
2293 * void []
2295 * RETURNS
2296 * Success: TRUE.
2297 * Failure: FALSE.
2299 BOOL WINAPI
2300 RevertToSelf( void )
2302 HANDLE Token = NULL;
2303 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2304 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2307 /******************************************************************************
2308 * ImpersonateSelf [ADVAPI32.@]
2310 * Makes an impersonation token that represents the process user and assigns
2311 * to the current thread.
2313 * PARAMS
2314 * ImpersonationLevel [I] Level at which to impersonate.
2316 * RETURNS
2317 * Success: TRUE.
2318 * Failure: FALSE.
2320 BOOL WINAPI
2321 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2323 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2326 /******************************************************************************
2327 * ImpersonateLoggedOnUser [ADVAPI32.@]
2329 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2331 DWORD size;
2332 NTSTATUS Status;
2333 HANDLE ImpersonationToken;
2334 TOKEN_TYPE Type;
2335 static BOOL warn = TRUE;
2337 if (warn)
2339 FIXME( "(%p)\n", hToken );
2340 warn = FALSE;
2342 if (!GetTokenInformation( hToken, TokenType, &Type,
2343 sizeof(TOKEN_TYPE), &size ))
2344 return FALSE;
2346 if (Type == TokenPrimary)
2348 OBJECT_ATTRIBUTES ObjectAttributes;
2350 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2352 Status = NtDuplicateToken( hToken,
2353 TOKEN_IMPERSONATE | TOKEN_QUERY,
2354 &ObjectAttributes,
2355 SecurityImpersonation,
2356 TokenImpersonation,
2357 &ImpersonationToken );
2358 if (Status != STATUS_SUCCESS)
2360 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2361 SetLastError( RtlNtStatusToDosError( Status ) );
2362 return FALSE;
2365 else
2366 ImpersonationToken = hToken;
2368 Status = NtSetInformationThread( GetCurrentThread(),
2369 ThreadImpersonationToken,
2370 &ImpersonationToken,
2371 sizeof(ImpersonationToken) );
2373 if (Type == TokenPrimary)
2374 NtClose( ImpersonationToken );
2376 if (Status != STATUS_SUCCESS)
2378 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2379 SetLastError( RtlNtStatusToDosError( Status ) );
2380 return FALSE;
2383 return TRUE;
2386 /******************************************************************************
2387 * AccessCheck [ADVAPI32.@]
2389 BOOL WINAPI
2390 AccessCheck(
2391 PSECURITY_DESCRIPTOR SecurityDescriptor,
2392 HANDLE ClientToken,
2393 DWORD DesiredAccess,
2394 PGENERIC_MAPPING GenericMapping,
2395 PPRIVILEGE_SET PrivilegeSet,
2396 LPDWORD PrivilegeSetLength,
2397 LPDWORD GrantedAccess,
2398 LPBOOL AccessStatus)
2400 NTSTATUS access_status;
2401 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2402 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2403 GrantedAccess, &access_status) );
2404 if (ret) *AccessStatus = set_ntstatus( access_status );
2405 return ret;
2409 /******************************************************************************
2410 * AccessCheckByType [ADVAPI32.@]
2412 BOOL WINAPI AccessCheckByType(
2413 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2414 PSID PrincipalSelfSid,
2415 HANDLE ClientToken,
2416 DWORD DesiredAccess,
2417 POBJECT_TYPE_LIST ObjectTypeList,
2418 DWORD ObjectTypeListLength,
2419 PGENERIC_MAPPING GenericMapping,
2420 PPRIVILEGE_SET PrivilegeSet,
2421 LPDWORD PrivilegeSetLength,
2422 LPDWORD GrantedAccess,
2423 LPBOOL AccessStatus)
2425 FIXME("stub\n");
2427 *AccessStatus = TRUE;
2429 return !*AccessStatus;
2432 /******************************************************************************
2433 * MapGenericMask [ADVAPI32.@]
2435 * Maps generic access rights into specific access rights according to the
2436 * supplied mapping.
2438 * PARAMS
2439 * AccessMask [I/O] Access rights.
2440 * GenericMapping [I] The mapping between generic and specific rights.
2442 * RETURNS
2443 * Nothing.
2445 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2447 RtlMapGenericMask( AccessMask, GenericMapping );
2450 /*************************************************************************
2451 * SetKernelObjectSecurity [ADVAPI32.@]
2453 BOOL WINAPI SetKernelObjectSecurity (
2454 IN HANDLE Handle,
2455 IN SECURITY_INFORMATION SecurityInformation,
2456 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2458 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2462 /******************************************************************************
2463 * AddAuditAccessAce [ADVAPI32.@]
2465 BOOL WINAPI AddAuditAccessAce(
2466 IN OUT PACL pAcl,
2467 IN DWORD dwAceRevision,
2468 IN DWORD dwAccessMask,
2469 IN PSID pSid,
2470 IN BOOL bAuditSuccess,
2471 IN BOOL bAuditFailure)
2473 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2474 bAuditSuccess, bAuditFailure) );
2477 /******************************************************************************
2478 * AddAuditAccessAce [ADVAPI32.@]
2480 BOOL WINAPI AddAuditAccessAceEx(
2481 IN OUT PACL pAcl,
2482 IN DWORD dwAceRevision,
2483 IN DWORD dwAceFlags,
2484 IN DWORD dwAccessMask,
2485 IN PSID pSid,
2486 IN BOOL bAuditSuccess,
2487 IN BOOL bAuditFailure)
2489 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2490 bAuditSuccess, bAuditFailure) );
2493 /******************************************************************************
2494 * LookupAccountNameA [ADVAPI32.@]
2496 BOOL WINAPI
2497 LookupAccountNameA(
2498 IN LPCSTR system,
2499 IN LPCSTR account,
2500 OUT PSID sid,
2501 OUT LPDWORD cbSid,
2502 LPSTR ReferencedDomainName,
2503 IN OUT LPDWORD cbReferencedDomainName,
2504 OUT PSID_NAME_USE name_use )
2506 BOOL ret;
2507 UNICODE_STRING lpSystemW;
2508 UNICODE_STRING lpAccountW;
2509 LPWSTR lpReferencedDomainNameW = NULL;
2511 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2512 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2514 if (ReferencedDomainName)
2515 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2517 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2518 cbReferencedDomainName, name_use);
2520 if (ret && lpReferencedDomainNameW)
2522 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2523 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2526 RtlFreeUnicodeString(&lpSystemW);
2527 RtlFreeUnicodeString(&lpAccountW);
2528 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2530 return ret;
2533 /******************************************************************************
2534 * lookup_user_account_name
2536 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2537 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2539 /* Default implementation: Always return a default SID */
2540 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2541 BOOL ret;
2542 PSID pSid;
2543 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2544 DWORD nameLen;
2545 LPCWSTR domainName;
2547 ret = AllocateAndInitializeSid(&identifierAuthority,
2549 SECURITY_BUILTIN_DOMAIN_RID,
2550 DOMAIN_ALIAS_RID_ADMINS,
2551 0, 0, 0, 0, 0, 0,
2552 &pSid);
2554 if (!ret)
2555 return FALSE;
2557 if (!RtlValidSid(pSid))
2559 FreeSid(pSid);
2560 return FALSE;
2563 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2564 CopySid(*cbSid, Sid, pSid);
2565 if (*cbSid < GetLengthSid(pSid))
2567 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2568 ret = FALSE;
2570 *cbSid = GetLengthSid(pSid);
2572 domainName = dm;
2573 nameLen = strlenW(domainName);
2575 if (*cchReferencedDomainName <= nameLen || !ret)
2577 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2578 nameLen += 1;
2579 ret = FALSE;
2581 else if (ReferencedDomainName)
2582 strcpyW(ReferencedDomainName, domainName);
2584 *cchReferencedDomainName = nameLen;
2586 if (ret)
2587 *peUse = SidTypeUser;
2589 FreeSid(pSid);
2591 return ret;
2594 /******************************************************************************
2595 * lookup_computer_account_name
2597 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2598 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2600 MAX_SID local;
2601 BOOL ret;
2602 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2603 DWORD nameLen;
2604 LPCWSTR domainName;
2606 if ((ret = ADVAPI_GetComputerSid(&local)))
2608 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2609 CopySid(*cbSid, Sid, &local);
2610 if (*cbSid < GetLengthSid(&local))
2612 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2613 ret = FALSE;
2615 *cbSid = GetLengthSid(&local);
2618 domainName = dm;
2619 nameLen = strlenW(domainName);
2621 if (*cchReferencedDomainName <= nameLen || !ret)
2623 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2624 nameLen += 1;
2625 ret = FALSE;
2627 else if (ReferencedDomainName)
2628 strcpyW(ReferencedDomainName, domainName);
2630 *cchReferencedDomainName = nameLen;
2632 if (ret)
2633 *peUse = SidTypeDomain;
2635 return ret;
2638 /******************************************************************************
2639 * LookupAccountNameW [ADVAPI32.@]
2641 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2642 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2643 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2645 BOOL ret;
2646 PSID pSid;
2647 unsigned int i;
2648 DWORD nameLen;
2649 LPWSTR userName = NULL;
2650 LPCWSTR domainName;
2652 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2653 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2655 if (!ADVAPI_IsLocalComputer(lpSystemName))
2657 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2658 return FALSE;
2661 if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2663 lpAccountName = BUILTIN;
2666 /* Check well known SIDs first */
2668 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2670 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2672 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2674 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2676 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2678 if (ret)
2680 if (*cbSid < sidLen)
2682 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2683 ret = FALSE;
2685 else if (Sid)
2687 CopySid(*cbSid, Sid, pSid);
2690 *cbSid = sidLen;
2693 domainName = ACCOUNT_SIDS[i].domain;
2694 nameLen = strlenW(domainName);
2696 if (*cchReferencedDomainName <= nameLen || !ret)
2698 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2699 nameLen += 1;
2700 ret = FALSE;
2702 else if (ReferencedDomainName)
2704 strcpyW(ReferencedDomainName, domainName);
2707 *cchReferencedDomainName = nameLen;
2709 if (ret)
2711 *peUse = ACCOUNT_SIDS[i].name_use;
2714 HeapFree(GetProcessHeap(), 0, pSid);
2716 return ret;
2720 /* Let the current Unix user id masquerade as first Windows user account */
2722 nameLen = UNLEN + 1;
2724 userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR));
2726 if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2727 ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
2728 cchReferencedDomainName, peUse);
2729 else
2731 nameLen = UNLEN + 1;
2732 if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountName, userName))
2733 ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
2734 cchReferencedDomainName, peUse);
2735 else
2737 SetLastError(ERROR_NONE_MAPPED);
2738 ret = FALSE;
2742 HeapFree(GetProcessHeap(), 0, userName);
2744 return ret;
2747 /******************************************************************************
2748 * PrivilegeCheck [ADVAPI32.@]
2750 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2752 BOOL ret;
2753 BOOLEAN Result;
2755 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2757 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2758 if (ret)
2759 *pfResult = Result;
2760 return ret;
2763 /******************************************************************************
2764 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2766 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2767 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2768 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2769 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2771 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2772 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2773 SecurityDescriptor, DesiredAccess, GenericMapping,
2774 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2775 return TRUE;
2778 /******************************************************************************
2779 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2781 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2782 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2783 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2784 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2786 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2787 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2788 SecurityDescriptor, DesiredAccess, GenericMapping,
2789 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2790 return TRUE;
2793 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2795 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2797 return TRUE;
2800 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2802 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2804 return TRUE;
2807 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2809 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2811 return TRUE;
2814 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2815 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2816 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2817 LPBOOL GenerateOnClose)
2819 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2820 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2821 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2822 GenerateOnClose);
2824 return TRUE;
2827 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2828 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2829 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2830 LPBOOL GenerateOnClose)
2832 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2833 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2834 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2835 GenerateOnClose);
2837 return TRUE;
2840 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2841 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2843 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2844 DesiredAccess, Privileges, AccessGranted);
2846 return TRUE;
2849 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2850 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2852 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2853 DesiredAccess, Privileges, AccessGranted);
2855 return TRUE;
2858 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2859 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2861 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2862 ClientToken, Privileges, AccessGranted);
2864 return TRUE;
2867 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2868 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2870 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2871 ClientToken, Privileges, AccessGranted);
2873 return TRUE;
2876 /******************************************************************************
2877 * GetSecurityInfo [ADVAPI32.@]
2879 * Retrieves a copy of the security descriptor associated with an object.
2881 * PARAMS
2882 * hObject [I] A handle for the object.
2883 * ObjectType [I] The type of object.
2884 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2885 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2886 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2887 * ppDacl [O] If non-null, receives a pointer to the DACL.
2888 * ppSacl [O] If non-null, receives a pointer to the SACL.
2889 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2890 * which must be freed with LocalFree.
2892 * RETURNS
2893 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2895 DWORD WINAPI GetSecurityInfo(
2896 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2897 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2898 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2899 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2902 PSECURITY_DESCRIPTOR sd;
2903 NTSTATUS status;
2904 ULONG n1, n2;
2905 BOOL present, defaulted;
2907 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2908 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2909 return RtlNtStatusToDosError(status);
2911 sd = LocalAlloc(0, n1);
2912 if (!sd)
2913 return ERROR_NOT_ENOUGH_MEMORY;
2915 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2916 if (status != STATUS_SUCCESS)
2918 LocalFree(sd);
2919 return RtlNtStatusToDosError(status);
2922 if (ppsidOwner)
2924 *ppsidOwner = NULL;
2925 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2927 if (ppsidGroup)
2929 *ppsidGroup = NULL;
2930 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2932 if (ppDacl)
2934 *ppDacl = NULL;
2935 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2937 if (ppSacl)
2939 *ppSacl = NULL;
2940 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2942 if (ppSecurityDescriptor)
2943 *ppSecurityDescriptor = sd;
2945 return ERROR_SUCCESS;
2948 /******************************************************************************
2949 * GetSecurityInfoExW [ADVAPI32.@]
2951 DWORD WINAPI GetSecurityInfoExW(
2952 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2953 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2954 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2955 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2958 FIXME("stub!\n");
2959 return ERROR_BAD_PROVIDER;
2962 /******************************************************************************
2963 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2965 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2966 LPSTR pTrusteeName, DWORD AccessPermissions,
2967 ACCESS_MODE AccessMode, DWORD Inheritance )
2969 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2970 AccessPermissions, AccessMode, Inheritance);
2972 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2973 pExplicitAccess->grfAccessMode = AccessMode;
2974 pExplicitAccess->grfInheritance = Inheritance;
2976 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2977 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2978 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2979 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2980 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2983 /******************************************************************************
2984 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2986 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2987 LPWSTR pTrusteeName, DWORD AccessPermissions,
2988 ACCESS_MODE AccessMode, DWORD Inheritance )
2990 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2991 AccessPermissions, AccessMode, Inheritance);
2993 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2994 pExplicitAccess->grfAccessMode = AccessMode;
2995 pExplicitAccess->grfInheritance = Inheritance;
2997 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2998 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2999 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3000 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3001 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3004 /******************************************************************************
3005 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3007 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3008 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3009 LPSTR InheritedObjectTypeName, LPSTR Name )
3011 DWORD ObjectsPresent = 0;
3013 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3014 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3016 /* Fill the OBJECTS_AND_NAME structure */
3017 pObjName->ObjectType = ObjectType;
3018 if (ObjectTypeName != NULL)
3020 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3023 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3024 if (InheritedObjectTypeName != NULL)
3026 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3029 pObjName->ObjectsPresent = ObjectsPresent;
3030 pObjName->ptstrName = Name;
3032 /* Fill the TRUSTEE structure */
3033 pTrustee->pMultipleTrustee = NULL;
3034 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3035 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3036 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3037 pTrustee->ptstrName = (LPSTR)pObjName;
3040 /******************************************************************************
3041 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3043 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3044 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3045 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3047 DWORD ObjectsPresent = 0;
3049 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3050 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3052 /* Fill the OBJECTS_AND_NAME structure */
3053 pObjName->ObjectType = ObjectType;
3054 if (ObjectTypeName != NULL)
3056 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3059 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3060 if (InheritedObjectTypeName != NULL)
3062 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3065 pObjName->ObjectsPresent = ObjectsPresent;
3066 pObjName->ptstrName = Name;
3068 /* Fill the TRUSTEE structure */
3069 pTrustee->pMultipleTrustee = NULL;
3070 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3071 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3072 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3073 pTrustee->ptstrName = (LPWSTR)pObjName;
3076 /******************************************************************************
3077 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3079 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3080 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3082 DWORD ObjectsPresent = 0;
3084 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3086 /* Fill the OBJECTS_AND_SID structure */
3087 if (pObjectGuid != NULL)
3089 pObjSid->ObjectTypeGuid = *pObjectGuid;
3090 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3092 else
3094 ZeroMemory(&pObjSid->ObjectTypeGuid,
3095 sizeof(GUID));
3098 if (pInheritedObjectGuid != NULL)
3100 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3101 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3103 else
3105 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3106 sizeof(GUID));
3109 pObjSid->ObjectsPresent = ObjectsPresent;
3110 pObjSid->pSid = pSid;
3112 /* Fill the TRUSTEE structure */
3113 pTrustee->pMultipleTrustee = NULL;
3114 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3115 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3116 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3117 pTrustee->ptstrName = (LPSTR) pObjSid;
3120 /******************************************************************************
3121 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3123 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3124 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3126 DWORD ObjectsPresent = 0;
3128 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3130 /* Fill the OBJECTS_AND_SID structure */
3131 if (pObjectGuid != NULL)
3133 pObjSid->ObjectTypeGuid = *pObjectGuid;
3134 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3136 else
3138 ZeroMemory(&pObjSid->ObjectTypeGuid,
3139 sizeof(GUID));
3142 if (pInheritedObjectGuid != NULL)
3144 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3145 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3147 else
3149 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3150 sizeof(GUID));
3153 pObjSid->ObjectsPresent = ObjectsPresent;
3154 pObjSid->pSid = pSid;
3156 /* Fill the TRUSTEE structure */
3157 pTrustee->pMultipleTrustee = NULL;
3158 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3159 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3160 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3161 pTrustee->ptstrName = (LPWSTR) pObjSid;
3164 /******************************************************************************
3165 * BuildTrusteeWithSidA [ADVAPI32.@]
3167 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3169 TRACE("%p %p\n", pTrustee, pSid);
3171 pTrustee->pMultipleTrustee = NULL;
3172 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3173 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3174 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3175 pTrustee->ptstrName = (LPSTR) pSid;
3178 /******************************************************************************
3179 * BuildTrusteeWithSidW [ADVAPI32.@]
3181 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3183 TRACE("%p %p\n", pTrustee, pSid);
3185 pTrustee->pMultipleTrustee = NULL;
3186 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3187 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3188 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3189 pTrustee->ptstrName = (LPWSTR) pSid;
3192 /******************************************************************************
3193 * BuildTrusteeWithNameA [ADVAPI32.@]
3195 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3197 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3199 pTrustee->pMultipleTrustee = NULL;
3200 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3201 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3202 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3203 pTrustee->ptstrName = name;
3206 /******************************************************************************
3207 * BuildTrusteeWithNameW [ADVAPI32.@]
3209 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3211 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3213 pTrustee->pMultipleTrustee = NULL;
3214 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3215 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3216 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3217 pTrustee->ptstrName = name;
3220 /******************************************************************************
3221 * GetTrusteeFormA [ADVAPI32.@]
3223 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3225 TRACE("(%p)\n", pTrustee);
3227 if (!pTrustee)
3228 return TRUSTEE_BAD_FORM;
3230 return pTrustee->TrusteeForm;
3233 /******************************************************************************
3234 * GetTrusteeFormW [ADVAPI32.@]
3236 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3238 TRACE("(%p)\n", pTrustee);
3240 if (!pTrustee)
3241 return TRUSTEE_BAD_FORM;
3243 return pTrustee->TrusteeForm;
3246 /******************************************************************************
3247 * GetTrusteeNameA [ADVAPI32.@]
3249 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3251 TRACE("(%p)\n", pTrustee);
3253 if (!pTrustee)
3254 return NULL;
3256 return pTrustee->ptstrName;
3259 /******************************************************************************
3260 * GetTrusteeNameW [ADVAPI32.@]
3262 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3264 TRACE("(%p)\n", pTrustee);
3266 if (!pTrustee)
3267 return NULL;
3269 return pTrustee->ptstrName;
3272 /******************************************************************************
3273 * GetTrusteeTypeA [ADVAPI32.@]
3275 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3277 TRACE("(%p)\n", pTrustee);
3279 if (!pTrustee)
3280 return TRUSTEE_IS_UNKNOWN;
3282 return pTrustee->TrusteeType;
3285 /******************************************************************************
3286 * GetTrusteeTypeW [ADVAPI32.@]
3288 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3290 TRACE("(%p)\n", pTrustee);
3292 if (!pTrustee)
3293 return TRUSTEE_IS_UNKNOWN;
3295 return pTrustee->TrusteeType;
3298 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3299 DWORD nAclInformationLength,
3300 ACL_INFORMATION_CLASS dwAclInformationClass )
3302 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3303 nAclInformationLength, dwAclInformationClass);
3305 return TRUE;
3308 /******************************************************************************
3309 * SetEntriesInAclA [ADVAPI32.@]
3311 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3312 PACL OldAcl, PACL* NewAcl )
3314 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3315 if (NewAcl)
3316 *NewAcl = NULL;
3317 return ERROR_SUCCESS;
3320 /******************************************************************************
3321 * SetEntriesInAclW [ADVAPI32.@]
3323 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3324 PACL OldAcl, PACL* NewAcl )
3326 ULONG i;
3327 PSID *ppsid;
3328 DWORD ret = ERROR_SUCCESS;
3329 DWORD acl_size = sizeof(ACL);
3330 NTSTATUS status;
3332 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3334 *NewAcl = NULL;
3336 if (!count && !OldAcl)
3337 return ERROR_SUCCESS;
3339 /* allocate array of maximum sized sids allowed */
3340 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3341 if (!ppsid)
3342 return ERROR_OUTOFMEMORY;
3344 for (i = 0; i < count; i++)
3346 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3348 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3349 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3350 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3351 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3352 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3353 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3354 pEntries[i].Trustee.ptstrName);
3356 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3358 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3359 ret = ERROR_INVALID_PARAMETER;
3360 goto exit;
3363 switch (pEntries[i].Trustee.TrusteeForm)
3365 case TRUSTEE_IS_SID:
3366 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3367 ppsid[i], pEntries[i].Trustee.ptstrName))
3369 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3370 ret = ERROR_INVALID_PARAMETER;
3371 goto exit;
3373 break;
3374 case TRUSTEE_IS_NAME:
3376 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3377 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3378 SID_NAME_USE use;
3379 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3381 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3382 ret = ERROR_INVALID_PARAMETER;
3383 goto exit;
3385 break;
3387 case TRUSTEE_IS_OBJECTS_AND_SID:
3388 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3389 break;
3390 case TRUSTEE_IS_OBJECTS_AND_NAME:
3391 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3392 break;
3393 default:
3394 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3395 ret = ERROR_INVALID_PARAMETER;
3396 goto exit;
3399 /* Note: we overestimate the ACL size here as a tradeoff between
3400 * instructions (simplicity) and memory */
3401 switch (pEntries[i].grfAccessMode)
3403 case GRANT_ACCESS:
3404 case SET_ACCESS:
3405 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3406 break;
3407 case DENY_ACCESS:
3408 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3409 break;
3410 case SET_AUDIT_SUCCESS:
3411 case SET_AUDIT_FAILURE:
3412 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3413 break;
3414 case REVOKE_ACCESS:
3415 break;
3416 default:
3417 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3418 ret = ERROR_INVALID_PARAMETER;
3419 goto exit;
3423 if (OldAcl)
3425 ACL_SIZE_INFORMATION size_info;
3427 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3428 if (status != STATUS_SUCCESS)
3430 ret = RtlNtStatusToDosError(status);
3431 goto exit;
3433 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3436 *NewAcl = LocalAlloc(0, acl_size);
3437 if (!*NewAcl)
3439 ret = ERROR_OUTOFMEMORY;
3440 goto exit;
3443 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3444 if (status != STATUS_SUCCESS)
3446 ret = RtlNtStatusToDosError(status);
3447 goto exit;
3450 for (i = 0; i < count; i++)
3452 switch (pEntries[i].grfAccessMode)
3454 case GRANT_ACCESS:
3455 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3456 pEntries[i].grfInheritance,
3457 pEntries[i].grfAccessPermissions,
3458 ppsid[i]);
3459 break;
3460 case SET_ACCESS:
3462 ULONG j;
3463 BOOL add = TRUE;
3464 if (OldAcl)
3466 for (j = 0; ; j++)
3468 const ACE_HEADER *existing_ace_header;
3469 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3470 if (status != STATUS_SUCCESS)
3471 break;
3472 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3473 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3474 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3476 add = FALSE;
3477 break;
3481 if (add)
3482 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3483 pEntries[i].grfInheritance,
3484 pEntries[i].grfAccessPermissions,
3485 ppsid[i]);
3486 break;
3488 case DENY_ACCESS:
3489 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3490 pEntries[i].grfInheritance,
3491 pEntries[i].grfAccessPermissions,
3492 ppsid[i]);
3493 break;
3494 case SET_AUDIT_SUCCESS:
3495 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3496 pEntries[i].grfInheritance,
3497 pEntries[i].grfAccessPermissions,
3498 ppsid[i], TRUE, FALSE);
3499 break;
3500 case SET_AUDIT_FAILURE:
3501 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3502 pEntries[i].grfInheritance,
3503 pEntries[i].grfAccessPermissions,
3504 ppsid[i], FALSE, TRUE);
3505 break;
3506 default:
3507 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3511 if (OldAcl)
3513 for (i = 0; ; i++)
3515 BOOL add = TRUE;
3516 ULONG j;
3517 const ACE_HEADER *old_ace_header;
3518 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3519 if (status != STATUS_SUCCESS) break;
3520 for (j = 0; j < count; j++)
3522 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3523 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3524 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3526 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3527 add = FALSE;
3528 break;
3530 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3532 switch (old_ace_header->AceType)
3534 case ACCESS_ALLOWED_ACE_TYPE:
3535 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3536 add = FALSE;
3537 break;
3538 case ACCESS_DENIED_ACE_TYPE:
3539 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3540 add = FALSE;
3541 break;
3542 case SYSTEM_AUDIT_ACE_TYPE:
3543 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3544 add = FALSE;
3545 break;
3546 case SYSTEM_ALARM_ACE_TYPE:
3547 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3548 add = FALSE;
3549 break;
3550 default:
3551 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3554 if (!add)
3555 break;
3558 if (add)
3559 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3560 if (status != STATUS_SUCCESS)
3562 WARN("RtlAddAce failed with error 0x%08x\n", status);
3563 ret = RtlNtStatusToDosError(status);
3564 break;
3569 exit:
3570 HeapFree(GetProcessHeap(), 0, ppsid);
3571 return ret;
3574 /******************************************************************************
3575 * SetNamedSecurityInfoA [ADVAPI32.@]
3577 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3578 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3579 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3581 DWORD len;
3582 LPWSTR wstr = NULL;
3583 DWORD r;
3585 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3586 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3588 if( pObjectName )
3590 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3591 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3592 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3595 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3596 psidGroup, pDacl, pSacl );
3598 HeapFree( GetProcessHeap(), 0, wstr );
3600 return r;
3603 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3604 PSECURITY_DESCRIPTOR ModificationDescriptor,
3605 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3606 PGENERIC_MAPPING GenericMapping,
3607 HANDLE Token )
3609 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3610 ObjectsSecurityDescriptor, GenericMapping, Token);
3612 return TRUE;
3615 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3617 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3620 /******************************************************************************
3621 * AreAnyAccessesGranted [ADVAPI32.@]
3623 * Determines whether or not any of a set of specified access permissions have
3624 * been granted or not.
3626 * PARAMS
3627 * GrantedAccess [I] The permissions that have been granted.
3628 * DesiredAccess [I] The permissions that you want to have.
3630 * RETURNS
3631 * Nonzero if any of the permissions have been granted, zero if none of the
3632 * permissions have been granted.
3635 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3637 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3640 /******************************************************************************
3641 * SetNamedSecurityInfoW [ADVAPI32.@]
3643 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3644 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3645 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3647 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3648 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3649 return ERROR_SUCCESS;
3652 /******************************************************************************
3653 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3655 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3656 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3658 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3659 return ERROR_CALL_NOT_IMPLEMENTED;
3662 /******************************************************************************
3663 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3665 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3666 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3668 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3669 return ERROR_CALL_NOT_IMPLEMENTED;
3672 /******************************************************************************
3673 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3675 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3676 PACCESS_MASK pFailedAuditRights)
3678 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3679 return ERROR_CALL_NOT_IMPLEMENTED;
3683 /******************************************************************************
3684 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3686 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3687 PACCESS_MASK pFailedAuditRights)
3689 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3690 return ERROR_CALL_NOT_IMPLEMENTED;
3694 /******************************************************************************
3695 * ParseAclStringFlags
3697 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3699 DWORD flags = 0;
3700 LPCWSTR szAcl = *StringAcl;
3702 while (*szAcl != '(')
3704 if (*szAcl == 'P')
3706 flags |= SE_DACL_PROTECTED;
3708 else if (*szAcl == 'A')
3710 szAcl++;
3711 if (*szAcl == 'R')
3712 flags |= SE_DACL_AUTO_INHERIT_REQ;
3713 else if (*szAcl == 'I')
3714 flags |= SE_DACL_AUTO_INHERITED;
3716 szAcl++;
3719 *StringAcl = szAcl;
3720 return flags;
3723 /******************************************************************************
3724 * ParseAceStringType
3726 static const ACEFLAG AceType[] =
3728 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3729 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3730 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3731 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3733 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3734 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3735 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3736 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3738 { NULL, 0 },
3741 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3743 UINT len = 0;
3744 LPCWSTR szAcl = *StringAcl;
3745 const ACEFLAG *lpaf = AceType;
3747 while (lpaf->wstr &&
3748 (len = strlenW(lpaf->wstr)) &&
3749 strncmpW(lpaf->wstr, szAcl, len))
3750 lpaf++;
3752 if (!lpaf->wstr)
3753 return 0;
3755 *StringAcl += len;
3756 return lpaf->value;
3760 /******************************************************************************
3761 * ParseAceStringFlags
3763 static const ACEFLAG AceFlags[] =
3765 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3766 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3767 { SDDL_INHERITED, INHERITED_ACE },
3768 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3769 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3770 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3771 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3772 { NULL, 0 },
3775 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3777 UINT len = 0;
3778 BYTE flags = 0;
3779 LPCWSTR szAcl = *StringAcl;
3781 while (*szAcl != ';')
3783 const ACEFLAG *lpaf = AceFlags;
3785 while (lpaf->wstr &&
3786 (len = strlenW(lpaf->wstr)) &&
3787 strncmpW(lpaf->wstr, szAcl, len))
3788 lpaf++;
3790 if (!lpaf->wstr)
3791 return 0;
3793 flags |= lpaf->value;
3794 szAcl += len;
3797 *StringAcl = szAcl;
3798 return flags;
3802 /******************************************************************************
3803 * ParseAceStringRights
3805 static const ACEFLAG AceRights[] =
3807 { SDDL_GENERIC_ALL, GENERIC_ALL },
3808 { SDDL_GENERIC_READ, GENERIC_READ },
3809 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3810 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3812 { SDDL_READ_CONTROL, READ_CONTROL },
3813 { SDDL_STANDARD_DELETE, DELETE },
3814 { SDDL_WRITE_DAC, WRITE_DAC },
3815 { SDDL_WRITE_OWNER, WRITE_OWNER },
3817 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3818 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3819 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3820 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3821 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3822 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3823 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3824 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3825 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3827 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3828 { SDDL_FILE_READ, FILE_GENERIC_READ },
3829 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3830 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3832 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3833 { SDDL_KEY_READ, KEY_READ },
3834 { SDDL_KEY_WRITE, KEY_WRITE },
3835 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3836 { NULL, 0 },
3839 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3841 UINT len = 0;
3842 DWORD rights = 0;
3843 LPCWSTR szAcl = *StringAcl;
3845 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3847 LPCWSTR p = szAcl;
3849 while (*p && *p != ';')
3850 p++;
3852 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3854 rights = strtoulW(szAcl, NULL, 16);
3855 szAcl = p;
3857 else
3858 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3860 else
3862 while (*szAcl != ';')
3864 const ACEFLAG *lpaf = AceRights;
3866 while (lpaf->wstr &&
3867 (len = strlenW(lpaf->wstr)) &&
3868 strncmpW(lpaf->wstr, szAcl, len))
3870 lpaf++;
3873 if (!lpaf->wstr)
3874 return 0;
3876 rights |= lpaf->value;
3877 szAcl += len;
3881 *StringAcl = szAcl;
3882 return rights;
3886 /******************************************************************************
3887 * ParseStringAclToAcl
3889 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3891 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3892 PACL pAcl, LPDWORD cBytes)
3894 DWORD val;
3895 DWORD sidlen;
3896 DWORD length = sizeof(ACL);
3897 DWORD acesize = 0;
3898 DWORD acecount = 0;
3899 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3901 TRACE("%s\n", debugstr_w(StringAcl));
3903 if (!StringAcl)
3904 return FALSE;
3906 if (pAcl) /* pAce is only useful if we're setting values */
3907 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3909 /* Parse ACL flags */
3910 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3912 /* Parse ACE */
3913 while (*StringAcl == '(')
3915 StringAcl++;
3917 /* Parse ACE type */
3918 val = ParseAceStringType(&StringAcl);
3919 if (pAce)
3920 pAce->Header.AceType = (BYTE) val;
3921 if (*StringAcl != ';')
3922 goto lerr;
3923 StringAcl++;
3925 /* Parse ACE flags */
3926 val = ParseAceStringFlags(&StringAcl);
3927 if (pAce)
3928 pAce->Header.AceFlags = (BYTE) val;
3929 if (*StringAcl != ';')
3930 goto lerr;
3931 StringAcl++;
3933 /* Parse ACE rights */
3934 val = ParseAceStringRights(&StringAcl);
3935 if (pAce)
3936 pAce->Mask = val;
3937 if (*StringAcl != ';')
3938 goto lerr;
3939 StringAcl++;
3941 /* Parse ACE object guid */
3942 if (*StringAcl != ';')
3944 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3945 goto lerr;
3947 StringAcl++;
3949 /* Parse ACE inherit object guid */
3950 if (*StringAcl != ';')
3952 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3953 goto lerr;
3955 StringAcl++;
3957 /* Parse ACE account sid */
3958 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3960 while (*StringAcl && *StringAcl != ')')
3961 StringAcl++;
3964 if (*StringAcl != ')')
3965 goto lerr;
3966 StringAcl++;
3968 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3969 length += acesize;
3970 if (pAce)
3972 pAce->Header.AceSize = acesize;
3973 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3975 acecount++;
3978 *cBytes = length;
3980 if (length > 0xffff)
3982 ERR("ACL too large\n");
3983 goto lerr;
3986 if (pAcl)
3988 pAcl->AclRevision = ACL_REVISION;
3989 pAcl->Sbz1 = 0;
3990 pAcl->AclSize = length;
3991 pAcl->AceCount = acecount++;
3992 pAcl->Sbz2 = 0;
3994 return TRUE;
3996 lerr:
3997 SetLastError(ERROR_INVALID_ACL);
3998 WARN("Invalid ACE string format\n");
3999 return FALSE;
4003 /******************************************************************************
4004 * ParseStringSecurityDescriptorToSecurityDescriptor
4006 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4007 LPCWSTR StringSecurityDescriptor,
4008 SECURITY_DESCRIPTOR* SecurityDescriptor,
4009 LPDWORD cBytes)
4011 BOOL bret = FALSE;
4012 WCHAR toktype;
4013 WCHAR tok[MAX_PATH];
4014 LPCWSTR lptoken;
4015 LPBYTE lpNext = NULL;
4016 DWORD len;
4018 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4020 if (SecurityDescriptor)
4021 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
4023 while (*StringSecurityDescriptor)
4025 toktype = *StringSecurityDescriptor;
4027 /* Expect char identifier followed by ':' */
4028 StringSecurityDescriptor++;
4029 if (*StringSecurityDescriptor != ':')
4031 SetLastError(ERROR_INVALID_PARAMETER);
4032 goto lend;
4034 StringSecurityDescriptor++;
4036 /* Extract token */
4037 lptoken = StringSecurityDescriptor;
4038 while (*lptoken && *lptoken != ':')
4039 lptoken++;
4041 if (*lptoken)
4042 lptoken--;
4044 len = lptoken - StringSecurityDescriptor;
4045 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4046 tok[len] = 0;
4048 switch (toktype)
4050 case 'O':
4052 DWORD bytes;
4054 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4055 goto lend;
4057 if (SecurityDescriptor)
4059 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4060 lpNext += bytes; /* Advance to next token */
4063 *cBytes += bytes;
4065 break;
4068 case 'G':
4070 DWORD bytes;
4072 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4073 goto lend;
4075 if (SecurityDescriptor)
4077 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4078 lpNext += bytes; /* Advance to next token */
4081 *cBytes += bytes;
4083 break;
4086 case 'D':
4088 DWORD flags;
4089 DWORD bytes;
4091 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4092 goto lend;
4094 if (SecurityDescriptor)
4096 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4097 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4098 lpNext += bytes; /* Advance to next token */
4101 *cBytes += bytes;
4103 break;
4106 case 'S':
4108 DWORD flags;
4109 DWORD bytes;
4111 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4112 goto lend;
4114 if (SecurityDescriptor)
4116 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4117 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4118 lpNext += bytes; /* Advance to next token */
4121 *cBytes += bytes;
4123 break;
4126 default:
4127 FIXME("Unknown token\n");
4128 SetLastError(ERROR_INVALID_PARAMETER);
4129 goto lend;
4132 StringSecurityDescriptor = lptoken;
4135 bret = TRUE;
4137 lend:
4138 return bret;
4141 /******************************************************************************
4142 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4144 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4145 LPCSTR StringSecurityDescriptor,
4146 DWORD StringSDRevision,
4147 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4148 PULONG SecurityDescriptorSize)
4150 UINT len;
4151 BOOL ret = FALSE;
4152 LPWSTR StringSecurityDescriptorW;
4154 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4155 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4157 if (StringSecurityDescriptorW)
4159 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4161 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4162 StringSDRevision, SecurityDescriptor,
4163 SecurityDescriptorSize);
4164 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4167 return ret;
4170 /******************************************************************************
4171 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4173 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4174 LPCWSTR StringSecurityDescriptor,
4175 DWORD StringSDRevision,
4176 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4177 PULONG SecurityDescriptorSize)
4179 DWORD cBytes;
4180 SECURITY_DESCRIPTOR* psd;
4181 BOOL bret = FALSE;
4183 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4185 if (GetVersion() & 0x80000000)
4187 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4188 goto lend;
4190 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4192 SetLastError(ERROR_INVALID_PARAMETER);
4193 goto lend;
4195 else if (StringSDRevision != SID_REVISION)
4197 SetLastError(ERROR_UNKNOWN_REVISION);
4198 goto lend;
4201 /* Compute security descriptor length */
4202 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4203 NULL, &cBytes))
4204 goto lend;
4206 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4207 GMEM_ZEROINIT, cBytes);
4208 if (!psd) goto lend;
4210 psd->Revision = SID_REVISION;
4211 psd->Control |= SE_SELF_RELATIVE;
4213 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4214 psd, &cBytes))
4216 LocalFree(psd);
4217 goto lend;
4220 if (SecurityDescriptorSize)
4221 *SecurityDescriptorSize = cBytes;
4223 bret = TRUE;
4225 lend:
4226 TRACE(" ret=%d\n", bret);
4227 return bret;
4230 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4232 if (cch == -1)
4233 cch = strlenW(string);
4235 if (plen)
4236 *plen += cch;
4238 if (pwptr)
4240 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4241 *pwptr += cch;
4245 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4247 DWORD i;
4248 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4249 WCHAR subauthfmt[] = { '-','%','u',0 };
4250 WCHAR buf[26];
4251 SID *pisid = psid;
4253 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4255 SetLastError(ERROR_INVALID_SID);
4256 return FALSE;
4259 if (pisid->IdentifierAuthority.Value[0] ||
4260 pisid->IdentifierAuthority.Value[1])
4262 FIXME("not matching MS' bugs\n");
4263 SetLastError(ERROR_INVALID_SID);
4264 return FALSE;
4267 sprintfW( buf, fmt, pisid->Revision,
4268 MAKELONG(
4269 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4270 pisid->IdentifierAuthority.Value[4] ),
4271 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4272 pisid->IdentifierAuthority.Value[2] )
4273 ) );
4274 DumpString(buf, -1, pwptr, plen);
4276 for( i=0; i<pisid->SubAuthorityCount; i++ )
4278 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4279 DumpString(buf, -1, pwptr, plen);
4281 return TRUE;
4284 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4286 size_t i;
4287 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4289 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4291 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4292 return TRUE;
4296 return DumpSidNumeric(psid, pwptr, plen);
4299 static const LPCWSTR AceRightBitNames[32] = {
4300 SDDL_CREATE_CHILD, /* 0 */
4301 SDDL_DELETE_CHILD,
4302 SDDL_LIST_CHILDREN,
4303 SDDL_SELF_WRITE,
4304 SDDL_READ_PROPERTY, /* 4 */
4305 SDDL_WRITE_PROPERTY,
4306 SDDL_DELETE_TREE,
4307 SDDL_LIST_OBJECT,
4308 SDDL_CONTROL_ACCESS, /* 8 */
4309 NULL,
4310 NULL,
4311 NULL,
4312 NULL, /* 12 */
4313 NULL,
4314 NULL,
4315 NULL,
4316 SDDL_STANDARD_DELETE, /* 16 */
4317 SDDL_READ_CONTROL,
4318 SDDL_WRITE_DAC,
4319 SDDL_WRITE_OWNER,
4320 NULL, /* 20 */
4321 NULL,
4322 NULL,
4323 NULL,
4324 NULL, /* 24 */
4325 NULL,
4326 NULL,
4327 NULL,
4328 SDDL_GENERIC_ALL, /* 28 */
4329 SDDL_GENERIC_EXECUTE,
4330 SDDL_GENERIC_WRITE,
4331 SDDL_GENERIC_READ
4334 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4336 static const WCHAR fmtW[] = {'0','x','%','x',0};
4337 WCHAR buf[15];
4338 size_t i;
4340 if (mask == 0)
4341 return;
4343 /* first check if the right have name */
4344 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4346 if (AceRights[i].wstr == NULL)
4347 break;
4348 if (mask == AceRights[i].value)
4350 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4351 return;
4355 /* then check if it can be built from bit names */
4356 for (i = 0; i < 32; i++)
4358 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4360 /* can't be built from bit names */
4361 sprintfW(buf, fmtW, mask);
4362 DumpString(buf, -1, pwptr, plen);
4363 return;
4367 /* build from bit names */
4368 for (i = 0; i < 32; i++)
4369 if (mask & (1 << i))
4370 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4373 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4375 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4376 static const WCHAR openbr = '(';
4377 static const WCHAR closebr = ')';
4378 static const WCHAR semicolon = ';';
4380 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4382 SetLastError(ERROR_INVALID_ACL);
4383 return FALSE;
4386 piace = (ACCESS_ALLOWED_ACE *)pace;
4387 DumpString(&openbr, 1, pwptr, plen);
4388 switch (piace->Header.AceType)
4390 case ACCESS_ALLOWED_ACE_TYPE:
4391 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4392 break;
4393 case ACCESS_DENIED_ACE_TYPE:
4394 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4395 break;
4396 case SYSTEM_AUDIT_ACE_TYPE:
4397 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4398 break;
4399 case SYSTEM_ALARM_ACE_TYPE:
4400 DumpString(SDDL_ALARM, -1, pwptr, plen);
4401 break;
4403 DumpString(&semicolon, 1, pwptr, plen);
4405 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4406 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4407 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4408 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4409 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4410 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4411 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4412 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4413 if (piace->Header.AceFlags & INHERITED_ACE)
4414 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4415 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4416 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4417 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4418 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4419 DumpString(&semicolon, 1, pwptr, plen);
4420 DumpRights(piace->Mask, pwptr, plen);
4421 DumpString(&semicolon, 1, pwptr, plen);
4422 /* objects not supported */
4423 DumpString(&semicolon, 1, pwptr, plen);
4424 /* objects not supported */
4425 DumpString(&semicolon, 1, pwptr, plen);
4426 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4427 return FALSE;
4428 DumpString(&closebr, 1, pwptr, plen);
4429 return TRUE;
4432 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4434 WORD count;
4435 int i;
4437 if (protected)
4438 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4439 if (autoInheritReq)
4440 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4441 if (autoInherited)
4442 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4444 if (pacl == NULL)
4445 return TRUE;
4447 if (!IsValidAcl(pacl))
4448 return FALSE;
4450 count = pacl->AceCount;
4451 for (i = 0; i < count; i++)
4453 LPVOID ace;
4454 if (!GetAce(pacl, i, &ace))
4455 return FALSE;
4456 if (!DumpAce(ace, pwptr, plen))
4457 return FALSE;
4460 return TRUE;
4463 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4465 static const WCHAR prefix[] = {'O',':',0};
4466 BOOL bDefaulted;
4467 PSID psid;
4469 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4470 return FALSE;
4472 if (psid == NULL)
4473 return TRUE;
4475 DumpString(prefix, -1, pwptr, plen);
4476 if (!DumpSid(psid, pwptr, plen))
4477 return FALSE;
4478 return TRUE;
4481 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4483 static const WCHAR prefix[] = {'G',':',0};
4484 BOOL bDefaulted;
4485 PSID psid;
4487 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4488 return FALSE;
4490 if (psid == NULL)
4491 return TRUE;
4493 DumpString(prefix, -1, pwptr, plen);
4494 if (!DumpSid(psid, pwptr, plen))
4495 return FALSE;
4496 return TRUE;
4499 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4501 static const WCHAR dacl[] = {'D',':',0};
4502 SECURITY_DESCRIPTOR_CONTROL control;
4503 BOOL present, defaulted;
4504 DWORD revision;
4505 PACL pacl;
4507 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4508 return FALSE;
4510 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4511 return FALSE;
4513 if (!present)
4514 return TRUE;
4516 DumpString(dacl, 2, pwptr, plen);
4517 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4518 return FALSE;
4519 return TRUE;
4522 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4524 static const WCHAR sacl[] = {'S',':',0};
4525 SECURITY_DESCRIPTOR_CONTROL control;
4526 BOOL present, defaulted;
4527 DWORD revision;
4528 PACL pacl;
4530 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4531 return FALSE;
4533 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4534 return FALSE;
4536 if (!present)
4537 return TRUE;
4539 DumpString(sacl, 2, pwptr, plen);
4540 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4541 return FALSE;
4542 return TRUE;
4545 /******************************************************************************
4546 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4548 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4550 ULONG len;
4551 WCHAR *wptr, *wstr;
4553 if (SDRevision != SDDL_REVISION_1)
4555 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4556 SetLastError(ERROR_UNKNOWN_REVISION);
4557 return FALSE;
4560 len = 0;
4561 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4562 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4563 return FALSE;
4564 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4565 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4566 return FALSE;
4567 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4568 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4569 return FALSE;
4570 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4571 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4572 return FALSE;
4574 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4575 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4576 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4577 return FALSE;
4578 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4579 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4580 return FALSE;
4581 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4582 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4583 return FALSE;
4584 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4585 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4586 return FALSE;
4587 *wptr = 0;
4589 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4590 *OutputString = wstr;
4591 if (OutputLen)
4592 *OutputLen = strlenW(*OutputString)+1;
4593 return TRUE;
4596 /******************************************************************************
4597 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4599 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4601 LPWSTR wstr;
4602 ULONG len;
4603 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4605 int lenA;
4607 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4608 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4609 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4610 LocalFree(wstr);
4612 if (OutputLen != NULL)
4613 *OutputLen = lenA;
4614 return TRUE;
4616 else
4618 *OutputString = NULL;
4619 if (OutputLen)
4620 *OutputLen = 0;
4621 return FALSE;
4625 /******************************************************************************
4626 * ConvertStringSidToSidW [ADVAPI32.@]
4628 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4630 BOOL bret = FALSE;
4631 DWORD cBytes;
4633 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4634 if (GetVersion() & 0x80000000)
4635 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4636 else if (!StringSid || !Sid)
4637 SetLastError(ERROR_INVALID_PARAMETER);
4638 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4640 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4642 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4643 if (!bret)
4644 LocalFree(*Sid);
4646 return bret;
4649 /******************************************************************************
4650 * ConvertStringSidToSidA [ADVAPI32.@]
4652 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4654 BOOL bret = FALSE;
4656 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4657 if (GetVersion() & 0x80000000)
4658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4659 else if (!StringSid || !Sid)
4660 SetLastError(ERROR_INVALID_PARAMETER);
4661 else
4663 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4664 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4665 len * sizeof(WCHAR));
4667 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4668 bret = ConvertStringSidToSidW(wStringSid, Sid);
4669 HeapFree(GetProcessHeap(), 0, wStringSid);
4671 return bret;
4674 /******************************************************************************
4675 * ConvertSidToStringSidW [ADVAPI32.@]
4677 * format of SID string is:
4678 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4679 * where
4680 * <rev> is the revision of the SID encoded as decimal
4681 * <auth> is the identifier authority encoded as hex
4682 * <subauthN> is the subauthority id encoded as decimal
4684 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4686 DWORD len = 0;
4687 LPWSTR wstr, wptr;
4689 TRACE("%p %p\n", pSid, pstr );
4691 len = 0;
4692 if (!DumpSidNumeric(pSid, NULL, &len))
4693 return FALSE;
4694 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4695 DumpSidNumeric(pSid, &wptr, NULL);
4696 *wptr = 0;
4698 *pstr = wstr;
4699 return TRUE;
4702 /******************************************************************************
4703 * ConvertSidToStringSidA [ADVAPI32.@]
4705 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4707 LPWSTR wstr = NULL;
4708 LPSTR str;
4709 UINT len;
4711 TRACE("%p %p\n", pSid, pstr );
4713 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4714 return FALSE;
4716 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4717 str = LocalAlloc( 0, len );
4718 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4719 LocalFree( wstr );
4721 *pstr = str;
4723 return TRUE;
4726 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4727 PSECURITY_DESCRIPTOR pdesc,
4728 PSECURITY_DESCRIPTOR cdesc,
4729 PSECURITY_DESCRIPTOR* ndesc,
4730 GUID* objtype,
4731 BOOL isdir,
4732 PGENERIC_MAPPING genmap )
4734 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4736 return FALSE;
4739 BOOL WINAPI CreatePrivateObjectSecurity(
4740 PSECURITY_DESCRIPTOR ParentDescriptor,
4741 PSECURITY_DESCRIPTOR CreatorDescriptor,
4742 PSECURITY_DESCRIPTOR* NewDescriptor,
4743 BOOL IsDirectoryObject,
4744 HANDLE Token,
4745 PGENERIC_MAPPING GenericMapping )
4747 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4748 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4750 return FALSE;
4753 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4755 FIXME("%p - stub\n", ObjectDescriptor);
4757 return TRUE;
4760 BOOL WINAPI CreateProcessAsUserA(
4761 HANDLE hToken,
4762 LPCSTR lpApplicationName,
4763 LPSTR lpCommandLine,
4764 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4765 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4766 BOOL bInheritHandles,
4767 DWORD dwCreationFlags,
4768 LPVOID lpEnvironment,
4769 LPCSTR lpCurrentDirectory,
4770 LPSTARTUPINFOA lpStartupInfo,
4771 LPPROCESS_INFORMATION lpProcessInformation )
4773 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4774 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4775 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4777 return FALSE;
4780 BOOL WINAPI CreateProcessAsUserW(
4781 HANDLE hToken,
4782 LPCWSTR lpApplicationName,
4783 LPWSTR lpCommandLine,
4784 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4785 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4786 BOOL bInheritHandles,
4787 DWORD dwCreationFlags,
4788 LPVOID lpEnvironment,
4789 LPCWSTR lpCurrentDirectory,
4790 LPSTARTUPINFOW lpStartupInfo,
4791 LPPROCESS_INFORMATION lpProcessInformation )
4793 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4794 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4795 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4796 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4798 /* We should create the process with a suspended main thread */
4799 if (!CreateProcessW (lpApplicationName,
4800 lpCommandLine,
4801 lpProcessAttributes,
4802 lpThreadAttributes,
4803 bInheritHandles,
4804 dwCreationFlags, /* CREATE_SUSPENDED */
4805 lpEnvironment,
4806 lpCurrentDirectory,
4807 lpStartupInfo,
4808 lpProcessInformation))
4810 return FALSE;
4813 return TRUE;
4816 /******************************************************************************
4817 * CreateProcessWithLogonW
4819 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4820 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4821 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4823 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4824 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4825 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4826 lpStartupInfo, lpProcessInformation);
4828 return FALSE;
4831 /******************************************************************************
4832 * DuplicateTokenEx [ADVAPI32.@]
4834 BOOL WINAPI DuplicateTokenEx(
4835 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4836 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4837 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4838 TOKEN_TYPE TokenType,
4839 PHANDLE DuplicateTokenHandle )
4841 OBJECT_ATTRIBUTES ObjectAttributes;
4843 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4844 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4846 InitializeObjectAttributes(
4847 &ObjectAttributes,
4848 NULL,
4849 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4850 NULL,
4851 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4853 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4854 dwDesiredAccess,
4855 &ObjectAttributes,
4856 ImpersonationLevel,
4857 TokenType,
4858 DuplicateTokenHandle ) );
4861 BOOL WINAPI DuplicateToken(
4862 HANDLE ExistingTokenHandle,
4863 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4864 PHANDLE DuplicateTokenHandle )
4866 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4867 NULL, ImpersonationLevel, TokenImpersonation,
4868 DuplicateTokenHandle );
4871 /******************************************************************************
4872 * ComputeStringSidSize
4874 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4876 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4878 int ctok = 0;
4879 while (*StringSid)
4881 if (*StringSid == '-')
4882 ctok++;
4883 StringSid++;
4886 if (ctok >= 3)
4887 return GetSidLengthRequired(ctok - 2);
4889 else /* String constant format - Only available in winxp and above */
4891 unsigned int i;
4893 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4894 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4895 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4898 return GetSidLengthRequired(0);
4901 /******************************************************************************
4902 * ParseStringSidToSid
4904 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4906 BOOL bret = FALSE;
4907 SID* pisid=pSid;
4909 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4910 if (!StringSid)
4912 SetLastError(ERROR_INVALID_PARAMETER);
4913 TRACE("StringSid is NULL, returning FALSE\n");
4914 return FALSE;
4917 *cBytes = ComputeStringSidSize(StringSid);
4918 if (!pisid) /* Simply compute the size */
4920 TRACE("only size requested, returning TRUE\n");
4921 return TRUE;
4924 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4926 DWORD i = 0, identAuth;
4927 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4929 StringSid += 2; /* Advance to Revision */
4930 pisid->Revision = atoiW(StringSid);
4932 if (pisid->Revision != SDDL_REVISION)
4934 TRACE("Revision %d is unknown\n", pisid->Revision);
4935 goto lend; /* ERROR_INVALID_SID */
4937 if (csubauth == 0)
4939 TRACE("SubAuthorityCount is 0\n");
4940 goto lend; /* ERROR_INVALID_SID */
4943 pisid->SubAuthorityCount = csubauth;
4945 /* Advance to identifier authority */
4946 while (*StringSid && *StringSid != '-')
4947 StringSid++;
4948 if (*StringSid == '-')
4949 StringSid++;
4951 /* MS' implementation can't handle values greater than 2^32 - 1, so
4952 * we don't either; assume most significant bytes are always 0
4954 pisid->IdentifierAuthority.Value[0] = 0;
4955 pisid->IdentifierAuthority.Value[1] = 0;
4956 identAuth = atoiW(StringSid);
4957 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4958 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4959 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4960 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4962 /* Advance to first sub authority */
4963 while (*StringSid && *StringSid != '-')
4964 StringSid++;
4965 if (*StringSid == '-')
4966 StringSid++;
4968 while (*StringSid)
4970 pisid->SubAuthority[i++] = atoiW(StringSid);
4972 while (*StringSid && *StringSid != '-')
4973 StringSid++;
4974 if (*StringSid == '-')
4975 StringSid++;
4978 if (i != pisid->SubAuthorityCount)
4979 goto lend; /* ERROR_INVALID_SID */
4981 bret = TRUE;
4983 else /* String constant format - Only available in winxp and above */
4985 unsigned int i;
4986 pisid->Revision = SDDL_REVISION;
4988 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4989 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4991 DWORD j;
4992 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4993 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4994 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4995 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4996 bret = TRUE;
4999 if (!bret)
5000 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5003 lend:
5004 if (!bret)
5005 SetLastError(ERROR_INVALID_SID);
5007 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5008 return bret;
5011 /******************************************************************************
5012 * GetNamedSecurityInfoA [ADVAPI32.@]
5014 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5015 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5016 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5017 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5019 DWORD len;
5020 LPWSTR wstr = NULL;
5021 DWORD r;
5023 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5024 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5026 if( pObjectName )
5028 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5029 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5030 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5033 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5034 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5036 HeapFree( GetProcessHeap(), 0, wstr );
5038 return r;
5041 /******************************************************************************
5042 * GetNamedSecurityInfoW [ADVAPI32.@]
5044 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5045 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5046 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5048 DWORD needed, offset;
5049 SECURITY_DESCRIPTOR_RELATIVE *relative;
5050 BYTE *buffer;
5052 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5053 group, dacl, sacl, descriptor );
5055 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5057 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5058 if (info & OWNER_SECURITY_INFORMATION)
5059 needed += sizeof(sidWorld);
5060 if (info & GROUP_SECURITY_INFORMATION)
5061 needed += sizeof(sidWorld);
5062 if (info & DACL_SECURITY_INFORMATION)
5063 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5064 if (info & SACL_SECURITY_INFORMATION)
5065 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5067 /* must be freed by caller */
5068 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5069 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5071 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5073 HeapFree( GetProcessHeap(), 0, *descriptor );
5074 return ERROR_INVALID_SECURITY_DESCR;
5077 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
5078 relative->Control |= SE_SELF_RELATIVE;
5079 buffer = (BYTE *)relative;
5080 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5082 if (info & OWNER_SECURITY_INFORMATION)
5084 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5085 relative->Owner = offset;
5086 if (owner)
5087 *owner = buffer + offset;
5088 offset += sizeof(sidWorld);
5090 if (info & GROUP_SECURITY_INFORMATION)
5092 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5093 relative->Group = offset;
5094 if (group)
5095 *group = buffer + offset;
5096 offset += sizeof(sidWorld);
5098 if (info & DACL_SECURITY_INFORMATION)
5100 relative->Control |= SE_DACL_PRESENT;
5101 GetWorldAccessACL( (PACL)(buffer + offset) );
5102 relative->Dacl = offset;
5103 if (dacl)
5104 *dacl = (PACL)(buffer + offset);
5105 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5107 if (info & SACL_SECURITY_INFORMATION)
5109 relative->Control |= SE_SACL_PRESENT;
5110 GetWorldAccessACL( (PACL)(buffer + offset) );
5111 relative->Sacl = offset;
5112 if (sacl)
5113 *sacl = (PACL)(buffer + offset);
5115 return ERROR_SUCCESS;
5118 /******************************************************************************
5119 * DecryptFileW [ADVAPI32.@]
5121 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5123 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5124 return TRUE;
5127 /******************************************************************************
5128 * DecryptFileA [ADVAPI32.@]
5130 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5132 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5133 return TRUE;
5136 /******************************************************************************
5137 * EncryptFileW [ADVAPI32.@]
5139 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5141 FIXME("%s\n", debugstr_w(lpFileName));
5142 return TRUE;
5145 /******************************************************************************
5146 * EncryptFileA [ADVAPI32.@]
5148 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5150 FIXME("%s\n", debugstr_a(lpFileName));
5151 return TRUE;
5154 /******************************************************************************
5155 * FileEncryptionStatusW [ADVAPI32.@]
5157 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5159 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5160 if (!lpStatus)
5161 return FALSE;
5162 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5163 return TRUE;
5166 /******************************************************************************
5167 * FileEncryptionStatusA [ADVAPI32.@]
5169 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5171 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5172 if (!lpStatus)
5173 return FALSE;
5174 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5175 return TRUE;
5178 /******************************************************************************
5179 * SetSecurityInfo [ADVAPI32.@]
5181 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5182 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5183 PSID psidGroup, PACL pDacl, PACL pSacl) {
5184 FIXME("stub\n");
5185 return ERROR_SUCCESS;
5188 /******************************************************************************
5189 * SaferCreateLevel [ADVAPI32.@]
5191 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5192 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5194 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5195 return FALSE;