advapi32: LookupAccountNameW() - use CreateWellKnownSid() properly.
[wine/multimedia.git] / dlls / advapi32 / security.c
blobfcb048bdb7a3cab92f933a7ab20af30ce16d6d78
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 "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38 #include "objbase.h"
39 #include "iads.h"
40 #include "advapi32_misc.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
47 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
48 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
49 PACL pAcl, LPDWORD cBytes);
50 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
51 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
52 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
53 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
54 LPCWSTR StringSecurityDescriptor,
55 SECURITY_DESCRIPTOR* SecurityDescriptor,
56 LPDWORD cBytes);
57 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
59 typedef struct _ACEFLAG
61 LPCWSTR wstr;
62 DWORD value;
63 } ACEFLAG, *LPACEFLAG;
65 typedef struct _MAX_SID
67 /* same fields as struct _SID */
68 BYTE Revision;
69 BYTE SubAuthorityCount;
70 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } MAX_SID;
74 typedef struct WELLKNOWNSID
76 WCHAR wstr[2];
77 WELL_KNOWN_SID_TYPE Type;
78 MAX_SID Sid;
79 } WELLKNOWNSID;
81 static const WELLKNOWNSID WellKnownSids[] =
83 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
84 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
85 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
86 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
87 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
88 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
89 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
90 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
91 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
92 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
93 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
94 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
95 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
96 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
97 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
98 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
99 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
100 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
101 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
102 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
103 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
104 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
105 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
106 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
107 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
108 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
109 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
110 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
111 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
112 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
113 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
114 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
115 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
116 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
117 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
118 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
119 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
121 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
122 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
123 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
124 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
125 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
126 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
127 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
128 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
129 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
130 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
134 typedef struct WELLKNOWNRID
136 WELL_KNOWN_SID_TYPE Type;
137 DWORD Rid;
138 } WELLKNOWNRID;
140 static const WELLKNOWNRID WellKnownRids[] = {
141 { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
142 { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
143 { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
144 { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
145 { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
146 { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
147 { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
148 { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
149 { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
150 { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
151 { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
152 { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
153 { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
157 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
159 typedef struct _AccountSid {
160 WELL_KNOWN_SID_TYPE type;
161 LPCWSTR account;
162 LPCWSTR domain;
163 SID_NAME_USE name_use;
164 } AccountSid;
166 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
167 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
168 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
169 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
170 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
171 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
172 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
173 static const WCHAR Blank[] = { 0 };
174 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
175 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
176 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
177 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 };
178 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
179 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 };
180 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
181 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 };
182 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
183 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
184 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
185 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
186 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
187 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
188 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
189 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 };
190 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
191 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 };
192 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
193 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
194 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
195 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
196 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
197 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
198 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 };
199 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
201 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
202 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
203 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
204 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
205 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 };
206 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 };
207 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
208 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 };
209 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
210 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
211 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
212 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 };
213 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 };
214 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
215 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
216 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 };
217 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
218 static const WCHAR SELF[] = { 'S','E','L','F',0 };
219 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
221 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
222 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 };
223 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
224 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
226 static const AccountSid ACCOUNT_SIDS[] = {
227 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
228 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
229 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
230 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
231 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
232 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
233 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
234 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
235 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
236 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
237 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
238 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
239 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
240 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
252 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
253 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
254 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
255 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
256 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
257 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
258 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
259 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
260 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
261 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
262 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
264 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
265 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
266 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
267 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
268 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
269 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
270 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
273 * ACE access rights
275 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
276 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
277 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
278 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
280 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
281 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
282 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
283 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
284 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
285 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
286 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
287 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
288 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
290 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
291 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
292 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
293 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
295 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
296 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
297 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
298 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
300 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
301 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
302 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
303 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
306 * ACL flags
308 static const WCHAR SDDL_PROTECTED[] = {'P',0};
309 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
310 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
313 * ACE types
315 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
316 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
317 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
318 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
319 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
320 static const WCHAR SDDL_ALARM[] = {'A','L',0};
321 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
322 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
325 * ACE flags
327 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
328 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
329 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
330 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
331 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
332 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
333 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
335 const char * debugstr_sid(PSID sid)
337 int auth = 0;
338 SID * psid = (SID *)sid;
340 if (psid == NULL)
341 return "(null)";
343 auth = psid->IdentifierAuthority.Value[5] +
344 (psid->IdentifierAuthority.Value[4] << 8) +
345 (psid->IdentifierAuthority.Value[3] << 16) +
346 (psid->IdentifierAuthority.Value[2] << 24);
348 switch (psid->SubAuthorityCount) {
349 case 0:
350 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
351 case 1:
352 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
353 psid->SubAuthority[0]);
354 case 2:
355 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
356 psid->SubAuthority[0], psid->SubAuthority[1]);
357 case 3:
358 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
359 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
360 case 4:
361 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
362 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
363 psid->SubAuthority[3]);
364 case 5:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
367 psid->SubAuthority[3], psid->SubAuthority[4]);
368 case 6:
369 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
370 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
371 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
372 case 7:
373 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
374 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
375 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
376 psid->SubAuthority[6]);
377 case 8:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
381 psid->SubAuthority[6], psid->SubAuthority[7]);
383 return "(too-big)";
386 /* set last error code from NT status and get the proper boolean return value */
387 /* used for functions that are a simple wrapper around the corresponding ntdll API */
388 static inline BOOL set_ntstatus( NTSTATUS status )
390 if (status) SetLastError( RtlNtStatusToDosError( status ));
391 return !status;
394 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
396 static void GetWorldAccessACL(PACL pACL)
398 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
400 pACL->AclRevision = ACL_REVISION;
401 pACL->Sbz1 = 0;
402 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
403 pACL->AceCount = 1;
404 pACL->Sbz2 = 0;
406 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
407 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
408 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
409 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
410 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
413 /************************************************************
414 * ADVAPI_IsLocalComputer
416 * Checks whether the server name indicates local machine.
418 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
420 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
421 BOOL Result;
422 LPWSTR buf;
424 if (!ServerName || !ServerName[0])
425 return TRUE;
427 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
428 Result = GetComputerNameW(buf, &dwSize);
429 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
430 ServerName += 2;
431 Result = Result && !lstrcmpW(ServerName, buf);
432 HeapFree(GetProcessHeap(), 0, buf);
434 return Result;
437 /************************************************************
438 * ADVAPI_GetComputerSid
440 * Reads the computer SID from the registry.
442 BOOL ADVAPI_GetComputerSid(PSID sid)
444 HKEY key;
445 LONG ret;
446 BOOL retval = FALSE;
447 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 };
448 static const WCHAR V[] = { 'V',0 };
450 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
451 KEY_READ, &key)) == ERROR_SUCCESS)
453 DWORD size = 0;
454 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
455 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
457 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
458 if (data)
460 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
461 data, &size)) == ERROR_SUCCESS)
463 /* the SID is in the last 24 bytes of the binary data */
464 CopyMemory(sid, &data[size-24], 24);
465 retval = TRUE;
467 HeapFree(GetProcessHeap(), 0, data);
470 RegCloseKey(key);
473 if(retval == TRUE) return retval;
475 /* create a new random SID */
476 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
477 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
479 PSID new_sid;
480 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
481 DWORD id[3];
483 if (RtlGenRandom(id, sizeof(id)))
485 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
487 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
488 retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
490 FreeSid(new_sid);
493 RegCloseKey(key);
496 return retval;
499 /* ##############################
500 ###### TOKEN FUNCTIONS ######
501 ##############################
504 /******************************************************************************
505 * OpenProcessToken [ADVAPI32.@]
506 * Opens the access token associated with a process handle.
508 * PARAMS
509 * ProcessHandle [I] Handle to process
510 * DesiredAccess [I] Desired access to process
511 * TokenHandle [O] Pointer to handle of open access token
513 * RETURNS
514 * Success: TRUE. TokenHandle contains the access token.
515 * Failure: FALSE.
517 * NOTES
518 * See NtOpenProcessToken.
520 BOOL WINAPI
521 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
522 HANDLE *TokenHandle )
524 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
527 /******************************************************************************
528 * OpenThreadToken [ADVAPI32.@]
530 * Opens the access token associated with a thread handle.
532 * PARAMS
533 * ThreadHandle [I] Handle to process
534 * DesiredAccess [I] Desired access to the thread
535 * OpenAsSelf [I] ???
536 * TokenHandle [O] Destination for the token handle
538 * RETURNS
539 * Success: TRUE. TokenHandle contains the access token.
540 * Failure: FALSE.
542 * NOTES
543 * See NtOpenThreadToken.
545 BOOL WINAPI
546 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
547 BOOL OpenAsSelf, HANDLE *TokenHandle)
549 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
552 BOOL WINAPI
553 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
554 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
556 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
557 PreviousState, ReturnLength));
560 /******************************************************************************
561 * AdjustTokenPrivileges [ADVAPI32.@]
563 * Adjust the privileges of an open token handle.
565 * PARAMS
566 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
567 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
568 * NewState [I] Desired new privileges of the token
569 * BufferLength [I] Length of NewState
570 * PreviousState [O] Destination for the previous state
571 * ReturnLength [I/O] Size of PreviousState
574 * RETURNS
575 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
576 * Failure: FALSE.
578 * NOTES
579 * See NtAdjustPrivilegesToken.
581 BOOL WINAPI
582 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
583 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
584 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
586 NTSTATUS status;
588 TRACE("\n");
590 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
591 NewState, BufferLength, PreviousState,
592 ReturnLength);
593 SetLastError( RtlNtStatusToDosError( status ));
594 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
595 return TRUE;
596 else
597 return FALSE;
600 /******************************************************************************
601 * CheckTokenMembership [ADVAPI32.@]
603 * Determine if an access token is a member of a SID.
605 * PARAMS
606 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
607 * SidToCheck [I] SID that possibly contains the token
608 * IsMember [O] Destination for result.
610 * RETURNS
611 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
612 * Failure: FALSE.
614 BOOL WINAPI
615 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
616 PBOOL IsMember )
618 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
620 *IsMember = TRUE;
621 return(TRUE);
624 /******************************************************************************
625 * GetTokenInformation [ADVAPI32.@]
627 * Get a type of information about an access token.
629 * PARAMS
630 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
631 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
632 * tokeninfo [O] Destination for token information
633 * tokeninfolength [I] Length of tokeninfo
634 * retlen [O] Destination for returned token information length
636 * RETURNS
637 * Success: TRUE. tokeninfo contains retlen bytes of token information
638 * Failure: FALSE.
640 * NOTES
641 * See NtQueryInformationToken.
643 BOOL WINAPI
644 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
645 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
647 TRACE("(%p, %s, %p, %d, %p):\n",
648 token,
649 (tokeninfoclass == TokenUser) ? "TokenUser" :
650 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
651 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
652 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
653 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
654 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
655 (tokeninfoclass == TokenSource) ? "TokenSource" :
656 (tokeninfoclass == TokenType) ? "TokenType" :
657 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
658 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
659 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
660 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
661 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
662 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
663 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
664 "Unknown",
665 tokeninfo, tokeninfolength, retlen);
666 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
667 tokeninfolength, retlen));
670 /******************************************************************************
671 * SetTokenInformation [ADVAPI32.@]
673 * Set information for an access token.
675 * PARAMS
676 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
677 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
678 * tokeninfo [I] Token information to set
679 * tokeninfolength [I] Length of tokeninfo
681 * RETURNS
682 * Success: TRUE. The information for the token is set to tokeninfo.
683 * Failure: FALSE.
685 BOOL WINAPI
686 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
687 LPVOID tokeninfo, DWORD tokeninfolength )
689 TRACE("(%p, %s, %p, %d): stub\n",
690 token,
691 (tokeninfoclass == TokenUser) ? "TokenUser" :
692 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
693 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
694 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
695 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
696 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
697 (tokeninfoclass == TokenSource) ? "TokenSource" :
698 (tokeninfoclass == TokenType) ? "TokenType" :
699 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
700 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
701 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
702 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
703 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
704 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
705 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
706 "Unknown",
707 tokeninfo, tokeninfolength);
709 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
712 /*************************************************************************
713 * SetThreadToken [ADVAPI32.@]
715 * Assigns an 'impersonation token' to a thread so it can assume the
716 * security privileges of another thread or process. Can also remove
717 * a previously assigned token.
719 * PARAMS
720 * thread [O] Handle to thread to set the token for
721 * token [I] Token to set
723 * RETURNS
724 * Success: TRUE. The threads access token is set to token
725 * Failure: FALSE.
727 * NOTES
728 * Only supported on NT or higher. On Win9X this function does nothing.
729 * See SetTokenInformation.
731 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
733 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
734 ThreadImpersonationToken, &token, sizeof token ));
737 /*************************************************************************
738 * CreateRestrictedToken [ADVAPI32.@]
740 * Create a new more restricted token from an existing token.
742 * PARAMS
743 * baseToken [I] Token to base the new restricted token on
744 * flags [I] Options
745 * nDisableSids [I] Length of disableSids array
746 * disableSids [I] Array of SIDs to disable in the new token
747 * nDeletePrivs [I] Length of deletePrivs array
748 * deletePrivs [I] Array of privileges to delete in the new token
749 * nRestrictSids [I] Length of restrictSids array
750 * restrictSids [I] Array of SIDs to restrict in the new token
751 * newToken [O] Address where the new token is stored
753 * RETURNS
754 * Success: TRUE
755 * Failure: FALSE
757 BOOL WINAPI CreateRestrictedToken(
758 HANDLE baseToken,
759 DWORD flags,
760 DWORD nDisableSids,
761 PSID_AND_ATTRIBUTES disableSids,
762 DWORD nDeletePrivs,
763 PLUID_AND_ATTRIBUTES deletePrivs,
764 DWORD nRestrictSids,
765 PSID_AND_ATTRIBUTES restrictSids,
766 PHANDLE newToken)
768 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
769 baseToken, flags, nDisableSids, disableSids,
770 nDeletePrivs, deletePrivs,
771 nRestrictSids, restrictSids,
772 newToken);
773 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
774 return FALSE;
777 /* ##############################
778 ###### SID FUNCTIONS ######
779 ##############################
782 /******************************************************************************
783 * AllocateAndInitializeSid [ADVAPI32.@]
785 * PARAMS
786 * pIdentifierAuthority []
787 * nSubAuthorityCount []
788 * nSubAuthority0 []
789 * nSubAuthority1 []
790 * nSubAuthority2 []
791 * nSubAuthority3 []
792 * nSubAuthority4 []
793 * nSubAuthority5 []
794 * nSubAuthority6 []
795 * nSubAuthority7 []
796 * pSid []
798 BOOL WINAPI
799 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
800 BYTE nSubAuthorityCount,
801 DWORD nSubAuthority0, DWORD nSubAuthority1,
802 DWORD nSubAuthority2, DWORD nSubAuthority3,
803 DWORD nSubAuthority4, DWORD nSubAuthority5,
804 DWORD nSubAuthority6, DWORD nSubAuthority7,
805 PSID *pSid )
807 return set_ntstatus( RtlAllocateAndInitializeSid(
808 pIdentifierAuthority, nSubAuthorityCount,
809 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
810 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
811 pSid ));
814 /******************************************************************************
815 * FreeSid [ADVAPI32.@]
817 * PARAMS
818 * pSid []
820 PVOID WINAPI
821 FreeSid( PSID pSid )
823 RtlFreeSid(pSid);
824 return NULL; /* is documented like this */
827 /******************************************************************************
828 * CopySid [ADVAPI32.@]
830 * PARAMS
831 * nDestinationSidLength []
832 * pDestinationSid []
833 * pSourceSid []
835 BOOL WINAPI
836 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
838 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
841 /******************************************************************************
842 * CreateWellKnownSid [ADVAPI32.@]
844 BOOL WINAPI
845 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
846 PSID DomainSid,
847 PSID pSid,
848 DWORD* cbSid)
850 unsigned int i;
851 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
853 if (cbSid == NULL || pSid == NULL || (DomainSid && !IsValidSid(DomainSid))) {
854 SetLastError(ERROR_INVALID_PARAMETER);
855 return FALSE;
858 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
859 if (WellKnownSids[i].Type == WellKnownSidType) {
860 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
862 if (*cbSid < length) {
863 SetLastError(ERROR_INSUFFICIENT_BUFFER);
864 return FALSE;
867 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
868 *cbSid = length;
869 return TRUE;
873 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
875 SetLastError(ERROR_INVALID_PARAMETER);
876 return FALSE;
879 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
880 if (WellKnownRids[i].Type == WellKnownSidType) {
881 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
882 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
883 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
885 if (*cbSid < output_sid_length) {
886 SetLastError(ERROR_INSUFFICIENT_BUFFER);
887 return FALSE;
890 CopyMemory(pSid, DomainSid, domain_sid_length);
891 (*GetSidSubAuthorityCount(pSid))++;
892 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
893 *cbSid = output_sid_length;
894 return TRUE;
897 SetLastError(ERROR_INVALID_PARAMETER);
898 return FALSE;
901 /******************************************************************************
902 * IsWellKnownSid [ADVAPI32.@]
904 BOOL WINAPI
905 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
907 unsigned int i;
908 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
910 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
911 if (WellKnownSids[i].Type == WellKnownSidType)
912 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
913 return TRUE;
915 return FALSE;
918 BOOL WINAPI
919 IsTokenRestricted( HANDLE TokenHandle )
921 TOKEN_GROUPS *groups;
922 DWORD size;
923 NTSTATUS status;
924 BOOL restricted;
926 TRACE("(%p)\n", TokenHandle);
928 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
929 if (status != STATUS_BUFFER_TOO_SMALL)
930 return FALSE;
932 groups = HeapAlloc(GetProcessHeap(), 0, size);
933 if (!groups)
935 SetLastError(ERROR_OUTOFMEMORY);
936 return FALSE;
939 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
940 if (status != STATUS_SUCCESS)
942 HeapFree(GetProcessHeap(), 0, groups);
943 return set_ntstatus(status);
946 if (groups->GroupCount)
947 restricted = TRUE;
948 else
949 restricted = FALSE;
951 HeapFree(GetProcessHeap(), 0, groups);
953 return restricted;
956 /******************************************************************************
957 * IsValidSid [ADVAPI32.@]
959 * PARAMS
960 * pSid []
962 BOOL WINAPI
963 IsValidSid( PSID pSid )
965 return RtlValidSid( pSid );
968 /******************************************************************************
969 * EqualSid [ADVAPI32.@]
971 * PARAMS
972 * pSid1 []
973 * pSid2 []
975 BOOL WINAPI
976 EqualSid( PSID pSid1, PSID pSid2 )
978 return RtlEqualSid( pSid1, pSid2 );
981 /******************************************************************************
982 * EqualPrefixSid [ADVAPI32.@]
984 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
986 return RtlEqualPrefixSid(pSid1, pSid2);
989 /******************************************************************************
990 * GetSidLengthRequired [ADVAPI32.@]
992 * PARAMS
993 * nSubAuthorityCount []
995 DWORD WINAPI
996 GetSidLengthRequired( BYTE nSubAuthorityCount )
998 return RtlLengthRequiredSid(nSubAuthorityCount);
1001 /******************************************************************************
1002 * InitializeSid [ADVAPI32.@]
1004 * PARAMS
1005 * pIdentifierAuthority []
1007 BOOL WINAPI
1008 InitializeSid (
1009 PSID pSid,
1010 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1011 BYTE nSubAuthorityCount)
1013 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1016 DWORD WINAPI
1017 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1019 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1021 return 1;
1024 DWORD WINAPI
1025 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1027 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1029 return 1;
1032 /******************************************************************************
1033 * GetSidIdentifierAuthority [ADVAPI32.@]
1035 * PARAMS
1036 * pSid []
1038 PSID_IDENTIFIER_AUTHORITY WINAPI
1039 GetSidIdentifierAuthority( PSID pSid )
1041 return RtlIdentifierAuthoritySid(pSid);
1044 /******************************************************************************
1045 * GetSidSubAuthority [ADVAPI32.@]
1047 * PARAMS
1048 * pSid []
1049 * nSubAuthority []
1051 PDWORD WINAPI
1052 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1054 return RtlSubAuthoritySid(pSid, nSubAuthority);
1057 /******************************************************************************
1058 * GetSidSubAuthorityCount [ADVAPI32.@]
1060 * PARAMS
1061 * pSid []
1063 PUCHAR WINAPI
1064 GetSidSubAuthorityCount (PSID pSid)
1066 return RtlSubAuthorityCountSid(pSid);
1069 /******************************************************************************
1070 * GetLengthSid [ADVAPI32.@]
1072 * PARAMS
1073 * pSid []
1075 DWORD WINAPI
1076 GetLengthSid (PSID pSid)
1078 return RtlLengthSid(pSid);
1081 /* ##############################################
1082 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1083 ##############################################
1086 /******************************************************************************
1087 * BuildSecurityDescriptorA [ADVAPI32.@]
1089 * Builds a SD from
1091 * PARAMS
1092 * pOwner [I]
1093 * pGroup [I]
1094 * cCountOfAccessEntries [I]
1095 * pListOfAccessEntries [I]
1096 * cCountOfAuditEntries [I]
1097 * pListofAuditEntries [I]
1098 * pOldSD [I]
1099 * lpdwBufferLength [I/O]
1100 * pNewSD [O]
1102 * RETURNS
1103 * Success: ERROR_SUCCESS
1104 * Failure: nonzero error code from Winerror.h
1106 DWORD WINAPI BuildSecurityDescriptorA(
1107 IN PTRUSTEEA pOwner,
1108 IN PTRUSTEEA pGroup,
1109 IN ULONG cCountOfAccessEntries,
1110 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1111 IN ULONG cCountOfAuditEntries,
1112 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1113 IN PSECURITY_DESCRIPTOR pOldSD,
1114 IN OUT PULONG lpdwBufferLength,
1115 OUT PSECURITY_DESCRIPTOR* pNewSD)
1117 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1118 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1119 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1121 return ERROR_CALL_NOT_IMPLEMENTED;
1124 /******************************************************************************
1125 * BuildSecurityDescriptorW [ADVAPI32.@]
1127 * See BuildSecurityDescriptorA.
1129 DWORD WINAPI BuildSecurityDescriptorW(
1130 IN PTRUSTEEW pOwner,
1131 IN PTRUSTEEW pGroup,
1132 IN ULONG cCountOfAccessEntries,
1133 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1134 IN ULONG cCountOfAuditEntries,
1135 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1136 IN PSECURITY_DESCRIPTOR pOldSD,
1137 IN OUT PULONG lpdwBufferLength,
1138 OUT PSECURITY_DESCRIPTOR* pNewSD)
1140 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1141 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1142 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1144 return ERROR_CALL_NOT_IMPLEMENTED;
1147 /******************************************************************************
1148 * InitializeSecurityDescriptor [ADVAPI32.@]
1150 * PARAMS
1151 * pDescr []
1152 * revision []
1154 BOOL WINAPI
1155 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1157 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1161 /******************************************************************************
1162 * MakeAbsoluteSD [ADVAPI32.@]
1164 BOOL WINAPI MakeAbsoluteSD (
1165 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1166 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1167 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1168 OUT PACL pDacl,
1169 OUT LPDWORD lpdwDaclSize,
1170 OUT PACL pSacl,
1171 OUT LPDWORD lpdwSaclSize,
1172 OUT PSID pOwner,
1173 OUT LPDWORD lpdwOwnerSize,
1174 OUT PSID pPrimaryGroup,
1175 OUT LPDWORD lpdwPrimaryGroupSize)
1177 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1178 pAbsoluteSecurityDescriptor,
1179 lpdwAbsoluteSecurityDescriptorSize,
1180 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1181 pOwner, lpdwOwnerSize,
1182 pPrimaryGroup, lpdwPrimaryGroupSize));
1185 /******************************************************************************
1186 * GetKernelObjectSecurity [ADVAPI32.@]
1188 BOOL WINAPI GetKernelObjectSecurity(
1189 HANDLE Handle,
1190 SECURITY_INFORMATION RequestedInformation,
1191 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1192 DWORD nLength,
1193 LPDWORD lpnLengthNeeded )
1195 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1196 pSecurityDescriptor, nLength, lpnLengthNeeded);
1198 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1199 nLength, lpnLengthNeeded ));
1202 /******************************************************************************
1203 * GetPrivateObjectSecurity [ADVAPI32.@]
1205 BOOL WINAPI GetPrivateObjectSecurity(
1206 PSECURITY_DESCRIPTOR ObjectDescriptor,
1207 SECURITY_INFORMATION SecurityInformation,
1208 PSECURITY_DESCRIPTOR ResultantDescriptor,
1209 DWORD DescriptorLength,
1210 PDWORD ReturnLength )
1212 SECURITY_DESCRIPTOR desc;
1213 BOOL defaulted, present;
1214 PACL pacl;
1215 PSID psid;
1217 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1218 ResultantDescriptor, DescriptorLength, ReturnLength);
1220 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1221 return FALSE;
1223 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1225 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1226 return FALSE;
1227 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1230 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1232 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1233 return FALSE;
1234 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1237 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1239 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1240 return FALSE;
1241 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1244 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1246 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1247 return FALSE;
1248 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1251 *ReturnLength = DescriptorLength;
1252 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1255 /******************************************************************************
1256 * GetSecurityDescriptorLength [ADVAPI32.@]
1258 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1260 return RtlLengthSecurityDescriptor(pDescr);
1263 /******************************************************************************
1264 * GetSecurityDescriptorOwner [ADVAPI32.@]
1266 * PARAMS
1267 * pOwner []
1268 * lpbOwnerDefaulted []
1270 BOOL WINAPI
1271 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1272 LPBOOL lpbOwnerDefaulted )
1274 BOOLEAN defaulted;
1275 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1276 *lpbOwnerDefaulted = defaulted;
1277 return ret;
1280 /******************************************************************************
1281 * SetSecurityDescriptorOwner [ADVAPI32.@]
1283 * PARAMS
1285 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1286 PSID pOwner, BOOL bOwnerDefaulted)
1288 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1290 /******************************************************************************
1291 * GetSecurityDescriptorGroup [ADVAPI32.@]
1293 BOOL WINAPI GetSecurityDescriptorGroup(
1294 PSECURITY_DESCRIPTOR SecurityDescriptor,
1295 PSID *Group,
1296 LPBOOL GroupDefaulted)
1298 BOOLEAN defaulted;
1299 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1300 *GroupDefaulted = defaulted;
1301 return ret;
1303 /******************************************************************************
1304 * SetSecurityDescriptorGroup [ADVAPI32.@]
1306 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1307 PSID Group, BOOL GroupDefaulted)
1309 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1312 /******************************************************************************
1313 * IsValidSecurityDescriptor [ADVAPI32.@]
1315 * PARAMS
1316 * lpsecdesc []
1318 BOOL WINAPI
1319 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1321 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1324 /******************************************************************************
1325 * GetSecurityDescriptorDacl [ADVAPI32.@]
1327 BOOL WINAPI GetSecurityDescriptorDacl(
1328 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1329 OUT LPBOOL lpbDaclPresent,
1330 OUT PACL *pDacl,
1331 OUT LPBOOL lpbDaclDefaulted)
1333 BOOLEAN present, defaulted;
1334 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1335 *lpbDaclPresent = present;
1336 *lpbDaclDefaulted = defaulted;
1337 return ret;
1340 /******************************************************************************
1341 * SetSecurityDescriptorDacl [ADVAPI32.@]
1343 BOOL WINAPI
1344 SetSecurityDescriptorDacl (
1345 PSECURITY_DESCRIPTOR lpsd,
1346 BOOL daclpresent,
1347 PACL dacl,
1348 BOOL dacldefaulted )
1350 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1352 /******************************************************************************
1353 * GetSecurityDescriptorSacl [ADVAPI32.@]
1355 BOOL WINAPI GetSecurityDescriptorSacl(
1356 IN PSECURITY_DESCRIPTOR lpsd,
1357 OUT LPBOOL lpbSaclPresent,
1358 OUT PACL *pSacl,
1359 OUT LPBOOL lpbSaclDefaulted)
1361 BOOLEAN present, defaulted;
1362 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1363 *lpbSaclPresent = present;
1364 *lpbSaclDefaulted = defaulted;
1365 return ret;
1368 /**************************************************************************
1369 * SetSecurityDescriptorSacl [ADVAPI32.@]
1371 BOOL WINAPI SetSecurityDescriptorSacl (
1372 PSECURITY_DESCRIPTOR lpsd,
1373 BOOL saclpresent,
1374 PACL lpsacl,
1375 BOOL sacldefaulted)
1377 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1379 /******************************************************************************
1380 * MakeSelfRelativeSD [ADVAPI32.@]
1382 * PARAMS
1383 * lpabssecdesc []
1384 * lpselfsecdesc []
1385 * lpbuflen []
1387 BOOL WINAPI
1388 MakeSelfRelativeSD(
1389 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1390 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1391 IN OUT LPDWORD lpdwBufferLength)
1393 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1394 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1397 /******************************************************************************
1398 * GetSecurityDescriptorControl [ADVAPI32.@]
1401 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1402 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1404 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1407 /******************************************************************************
1408 * SetSecurityDescriptorControl [ADVAPI32.@]
1410 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1411 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1412 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1414 return set_ntstatus( RtlSetControlSecurityDescriptor(
1415 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1418 /* ##############################
1419 ###### ACL FUNCTIONS ######
1420 ##############################
1423 /*************************************************************************
1424 * InitializeAcl [ADVAPI32.@]
1426 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1428 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1431 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1433 IO_STATUS_BLOCK io_block;
1435 TRACE("(%p)\n", hNamedPipe);
1437 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1438 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1441 /******************************************************************************
1442 * AddAccessAllowedAce [ADVAPI32.@]
1444 BOOL WINAPI AddAccessAllowedAce(
1445 IN OUT PACL pAcl,
1446 IN DWORD dwAceRevision,
1447 IN DWORD AccessMask,
1448 IN PSID pSid)
1450 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1453 /******************************************************************************
1454 * AddAccessAllowedAceEx [ADVAPI32.@]
1456 BOOL WINAPI AddAccessAllowedAceEx(
1457 IN OUT PACL pAcl,
1458 IN DWORD dwAceRevision,
1459 IN DWORD AceFlags,
1460 IN DWORD AccessMask,
1461 IN PSID pSid)
1463 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1466 /******************************************************************************
1467 * AddAccessDeniedAce [ADVAPI32.@]
1469 BOOL WINAPI AddAccessDeniedAce(
1470 IN OUT PACL pAcl,
1471 IN DWORD dwAceRevision,
1472 IN DWORD AccessMask,
1473 IN PSID pSid)
1475 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1478 /******************************************************************************
1479 * AddAccessDeniedAceEx [ADVAPI32.@]
1481 BOOL WINAPI AddAccessDeniedAceEx(
1482 IN OUT PACL pAcl,
1483 IN DWORD dwAceRevision,
1484 IN DWORD AceFlags,
1485 IN DWORD AccessMask,
1486 IN PSID pSid)
1488 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1491 /******************************************************************************
1492 * AddAce [ADVAPI32.@]
1494 BOOL WINAPI AddAce(
1495 IN OUT PACL pAcl,
1496 IN DWORD dwAceRevision,
1497 IN DWORD dwStartingAceIndex,
1498 LPVOID pAceList,
1499 DWORD nAceListLength)
1501 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1504 /******************************************************************************
1505 * DeleteAce [ADVAPI32.@]
1507 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1509 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1512 /******************************************************************************
1513 * FindFirstFreeAce [ADVAPI32.@]
1515 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1517 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1520 /******************************************************************************
1521 * GetAce [ADVAPI32.@]
1523 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1525 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1528 /******************************************************************************
1529 * GetAclInformation [ADVAPI32.@]
1531 BOOL WINAPI GetAclInformation(
1532 PACL pAcl,
1533 LPVOID pAclInformation,
1534 DWORD nAclInformationLength,
1535 ACL_INFORMATION_CLASS dwAclInformationClass)
1537 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1538 nAclInformationLength, dwAclInformationClass));
1541 /******************************************************************************
1542 * IsValidAcl [ADVAPI32.@]
1544 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1546 return RtlValidAcl(pAcl);
1549 /* ##############################
1550 ###### MISC FUNCTIONS ######
1551 ##############################
1554 /******************************************************************************
1555 * AllocateLocallyUniqueId [ADVAPI32.@]
1557 * PARAMS
1558 * lpLuid []
1560 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1562 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1565 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1566 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1567 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1568 { '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 };
1569 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1570 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1571 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1572 { '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 };
1573 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1574 { '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 };
1575 static const WCHAR SE_TCB_NAME_W[] =
1576 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1577 static const WCHAR SE_SECURITY_NAME_W[] =
1578 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1579 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1580 { '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 };
1581 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1582 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1583 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1584 { '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 };
1585 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1586 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1587 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1588 { '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 };
1589 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1590 { '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 };
1591 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1592 { '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 };
1593 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1594 { '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 };
1595 static const WCHAR SE_BACKUP_NAME_W[] =
1596 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1597 static const WCHAR SE_RESTORE_NAME_W[] =
1598 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1599 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1600 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1601 static const WCHAR SE_DEBUG_NAME_W[] =
1602 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1603 static const WCHAR SE_AUDIT_NAME_W[] =
1604 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1605 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1606 { '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 };
1607 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1608 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1609 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1610 { '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 };
1611 static const WCHAR SE_UNDOCK_NAME_W[] =
1612 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1613 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1614 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1615 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1616 { '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 };
1617 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1618 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1619 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1620 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1622 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1626 NULL,
1627 NULL,
1628 SE_CREATE_TOKEN_NAME_W,
1629 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1630 SE_LOCK_MEMORY_NAME_W,
1631 SE_INCREASE_QUOTA_NAME_W,
1632 SE_MACHINE_ACCOUNT_NAME_W,
1633 SE_TCB_NAME_W,
1634 SE_SECURITY_NAME_W,
1635 SE_TAKE_OWNERSHIP_NAME_W,
1636 SE_LOAD_DRIVER_NAME_W,
1637 SE_SYSTEM_PROFILE_NAME_W,
1638 SE_SYSTEMTIME_NAME_W,
1639 SE_PROF_SINGLE_PROCESS_NAME_W,
1640 SE_INC_BASE_PRIORITY_NAME_W,
1641 SE_CREATE_PAGEFILE_NAME_W,
1642 SE_CREATE_PERMANENT_NAME_W,
1643 SE_BACKUP_NAME_W,
1644 SE_RESTORE_NAME_W,
1645 SE_SHUTDOWN_NAME_W,
1646 SE_DEBUG_NAME_W,
1647 SE_AUDIT_NAME_W,
1648 SE_SYSTEM_ENVIRONMENT_NAME_W,
1649 SE_CHANGE_NOTIFY_NAME_W,
1650 SE_REMOTE_SHUTDOWN_NAME_W,
1651 SE_UNDOCK_NAME_W,
1652 SE_SYNC_AGENT_NAME_W,
1653 SE_ENABLE_DELEGATION_NAME_W,
1654 SE_MANAGE_VOLUME_NAME_W,
1655 SE_IMPERSONATE_NAME_W,
1656 SE_CREATE_GLOBAL_NAME_W,
1659 /******************************************************************************
1660 * LookupPrivilegeValueW [ADVAPI32.@]
1662 * See LookupPrivilegeValueA.
1664 BOOL WINAPI
1665 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1667 UINT i;
1669 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1671 if (!ADVAPI_IsLocalComputer(lpSystemName))
1673 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1674 return FALSE;
1676 if (!lpName)
1678 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1679 return FALSE;
1681 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1683 if( !WellKnownPrivNames[i] )
1684 continue;
1685 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1686 continue;
1687 lpLuid->LowPart = i;
1688 lpLuid->HighPart = 0;
1689 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1690 lpLuid->HighPart, lpLuid->LowPart );
1691 return TRUE;
1693 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1694 return FALSE;
1697 /******************************************************************************
1698 * LookupPrivilegeValueA [ADVAPI32.@]
1700 * Retrieves LUID used on a system to represent the privilege name.
1702 * PARAMS
1703 * lpSystemName [I] Name of the system
1704 * lpName [I] Name of the privilege
1705 * lpLuid [O] Destination for the resulting LUID
1707 * RETURNS
1708 * Success: TRUE. lpLuid contains the requested LUID.
1709 * Failure: FALSE.
1711 BOOL WINAPI
1712 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1714 UNICODE_STRING lpSystemNameW;
1715 UNICODE_STRING lpNameW;
1716 BOOL ret;
1718 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1719 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1720 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1721 RtlFreeUnicodeString(&lpNameW);
1722 RtlFreeUnicodeString(&lpSystemNameW);
1723 return ret;
1726 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1727 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1729 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1730 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1732 return FALSE;
1735 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1736 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1738 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1739 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1741 return FALSE;
1744 /******************************************************************************
1745 * LookupPrivilegeNameA [ADVAPI32.@]
1747 * See LookupPrivilegeNameW.
1749 BOOL WINAPI
1750 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1751 LPDWORD cchName)
1753 UNICODE_STRING lpSystemNameW;
1754 BOOL ret;
1755 DWORD wLen = 0;
1757 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1759 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1760 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1761 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1763 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1765 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1766 &wLen);
1767 if (ret)
1769 /* Windows crashes if cchName is NULL, so will I */
1770 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1771 *cchName, NULL, NULL);
1773 if (len == 0)
1775 /* WideCharToMultiByte failed */
1776 ret = FALSE;
1778 else if (len > *cchName)
1780 *cchName = len;
1781 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1782 ret = FALSE;
1784 else
1786 /* WideCharToMultiByte succeeded, output length needs to be
1787 * length not including NULL terminator
1789 *cchName = len - 1;
1792 HeapFree(GetProcessHeap(), 0, lpNameW);
1794 RtlFreeUnicodeString(&lpSystemNameW);
1795 return ret;
1798 /******************************************************************************
1799 * LookupPrivilegeNameW [ADVAPI32.@]
1801 * Retrieves the privilege name referred to by the LUID lpLuid.
1803 * PARAMS
1804 * lpSystemName [I] Name of the system
1805 * lpLuid [I] Privilege value
1806 * lpName [O] Name of the privilege
1807 * cchName [I/O] Number of characters in lpName.
1809 * RETURNS
1810 * Success: TRUE. lpName contains the name of the privilege whose value is
1811 * *lpLuid.
1812 * Failure: FALSE.
1814 * REMARKS
1815 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1816 * using this function.
1817 * If the length of lpName is too small, on return *cchName will contain the
1818 * number of WCHARs needed to contain the privilege, including the NULL
1819 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1820 * On success, *cchName will contain the number of characters stored in
1821 * lpName, NOT including the NULL terminator.
1823 BOOL WINAPI
1824 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1825 LPDWORD cchName)
1827 size_t privNameLen;
1829 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1831 if (!ADVAPI_IsLocalComputer(lpSystemName))
1833 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1834 return FALSE;
1836 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1837 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1839 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1840 return FALSE;
1842 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1843 /* Windows crashes if cchName is NULL, so will I */
1844 if (*cchName <= privNameLen)
1846 *cchName = privNameLen + 1;
1847 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1848 return FALSE;
1850 else
1852 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1853 *cchName = privNameLen;
1854 return TRUE;
1858 /******************************************************************************
1859 * GetFileSecurityA [ADVAPI32.@]
1861 * Obtains Specified information about the security of a file or directory.
1863 * PARAMS
1864 * lpFileName [I] Name of the file to get info for
1865 * RequestedInformation [I] SE_ flags from "winnt.h"
1866 * pSecurityDescriptor [O] Destination for security information
1867 * nLength [I] Length of pSecurityDescriptor
1868 * lpnLengthNeeded [O] Destination for length of returned security information
1870 * RETURNS
1871 * Success: TRUE. pSecurityDescriptor contains the requested information.
1872 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1874 * NOTES
1875 * The information returned is constrained by the callers access rights and
1876 * privileges.
1878 BOOL WINAPI
1879 GetFileSecurityA( LPCSTR lpFileName,
1880 SECURITY_INFORMATION RequestedInformation,
1881 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1882 DWORD nLength, LPDWORD lpnLengthNeeded )
1884 DWORD len;
1885 BOOL r;
1886 LPWSTR name = NULL;
1888 if( lpFileName )
1890 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1891 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1892 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1895 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1896 nLength, lpnLengthNeeded );
1897 HeapFree( GetProcessHeap(), 0, name );
1899 return r;
1902 /******************************************************************************
1903 * GetFileSecurityW [ADVAPI32.@]
1905 * See GetFileSecurityA.
1907 BOOL WINAPI
1908 GetFileSecurityW( LPCWSTR lpFileName,
1909 SECURITY_INFORMATION RequestedInformation,
1910 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1911 DWORD nLength, LPDWORD lpnLengthNeeded )
1913 HANDLE hfile;
1914 NTSTATUS status;
1915 DWORD access = 0;
1917 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1918 DACL_SECURITY_INFORMATION))
1919 access |= READ_CONTROL;
1920 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1921 access |= ACCESS_SYSTEM_SECURITY;
1923 hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1924 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1925 if ( hfile == INVALID_HANDLE_VALUE )
1926 return FALSE;
1928 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1929 nLength, lpnLengthNeeded );
1930 CloseHandle( hfile );
1931 return set_ntstatus( status );
1935 /******************************************************************************
1936 * LookupAccountSidA [ADVAPI32.@]
1938 BOOL WINAPI
1939 LookupAccountSidA(
1940 IN LPCSTR system,
1941 IN PSID sid,
1942 OUT LPSTR account,
1943 IN OUT LPDWORD accountSize,
1944 OUT LPSTR domain,
1945 IN OUT LPDWORD domainSize,
1946 OUT PSID_NAME_USE name_use )
1948 DWORD len;
1949 BOOL r;
1950 LPWSTR systemW = NULL;
1951 LPWSTR accountW = NULL;
1952 LPWSTR domainW = NULL;
1953 DWORD accountSizeW = *accountSize;
1954 DWORD domainSizeW = *domainSize;
1956 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1957 debugstr_a(system),debugstr_sid(sid),
1958 account,accountSize,accountSize?*accountSize:0,
1959 domain,domainSize,domainSize?*domainSize:0,
1960 name_use);
1962 if (system) {
1963 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1964 systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1965 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1967 if (account)
1968 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1969 if (domain)
1970 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1972 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1974 if (r) {
1975 if (accountW && *accountSize) {
1976 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1977 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1978 *accountSize = len;
1979 } else
1980 *accountSize = accountSizeW + 1;
1982 if (domainW && *domainSize) {
1983 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1984 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1985 *domainSize = len;
1986 } else
1987 *domainSize = domainSizeW + 1;
1990 HeapFree( GetProcessHeap(), 0, systemW );
1991 HeapFree( GetProcessHeap(), 0, accountW );
1992 HeapFree( GetProcessHeap(), 0, domainW );
1994 return r;
1997 /******************************************************************************
1998 * LookupAccountSidW [ADVAPI32.@]
2000 * PARAMS
2001 * system []
2002 * sid []
2003 * account []
2004 * accountSize []
2005 * domain []
2006 * domainSize []
2007 * name_use []
2010 BOOL WINAPI
2011 LookupAccountSidW(
2012 IN LPCWSTR system,
2013 IN PSID sid,
2014 OUT LPWSTR account,
2015 IN OUT LPDWORD accountSize,
2016 OUT LPWSTR domain,
2017 IN OUT LPDWORD domainSize,
2018 OUT PSID_NAME_USE name_use )
2020 unsigned int i, j;
2021 const WCHAR * ac = NULL;
2022 const WCHAR * dm = NULL;
2023 SID_NAME_USE use = 0;
2024 LPWSTR computer_name = NULL;
2026 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2027 debugstr_w(system),debugstr_sid(sid),
2028 account,accountSize,accountSize?*accountSize:0,
2029 domain,domainSize,domainSize?*domainSize:0,
2030 name_use);
2032 if (!ADVAPI_IsLocalComputer(system)) {
2033 FIXME("Only local computer supported!\n");
2034 SetLastError(ERROR_NONE_MAPPED);
2035 return FALSE;
2038 /* check the well known SIDs first */
2039 for (i = 0; i <= 60; i++) {
2040 if (IsWellKnownSid(sid, i)) {
2041 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2042 if (ACCOUNT_SIDS[j].type == i) {
2043 ac = ACCOUNT_SIDS[j].account;
2044 dm = ACCOUNT_SIDS[j].domain;
2045 use = ACCOUNT_SIDS[j].name_use;
2048 break;
2052 if (dm == NULL) {
2053 MAX_SID local;
2055 /* check for the local computer next */
2056 if (ADVAPI_GetComputerSid(&local)) {
2057 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2058 BOOL result;
2060 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2061 result = GetComputerNameW(computer_name, &size);
2063 if (result) {
2064 if (EqualSid(sid, &local)) {
2065 dm = computer_name;
2066 ac = Blank;
2067 use = 3;
2068 } else {
2069 local.SubAuthorityCount++;
2071 if (EqualPrefixSid(sid, &local)) {
2072 dm = computer_name;
2073 use = 1;
2074 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2075 case DOMAIN_USER_RID_ADMIN:
2076 ac = Administrator;
2077 break;
2078 case DOMAIN_USER_RID_GUEST:
2079 ac = Guest;
2080 break;
2081 case DOMAIN_GROUP_RID_ADMINS:
2082 ac = Domain_Admins;
2083 break;
2084 case DOMAIN_GROUP_RID_USERS:
2085 ac = Domain_Users;
2086 break;
2087 case DOMAIN_GROUP_RID_GUESTS:
2088 ac = Domain_Guests;
2089 break;
2090 case DOMAIN_GROUP_RID_COMPUTERS:
2091 ac = Domain_Computers;
2092 break;
2093 case DOMAIN_GROUP_RID_CONTROLLERS:
2094 ac = Domain_Controllers;
2095 break;
2096 case DOMAIN_GROUP_RID_CERT_ADMINS:
2097 ac = Cert_Publishers;
2098 break;
2099 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2100 ac = Schema_Admins;
2101 break;
2102 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2103 ac = Enterprise_Admins;
2104 break;
2105 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2106 ac = Group_Policy_Creator_Owners;
2107 break;
2108 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2109 ac = RAS_and_IAS_Servers;
2110 break;
2111 default:
2112 dm = NULL;
2113 break;
2121 if (dm) {
2122 DWORD ac_len = lstrlenW(ac);
2123 DWORD dm_len = lstrlenW(dm);
2124 BOOL status = TRUE;
2126 if (*accountSize > ac_len) {
2127 if (account)
2128 lstrcpyW(account, ac);
2130 if (*domainSize > dm_len) {
2131 if (domain)
2132 lstrcpyW(domain, dm);
2134 if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2135 ((*domainSize != 0) && (*domainSize < dm_len))) {
2136 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2137 status = FALSE;
2139 if (*domainSize)
2140 *domainSize = dm_len;
2141 else
2142 *domainSize = dm_len + 1;
2143 if (*accountSize)
2144 *accountSize = ac_len;
2145 else
2146 *accountSize = ac_len + 1;
2147 *name_use = use;
2148 HeapFree(GetProcessHeap(), 0, computer_name);
2149 return status;
2152 HeapFree(GetProcessHeap(), 0, computer_name);
2153 SetLastError(ERROR_NONE_MAPPED);
2154 return FALSE;
2157 /******************************************************************************
2158 * SetFileSecurityA [ADVAPI32.@]
2160 * See SetFileSecurityW.
2162 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2163 SECURITY_INFORMATION RequestedInformation,
2164 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2166 DWORD len;
2167 BOOL r;
2168 LPWSTR name = NULL;
2170 if( lpFileName )
2172 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2173 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2174 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2177 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2178 HeapFree( GetProcessHeap(), 0, name );
2180 return r;
2183 /******************************************************************************
2184 * SetFileSecurityW [ADVAPI32.@]
2186 * Sets the security of a file or directory.
2188 * PARAMS
2189 * lpFileName []
2190 * RequestedInformation []
2191 * pSecurityDescriptor []
2193 * RETURNS
2194 * Success: TRUE.
2195 * Failure: FALSE.
2197 BOOL WINAPI
2198 SetFileSecurityW( LPCWSTR lpFileName,
2199 SECURITY_INFORMATION RequestedInformation,
2200 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2202 HANDLE file;
2203 DWORD access = 0;
2204 NTSTATUS status;
2206 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2207 pSecurityDescriptor );
2209 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2210 RequestedInformation & GROUP_SECURITY_INFORMATION)
2211 access |= WRITE_OWNER;
2212 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2213 access |= ACCESS_SYSTEM_SECURITY;
2214 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2215 access |= WRITE_DAC;
2217 file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2218 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2219 if (file == INVALID_HANDLE_VALUE)
2220 return FALSE;
2222 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2223 CloseHandle( file );
2224 return set_ntstatus( status );
2227 /******************************************************************************
2228 * QueryWindows31FilesMigration [ADVAPI32.@]
2230 * PARAMS
2231 * x1 []
2233 BOOL WINAPI
2234 QueryWindows31FilesMigration( DWORD x1 )
2236 FIXME("(%d):stub\n",x1);
2237 return TRUE;
2240 /******************************************************************************
2241 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2243 * PARAMS
2244 * x1 []
2245 * x2 []
2246 * x3 []
2247 * x4 []
2249 BOOL WINAPI
2250 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2251 DWORD x4 )
2253 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2254 return TRUE;
2257 /******************************************************************************
2258 * NotifyBootConfigStatus [ADVAPI32.@]
2260 * PARAMS
2261 * x1 []
2263 BOOL WINAPI
2264 NotifyBootConfigStatus( BOOL x1 )
2266 FIXME("(0x%08d):stub\n",x1);
2267 return 1;
2270 /******************************************************************************
2271 * RevertToSelf [ADVAPI32.@]
2273 * Ends the impersonation of a user.
2275 * PARAMS
2276 * void []
2278 * RETURNS
2279 * Success: TRUE.
2280 * Failure: FALSE.
2282 BOOL WINAPI
2283 RevertToSelf( void )
2285 HANDLE Token = NULL;
2286 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2287 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2290 /******************************************************************************
2291 * ImpersonateSelf [ADVAPI32.@]
2293 * Makes an impersonation token that represents the process user and assigns
2294 * to the current thread.
2296 * PARAMS
2297 * ImpersonationLevel [I] Level at which to impersonate.
2299 * RETURNS
2300 * Success: TRUE.
2301 * Failure: FALSE.
2303 BOOL WINAPI
2304 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2306 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2309 /******************************************************************************
2310 * ImpersonateLoggedOnUser [ADVAPI32.@]
2312 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2314 DWORD size;
2315 NTSTATUS Status;
2316 HANDLE ImpersonationToken;
2317 TOKEN_TYPE Type;
2318 static BOOL warn = TRUE;
2320 if (warn)
2322 FIXME( "(%p)\n", hToken );
2323 warn = FALSE;
2325 if (!GetTokenInformation( hToken, TokenType, &Type,
2326 sizeof(TOKEN_TYPE), &size ))
2327 return FALSE;
2329 if (Type == TokenPrimary)
2331 OBJECT_ATTRIBUTES ObjectAttributes;
2333 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2335 Status = NtDuplicateToken( hToken,
2336 TOKEN_IMPERSONATE | TOKEN_QUERY,
2337 &ObjectAttributes,
2338 SecurityImpersonation,
2339 TokenImpersonation,
2340 &ImpersonationToken );
2341 if (Status != STATUS_SUCCESS)
2343 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2344 SetLastError( RtlNtStatusToDosError( Status ) );
2345 return FALSE;
2348 else
2349 ImpersonationToken = hToken;
2351 Status = NtSetInformationThread( GetCurrentThread(),
2352 ThreadImpersonationToken,
2353 &ImpersonationToken,
2354 sizeof(ImpersonationToken) );
2356 if (Type == TokenPrimary)
2357 NtClose( ImpersonationToken );
2359 if (Status != STATUS_SUCCESS)
2361 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2362 SetLastError( RtlNtStatusToDosError( Status ) );
2363 return FALSE;
2366 return TRUE;
2369 /******************************************************************************
2370 * AccessCheck [ADVAPI32.@]
2372 BOOL WINAPI
2373 AccessCheck(
2374 PSECURITY_DESCRIPTOR SecurityDescriptor,
2375 HANDLE ClientToken,
2376 DWORD DesiredAccess,
2377 PGENERIC_MAPPING GenericMapping,
2378 PPRIVILEGE_SET PrivilegeSet,
2379 LPDWORD PrivilegeSetLength,
2380 LPDWORD GrantedAccess,
2381 LPBOOL AccessStatus)
2383 NTSTATUS access_status;
2384 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2385 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2386 GrantedAccess, &access_status) );
2387 if (ret) *AccessStatus = set_ntstatus( access_status );
2388 return ret;
2392 /******************************************************************************
2393 * AccessCheckByType [ADVAPI32.@]
2395 BOOL WINAPI AccessCheckByType(
2396 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2397 PSID PrincipalSelfSid,
2398 HANDLE ClientToken,
2399 DWORD DesiredAccess,
2400 POBJECT_TYPE_LIST ObjectTypeList,
2401 DWORD ObjectTypeListLength,
2402 PGENERIC_MAPPING GenericMapping,
2403 PPRIVILEGE_SET PrivilegeSet,
2404 LPDWORD PrivilegeSetLength,
2405 LPDWORD GrantedAccess,
2406 LPBOOL AccessStatus)
2408 FIXME("stub\n");
2410 *AccessStatus = TRUE;
2412 return !*AccessStatus;
2415 /******************************************************************************
2416 * MapGenericMask [ADVAPI32.@]
2418 * Maps generic access rights into specific access rights according to the
2419 * supplied mapping.
2421 * PARAMS
2422 * AccessMask [I/O] Access rights.
2423 * GenericMapping [I] The mapping between generic and specific rights.
2425 * RETURNS
2426 * Nothing.
2428 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2430 RtlMapGenericMask( AccessMask, GenericMapping );
2433 /*************************************************************************
2434 * SetKernelObjectSecurity [ADVAPI32.@]
2436 BOOL WINAPI SetKernelObjectSecurity (
2437 IN HANDLE Handle,
2438 IN SECURITY_INFORMATION SecurityInformation,
2439 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2441 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2445 /******************************************************************************
2446 * AddAuditAccessAce [ADVAPI32.@]
2448 BOOL WINAPI AddAuditAccessAce(
2449 IN OUT PACL pAcl,
2450 IN DWORD dwAceRevision,
2451 IN DWORD dwAccessMask,
2452 IN PSID pSid,
2453 IN BOOL bAuditSuccess,
2454 IN BOOL bAuditFailure)
2456 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2457 bAuditSuccess, bAuditFailure) );
2460 /******************************************************************************
2461 * AddAuditAccessAce [ADVAPI32.@]
2463 BOOL WINAPI AddAuditAccessAceEx(
2464 IN OUT PACL pAcl,
2465 IN DWORD dwAceRevision,
2466 IN DWORD dwAceFlags,
2467 IN DWORD dwAccessMask,
2468 IN PSID pSid,
2469 IN BOOL bAuditSuccess,
2470 IN BOOL bAuditFailure)
2472 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2473 bAuditSuccess, bAuditFailure) );
2476 /******************************************************************************
2477 * LookupAccountNameA [ADVAPI32.@]
2479 BOOL WINAPI
2480 LookupAccountNameA(
2481 IN LPCSTR system,
2482 IN LPCSTR account,
2483 OUT PSID sid,
2484 OUT LPDWORD cbSid,
2485 LPSTR ReferencedDomainName,
2486 IN OUT LPDWORD cbReferencedDomainName,
2487 OUT PSID_NAME_USE name_use )
2489 BOOL ret;
2490 UNICODE_STRING lpSystemW;
2491 UNICODE_STRING lpAccountW;
2492 LPWSTR lpReferencedDomainNameW = NULL;
2494 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2495 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2497 if (ReferencedDomainName)
2498 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2500 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2501 cbReferencedDomainName, name_use);
2503 if (ret && lpReferencedDomainNameW)
2505 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2506 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2509 RtlFreeUnicodeString(&lpSystemW);
2510 RtlFreeUnicodeString(&lpAccountW);
2511 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2513 return ret;
2516 /******************************************************************************
2517 * LookupAccountNameW [ADVAPI32.@]
2519 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2520 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2521 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2523 /* Default implementation: Always return a default SID */
2524 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2525 BOOL ret;
2526 PSID pSid;
2527 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2528 unsigned int i;
2529 DWORD nameLen;
2530 LPCWSTR domainName;
2532 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2533 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2535 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2537 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2539 DWORD sidLen = SECURITY_MAX_SID_SIZE;
2541 pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2543 ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2545 if (ret)
2547 if (*cbSid < sidLen)
2549 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2550 ret = FALSE;
2552 else if (Sid)
2554 CopySid(*cbSid, Sid, pSid);
2557 *cbSid = sidLen;
2560 domainName = ACCOUNT_SIDS[i].domain;
2561 nameLen = strlenW(domainName);
2563 if (*cchReferencedDomainName <= nameLen || !ret)
2565 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2566 nameLen += 1;
2567 ret = FALSE;
2569 else if (ReferencedDomainName && domainName)
2571 strcpyW(ReferencedDomainName, domainName);
2574 *cchReferencedDomainName = nameLen;
2576 if (ret)
2578 *peUse = ACCOUNT_SIDS[i].name_use;
2581 HeapFree(GetProcessHeap(), 0, pSid);
2583 return ret;
2587 ret = AllocateAndInitializeSid(&identifierAuthority,
2589 SECURITY_BUILTIN_DOMAIN_RID,
2590 DOMAIN_ALIAS_RID_ADMINS,
2591 0, 0, 0, 0, 0, 0,
2592 &pSid);
2594 if (!ret)
2595 return FALSE;
2597 if (!RtlValidSid(pSid))
2599 FreeSid(pSid);
2600 return FALSE;
2603 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2604 CopySid(*cbSid, Sid, pSid);
2605 if (*cbSid < GetLengthSid(pSid))
2607 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2608 ret = FALSE;
2610 *cbSid = GetLengthSid(pSid);
2612 domainName = dm;
2613 nameLen = strlenW(domainName);
2615 if (*cchReferencedDomainName <= nameLen || !ret)
2617 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2618 nameLen += 1;
2619 ret = FALSE;
2621 else if (ReferencedDomainName && domainName)
2623 strcpyW(ReferencedDomainName, domainName);
2626 *cchReferencedDomainName = nameLen;
2628 if (ret)
2630 *peUse = SidTypeUser;
2633 FreeSid(pSid);
2635 return ret;
2638 /******************************************************************************
2639 * PrivilegeCheck [ADVAPI32.@]
2641 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2643 BOOL ret;
2644 BOOLEAN Result;
2646 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2648 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2649 if (ret)
2650 *pfResult = Result;
2651 return ret;
2654 /******************************************************************************
2655 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2657 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2658 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2659 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2660 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2662 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2663 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2664 SecurityDescriptor, DesiredAccess, GenericMapping,
2665 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2666 return TRUE;
2669 /******************************************************************************
2670 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2672 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2673 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2674 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2675 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2677 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2678 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2679 SecurityDescriptor, DesiredAccess, GenericMapping,
2680 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2681 return TRUE;
2684 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2686 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2688 return TRUE;
2691 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2693 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2695 return TRUE;
2698 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2700 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2702 return TRUE;
2705 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2706 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2707 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2708 LPBOOL GenerateOnClose)
2710 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2711 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2712 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2713 GenerateOnClose);
2715 return TRUE;
2718 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2719 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2720 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2721 LPBOOL GenerateOnClose)
2723 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2724 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2725 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2726 GenerateOnClose);
2728 return TRUE;
2731 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2732 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2734 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2735 DesiredAccess, Privileges, AccessGranted);
2737 return TRUE;
2740 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2741 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2743 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2744 DesiredAccess, Privileges, AccessGranted);
2746 return TRUE;
2749 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2750 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2752 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2753 ClientToken, Privileges, AccessGranted);
2755 return TRUE;
2758 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2759 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2761 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2762 ClientToken, Privileges, AccessGranted);
2764 return TRUE;
2767 /******************************************************************************
2768 * GetSecurityInfo [ADVAPI32.@]
2770 * Retrieves a copy of the security descriptor associated with an object.
2772 * PARAMS
2773 * hObject [I] A handle for the object.
2774 * ObjectType [I] The type of object.
2775 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2776 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2777 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2778 * ppDacl [O] If non-null, receives a pointer to the DACL.
2779 * ppSacl [O] If non-null, receives a pointer to the SACL.
2780 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2781 * which must be freed with LocalFree.
2783 * RETURNS
2784 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2786 DWORD WINAPI GetSecurityInfo(
2787 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2788 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2789 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2790 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2793 PSECURITY_DESCRIPTOR sd;
2794 NTSTATUS status;
2795 ULONG n1, n2;
2796 BOOL present, defaulted;
2798 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2799 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2800 return RtlNtStatusToDosError(status);
2802 sd = LocalAlloc(0, n1);
2803 if (!sd)
2804 return ERROR_NOT_ENOUGH_MEMORY;
2806 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2807 if (status != STATUS_SUCCESS)
2809 LocalFree(sd);
2810 return RtlNtStatusToDosError(status);
2813 if (ppsidOwner)
2815 *ppsidOwner = NULL;
2816 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2818 if (ppsidGroup)
2820 *ppsidGroup = NULL;
2821 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2823 if (ppDacl)
2825 *ppDacl = NULL;
2826 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2828 if (ppSacl)
2830 *ppSacl = NULL;
2831 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2833 if (ppSecurityDescriptor)
2834 *ppSecurityDescriptor = sd;
2836 return ERROR_SUCCESS;
2839 /******************************************************************************
2840 * GetSecurityInfoExW [ADVAPI32.@]
2842 DWORD WINAPI GetSecurityInfoExW(
2843 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2844 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2845 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2846 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2849 FIXME("stub!\n");
2850 return ERROR_BAD_PROVIDER;
2853 /******************************************************************************
2854 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2856 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2857 LPSTR pTrusteeName, DWORD AccessPermissions,
2858 ACCESS_MODE AccessMode, DWORD Inheritance )
2860 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2861 AccessPermissions, AccessMode, Inheritance);
2863 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2864 pExplicitAccess->grfAccessMode = AccessMode;
2865 pExplicitAccess->grfInheritance = Inheritance;
2867 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2868 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2869 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2870 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2871 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2874 /******************************************************************************
2875 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2877 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2878 LPWSTR pTrusteeName, DWORD AccessPermissions,
2879 ACCESS_MODE AccessMode, DWORD Inheritance )
2881 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2882 AccessPermissions, AccessMode, Inheritance);
2884 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2885 pExplicitAccess->grfAccessMode = AccessMode;
2886 pExplicitAccess->grfInheritance = Inheritance;
2888 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2889 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2890 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2891 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2892 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2895 /******************************************************************************
2896 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2898 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2899 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2900 LPSTR InheritedObjectTypeName, LPSTR Name )
2902 DWORD ObjectsPresent = 0;
2904 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2905 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2907 /* Fill the OBJECTS_AND_NAME structure */
2908 pObjName->ObjectType = ObjectType;
2909 if (ObjectTypeName != NULL)
2911 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2914 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2915 if (InheritedObjectTypeName != NULL)
2917 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2920 pObjName->ObjectsPresent = ObjectsPresent;
2921 pObjName->ptstrName = Name;
2923 /* Fill the TRUSTEE structure */
2924 pTrustee->pMultipleTrustee = NULL;
2925 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2926 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2927 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2928 pTrustee->ptstrName = (LPSTR)pObjName;
2931 /******************************************************************************
2932 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2934 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2935 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2936 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2938 DWORD ObjectsPresent = 0;
2940 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2941 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2943 /* Fill the OBJECTS_AND_NAME structure */
2944 pObjName->ObjectType = ObjectType;
2945 if (ObjectTypeName != NULL)
2947 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2950 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2951 if (InheritedObjectTypeName != NULL)
2953 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2956 pObjName->ObjectsPresent = ObjectsPresent;
2957 pObjName->ptstrName = Name;
2959 /* Fill the TRUSTEE structure */
2960 pTrustee->pMultipleTrustee = NULL;
2961 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2962 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2963 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2964 pTrustee->ptstrName = (LPWSTR)pObjName;
2967 /******************************************************************************
2968 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2970 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2971 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2973 DWORD ObjectsPresent = 0;
2975 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2977 /* Fill the OBJECTS_AND_SID structure */
2978 if (pObjectGuid != NULL)
2980 pObjSid->ObjectTypeGuid = *pObjectGuid;
2981 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2983 else
2985 ZeroMemory(&pObjSid->ObjectTypeGuid,
2986 sizeof(GUID));
2989 if (pInheritedObjectGuid != NULL)
2991 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2992 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2994 else
2996 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2997 sizeof(GUID));
3000 pObjSid->ObjectsPresent = ObjectsPresent;
3001 pObjSid->pSid = pSid;
3003 /* Fill the TRUSTEE structure */
3004 pTrustee->pMultipleTrustee = NULL;
3005 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3006 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3007 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3008 pTrustee->ptstrName = (LPSTR) pObjSid;
3011 /******************************************************************************
3012 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3014 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3015 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3017 DWORD ObjectsPresent = 0;
3019 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3021 /* Fill the OBJECTS_AND_SID structure */
3022 if (pObjectGuid != NULL)
3024 pObjSid->ObjectTypeGuid = *pObjectGuid;
3025 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3027 else
3029 ZeroMemory(&pObjSid->ObjectTypeGuid,
3030 sizeof(GUID));
3033 if (pInheritedObjectGuid != NULL)
3035 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3036 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3038 else
3040 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3041 sizeof(GUID));
3044 pObjSid->ObjectsPresent = ObjectsPresent;
3045 pObjSid->pSid = pSid;
3047 /* Fill the TRUSTEE structure */
3048 pTrustee->pMultipleTrustee = NULL;
3049 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3050 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3051 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3052 pTrustee->ptstrName = (LPWSTR) pObjSid;
3055 /******************************************************************************
3056 * BuildTrusteeWithSidA [ADVAPI32.@]
3058 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3060 TRACE("%p %p\n", pTrustee, pSid);
3062 pTrustee->pMultipleTrustee = NULL;
3063 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3064 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3065 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3066 pTrustee->ptstrName = (LPSTR) pSid;
3069 /******************************************************************************
3070 * BuildTrusteeWithSidW [ADVAPI32.@]
3072 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3074 TRACE("%p %p\n", pTrustee, pSid);
3076 pTrustee->pMultipleTrustee = NULL;
3077 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3078 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3079 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3080 pTrustee->ptstrName = (LPWSTR) pSid;
3083 /******************************************************************************
3084 * BuildTrusteeWithNameA [ADVAPI32.@]
3086 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3088 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3090 pTrustee->pMultipleTrustee = NULL;
3091 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3092 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3093 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3094 pTrustee->ptstrName = name;
3097 /******************************************************************************
3098 * BuildTrusteeWithNameW [ADVAPI32.@]
3100 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3102 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3104 pTrustee->pMultipleTrustee = NULL;
3105 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3106 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3107 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3108 pTrustee->ptstrName = name;
3111 /******************************************************************************
3112 * GetTrusteeFormA [ADVAPI32.@]
3114 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3116 TRACE("(%p)\n", pTrustee);
3118 if (!pTrustee)
3119 return TRUSTEE_BAD_FORM;
3121 return pTrustee->TrusteeForm;
3124 /******************************************************************************
3125 * GetTrusteeFormW [ADVAPI32.@]
3127 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3129 TRACE("(%p)\n", pTrustee);
3131 if (!pTrustee)
3132 return TRUSTEE_BAD_FORM;
3134 return pTrustee->TrusteeForm;
3137 /******************************************************************************
3138 * GetTrusteeNameA [ADVAPI32.@]
3140 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3142 TRACE("(%p)\n", pTrustee);
3144 if (!pTrustee)
3145 return NULL;
3147 return pTrustee->ptstrName;
3150 /******************************************************************************
3151 * GetTrusteeNameW [ADVAPI32.@]
3153 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3155 TRACE("(%p)\n", pTrustee);
3157 if (!pTrustee)
3158 return NULL;
3160 return pTrustee->ptstrName;
3163 /******************************************************************************
3164 * GetTrusteeTypeA [ADVAPI32.@]
3166 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3168 TRACE("(%p)\n", pTrustee);
3170 if (!pTrustee)
3171 return TRUSTEE_IS_UNKNOWN;
3173 return pTrustee->TrusteeType;
3176 /******************************************************************************
3177 * GetTrusteeTypeW [ADVAPI32.@]
3179 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3181 TRACE("(%p)\n", pTrustee);
3183 if (!pTrustee)
3184 return TRUSTEE_IS_UNKNOWN;
3186 return pTrustee->TrusteeType;
3189 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3190 DWORD nAclInformationLength,
3191 ACL_INFORMATION_CLASS dwAclInformationClass )
3193 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3194 nAclInformationLength, dwAclInformationClass);
3196 return TRUE;
3199 /******************************************************************************
3200 * SetEntriesInAclA [ADVAPI32.@]
3202 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3203 PACL OldAcl, PACL* NewAcl )
3205 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3206 if (NewAcl)
3207 *NewAcl = NULL;
3208 return ERROR_SUCCESS;
3211 /******************************************************************************
3212 * SetEntriesInAclW [ADVAPI32.@]
3214 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3215 PACL OldAcl, PACL* NewAcl )
3217 ULONG i;
3218 PSID *ppsid;
3219 DWORD ret = ERROR_SUCCESS;
3220 DWORD acl_size = sizeof(ACL);
3221 NTSTATUS status;
3223 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3225 *NewAcl = NULL;
3227 if (!count && !OldAcl)
3228 return ERROR_SUCCESS;
3230 /* allocate array of maximum sized sids allowed */
3231 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3232 if (!ppsid)
3233 return ERROR_OUTOFMEMORY;
3235 for (i = 0; i < count; i++)
3237 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3239 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3240 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3241 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3242 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3243 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3244 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3245 pEntries[i].Trustee.ptstrName);
3247 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3249 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3250 ret = ERROR_INVALID_PARAMETER;
3251 goto exit;
3254 switch (pEntries[i].Trustee.TrusteeForm)
3256 case TRUSTEE_IS_SID:
3257 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3258 ppsid[i], pEntries[i].Trustee.ptstrName))
3260 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3261 ret = ERROR_INVALID_PARAMETER;
3262 goto exit;
3264 break;
3265 case TRUSTEE_IS_NAME:
3267 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3268 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3269 SID_NAME_USE use;
3270 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3272 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3273 ret = ERROR_INVALID_PARAMETER;
3274 goto exit;
3276 break;
3278 case TRUSTEE_IS_OBJECTS_AND_SID:
3279 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3280 break;
3281 case TRUSTEE_IS_OBJECTS_AND_NAME:
3282 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3283 break;
3284 default:
3285 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3286 ret = ERROR_INVALID_PARAMETER;
3287 goto exit;
3290 /* Note: we overestimate the ACL size here as a tradeoff between
3291 * instructions (simplicity) and memory */
3292 switch (pEntries[i].grfAccessMode)
3294 case GRANT_ACCESS:
3295 case SET_ACCESS:
3296 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3297 break;
3298 case DENY_ACCESS:
3299 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3300 break;
3301 case SET_AUDIT_SUCCESS:
3302 case SET_AUDIT_FAILURE:
3303 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3304 break;
3305 case REVOKE_ACCESS:
3306 break;
3307 default:
3308 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3309 ret = ERROR_INVALID_PARAMETER;
3310 goto exit;
3314 if (OldAcl)
3316 ACL_SIZE_INFORMATION size_info;
3318 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3319 if (status != STATUS_SUCCESS)
3321 ret = RtlNtStatusToDosError(status);
3322 goto exit;
3324 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3327 *NewAcl = LocalAlloc(0, acl_size);
3328 if (!*NewAcl)
3330 ret = ERROR_OUTOFMEMORY;
3331 goto exit;
3334 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3335 if (status != STATUS_SUCCESS)
3337 ret = RtlNtStatusToDosError(status);
3338 goto exit;
3341 for (i = 0; i < count; i++)
3343 switch (pEntries[i].grfAccessMode)
3345 case GRANT_ACCESS:
3346 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3347 pEntries[i].grfInheritance,
3348 pEntries[i].grfAccessPermissions,
3349 ppsid[i]);
3350 break;
3351 case SET_ACCESS:
3353 ULONG j;
3354 BOOL add = TRUE;
3355 if (OldAcl)
3357 for (j = 0; ; j++)
3359 const ACE_HEADER *existing_ace_header;
3360 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3361 if (status != STATUS_SUCCESS)
3362 break;
3363 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3364 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3365 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3367 add = FALSE;
3368 break;
3372 if (add)
3373 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3374 pEntries[i].grfInheritance,
3375 pEntries[i].grfAccessPermissions,
3376 ppsid[i]);
3377 break;
3379 case DENY_ACCESS:
3380 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3381 pEntries[i].grfInheritance,
3382 pEntries[i].grfAccessPermissions,
3383 ppsid[i]);
3384 break;
3385 case SET_AUDIT_SUCCESS:
3386 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3387 pEntries[i].grfInheritance,
3388 pEntries[i].grfAccessPermissions,
3389 ppsid[i], TRUE, FALSE);
3390 break;
3391 case SET_AUDIT_FAILURE:
3392 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3393 pEntries[i].grfInheritance,
3394 pEntries[i].grfAccessPermissions,
3395 ppsid[i], FALSE, TRUE);
3396 break;
3397 default:
3398 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3402 if (OldAcl)
3404 for (i = 0; ; i++)
3406 BOOL add = TRUE;
3407 ULONG j;
3408 const ACE_HEADER *old_ace_header;
3409 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3410 if (status != STATUS_SUCCESS) break;
3411 for (j = 0; j < count; j++)
3413 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3414 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3415 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3417 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3418 add = FALSE;
3419 break;
3421 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3423 switch (old_ace_header->AceType)
3425 case ACCESS_ALLOWED_ACE_TYPE:
3426 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3427 add = FALSE;
3428 break;
3429 case ACCESS_DENIED_ACE_TYPE:
3430 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3431 add = FALSE;
3432 break;
3433 case SYSTEM_AUDIT_ACE_TYPE:
3434 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3435 add = FALSE;
3436 break;
3437 case SYSTEM_ALARM_ACE_TYPE:
3438 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3439 add = FALSE;
3440 break;
3441 default:
3442 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3445 if (!add)
3446 break;
3449 if (add)
3450 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3451 if (status != STATUS_SUCCESS)
3453 WARN("RtlAddAce failed with error 0x%08x\n", status);
3454 ret = RtlNtStatusToDosError(status);
3455 break;
3460 exit:
3461 HeapFree(GetProcessHeap(), 0, ppsid);
3462 return ret;
3465 /******************************************************************************
3466 * SetNamedSecurityInfoA [ADVAPI32.@]
3468 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3469 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3470 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3472 DWORD len;
3473 LPWSTR wstr = NULL;
3474 DWORD r;
3476 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3477 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3479 if( pObjectName )
3481 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3482 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3483 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3486 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3487 psidGroup, pDacl, pSacl );
3489 HeapFree( GetProcessHeap(), 0, wstr );
3491 return r;
3494 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3495 PSECURITY_DESCRIPTOR ModificationDescriptor,
3496 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3497 PGENERIC_MAPPING GenericMapping,
3498 HANDLE Token )
3500 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3501 ObjectsSecurityDescriptor, GenericMapping, Token);
3503 return TRUE;
3506 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3508 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3511 /******************************************************************************
3512 * AreAnyAccessesGranted [ADVAPI32.@]
3514 * Determines whether or not any of a set of specified access permissions have
3515 * been granted or not.
3517 * PARAMS
3518 * GrantedAccess [I] The permissions that have been granted.
3519 * DesiredAccess [I] The permissions that you want to have.
3521 * RETURNS
3522 * Nonzero if any of the permissions have been granted, zero if none of the
3523 * permissions have been granted.
3526 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3528 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3531 /******************************************************************************
3532 * SetNamedSecurityInfoW [ADVAPI32.@]
3534 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3535 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3536 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3538 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3539 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3540 return ERROR_SUCCESS;
3543 /******************************************************************************
3544 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3546 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3547 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3549 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3550 return ERROR_CALL_NOT_IMPLEMENTED;
3553 /******************************************************************************
3554 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3556 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3557 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3559 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3560 return ERROR_CALL_NOT_IMPLEMENTED;
3563 /******************************************************************************
3564 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3566 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3567 PACCESS_MASK pFailedAuditRights)
3569 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3570 return ERROR_CALL_NOT_IMPLEMENTED;
3574 /******************************************************************************
3575 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3577 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3578 PACCESS_MASK pFailedAuditRights)
3580 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3581 return ERROR_CALL_NOT_IMPLEMENTED;
3585 /******************************************************************************
3586 * ParseAclStringFlags
3588 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3590 DWORD flags = 0;
3591 LPCWSTR szAcl = *StringAcl;
3593 while (*szAcl != '(')
3595 if (*szAcl == 'P')
3597 flags |= SE_DACL_PROTECTED;
3599 else if (*szAcl == 'A')
3601 szAcl++;
3602 if (*szAcl == 'R')
3603 flags |= SE_DACL_AUTO_INHERIT_REQ;
3604 else if (*szAcl == 'I')
3605 flags |= SE_DACL_AUTO_INHERITED;
3607 szAcl++;
3610 *StringAcl = szAcl;
3611 return flags;
3614 /******************************************************************************
3615 * ParseAceStringType
3617 static const ACEFLAG AceType[] =
3619 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3620 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3621 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3622 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3624 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3625 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3626 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3627 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3629 { NULL, 0 },
3632 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3634 UINT len = 0;
3635 LPCWSTR szAcl = *StringAcl;
3636 const ACEFLAG *lpaf = AceType;
3638 while (lpaf->wstr &&
3639 (len = strlenW(lpaf->wstr)) &&
3640 strncmpW(lpaf->wstr, szAcl, len))
3641 lpaf++;
3643 if (!lpaf->wstr)
3644 return 0;
3646 *StringAcl += len;
3647 return lpaf->value;
3651 /******************************************************************************
3652 * ParseAceStringFlags
3654 static const ACEFLAG AceFlags[] =
3656 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3657 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3658 { SDDL_INHERITED, INHERITED_ACE },
3659 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3660 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3661 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3662 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3663 { NULL, 0 },
3666 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3668 UINT len = 0;
3669 BYTE flags = 0;
3670 LPCWSTR szAcl = *StringAcl;
3672 while (*szAcl != ';')
3674 const ACEFLAG *lpaf = AceFlags;
3676 while (lpaf->wstr &&
3677 (len = strlenW(lpaf->wstr)) &&
3678 strncmpW(lpaf->wstr, szAcl, len))
3679 lpaf++;
3681 if (!lpaf->wstr)
3682 return 0;
3684 flags |= lpaf->value;
3685 szAcl += len;
3688 *StringAcl = szAcl;
3689 return flags;
3693 /******************************************************************************
3694 * ParseAceStringRights
3696 static const ACEFLAG AceRights[] =
3698 { SDDL_GENERIC_ALL, GENERIC_ALL },
3699 { SDDL_GENERIC_READ, GENERIC_READ },
3700 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3701 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3703 { SDDL_READ_CONTROL, READ_CONTROL },
3704 { SDDL_STANDARD_DELETE, DELETE },
3705 { SDDL_WRITE_DAC, WRITE_DAC },
3706 { SDDL_WRITE_OWNER, WRITE_OWNER },
3708 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3709 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3710 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3711 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3712 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3713 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3714 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3715 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3716 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3718 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3719 { SDDL_FILE_READ, FILE_GENERIC_READ },
3720 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3721 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3723 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3724 { SDDL_KEY_READ, KEY_READ },
3725 { SDDL_KEY_WRITE, KEY_WRITE },
3726 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3727 { NULL, 0 },
3730 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3732 UINT len = 0;
3733 DWORD rights = 0;
3734 LPCWSTR szAcl = *StringAcl;
3736 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3738 LPCWSTR p = szAcl;
3740 while (*p && *p != ';')
3741 p++;
3743 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3745 rights = strtoulW(szAcl, NULL, 16);
3746 szAcl = p;
3748 else
3749 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3751 else
3753 while (*szAcl != ';')
3755 const ACEFLAG *lpaf = AceRights;
3757 while (lpaf->wstr &&
3758 (len = strlenW(lpaf->wstr)) &&
3759 strncmpW(lpaf->wstr, szAcl, len))
3761 lpaf++;
3764 if (!lpaf->wstr)
3765 return 0;
3767 rights |= lpaf->value;
3768 szAcl += len;
3772 *StringAcl = szAcl;
3773 return rights;
3777 /******************************************************************************
3778 * ParseStringAclToAcl
3780 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3782 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3783 PACL pAcl, LPDWORD cBytes)
3785 DWORD val;
3786 DWORD sidlen;
3787 DWORD length = sizeof(ACL);
3788 DWORD acesize = 0;
3789 DWORD acecount = 0;
3790 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3792 TRACE("%s\n", debugstr_w(StringAcl));
3794 if (!StringAcl)
3795 return FALSE;
3797 if (pAcl) /* pAce is only useful if we're setting values */
3798 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3800 /* Parse ACL flags */
3801 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3803 /* Parse ACE */
3804 while (*StringAcl == '(')
3806 StringAcl++;
3808 /* Parse ACE type */
3809 val = ParseAceStringType(&StringAcl);
3810 if (pAce)
3811 pAce->Header.AceType = (BYTE) val;
3812 if (*StringAcl != ';')
3813 goto lerr;
3814 StringAcl++;
3816 /* Parse ACE flags */
3817 val = ParseAceStringFlags(&StringAcl);
3818 if (pAce)
3819 pAce->Header.AceFlags = (BYTE) val;
3820 if (*StringAcl != ';')
3821 goto lerr;
3822 StringAcl++;
3824 /* Parse ACE rights */
3825 val = ParseAceStringRights(&StringAcl);
3826 if (pAce)
3827 pAce->Mask = val;
3828 if (*StringAcl != ';')
3829 goto lerr;
3830 StringAcl++;
3832 /* Parse ACE object guid */
3833 if (*StringAcl != ';')
3835 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3836 goto lerr;
3838 StringAcl++;
3840 /* Parse ACE inherit object guid */
3841 if (*StringAcl != ';')
3843 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3844 goto lerr;
3846 StringAcl++;
3848 /* Parse ACE account sid */
3849 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3851 while (*StringAcl && *StringAcl != ')')
3852 StringAcl++;
3855 if (*StringAcl != ')')
3856 goto lerr;
3857 StringAcl++;
3859 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3860 length += acesize;
3861 if (pAce)
3863 pAce->Header.AceSize = acesize;
3864 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3866 acecount++;
3869 *cBytes = length;
3871 if (length > 0xffff)
3873 ERR("ACL too large\n");
3874 goto lerr;
3877 if (pAcl)
3879 pAcl->AclRevision = ACL_REVISION;
3880 pAcl->Sbz1 = 0;
3881 pAcl->AclSize = length;
3882 pAcl->AceCount = acecount++;
3883 pAcl->Sbz2 = 0;
3885 return TRUE;
3887 lerr:
3888 SetLastError(ERROR_INVALID_ACL);
3889 WARN("Invalid ACE string format\n");
3890 return FALSE;
3894 /******************************************************************************
3895 * ParseStringSecurityDescriptorToSecurityDescriptor
3897 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3898 LPCWSTR StringSecurityDescriptor,
3899 SECURITY_DESCRIPTOR* SecurityDescriptor,
3900 LPDWORD cBytes)
3902 BOOL bret = FALSE;
3903 WCHAR toktype;
3904 WCHAR tok[MAX_PATH];
3905 LPCWSTR lptoken;
3906 LPBYTE lpNext = NULL;
3907 DWORD len;
3909 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3911 if (SecurityDescriptor)
3912 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3914 while (*StringSecurityDescriptor)
3916 toktype = *StringSecurityDescriptor;
3918 /* Expect char identifier followed by ':' */
3919 StringSecurityDescriptor++;
3920 if (*StringSecurityDescriptor != ':')
3922 SetLastError(ERROR_INVALID_PARAMETER);
3923 goto lend;
3925 StringSecurityDescriptor++;
3927 /* Extract token */
3928 lptoken = StringSecurityDescriptor;
3929 while (*lptoken && *lptoken != ':')
3930 lptoken++;
3932 if (*lptoken)
3933 lptoken--;
3935 len = lptoken - StringSecurityDescriptor;
3936 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3937 tok[len] = 0;
3939 switch (toktype)
3941 case 'O':
3943 DWORD bytes;
3945 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3946 goto lend;
3948 if (SecurityDescriptor)
3950 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3951 lpNext += bytes; /* Advance to next token */
3954 *cBytes += bytes;
3956 break;
3959 case 'G':
3961 DWORD bytes;
3963 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3964 goto lend;
3966 if (SecurityDescriptor)
3968 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3969 lpNext += bytes; /* Advance to next token */
3972 *cBytes += bytes;
3974 break;
3977 case 'D':
3979 DWORD flags;
3980 DWORD bytes;
3982 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3983 goto lend;
3985 if (SecurityDescriptor)
3987 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3988 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3989 lpNext += bytes; /* Advance to next token */
3992 *cBytes += bytes;
3994 break;
3997 case 'S':
3999 DWORD flags;
4000 DWORD bytes;
4002 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4003 goto lend;
4005 if (SecurityDescriptor)
4007 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4008 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4009 lpNext += bytes; /* Advance to next token */
4012 *cBytes += bytes;
4014 break;
4017 default:
4018 FIXME("Unknown token\n");
4019 SetLastError(ERROR_INVALID_PARAMETER);
4020 goto lend;
4023 StringSecurityDescriptor = lptoken;
4026 bret = TRUE;
4028 lend:
4029 return bret;
4032 /******************************************************************************
4033 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4035 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4036 LPCSTR StringSecurityDescriptor,
4037 DWORD StringSDRevision,
4038 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4039 PULONG SecurityDescriptorSize)
4041 UINT len;
4042 BOOL ret = FALSE;
4043 LPWSTR StringSecurityDescriptorW;
4045 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4046 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4048 if (StringSecurityDescriptorW)
4050 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4052 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4053 StringSDRevision, SecurityDescriptor,
4054 SecurityDescriptorSize);
4055 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4058 return ret;
4061 /******************************************************************************
4062 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4064 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4065 LPCWSTR StringSecurityDescriptor,
4066 DWORD StringSDRevision,
4067 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4068 PULONG SecurityDescriptorSize)
4070 DWORD cBytes;
4071 SECURITY_DESCRIPTOR* psd;
4072 BOOL bret = FALSE;
4074 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4076 if (GetVersion() & 0x80000000)
4078 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4079 goto lend;
4081 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4083 SetLastError(ERROR_INVALID_PARAMETER);
4084 goto lend;
4086 else if (StringSDRevision != SID_REVISION)
4088 SetLastError(ERROR_UNKNOWN_REVISION);
4089 goto lend;
4092 /* Compute security descriptor length */
4093 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4094 NULL, &cBytes))
4095 goto lend;
4097 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4098 GMEM_ZEROINIT, cBytes);
4099 if (!psd) goto lend;
4101 psd->Revision = SID_REVISION;
4102 psd->Control |= SE_SELF_RELATIVE;
4104 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4105 psd, &cBytes))
4107 LocalFree(psd);
4108 goto lend;
4111 if (SecurityDescriptorSize)
4112 *SecurityDescriptorSize = cBytes;
4114 bret = TRUE;
4116 lend:
4117 TRACE(" ret=%d\n", bret);
4118 return bret;
4121 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4123 if (cch == -1)
4124 cch = strlenW(string);
4126 if (plen)
4127 *plen += cch;
4129 if (pwptr)
4131 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4132 *pwptr += cch;
4136 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4138 DWORD i;
4139 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4140 WCHAR subauthfmt[] = { '-','%','u',0 };
4141 WCHAR buf[26];
4142 SID *pisid = psid;
4144 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4146 SetLastError(ERROR_INVALID_SID);
4147 return FALSE;
4150 if (pisid->IdentifierAuthority.Value[0] ||
4151 pisid->IdentifierAuthority.Value[1])
4153 FIXME("not matching MS' bugs\n");
4154 SetLastError(ERROR_INVALID_SID);
4155 return FALSE;
4158 sprintfW( buf, fmt, pisid->Revision,
4159 MAKELONG(
4160 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4161 pisid->IdentifierAuthority.Value[4] ),
4162 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4163 pisid->IdentifierAuthority.Value[2] )
4164 ) );
4165 DumpString(buf, -1, pwptr, plen);
4167 for( i=0; i<pisid->SubAuthorityCount; i++ )
4169 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4170 DumpString(buf, -1, pwptr, plen);
4172 return TRUE;
4175 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4177 size_t i;
4178 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4180 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4182 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4183 return TRUE;
4187 return DumpSidNumeric(psid, pwptr, plen);
4190 static const LPCWSTR AceRightBitNames[32] = {
4191 SDDL_CREATE_CHILD, /* 0 */
4192 SDDL_DELETE_CHILD,
4193 SDDL_LIST_CHILDREN,
4194 SDDL_SELF_WRITE,
4195 SDDL_READ_PROPERTY, /* 4 */
4196 SDDL_WRITE_PROPERTY,
4197 SDDL_DELETE_TREE,
4198 SDDL_LIST_OBJECT,
4199 SDDL_CONTROL_ACCESS, /* 8 */
4200 NULL,
4201 NULL,
4202 NULL,
4203 NULL, /* 12 */
4204 NULL,
4205 NULL,
4206 NULL,
4207 SDDL_STANDARD_DELETE, /* 16 */
4208 SDDL_READ_CONTROL,
4209 SDDL_WRITE_DAC,
4210 SDDL_WRITE_OWNER,
4211 NULL, /* 20 */
4212 NULL,
4213 NULL,
4214 NULL,
4215 NULL, /* 24 */
4216 NULL,
4217 NULL,
4218 NULL,
4219 SDDL_GENERIC_ALL, /* 28 */
4220 SDDL_GENERIC_EXECUTE,
4221 SDDL_GENERIC_WRITE,
4222 SDDL_GENERIC_READ
4225 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4227 static const WCHAR fmtW[] = {'0','x','%','x',0};
4228 WCHAR buf[15];
4229 size_t i;
4231 if (mask == 0)
4232 return;
4234 /* first check if the right have name */
4235 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4237 if (AceRights[i].wstr == NULL)
4238 break;
4239 if (mask == AceRights[i].value)
4241 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4242 return;
4246 /* then check if it can be built from bit names */
4247 for (i = 0; i < 32; i++)
4249 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4251 /* can't be built from bit names */
4252 sprintfW(buf, fmtW, mask);
4253 DumpString(buf, -1, pwptr, plen);
4254 return;
4258 /* build from bit names */
4259 for (i = 0; i < 32; i++)
4260 if (mask & (1 << i))
4261 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4264 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4266 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4267 static const WCHAR openbr = '(';
4268 static const WCHAR closebr = ')';
4269 static const WCHAR semicolon = ';';
4271 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4273 SetLastError(ERROR_INVALID_ACL);
4274 return FALSE;
4277 piace = (ACCESS_ALLOWED_ACE *)pace;
4278 DumpString(&openbr, 1, pwptr, plen);
4279 switch (piace->Header.AceType)
4281 case ACCESS_ALLOWED_ACE_TYPE:
4282 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4283 break;
4284 case ACCESS_DENIED_ACE_TYPE:
4285 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4286 break;
4287 case SYSTEM_AUDIT_ACE_TYPE:
4288 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4289 break;
4290 case SYSTEM_ALARM_ACE_TYPE:
4291 DumpString(SDDL_ALARM, -1, pwptr, plen);
4292 break;
4294 DumpString(&semicolon, 1, pwptr, plen);
4296 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4297 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4298 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4299 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4300 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4301 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4302 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4303 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4304 if (piace->Header.AceFlags & INHERITED_ACE)
4305 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4306 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4307 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4308 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4309 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4310 DumpString(&semicolon, 1, pwptr, plen);
4311 DumpRights(piace->Mask, pwptr, plen);
4312 DumpString(&semicolon, 1, pwptr, plen);
4313 /* objects not supported */
4314 DumpString(&semicolon, 1, pwptr, plen);
4315 /* objects not supported */
4316 DumpString(&semicolon, 1, pwptr, plen);
4317 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4318 return FALSE;
4319 DumpString(&closebr, 1, pwptr, plen);
4320 return TRUE;
4323 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4325 WORD count;
4326 int i;
4328 if (protected)
4329 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4330 if (autoInheritReq)
4331 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4332 if (autoInherited)
4333 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4335 if (pacl == NULL)
4336 return TRUE;
4338 if (!IsValidAcl(pacl))
4339 return FALSE;
4341 count = pacl->AceCount;
4342 for (i = 0; i < count; i++)
4344 LPVOID ace;
4345 if (!GetAce(pacl, i, &ace))
4346 return FALSE;
4347 if (!DumpAce(ace, pwptr, plen))
4348 return FALSE;
4351 return TRUE;
4354 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4356 static const WCHAR prefix[] = {'O',':',0};
4357 BOOL bDefaulted;
4358 PSID psid;
4360 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4361 return FALSE;
4363 if (psid == NULL)
4364 return TRUE;
4366 DumpString(prefix, -1, pwptr, plen);
4367 if (!DumpSid(psid, pwptr, plen))
4368 return FALSE;
4369 return TRUE;
4372 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4374 static const WCHAR prefix[] = {'G',':',0};
4375 BOOL bDefaulted;
4376 PSID psid;
4378 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4379 return FALSE;
4381 if (psid == NULL)
4382 return TRUE;
4384 DumpString(prefix, -1, pwptr, plen);
4385 if (!DumpSid(psid, pwptr, plen))
4386 return FALSE;
4387 return TRUE;
4390 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4392 static const WCHAR dacl[] = {'D',':',0};
4393 SECURITY_DESCRIPTOR_CONTROL control;
4394 BOOL present, defaulted;
4395 DWORD revision;
4396 PACL pacl;
4398 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4399 return FALSE;
4401 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4402 return FALSE;
4404 if (!present)
4405 return TRUE;
4407 DumpString(dacl, 2, pwptr, plen);
4408 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4409 return FALSE;
4410 return TRUE;
4413 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4415 static const WCHAR sacl[] = {'S',':',0};
4416 SECURITY_DESCRIPTOR_CONTROL control;
4417 BOOL present, defaulted;
4418 DWORD revision;
4419 PACL pacl;
4421 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4422 return FALSE;
4424 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4425 return FALSE;
4427 if (!present)
4428 return TRUE;
4430 DumpString(sacl, 2, pwptr, plen);
4431 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4432 return FALSE;
4433 return TRUE;
4436 /******************************************************************************
4437 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4439 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4441 ULONG len;
4442 WCHAR *wptr, *wstr;
4444 if (SDRevision != SDDL_REVISION_1)
4446 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4447 SetLastError(ERROR_UNKNOWN_REVISION);
4448 return FALSE;
4451 len = 0;
4452 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4453 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4454 return FALSE;
4455 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4456 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4457 return FALSE;
4458 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4459 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4460 return FALSE;
4461 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4462 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4463 return FALSE;
4465 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4466 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4467 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4468 return FALSE;
4469 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4470 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4471 return FALSE;
4472 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4473 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4474 return FALSE;
4475 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4476 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4477 return FALSE;
4478 *wptr = 0;
4480 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4481 *OutputString = wstr;
4482 if (OutputLen)
4483 *OutputLen = strlenW(*OutputString)+1;
4484 return TRUE;
4487 /******************************************************************************
4488 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4490 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4492 LPWSTR wstr;
4493 ULONG len;
4494 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4496 int lenA;
4498 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4499 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4500 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4501 LocalFree(wstr);
4503 if (OutputLen != NULL)
4504 *OutputLen = lenA;
4505 return TRUE;
4507 else
4509 *OutputString = NULL;
4510 if (OutputLen)
4511 *OutputLen = 0;
4512 return FALSE;
4516 /******************************************************************************
4517 * ConvertStringSidToSidW [ADVAPI32.@]
4519 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4521 BOOL bret = FALSE;
4522 DWORD cBytes;
4524 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4525 if (GetVersion() & 0x80000000)
4526 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4527 else if (!StringSid || !Sid)
4528 SetLastError(ERROR_INVALID_PARAMETER);
4529 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4531 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4533 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4534 if (!bret)
4535 LocalFree(*Sid);
4537 return bret;
4540 /******************************************************************************
4541 * ConvertStringSidToSidA [ADVAPI32.@]
4543 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4545 BOOL bret = FALSE;
4547 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4548 if (GetVersion() & 0x80000000)
4549 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4550 else if (!StringSid || !Sid)
4551 SetLastError(ERROR_INVALID_PARAMETER);
4552 else
4554 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4555 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4556 len * sizeof(WCHAR));
4558 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4559 bret = ConvertStringSidToSidW(wStringSid, Sid);
4560 HeapFree(GetProcessHeap(), 0, wStringSid);
4562 return bret;
4565 /******************************************************************************
4566 * ConvertSidToStringSidW [ADVAPI32.@]
4568 * format of SID string is:
4569 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4570 * where
4571 * <rev> is the revision of the SID encoded as decimal
4572 * <auth> is the identifier authority encoded as hex
4573 * <subauthN> is the subauthority id encoded as decimal
4575 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4577 DWORD len = 0;
4578 LPWSTR wstr, wptr;
4580 TRACE("%p %p\n", pSid, pstr );
4582 len = 0;
4583 if (!DumpSidNumeric(pSid, NULL, &len))
4584 return FALSE;
4585 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4586 DumpSidNumeric(pSid, &wptr, NULL);
4587 *wptr = 0;
4589 *pstr = wstr;
4590 return TRUE;
4593 /******************************************************************************
4594 * ConvertSidToStringSidA [ADVAPI32.@]
4596 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4598 LPWSTR wstr = NULL;
4599 LPSTR str;
4600 UINT len;
4602 TRACE("%p %p\n", pSid, pstr );
4604 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4605 return FALSE;
4607 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4608 str = LocalAlloc( 0, len );
4609 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4610 LocalFree( wstr );
4612 *pstr = str;
4614 return TRUE;
4617 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4618 PSECURITY_DESCRIPTOR pdesc,
4619 PSECURITY_DESCRIPTOR cdesc,
4620 PSECURITY_DESCRIPTOR* ndesc,
4621 GUID* objtype,
4622 BOOL isdir,
4623 PGENERIC_MAPPING genmap )
4625 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4627 return FALSE;
4630 BOOL WINAPI CreatePrivateObjectSecurity(
4631 PSECURITY_DESCRIPTOR ParentDescriptor,
4632 PSECURITY_DESCRIPTOR CreatorDescriptor,
4633 PSECURITY_DESCRIPTOR* NewDescriptor,
4634 BOOL IsDirectoryObject,
4635 HANDLE Token,
4636 PGENERIC_MAPPING GenericMapping )
4638 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4639 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4641 return FALSE;
4644 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4646 FIXME("%p - stub\n", ObjectDescriptor);
4648 return TRUE;
4651 BOOL WINAPI CreateProcessAsUserA(
4652 HANDLE hToken,
4653 LPCSTR lpApplicationName,
4654 LPSTR lpCommandLine,
4655 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4656 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4657 BOOL bInheritHandles,
4658 DWORD dwCreationFlags,
4659 LPVOID lpEnvironment,
4660 LPCSTR lpCurrentDirectory,
4661 LPSTARTUPINFOA lpStartupInfo,
4662 LPPROCESS_INFORMATION lpProcessInformation )
4664 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4665 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4666 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4668 return FALSE;
4671 BOOL WINAPI CreateProcessAsUserW(
4672 HANDLE hToken,
4673 LPCWSTR lpApplicationName,
4674 LPWSTR lpCommandLine,
4675 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4676 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4677 BOOL bInheritHandles,
4678 DWORD dwCreationFlags,
4679 LPVOID lpEnvironment,
4680 LPCWSTR lpCurrentDirectory,
4681 LPSTARTUPINFOW lpStartupInfo,
4682 LPPROCESS_INFORMATION lpProcessInformation )
4684 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4685 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4686 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4687 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4689 /* We should create the process with a suspended main thread */
4690 if (!CreateProcessW (lpApplicationName,
4691 lpCommandLine,
4692 lpProcessAttributes,
4693 lpThreadAttributes,
4694 bInheritHandles,
4695 dwCreationFlags, /* CREATE_SUSPENDED */
4696 lpEnvironment,
4697 lpCurrentDirectory,
4698 lpStartupInfo,
4699 lpProcessInformation))
4701 return FALSE;
4704 return TRUE;
4707 /******************************************************************************
4708 * CreateProcessWithLogonW
4710 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4711 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4712 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4714 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4715 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4716 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4717 lpStartupInfo, lpProcessInformation);
4719 return FALSE;
4722 /******************************************************************************
4723 * DuplicateTokenEx [ADVAPI32.@]
4725 BOOL WINAPI DuplicateTokenEx(
4726 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4727 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4728 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4729 TOKEN_TYPE TokenType,
4730 PHANDLE DuplicateTokenHandle )
4732 OBJECT_ATTRIBUTES ObjectAttributes;
4734 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4735 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4737 InitializeObjectAttributes(
4738 &ObjectAttributes,
4739 NULL,
4740 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4741 NULL,
4742 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4744 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4745 dwDesiredAccess,
4746 &ObjectAttributes,
4747 ImpersonationLevel,
4748 TokenType,
4749 DuplicateTokenHandle ) );
4752 BOOL WINAPI DuplicateToken(
4753 HANDLE ExistingTokenHandle,
4754 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4755 PHANDLE DuplicateTokenHandle )
4757 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4758 NULL, ImpersonationLevel, TokenImpersonation,
4759 DuplicateTokenHandle );
4762 /******************************************************************************
4763 * ComputeStringSidSize
4765 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4767 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4769 int ctok = 0;
4770 while (*StringSid)
4772 if (*StringSid == '-')
4773 ctok++;
4774 StringSid++;
4777 if (ctok >= 3)
4778 return GetSidLengthRequired(ctok - 2);
4780 else /* String constant format - Only available in winxp and above */
4782 unsigned int i;
4784 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4785 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4786 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4789 return GetSidLengthRequired(0);
4792 /******************************************************************************
4793 * ParseStringSidToSid
4795 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4797 BOOL bret = FALSE;
4798 SID* pisid=pSid;
4800 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4801 if (!StringSid)
4803 SetLastError(ERROR_INVALID_PARAMETER);
4804 TRACE("StringSid is NULL, returning FALSE\n");
4805 return FALSE;
4808 *cBytes = ComputeStringSidSize(StringSid);
4809 if (!pisid) /* Simply compute the size */
4811 TRACE("only size requested, returning TRUE\n");
4812 return TRUE;
4815 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4817 DWORD i = 0, identAuth;
4818 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4820 StringSid += 2; /* Advance to Revision */
4821 pisid->Revision = atoiW(StringSid);
4823 if (pisid->Revision != SDDL_REVISION)
4825 TRACE("Revision %d is unknown\n", pisid->Revision);
4826 goto lend; /* ERROR_INVALID_SID */
4828 if (csubauth == 0)
4830 TRACE("SubAuthorityCount is 0\n");
4831 goto lend; /* ERROR_INVALID_SID */
4834 pisid->SubAuthorityCount = csubauth;
4836 /* Advance to identifier authority */
4837 while (*StringSid && *StringSid != '-')
4838 StringSid++;
4839 if (*StringSid == '-')
4840 StringSid++;
4842 /* MS' implementation can't handle values greater than 2^32 - 1, so
4843 * we don't either; assume most significant bytes are always 0
4845 pisid->IdentifierAuthority.Value[0] = 0;
4846 pisid->IdentifierAuthority.Value[1] = 0;
4847 identAuth = atoiW(StringSid);
4848 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4849 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4850 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4851 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4853 /* Advance to first sub authority */
4854 while (*StringSid && *StringSid != '-')
4855 StringSid++;
4856 if (*StringSid == '-')
4857 StringSid++;
4859 while (*StringSid)
4861 pisid->SubAuthority[i++] = atoiW(StringSid);
4863 while (*StringSid && *StringSid != '-')
4864 StringSid++;
4865 if (*StringSid == '-')
4866 StringSid++;
4869 if (i != pisid->SubAuthorityCount)
4870 goto lend; /* ERROR_INVALID_SID */
4872 bret = TRUE;
4874 else /* String constant format - Only available in winxp and above */
4876 unsigned int i;
4877 pisid->Revision = SDDL_REVISION;
4879 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4880 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4882 DWORD j;
4883 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4884 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4885 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4886 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4887 bret = TRUE;
4890 if (!bret)
4891 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4894 lend:
4895 if (!bret)
4896 SetLastError(ERROR_INVALID_SID);
4898 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4899 return bret;
4902 /******************************************************************************
4903 * GetNamedSecurityInfoA [ADVAPI32.@]
4905 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4906 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4907 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4908 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4910 DWORD len;
4911 LPWSTR wstr = NULL;
4912 DWORD r;
4914 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4915 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4917 if( pObjectName )
4919 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4920 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4921 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4924 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4925 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4927 HeapFree( GetProcessHeap(), 0, wstr );
4929 return r;
4932 /******************************************************************************
4933 * GetNamedSecurityInfoW [ADVAPI32.@]
4935 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4936 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4937 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4939 DWORD needed, offset;
4940 SECURITY_DESCRIPTOR_RELATIVE *relative;
4941 BYTE *buffer;
4943 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4944 group, dacl, sacl, descriptor );
4946 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4948 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4949 if (info & OWNER_SECURITY_INFORMATION)
4950 needed += sizeof(sidWorld);
4951 if (info & GROUP_SECURITY_INFORMATION)
4952 needed += sizeof(sidWorld);
4953 if (info & DACL_SECURITY_INFORMATION)
4954 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4955 if (info & SACL_SECURITY_INFORMATION)
4956 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4958 /* must be freed by caller */
4959 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4960 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4962 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4964 HeapFree( GetProcessHeap(), 0, *descriptor );
4965 return ERROR_INVALID_SECURITY_DESCR;
4968 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4969 relative->Control |= SE_SELF_RELATIVE;
4970 buffer = (BYTE *)relative;
4971 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4973 if (info & OWNER_SECURITY_INFORMATION)
4975 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4976 relative->Owner = offset;
4977 if (owner)
4978 *owner = buffer + offset;
4979 offset += sizeof(sidWorld);
4981 if (info & GROUP_SECURITY_INFORMATION)
4983 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4984 relative->Group = offset;
4985 if (group)
4986 *group = buffer + offset;
4987 offset += sizeof(sidWorld);
4989 if (info & DACL_SECURITY_INFORMATION)
4991 relative->Control |= SE_DACL_PRESENT;
4992 GetWorldAccessACL( (PACL)(buffer + offset) );
4993 relative->Dacl = offset;
4994 if (dacl)
4995 *dacl = (PACL)(buffer + offset);
4996 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4998 if (info & SACL_SECURITY_INFORMATION)
5000 relative->Control |= SE_SACL_PRESENT;
5001 GetWorldAccessACL( (PACL)(buffer + offset) );
5002 relative->Sacl = offset;
5003 if (sacl)
5004 *sacl = (PACL)(buffer + offset);
5006 return ERROR_SUCCESS;
5009 /******************************************************************************
5010 * DecryptFileW [ADVAPI32.@]
5012 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5014 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5015 return TRUE;
5018 /******************************************************************************
5019 * DecryptFileA [ADVAPI32.@]
5021 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5023 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5024 return TRUE;
5027 /******************************************************************************
5028 * EncryptFileW [ADVAPI32.@]
5030 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5032 FIXME("%s\n", debugstr_w(lpFileName));
5033 return TRUE;
5036 /******************************************************************************
5037 * EncryptFileA [ADVAPI32.@]
5039 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5041 FIXME("%s\n", debugstr_a(lpFileName));
5042 return TRUE;
5045 /******************************************************************************
5046 * FileEncryptionStatusW [ADVAPI32.@]
5048 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5050 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5051 if (!lpStatus)
5052 return FALSE;
5053 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5054 return TRUE;
5057 /******************************************************************************
5058 * FileEncryptionStatusA [ADVAPI32.@]
5060 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5062 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5063 if (!lpStatus)
5064 return FALSE;
5065 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5066 return TRUE;
5069 /******************************************************************************
5070 * SetSecurityInfo [ADVAPI32.@]
5072 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5073 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5074 PSID psidGroup, PACL pDacl, PACL pSacl) {
5075 FIXME("stub\n");
5076 return ERROR_SUCCESS;