winealsa.drv/dsound: Handle underruns better.
[wine/testsucceed.git] / dlls / advapi32 / security.c
blobef9ce6ea353e4ffebd462d3f234b5b81c0f9bad4
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;
2319 FIXME( "(%p)\n", hToken );
2321 if (!GetTokenInformation( hToken, TokenType, &Type,
2322 sizeof(TOKEN_TYPE), &size ))
2323 return FALSE;
2325 if (Type == TokenPrimary)
2327 OBJECT_ATTRIBUTES ObjectAttributes;
2329 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2331 Status = NtDuplicateToken( hToken,
2332 TOKEN_IMPERSONATE | TOKEN_QUERY,
2333 &ObjectAttributes,
2334 SecurityImpersonation,
2335 TokenImpersonation,
2336 &ImpersonationToken );
2337 if (Status != STATUS_SUCCESS)
2339 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2340 SetLastError( RtlNtStatusToDosError( Status ) );
2341 return FALSE;
2344 else
2345 ImpersonationToken = hToken;
2347 Status = NtSetInformationThread( GetCurrentThread(),
2348 ThreadImpersonationToken,
2349 &ImpersonationToken,
2350 sizeof(ImpersonationToken) );
2352 if (Type == TokenPrimary)
2353 NtClose( ImpersonationToken );
2355 if (Status != STATUS_SUCCESS)
2357 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2358 SetLastError( RtlNtStatusToDosError( Status ) );
2359 return FALSE;
2362 return TRUE;
2365 /******************************************************************************
2366 * AccessCheck [ADVAPI32.@]
2368 BOOL WINAPI
2369 AccessCheck(
2370 PSECURITY_DESCRIPTOR SecurityDescriptor,
2371 HANDLE ClientToken,
2372 DWORD DesiredAccess,
2373 PGENERIC_MAPPING GenericMapping,
2374 PPRIVILEGE_SET PrivilegeSet,
2375 LPDWORD PrivilegeSetLength,
2376 LPDWORD GrantedAccess,
2377 LPBOOL AccessStatus)
2379 NTSTATUS access_status;
2380 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2381 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2382 GrantedAccess, &access_status) );
2383 if (ret) *AccessStatus = set_ntstatus( access_status );
2384 return ret;
2388 /******************************************************************************
2389 * AccessCheckByType [ADVAPI32.@]
2391 BOOL WINAPI AccessCheckByType(
2392 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2393 PSID PrincipalSelfSid,
2394 HANDLE ClientToken,
2395 DWORD DesiredAccess,
2396 POBJECT_TYPE_LIST ObjectTypeList,
2397 DWORD ObjectTypeListLength,
2398 PGENERIC_MAPPING GenericMapping,
2399 PPRIVILEGE_SET PrivilegeSet,
2400 LPDWORD PrivilegeSetLength,
2401 LPDWORD GrantedAccess,
2402 LPBOOL AccessStatus)
2404 FIXME("stub\n");
2406 *AccessStatus = TRUE;
2408 return !*AccessStatus;
2411 /******************************************************************************
2412 * MapGenericMask [ADVAPI32.@]
2414 * Maps generic access rights into specific access rights according to the
2415 * supplied mapping.
2417 * PARAMS
2418 * AccessMask [I/O] Access rights.
2419 * GenericMapping [I] The mapping between generic and specific rights.
2421 * RETURNS
2422 * Nothing.
2424 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2426 RtlMapGenericMask( AccessMask, GenericMapping );
2429 /*************************************************************************
2430 * SetKernelObjectSecurity [ADVAPI32.@]
2432 BOOL WINAPI SetKernelObjectSecurity (
2433 IN HANDLE Handle,
2434 IN SECURITY_INFORMATION SecurityInformation,
2435 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2437 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2441 /******************************************************************************
2442 * AddAuditAccessAce [ADVAPI32.@]
2444 BOOL WINAPI AddAuditAccessAce(
2445 IN OUT PACL pAcl,
2446 IN DWORD dwAceRevision,
2447 IN DWORD dwAccessMask,
2448 IN PSID pSid,
2449 IN BOOL bAuditSuccess,
2450 IN BOOL bAuditFailure)
2452 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2453 bAuditSuccess, bAuditFailure) );
2456 /******************************************************************************
2457 * AddAuditAccessAce [ADVAPI32.@]
2459 BOOL WINAPI AddAuditAccessAceEx(
2460 IN OUT PACL pAcl,
2461 IN DWORD dwAceRevision,
2462 IN DWORD dwAceFlags,
2463 IN DWORD dwAccessMask,
2464 IN PSID pSid,
2465 IN BOOL bAuditSuccess,
2466 IN BOOL bAuditFailure)
2468 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2469 bAuditSuccess, bAuditFailure) );
2472 /******************************************************************************
2473 * LookupAccountNameA [ADVAPI32.@]
2475 BOOL WINAPI
2476 LookupAccountNameA(
2477 IN LPCSTR system,
2478 IN LPCSTR account,
2479 OUT PSID sid,
2480 OUT LPDWORD cbSid,
2481 LPSTR ReferencedDomainName,
2482 IN OUT LPDWORD cbReferencedDomainName,
2483 OUT PSID_NAME_USE name_use )
2485 BOOL ret;
2486 UNICODE_STRING lpSystemW;
2487 UNICODE_STRING lpAccountW;
2488 LPWSTR lpReferencedDomainNameW = NULL;
2490 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2491 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2493 if (ReferencedDomainName)
2494 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2496 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2497 cbReferencedDomainName, name_use);
2499 if (ret && lpReferencedDomainNameW)
2501 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2502 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2505 RtlFreeUnicodeString(&lpSystemW);
2506 RtlFreeUnicodeString(&lpAccountW);
2507 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2509 return ret;
2512 /******************************************************************************
2513 * LookupAccountNameW [ADVAPI32.@]
2515 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2516 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2517 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2519 /* Default implementation: Always return a default SID */
2520 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2521 BOOL ret;
2522 PSID pSid;
2523 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2524 unsigned int i;
2526 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2527 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2529 for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2531 if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2533 if (*cchReferencedDomainName)
2534 *ReferencedDomainName = '\0';
2535 *cchReferencedDomainName = 0;
2536 *peUse = SidTypeWellKnownGroup;
2537 return CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, Sid, cbSid);
2541 ret = AllocateAndInitializeSid(&identifierAuthority,
2543 SECURITY_BUILTIN_DOMAIN_RID,
2544 DOMAIN_ALIAS_RID_ADMINS,
2545 0, 0, 0, 0, 0, 0,
2546 &pSid);
2548 if (!ret)
2549 return FALSE;
2551 if (!RtlValidSid(pSid))
2553 FreeSid(pSid);
2554 return FALSE;
2557 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2558 CopySid(*cbSid, Sid, pSid);
2559 if (*cbSid < GetLengthSid(pSid))
2561 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2562 ret = FALSE;
2564 *cbSid = GetLengthSid(pSid);
2566 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2567 strcpyW(ReferencedDomainName, dm);
2569 if (*cchReferencedDomainName <= strlenW(dm))
2571 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2572 ret = FALSE;
2575 *cchReferencedDomainName = strlenW(dm)+1;
2577 FreeSid(pSid);
2579 return ret;
2582 /******************************************************************************
2583 * PrivilegeCheck [ADVAPI32.@]
2585 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2587 BOOL ret;
2588 BOOLEAN Result;
2590 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2592 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2593 if (ret)
2594 *pfResult = Result;
2595 return ret;
2598 /******************************************************************************
2599 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2601 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2602 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2603 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2604 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2606 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2607 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2608 SecurityDescriptor, DesiredAccess, GenericMapping,
2609 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2610 return TRUE;
2613 /******************************************************************************
2614 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2616 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2617 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2618 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2619 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2621 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2622 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2623 SecurityDescriptor, DesiredAccess, GenericMapping,
2624 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2625 return TRUE;
2628 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2630 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2632 return TRUE;
2635 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2637 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2639 return TRUE;
2642 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2644 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2646 return TRUE;
2649 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2650 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2651 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2652 LPBOOL GenerateOnClose)
2654 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2655 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2656 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2657 GenerateOnClose);
2659 return TRUE;
2662 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2663 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2664 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2665 LPBOOL GenerateOnClose)
2667 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2668 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2669 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2670 GenerateOnClose);
2672 return TRUE;
2675 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2676 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2678 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2679 DesiredAccess, Privileges, AccessGranted);
2681 return TRUE;
2684 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2685 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2687 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2688 DesiredAccess, Privileges, AccessGranted);
2690 return TRUE;
2693 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2694 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2696 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2697 ClientToken, Privileges, AccessGranted);
2699 return TRUE;
2702 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2703 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2705 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2706 ClientToken, Privileges, AccessGranted);
2708 return TRUE;
2711 /******************************************************************************
2712 * GetSecurityInfo [ADVAPI32.@]
2714 * Retrieves a copy of the security descriptor associated with an object.
2716 * PARAMS
2717 * hObject [I] A handle for the object.
2718 * ObjectType [I] The type of object.
2719 * SecurityInfo [I] A bitmask indicating what info to retrieve.
2720 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
2721 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
2722 * ppDacl [O] If non-null, receives a pointer to the DACL.
2723 * ppSacl [O] If non-null, receives a pointer to the SACL.
2724 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2725 * which must be freed with LocalFree.
2727 * RETURNS
2728 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2730 DWORD WINAPI GetSecurityInfo(
2731 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2732 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2733 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2734 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2737 PSECURITY_DESCRIPTOR sd;
2738 NTSTATUS status;
2739 ULONG n1, n2;
2740 BOOL present, defaulted;
2742 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2743 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2744 return RtlNtStatusToDosError(status);
2746 sd = LocalAlloc(0, n1);
2747 if (!sd)
2748 return ERROR_NOT_ENOUGH_MEMORY;
2750 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2751 if (status != STATUS_SUCCESS)
2753 LocalFree(sd);
2754 return RtlNtStatusToDosError(status);
2757 if (ppsidOwner)
2759 *ppsidOwner = NULL;
2760 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2762 if (ppsidGroup)
2764 *ppsidGroup = NULL;
2765 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2767 if (ppDacl)
2769 *ppDacl = NULL;
2770 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2772 if (ppSacl)
2774 *ppSacl = NULL;
2775 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2777 if (ppSecurityDescriptor)
2778 *ppSecurityDescriptor = sd;
2780 return ERROR_SUCCESS;
2783 /******************************************************************************
2784 * GetSecurityInfoExW [ADVAPI32.@]
2786 DWORD WINAPI GetSecurityInfoExW(
2787 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2788 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2789 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2790 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2793 FIXME("stub!\n");
2794 return ERROR_BAD_PROVIDER;
2797 /******************************************************************************
2798 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2800 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2801 LPSTR pTrusteeName, DWORD AccessPermissions,
2802 ACCESS_MODE AccessMode, DWORD Inheritance )
2804 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2805 AccessPermissions, AccessMode, Inheritance);
2807 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2808 pExplicitAccess->grfAccessMode = AccessMode;
2809 pExplicitAccess->grfInheritance = Inheritance;
2811 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2812 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2813 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2814 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2815 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2818 /******************************************************************************
2819 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2821 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2822 LPWSTR pTrusteeName, DWORD AccessPermissions,
2823 ACCESS_MODE AccessMode, DWORD Inheritance )
2825 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2826 AccessPermissions, AccessMode, Inheritance);
2828 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2829 pExplicitAccess->grfAccessMode = AccessMode;
2830 pExplicitAccess->grfInheritance = Inheritance;
2832 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2833 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2834 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2835 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2836 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2839 /******************************************************************************
2840 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2842 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2843 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2844 LPSTR InheritedObjectTypeName, LPSTR Name )
2846 DWORD ObjectsPresent = 0;
2848 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2849 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2851 /* Fill the OBJECTS_AND_NAME structure */
2852 pObjName->ObjectType = ObjectType;
2853 if (ObjectTypeName != NULL)
2855 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2858 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2859 if (InheritedObjectTypeName != NULL)
2861 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2864 pObjName->ObjectsPresent = ObjectsPresent;
2865 pObjName->ptstrName = Name;
2867 /* Fill the TRUSTEE structure */
2868 pTrustee->pMultipleTrustee = NULL;
2869 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2870 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2871 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2872 pTrustee->ptstrName = (LPSTR)pObjName;
2875 /******************************************************************************
2876 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2878 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2879 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2880 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2882 DWORD ObjectsPresent = 0;
2884 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2885 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2887 /* Fill the OBJECTS_AND_NAME structure */
2888 pObjName->ObjectType = ObjectType;
2889 if (ObjectTypeName != NULL)
2891 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2894 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2895 if (InheritedObjectTypeName != NULL)
2897 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2900 pObjName->ObjectsPresent = ObjectsPresent;
2901 pObjName->ptstrName = Name;
2903 /* Fill the TRUSTEE structure */
2904 pTrustee->pMultipleTrustee = NULL;
2905 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2906 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2907 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2908 pTrustee->ptstrName = (LPWSTR)pObjName;
2911 /******************************************************************************
2912 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2914 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2915 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2917 DWORD ObjectsPresent = 0;
2919 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2921 /* Fill the OBJECTS_AND_SID structure */
2922 if (pObjectGuid != NULL)
2924 pObjSid->ObjectTypeGuid = *pObjectGuid;
2925 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2927 else
2929 ZeroMemory(&pObjSid->ObjectTypeGuid,
2930 sizeof(GUID));
2933 if (pInheritedObjectGuid != NULL)
2935 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2936 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2938 else
2940 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2941 sizeof(GUID));
2944 pObjSid->ObjectsPresent = ObjectsPresent;
2945 pObjSid->pSid = pSid;
2947 /* Fill the TRUSTEE structure */
2948 pTrustee->pMultipleTrustee = NULL;
2949 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2950 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2951 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2952 pTrustee->ptstrName = (LPSTR) pObjSid;
2955 /******************************************************************************
2956 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2958 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2959 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2961 DWORD ObjectsPresent = 0;
2963 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2965 /* Fill the OBJECTS_AND_SID structure */
2966 if (pObjectGuid != NULL)
2968 pObjSid->ObjectTypeGuid = *pObjectGuid;
2969 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2971 else
2973 ZeroMemory(&pObjSid->ObjectTypeGuid,
2974 sizeof(GUID));
2977 if (pInheritedObjectGuid != NULL)
2979 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2980 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2982 else
2984 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2985 sizeof(GUID));
2988 pObjSid->ObjectsPresent = ObjectsPresent;
2989 pObjSid->pSid = pSid;
2991 /* Fill the TRUSTEE structure */
2992 pTrustee->pMultipleTrustee = NULL;
2993 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2994 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2995 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2996 pTrustee->ptstrName = (LPWSTR) pObjSid;
2999 /******************************************************************************
3000 * BuildTrusteeWithSidA [ADVAPI32.@]
3002 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3004 TRACE("%p %p\n", pTrustee, pSid);
3006 pTrustee->pMultipleTrustee = NULL;
3007 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3008 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3009 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3010 pTrustee->ptstrName = (LPSTR) pSid;
3013 /******************************************************************************
3014 * BuildTrusteeWithSidW [ADVAPI32.@]
3016 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3018 TRACE("%p %p\n", pTrustee, pSid);
3020 pTrustee->pMultipleTrustee = NULL;
3021 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3022 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3023 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3024 pTrustee->ptstrName = (LPWSTR) pSid;
3027 /******************************************************************************
3028 * BuildTrusteeWithNameA [ADVAPI32.@]
3030 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3032 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3034 pTrustee->pMultipleTrustee = NULL;
3035 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3036 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3037 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3038 pTrustee->ptstrName = name;
3041 /******************************************************************************
3042 * BuildTrusteeWithNameW [ADVAPI32.@]
3044 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3046 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3048 pTrustee->pMultipleTrustee = NULL;
3049 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3050 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3051 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3052 pTrustee->ptstrName = name;
3055 /******************************************************************************
3056 * GetTrusteeFormA [ADVAPI32.@]
3058 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3060 TRACE("(%p)\n", pTrustee);
3062 if (!pTrustee)
3063 return TRUSTEE_BAD_FORM;
3065 return pTrustee->TrusteeForm;
3068 /******************************************************************************
3069 * GetTrusteeFormW [ADVAPI32.@]
3071 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3073 TRACE("(%p)\n", pTrustee);
3075 if (!pTrustee)
3076 return TRUSTEE_BAD_FORM;
3078 return pTrustee->TrusteeForm;
3081 /******************************************************************************
3082 * GetTrusteeNameA [ADVAPI32.@]
3084 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3086 TRACE("(%p)\n", pTrustee);
3088 if (!pTrustee)
3089 return NULL;
3091 return pTrustee->ptstrName;
3094 /******************************************************************************
3095 * GetTrusteeNameW [ADVAPI32.@]
3097 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3099 TRACE("(%p)\n", pTrustee);
3101 if (!pTrustee)
3102 return NULL;
3104 return pTrustee->ptstrName;
3107 /******************************************************************************
3108 * GetTrusteeTypeA [ADVAPI32.@]
3110 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3112 TRACE("(%p)\n", pTrustee);
3114 if (!pTrustee)
3115 return TRUSTEE_IS_UNKNOWN;
3117 return pTrustee->TrusteeType;
3120 /******************************************************************************
3121 * GetTrusteeTypeW [ADVAPI32.@]
3123 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3125 TRACE("(%p)\n", pTrustee);
3127 if (!pTrustee)
3128 return TRUSTEE_IS_UNKNOWN;
3130 return pTrustee->TrusteeType;
3133 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3134 DWORD nAclInformationLength,
3135 ACL_INFORMATION_CLASS dwAclInformationClass )
3137 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3138 nAclInformationLength, dwAclInformationClass);
3140 return TRUE;
3143 /******************************************************************************
3144 * SetEntriesInAclA [ADVAPI32.@]
3146 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3147 PACL OldAcl, PACL* NewAcl )
3149 FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3150 *NewAcl = NULL;
3151 return ERROR_SUCCESS;
3154 /******************************************************************************
3155 * SetEntriesInAclW [ADVAPI32.@]
3157 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3158 PACL OldAcl, PACL* NewAcl )
3160 ULONG i;
3161 PSID *ppsid;
3162 DWORD ret = ERROR_SUCCESS;
3163 DWORD acl_size = sizeof(ACL);
3164 NTSTATUS status;
3166 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3168 *NewAcl = NULL;
3170 if (!count && !OldAcl)
3171 return ERROR_SUCCESS;
3173 /* allocate array of maximum sized sids allowed */
3174 ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3175 if (!ppsid)
3176 return ERROR_OUTOFMEMORY;
3178 for (i = 0; i < count; i++)
3180 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3182 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3183 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3184 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3185 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3186 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3187 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3188 pEntries[i].Trustee.ptstrName);
3190 if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3192 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3193 ret = ERROR_INVALID_PARAMETER;
3194 goto exit;
3197 switch (pEntries[i].Trustee.TrusteeForm)
3199 case TRUSTEE_IS_SID:
3200 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3201 ppsid[i], pEntries[i].Trustee.ptstrName))
3203 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3204 ret = ERROR_INVALID_PARAMETER;
3205 goto exit;
3207 break;
3208 case TRUSTEE_IS_NAME:
3210 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3211 DWORD domain_size = 0;
3212 SID_NAME_USE use;
3213 if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3215 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3216 ret = ERROR_INVALID_PARAMETER;
3217 goto exit;
3219 break;
3221 case TRUSTEE_IS_OBJECTS_AND_SID:
3222 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3223 break;
3224 case TRUSTEE_IS_OBJECTS_AND_NAME:
3225 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3226 break;
3227 default:
3228 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3229 ret = ERROR_INVALID_PARAMETER;
3230 goto exit;
3233 /* Note: we overestimate the ACL size here as a tradeoff between
3234 * instructions (simplicity) and memory */
3235 switch (pEntries[i].grfAccessMode)
3237 case GRANT_ACCESS:
3238 case SET_ACCESS:
3239 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3240 break;
3241 case DENY_ACCESS:
3242 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3243 break;
3244 case SET_AUDIT_SUCCESS:
3245 case SET_AUDIT_FAILURE:
3246 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3247 break;
3248 case REVOKE_ACCESS:
3249 break;
3250 default:
3251 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3252 ret = ERROR_INVALID_PARAMETER;
3253 goto exit;
3257 if (OldAcl)
3259 ACL_SIZE_INFORMATION size_info;
3261 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3262 if (status != STATUS_SUCCESS)
3264 ret = RtlNtStatusToDosError(status);
3265 goto exit;
3267 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3270 *NewAcl = LocalAlloc(0, acl_size);
3271 if (!*NewAcl)
3273 ret = ERROR_OUTOFMEMORY;
3274 goto exit;
3277 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3278 if (status != STATUS_SUCCESS)
3280 ret = RtlNtStatusToDosError(status);
3281 goto exit;
3284 for (i = 0; i < count; i++)
3286 switch (pEntries[i].grfAccessMode)
3288 case GRANT_ACCESS:
3289 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3290 pEntries[i].grfInheritance,
3291 pEntries[i].grfAccessPermissions,
3292 ppsid[i]);
3293 break;
3294 case SET_ACCESS:
3296 ULONG j;
3297 BOOL add = TRUE;
3298 if (OldAcl)
3300 for (j = 0; ; j++)
3302 const ACE_HEADER *existing_ace_header;
3303 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3304 if (status != STATUS_SUCCESS)
3305 break;
3306 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3307 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3308 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3310 add = FALSE;
3311 break;
3315 if (add)
3316 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3317 pEntries[i].grfInheritance,
3318 pEntries[i].grfAccessPermissions,
3319 ppsid[i]);
3320 break;
3322 case DENY_ACCESS:
3323 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3324 pEntries[i].grfInheritance,
3325 pEntries[i].grfAccessPermissions,
3326 ppsid[i]);
3327 break;
3328 case SET_AUDIT_SUCCESS:
3329 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3330 pEntries[i].grfInheritance,
3331 pEntries[i].grfAccessPermissions,
3332 ppsid[i], TRUE, FALSE);
3333 break;
3334 case SET_AUDIT_FAILURE:
3335 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3336 pEntries[i].grfInheritance,
3337 pEntries[i].grfAccessPermissions,
3338 ppsid[i], FALSE, TRUE);
3339 break;
3340 default:
3341 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3345 if (OldAcl)
3347 for (i = 0; ; i++)
3349 BOOL add = TRUE;
3350 ULONG j;
3351 const ACE_HEADER *old_ace_header;
3352 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3353 if (status != STATUS_SUCCESS) break;
3354 for (j = 0; j < count; j++)
3356 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3357 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3358 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3360 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3361 add = FALSE;
3362 break;
3364 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3366 switch (old_ace_header->AceType)
3368 case ACCESS_ALLOWED_ACE_TYPE:
3369 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3370 add = FALSE;
3371 break;
3372 case ACCESS_DENIED_ACE_TYPE:
3373 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3374 add = FALSE;
3375 break;
3376 case SYSTEM_AUDIT_ACE_TYPE:
3377 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3378 add = FALSE;
3379 break;
3380 case SYSTEM_ALARM_ACE_TYPE:
3381 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3382 add = FALSE;
3383 break;
3384 default:
3385 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3388 if (!add)
3389 break;
3392 if (add)
3393 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3394 if (status != STATUS_SUCCESS)
3396 WARN("RtlAddAce failed with error 0x%08x\n", status);
3397 ret = RtlNtStatusToDosError(status);
3398 break;
3403 exit:
3404 HeapFree(GetProcessHeap(), 0, ppsid);
3405 return ret;
3408 /******************************************************************************
3409 * SetNamedSecurityInfoA [ADVAPI32.@]
3411 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3412 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3413 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3415 DWORD len;
3416 LPWSTR wstr = NULL;
3417 DWORD r;
3419 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3420 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3422 if( pObjectName )
3424 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3425 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3426 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3429 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3430 psidGroup, pDacl, pSacl );
3432 HeapFree( GetProcessHeap(), 0, wstr );
3434 return r;
3437 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3438 PSECURITY_DESCRIPTOR ModificationDescriptor,
3439 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3440 PGENERIC_MAPPING GenericMapping,
3441 HANDLE Token )
3443 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3444 ObjectsSecurityDescriptor, GenericMapping, Token);
3446 return TRUE;
3449 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3451 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3454 /******************************************************************************
3455 * AreAnyAccessesGranted [ADVAPI32.@]
3457 * Determines whether or not any of a set of specified access permissions have
3458 * been granted or not.
3460 * PARAMS
3461 * GrantedAccess [I] The permissions that have been granted.
3462 * DesiredAccess [I] The permissions that you want to have.
3464 * RETURNS
3465 * Nonzero if any of the permissions have been granted, zero if none of the
3466 * permissions have been granted.
3469 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3471 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3474 /******************************************************************************
3475 * SetNamedSecurityInfoW [ADVAPI32.@]
3477 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3478 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3479 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3481 FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3482 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3483 return ERROR_SUCCESS;
3486 /******************************************************************************
3487 * GetExplicitEntriesFromAclA [ADVAPI32.@]
3489 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3490 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3492 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3493 return ERROR_CALL_NOT_IMPLEMENTED;
3496 /******************************************************************************
3497 * GetExplicitEntriesFromAclW [ADVAPI32.@]
3499 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3500 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3502 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3503 return ERROR_CALL_NOT_IMPLEMENTED;
3506 /******************************************************************************
3507 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3509 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3510 PACCESS_MASK pFailedAuditRights)
3512 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3513 return ERROR_CALL_NOT_IMPLEMENTED;
3517 /******************************************************************************
3518 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3520 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3521 PACCESS_MASK pFailedAuditRights)
3523 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3524 return ERROR_CALL_NOT_IMPLEMENTED;
3528 /******************************************************************************
3529 * ParseAclStringFlags
3531 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3533 DWORD flags = 0;
3534 LPCWSTR szAcl = *StringAcl;
3536 while (*szAcl != '(')
3538 if (*szAcl == 'P')
3540 flags |= SE_DACL_PROTECTED;
3542 else if (*szAcl == 'A')
3544 szAcl++;
3545 if (*szAcl == 'R')
3546 flags |= SE_DACL_AUTO_INHERIT_REQ;
3547 else if (*szAcl == 'I')
3548 flags |= SE_DACL_AUTO_INHERITED;
3550 szAcl++;
3553 *StringAcl = szAcl;
3554 return flags;
3557 /******************************************************************************
3558 * ParseAceStringType
3560 static const ACEFLAG AceType[] =
3562 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
3563 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
3564 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3565 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
3567 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3568 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
3569 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
3570 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3572 { NULL, 0 },
3575 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3577 UINT len = 0;
3578 LPCWSTR szAcl = *StringAcl;
3579 const ACEFLAG *lpaf = AceType;
3581 while (lpaf->wstr &&
3582 (len = strlenW(lpaf->wstr)) &&
3583 strncmpW(lpaf->wstr, szAcl, len))
3584 lpaf++;
3586 if (!lpaf->wstr)
3587 return 0;
3589 *StringAcl += len;
3590 return lpaf->value;
3594 /******************************************************************************
3595 * ParseAceStringFlags
3597 static const ACEFLAG AceFlags[] =
3599 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3600 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3601 { SDDL_INHERITED, INHERITED_ACE },
3602 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3603 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3604 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3605 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3606 { NULL, 0 },
3609 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3611 UINT len = 0;
3612 BYTE flags = 0;
3613 LPCWSTR szAcl = *StringAcl;
3615 while (*szAcl != ';')
3617 const ACEFLAG *lpaf = AceFlags;
3619 while (lpaf->wstr &&
3620 (len = strlenW(lpaf->wstr)) &&
3621 strncmpW(lpaf->wstr, szAcl, len))
3622 lpaf++;
3624 if (!lpaf->wstr)
3625 return 0;
3627 flags |= lpaf->value;
3628 szAcl += len;
3631 *StringAcl = szAcl;
3632 return flags;
3636 /******************************************************************************
3637 * ParseAceStringRights
3639 static const ACEFLAG AceRights[] =
3641 { SDDL_GENERIC_ALL, GENERIC_ALL },
3642 { SDDL_GENERIC_READ, GENERIC_READ },
3643 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3644 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3646 { SDDL_READ_CONTROL, READ_CONTROL },
3647 { SDDL_STANDARD_DELETE, DELETE },
3648 { SDDL_WRITE_DAC, WRITE_DAC },
3649 { SDDL_WRITE_OWNER, WRITE_OWNER },
3651 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
3652 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
3653 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
3654 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
3655 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
3656 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
3657 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
3658 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
3659 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
3661 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
3662 { SDDL_FILE_READ, FILE_GENERIC_READ },
3663 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
3664 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
3666 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
3667 { SDDL_KEY_READ, KEY_READ },
3668 { SDDL_KEY_WRITE, KEY_WRITE },
3669 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
3670 { NULL, 0 },
3673 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3675 UINT len = 0;
3676 DWORD rights = 0;
3677 LPCWSTR szAcl = *StringAcl;
3679 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3681 LPCWSTR p = szAcl;
3683 while (*p && *p != ';')
3684 p++;
3686 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3688 rights = strtoulW(szAcl, NULL, 16);
3689 szAcl = p;
3691 else
3692 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3694 else
3696 while (*szAcl != ';')
3698 const ACEFLAG *lpaf = AceRights;
3700 while (lpaf->wstr &&
3701 (len = strlenW(lpaf->wstr)) &&
3702 strncmpW(lpaf->wstr, szAcl, len))
3704 lpaf++;
3707 if (!lpaf->wstr)
3708 return 0;
3710 rights |= lpaf->value;
3711 szAcl += len;
3715 *StringAcl = szAcl;
3716 return rights;
3720 /******************************************************************************
3721 * ParseStringAclToAcl
3723 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3725 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3726 PACL pAcl, LPDWORD cBytes)
3728 DWORD val;
3729 DWORD sidlen;
3730 DWORD length = sizeof(ACL);
3731 DWORD acesize = 0;
3732 DWORD acecount = 0;
3733 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3735 TRACE("%s\n", debugstr_w(StringAcl));
3737 if (!StringAcl)
3738 return FALSE;
3740 if (pAcl) /* pAce is only useful if we're setting values */
3741 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3743 /* Parse ACL flags */
3744 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3746 /* Parse ACE */
3747 while (*StringAcl == '(')
3749 StringAcl++;
3751 /* Parse ACE type */
3752 val = ParseAceStringType(&StringAcl);
3753 if (pAce)
3754 pAce->Header.AceType = (BYTE) val;
3755 if (*StringAcl != ';')
3756 goto lerr;
3757 StringAcl++;
3759 /* Parse ACE flags */
3760 val = ParseAceStringFlags(&StringAcl);
3761 if (pAce)
3762 pAce->Header.AceFlags = (BYTE) val;
3763 if (*StringAcl != ';')
3764 goto lerr;
3765 StringAcl++;
3767 /* Parse ACE rights */
3768 val = ParseAceStringRights(&StringAcl);
3769 if (pAce)
3770 pAce->Mask = val;
3771 if (*StringAcl != ';')
3772 goto lerr;
3773 StringAcl++;
3775 /* Parse ACE object guid */
3776 if (*StringAcl != ';')
3778 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3779 goto lerr;
3781 StringAcl++;
3783 /* Parse ACE inherit object guid */
3784 if (*StringAcl != ';')
3786 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3787 goto lerr;
3789 StringAcl++;
3791 /* Parse ACE account sid */
3792 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3794 while (*StringAcl && *StringAcl != ')')
3795 StringAcl++;
3798 if (*StringAcl != ')')
3799 goto lerr;
3800 StringAcl++;
3802 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3803 length += acesize;
3804 if (pAce)
3806 pAce->Header.AceSize = acesize;
3807 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3809 acecount++;
3812 *cBytes = length;
3814 if (length > 0xffff)
3816 ERR("ACL too large\n");
3817 goto lerr;
3820 if (pAcl)
3822 pAcl->AclRevision = ACL_REVISION;
3823 pAcl->Sbz1 = 0;
3824 pAcl->AclSize = length;
3825 pAcl->AceCount = acecount++;
3826 pAcl->Sbz2 = 0;
3828 return TRUE;
3830 lerr:
3831 WARN("Invalid ACE string format\n");
3832 return FALSE;
3836 /******************************************************************************
3837 * ParseStringSecurityDescriptorToSecurityDescriptor
3839 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3840 LPCWSTR StringSecurityDescriptor,
3841 SECURITY_DESCRIPTOR* SecurityDescriptor,
3842 LPDWORD cBytes)
3844 BOOL bret = FALSE;
3845 WCHAR toktype;
3846 WCHAR tok[MAX_PATH];
3847 LPCWSTR lptoken;
3848 LPBYTE lpNext = NULL;
3849 DWORD len;
3851 *cBytes = sizeof(SECURITY_DESCRIPTOR);
3853 if (SecurityDescriptor)
3854 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3856 while (*StringSecurityDescriptor)
3858 toktype = *StringSecurityDescriptor;
3860 /* Expect char identifier followed by ':' */
3861 StringSecurityDescriptor++;
3862 if (*StringSecurityDescriptor != ':')
3864 SetLastError(ERROR_INVALID_PARAMETER);
3865 goto lend;
3867 StringSecurityDescriptor++;
3869 /* Extract token */
3870 lptoken = StringSecurityDescriptor;
3871 while (*lptoken && *lptoken != ':')
3872 lptoken++;
3874 if (*lptoken)
3875 lptoken--;
3877 len = lptoken - StringSecurityDescriptor;
3878 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3879 tok[len] = 0;
3881 switch (toktype)
3883 case 'O':
3885 DWORD bytes;
3887 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3888 goto lend;
3890 if (SecurityDescriptor)
3892 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3893 lpNext += bytes; /* Advance to next token */
3896 *cBytes += bytes;
3898 break;
3901 case 'G':
3903 DWORD bytes;
3905 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3906 goto lend;
3908 if (SecurityDescriptor)
3910 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3911 lpNext += bytes; /* Advance to next token */
3914 *cBytes += bytes;
3916 break;
3919 case 'D':
3921 DWORD flags;
3922 DWORD bytes;
3924 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3925 goto lend;
3927 if (SecurityDescriptor)
3929 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3930 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3931 lpNext += bytes; /* Advance to next token */
3934 *cBytes += bytes;
3936 break;
3939 case 'S':
3941 DWORD flags;
3942 DWORD bytes;
3944 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3945 goto lend;
3947 if (SecurityDescriptor)
3949 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3950 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3951 lpNext += bytes; /* Advance to next token */
3954 *cBytes += bytes;
3956 break;
3959 default:
3960 FIXME("Unknown token\n");
3961 SetLastError(ERROR_INVALID_PARAMETER);
3962 goto lend;
3965 StringSecurityDescriptor = lptoken;
3968 bret = TRUE;
3970 lend:
3971 return bret;
3974 /******************************************************************************
3975 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3977 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3978 LPCSTR StringSecurityDescriptor,
3979 DWORD StringSDRevision,
3980 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3981 PULONG SecurityDescriptorSize)
3983 UINT len;
3984 BOOL ret = FALSE;
3985 LPWSTR StringSecurityDescriptorW;
3987 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3988 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3990 if (StringSecurityDescriptorW)
3992 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3994 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3995 StringSDRevision, SecurityDescriptor,
3996 SecurityDescriptorSize);
3997 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4000 return ret;
4003 /******************************************************************************
4004 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4006 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4007 LPCWSTR StringSecurityDescriptor,
4008 DWORD StringSDRevision,
4009 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4010 PULONG SecurityDescriptorSize)
4012 DWORD cBytes;
4013 SECURITY_DESCRIPTOR* psd;
4014 BOOL bret = FALSE;
4016 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4018 if (GetVersion() & 0x80000000)
4020 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4021 goto lend;
4023 else if (StringSDRevision != SID_REVISION)
4025 SetLastError(ERROR_UNKNOWN_REVISION);
4026 goto lend;
4029 /* Compute security descriptor length */
4030 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4031 NULL, &cBytes))
4032 goto lend;
4034 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4035 GMEM_ZEROINIT, cBytes);
4036 if (!psd) goto lend;
4038 psd->Revision = SID_REVISION;
4039 psd->Control |= SE_SELF_RELATIVE;
4041 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4042 psd, &cBytes))
4044 LocalFree(psd);
4045 goto lend;
4048 if (SecurityDescriptorSize)
4049 *SecurityDescriptorSize = cBytes;
4051 bret = TRUE;
4053 lend:
4054 TRACE(" ret=%d\n", bret);
4055 return bret;
4058 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4060 if (cch == -1)
4061 cch = strlenW(string);
4063 if (plen)
4064 *plen += cch;
4066 if (pwptr)
4068 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4069 *pwptr += cch;
4073 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4075 DWORD i;
4076 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4077 WCHAR subauthfmt[] = { '-','%','u',0 };
4078 WCHAR buf[26];
4079 SID *pisid = psid;
4081 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4083 SetLastError(ERROR_INVALID_SID);
4084 return FALSE;
4087 if (pisid->IdentifierAuthority.Value[0] ||
4088 pisid->IdentifierAuthority.Value[1])
4090 FIXME("not matching MS' bugs\n");
4091 SetLastError(ERROR_INVALID_SID);
4092 return FALSE;
4095 sprintfW( buf, fmt, pisid->Revision,
4096 MAKELONG(
4097 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4098 pisid->IdentifierAuthority.Value[4] ),
4099 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4100 pisid->IdentifierAuthority.Value[2] )
4101 ) );
4102 DumpString(buf, -1, pwptr, plen);
4104 for( i=0; i<pisid->SubAuthorityCount; i++ )
4106 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4107 DumpString(buf, -1, pwptr, plen);
4109 return TRUE;
4112 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4114 size_t i;
4115 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4117 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4119 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4120 return TRUE;
4124 return DumpSidNumeric(psid, pwptr, plen);
4127 static const LPCWSTR AceRightBitNames[32] = {
4128 SDDL_CREATE_CHILD, /* 0 */
4129 SDDL_DELETE_CHILD,
4130 SDDL_LIST_CHILDREN,
4131 SDDL_SELF_WRITE,
4132 SDDL_READ_PROPERTY, /* 4 */
4133 SDDL_WRITE_PROPERTY,
4134 SDDL_DELETE_TREE,
4135 SDDL_LIST_OBJECT,
4136 SDDL_CONTROL_ACCESS, /* 8 */
4137 NULL,
4138 NULL,
4139 NULL,
4140 NULL, /* 12 */
4141 NULL,
4142 NULL,
4143 NULL,
4144 SDDL_STANDARD_DELETE, /* 16 */
4145 SDDL_READ_CONTROL,
4146 SDDL_WRITE_DAC,
4147 SDDL_WRITE_OWNER,
4148 NULL, /* 20 */
4149 NULL,
4150 NULL,
4151 NULL,
4152 NULL, /* 24 */
4153 NULL,
4154 NULL,
4155 NULL,
4156 SDDL_GENERIC_ALL, /* 28 */
4157 SDDL_GENERIC_EXECUTE,
4158 SDDL_GENERIC_WRITE,
4159 SDDL_GENERIC_READ
4162 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4164 static const WCHAR fmtW[] = {'0','x','%','x',0};
4165 WCHAR buf[15];
4166 size_t i;
4168 if (mask == 0)
4169 return;
4171 /* first check if the right have name */
4172 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4174 if (AceRights[i].wstr == NULL)
4175 break;
4176 if (mask == AceRights[i].value)
4178 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4179 return;
4183 /* then check if it can be built from bit names */
4184 for (i = 0; i < 32; i++)
4186 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4188 /* can't be built from bit names */
4189 sprintfW(buf, fmtW, mask);
4190 DumpString(buf, -1, pwptr, plen);
4191 return;
4195 /* build from bit names */
4196 for (i = 0; i < 32; i++)
4197 if (mask & (1 << i))
4198 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4201 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4203 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4204 static const WCHAR openbr = '(';
4205 static const WCHAR closebr = ')';
4206 static const WCHAR semicolon = ';';
4208 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4210 SetLastError(ERROR_INVALID_ACL);
4211 return FALSE;
4214 piace = (ACCESS_ALLOWED_ACE *)pace;
4215 DumpString(&openbr, 1, pwptr, plen);
4216 switch (piace->Header.AceType)
4218 case ACCESS_ALLOWED_ACE_TYPE:
4219 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4220 break;
4221 case ACCESS_DENIED_ACE_TYPE:
4222 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4223 break;
4224 case SYSTEM_AUDIT_ACE_TYPE:
4225 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4226 break;
4227 case SYSTEM_ALARM_ACE_TYPE:
4228 DumpString(SDDL_ALARM, -1, pwptr, plen);
4229 break;
4231 DumpString(&semicolon, 1, pwptr, plen);
4233 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4234 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4235 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4236 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4237 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4238 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4239 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4240 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4241 if (piace->Header.AceFlags & INHERITED_ACE)
4242 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4243 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4244 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4245 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4246 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4247 DumpString(&semicolon, 1, pwptr, plen);
4248 DumpRights(piace->Mask, pwptr, plen);
4249 DumpString(&semicolon, 1, pwptr, plen);
4250 /* objects not supported */
4251 DumpString(&semicolon, 1, pwptr, plen);
4252 /* objects not supported */
4253 DumpString(&semicolon, 1, pwptr, plen);
4254 if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4255 return FALSE;
4256 DumpString(&closebr, 1, pwptr, plen);
4257 return TRUE;
4260 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4262 WORD count;
4263 int i;
4265 if (protected)
4266 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4267 if (autoInheritReq)
4268 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4269 if (autoInherited)
4270 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4272 if (pacl == NULL)
4273 return TRUE;
4275 if (!IsValidAcl(pacl))
4276 return FALSE;
4278 count = pacl->AceCount;
4279 for (i = 0; i < count; i++)
4281 LPVOID ace;
4282 if (!GetAce(pacl, i, &ace))
4283 return FALSE;
4284 if (!DumpAce(ace, pwptr, plen))
4285 return FALSE;
4288 return TRUE;
4291 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4293 static const WCHAR prefix[] = {'O',':',0};
4294 BOOL bDefaulted;
4295 PSID psid;
4297 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4298 return FALSE;
4300 if (psid == NULL)
4301 return TRUE;
4303 DumpString(prefix, -1, pwptr, plen);
4304 if (!DumpSid(psid, pwptr, plen))
4305 return FALSE;
4306 return TRUE;
4309 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4311 static const WCHAR prefix[] = {'G',':',0};
4312 BOOL bDefaulted;
4313 PSID psid;
4315 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4316 return FALSE;
4318 if (psid == NULL)
4319 return TRUE;
4321 DumpString(prefix, -1, pwptr, plen);
4322 if (!DumpSid(psid, pwptr, plen))
4323 return FALSE;
4324 return TRUE;
4327 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4329 static const WCHAR dacl[] = {'D',':',0};
4330 SECURITY_DESCRIPTOR_CONTROL control;
4331 BOOL present, defaulted;
4332 DWORD revision;
4333 PACL pacl;
4335 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4336 return FALSE;
4338 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4339 return FALSE;
4341 if (!present)
4342 return TRUE;
4344 DumpString(dacl, 2, pwptr, plen);
4345 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4346 return FALSE;
4347 return TRUE;
4350 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4352 static const WCHAR sacl[] = {'S',':',0};
4353 SECURITY_DESCRIPTOR_CONTROL control;
4354 BOOL present, defaulted;
4355 DWORD revision;
4356 PACL pacl;
4358 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4359 return FALSE;
4361 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4362 return FALSE;
4364 if (!present)
4365 return TRUE;
4367 DumpString(sacl, 2, pwptr, plen);
4368 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4369 return FALSE;
4370 return TRUE;
4373 /******************************************************************************
4374 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4376 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4378 ULONG len;
4379 WCHAR *wptr, *wstr;
4381 if (SDRevision != SDDL_REVISION_1)
4383 ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4384 SetLastError(ERROR_UNKNOWN_REVISION);
4385 return FALSE;
4388 len = 0;
4389 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4390 if (!DumpOwner(SecurityDescriptor, NULL, &len))
4391 return FALSE;
4392 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4393 if (!DumpGroup(SecurityDescriptor, NULL, &len))
4394 return FALSE;
4395 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4396 if (!DumpDacl(SecurityDescriptor, NULL, &len))
4397 return FALSE;
4398 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4399 if (!DumpSacl(SecurityDescriptor, NULL, &len))
4400 return FALSE;
4402 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4403 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4404 if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4405 return FALSE;
4406 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4407 if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4408 return FALSE;
4409 if (RequestedInformation & DACL_SECURITY_INFORMATION)
4410 if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4411 return FALSE;
4412 if (RequestedInformation & SACL_SECURITY_INFORMATION)
4413 if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4414 return FALSE;
4415 *wptr = 0;
4417 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4418 *OutputString = wstr;
4419 if (OutputLen)
4420 *OutputLen = strlenW(*OutputString)+1;
4421 return TRUE;
4424 /******************************************************************************
4425 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4427 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4429 LPWSTR wstr;
4430 ULONG len;
4431 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4433 int lenA;
4435 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4436 *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4437 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4438 LocalFree(wstr);
4440 if (OutputLen != NULL)
4441 *OutputLen = lenA;
4442 return TRUE;
4444 else
4446 *OutputString = NULL;
4447 if (OutputLen)
4448 *OutputLen = 0;
4449 return FALSE;
4453 /******************************************************************************
4454 * ConvertStringSidToSidW [ADVAPI32.@]
4456 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4458 BOOL bret = FALSE;
4459 DWORD cBytes;
4461 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4462 if (GetVersion() & 0x80000000)
4463 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4464 else if (!StringSid || !Sid)
4465 SetLastError(ERROR_INVALID_PARAMETER);
4466 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4468 PSID pSid = *Sid = LocalAlloc(0, cBytes);
4470 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4471 if (!bret)
4472 LocalFree(*Sid);
4474 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4475 return bret;
4478 /******************************************************************************
4479 * ConvertStringSidToSidA [ADVAPI32.@]
4481 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4483 BOOL bret = FALSE;
4485 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4486 if (GetVersion() & 0x80000000)
4487 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4488 else if (!StringSid || !Sid)
4489 SetLastError(ERROR_INVALID_PARAMETER);
4490 else
4492 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4493 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4494 len * sizeof(WCHAR));
4496 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4497 bret = ConvertStringSidToSidW(wStringSid, Sid);
4498 HeapFree(GetProcessHeap(), 0, wStringSid);
4500 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4501 return bret;
4504 /******************************************************************************
4505 * ConvertSidToStringSidW [ADVAPI32.@]
4507 * format of SID string is:
4508 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4509 * where
4510 * <rev> is the revision of the SID encoded as decimal
4511 * <auth> is the identifier authority encoded as hex
4512 * <subauthN> is the subauthority id encoded as decimal
4514 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4516 DWORD len = 0;
4517 LPWSTR wstr, wptr;
4519 TRACE("%p %p\n", pSid, pstr );
4521 len = 0;
4522 if (!DumpSidNumeric(pSid, NULL, &len))
4523 return FALSE;
4524 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4525 DumpSidNumeric(pSid, &wptr, NULL);
4526 *wptr = 0;
4528 *pstr = wstr;
4529 return TRUE;
4532 /******************************************************************************
4533 * ConvertSidToStringSidA [ADVAPI32.@]
4535 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4537 LPWSTR wstr = NULL;
4538 LPSTR str;
4539 UINT len;
4541 TRACE("%p %p\n", pSid, pstr );
4543 if( !ConvertSidToStringSidW( pSid, &wstr ) )
4544 return FALSE;
4546 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4547 str = LocalAlloc( 0, len );
4548 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4549 LocalFree( wstr );
4551 *pstr = str;
4553 return TRUE;
4556 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4557 PSECURITY_DESCRIPTOR pdesc,
4558 PSECURITY_DESCRIPTOR cdesc,
4559 PSECURITY_DESCRIPTOR* ndesc,
4560 GUID* objtype,
4561 BOOL isdir,
4562 PGENERIC_MAPPING genmap )
4564 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4566 return FALSE;
4569 BOOL WINAPI CreatePrivateObjectSecurity(
4570 PSECURITY_DESCRIPTOR ParentDescriptor,
4571 PSECURITY_DESCRIPTOR CreatorDescriptor,
4572 PSECURITY_DESCRIPTOR* NewDescriptor,
4573 BOOL IsDirectoryObject,
4574 HANDLE Token,
4575 PGENERIC_MAPPING GenericMapping )
4577 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4578 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4580 return FALSE;
4583 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4585 FIXME("%p - stub\n", ObjectDescriptor);
4587 return TRUE;
4590 BOOL WINAPI CreateProcessAsUserA(
4591 HANDLE hToken,
4592 LPCSTR lpApplicationName,
4593 LPSTR lpCommandLine,
4594 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4595 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4596 BOOL bInheritHandles,
4597 DWORD dwCreationFlags,
4598 LPVOID lpEnvironment,
4599 LPCSTR lpCurrentDirectory,
4600 LPSTARTUPINFOA lpStartupInfo,
4601 LPPROCESS_INFORMATION lpProcessInformation )
4603 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4604 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4605 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4607 return FALSE;
4610 BOOL WINAPI CreateProcessAsUserW(
4611 HANDLE hToken,
4612 LPCWSTR lpApplicationName,
4613 LPWSTR lpCommandLine,
4614 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4615 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4616 BOOL bInheritHandles,
4617 DWORD dwCreationFlags,
4618 LPVOID lpEnvironment,
4619 LPCWSTR lpCurrentDirectory,
4620 LPSTARTUPINFOW lpStartupInfo,
4621 LPPROCESS_INFORMATION lpProcessInformation )
4623 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken,
4624 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4625 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
4626 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4628 /* We should create the process with a suspended main thread */
4629 if (!CreateProcessW (lpApplicationName,
4630 lpCommandLine,
4631 lpProcessAttributes,
4632 lpThreadAttributes,
4633 bInheritHandles,
4634 dwCreationFlags, /* CREATE_SUSPENDED */
4635 lpEnvironment,
4636 lpCurrentDirectory,
4637 lpStartupInfo,
4638 lpProcessInformation))
4640 return FALSE;
4643 return TRUE;
4646 /******************************************************************************
4647 * CreateProcessWithLogonW
4649 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4650 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4651 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4653 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4654 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4655 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4656 lpStartupInfo, lpProcessInformation);
4658 return FALSE;
4661 /******************************************************************************
4662 * DuplicateTokenEx [ADVAPI32.@]
4664 BOOL WINAPI DuplicateTokenEx(
4665 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4666 LPSECURITY_ATTRIBUTES lpTokenAttributes,
4667 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4668 TOKEN_TYPE TokenType,
4669 PHANDLE DuplicateTokenHandle )
4671 OBJECT_ATTRIBUTES ObjectAttributes;
4673 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4674 ImpersonationLevel, TokenType, DuplicateTokenHandle);
4676 InitializeObjectAttributes(
4677 &ObjectAttributes,
4678 NULL,
4679 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4680 NULL,
4681 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4683 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4684 dwDesiredAccess,
4685 &ObjectAttributes,
4686 ImpersonationLevel,
4687 TokenType,
4688 DuplicateTokenHandle ) );
4691 BOOL WINAPI DuplicateToken(
4692 HANDLE ExistingTokenHandle,
4693 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4694 PHANDLE DuplicateTokenHandle )
4696 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4697 NULL, ImpersonationLevel, TokenImpersonation,
4698 DuplicateTokenHandle );
4701 /******************************************************************************
4702 * ComputeStringSidSize
4704 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4706 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4708 int ctok = 0;
4709 while (*StringSid)
4711 if (*StringSid == '-')
4712 ctok++;
4713 StringSid++;
4716 if (ctok >= 3)
4717 return GetSidLengthRequired(ctok - 2);
4719 else /* String constant format - Only available in winxp and above */
4721 unsigned int i;
4723 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4724 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4725 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4728 return GetSidLengthRequired(0);
4731 /******************************************************************************
4732 * ParseStringSidToSid
4734 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4736 BOOL bret = FALSE;
4737 SID* pisid=pSid;
4739 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4740 if (!StringSid)
4742 SetLastError(ERROR_INVALID_PARAMETER);
4743 TRACE("StringSid is NULL, returning FALSE\n");
4744 return FALSE;
4747 *cBytes = ComputeStringSidSize(StringSid);
4748 if (!pisid) /* Simply compute the size */
4750 TRACE("only size requested, returning TRUE\n");
4751 return TRUE;
4754 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4756 DWORD i = 0, identAuth;
4757 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4759 StringSid += 2; /* Advance to Revision */
4760 pisid->Revision = atoiW(StringSid);
4762 if (pisid->Revision != SDDL_REVISION)
4764 TRACE("Revision %d is unknown\n", pisid->Revision);
4765 goto lend; /* ERROR_INVALID_SID */
4767 if (csubauth == 0)
4769 TRACE("SubAuthorityCount is 0\n");
4770 goto lend; /* ERROR_INVALID_SID */
4773 pisid->SubAuthorityCount = csubauth;
4775 /* Advance to identifier authority */
4776 while (*StringSid && *StringSid != '-')
4777 StringSid++;
4778 if (*StringSid == '-')
4779 StringSid++;
4781 /* MS' implementation can't handle values greater than 2^32 - 1, so
4782 * we don't either; assume most significant bytes are always 0
4784 pisid->IdentifierAuthority.Value[0] = 0;
4785 pisid->IdentifierAuthority.Value[1] = 0;
4786 identAuth = atoiW(StringSid);
4787 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4788 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4789 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4790 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4792 /* Advance to first sub authority */
4793 while (*StringSid && *StringSid != '-')
4794 StringSid++;
4795 if (*StringSid == '-')
4796 StringSid++;
4798 while (*StringSid)
4800 pisid->SubAuthority[i++] = atoiW(StringSid);
4802 while (*StringSid && *StringSid != '-')
4803 StringSid++;
4804 if (*StringSid == '-')
4805 StringSid++;
4808 if (i != pisid->SubAuthorityCount)
4809 goto lend; /* ERROR_INVALID_SID */
4811 bret = TRUE;
4813 else /* String constant format - Only available in winxp and above */
4815 unsigned int i;
4816 pisid->Revision = SDDL_REVISION;
4818 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4819 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4821 DWORD j;
4822 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4823 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4824 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4825 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4826 bret = TRUE;
4829 if (!bret)
4830 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4833 lend:
4834 if (!bret)
4835 SetLastError(ERROR_INVALID_SID);
4837 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4838 return bret;
4841 /******************************************************************************
4842 * GetNamedSecurityInfoA [ADVAPI32.@]
4844 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4845 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4846 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4847 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4849 DWORD len;
4850 LPWSTR wstr = NULL;
4851 DWORD r;
4853 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4854 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4856 if( pObjectName )
4858 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4859 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4860 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4863 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4864 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4866 HeapFree( GetProcessHeap(), 0, wstr );
4868 return r;
4871 /******************************************************************************
4872 * GetNamedSecurityInfoW [ADVAPI32.@]
4874 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4875 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4876 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4878 DWORD needed, offset;
4879 SECURITY_DESCRIPTOR_RELATIVE *relative;
4880 BYTE *buffer;
4882 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4883 group, dacl, sacl, descriptor );
4885 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4887 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4888 if (info & OWNER_SECURITY_INFORMATION)
4889 needed += sizeof(sidWorld);
4890 if (info & GROUP_SECURITY_INFORMATION)
4891 needed += sizeof(sidWorld);
4892 if (info & DACL_SECURITY_INFORMATION)
4893 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4894 if (info & SACL_SECURITY_INFORMATION)
4895 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4897 /* must be freed by caller */
4898 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
4899 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
4901 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
4903 HeapFree( GetProcessHeap(), 0, *descriptor );
4904 return ERROR_INVALID_SECURITY_DESCR;
4907 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
4908 relative->Control |= SE_SELF_RELATIVE;
4909 buffer = (BYTE *)relative;
4910 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4912 if (info & OWNER_SECURITY_INFORMATION)
4914 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4915 relative->Owner = offset;
4916 if (owner)
4917 *owner = buffer + offset;
4918 offset += sizeof(sidWorld);
4920 if (info & GROUP_SECURITY_INFORMATION)
4922 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4923 relative->Group = offset;
4924 if (group)
4925 *group = buffer + offset;
4926 offset += sizeof(sidWorld);
4928 if (info & DACL_SECURITY_INFORMATION)
4930 relative->Control |= SE_DACL_PRESENT;
4931 GetWorldAccessACL( (PACL)(buffer + offset) );
4932 relative->Dacl = offset;
4933 if (dacl)
4934 *dacl = (PACL)(buffer + offset);
4935 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4937 if (info & SACL_SECURITY_INFORMATION)
4939 relative->Control |= SE_SACL_PRESENT;
4940 GetWorldAccessACL( (PACL)(buffer + offset) );
4941 relative->Sacl = offset;
4942 if (sacl)
4943 *sacl = (PACL)(buffer + offset);
4945 return ERROR_SUCCESS;
4948 /******************************************************************************
4949 * DecryptFileW [ADVAPI32.@]
4951 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4953 FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4954 return TRUE;
4957 /******************************************************************************
4958 * DecryptFileA [ADVAPI32.@]
4960 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4962 FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4963 return TRUE;
4966 /******************************************************************************
4967 * EncryptFileW [ADVAPI32.@]
4969 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4971 FIXME("%s\n", debugstr_w(lpFileName));
4972 return TRUE;
4975 /******************************************************************************
4976 * EncryptFileA [ADVAPI32.@]
4978 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4980 FIXME("%s\n", debugstr_a(lpFileName));
4981 return TRUE;
4984 /******************************************************************************
4985 * FileEncryptionStatusW [ADVAPI32.@]
4987 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4989 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4990 if (!lpStatus)
4991 return FALSE;
4992 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4993 return TRUE;
4996 /******************************************************************************
4997 * FileEncryptionStatusA [ADVAPI32.@]
4999 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5001 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5002 if (!lpStatus)
5003 return FALSE;
5004 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5005 return TRUE;
5008 /******************************************************************************
5009 * SetSecurityInfo [ADVAPI32.@]
5011 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5012 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5013 PSID psidGroup, PACL pDacl, PACL pSacl) {
5014 FIXME("stub\n");
5015 return ERROR_SUCCESS;