user: Implement MNS_NOTIFYBYPOS.
[wine/wine64.git] / dlls / advapi32 / security.c
blob2eade3e9b1dac2281ae1931a53b9a3ecebfa895e
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "rpcnterr.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 "advapi32_misc.h"
40 #include "wine/debug.h"
41 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
45 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
46 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
47 PACL pAcl, LPDWORD cBytes);
48 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
49 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
50 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
51 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
52 LPCWSTR StringSecurityDescriptor,
53 SECURITY_DESCRIPTOR* SecurityDescriptor,
54 LPDWORD cBytes);
55 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
57 typedef struct _ACEFLAG
59 LPCWSTR wstr;
60 DWORD value;
61 } ACEFLAG, *LPACEFLAG;
63 typedef struct _MAX_SID
65 /* same fields as struct _SID */
66 BYTE Revision;
67 BYTE SubAuthorityCount;
68 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
69 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
70 } MAX_SID;
72 typedef struct WELLKNOWNSID
74 WCHAR wstr[2];
75 WELL_KNOWN_SID_TYPE Type;
76 MAX_SID Sid;
77 } WELLKNOWNSID;
79 static const WELLKNOWNSID WellKnownSids[] =
81 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
82 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
83 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
84 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
85 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
86 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
87 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
88 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { } } },
89 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
90 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
91 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
92 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
93 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
94 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
95 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
96 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
97 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
98 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
99 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
100 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
101 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
102 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
103 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
104 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
105 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
106 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
107 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
108 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
109 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
110 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
111 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
112 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
113 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
114 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
115 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
116 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
117 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
120 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
122 typedef struct _AccountSid {
123 WELL_KNOWN_SID_TYPE type;
124 LPCWSTR account;
125 LPCWSTR domain;
126 SID_NAME_USE name_use;
127 } AccountSid;
129 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
130 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
131 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
132 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
133 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
134 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
135 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
136 static const WCHAR Blank[] = { 0 };
137 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
138 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
139 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 };
140 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
141 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 };
142 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
143 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
144 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 };
145 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
146 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
147 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
148 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
149 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
150 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
151 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
152 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 };
153 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
154 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
155 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
156 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
157 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
158 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
159 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
160 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 };
161 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 };
162 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
163 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
164 static const WCHAR SELF[] = { 'S','E','L','F',0 };
165 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
166 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
167 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
168 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 };
169 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
171 static const AccountSid ACCOUNT_SIDS[] = {
172 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
173 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
174 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
175 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
176 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
177 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
178 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
179 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
180 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
181 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
182 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
183 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
184 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
185 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
186 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
187 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
188 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
189 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
190 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
191 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
192 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
193 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
194 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
195 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
196 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
197 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
198 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
199 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
200 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
201 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
202 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
203 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
204 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
205 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
206 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
207 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
210 * ACE access rights
212 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
213 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
214 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
215 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
216 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
217 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
218 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
219 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
222 * ACE types
224 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
225 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
226 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
227 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
228 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
229 static const WCHAR SDDL_ALARM[] = {'A','L',0};
230 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
231 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
234 * ACE flags
236 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
237 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
238 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
239 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
240 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
241 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
242 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
244 const char * debugstr_sid(PSID sid)
246 int auth = 0;
247 SID * psid = (SID *)sid;
249 if (psid == NULL)
250 return "(null)";
252 auth = psid->IdentifierAuthority.Value[5] +
253 (psid->IdentifierAuthority.Value[4] << 8) +
254 (psid->IdentifierAuthority.Value[3] << 16) +
255 (psid->IdentifierAuthority.Value[2] << 24);
257 switch (psid->SubAuthorityCount) {
258 case 0:
259 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
260 case 1:
261 return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth,
262 psid->SubAuthority[0]);
263 case 2:
264 return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth,
265 psid->SubAuthority[0], psid->SubAuthority[1]);
266 case 3:
267 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth,
268 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
269 case 4:
270 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth,
271 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
272 psid->SubAuthority[3]);
273 case 5:
274 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
275 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
276 psid->SubAuthority[3], psid->SubAuthority[4]);
277 case 6:
278 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
279 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
280 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
281 case 7:
282 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
283 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
284 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
285 psid->SubAuthority[6]);
286 case 8:
287 return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
288 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
289 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
290 psid->SubAuthority[6], psid->SubAuthority[7]);
292 return "(too-big)";
295 /* set last error code from NT status and get the proper boolean return value */
296 /* used for functions that are a simple wrapper around the corresponding ntdll API */
297 static inline BOOL set_ntstatus( NTSTATUS status )
299 if (status) SetLastError( RtlNtStatusToDosError( status ));
300 return !status;
303 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
305 static void GetWorldAccessACL(PACL pACL)
307 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
309 pACL->AclRevision = ACL_REVISION;
310 pACL->Sbz1 = 0;
311 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
312 pACL->AceCount = 1;
313 pACL->Sbz2 = 0;
315 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
316 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
317 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
318 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
319 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
322 /************************************************************
323 * ADVAPI_IsLocalComputer
325 * Checks whether the server name indicates local machine.
327 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
329 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
330 BOOL Result;
331 LPWSTR buf;
333 if (!ServerName || !ServerName[0])
334 return TRUE;
336 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
337 Result = GetComputerNameW(buf, &dwSize);
338 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
339 ServerName += 2;
340 Result = Result && !lstrcmpW(ServerName, buf);
341 HeapFree(GetProcessHeap(), 0, buf);
343 return Result;
346 /************************************************************
347 * ADVAPI_GetComputerSid
349 * Reads the computer SID from the registry.
351 BOOL ADVAPI_GetComputerSid(PSID sid)
353 HKEY key;
354 LONG ret;
355 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 };
356 static const WCHAR V[] = { 'V',0 };
358 if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
359 KEY_READ, &key)) == ERROR_SUCCESS)
361 DWORD size = 0;
362 ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
363 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
365 BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
366 if (data)
368 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
369 data, &size)) == ERROR_SUCCESS)
371 /* the SID is in the last 24 bytes of the binary data */
372 CopyMemory(sid, &data[size-24], 24);
373 HeapFree(GetProcessHeap(), 0, data);
374 RegCloseKey(key);
375 return TRUE;
377 HeapFree(GetProcessHeap(), 0, data);
380 RegCloseKey(key);
383 /* create a new random SID */
384 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
385 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
387 PSID new_sid;
388 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
389 DWORD id[3];
391 if (RtlGenRandom(&id, sizeof(id)))
393 if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
395 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
397 FreeSid(new_sid);
398 RegCloseKey(key);
399 return CopySid(GetLengthSid(new_sid), sid, &new_sid);
401 FreeSid(new_sid);
404 RegCloseKey(key);
407 return FALSE;
410 /* ##############################
411 ###### TOKEN FUNCTIONS ######
412 ##############################
415 /******************************************************************************
416 * OpenProcessToken [ADVAPI32.@]
417 * Opens the access token associated with a process handle.
419 * PARAMS
420 * ProcessHandle [I] Handle to process
421 * DesiredAccess [I] Desired access to process
422 * TokenHandle [O] Pointer to handle of open access token
424 * RETURNS
425 * Success: TRUE. TokenHandle contains the access token.
426 * Failure: FALSE.
428 * NOTES
429 * See NtOpenProcessToken.
431 BOOL WINAPI
432 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
433 HANDLE *TokenHandle )
435 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
438 /******************************************************************************
439 * OpenThreadToken [ADVAPI32.@]
441 * Opens the access token associated with a thread handle.
443 * PARAMS
444 * ThreadHandle [I] Handle to process
445 * DesiredAccess [I] Desired access to the thread
446 * OpenAsSelf [I] ???
447 * TokenHandle [O] Destination for the token handle
449 * RETURNS
450 * Success: TRUE. TokenHandle contains the access token.
451 * Failure: FALSE.
453 * NOTES
454 * See NtOpenThreadToken.
456 BOOL WINAPI
457 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
458 BOOL OpenAsSelf, HANDLE *TokenHandle)
460 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
463 BOOL WINAPI
464 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
465 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
467 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
468 PreviousState, ReturnLength));
471 /******************************************************************************
472 * AdjustTokenPrivileges [ADVAPI32.@]
474 * Adjust the privileges of an open token handle.
476 * PARAMS
477 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
478 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
479 * NewState [I] Desired new privileges of the token
480 * BufferLength [I] Length of NewState
481 * PreviousState [O] Destination for the previous state
482 * ReturnLength [I/O] Size of PreviousState
485 * RETURNS
486 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
487 * Failure: FALSE.
489 * NOTES
490 * See NtAdjustPrivilegesToken.
492 BOOL WINAPI
493 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
494 LPVOID NewState, DWORD BufferLength,
495 LPVOID PreviousState, LPDWORD ReturnLength )
497 NTSTATUS status;
499 TRACE("\n");
501 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
502 NewState, BufferLength, PreviousState,
503 ReturnLength);
504 SetLastError( RtlNtStatusToDosError( status ));
505 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
506 return TRUE;
507 else
508 return FALSE;
511 /******************************************************************************
512 * CheckTokenMembership [ADVAPI32.@]
514 * Determine if an access token is a member of a SID.
516 * PARAMS
517 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
518 * SidToCheck [I] SID that possibly contains the token
519 * IsMember [O] Destination for result.
521 * RETURNS
522 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
523 * Failure: FALSE.
525 BOOL WINAPI
526 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
527 PBOOL IsMember )
529 FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
531 *IsMember = TRUE;
532 return(TRUE);
535 /******************************************************************************
536 * GetTokenInformation [ADVAPI32.@]
538 * Get a type of information about an access token.
540 * PARAMS
541 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
542 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
543 * tokeninfo [O] Destination for token information
544 * tokeninfolength [I] Length of tokeninfo
545 * retlen [O] Destination for returned token information length
547 * RETURNS
548 * Success: TRUE. tokeninfo contains retlen bytes of token information
549 * Failure: FALSE.
551 * NOTES
552 * See NtQueryInformationToken.
554 BOOL WINAPI
555 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
556 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
558 TRACE("(%p, %s, %p, %ld, %p):\n",
559 token,
560 (tokeninfoclass == TokenUser) ? "TokenUser" :
561 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
562 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
563 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
564 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
565 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
566 (tokeninfoclass == TokenSource) ? "TokenSource" :
567 (tokeninfoclass == TokenType) ? "TokenType" :
568 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
569 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
570 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
571 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
572 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
573 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
574 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
575 "Unknown",
576 tokeninfo, tokeninfolength, retlen);
577 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
578 tokeninfolength, retlen));
581 /******************************************************************************
582 * SetTokenInformation [ADVAPI32.@]
584 * Set information for an access token.
586 * PARAMS
587 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
588 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
589 * tokeninfo [I] Token information to set
590 * tokeninfolength [I] Length of tokeninfo
592 * RETURNS
593 * Success: TRUE. The information for the token is set to tokeninfo.
594 * Failure: FALSE.
596 BOOL WINAPI
597 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
598 LPVOID tokeninfo, DWORD tokeninfolength )
600 TRACE("(%p, %s, %p, %ld): stub\n",
601 token,
602 (tokeninfoclass == TokenUser) ? "TokenUser" :
603 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
604 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
605 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
606 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
607 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
608 (tokeninfoclass == TokenSource) ? "TokenSource" :
609 (tokeninfoclass == TokenType) ? "TokenType" :
610 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
611 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
612 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
613 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
614 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
615 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
616 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
617 "Unknown",
618 tokeninfo, tokeninfolength);
620 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
623 /*************************************************************************
624 * SetThreadToken [ADVAPI32.@]
626 * Assigns an 'impersonation token' to a thread so it can assume the
627 * security privileges of another thread or process. Can also remove
628 * a previously assigned token.
630 * PARAMS
631 * thread [O] Handle to thread to set the token for
632 * token [I] Token to set
634 * RETURNS
635 * Success: TRUE. The threads access token is set to token
636 * Failure: FALSE.
638 * NOTES
639 * Only supported on NT or higher. On Win9X this function does nothing.
640 * See SetTokenInformation.
642 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
644 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
645 ThreadImpersonationToken, &token, sizeof token ));
648 /* ##############################
649 ###### SID FUNCTIONS ######
650 ##############################
653 /******************************************************************************
654 * AllocateAndInitializeSid [ADVAPI32.@]
656 * PARAMS
657 * pIdentifierAuthority []
658 * nSubAuthorityCount []
659 * nSubAuthority0 []
660 * nSubAuthority1 []
661 * nSubAuthority2 []
662 * nSubAuthority3 []
663 * nSubAuthority4 []
664 * nSubAuthority5 []
665 * nSubAuthority6 []
666 * nSubAuthority7 []
667 * pSid []
669 BOOL WINAPI
670 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
671 BYTE nSubAuthorityCount,
672 DWORD nSubAuthority0, DWORD nSubAuthority1,
673 DWORD nSubAuthority2, DWORD nSubAuthority3,
674 DWORD nSubAuthority4, DWORD nSubAuthority5,
675 DWORD nSubAuthority6, DWORD nSubAuthority7,
676 PSID *pSid )
678 return set_ntstatus( RtlAllocateAndInitializeSid(
679 pIdentifierAuthority, nSubAuthorityCount,
680 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
681 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
682 pSid ));
685 /******************************************************************************
686 * FreeSid [ADVAPI32.@]
688 * PARAMS
689 * pSid []
691 PVOID WINAPI
692 FreeSid( PSID pSid )
694 RtlFreeSid(pSid);
695 return NULL; /* is documented like this */
698 /******************************************************************************
699 * CopySid [ADVAPI32.@]
701 * PARAMS
702 * nDestinationSidLength []
703 * pDestinationSid []
704 * pSourceSid []
706 BOOL WINAPI
707 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
709 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
712 /******************************************************************************
713 * CreateWellKnownSid [ADVAPI32.@]
715 BOOL WINAPI
716 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
717 PSID DomainSid,
718 PSID pSid,
719 DWORD* cbSid)
721 int i;
722 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
724 if (DomainSid != NULL) {
725 FIXME("Only local computer supported!\n");
726 SetLastError(ERROR_INVALID_PARAMETER); /* FIXME */
727 return FALSE;
730 if (cbSid == NULL || pSid == NULL) {
731 SetLastError(ERROR_INVALID_PARAMETER);
732 return FALSE;
735 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
736 if (WellKnownSids[i].Type == WellKnownSidType) {
737 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
739 if (*cbSid < length) {
740 SetLastError(ERROR_INSUFFICIENT_BUFFER);
741 return FALSE;
744 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
745 *cbSid = length;
746 return TRUE;
750 SetLastError(ERROR_INVALID_PARAMETER);
751 return FALSE;
754 /******************************************************************************
755 * IsWellKnownSid [ADVAPI32.@]
757 BOOL WINAPI
758 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
760 int i;
761 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
763 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
764 if (WellKnownSids[i].Type == WellKnownSidType)
765 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
766 return TRUE;
768 return FALSE;
771 BOOL WINAPI
772 IsTokenRestricted( HANDLE TokenHandle )
774 TOKEN_GROUPS *groups;
775 DWORD size;
776 NTSTATUS status;
777 BOOL restricted;
779 TRACE("(%p)\n", TokenHandle);
781 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
782 if (status != STATUS_BUFFER_TOO_SMALL)
783 return FALSE;
785 groups = HeapAlloc(GetProcessHeap(), 0, size);
786 if (!groups)
788 SetLastError(ERROR_OUTOFMEMORY);
789 return FALSE;
792 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
793 if (status != STATUS_SUCCESS)
795 HeapFree(GetProcessHeap(), 0, groups);
796 return set_ntstatus(status);
799 if (groups->GroupCount)
800 restricted = TRUE;
801 else
802 restricted = FALSE;
804 HeapFree(GetProcessHeap(), 0, groups);
806 return restricted;
809 /******************************************************************************
810 * IsValidSid [ADVAPI32.@]
812 * PARAMS
813 * pSid []
815 BOOL WINAPI
816 IsValidSid( PSID pSid )
818 return RtlValidSid( pSid );
821 /******************************************************************************
822 * EqualSid [ADVAPI32.@]
824 * PARAMS
825 * pSid1 []
826 * pSid2 []
828 BOOL WINAPI
829 EqualSid( PSID pSid1, PSID pSid2 )
831 return RtlEqualSid( pSid1, pSid2 );
834 /******************************************************************************
835 * EqualPrefixSid [ADVAPI32.@]
837 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
839 return RtlEqualPrefixSid(pSid1, pSid2);
842 /******************************************************************************
843 * GetSidLengthRequired [ADVAPI32.@]
845 * PARAMS
846 * nSubAuthorityCount []
848 DWORD WINAPI
849 GetSidLengthRequired( BYTE nSubAuthorityCount )
851 return RtlLengthRequiredSid(nSubAuthorityCount);
854 /******************************************************************************
855 * InitializeSid [ADVAPI32.@]
857 * PARAMS
858 * pIdentifierAuthority []
860 BOOL WINAPI
861 InitializeSid (
862 PSID pSid,
863 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
864 BYTE nSubAuthorityCount)
866 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
869 DWORD WINAPI
870 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
872 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
874 return 1;
877 DWORD WINAPI
878 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
880 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
882 return 1;
885 /******************************************************************************
886 * GetSidIdentifierAuthority [ADVAPI32.@]
888 * PARAMS
889 * pSid []
891 PSID_IDENTIFIER_AUTHORITY WINAPI
892 GetSidIdentifierAuthority( PSID pSid )
894 return RtlIdentifierAuthoritySid(pSid);
897 /******************************************************************************
898 * GetSidSubAuthority [ADVAPI32.@]
900 * PARAMS
901 * pSid []
902 * nSubAuthority []
904 PDWORD WINAPI
905 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
907 return RtlSubAuthoritySid(pSid, nSubAuthority);
910 /******************************************************************************
911 * GetSidSubAuthorityCount [ADVAPI32.@]
913 * PARAMS
914 * pSid []
916 PUCHAR WINAPI
917 GetSidSubAuthorityCount (PSID pSid)
919 return RtlSubAuthorityCountSid(pSid);
922 /******************************************************************************
923 * GetLengthSid [ADVAPI32.@]
925 * PARAMS
926 * pSid []
928 DWORD WINAPI
929 GetLengthSid (PSID pSid)
931 return RtlLengthSid(pSid);
934 /* ##############################################
935 ###### SECURITY DESCRIPTOR FUNCTIONS ######
936 ##############################################
939 /******************************************************************************
940 * BuildSecurityDescriptorA [ADVAPI32.@]
942 * Builds a SD from
944 * PARAMS
945 * pOwner [I]
946 * pGroup [I]
947 * cCountOfAccessEntries [I]
948 * pListOfAccessEntries [I]
949 * cCountOfAuditEntries [I]
950 * pListofAuditEntries [I]
951 * pOldSD [I]
952 * lpdwBufferLength [I/O]
953 * pNewSD [O]
955 * RETURNS
956 * Success: ERROR_SUCCESS
957 * Failure: nonzero error code from Winerror.h
959 DWORD WINAPI BuildSecurityDescriptorA(
960 IN PTRUSTEEA pOwner,
961 IN PTRUSTEEA pGroup,
962 IN ULONG cCountOfAccessEntries,
963 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
964 IN ULONG cCountOfAuditEntries,
965 IN PEXPLICIT_ACCESSA pListofAuditEntries,
966 IN PSECURITY_DESCRIPTOR pOldSD,
967 IN OUT PULONG lpdwBufferLength,
968 OUT PSECURITY_DESCRIPTOR* pNewSD)
970 FIXME("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
971 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
972 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
974 return ERROR_CALL_NOT_IMPLEMENTED;
977 /******************************************************************************
978 * BuildSecurityDescriptorW [ADVAPI32.@]
980 * See BuildSecurityDescriptorA.
982 DWORD WINAPI BuildSecurityDescriptorW(
983 IN PTRUSTEEW pOwner,
984 IN PTRUSTEEW pGroup,
985 IN ULONG cCountOfAccessEntries,
986 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
987 IN ULONG cCountOfAuditEntries,
988 IN PEXPLICIT_ACCESSW pListofAuditEntries,
989 IN PSECURITY_DESCRIPTOR pOldSD,
990 IN OUT PULONG lpdwBufferLength,
991 OUT PSECURITY_DESCRIPTOR* pNewSD)
993 FIXME("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
994 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
995 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
997 return ERROR_CALL_NOT_IMPLEMENTED;
1000 /******************************************************************************
1001 * InitializeSecurityDescriptor [ADVAPI32.@]
1003 * PARAMS
1004 * pDescr []
1005 * revision []
1007 BOOL WINAPI
1008 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1010 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1014 /******************************************************************************
1015 * MakeAbsoluteSD [ADVAPI32.@]
1017 BOOL WINAPI MakeAbsoluteSD (
1018 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1019 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1020 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1021 OUT PACL pDacl,
1022 OUT LPDWORD lpdwDaclSize,
1023 OUT PACL pSacl,
1024 OUT LPDWORD lpdwSaclSize,
1025 OUT PSID pOwner,
1026 OUT LPDWORD lpdwOwnerSize,
1027 OUT PSID pPrimaryGroup,
1028 OUT LPDWORD lpdwPrimaryGroupSize)
1030 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1031 pAbsoluteSecurityDescriptor,
1032 lpdwAbsoluteSecurityDescriptorSize,
1033 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1034 pOwner, lpdwOwnerSize,
1035 pPrimaryGroup, lpdwPrimaryGroupSize));
1038 /******************************************************************************
1039 * GetKernelObjectSecurity [ADVAPI32.@]
1041 BOOL WINAPI GetKernelObjectSecurity(
1042 HANDLE Handle,
1043 SECURITY_INFORMATION RequestedInformation,
1044 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1045 DWORD nLength,
1046 LPDWORD lpnLengthNeeded )
1048 TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", Handle, RequestedInformation,
1049 pSecurityDescriptor, nLength, lpnLengthNeeded);
1051 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1052 nLength, lpnLengthNeeded ));
1055 /******************************************************************************
1056 * GetPrivateObjectSecurity [ADVAPI32.@]
1058 BOOL WINAPI GetPrivateObjectSecurity(
1059 PSECURITY_DESCRIPTOR ObjectDescriptor,
1060 SECURITY_INFORMATION SecurityInformation,
1061 PSECURITY_DESCRIPTOR ResultantDescriptor,
1062 DWORD DescriptorLength,
1063 PDWORD ReturnLength )
1065 TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", ObjectDescriptor, SecurityInformation,
1066 ResultantDescriptor, DescriptorLength, ReturnLength);
1068 return set_ntstatus( NtQuerySecurityObject(ObjectDescriptor, SecurityInformation,
1069 ResultantDescriptor, DescriptorLength, ReturnLength ));
1072 /******************************************************************************
1073 * GetSecurityDescriptorLength [ADVAPI32.@]
1075 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1077 return RtlLengthSecurityDescriptor(pDescr);
1080 /******************************************************************************
1081 * GetSecurityDescriptorOwner [ADVAPI32.@]
1083 * PARAMS
1084 * pOwner []
1085 * lpbOwnerDefaulted []
1087 BOOL WINAPI
1088 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1089 LPBOOL lpbOwnerDefaulted )
1091 BOOLEAN defaulted;
1092 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1093 *lpbOwnerDefaulted = defaulted;
1094 return ret;
1097 /******************************************************************************
1098 * SetSecurityDescriptorOwner [ADVAPI32.@]
1100 * PARAMS
1102 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1103 PSID pOwner, BOOL bOwnerDefaulted)
1105 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1107 /******************************************************************************
1108 * GetSecurityDescriptorGroup [ADVAPI32.@]
1110 BOOL WINAPI GetSecurityDescriptorGroup(
1111 PSECURITY_DESCRIPTOR SecurityDescriptor,
1112 PSID *Group,
1113 LPBOOL GroupDefaulted)
1115 BOOLEAN defaulted;
1116 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1117 *GroupDefaulted = defaulted;
1118 return ret;
1120 /******************************************************************************
1121 * SetSecurityDescriptorGroup [ADVAPI32.@]
1123 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1124 PSID Group, BOOL GroupDefaulted)
1126 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1129 /******************************************************************************
1130 * IsValidSecurityDescriptor [ADVAPI32.@]
1132 * PARAMS
1133 * lpsecdesc []
1135 BOOL WINAPI
1136 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1138 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1141 /******************************************************************************
1142 * GetSecurityDescriptorDacl [ADVAPI32.@]
1144 BOOL WINAPI GetSecurityDescriptorDacl(
1145 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1146 OUT LPBOOL lpbDaclPresent,
1147 OUT PACL *pDacl,
1148 OUT LPBOOL lpbDaclDefaulted)
1150 BOOLEAN present, defaulted;
1151 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1152 *lpbDaclPresent = present;
1153 *lpbDaclDefaulted = defaulted;
1154 return ret;
1157 /******************************************************************************
1158 * SetSecurityDescriptorDacl [ADVAPI32.@]
1160 BOOL WINAPI
1161 SetSecurityDescriptorDacl (
1162 PSECURITY_DESCRIPTOR lpsd,
1163 BOOL daclpresent,
1164 PACL dacl,
1165 BOOL dacldefaulted )
1167 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1169 /******************************************************************************
1170 * GetSecurityDescriptorSacl [ADVAPI32.@]
1172 BOOL WINAPI GetSecurityDescriptorSacl(
1173 IN PSECURITY_DESCRIPTOR lpsd,
1174 OUT LPBOOL lpbSaclPresent,
1175 OUT PACL *pSacl,
1176 OUT LPBOOL lpbSaclDefaulted)
1178 BOOLEAN present, defaulted;
1179 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1180 *lpbSaclPresent = present;
1181 *lpbSaclDefaulted = defaulted;
1182 return ret;
1185 /**************************************************************************
1186 * SetSecurityDescriptorSacl [ADVAPI32.@]
1188 BOOL WINAPI SetSecurityDescriptorSacl (
1189 PSECURITY_DESCRIPTOR lpsd,
1190 BOOL saclpresent,
1191 PACL lpsacl,
1192 BOOL sacldefaulted)
1194 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1196 /******************************************************************************
1197 * MakeSelfRelativeSD [ADVAPI32.@]
1199 * PARAMS
1200 * lpabssecdesc []
1201 * lpselfsecdesc []
1202 * lpbuflen []
1204 BOOL WINAPI
1205 MakeSelfRelativeSD(
1206 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1207 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1208 IN OUT LPDWORD lpdwBufferLength)
1210 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1211 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1214 /******************************************************************************
1215 * GetSecurityDescriptorControl [ADVAPI32.@]
1218 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1219 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1221 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1224 /* ##############################
1225 ###### ACL FUNCTIONS ######
1226 ##############################
1229 /*************************************************************************
1230 * InitializeAcl [ADVAPI32.@]
1232 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1234 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1237 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1239 TRACE("(%p)\n", hNamedPipe);
1241 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL, NULL,
1242 FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1245 /******************************************************************************
1246 * AddAccessAllowedAce [ADVAPI32.@]
1248 BOOL WINAPI AddAccessAllowedAce(
1249 IN OUT PACL pAcl,
1250 IN DWORD dwAceRevision,
1251 IN DWORD AccessMask,
1252 IN PSID pSid)
1254 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1257 /******************************************************************************
1258 * AddAccessAllowedAceEx [ADVAPI32.@]
1260 BOOL WINAPI AddAccessAllowedAceEx(
1261 IN OUT PACL pAcl,
1262 IN DWORD dwAceRevision,
1263 IN DWORD AceFlags,
1264 IN DWORD AccessMask,
1265 IN PSID pSid)
1267 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1270 /******************************************************************************
1271 * AddAccessDeniedAce [ADVAPI32.@]
1273 BOOL WINAPI AddAccessDeniedAce(
1274 IN OUT PACL pAcl,
1275 IN DWORD dwAceRevision,
1276 IN DWORD AccessMask,
1277 IN PSID pSid)
1279 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1282 /******************************************************************************
1283 * AddAccessDeniedAceEx [ADVAPI32.@]
1285 BOOL WINAPI AddAccessDeniedAceEx(
1286 IN OUT PACL pAcl,
1287 IN DWORD dwAceRevision,
1288 IN DWORD AceFlags,
1289 IN DWORD AccessMask,
1290 IN PSID pSid)
1292 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1295 /******************************************************************************
1296 * AddAce [ADVAPI32.@]
1298 BOOL WINAPI AddAce(
1299 IN OUT PACL pAcl,
1300 IN DWORD dwAceRevision,
1301 IN DWORD dwStartingAceIndex,
1302 LPVOID pAceList,
1303 DWORD nAceListLength)
1305 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1308 /******************************************************************************
1309 * DeleteAce [ADVAPI32.@]
1311 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1313 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1316 /******************************************************************************
1317 * FindFirstFreeAce [ADVAPI32.@]
1319 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1321 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1324 /******************************************************************************
1325 * GetAce [ADVAPI32.@]
1327 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1329 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1332 /******************************************************************************
1333 * GetAclInformation [ADVAPI32.@]
1335 BOOL WINAPI GetAclInformation(
1336 PACL pAcl,
1337 LPVOID pAclInformation,
1338 DWORD nAclInformationLength,
1339 ACL_INFORMATION_CLASS dwAclInformationClass)
1341 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1342 nAclInformationLength, dwAclInformationClass));
1345 /******************************************************************************
1346 * IsValidAcl [ADVAPI32.@]
1348 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1350 return RtlValidAcl(pAcl);
1353 /* ##############################
1354 ###### MISC FUNCTIONS ######
1355 ##############################
1358 /******************************************************************************
1359 * AllocateLocallyUniqueId [ADVAPI32.@]
1361 * PARAMS
1362 * lpLuid []
1364 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1366 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1369 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1370 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1371 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1372 { '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 };
1373 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1374 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1375 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1376 { '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 };
1377 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1378 { '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 };
1379 static const WCHAR SE_TCB_NAME_W[] =
1380 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1381 static const WCHAR SE_SECURITY_NAME_W[] =
1382 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1383 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1384 { '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 };
1385 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1386 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1387 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1388 { '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 };
1389 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1390 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1391 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1392 { '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 };
1393 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1394 { '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 };
1395 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1396 { '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 };
1397 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1398 { '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 };
1399 static const WCHAR SE_BACKUP_NAME_W[] =
1400 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1401 static const WCHAR SE_RESTORE_NAME_W[] =
1402 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1403 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1404 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1405 static const WCHAR SE_DEBUG_NAME_W[] =
1406 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1407 static const WCHAR SE_AUDIT_NAME_W[] =
1408 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1409 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1410 { '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 };
1411 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1412 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1413 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1414 { '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 };
1415 static const WCHAR SE_UNDOCK_NAME_W[] =
1416 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1417 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1418 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1419 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1420 { '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 };
1421 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1422 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1423 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1424 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1425 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1426 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1428 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1430 NULL,
1431 NULL,
1432 SE_CREATE_TOKEN_NAME_W,
1433 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1434 SE_LOCK_MEMORY_NAME_W,
1435 SE_INCREASE_QUOTA_NAME_W,
1436 SE_MACHINE_ACCOUNT_NAME_W,
1437 SE_TCB_NAME_W,
1438 SE_SECURITY_NAME_W,
1439 SE_TAKE_OWNERSHIP_NAME_W,
1440 SE_LOAD_DRIVER_NAME_W,
1441 SE_SYSTEM_PROFILE_NAME_W,
1442 SE_SYSTEMTIME_NAME_W,
1443 SE_PROF_SINGLE_PROCESS_NAME_W,
1444 SE_INC_BASE_PRIORITY_NAME_W,
1445 SE_CREATE_PAGEFILE_NAME_W,
1446 SE_CREATE_PERMANENT_NAME_W,
1447 SE_BACKUP_NAME_W,
1448 SE_RESTORE_NAME_W,
1449 SE_SHUTDOWN_NAME_W,
1450 SE_DEBUG_NAME_W,
1451 SE_AUDIT_NAME_W,
1452 SE_SYSTEM_ENVIRONMENT_NAME_W,
1453 SE_CHANGE_NOTIFY_NAME_W,
1454 SE_REMOTE_SHUTDOWN_NAME_W,
1455 SE_UNDOCK_NAME_W,
1456 SE_SYNC_AGENT_NAME_W,
1457 SE_ENABLE_DELEGATION_NAME_W,
1458 SE_MANAGE_VOLUME_NAME_W,
1459 SE_IMPERSONATE_NAME_W,
1460 SE_CREATE_GLOBAL_NAME_W,
1463 /******************************************************************************
1464 * LookupPrivilegeValueW [ADVAPI32.@]
1466 * See LookupPrivilegeValueA.
1468 BOOL WINAPI
1469 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1471 UINT i;
1473 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1475 if (!ADVAPI_IsLocalComputer(lpSystemName))
1477 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1478 return FALSE;
1480 if (!lpName)
1482 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1483 return FALSE;
1485 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1487 if( !WellKnownPrivNames[i] )
1488 continue;
1489 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1490 continue;
1491 lpLuid->LowPart = i;
1492 lpLuid->HighPart = 0;
1493 TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
1494 lpLuid->HighPart, lpLuid->LowPart );
1495 return TRUE;
1497 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1498 return FALSE;
1501 /******************************************************************************
1502 * LookupPrivilegeValueA [ADVAPI32.@]
1504 * Retrieves LUID used on a system to represent the privilege name.
1506 * PARAMS
1507 * lpSystemName [I] Name of the system
1508 * lpName [I] Name of the privilege
1509 * lpLuid [O] Destination for the resulting LUID
1511 * RETURNS
1512 * Success: TRUE. lpLuid contains the requested LUID.
1513 * Failure: FALSE.
1515 BOOL WINAPI
1516 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1518 UNICODE_STRING lpSystemNameW;
1519 UNICODE_STRING lpNameW;
1520 BOOL ret;
1522 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1523 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1524 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1525 RtlFreeUnicodeString(&lpNameW);
1526 RtlFreeUnicodeString(&lpSystemNameW);
1527 return ret;
1530 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1531 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1533 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1534 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1536 return FALSE;
1539 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1540 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1542 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1543 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1545 return FALSE;
1548 /******************************************************************************
1549 * LookupPrivilegeNameA [ADVAPI32.@]
1551 * See LookupPrivilegeNameW.
1553 BOOL WINAPI
1554 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1555 LPDWORD cchName)
1557 UNICODE_STRING lpSystemNameW;
1558 BOOL ret;
1559 DWORD wLen = 0;
1561 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1563 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1564 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1565 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1567 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1569 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1570 &wLen);
1571 if (ret)
1573 /* Windows crashes if cchName is NULL, so will I */
1574 int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1575 *cchName, NULL, NULL);
1577 if (len == 0)
1579 /* WideCharToMultiByte failed */
1580 ret = FALSE;
1582 else if (len > *cchName)
1584 *cchName = len;
1585 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1586 ret = FALSE;
1588 else
1590 /* WideCharToMultiByte succeeded, output length needs to be
1591 * length not including NULL terminator
1593 *cchName = len - 1;
1596 HeapFree(GetProcessHeap(), 0, lpNameW);
1598 RtlFreeUnicodeString(&lpSystemNameW);
1599 return ret;
1602 /******************************************************************************
1603 * LookupPrivilegeNameW [ADVAPI32.@]
1605 * Retrieves the privilege name referred to by the LUID lpLuid.
1607 * PARAMS
1608 * lpSystemName [I] Name of the system
1609 * lpLuid [I] Privilege value
1610 * lpName [O] Name of the privilege
1611 * cchName [I/O] Number of characters in lpName.
1613 * RETURNS
1614 * Success: TRUE. lpName contains the name of the privilege whose value is
1615 * *lpLuid.
1616 * Failure: FALSE.
1618 * REMARKS
1619 * Only well-known privilege names (those defined in winnt.h) can be retrieved
1620 * using this function.
1621 * If the length of lpName is too small, on return *cchName will contain the
1622 * number of WCHARs needed to contain the privilege, including the NULL
1623 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1624 * On success, *cchName will contain the number of characters stored in
1625 * lpName, NOT including the NULL terminator.
1627 BOOL WINAPI
1628 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1629 LPDWORD cchName)
1631 size_t privNameLen;
1633 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1635 if (!ADVAPI_IsLocalComputer(lpSystemName))
1637 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1638 return FALSE;
1640 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1641 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1643 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1644 return FALSE;
1646 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1647 /* Windows crashes if cchName is NULL, so will I */
1648 if (*cchName <= privNameLen)
1650 *cchName = privNameLen + 1;
1651 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1652 return FALSE;
1654 else
1656 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1657 *cchName = privNameLen;
1658 return TRUE;
1662 /******************************************************************************
1663 * GetFileSecurityA [ADVAPI32.@]
1665 * Obtains Specified information about the security of a file or directory.
1667 * PARAMS
1668 * lpFileName [I] Name of the file to get info for
1669 * RequestedInformation [I] SE_ flags from "winnt.h"
1670 * pSecurityDescriptor [O] Destination for security information
1671 * nLength [I] Length of pSecurityDescriptor
1672 * lpnLengthNeeded [O] Destination for length of returned security information
1674 * RETURNS
1675 * Success: TRUE. pSecurityDescriptor contains the requested information.
1676 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
1678 * NOTES
1679 * The information returned is constrained by the callers access rights and
1680 * privileges.
1682 BOOL WINAPI
1683 GetFileSecurityA( LPCSTR lpFileName,
1684 SECURITY_INFORMATION RequestedInformation,
1685 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1686 DWORD nLength, LPDWORD lpnLengthNeeded )
1688 DWORD len;
1689 BOOL r;
1690 LPWSTR name = NULL;
1692 if( lpFileName )
1694 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1695 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1696 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1699 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1700 nLength, lpnLengthNeeded );
1701 HeapFree( GetProcessHeap(), 0, name );
1703 return r;
1706 /******************************************************************************
1707 * GetFileSecurityW [ADVAPI32.@]
1709 * See GetFileSecurityA.
1711 BOOL WINAPI
1712 GetFileSecurityW( LPCWSTR lpFileName,
1713 SECURITY_INFORMATION RequestedInformation,
1714 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1715 DWORD nLength, LPDWORD lpnLengthNeeded )
1717 DWORD nNeeded;
1718 LPBYTE pBuffer;
1719 DWORD iLocNow;
1720 SECURITY_DESCRIPTOR_RELATIVE *pSDRelative;
1722 if(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(lpFileName))
1723 return FALSE;
1725 FIXME("(%s) : returns fake SECURITY_DESCRIPTOR\n", debugstr_w(lpFileName) );
1727 nNeeded = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1728 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1729 nNeeded += sizeof(sidWorld);
1730 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1731 nNeeded += sizeof(sidWorld);
1732 if (RequestedInformation & DACL_SECURITY_INFORMATION)
1733 nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1734 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1735 nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1737 *lpnLengthNeeded = nNeeded;
1739 if (nNeeded > nLength)
1740 return TRUE;
1742 if (!InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
1743 return FALSE;
1745 pSDRelative = (PISECURITY_DESCRIPTOR_RELATIVE) pSecurityDescriptor;
1746 pSDRelative->Control |= SE_SELF_RELATIVE;
1747 pBuffer = (LPBYTE) pSDRelative;
1748 iLocNow = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1750 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1752 memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1753 pSDRelative->Owner = iLocNow;
1754 iLocNow += sizeof(sidWorld);
1756 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1758 memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1759 pSDRelative->Group = iLocNow;
1760 iLocNow += sizeof(sidWorld);
1762 if (RequestedInformation & DACL_SECURITY_INFORMATION)
1764 GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1765 pSDRelative->Dacl = iLocNow;
1766 iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1768 if (RequestedInformation & SACL_SECURITY_INFORMATION)
1770 GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1771 pSDRelative->Sacl = iLocNow;
1772 /* iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL; */
1774 return TRUE;
1778 /******************************************************************************
1779 * LookupAccountSidA [ADVAPI32.@]
1781 BOOL WINAPI
1782 LookupAccountSidA(
1783 IN LPCSTR system,
1784 IN PSID sid,
1785 OUT LPSTR account,
1786 IN OUT LPDWORD accountSize,
1787 OUT LPSTR domain,
1788 IN OUT LPDWORD domainSize,
1789 OUT PSID_NAME_USE name_use )
1791 DWORD len;
1792 BOOL r;
1793 LPWSTR systemW = NULL;
1794 LPWSTR accountW = NULL;
1795 LPWSTR domainW = NULL;
1796 DWORD accountSizeW = *accountSize * sizeof(WCHAR);
1797 DWORD domainSizeW = *domainSize * sizeof(WCHAR);
1799 TRACE("(%s,sid=%s,%p,%p(%lu),%p,%p(%lu),%p)\n",
1800 debugstr_a(system),debugstr_sid(sid),
1801 account,accountSize,accountSize?*accountSize:0,
1802 domain,domainSize,domainSize?*domainSize:0,
1803 name_use);
1805 if (system) {
1806 len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1807 systemW = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
1808 MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1810 accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW );
1811 domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW );
1813 r = LookupAccountSidW(systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1815 if (r) {
1816 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1817 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1818 *accountSize = len;
1820 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1821 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1822 *domainSize = len;
1825 HeapFree( GetProcessHeap(), 0, systemW );
1826 HeapFree( GetProcessHeap(), 0, accountW );
1827 HeapFree( GetProcessHeap(), 0, domainW );
1829 return r;
1832 /******************************************************************************
1833 * LookupAccountSidW [ADVAPI32.@]
1835 * PARAMS
1836 * system []
1837 * sid []
1838 * account []
1839 * accountSize []
1840 * domain []
1841 * domainSize []
1842 * name_use []
1845 BOOL WINAPI
1846 LookupAccountSidW(
1847 IN LPCWSTR system,
1848 IN PSID sid,
1849 OUT LPWSTR account,
1850 IN OUT LPDWORD accountSize,
1851 OUT LPWSTR domain,
1852 IN OUT LPDWORD domainSize,
1853 OUT PSID_NAME_USE name_use )
1855 int i, j;
1856 const WCHAR * ac = NULL;
1857 const WCHAR * dm = NULL;
1858 SID_NAME_USE use = 0;
1859 LPWSTR computer_name = NULL;
1861 TRACE("(%s,sid=%s,%p,%p(%lu),%p,%p(%lu),%p)\n",
1862 debugstr_w(system),debugstr_sid(sid),
1863 account,accountSize,accountSize?*accountSize:0,
1864 domain,domainSize,domainSize?*domainSize:0,
1865 name_use);
1867 if (!ADVAPI_IsLocalComputer(system)) {
1868 FIXME("Only local computer supported!\n");
1869 SetLastError(ERROR_NONE_MAPPED);
1870 return FALSE;
1873 /* check the well known SIDs first */
1874 for (i = 0; i <= 60; i++) {
1875 if (IsWellKnownSid(sid, i)) {
1876 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1877 if (ACCOUNT_SIDS[j].type == i) {
1878 ac = ACCOUNT_SIDS[j].account;
1879 dm = ACCOUNT_SIDS[j].domain;
1880 use = ACCOUNT_SIDS[j].name_use;
1883 break;
1887 if (dm == NULL) {
1888 MAX_SID local;
1889 MAX_SID admin;
1890 MAX_SID guest;
1892 /* check for the local computer next */
1893 if (ADVAPI_GetComputerSid(&local)) {
1894 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1895 BOOL result;
1897 computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1898 result = GetComputerNameW(computer_name, &size);
1900 if (result) {
1901 CopySid(GetSidLengthRequired(local.SubAuthorityCount), &admin, &local);
1902 admin.SubAuthorityCount++;
1903 admin.SubAuthority[4] = DOMAIN_USER_RID_ADMIN;
1904 CopySid(GetSidLengthRequired(local.SubAuthorityCount), &guest, &local);
1905 guest.SubAuthorityCount++;
1906 guest.SubAuthority[4] = DOMAIN_USER_RID_GUEST;
1908 if (EqualSid(sid, &local)) {
1909 dm = computer_name;
1910 ac = Blank;
1911 use = 3;
1912 } else if (EqualSid(sid, &admin)) {
1913 dm = computer_name;
1914 ac = Administrator;
1915 use = 1;
1916 } else if (EqualSid(sid, &guest)) {
1917 dm = computer_name;
1918 ac = Guest;
1919 use = 1;
1925 if (dm) {
1926 *accountSize = strlenW(ac)+1;
1927 if (account && (*accountSize > strlenW(ac)))
1928 strcpyW(account, ac);
1930 *domainSize = strlenW(dm)+1;
1931 if (domain && (*domainSize > strlenW(dm)))
1932 strcpyW(domain,dm);
1934 *name_use = use;
1935 HeapFree(GetProcessHeap(), 0, computer_name);
1936 return TRUE;
1939 HeapFree(GetProcessHeap(), 0, computer_name);
1940 SetLastError(ERROR_NONE_MAPPED);
1941 return FALSE;
1944 /******************************************************************************
1945 * SetFileSecurityA [ADVAPI32.@]
1947 * See SetFileSecurityW.
1949 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1950 SECURITY_INFORMATION RequestedInformation,
1951 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1953 DWORD len;
1954 BOOL r;
1955 LPWSTR name = NULL;
1957 if( lpFileName )
1959 len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1960 name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1961 MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1964 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
1965 HeapFree( GetProcessHeap(), 0, name );
1967 return r;
1970 /******************************************************************************
1971 * SetFileSecurityW [ADVAPI32.@]
1973 * Sets the security of a file or directory.
1975 * PARAMS
1976 * lpFileName []
1977 * RequestedInformation []
1978 * pSecurityDescriptor []
1980 * RETURNS
1981 * Success: TRUE.
1982 * Failure: FALSE.
1984 BOOL WINAPI
1985 SetFileSecurityW( LPCWSTR lpFileName,
1986 SECURITY_INFORMATION RequestedInformation,
1987 PSECURITY_DESCRIPTOR pSecurityDescriptor )
1989 FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1990 return TRUE;
1993 /******************************************************************************
1994 * QueryWindows31FilesMigration [ADVAPI32.@]
1996 * PARAMS
1997 * x1 []
1999 BOOL WINAPI
2000 QueryWindows31FilesMigration( DWORD x1 )
2002 FIXME("(%ld):stub\n",x1);
2003 return TRUE;
2006 /******************************************************************************
2007 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2009 * PARAMS
2010 * x1 []
2011 * x2 []
2012 * x3 []
2013 * x4 []
2015 BOOL WINAPI
2016 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2017 DWORD x4 )
2019 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
2020 return TRUE;
2023 /******************************************************************************
2024 * NotifyBootConfigStatus [ADVAPI32.@]
2026 * PARAMS
2027 * x1 []
2029 BOOL WINAPI
2030 NotifyBootConfigStatus( BOOL x1 )
2032 FIXME("(0x%08d):stub\n",x1);
2033 return 1;
2036 /******************************************************************************
2037 * RevertToSelf [ADVAPI32.@]
2039 * Ends the impersonation of a user.
2041 * PARAMS
2042 * void []
2044 * RETURNS
2045 * Success: TRUE.
2046 * Failure: FALSE.
2048 BOOL WINAPI
2049 RevertToSelf( void )
2051 HANDLE Token = NULL;
2052 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2053 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2056 /******************************************************************************
2057 * ImpersonateSelf [ADVAPI32.@]
2059 * Makes an impersonation token that represents the process user and assigns
2060 * to the current thread.
2062 * PARAMS
2063 * ImpersonationLevel [I] Level at which to impersonate.
2065 * RETURNS
2066 * Success: TRUE.
2067 * Failure: FALSE.
2069 BOOL WINAPI
2070 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2072 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2075 /******************************************************************************
2076 * ImpersonateLoggedOnUser [ADVAPI32.@]
2078 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2080 DWORD size;
2081 NTSTATUS Status;
2082 HANDLE ImpersonationToken;
2083 TOKEN_TYPE Type;
2085 FIXME( "(%p)\n", hToken );
2087 if (!GetTokenInformation( hToken, TokenType, &Type,
2088 sizeof(TOKEN_TYPE), &size ))
2089 return FALSE;
2091 if (Type == TokenPrimary)
2093 OBJECT_ATTRIBUTES ObjectAttributes;
2095 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2097 Status = NtDuplicateToken( hToken,
2098 TOKEN_IMPERSONATE | TOKEN_QUERY,
2099 &ObjectAttributes,
2100 SecurityImpersonation,
2101 TokenImpersonation,
2102 &ImpersonationToken );
2103 if (Status != STATUS_SUCCESS)
2105 ERR( "NtDuplicateToken failed with error 0x%08lx\n", Status );
2106 SetLastError( RtlNtStatusToDosError( Status ) );
2107 return FALSE;
2110 else
2111 ImpersonationToken = hToken;
2113 Status = NtSetInformationThread( GetCurrentThread(),
2114 ThreadImpersonationToken,
2115 &ImpersonationToken,
2116 sizeof(ImpersonationToken) );
2118 if (Type == TokenPrimary)
2119 NtClose( ImpersonationToken );
2121 if (Status != STATUS_SUCCESS)
2123 ERR( "NtSetInformationThread failed with error 0x%08lx\n", Status );
2124 SetLastError( RtlNtStatusToDosError( Status ) );
2125 return FALSE;
2128 return TRUE;
2131 /******************************************************************************
2132 * AccessCheck [ADVAPI32.@]
2134 BOOL WINAPI
2135 AccessCheck(
2136 PSECURITY_DESCRIPTOR SecurityDescriptor,
2137 HANDLE ClientToken,
2138 DWORD DesiredAccess,
2139 PGENERIC_MAPPING GenericMapping,
2140 PPRIVILEGE_SET PrivilegeSet,
2141 LPDWORD PrivilegeSetLength,
2142 LPDWORD GrantedAccess,
2143 LPBOOL AccessStatus)
2145 NTSTATUS access_status;
2146 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2147 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2148 GrantedAccess, &access_status) );
2149 if (ret) *AccessStatus = set_ntstatus( access_status );
2150 return ret;
2154 /******************************************************************************
2155 * AccessCheckByType [ADVAPI32.@]
2157 BOOL WINAPI AccessCheckByType(
2158 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2159 PSID PrincipalSelfSid,
2160 HANDLE ClientToken,
2161 DWORD DesiredAccess,
2162 POBJECT_TYPE_LIST ObjectTypeList,
2163 DWORD ObjectTypeListLength,
2164 PGENERIC_MAPPING GenericMapping,
2165 PPRIVILEGE_SET PrivilegeSet,
2166 LPDWORD PrivilegeSetLength,
2167 LPDWORD GrantedAccess,
2168 LPBOOL AccessStatus)
2170 FIXME("stub\n");
2172 *AccessStatus = TRUE;
2174 return !*AccessStatus;
2177 /******************************************************************************
2178 * MapGenericMask [ADVAPI32.@]
2180 * Maps generic access rights into specific access rights according to the
2181 * supplied mapping.
2183 * PARAMS
2184 * AccessMask [I/O] Access rights.
2185 * GenericMapping [I] The mapping between generic and specific rights.
2187 * RETURNS
2188 * Nothing.
2190 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2192 RtlMapGenericMask( AccessMask, GenericMapping );
2195 /*************************************************************************
2196 * SetKernelObjectSecurity [ADVAPI32.@]
2198 BOOL WINAPI SetKernelObjectSecurity (
2199 IN HANDLE Handle,
2200 IN SECURITY_INFORMATION SecurityInformation,
2201 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2203 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2207 /******************************************************************************
2208 * AddAuditAccessAce [ADVAPI32.@]
2210 BOOL WINAPI AddAuditAccessAce(
2211 IN OUT PACL pAcl,
2212 IN DWORD dwAceRevision,
2213 IN DWORD dwAccessMask,
2214 IN PSID pSid,
2215 IN BOOL bAuditSuccess,
2216 IN BOOL bAuditFailure)
2218 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2219 bAuditSuccess, bAuditFailure) );
2222 /******************************************************************************
2223 * LookupAccountNameA [ADVAPI32.@]
2225 BOOL WINAPI
2226 LookupAccountNameA(
2227 IN LPCSTR system,
2228 IN LPCSTR account,
2229 OUT PSID sid,
2230 OUT LPDWORD cbSid,
2231 LPSTR ReferencedDomainName,
2232 IN OUT LPDWORD cbReferencedDomainName,
2233 OUT PSID_NAME_USE name_use )
2235 BOOL ret;
2236 UNICODE_STRING lpSystemW;
2237 UNICODE_STRING lpAccountW;
2238 LPWSTR lpReferencedDomainNameW = NULL;
2240 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2241 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2243 if (ReferencedDomainName)
2244 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2246 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2247 cbReferencedDomainName, name_use);
2249 if (ret && lpReferencedDomainNameW)
2251 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2252 ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2255 RtlFreeUnicodeString(&lpSystemW);
2256 RtlFreeUnicodeString(&lpAccountW);
2257 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2259 return ret;
2262 /******************************************************************************
2263 * LookupAccountNameW [ADVAPI32.@]
2265 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2266 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2267 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2269 /* Default implementation: Always return a default SID */
2270 SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2271 BOOL ret;
2272 PSID pSid;
2273 static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2275 FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2276 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2278 ret = AllocateAndInitializeSid(&identifierAuthority,
2280 SECURITY_BUILTIN_DOMAIN_RID,
2281 DOMAIN_ALIAS_RID_ADMINS,
2282 0, 0, 0, 0, 0, 0,
2283 &pSid);
2285 if (!ret)
2286 return FALSE;
2288 if (!RtlValidSid(pSid))
2290 FreeSid(pSid);
2291 return FALSE;
2294 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2295 CopySid(*cbSid, Sid, pSid);
2296 if (*cbSid < GetLengthSid(pSid))
2298 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2299 ret = FALSE;
2301 *cbSid = GetLengthSid(pSid);
2303 if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2304 strcpyW(ReferencedDomainName, dm);
2306 if (*cchReferencedDomainName <= strlenW(dm))
2308 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2309 ret = FALSE;
2312 *cchReferencedDomainName = strlenW(dm)+1;
2314 FreeSid(pSid);
2316 return ret;
2319 /******************************************************************************
2320 * PrivilegeCheck [ADVAPI32.@]
2322 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2324 BOOL ret;
2325 BOOLEAN Result;
2327 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2329 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2330 if (ret)
2331 *pfResult = Result;
2332 return ret;
2335 /******************************************************************************
2336 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2338 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2339 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2340 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2341 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2343 FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2344 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2345 SecurityDescriptor, DesiredAccess, GenericMapping,
2346 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2347 return TRUE;
2350 /******************************************************************************
2351 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2353 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2354 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2355 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2356 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2358 FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2359 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2360 SecurityDescriptor, DesiredAccess, GenericMapping,
2361 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2362 return TRUE;
2365 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2367 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2369 return TRUE;
2372 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2374 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2376 return TRUE;
2379 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2381 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2383 return TRUE;
2386 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2387 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2388 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2389 LPBOOL GenerateOnClose)
2391 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2392 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2393 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2394 GenerateOnClose);
2396 return TRUE;
2399 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2400 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2401 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2402 LPBOOL GenerateOnClose)
2404 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2405 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2406 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2407 GenerateOnClose);
2409 return TRUE;
2412 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2413 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2415 FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2416 DesiredAccess, Privileges, AccessGranted);
2418 return TRUE;
2421 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2422 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2424 FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2425 DesiredAccess, Privileges, AccessGranted);
2427 return TRUE;
2430 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2431 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2433 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2434 ClientToken, Privileges, AccessGranted);
2436 return TRUE;
2439 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2440 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2442 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2443 ClientToken, Privileges, AccessGranted);
2445 return TRUE;
2448 /******************************************************************************
2449 * GetSecurityInfo [ADVAPI32.@]
2451 DWORD WINAPI GetSecurityInfo(
2452 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2453 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2454 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2455 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2458 FIXME("stub!\n");
2459 return ERROR_BAD_PROVIDER;
2462 /******************************************************************************
2463 * GetSecurityInfoExW [ADVAPI32.@]
2465 DWORD WINAPI GetSecurityInfoExW(
2466 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2467 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2468 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
2469 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2472 FIXME("stub!\n");
2473 return ERROR_BAD_PROVIDER;
2476 /******************************************************************************
2477 * BuildExplicitAccessWithNameA [ADVAPI32.@]
2479 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2480 LPSTR pTrusteeName, DWORD AccessPermissions,
2481 ACCESS_MODE AccessMode, DWORD Inheritance )
2483 TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2484 AccessPermissions, AccessMode, Inheritance);
2486 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2487 pExplicitAccess->grfAccessMode = AccessMode;
2488 pExplicitAccess->grfInheritance = Inheritance;
2490 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2491 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2492 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2493 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2494 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2497 /******************************************************************************
2498 * BuildExplicitAccessWithNameW [ADVAPI32.@]
2500 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2501 LPWSTR pTrusteeName, DWORD AccessPermissions,
2502 ACCESS_MODE AccessMode, DWORD Inheritance )
2504 TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2505 AccessPermissions, AccessMode, Inheritance);
2507 pExplicitAccess->grfAccessPermissions = AccessPermissions;
2508 pExplicitAccess->grfAccessMode = AccessMode;
2509 pExplicitAccess->grfInheritance = Inheritance;
2511 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2512 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2513 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2514 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2515 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2518 /******************************************************************************
2519 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2521 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2522 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2523 LPSTR InheritedObjectTypeName, LPSTR Name )
2525 DWORD ObjectsPresent = 0;
2527 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2528 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2530 /* Fill the OBJECTS_AND_NAME structure */
2531 pObjName->ObjectType = ObjectType;
2532 if (ObjectTypeName != NULL)
2534 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2537 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2538 if (InheritedObjectTypeName != NULL)
2540 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2543 pObjName->ObjectsPresent = ObjectsPresent;
2544 pObjName->ptstrName = Name;
2546 /* Fill the TRUSTEE structure */
2547 pTrustee->pMultipleTrustee = NULL;
2548 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2549 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2550 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2551 pTrustee->ptstrName = (LPSTR)pObjName;
2554 /******************************************************************************
2555 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2557 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2558 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2559 LPWSTR InheritedObjectTypeName, LPWSTR Name )
2561 DWORD ObjectsPresent = 0;
2563 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2564 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2566 /* Fill the OBJECTS_AND_NAME structure */
2567 pObjName->ObjectType = ObjectType;
2568 if (ObjectTypeName != NULL)
2570 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2573 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2574 if (InheritedObjectTypeName != NULL)
2576 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2579 pObjName->ObjectsPresent = ObjectsPresent;
2580 pObjName->ptstrName = Name;
2582 /* Fill the TRUSTEE structure */
2583 pTrustee->pMultipleTrustee = NULL;
2584 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2585 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2586 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2587 pTrustee->ptstrName = (LPWSTR)pObjName;
2590 /******************************************************************************
2591 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2593 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2594 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2596 DWORD ObjectsPresent = 0;
2598 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2600 /* Fill the OBJECTS_AND_SID structure */
2601 if (pObjectGuid != NULL)
2603 pObjSid->ObjectTypeGuid = *pObjectGuid;
2604 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2606 else
2608 ZeroMemory(&pObjSid->ObjectTypeGuid,
2609 sizeof(GUID));
2612 if (pInheritedObjectGuid != NULL)
2614 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2615 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2617 else
2619 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2620 sizeof(GUID));
2623 pObjSid->ObjectsPresent = ObjectsPresent;
2624 pObjSid->pSid = pSid;
2626 /* Fill the TRUSTEE structure */
2627 pTrustee->pMultipleTrustee = NULL;
2628 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2629 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2630 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2631 pTrustee->ptstrName = (LPSTR) pObjSid;
2634 /******************************************************************************
2635 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2637 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2638 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2640 DWORD ObjectsPresent = 0;
2642 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2644 /* Fill the OBJECTS_AND_SID structure */
2645 if (pObjectGuid != NULL)
2647 pObjSid->ObjectTypeGuid = *pObjectGuid;
2648 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2650 else
2652 ZeroMemory(&pObjSid->ObjectTypeGuid,
2653 sizeof(GUID));
2656 if (pInheritedObjectGuid != NULL)
2658 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2659 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2661 else
2663 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2664 sizeof(GUID));
2667 pObjSid->ObjectsPresent = ObjectsPresent;
2668 pObjSid->pSid = pSid;
2670 /* Fill the TRUSTEE structure */
2671 pTrustee->pMultipleTrustee = NULL;
2672 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2673 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2674 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2675 pTrustee->ptstrName = (LPWSTR) pObjSid;
2678 /******************************************************************************
2679 * BuildTrusteeWithSidA [ADVAPI32.@]
2681 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2683 TRACE("%p %p\n", pTrustee, pSid);
2685 pTrustee->pMultipleTrustee = NULL;
2686 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2687 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2688 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2689 pTrustee->ptstrName = (LPSTR) pSid;
2692 /******************************************************************************
2693 * BuildTrusteeWithSidW [ADVAPI32.@]
2695 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2697 TRACE("%p %p\n", pTrustee, pSid);
2699 pTrustee->pMultipleTrustee = NULL;
2700 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2701 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2702 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2703 pTrustee->ptstrName = (LPWSTR) pSid;
2706 /******************************************************************************
2707 * BuildTrusteeWithNameA [ADVAPI32.@]
2709 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2711 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2713 pTrustee->pMultipleTrustee = NULL;
2714 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2715 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2716 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2717 pTrustee->ptstrName = name;
2720 /******************************************************************************
2721 * BuildTrusteeWithNameW [ADVAPI32.@]
2723 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2725 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2727 pTrustee->pMultipleTrustee = NULL;
2728 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2729 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2730 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2731 pTrustee->ptstrName = name;
2734 /******************************************************************************
2735 * GetTrusteeFormA [ADVAPI32.@]
2737 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
2739 TRACE("(%p)\n", pTrustee);
2741 if (!pTrustee)
2742 return TRUSTEE_BAD_FORM;
2744 return pTrustee->TrusteeForm;
2747 /******************************************************************************
2748 * GetTrusteeFormW [ADVAPI32.@]
2750 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
2752 TRACE("(%p)\n", pTrustee);
2754 if (!pTrustee)
2755 return TRUSTEE_BAD_FORM;
2757 return pTrustee->TrusteeForm;
2760 /******************************************************************************
2761 * GetTrusteeNameA [ADVAPI32.@]
2763 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
2765 TRACE("(%p)\n", pTrustee);
2767 if (!pTrustee)
2768 return NULL;
2770 return pTrustee->ptstrName;
2773 /******************************************************************************
2774 * GetTrusteeNameW [ADVAPI32.@]
2776 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
2778 TRACE("(%p)\n", pTrustee);
2780 if (!pTrustee)
2781 return NULL;
2783 return pTrustee->ptstrName;
2786 /******************************************************************************
2787 * GetTrusteeTypeA [ADVAPI32.@]
2789 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
2791 TRACE("(%p)\n", pTrustee);
2793 if (!pTrustee)
2794 return TRUSTEE_IS_UNKNOWN;
2796 return pTrustee->TrusteeType;
2799 /******************************************************************************
2800 * GetTrusteeTypeW [ADVAPI32.@]
2802 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
2804 TRACE("(%p)\n", pTrustee);
2806 if (!pTrustee)
2807 return TRUSTEE_IS_UNKNOWN;
2809 return pTrustee->TrusteeType;
2812 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2813 DWORD nAclInformationLength,
2814 ACL_INFORMATION_CLASS dwAclInformationClass )
2816 FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2817 nAclInformationLength, dwAclInformationClass);
2819 return TRUE;
2822 /******************************************************************************
2823 * SetEntriesInAclA [ADVAPI32.@]
2825 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2826 PACL OldAcl, PACL* NewAcl )
2828 FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2829 return ERROR_CALL_NOT_IMPLEMENTED;
2832 /******************************************************************************
2833 * SetEntriesInAclW [ADVAPI32.@]
2835 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2836 PACL OldAcl, PACL* NewAcl )
2838 FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2839 return ERROR_CALL_NOT_IMPLEMENTED;
2842 /******************************************************************************
2843 * SetNamedSecurityInfoA [ADVAPI32.@]
2845 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2846 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2847 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2849 DWORD len;
2850 LPWSTR wstr = NULL;
2851 DWORD r;
2853 TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2854 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2856 if( pObjectName )
2858 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2859 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2860 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2863 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2864 psidGroup, pDacl, pSacl );
2866 HeapFree( GetProcessHeap(), 0, wstr );
2868 return r;
2871 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2872 PSECURITY_DESCRIPTOR ModificationDescriptor,
2873 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2874 PGENERIC_MAPPING GenericMapping,
2875 HANDLE Token )
2877 FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2878 ObjectsSecurityDescriptor, GenericMapping, Token);
2880 return TRUE;
2883 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2884 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2885 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2887 FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2888 ControlBitsToSet);
2890 return TRUE;
2893 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2895 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2898 /******************************************************************************
2899 * AreAnyAccessesGranted [ADVAPI32.@]
2901 * Determines whether or not any of a set of specified access permissions have
2902 * been granted or not.
2904 * PARAMS
2905 * GrantedAccess [I] The permissions that have been granted.
2906 * DesiredAccess [I] The permissions that you want to have.
2908 * RETURNS
2909 * Nonzero if any of the permissions have been granted, zero if none of the
2910 * permissions have been granted.
2913 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2915 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2918 /******************************************************************************
2919 * SetNamedSecurityInfoW [ADVAPI32.@]
2921 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2922 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2923 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2925 FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2926 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2927 return ERROR_SUCCESS;
2930 /******************************************************************************
2931 * GetExplicitEntriesFromAclA [ADVAPI32.@]
2933 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2934 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2936 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2937 return ERROR_CALL_NOT_IMPLEMENTED;
2940 /******************************************************************************
2941 * GetExplicitEntriesFromAclW [ADVAPI32.@]
2943 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2944 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2946 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2947 return ERROR_CALL_NOT_IMPLEMENTED;
2951 /******************************************************************************
2952 * ParseAclStringFlags
2954 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2956 DWORD flags = 0;
2957 LPCWSTR szAcl = *StringAcl;
2959 while (*szAcl != '(')
2961 if (*szAcl == 'P')
2963 flags |= SE_DACL_PROTECTED;
2965 else if (*szAcl == 'A')
2967 szAcl++;
2968 if (*szAcl == 'R')
2969 flags |= SE_DACL_AUTO_INHERIT_REQ;
2970 else if (*szAcl == 'I')
2971 flags |= SE_DACL_AUTO_INHERITED;
2973 szAcl++;
2976 *StringAcl = szAcl;
2977 return flags;
2980 /******************************************************************************
2981 * ParseAceStringType
2983 static const ACEFLAG AceType[] =
2985 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2986 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
2987 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
2988 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
2990 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2991 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
2992 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
2993 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2995 { NULL, 0 },
2998 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3000 UINT len = 0;
3001 LPCWSTR szAcl = *StringAcl;
3002 const ACEFLAG *lpaf = AceType;
3004 while (lpaf->wstr &&
3005 (len = strlenW(lpaf->wstr)) &&
3006 strncmpW(lpaf->wstr, szAcl, len))
3007 lpaf++;
3009 if (!lpaf->wstr)
3010 return 0;
3012 *StringAcl += len;
3013 return lpaf->value;
3017 /******************************************************************************
3018 * ParseAceStringFlags
3020 static const ACEFLAG AceFlags[] =
3022 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3023 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
3024 { SDDL_INHERITED, INHERITED_ACE },
3025 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
3026 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
3027 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
3028 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
3029 { NULL, 0 },
3032 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3034 UINT len = 0;
3035 BYTE flags = 0;
3036 LPCWSTR szAcl = *StringAcl;
3038 while (*szAcl != ';')
3040 const ACEFLAG *lpaf = AceFlags;
3042 while (lpaf->wstr &&
3043 (len = strlenW(lpaf->wstr)) &&
3044 strncmpW(lpaf->wstr, szAcl, len))
3045 lpaf++;
3047 if (!lpaf->wstr)
3048 return 0;
3050 flags |= lpaf->value;
3051 szAcl += len;
3054 *StringAcl = szAcl;
3055 return flags;
3059 /******************************************************************************
3060 * ParseAceStringRights
3062 static const ACEFLAG AceRights[] =
3064 { SDDL_GENERIC_ALL, GENERIC_ALL },
3065 { SDDL_GENERIC_READ, GENERIC_READ },
3066 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
3067 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3068 { SDDL_READ_CONTROL, READ_CONTROL },
3069 { SDDL_STANDARD_DELETE, DELETE },
3070 { SDDL_WRITE_DAC, WRITE_DAC },
3071 { SDDL_WRITE_OWNER, WRITE_OWNER },
3072 { NULL, 0 },
3075 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3077 UINT len = 0;
3078 DWORD rights = 0;
3079 LPCWSTR szAcl = *StringAcl;
3081 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3083 LPCWSTR p = szAcl;
3085 while (*p && *p != ';')
3086 p++;
3088 if (p - szAcl <= 8)
3090 rights = strtoulW(szAcl, NULL, 16);
3091 *StringAcl = p;
3093 else
3094 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3096 else
3098 while (*szAcl != ';')
3100 const ACEFLAG *lpaf = AceRights;
3102 while (lpaf->wstr &&
3103 (len = strlenW(lpaf->wstr)) &&
3104 strncmpW(lpaf->wstr, szAcl, len))
3106 lpaf++;
3109 if (!lpaf->wstr)
3110 return 0;
3112 rights |= lpaf->value;
3113 szAcl += len;
3117 *StringAcl = szAcl;
3118 return rights;
3122 /******************************************************************************
3123 * ParseStringAclToAcl
3125 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
3127 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
3128 PACL pAcl, LPDWORD cBytes)
3130 DWORD val;
3131 DWORD sidlen;
3132 DWORD length = sizeof(ACL);
3133 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3135 TRACE("%s\n", debugstr_w(StringAcl));
3137 if (!StringAcl)
3138 return FALSE;
3140 if (pAcl) /* pAce is only useful if we're setting values */
3141 pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
3143 /* Parse ACL flags */
3144 *lpdwFlags = ParseAclStringFlags(&StringAcl);
3146 /* Parse ACE */
3147 while (*StringAcl == '(')
3149 StringAcl++;
3151 /* Parse ACE type */
3152 val = ParseAceStringType(&StringAcl);
3153 if (pAce)
3154 pAce->Header.AceType = (BYTE) val;
3155 if (*StringAcl != ';')
3156 goto lerr;
3157 StringAcl++;
3159 /* Parse ACE flags */
3160 val = ParseAceStringFlags(&StringAcl);
3161 if (pAce)
3162 pAce->Header.AceFlags = (BYTE) val;
3163 if (*StringAcl != ';')
3164 goto lerr;
3165 StringAcl++;
3167 /* Parse ACE rights */
3168 val = ParseAceStringRights(&StringAcl);
3169 if (pAce)
3170 pAce->Mask = val;
3171 if (*StringAcl != ';')
3172 goto lerr;
3173 StringAcl++;
3175 /* Parse ACE object guid */
3176 if (*StringAcl != ';')
3178 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3179 goto lerr;
3181 StringAcl++;
3183 /* Parse ACE inherit object guid */
3184 if (*StringAcl != ';')
3186 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3187 goto lerr;
3189 StringAcl++;
3191 /* Parse ACE account sid */
3192 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3194 while (*StringAcl && *StringAcl != ')')
3195 StringAcl++;
3198 if (*StringAcl != ')')
3199 goto lerr;
3200 StringAcl++;
3202 length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3205 *cBytes = length;
3206 return TRUE;
3208 lerr:
3209 WARN("Invalid ACE string format\n");
3210 return FALSE;
3214 /******************************************************************************
3215 * ParseStringSecurityDescriptorToSecurityDescriptor
3217 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3218 LPCWSTR StringSecurityDescriptor,
3219 SECURITY_DESCRIPTOR* SecurityDescriptor,
3220 LPDWORD cBytes)
3222 BOOL bret = FALSE;
3223 WCHAR toktype;
3224 WCHAR tok[MAX_PATH];
3225 LPCWSTR lptoken;
3226 LPBYTE lpNext = NULL;
3227 DWORD len;
3229 *cBytes = 0;
3231 if (SecurityDescriptor)
3232 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3234 while (*StringSecurityDescriptor)
3236 toktype = *StringSecurityDescriptor;
3238 /* Expect char identifier followed by ':' */
3239 StringSecurityDescriptor++;
3240 if (*StringSecurityDescriptor != ':')
3242 SetLastError(ERROR_INVALID_PARAMETER);
3243 goto lend;
3245 StringSecurityDescriptor++;
3247 /* Extract token */
3248 lptoken = StringSecurityDescriptor;
3249 while (*lptoken && *lptoken != ':')
3250 lptoken++;
3252 if (*lptoken)
3253 lptoken--;
3255 len = lptoken - StringSecurityDescriptor;
3256 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3257 tok[len] = 0;
3259 switch (toktype)
3261 case 'O':
3263 DWORD bytes;
3265 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3266 goto lend;
3268 if (SecurityDescriptor)
3270 SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3271 lpNext += bytes; /* Advance to next token */
3274 *cBytes += bytes;
3276 break;
3279 case 'G':
3281 DWORD bytes;
3283 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3284 goto lend;
3286 if (SecurityDescriptor)
3288 SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3289 lpNext += bytes; /* Advance to next token */
3292 *cBytes += bytes;
3294 break;
3297 case 'D':
3299 DWORD flags;
3300 DWORD bytes;
3302 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3303 goto lend;
3305 if (SecurityDescriptor)
3307 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3308 SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3309 lpNext += bytes; /* Advance to next token */
3312 *cBytes += bytes;
3314 break;
3317 case 'S':
3319 DWORD flags;
3320 DWORD bytes;
3322 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3323 goto lend;
3325 if (SecurityDescriptor)
3327 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3328 SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3329 lpNext += bytes; /* Advance to next token */
3332 *cBytes += bytes;
3334 break;
3337 default:
3338 FIXME("Unknown token\n");
3339 SetLastError(ERROR_INVALID_PARAMETER);
3340 goto lend;
3343 StringSecurityDescriptor = lptoken;
3346 bret = TRUE;
3348 lend:
3349 return bret;
3352 /******************************************************************************
3353 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3355 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3356 LPCSTR StringSecurityDescriptor,
3357 DWORD StringSDRevision,
3358 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3359 PULONG SecurityDescriptorSize)
3361 UINT len;
3362 BOOL ret = FALSE;
3363 LPWSTR StringSecurityDescriptorW;
3365 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3366 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3368 if (StringSecurityDescriptorW)
3370 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3372 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3373 StringSDRevision, SecurityDescriptor,
3374 SecurityDescriptorSize);
3375 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3378 return ret;
3381 /******************************************************************************
3382 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3384 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3385 LPCWSTR StringSecurityDescriptor,
3386 DWORD StringSDRevision,
3387 PSECURITY_DESCRIPTOR* SecurityDescriptor,
3388 PULONG SecurityDescriptorSize)
3390 DWORD cBytes;
3391 SECURITY_DESCRIPTOR* psd;
3392 BOOL bret = FALSE;
3394 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3396 if (GetVersion() & 0x80000000)
3398 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3399 goto lend;
3401 else if (StringSDRevision != SID_REVISION)
3403 SetLastError(ERROR_UNKNOWN_REVISION);
3404 goto lend;
3407 /* Compute security descriptor length */
3408 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3409 NULL, &cBytes))
3410 goto lend;
3412 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3413 GMEM_ZEROINIT, cBytes);
3415 psd->Revision = SID_REVISION;
3416 psd->Control |= SE_SELF_RELATIVE;
3418 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3419 psd, &cBytes))
3421 LocalFree(psd);
3422 goto lend;
3425 if (SecurityDescriptorSize)
3426 *SecurityDescriptorSize = cBytes;
3428 bret = TRUE;
3430 lend:
3431 TRACE(" ret=%d\n", bret);
3432 return bret;
3435 /******************************************************************************
3436 * ConvertStringSidToSidW [ADVAPI32.@]
3438 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3440 BOOL bret = FALSE;
3441 DWORD cBytes;
3443 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3444 if (GetVersion() & 0x80000000)
3445 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3446 else if (!StringSid || !Sid)
3447 SetLastError(ERROR_INVALID_PARAMETER);
3448 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3450 PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3452 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3453 if (!bret)
3454 LocalFree(*Sid);
3456 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3457 return bret;
3460 /******************************************************************************
3461 * ConvertStringSidToSidA [ADVAPI32.@]
3463 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3465 BOOL bret = FALSE;
3467 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3468 if (GetVersion() & 0x80000000)
3469 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3470 else if (!StringSid || !Sid)
3471 SetLastError(ERROR_INVALID_PARAMETER);
3472 else
3474 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3475 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3476 len * sizeof(WCHAR));
3478 MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3479 bret = ConvertStringSidToSidW(wStringSid, Sid);
3480 HeapFree(GetProcessHeap(), 0, wStringSid);
3482 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3483 return bret;
3486 /******************************************************************************
3487 * ConvertSidToStringSidW [ADVAPI32.@]
3489 * format of SID string is:
3490 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3491 * where
3492 * <rev> is the revision of the SID encoded as decimal
3493 * <auth> is the identifier authority encoded as hex
3494 * <subauthN> is the subauthority id encoded as decimal
3496 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3498 DWORD sz, i;
3499 LPWSTR str;
3500 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3501 WCHAR subauthfmt[] = { '-','%','u',0 };
3502 SID* pisid=pSid;
3504 TRACE("%p %p\n", pSid, pstr );
3506 if( !IsValidSid( pSid ) )
3507 return FALSE;
3509 if (pisid->Revision != SDDL_REVISION)
3510 return FALSE;
3511 if (pisid->IdentifierAuthority.Value[0] ||
3512 pisid->IdentifierAuthority.Value[1])
3514 FIXME("not matching MS' bugs\n");
3515 return FALSE;
3518 sz = 14 + pisid->SubAuthorityCount * 11;
3519 str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3520 sprintfW( str, fmt, pisid->Revision, MAKELONG(
3521 MAKEWORD( pisid->IdentifierAuthority.Value[5],
3522 pisid->IdentifierAuthority.Value[4] ),
3523 MAKEWORD( pisid->IdentifierAuthority.Value[3],
3524 pisid->IdentifierAuthority.Value[2] ) ) );
3525 for( i=0; i<pisid->SubAuthorityCount; i++ )
3526 sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3527 *pstr = str;
3529 return TRUE;
3532 /******************************************************************************
3533 * ConvertSidToStringSidA [ADVAPI32.@]
3535 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3537 LPWSTR wstr = NULL;
3538 LPSTR str;
3539 UINT len;
3541 TRACE("%p %p\n", pSid, pstr );
3543 if( !ConvertSidToStringSidW( pSid, &wstr ) )
3544 return FALSE;
3546 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3547 str = LocalAlloc( 0, len );
3548 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3549 LocalFree( wstr );
3551 *pstr = str;
3553 return TRUE;
3556 BOOL WINAPI CreatePrivateObjectSecurity(
3557 PSECURITY_DESCRIPTOR ParentDescriptor,
3558 PSECURITY_DESCRIPTOR CreatorDescriptor,
3559 PSECURITY_DESCRIPTOR* NewDescriptor,
3560 BOOL IsDirectoryObject,
3561 HANDLE Token,
3562 PGENERIC_MAPPING GenericMapping )
3564 FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3565 NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3567 return FALSE;
3570 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3572 FIXME("%p - stub\n", ObjectDescriptor);
3574 return TRUE;
3577 BOOL WINAPI CreateProcessAsUserA(
3578 HANDLE hToken,
3579 LPCSTR lpApplicationName,
3580 LPSTR lpCommandLine,
3581 LPSECURITY_ATTRIBUTES lpProcessAttributes,
3582 LPSECURITY_ATTRIBUTES lpThreadAttributes,
3583 BOOL bInheritHandles,
3584 DWORD dwCreationFlags,
3585 LPVOID lpEnvironment,
3586 LPCSTR lpCurrentDirectory,
3587 LPSTARTUPINFOA lpStartupInfo,
3588 LPPROCESS_INFORMATION lpProcessInformation )
3590 FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3591 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3592 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3594 return FALSE;
3597 BOOL WINAPI CreateProcessAsUserW(
3598 HANDLE hToken,
3599 LPCWSTR lpApplicationName,
3600 LPWSTR lpCommandLine,
3601 LPSECURITY_ATTRIBUTES lpProcessAttributes,
3602 LPSECURITY_ATTRIBUTES lpThreadAttributes,
3603 BOOL bInheritHandles,
3604 DWORD dwCreationFlags,
3605 LPVOID lpEnvironment,
3606 LPCWSTR lpCurrentDirectory,
3607 LPSTARTUPINFOW lpStartupInfo,
3608 LPPROCESS_INFORMATION lpProcessInformation )
3610 FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - semi- stub\n", hToken,
3611 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3612 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
3613 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3615 /* We should create the process with a suspended main thread */
3616 if (!CreateProcessW (lpApplicationName,
3617 lpCommandLine,
3618 lpProcessAttributes,
3619 lpThreadAttributes,
3620 bInheritHandles,
3621 dwCreationFlags, /* CREATE_SUSPENDED */
3622 lpEnvironment,
3623 lpCurrentDirectory,
3624 lpStartupInfo,
3625 lpProcessInformation))
3627 return FALSE;
3630 return TRUE;
3633 BOOL WINAPI DuplicateTokenEx(
3634 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3635 LPSECURITY_ATTRIBUTES lpTokenAttributes,
3636 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3637 TOKEN_TYPE TokenType,
3638 PHANDLE DuplicateTokenHandle )
3640 OBJECT_ATTRIBUTES ObjectAttributes;
3642 TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3643 ImpersonationLevel, TokenType, DuplicateTokenHandle);
3645 InitializeObjectAttributes(
3646 &ObjectAttributes,
3647 NULL,
3648 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3649 NULL,
3650 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3652 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3653 dwDesiredAccess,
3654 &ObjectAttributes,
3655 ImpersonationLevel,
3656 TokenType,
3657 DuplicateTokenHandle ) );
3660 BOOL WINAPI DuplicateToken(
3661 HANDLE ExistingTokenHandle,
3662 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3663 PHANDLE DuplicateTokenHandle )
3665 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3666 NULL, ImpersonationLevel, TokenImpersonation,
3667 DuplicateTokenHandle );
3670 BOOL WINAPI EnumDependentServicesA(
3671 SC_HANDLE hService,
3672 DWORD dwServiceState,
3673 LPENUM_SERVICE_STATUSA lpServices,
3674 DWORD cbBufSize,
3675 LPDWORD pcbBytesNeeded,
3676 LPDWORD lpServicesReturned )
3678 FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3679 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3681 return FALSE;
3684 BOOL WINAPI EnumDependentServicesW(
3685 SC_HANDLE hService,
3686 DWORD dwServiceState,
3687 LPENUM_SERVICE_STATUSW lpServices,
3688 DWORD cbBufSize,
3689 LPDWORD pcbBytesNeeded,
3690 LPDWORD lpServicesReturned )
3692 FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3693 lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3695 return FALSE;
3698 /******************************************************************************
3699 * ComputeStringSidSize
3701 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3703 DWORD size = sizeof(SID);
3705 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3707 int ctok = 0;
3708 while (*StringSid)
3710 if (*StringSid == '-')
3711 ctok++;
3712 StringSid++;
3715 if (ctok > 3)
3716 size += (ctok - 3) * sizeof(DWORD);
3718 else /* String constant format - Only available in winxp and above */
3720 int i;
3722 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3723 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3724 size += (WellKnownSids[i].Sid.SubAuthorityCount - 1) * sizeof(DWORD);
3727 return size;
3730 /******************************************************************************
3731 * ParseStringSidToSid
3733 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3735 BOOL bret = FALSE;
3736 SID* pisid=pSid;
3738 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3739 if (!StringSid)
3741 SetLastError(ERROR_INVALID_PARAMETER);
3742 TRACE("StringSid is NULL, returning FALSE\n");
3743 return FALSE;
3746 *cBytes = ComputeStringSidSize(StringSid);
3747 if (!pisid) /* Simply compute the size */
3749 TRACE("only size requested, returning TRUE\n");
3750 return TRUE;
3753 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3755 DWORD i = 0, identAuth;
3756 DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3758 StringSid += 2; /* Advance to Revision */
3759 pisid->Revision = atoiW(StringSid);
3761 if (pisid->Revision != SDDL_REVISION)
3763 TRACE("Revision %d is unknown\n", pisid->Revision);
3764 goto lend; /* ERROR_INVALID_SID */
3766 if (csubauth == 0)
3768 TRACE("SubAuthorityCount is 0\n");
3769 goto lend; /* ERROR_INVALID_SID */
3772 pisid->SubAuthorityCount = csubauth;
3774 /* Advance to identifier authority */
3775 while (*StringSid && *StringSid != '-')
3776 StringSid++;
3777 if (*StringSid == '-')
3778 StringSid++;
3780 /* MS' implementation can't handle values greater than 2^32 - 1, so
3781 * we don't either; assume most significant bytes are always 0
3783 pisid->IdentifierAuthority.Value[0] = 0;
3784 pisid->IdentifierAuthority.Value[1] = 0;
3785 identAuth = atoiW(StringSid);
3786 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3787 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3788 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3789 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3791 /* Advance to first sub authority */
3792 while (*StringSid && *StringSid != '-')
3793 StringSid++;
3794 if (*StringSid == '-')
3795 StringSid++;
3797 while (*StringSid)
3799 while (*StringSid && *StringSid != '-')
3800 StringSid++;
3801 if (*StringSid == '-')
3802 StringSid++;
3804 pisid->SubAuthority[i++] = atoiW(StringSid);
3807 if (i != pisid->SubAuthorityCount)
3808 goto lend; /* ERROR_INVALID_SID */
3810 bret = TRUE;
3812 else /* String constant format - Only available in winxp and above */
3814 int i;
3815 pisid->Revision = SDDL_REVISION;
3817 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3818 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3820 DWORD j;
3821 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
3822 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
3823 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
3824 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
3825 bret = TRUE;
3828 if (!bret)
3829 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3832 lend:
3833 if (!bret)
3834 SetLastError(ERROR_INVALID_SID);
3836 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3837 return bret;
3840 /******************************************************************************
3841 * GetNamedSecurityInfoA [ADVAPI32.@]
3843 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3844 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3845 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3846 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3848 DWORD len;
3849 LPWSTR wstr = NULL;
3850 DWORD r;
3852 TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3853 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3855 if( pObjectName )
3857 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3858 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3859 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3862 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3863 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3865 HeapFree( GetProcessHeap(), 0, wstr );
3867 return r;
3870 /******************************************************************************
3871 * GetNamedSecurityInfoW [ADVAPI32.@]
3873 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3874 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3875 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3877 DWORD needed, offset;
3878 SECURITY_DESCRIPTOR_RELATIVE *relative;
3879 BYTE *buffer;
3881 TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3882 group, dacl, sacl, descriptor );
3884 if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3886 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3887 if (info & OWNER_SECURITY_INFORMATION)
3888 needed += sizeof(sidWorld);
3889 if (info & GROUP_SECURITY_INFORMATION)
3890 needed += sizeof(sidWorld);
3891 if (info & DACL_SECURITY_INFORMATION)
3892 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3893 if (info & SACL_SECURITY_INFORMATION)
3894 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3896 /* must be freed by caller */
3897 *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3898 if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3900 if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3902 HeapFree( GetProcessHeap(), 0, *descriptor );
3903 return ERROR_INVALID_SECURITY_DESCR;
3906 relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3907 relative->Control |= SE_SELF_RELATIVE;
3908 buffer = (BYTE *)relative;
3909 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3911 if (owner && (info & OWNER_SECURITY_INFORMATION))
3913 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3914 relative->Owner = offset;
3915 *owner = buffer + offset;
3916 offset += sizeof(sidWorld);
3918 if (group && (info & GROUP_SECURITY_INFORMATION))
3920 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3921 relative->Group = offset;
3922 *group = buffer + offset;
3923 offset += sizeof(sidWorld);
3925 if (dacl && (info & DACL_SECURITY_INFORMATION))
3927 GetWorldAccessACL( (PACL)(buffer + offset) );
3928 relative->Dacl = offset;
3929 *dacl = (PACL)(buffer + offset);
3930 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3932 if (sacl && (info & SACL_SECURITY_INFORMATION))
3934 GetWorldAccessACL( (PACL)(buffer + offset) );
3935 relative->Sacl = offset;
3936 *sacl = (PACL)(buffer + offset);
3938 return ERROR_SUCCESS;
3941 /******************************************************************************
3942 * DecryptFileW [ADVAPI32.@]
3944 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3946 FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3947 return TRUE;
3950 /******************************************************************************
3951 * DecryptFileA [ADVAPI32.@]
3953 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3955 FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3956 return TRUE;
3959 /******************************************************************************
3960 * EncryptFileW [ADVAPI32.@]
3962 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3964 FIXME("%s\n", debugstr_w(lpFileName));
3965 return TRUE;
3968 /******************************************************************************
3969 * EncryptFileA [ADVAPI32.@]
3971 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3973 FIXME("%s\n", debugstr_a(lpFileName));
3974 return TRUE;
3977 /******************************************************************************
3978 * FileEncryptionStatusW [ADVAPI32.@]
3980 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
3982 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
3983 if (!lpStatus)
3984 return FALSE;
3985 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3986 return TRUE;
3989 /******************************************************************************
3990 * FileEncryptionStatusA [ADVAPI32.@]
3992 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
3994 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
3995 if (!lpStatus)
3996 return FALSE;
3997 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3998 return TRUE;
4001 /******************************************************************************
4002 * SetSecurityInfo [ADVAPI32.@]
4004 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
4005 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4006 PSID psidGroup, PACL pDacl, PACL pSacl) {
4007 FIXME("stub\n");
4008 return ERROR_SUCCESS;