kernel32: DETACHED_PROCESS doesn't affect STARTUPINFO console handles.
[wine.git] / dlls / advapi32 / security.c
blob7e41c0a736170ce46bc02d9b7ff744878599bfd7
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <stdarg.h>
25 #include <string.h>
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "winreg.h"
33 #include "winsafer.h"
34 #include "winternl.h"
35 #include "winioctl.h"
36 #include "accctrl.h"
37 #include "sddl.h"
38 #include "winsvc.h"
39 #include "aclapi.h"
40 #include "objbase.h"
41 #include "iads.h"
42 #include "advapi32_misc.h"
43 #include "lmcons.h"
45 #include "wine/debug.h"
46 #include "wine/unicode.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
50 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
51 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
52 PACL pAcl, LPDWORD cBytes);
53 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
54 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
55 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
56 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
57 LPCWSTR StringSecurityDescriptor,
58 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
59 LPDWORD cBytes);
60 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
62 typedef struct _ACEFLAG
64 LPCWSTR wstr;
65 DWORD value;
66 } ACEFLAG, *LPACEFLAG;
68 typedef struct _MAX_SID
70 /* same fields as struct _SID */
71 BYTE Revision;
72 BYTE SubAuthorityCount;
73 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
74 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
75 } MAX_SID;
77 typedef struct WELLKNOWNSID
79 WCHAR wstr[2];
80 WELL_KNOWN_SID_TYPE Type;
81 MAX_SID Sid;
82 } WELLKNOWNSID;
84 static const WELLKNOWNSID WellKnownSids[] =
86 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
87 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
88 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
89 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
90 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
91 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
92 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
93 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
94 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
95 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
96 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
97 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
98 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
99 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
100 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
101 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
102 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
103 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
104 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
105 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
106 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
107 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
108 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
109 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
110 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
111 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
112 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
113 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
114 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
115 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
116 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
117 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
118 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
119 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
120 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
121 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
122 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
123 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
124 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
125 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
126 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
127 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
128 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
129 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
130 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
131 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
132 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
133 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
134 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
135 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
136 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
137 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
138 { {0,0}, WinBuiltinAnyPackageSid, { SID_REVISION, 2, { SECURITY_APP_PACKAGE_AUTHORITY }, { SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE } } },
141 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
142 typedef struct WELLKNOWNRID
144 WCHAR wstr[2];
145 WELL_KNOWN_SID_TYPE Type;
146 DWORD Rid;
147 } WELLKNOWNRID;
149 static const WELLKNOWNRID WellKnownRids[] = {
150 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
151 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
152 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
153 { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
154 { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
155 { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
156 { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
157 { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
158 { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
159 { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
160 { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
161 { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
162 { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
166 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
168 typedef struct _AccountSid {
169 WELL_KNOWN_SID_TYPE type;
170 LPCWSTR account;
171 LPCWSTR domain;
172 SID_NAME_USE name_use;
173 LPCWSTR alias;
174 } AccountSid;
176 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
177 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
178 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
179 static const WCHAR ALL_APPLICATION_PACKAGES[] = { 'A','L','L',' ','A','P','P','L','I','C','A','T','I','O','N',' ','P','A','C','K','A','G','E','S',0 };
180 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
181 static const WCHAR APPLICATION_PACKAGE_AUTHORITY[] = { 'A','P','P','L','I','C','A','T','I','O','N',' ','P','A','C','K','A','G','E',' ','A','U','T','H','O','R','I','T','Y',0 };
182 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
183 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
184 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
185 static const WCHAR Blank[] = { 0 };
186 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
187 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
188 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
189 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 };
190 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
191 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 };
192 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
193 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
194 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
195 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
196 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
197 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
198 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
199 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
200 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
201 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 };
202 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
203 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
204 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
205 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
206 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
207 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
208 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
210 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
211 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 };
212 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
213 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
214 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
215 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
216 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
217 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
218 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
219 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
220 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
221 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
222 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
223 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
224 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
225 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
226 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 };
227 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 };
228 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
229 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
230 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
231 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
232 static const WCHAR SELF[] = { 'S','E','L','F',0 };
233 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
234 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
235 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
236 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 };
237 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
238 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
240 static const AccountSid ACCOUNT_SIDS[] = {
241 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
242 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
243 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
244 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
245 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
246 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
247 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
248 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
249 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
257 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
258 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
259 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
260 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
261 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
262 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
263 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
264 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
265 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
266 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
267 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
268 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
269 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
270 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
271 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
272 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
273 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
274 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
275 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
276 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
277 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
278 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
279 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
280 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
281 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
282 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
283 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
284 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
285 { WinBuiltinAnyPackageSid, ALL_APPLICATION_PACKAGES, APPLICATION_PACKAGE_AUTHORITY, SidTypeWellKnownGroup },
288 * ACE access rights
290 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
291 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
292 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
293 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
295 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
296 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
297 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
298 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
299 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
300 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
301 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
302 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
303 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
305 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
306 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
307 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
308 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
310 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
311 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
312 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
313 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
315 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
316 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
317 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
318 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
320 static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0};
321 static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0};
322 static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0};
325 * ACL flags
327 static const WCHAR SDDL_PROTECTED[] = {'P',0};
328 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
329 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
332 * ACE types
334 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
335 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
336 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
337 static const WCHAR SDDL_ALARM[] = {'A','L',0};
338 static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0};
341 * ACE flags
343 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
344 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
345 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
346 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
347 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
348 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
349 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
351 const char * debugstr_sid(PSID sid)
353 int auth = 0;
354 SID * psid = sid;
356 if (psid == NULL)
357 return "(null)";
359 auth = psid->IdentifierAuthority.Value[5] +
360 (psid->IdentifierAuthority.Value[4] << 8) +
361 (psid->IdentifierAuthority.Value[3] << 16) +
362 (psid->IdentifierAuthority.Value[2] << 24);
364 switch (psid->SubAuthorityCount) {
365 case 0:
366 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
367 case 1:
368 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
369 psid->SubAuthority[0]);
370 case 2:
371 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
372 psid->SubAuthority[0], psid->SubAuthority[1]);
373 case 3:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
376 case 4:
377 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
378 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
379 psid->SubAuthority[3]);
380 case 5:
381 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
382 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
383 psid->SubAuthority[3], psid->SubAuthority[4]);
384 case 6:
385 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
386 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
387 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
388 case 7:
389 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
390 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
391 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
392 psid->SubAuthority[6]);
393 case 8:
394 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
395 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
396 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
397 psid->SubAuthority[6], psid->SubAuthority[7]);
399 return "(too-big)";
402 /* set last error code from NT status and get the proper boolean return value */
403 /* used for functions that are a simple wrapper around the corresponding ntdll API */
404 static inline BOOL set_ntstatus( NTSTATUS status )
406 if (status) SetLastError( RtlNtStatusToDosError( status ));
407 return !status;
410 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
411 static inline DWORD get_security_file( LPCWSTR full_file_name, DWORD access, HANDLE *file )
413 UNICODE_STRING file_nameW;
414 OBJECT_ATTRIBUTES attr;
415 IO_STATUS_BLOCK io;
416 NTSTATUS status;
418 if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
419 return ERROR_PATH_NOT_FOUND;
420 attr.Length = sizeof(attr);
421 attr.RootDirectory = 0;
422 attr.Attributes = OBJ_CASE_INSENSITIVE;
423 attr.ObjectName = &file_nameW;
424 attr.SecurityDescriptor = NULL;
425 status = NtCreateFile( file, access|SYNCHRONIZE, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
426 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
427 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
428 RtlFreeUnicodeString( &file_nameW );
429 return RtlNtStatusToDosError( status );
432 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
433 static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service )
435 SC_HANDLE manager = 0;
436 DWORD err;
438 err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager );
439 if (err == ERROR_SUCCESS)
441 err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service );
442 CloseServiceHandle( manager );
444 return err;
447 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
448 static inline DWORD get_security_regkey( LPWSTR full_key_name, DWORD access, HANDLE *key )
450 WCHAR classes_rootW[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
451 WCHAR current_userW[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
452 WCHAR machineW[] = {'M','A','C','H','I','N','E',0};
453 WCHAR usersW[] = {'U','S','E','R','S',0};
454 LPWSTR p = strchrW(full_key_name, '\\');
455 int len = p-full_key_name;
456 HKEY hParent;
458 if (!p) return ERROR_INVALID_PARAMETER;
459 if (strncmpW( full_key_name, classes_rootW, len ) == 0)
460 hParent = HKEY_CLASSES_ROOT;
461 else if (strncmpW( full_key_name, current_userW, len ) == 0)
462 hParent = HKEY_CURRENT_USER;
463 else if (strncmpW( full_key_name, machineW, len ) == 0)
464 hParent = HKEY_LOCAL_MACHINE;
465 else if (strncmpW( full_key_name, usersW, len ) == 0)
466 hParent = HKEY_USERS;
467 else
468 return ERROR_INVALID_PARAMETER;
469 return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
472 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
474 static void GetWorldAccessACL(PACL pACL)
476 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
478 pACL->AclRevision = ACL_REVISION;
479 pACL->Sbz1 = 0;
480 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
481 pACL->AceCount = 1;
482 pACL->Sbz2 = 0;
484 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
485 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
486 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
487 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
488 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
491 /************************************************************
492 * ADVAPI_IsLocalComputer
494 * Checks whether the server name indicates local machine.
496 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
498 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
499 BOOL Result;
500 LPWSTR buf;
502 if (!ServerName || !ServerName[0])
503 return TRUE;
505 buf = heap_alloc(dwSize * sizeof(WCHAR));
506 Result = GetComputerNameW(buf, &dwSize);
507 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
508 ServerName += 2;
509 Result = Result && !lstrcmpW(ServerName, buf);
510 heap_free(buf);
512 return Result;
515 /************************************************************
516 * ADVAPI_GetComputerSid
518 BOOL ADVAPI_GetComputerSid(PSID sid)
520 static const struct /* same fields as struct SID */
522 BYTE Revision;
523 BYTE SubAuthorityCount;
524 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
525 DWORD SubAuthority[4];
526 } computer_sid =
527 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
529 memcpy( sid, &computer_sid, sizeof(computer_sid) );
530 return TRUE;
533 /* ##############################
534 ###### TOKEN FUNCTIONS ######
535 ##############################
538 /******************************************************************************
539 * OpenProcessToken [ADVAPI32.@]
540 * Opens the access token associated with a process handle.
542 * PARAMS
543 * ProcessHandle [I] Handle to process
544 * DesiredAccess [I] Desired access to process
545 * TokenHandle [O] Pointer to handle of open access token
547 * RETURNS
548 * Success: TRUE. TokenHandle contains the access token.
549 * Failure: FALSE.
551 * NOTES
552 * See NtOpenProcessToken.
554 BOOL WINAPI
555 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
556 HANDLE *TokenHandle )
558 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
561 /******************************************************************************
562 * OpenThreadToken [ADVAPI32.@]
564 * Opens the access token associated with a thread handle.
566 * PARAMS
567 * ThreadHandle [I] Handle to process
568 * DesiredAccess [I] Desired access to the thread
569 * OpenAsSelf [I] ???
570 * TokenHandle [O] Destination for the token handle
572 * RETURNS
573 * Success: TRUE. TokenHandle contains the access token.
574 * Failure: FALSE.
576 * NOTES
577 * See NtOpenThreadToken.
579 BOOL WINAPI
580 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
581 BOOL OpenAsSelf, HANDLE *TokenHandle)
583 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
586 BOOL WINAPI
587 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
588 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
590 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
591 PreviousState, ReturnLength));
594 /******************************************************************************
595 * AdjustTokenPrivileges [ADVAPI32.@]
597 * Adjust the privileges of an open token handle.
599 * PARAMS
600 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
601 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
602 * NewState [I] Desired new privileges of the token
603 * BufferLength [I] Length of NewState
604 * PreviousState [O] Destination for the previous state
605 * ReturnLength [I/O] Size of PreviousState
608 * RETURNS
609 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
610 * Failure: FALSE.
612 * NOTES
613 * See NtAdjustPrivilegesToken.
615 BOOL WINAPI
616 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
617 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
618 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
620 NTSTATUS status;
622 TRACE("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
623 PreviousState, ReturnLength);
625 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
626 NewState, BufferLength, PreviousState,
627 ReturnLength);
628 SetLastError( RtlNtStatusToDosError( status ));
629 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
630 return TRUE;
631 else
632 return FALSE;
635 /******************************************************************************
636 * CheckTokenMembership [ADVAPI32.@]
638 * Determine if an access token is a member of a SID.
640 * PARAMS
641 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
642 * SidToCheck [I] SID that possibly contains the token
643 * IsMember [O] Destination for result.
645 * RETURNS
646 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
647 * Failure: FALSE.
649 BOOL WINAPI
650 CheckTokenMembership( HANDLE token, PSID sid_to_check,
651 PBOOL is_member )
653 PTOKEN_GROUPS token_groups = NULL;
654 HANDLE thread_token = NULL;
655 DWORD size, i;
656 BOOL ret;
658 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
660 *is_member = FALSE;
662 if (!token)
664 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
666 HANDLE process_token;
667 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
668 if (!ret)
669 goto exit;
670 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
671 NULL, SecurityImpersonation, TokenImpersonation,
672 &thread_token);
673 CloseHandle(process_token);
674 if (!ret)
675 goto exit;
677 token = thread_token;
679 else
681 TOKEN_TYPE type;
683 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
684 if (!ret) goto exit;
686 if (type == TokenPrimary)
688 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
689 return FALSE;
693 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
694 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
695 goto exit;
697 token_groups = heap_alloc(size);
698 if (!token_groups)
700 ret = FALSE;
701 goto exit;
704 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
705 if (!ret)
706 goto exit;
708 for (i = 0; i < token_groups->GroupCount; i++)
710 TRACE("Groups[%d]: {0x%x, %s}\n", i,
711 token_groups->Groups[i].Attributes,
712 debugstr_sid(token_groups->Groups[i].Sid));
713 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
714 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
716 *is_member = TRUE;
717 TRACE("sid enabled and found in token\n");
718 break;
722 exit:
723 heap_free(token_groups);
724 if (thread_token != NULL) CloseHandle(thread_token);
726 return ret;
729 /******************************************************************************
730 * GetTokenInformation [ADVAPI32.@]
732 * Get a type of information about an access token.
734 * PARAMS
735 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
736 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
737 * tokeninfo [O] Destination for token information
738 * tokeninfolength [I] Length of tokeninfo
739 * retlen [O] Destination for returned token information length
741 * RETURNS
742 * Success: TRUE. tokeninfo contains retlen bytes of token information
743 * Failure: FALSE.
745 * NOTES
746 * See NtQueryInformationToken.
748 BOOL WINAPI
749 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
750 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
752 TRACE("(%p, %s, %p, %d, %p):\n",
753 token,
754 (tokeninfoclass == TokenUser) ? "TokenUser" :
755 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
756 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
757 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
758 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
759 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
760 (tokeninfoclass == TokenSource) ? "TokenSource" :
761 (tokeninfoclass == TokenType) ? "TokenType" :
762 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
763 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
764 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
765 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
766 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
767 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
768 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
769 "Unknown",
770 tokeninfo, tokeninfolength, retlen);
771 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
772 tokeninfolength, retlen));
775 /******************************************************************************
776 * SetTokenInformation [ADVAPI32.@]
778 * Set information for an access token.
780 * PARAMS
781 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
782 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
783 * tokeninfo [I] Token information to set
784 * tokeninfolength [I] Length of tokeninfo
786 * RETURNS
787 * Success: TRUE. The information for the token is set to tokeninfo.
788 * Failure: FALSE.
790 BOOL WINAPI
791 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
792 LPVOID tokeninfo, DWORD tokeninfolength )
794 TRACE("(%p, %s, %p, %d)\n",
795 token,
796 (tokeninfoclass == TokenUser) ? "TokenUser" :
797 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
798 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
799 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
800 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
801 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
802 (tokeninfoclass == TokenSource) ? "TokenSource" :
803 (tokeninfoclass == TokenType) ? "TokenType" :
804 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
805 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
806 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
807 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
808 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
809 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
810 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
811 "Unknown",
812 tokeninfo, tokeninfolength);
814 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
817 /*************************************************************************
818 * SetThreadToken [ADVAPI32.@]
820 * Assigns an 'impersonation token' to a thread so it can assume the
821 * security privileges of another thread or process. Can also remove
822 * a previously assigned token.
824 * PARAMS
825 * thread [O] Handle to thread to set the token for
826 * token [I] Token to set
828 * RETURNS
829 * Success: TRUE. The threads access token is set to token
830 * Failure: FALSE.
832 * NOTES
833 * Only supported on NT or higher. On Win9X this function does nothing.
834 * See SetTokenInformation.
836 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
838 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
839 ThreadImpersonationToken, &token, sizeof token ));
842 /*************************************************************************
843 * CreateRestrictedToken [ADVAPI32.@]
845 * Create a new more restricted token from an existing token.
847 * PARAMS
848 * baseToken [I] Token to base the new restricted token on
849 * flags [I] Options
850 * nDisableSids [I] Length of disableSids array
851 * disableSids [I] Array of SIDs to disable in the new token
852 * nDeletePrivs [I] Length of deletePrivs array
853 * deletePrivs [I] Array of privileges to delete in the new token
854 * nRestrictSids [I] Length of restrictSids array
855 * restrictSids [I] Array of SIDs to restrict in the new token
856 * newToken [O] Address where the new token is stored
858 * RETURNS
859 * Success: TRUE
860 * Failure: FALSE
862 BOOL WINAPI CreateRestrictedToken(
863 HANDLE baseToken,
864 DWORD flags,
865 DWORD nDisableSids,
866 PSID_AND_ATTRIBUTES disableSids,
867 DWORD nDeletePrivs,
868 PLUID_AND_ATTRIBUTES deletePrivs,
869 DWORD nRestrictSids,
870 PSID_AND_ATTRIBUTES restrictSids,
871 PHANDLE newToken)
873 TOKEN_TYPE type;
874 SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
875 DWORD size;
877 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
878 baseToken, flags, nDisableSids, disableSids,
879 nDeletePrivs, deletePrivs,
880 nRestrictSids, restrictSids,
881 newToken);
883 size = sizeof(type);
884 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
885 if (type == TokenImpersonation)
887 size = sizeof(level);
888 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
889 return FALSE;
891 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
894 /* ##############################
895 ###### SID FUNCTIONS ######
896 ##############################
899 /******************************************************************************
900 * AllocateAndInitializeSid [ADVAPI32.@]
902 * PARAMS
903 * pIdentifierAuthority []
904 * nSubAuthorityCount []
905 * nSubAuthority0 []
906 * nSubAuthority1 []
907 * nSubAuthority2 []
908 * nSubAuthority3 []
909 * nSubAuthority4 []
910 * nSubAuthority5 []
911 * nSubAuthority6 []
912 * nSubAuthority7 []
913 * pSid []
915 BOOL WINAPI
916 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
917 BYTE nSubAuthorityCount,
918 DWORD nSubAuthority0, DWORD nSubAuthority1,
919 DWORD nSubAuthority2, DWORD nSubAuthority3,
920 DWORD nSubAuthority4, DWORD nSubAuthority5,
921 DWORD nSubAuthority6, DWORD nSubAuthority7,
922 PSID *pSid )
924 return set_ntstatus( RtlAllocateAndInitializeSid(
925 pIdentifierAuthority, nSubAuthorityCount,
926 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
927 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
928 pSid ));
931 /******************************************************************************
932 * FreeSid [ADVAPI32.@]
934 * PARAMS
935 * pSid []
937 PVOID WINAPI
938 FreeSid( PSID pSid )
940 RtlFreeSid(pSid);
941 return NULL; /* is documented like this */
944 /******************************************************************************
945 * CopySid [ADVAPI32.@]
947 * PARAMS
948 * nDestinationSidLength []
949 * pDestinationSid []
950 * pSourceSid []
952 BOOL WINAPI
953 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
955 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
958 /******************************************************************************
959 * CreateWellKnownSid [ADVAPI32.@]
961 BOOL WINAPI
962 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
963 PSID DomainSid,
964 PSID pSid,
965 DWORD* cbSid)
967 unsigned int i;
968 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
970 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
972 SetLastError(ERROR_INVALID_PARAMETER);
973 return FALSE;
976 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
977 if (WellKnownSids[i].Type == WellKnownSidType) {
978 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
980 if (*cbSid < length)
982 *cbSid = length;
983 SetLastError(ERROR_INSUFFICIENT_BUFFER);
984 return FALSE;
986 if (!pSid)
988 SetLastError(ERROR_INVALID_PARAMETER);
989 return FALSE;
991 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
992 *cbSid = length;
993 return TRUE;
997 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
999 SetLastError(ERROR_INVALID_PARAMETER);
1000 return FALSE;
1003 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
1004 if (WellKnownRids[i].Type == WellKnownSidType) {
1005 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
1006 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
1007 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
1009 if (*cbSid < output_sid_length)
1011 *cbSid = output_sid_length;
1012 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1013 return FALSE;
1015 if (!pSid)
1017 SetLastError(ERROR_INVALID_PARAMETER);
1018 return FALSE;
1020 CopyMemory(pSid, DomainSid, domain_sid_length);
1021 (*GetSidSubAuthorityCount(pSid))++;
1022 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1023 *cbSid = output_sid_length;
1024 return TRUE;
1027 SetLastError(ERROR_INVALID_PARAMETER);
1028 return FALSE;
1031 /******************************************************************************
1032 * IsWellKnownSid [ADVAPI32.@]
1034 BOOL WINAPI
1035 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1037 unsigned int i;
1038 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1040 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
1041 if (WellKnownSids[i].Type == WellKnownSidType)
1042 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1043 return TRUE;
1045 return FALSE;
1048 BOOL WINAPI
1049 IsTokenRestricted( HANDLE TokenHandle )
1051 TOKEN_GROUPS *groups;
1052 DWORD size;
1053 NTSTATUS status;
1054 BOOL restricted;
1056 TRACE("(%p)\n", TokenHandle);
1058 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1059 if (status != STATUS_BUFFER_TOO_SMALL)
1060 return FALSE;
1062 groups = heap_alloc(size);
1063 if (!groups)
1065 SetLastError(ERROR_OUTOFMEMORY);
1066 return FALSE;
1069 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1070 if (status != STATUS_SUCCESS)
1072 heap_free(groups);
1073 return set_ntstatus(status);
1076 restricted = groups->GroupCount > 0;
1077 heap_free(groups);
1079 return restricted;
1082 /******************************************************************************
1083 * IsValidSid [ADVAPI32.@]
1085 * PARAMS
1086 * pSid []
1088 BOOL WINAPI
1089 IsValidSid( PSID pSid )
1091 return RtlValidSid( pSid );
1094 /******************************************************************************
1095 * EqualSid [ADVAPI32.@]
1097 * PARAMS
1098 * pSid1 []
1099 * pSid2 []
1101 BOOL WINAPI
1102 EqualSid( PSID pSid1, PSID pSid2 )
1104 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1105 SetLastError(ERROR_SUCCESS);
1106 return ret;
1109 /******************************************************************************
1110 * EqualPrefixSid [ADVAPI32.@]
1112 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1114 return RtlEqualPrefixSid(pSid1, pSid2);
1117 /******************************************************************************
1118 * GetSidLengthRequired [ADVAPI32.@]
1120 * PARAMS
1121 * nSubAuthorityCount []
1123 DWORD WINAPI
1124 GetSidLengthRequired( BYTE nSubAuthorityCount )
1126 return RtlLengthRequiredSid(nSubAuthorityCount);
1129 /******************************************************************************
1130 * InitializeSid [ADVAPI32.@]
1132 * PARAMS
1133 * pIdentifierAuthority []
1135 BOOL WINAPI
1136 InitializeSid (
1137 PSID pSid,
1138 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1139 BYTE nSubAuthorityCount)
1141 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1144 DWORD WINAPI
1145 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1147 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1149 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1150 return 0;
1153 DWORD WINAPI
1154 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1156 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1158 return 1;
1161 /******************************************************************************
1162 * GetSidIdentifierAuthority [ADVAPI32.@]
1164 * PARAMS
1165 * pSid []
1167 PSID_IDENTIFIER_AUTHORITY WINAPI
1168 GetSidIdentifierAuthority( PSID pSid )
1170 SetLastError(ERROR_SUCCESS);
1171 return RtlIdentifierAuthoritySid(pSid);
1174 /******************************************************************************
1175 * GetSidSubAuthority [ADVAPI32.@]
1177 * PARAMS
1178 * pSid []
1179 * nSubAuthority []
1181 PDWORD WINAPI
1182 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1184 SetLastError(ERROR_SUCCESS);
1185 return RtlSubAuthoritySid(pSid, nSubAuthority);
1188 /******************************************************************************
1189 * GetSidSubAuthorityCount [ADVAPI32.@]
1191 * PARAMS
1192 * pSid []
1194 PUCHAR WINAPI
1195 GetSidSubAuthorityCount (PSID pSid)
1197 SetLastError(ERROR_SUCCESS);
1198 return RtlSubAuthorityCountSid(pSid);
1201 /******************************************************************************
1202 * GetLengthSid [ADVAPI32.@]
1204 * PARAMS
1205 * pSid []
1207 DWORD WINAPI
1208 GetLengthSid (PSID pSid)
1210 return RtlLengthSid(pSid);
1213 /* ##############################################
1214 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1215 ##############################################
1218 /******************************************************************************
1219 * BuildSecurityDescriptorA [ADVAPI32.@]
1221 * Builds a SD from
1223 * PARAMS
1224 * pOwner [I]
1225 * pGroup [I]
1226 * cCountOfAccessEntries [I]
1227 * pListOfAccessEntries [I]
1228 * cCountOfAuditEntries [I]
1229 * pListofAuditEntries [I]
1230 * pOldSD [I]
1231 * lpdwBufferLength [I/O]
1232 * pNewSD [O]
1234 * RETURNS
1235 * Success: ERROR_SUCCESS
1236 * Failure: nonzero error code from Winerror.h
1238 DWORD WINAPI BuildSecurityDescriptorA(
1239 IN PTRUSTEEA pOwner,
1240 IN PTRUSTEEA pGroup,
1241 IN ULONG cCountOfAccessEntries,
1242 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1243 IN ULONG cCountOfAuditEntries,
1244 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1245 IN PSECURITY_DESCRIPTOR pOldSD,
1246 IN OUT PULONG lpdwBufferLength,
1247 OUT PSECURITY_DESCRIPTOR* pNewSD)
1249 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1250 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1251 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1253 return ERROR_CALL_NOT_IMPLEMENTED;
1256 /******************************************************************************
1257 * BuildSecurityDescriptorW [ADVAPI32.@]
1259 * See BuildSecurityDescriptorA.
1261 DWORD WINAPI BuildSecurityDescriptorW(
1262 IN PTRUSTEEW pOwner,
1263 IN PTRUSTEEW pGroup,
1264 IN ULONG cCountOfAccessEntries,
1265 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1266 IN ULONG cCountOfAuditEntries,
1267 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1268 IN PSECURITY_DESCRIPTOR pOldSD,
1269 IN OUT PULONG lpdwBufferLength,
1270 OUT PSECURITY_DESCRIPTOR* pNewSD)
1272 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1273 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1274 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1276 return ERROR_CALL_NOT_IMPLEMENTED;
1279 /******************************************************************************
1280 * InitializeSecurityDescriptor [ADVAPI32.@]
1282 * PARAMS
1283 * pDescr []
1284 * revision []
1286 BOOL WINAPI
1287 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1289 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1293 /******************************************************************************
1294 * MakeAbsoluteSD [ADVAPI32.@]
1296 BOOL WINAPI MakeAbsoluteSD (
1297 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1298 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1299 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1300 OUT PACL pDacl,
1301 OUT LPDWORD lpdwDaclSize,
1302 OUT PACL pSacl,
1303 OUT LPDWORD lpdwSaclSize,
1304 OUT PSID pOwner,
1305 OUT LPDWORD lpdwOwnerSize,
1306 OUT PSID pPrimaryGroup,
1307 OUT LPDWORD lpdwPrimaryGroupSize)
1309 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1310 pAbsoluteSecurityDescriptor,
1311 lpdwAbsoluteSecurityDescriptorSize,
1312 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1313 pOwner, lpdwOwnerSize,
1314 pPrimaryGroup, lpdwPrimaryGroupSize));
1317 /******************************************************************************
1318 * GetKernelObjectSecurity [ADVAPI32.@]
1320 BOOL WINAPI GetKernelObjectSecurity(
1321 HANDLE Handle,
1322 SECURITY_INFORMATION RequestedInformation,
1323 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1324 DWORD nLength,
1325 LPDWORD lpnLengthNeeded )
1327 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1328 pSecurityDescriptor, nLength, lpnLengthNeeded);
1330 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1331 nLength, lpnLengthNeeded ));
1334 /******************************************************************************
1335 * GetPrivateObjectSecurity [ADVAPI32.@]
1337 BOOL WINAPI GetPrivateObjectSecurity(
1338 PSECURITY_DESCRIPTOR ObjectDescriptor,
1339 SECURITY_INFORMATION SecurityInformation,
1340 PSECURITY_DESCRIPTOR ResultantDescriptor,
1341 DWORD DescriptorLength,
1342 PDWORD ReturnLength )
1344 SECURITY_DESCRIPTOR desc;
1345 BOOL defaulted, present;
1346 PACL pacl;
1347 PSID psid;
1349 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1350 ResultantDescriptor, DescriptorLength, ReturnLength);
1352 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1353 return FALSE;
1355 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1357 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1358 return FALSE;
1359 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1362 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1364 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1365 return FALSE;
1366 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1369 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1371 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1372 return FALSE;
1373 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1376 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1378 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1379 return FALSE;
1380 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1383 *ReturnLength = DescriptorLength;
1384 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1387 /******************************************************************************
1388 * GetSecurityDescriptorLength [ADVAPI32.@]
1390 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1392 return RtlLengthSecurityDescriptor(pDescr);
1395 /******************************************************************************
1396 * GetSecurityDescriptorOwner [ADVAPI32.@]
1398 * PARAMS
1399 * pOwner []
1400 * lpbOwnerDefaulted []
1402 BOOL WINAPI
1403 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1404 LPBOOL lpbOwnerDefaulted )
1406 BOOLEAN defaulted;
1407 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1408 *lpbOwnerDefaulted = defaulted;
1409 return ret;
1412 /******************************************************************************
1413 * SetSecurityDescriptorOwner [ADVAPI32.@]
1415 * PARAMS
1417 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1418 PSID pOwner, BOOL bOwnerDefaulted)
1420 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1422 /******************************************************************************
1423 * GetSecurityDescriptorGroup [ADVAPI32.@]
1425 BOOL WINAPI GetSecurityDescriptorGroup(
1426 PSECURITY_DESCRIPTOR SecurityDescriptor,
1427 PSID *Group,
1428 LPBOOL GroupDefaulted)
1430 BOOLEAN defaulted;
1431 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1432 *GroupDefaulted = defaulted;
1433 return ret;
1435 /******************************************************************************
1436 * SetSecurityDescriptorGroup [ADVAPI32.@]
1438 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1439 PSID Group, BOOL GroupDefaulted)
1441 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1444 /******************************************************************************
1445 * IsValidSecurityDescriptor [ADVAPI32.@]
1447 * PARAMS
1448 * lpsecdesc []
1450 BOOL WINAPI
1451 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1453 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1456 /******************************************************************************
1457 * GetSecurityDescriptorDacl [ADVAPI32.@]
1459 BOOL WINAPI GetSecurityDescriptorDacl(
1460 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1461 OUT LPBOOL lpbDaclPresent,
1462 OUT PACL *pDacl,
1463 OUT LPBOOL lpbDaclDefaulted)
1465 BOOLEAN present, defaulted;
1466 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1467 *lpbDaclPresent = present;
1468 *lpbDaclDefaulted = defaulted;
1469 return ret;
1472 /******************************************************************************
1473 * SetSecurityDescriptorDacl [ADVAPI32.@]
1475 BOOL WINAPI
1476 SetSecurityDescriptorDacl (
1477 PSECURITY_DESCRIPTOR lpsd,
1478 BOOL daclpresent,
1479 PACL dacl,
1480 BOOL dacldefaulted )
1482 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1484 /******************************************************************************
1485 * GetSecurityDescriptorSacl [ADVAPI32.@]
1487 BOOL WINAPI GetSecurityDescriptorSacl(
1488 IN PSECURITY_DESCRIPTOR lpsd,
1489 OUT LPBOOL lpbSaclPresent,
1490 OUT PACL *pSacl,
1491 OUT LPBOOL lpbSaclDefaulted)
1493 BOOLEAN present, defaulted;
1494 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1495 *lpbSaclPresent = present;
1496 *lpbSaclDefaulted = defaulted;
1497 return ret;
1500 /**************************************************************************
1501 * SetSecurityDescriptorSacl [ADVAPI32.@]
1503 BOOL WINAPI SetSecurityDescriptorSacl (
1504 PSECURITY_DESCRIPTOR lpsd,
1505 BOOL saclpresent,
1506 PACL lpsacl,
1507 BOOL sacldefaulted)
1509 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1511 /******************************************************************************
1512 * MakeSelfRelativeSD [ADVAPI32.@]
1514 * PARAMS
1515 * lpabssecdesc []
1516 * lpselfsecdesc []
1517 * lpbuflen []
1519 BOOL WINAPI
1520 MakeSelfRelativeSD(
1521 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1522 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1523 IN OUT LPDWORD lpdwBufferLength)
1525 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1526 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1529 /******************************************************************************
1530 * GetSecurityDescriptorControl [ADVAPI32.@]
1533 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1534 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1536 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1539 /******************************************************************************
1540 * SetSecurityDescriptorControl [ADVAPI32.@]
1542 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1543 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1544 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1546 return set_ntstatus( RtlSetControlSecurityDescriptor(
1547 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1550 /******************************************************************************
1551 * GetWindowsAccountDomainSid [ADVAPI32.@]
1553 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
1555 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
1556 DWORD required_size;
1557 int i;
1559 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
1561 if (!sid || !IsValidSid( sid ))
1563 SetLastError( ERROR_INVALID_SID );
1564 return FALSE;
1567 if (!size)
1569 SetLastError( ERROR_INVALID_PARAMETER );
1570 return FALSE;
1573 if (*GetSidSubAuthorityCount( sid ) < 4)
1575 SetLastError( ERROR_INVALID_SID );
1576 return FALSE;
1579 required_size = GetSidLengthRequired( 4 );
1580 if (*size < required_size || !domain_sid)
1582 *size = required_size;
1583 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
1584 ERROR_INVALID_PARAMETER );
1585 return FALSE;
1588 InitializeSid( domain_sid, &domain_ident, 4 );
1589 for (i = 0; i < 4; i++)
1590 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
1592 *size = required_size;
1593 return TRUE;
1596 /* ##############################
1597 ###### ACL FUNCTIONS ######
1598 ##############################
1601 /*************************************************************************
1602 * InitializeAcl [ADVAPI32.@]
1604 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1606 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1609 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1611 IO_STATUS_BLOCK io_block;
1613 TRACE("(%p)\n", hNamedPipe);
1615 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1616 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1619 /******************************************************************************
1620 * AddAccessAllowedAce [ADVAPI32.@]
1622 BOOL WINAPI AddAccessAllowedAce(
1623 IN OUT PACL pAcl,
1624 IN DWORD dwAceRevision,
1625 IN DWORD AccessMask,
1626 IN PSID pSid)
1628 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1631 /******************************************************************************
1632 * AddAccessAllowedAceEx [ADVAPI32.@]
1634 BOOL WINAPI AddAccessAllowedAceEx(
1635 IN OUT PACL pAcl,
1636 IN DWORD dwAceRevision,
1637 IN DWORD AceFlags,
1638 IN DWORD AccessMask,
1639 IN PSID pSid)
1641 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1644 /******************************************************************************
1645 * AddAccessAllowedObjectAce [ADVAPI32.@]
1647 BOOL WINAPI AddAccessAllowedObjectAce(
1648 IN OUT PACL pAcl,
1649 IN DWORD dwAceRevision,
1650 IN DWORD dwAceFlags,
1651 IN DWORD dwAccessMask,
1652 IN GUID* pObjectTypeGuid,
1653 IN GUID* pInheritedObjectTypeGuid,
1654 IN PSID pSid)
1656 return set_ntstatus(RtlAddAccessAllowedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1657 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid));
1660 /******************************************************************************
1661 * AddAccessDeniedAce [ADVAPI32.@]
1663 BOOL WINAPI AddAccessDeniedAce(
1664 IN OUT PACL pAcl,
1665 IN DWORD dwAceRevision,
1666 IN DWORD AccessMask,
1667 IN PSID pSid)
1669 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1672 /******************************************************************************
1673 * AddAccessDeniedAceEx [ADVAPI32.@]
1675 BOOL WINAPI AddAccessDeniedAceEx(
1676 IN OUT PACL pAcl,
1677 IN DWORD dwAceRevision,
1678 IN DWORD AceFlags,
1679 IN DWORD AccessMask,
1680 IN PSID pSid)
1682 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1685 /******************************************************************************
1686 * AddAccessDeniedObjectAce [ADVAPI32.@]
1688 BOOL WINAPI AddAccessDeniedObjectAce(
1689 IN OUT PACL pAcl,
1690 IN DWORD dwAceRevision,
1691 IN DWORD dwAceFlags,
1692 IN DWORD dwAccessMask,
1693 IN GUID* pObjectTypeGuid,
1694 IN GUID* pInheritedObjectTypeGuid,
1695 IN PSID pSid)
1697 return set_ntstatus( RtlAddAccessDeniedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1698 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid) );
1701 /******************************************************************************
1702 * AddAce [ADVAPI32.@]
1704 BOOL WINAPI AddAce(
1705 IN OUT PACL pAcl,
1706 IN DWORD dwAceRevision,
1707 IN DWORD dwStartingAceIndex,
1708 LPVOID pAceList,
1709 DWORD nAceListLength)
1711 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1714 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1716 FIXME("%p %x %x %x %p - stub\n", acl, ace_revision, ace_flags, mandatory_policy, label_sid);
1717 return FALSE;
1720 /******************************************************************************
1721 * DeleteAce [ADVAPI32.@]
1723 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1725 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1728 /******************************************************************************
1729 * FindFirstFreeAce [ADVAPI32.@]
1731 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1733 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1736 /******************************************************************************
1737 * GetAce [ADVAPI32.@]
1739 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1741 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1744 /******************************************************************************
1745 * GetAclInformation [ADVAPI32.@]
1747 BOOL WINAPI GetAclInformation(
1748 PACL pAcl,
1749 LPVOID pAclInformation,
1750 DWORD nAclInformationLength,
1751 ACL_INFORMATION_CLASS dwAclInformationClass)
1753 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1754 nAclInformationLength, dwAclInformationClass));
1757 /******************************************************************************
1758 * IsValidAcl [ADVAPI32.@]
1760 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1762 return RtlValidAcl(pAcl);
1765 /* ##############################
1766 ###### MISC FUNCTIONS ######
1767 ##############################
1770 /******************************************************************************
1771 * AllocateLocallyUniqueId [ADVAPI32.@]
1773 * PARAMS
1774 * lpLuid []
1776 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1778 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1781 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1782 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1783 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1784 { '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 };
1785 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1786 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1787 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1788 { '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 };
1789 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1790 { '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 };
1791 static const WCHAR SE_TCB_NAME_W[] =
1792 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1793 static const WCHAR SE_SECURITY_NAME_W[] =
1794 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1795 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1796 { '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 };
1797 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1798 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1799 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1800 { '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 };
1801 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1802 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1803 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1804 { '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 };
1805 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1806 { '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 };
1807 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1808 { '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 };
1809 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1810 { '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 };
1811 static const WCHAR SE_BACKUP_NAME_W[] =
1812 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1813 static const WCHAR SE_RESTORE_NAME_W[] =
1814 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1815 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1816 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1817 static const WCHAR SE_DEBUG_NAME_W[] =
1818 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1819 static const WCHAR SE_AUDIT_NAME_W[] =
1820 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1821 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1822 { '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 };
1823 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1824 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1825 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1826 { '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 };
1827 static const WCHAR SE_UNDOCK_NAME_W[] =
1828 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1829 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1830 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1831 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1832 { '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 };
1833 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1834 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1835 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1836 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1837 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1838 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1840 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1842 NULL,
1843 NULL,
1844 SE_CREATE_TOKEN_NAME_W,
1845 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1846 SE_LOCK_MEMORY_NAME_W,
1847 SE_INCREASE_QUOTA_NAME_W,
1848 SE_MACHINE_ACCOUNT_NAME_W,
1849 SE_TCB_NAME_W,
1850 SE_SECURITY_NAME_W,
1851 SE_TAKE_OWNERSHIP_NAME_W,
1852 SE_LOAD_DRIVER_NAME_W,
1853 SE_SYSTEM_PROFILE_NAME_W,
1854 SE_SYSTEMTIME_NAME_W,
1855 SE_PROF_SINGLE_PROCESS_NAME_W,
1856 SE_INC_BASE_PRIORITY_NAME_W,
1857 SE_CREATE_PAGEFILE_NAME_W,
1858 SE_CREATE_PERMANENT_NAME_W,
1859 SE_BACKUP_NAME_W,
1860 SE_RESTORE_NAME_W,
1861 SE_SHUTDOWN_NAME_W,
1862 SE_DEBUG_NAME_W,
1863 SE_AUDIT_NAME_W,
1864 SE_SYSTEM_ENVIRONMENT_NAME_W,
1865 SE_CHANGE_NOTIFY_NAME_W,
1866 SE_REMOTE_SHUTDOWN_NAME_W,
1867 SE_UNDOCK_NAME_W,
1868 SE_SYNC_AGENT_NAME_W,
1869 SE_ENABLE_DELEGATION_NAME_W,
1870 SE_MANAGE_VOLUME_NAME_W,
1871 SE_IMPERSONATE_NAME_W,
1872 SE_CREATE_GLOBAL_NAME_W,
1875 /******************************************************************************
1876 * LookupPrivilegeValueW [ADVAPI32.@]
1878 * See LookupPrivilegeValueA.
1880 BOOL WINAPI
1881 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1883 UINT i;
1885 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1887 if (!ADVAPI_IsLocalComputer(lpSystemName))
1889 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1890 return FALSE;
1892 if (!lpName)
1894 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1895 return FALSE;
1897 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1899 if( !WellKnownPrivNames[i] )
1900 continue;
1901 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1902 continue;
1903 lpLuid->LowPart = i;
1904 lpLuid->HighPart = 0;
1905 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1906 lpLuid->HighPart, lpLuid->LowPart );
1907 return TRUE;
1909 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1910 return FALSE;
1913 /******************************************************************************
1914 * LookupPrivilegeValueA [ADVAPI32.@]
1916 * Retrieves LUID used on a system to represent the privilege name.
1918 * PARAMS
1919 * lpSystemName [I] Name of the system
1920 * lpName [I] Name of the privilege
1921 * lpLuid [O] Destination for the resulting LUID
1923 * RETURNS
1924 * Success: TRUE. lpLuid contains the requested LUID.
1925 * Failure: FALSE.
1927 BOOL WINAPI
1928 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1930 UNICODE_STRING lpSystemNameW;
1931 UNICODE_STRING lpNameW;
1932 BOOL ret;
1934 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1935 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1936 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1937 RtlFreeUnicodeString(&lpNameW);
1938 RtlFreeUnicodeString(&lpSystemNameW);
1939 return ret;
1942 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1943 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1945 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1946 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1948 return FALSE;
1951 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1952 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1954 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1955 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1957 return FALSE;
1960 /******************************************************************************
1961 * LookupPrivilegeNameA [ADVAPI32.@]
1963 * See LookupPrivilegeNameW.
1965 BOOL WINAPI
1966 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1967 LPDWORD cchName)
1969 UNICODE_STRING lpSystemNameW;
1970 BOOL ret;
1971 DWORD wLen = 0;
1973 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1975 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1976 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1977 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1979 LPWSTR lpNameW = heap_alloc(wLen * sizeof(WCHAR));
1981 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1982 &wLen);
1983 if (ret)
1985 /* Windows crashes if cchName is NULL, so will I */
1986 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1987 *cchName, NULL, NULL);
1989 if (len == 0)
1991 /* WideCharToMultiByte failed */
1992 ret = FALSE;
1994 else if (len > *cchName)
1996 *cchName = len;
1997 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1998 ret = FALSE;
2000 else
2002 /* WideCharToMultiByte succeeded, output length needs to be
2003 * length not including NULL terminator
2005 *cchName = len - 1;
2008 heap_free(lpNameW);
2010 RtlFreeUnicodeString(&lpSystemNameW);
2011 return ret;
2014 /******************************************************************************
2015 * LookupPrivilegeNameW [ADVAPI32.@]
2017 * Retrieves the privilege name referred to by the LUID lpLuid.
2019 * PARAMS
2020 * lpSystemName [I] Name of the system
2021 * lpLuid [I] Privilege value
2022 * lpName [O] Name of the privilege
2023 * cchName [I/O] Number of characters in lpName.
2025 * RETURNS
2026 * Success: TRUE. lpName contains the name of the privilege whose value is
2027 * *lpLuid.
2028 * Failure: FALSE.
2030 * REMARKS
2031 * Only well-known privilege names (those defined in winnt.h) can be retrieved
2032 * using this function.
2033 * If the length of lpName is too small, on return *cchName will contain the
2034 * number of WCHARs needed to contain the privilege, including the NULL
2035 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
2036 * On success, *cchName will contain the number of characters stored in
2037 * lpName, NOT including the NULL terminator.
2039 BOOL WINAPI
2040 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
2041 LPDWORD cchName)
2043 size_t privNameLen;
2045 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
2047 if (!ADVAPI_IsLocalComputer(lpSystemName))
2049 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2050 return FALSE;
2052 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
2053 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
2055 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
2056 return FALSE;
2058 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
2059 /* Windows crashes if cchName is NULL, so will I */
2060 if (*cchName <= privNameLen)
2062 *cchName = privNameLen + 1;
2063 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2064 return FALSE;
2066 else
2068 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
2069 *cchName = privNameLen;
2070 return TRUE;
2074 /******************************************************************************
2075 * GetFileSecurityA [ADVAPI32.@]
2077 * Obtains Specified information about the security of a file or directory.
2079 * PARAMS
2080 * lpFileName [I] Name of the file to get info for
2081 * RequestedInformation [I] SE_ flags from "winnt.h"
2082 * pSecurityDescriptor [O] Destination for security information
2083 * nLength [I] Length of pSecurityDescriptor
2084 * lpnLengthNeeded [O] Destination for length of returned security information
2086 * RETURNS
2087 * Success: TRUE. pSecurityDescriptor contains the requested information.
2088 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2090 * NOTES
2091 * The information returned is constrained by the callers access rights and
2092 * privileges.
2094 BOOL WINAPI
2095 GetFileSecurityA( LPCSTR lpFileName,
2096 SECURITY_INFORMATION RequestedInformation,
2097 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2098 DWORD nLength, LPDWORD lpnLengthNeeded )
2100 BOOL r;
2101 LPWSTR name;
2103 name = SERV_dup(lpFileName);
2104 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2105 nLength, lpnLengthNeeded );
2106 heap_free( name );
2108 return r;
2111 /******************************************************************************
2112 * GetFileSecurityW [ADVAPI32.@]
2114 * See GetFileSecurityA.
2116 BOOL WINAPI
2117 GetFileSecurityW( LPCWSTR lpFileName,
2118 SECURITY_INFORMATION RequestedInformation,
2119 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2120 DWORD nLength, LPDWORD lpnLengthNeeded )
2122 HANDLE hfile;
2123 NTSTATUS status;
2124 DWORD access = 0, err;
2126 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2127 RequestedInformation, pSecurityDescriptor,
2128 nLength, lpnLengthNeeded);
2130 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2131 DACL_SECURITY_INFORMATION))
2132 access |= READ_CONTROL;
2133 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2134 access |= ACCESS_SYSTEM_SECURITY;
2136 err = get_security_file( lpFileName, access, &hfile);
2137 if (err)
2139 SetLastError(err);
2140 return FALSE;
2143 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2144 nLength, lpnLengthNeeded );
2145 CloseHandle( hfile );
2146 return set_ntstatus( status );
2150 /******************************************************************************
2151 * LookupAccountSidA [ADVAPI32.@]
2153 BOOL WINAPI
2154 LookupAccountSidA(
2155 IN LPCSTR system,
2156 IN PSID sid,
2157 OUT LPSTR account,
2158 IN OUT LPDWORD accountSize,
2159 OUT LPSTR domain,
2160 IN OUT LPDWORD domainSize,
2161 OUT PSID_NAME_USE name_use )
2163 DWORD len;
2164 BOOL r;
2165 LPWSTR systemW;
2166 LPWSTR accountW = NULL;
2167 LPWSTR domainW = NULL;
2168 DWORD accountSizeW = *accountSize;
2169 DWORD domainSizeW = *domainSize;
2171 systemW = SERV_dup(system);
2172 if (account)
2173 accountW = heap_alloc( accountSizeW * sizeof(WCHAR) );
2174 if (domain)
2175 domainW = heap_alloc( domainSizeW * sizeof(WCHAR) );
2177 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2179 if (r) {
2180 if (accountW && *accountSize) {
2181 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2182 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2183 *accountSize = len;
2184 } else
2185 *accountSize = accountSizeW + 1;
2187 if (domainW && *domainSize) {
2188 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2189 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2190 *domainSize = len;
2191 } else
2192 *domainSize = domainSizeW + 1;
2194 else
2196 *accountSize = accountSizeW + 1;
2197 *domainSize = domainSizeW + 1;
2200 heap_free( systemW );
2201 heap_free( accountW );
2202 heap_free( domainW );
2204 return r;
2207 /******************************************************************************
2208 * LookupAccountSidW [ADVAPI32.@]
2210 * PARAMS
2211 * system []
2212 * sid []
2213 * account []
2214 * accountSize []
2215 * domain []
2216 * domainSize []
2217 * name_use []
2220 BOOL WINAPI
2221 LookupAccountSidW(
2222 IN LPCWSTR system,
2223 IN PSID sid,
2224 OUT LPWSTR account,
2225 IN OUT LPDWORD accountSize,
2226 OUT LPWSTR domain,
2227 IN OUT LPDWORD domainSize,
2228 OUT PSID_NAME_USE name_use )
2230 unsigned int i, j;
2231 const WCHAR * ac = NULL;
2232 const WCHAR * dm = NULL;
2233 SID_NAME_USE use = 0;
2234 LPWSTR computer_name = NULL;
2235 LPWSTR account_name = NULL;
2237 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2238 debugstr_w(system),debugstr_sid(sid),
2239 account,accountSize,accountSize?*accountSize:0,
2240 domain,domainSize,domainSize?*domainSize:0,
2241 name_use);
2243 if (!ADVAPI_IsLocalComputer(system)) {
2244 FIXME("Only local computer supported!\n");
2245 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2246 return FALSE;
2249 /* check the well known SIDs first */
2250 for (i = 0; i <= WinAccountProtectedUsersSid; i++) {
2251 if (IsWellKnownSid(sid, i)) {
2252 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2253 if (ACCOUNT_SIDS[j].type == i) {
2254 ac = ACCOUNT_SIDS[j].account;
2255 dm = ACCOUNT_SIDS[j].domain;
2256 use = ACCOUNT_SIDS[j].name_use;
2259 break;
2263 if (dm == NULL) {
2264 MAX_SID local;
2266 /* check for the local computer next */
2267 if (ADVAPI_GetComputerSid(&local)) {
2268 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2269 BOOL result;
2271 computer_name = heap_alloc(size * sizeof(WCHAR));
2272 result = GetComputerNameW(computer_name, &size);
2274 if (result) {
2275 if (EqualSid(sid, &local)) {
2276 dm = computer_name;
2277 ac = Blank;
2278 use = 3;
2279 } else {
2280 local.SubAuthorityCount++;
2282 if (EqualPrefixSid(sid, &local)) {
2283 dm = computer_name;
2284 use = 1;
2285 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2286 case DOMAIN_USER_RID_ADMIN:
2287 ac = Administrator;
2288 break;
2289 case DOMAIN_USER_RID_GUEST:
2290 ac = Guest;
2291 break;
2292 case DOMAIN_GROUP_RID_ADMINS:
2293 ac = Domain_Admins;
2294 break;
2295 case DOMAIN_GROUP_RID_USERS:
2296 ac = Domain_Users;
2297 break;
2298 case DOMAIN_GROUP_RID_GUESTS:
2299 ac = Domain_Guests;
2300 break;
2301 case DOMAIN_GROUP_RID_COMPUTERS:
2302 ac = Domain_Computers;
2303 break;
2304 case DOMAIN_GROUP_RID_CONTROLLERS:
2305 ac = Domain_Controllers;
2306 break;
2307 case DOMAIN_GROUP_RID_CERT_ADMINS:
2308 ac = Cert_Publishers;
2309 break;
2310 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2311 ac = Schema_Admins;
2312 break;
2313 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2314 ac = Enterprise_Admins;
2315 break;
2316 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2317 ac = Group_Policy_Creator_Owners;
2318 break;
2319 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2320 ac = RAS_and_IAS_Servers;
2321 break;
2322 case 1000: /* first user account */
2323 size = UNLEN + 1;
2324 account_name = heap_alloc(size * sizeof(WCHAR));
2325 if (GetUserNameW(account_name, &size))
2326 ac = account_name;
2327 else
2328 dm = NULL;
2330 break;
2331 default:
2332 dm = NULL;
2333 break;
2341 if (dm) {
2342 DWORD ac_len = lstrlenW(ac);
2343 DWORD dm_len = lstrlenW(dm);
2344 BOOL status = TRUE;
2346 if (*accountSize > ac_len) {
2347 if (account)
2348 lstrcpyW(account, ac);
2350 if (*domainSize > dm_len) {
2351 if (domain)
2352 lstrcpyW(domain, dm);
2354 if ((*accountSize && *accountSize < ac_len) ||
2355 (!account && !*accountSize && ac_len) ||
2356 (*domainSize && *domainSize < dm_len) ||
2357 (!domain && !*domainSize && dm_len))
2359 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2360 status = FALSE;
2362 if (*domainSize)
2363 *domainSize = dm_len;
2364 else
2365 *domainSize = dm_len + 1;
2366 if (*accountSize)
2367 *accountSize = ac_len;
2368 else
2369 *accountSize = ac_len + 1;
2371 heap_free(account_name);
2372 heap_free(computer_name);
2373 if (status) *name_use = use;
2374 return status;
2377 heap_free(account_name);
2378 heap_free(computer_name);
2379 SetLastError(ERROR_NONE_MAPPED);
2380 return FALSE;
2383 /******************************************************************************
2384 * SetFileSecurityA [ADVAPI32.@]
2386 * See SetFileSecurityW.
2388 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2389 SECURITY_INFORMATION RequestedInformation,
2390 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2392 BOOL r;
2393 LPWSTR name;
2395 name = SERV_dup(lpFileName);
2396 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2397 heap_free( name );
2399 return r;
2402 /******************************************************************************
2403 * SetFileSecurityW [ADVAPI32.@]
2405 * Sets the security of a file or directory.
2407 * PARAMS
2408 * lpFileName []
2409 * RequestedInformation []
2410 * pSecurityDescriptor []
2412 * RETURNS
2413 * Success: TRUE.
2414 * Failure: FALSE.
2416 BOOL WINAPI
2417 SetFileSecurityW( LPCWSTR lpFileName,
2418 SECURITY_INFORMATION RequestedInformation,
2419 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2421 HANDLE file;
2422 DWORD access = 0, err;
2423 NTSTATUS status;
2425 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2426 pSecurityDescriptor );
2428 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2429 RequestedInformation & GROUP_SECURITY_INFORMATION)
2430 access |= WRITE_OWNER;
2431 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2432 access |= ACCESS_SYSTEM_SECURITY;
2433 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2434 access |= WRITE_DAC;
2436 err = get_security_file( lpFileName, access, &file);
2437 if (err)
2439 SetLastError(err);
2440 return FALSE;
2443 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2444 CloseHandle( file );
2445 return set_ntstatus( status );
2448 /******************************************************************************
2449 * QueryWindows31FilesMigration [ADVAPI32.@]
2451 * PARAMS
2452 * x1 []
2454 BOOL WINAPI
2455 QueryWindows31FilesMigration( DWORD x1 )
2457 FIXME("(%d):stub\n",x1);
2458 return TRUE;
2461 /******************************************************************************
2462 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2464 * PARAMS
2465 * x1 []
2466 * x2 []
2467 * x3 []
2468 * x4 []
2470 BOOL WINAPI
2471 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2472 DWORD x4 )
2474 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2475 return TRUE;
2478 /******************************************************************************
2479 * NotifyBootConfigStatus [ADVAPI32.@]
2481 * PARAMS
2482 * x1 []
2484 BOOL WINAPI
2485 NotifyBootConfigStatus( BOOL x1 )
2487 FIXME("(0x%08d):stub\n",x1);
2488 return TRUE;
2491 /******************************************************************************
2492 * RevertToSelf [ADVAPI32.@]
2494 * Ends the impersonation of a user.
2496 * PARAMS
2497 * void []
2499 * RETURNS
2500 * Success: TRUE.
2501 * Failure: FALSE.
2503 BOOL WINAPI
2504 RevertToSelf( void )
2506 HANDLE Token = NULL;
2507 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2508 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2511 /******************************************************************************
2512 * ImpersonateSelf [ADVAPI32.@]
2514 * Makes an impersonation token that represents the process user and assigns
2515 * to the current thread.
2517 * PARAMS
2518 * ImpersonationLevel [I] Level at which to impersonate.
2520 * RETURNS
2521 * Success: TRUE.
2522 * Failure: FALSE.
2524 BOOL WINAPI
2525 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2527 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2530 /******************************************************************************
2531 * ImpersonateLoggedOnUser [ADVAPI32.@]
2533 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2535 DWORD size;
2536 NTSTATUS Status;
2537 HANDLE ImpersonationToken;
2538 TOKEN_TYPE Type;
2539 static BOOL warn = TRUE;
2541 if (warn)
2543 FIXME( "(%p)\n", hToken );
2544 warn = FALSE;
2546 if (!GetTokenInformation( hToken, TokenType, &Type,
2547 sizeof(TOKEN_TYPE), &size ))
2548 return FALSE;
2550 if (Type == TokenPrimary)
2552 OBJECT_ATTRIBUTES ObjectAttributes;
2554 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2556 Status = NtDuplicateToken( hToken,
2557 TOKEN_IMPERSONATE | TOKEN_QUERY,
2558 &ObjectAttributes,
2559 SecurityImpersonation,
2560 TokenImpersonation,
2561 &ImpersonationToken );
2562 if (Status != STATUS_SUCCESS)
2564 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2565 SetLastError( RtlNtStatusToDosError( Status ) );
2566 return FALSE;
2569 else
2570 ImpersonationToken = hToken;
2572 Status = NtSetInformationThread( GetCurrentThread(),
2573 ThreadImpersonationToken,
2574 &ImpersonationToken,
2575 sizeof(ImpersonationToken) );
2577 if (Type == TokenPrimary)
2578 NtClose( ImpersonationToken );
2580 if (Status != STATUS_SUCCESS)
2582 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2583 SetLastError( RtlNtStatusToDosError( Status ) );
2584 return FALSE;
2587 return TRUE;
2590 /******************************************************************************
2591 * ImpersonateAnonymousToken [ADVAPI32.@]
2593 BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
2595 TRACE("(%p)\n", thread);
2596 return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
2599 /******************************************************************************
2600 * AccessCheck [ADVAPI32.@]
2602 BOOL WINAPI
2603 AccessCheck(
2604 PSECURITY_DESCRIPTOR SecurityDescriptor,
2605 HANDLE ClientToken,
2606 DWORD DesiredAccess,
2607 PGENERIC_MAPPING GenericMapping,
2608 PPRIVILEGE_SET PrivilegeSet,
2609 LPDWORD PrivilegeSetLength,
2610 LPDWORD GrantedAccess,
2611 LPBOOL AccessStatus)
2613 NTSTATUS access_status;
2614 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2615 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2616 GrantedAccess, &access_status) );
2617 if (ret) *AccessStatus = set_ntstatus( access_status );
2618 return ret;
2622 /******************************************************************************
2623 * AccessCheckByType [ADVAPI32.@]
2625 BOOL WINAPI AccessCheckByType(
2626 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2627 PSID PrincipalSelfSid,
2628 HANDLE ClientToken,
2629 DWORD DesiredAccess,
2630 POBJECT_TYPE_LIST ObjectTypeList,
2631 DWORD ObjectTypeListLength,
2632 PGENERIC_MAPPING GenericMapping,
2633 PPRIVILEGE_SET PrivilegeSet,
2634 LPDWORD PrivilegeSetLength,
2635 LPDWORD GrantedAccess,
2636 LPBOOL AccessStatus)
2638 FIXME("stub\n");
2640 *AccessStatus = TRUE;
2642 return !*AccessStatus;
2645 /******************************************************************************
2646 * MapGenericMask [ADVAPI32.@]
2648 * Maps generic access rights into specific access rights according to the
2649 * supplied mapping.
2651 * PARAMS
2652 * AccessMask [I/O] Access rights.
2653 * GenericMapping [I] The mapping between generic and specific rights.
2655 * RETURNS
2656 * Nothing.
2658 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2660 RtlMapGenericMask( AccessMask, GenericMapping );
2663 /*************************************************************************
2664 * SetKernelObjectSecurity [ADVAPI32.@]
2666 BOOL WINAPI SetKernelObjectSecurity (
2667 IN HANDLE Handle,
2668 IN SECURITY_INFORMATION SecurityInformation,
2669 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2671 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2675 /******************************************************************************
2676 * AddAuditAccessAce [ADVAPI32.@]
2678 BOOL WINAPI AddAuditAccessAce(
2679 IN OUT PACL pAcl,
2680 IN DWORD dwAceRevision,
2681 IN DWORD dwAccessMask,
2682 IN PSID pSid,
2683 IN BOOL bAuditSuccess,
2684 IN BOOL bAuditFailure)
2686 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2687 bAuditSuccess, bAuditFailure) );
2690 /******************************************************************************
2691 * AddAuditAccessAceEx [ADVAPI32.@]
2693 BOOL WINAPI AddAuditAccessAceEx(
2694 IN OUT PACL pAcl,
2695 IN DWORD dwAceRevision,
2696 IN DWORD dwAceFlags,
2697 IN DWORD dwAccessMask,
2698 IN PSID pSid,
2699 IN BOOL bAuditSuccess,
2700 IN BOOL bAuditFailure)
2702 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2703 bAuditSuccess, bAuditFailure) );
2706 /******************************************************************************
2707 * AddAuditAccessObjectAce [ADVAPI32.@]
2709 BOOL WINAPI AddAuditAccessObjectAce(
2710 IN OUT PACL pAcl,
2711 IN DWORD dwAceRevision,
2712 IN DWORD dwAceFlags,
2713 IN DWORD dwAccessMask,
2714 IN GUID* pObjectTypeGuid,
2715 IN GUID* pInheritedObjectTypeGuid,
2716 IN PSID pSid,
2717 IN BOOL bAuditSuccess,
2718 IN BOOL bAuditFailure)
2720 return set_ntstatus( RtlAddAuditAccessObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
2721 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid, bAuditSuccess, bAuditFailure) );
2724 /******************************************************************************
2725 * LookupAccountNameA [ADVAPI32.@]
2727 BOOL WINAPI
2728 LookupAccountNameA(
2729 IN LPCSTR system,
2730 IN LPCSTR account,
2731 OUT PSID sid,
2732 OUT LPDWORD cbSid,
2733 LPSTR ReferencedDomainName,
2734 IN OUT LPDWORD cbReferencedDomainName,
2735 OUT PSID_NAME_USE name_use )
2737 BOOL ret;
2738 UNICODE_STRING lpSystemW;
2739 UNICODE_STRING lpAccountW;
2740 LPWSTR lpReferencedDomainNameW = NULL;
2742 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2743 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2745 if (ReferencedDomainName)
2746 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2748 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2749 cbReferencedDomainName, name_use);
2751 if (ret && lpReferencedDomainNameW)
2753 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2754 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2757 RtlFreeUnicodeString(&lpSystemW);
2758 RtlFreeUnicodeString(&lpAccountW);
2759 heap_free(lpReferencedDomainNameW);
2761 return ret;
2764 /******************************************************************************
2765 * lookup_user_account_name
2767 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2768 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2770 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2771 DWORD len = sizeof(buffer);
2772 HANDLE token;
2773 BOOL ret;
2774 PSID pSid;
2775 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2776 DWORD nameLen;
2778 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2780 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2781 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2784 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2785 CloseHandle( token );
2787 if (!ret) return FALSE;
2789 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2791 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2792 CopySid(*cbSid, Sid, pSid);
2793 if (*cbSid < GetLengthSid(pSid))
2795 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2796 ret = FALSE;
2798 *cbSid = GetLengthSid(pSid);
2800 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2801 if (!GetComputerNameW(domainName, &nameLen))
2803 domainName[0] = 0;
2804 nameLen = 0;
2806 if (*cchReferencedDomainName <= nameLen || !ret)
2808 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2809 nameLen += 1;
2810 ret = FALSE;
2812 else if (ReferencedDomainName)
2813 strcpyW(ReferencedDomainName, domainName);
2815 *cchReferencedDomainName = nameLen;
2817 if (ret)
2818 *peUse = SidTypeUser;
2820 return ret;
2823 /******************************************************************************
2824 * lookup_computer_account_name
2826 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2827 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2829 MAX_SID local;
2830 BOOL ret;
2831 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2832 DWORD nameLen;
2834 if ((ret = ADVAPI_GetComputerSid(&local)))
2836 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2837 CopySid(*cbSid, Sid, &local);
2838 if (*cbSid < GetLengthSid(&local))
2840 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2841 ret = FALSE;
2843 *cbSid = GetLengthSid(&local);
2846 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2847 if (!GetComputerNameW(domainName, &nameLen))
2849 domainName[0] = 0;
2850 nameLen = 0;
2852 if (*cchReferencedDomainName <= nameLen || !ret)
2854 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2855 nameLen += 1;
2856 ret = FALSE;
2858 else if (ReferencedDomainName)
2859 strcpyW(ReferencedDomainName, domainName);
2861 *cchReferencedDomainName = nameLen;
2863 if (ret)
2864 *peUse = SidTypeDomain;
2866 return ret;
2869 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2870 LSA_UNICODE_STRING *domain )
2872 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2874 while (p > str->Buffer && *p != '\\') p--;
2876 if (*p == '\\')
2878 domain->Buffer = str->Buffer;
2879 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2881 account->Buffer = p + 1;
2882 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2884 else
2886 domain->Buffer = NULL;
2887 domain->Length = 0;
2889 account->Buffer = str->Buffer;
2890 account->Length = str->Length;
2894 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2896 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2898 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2899 return TRUE;
2901 return FALSE;
2904 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2906 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2908 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2909 return TRUE;
2911 if (ACCOUNT_SIDS[idx].alias)
2913 len = strlenW( ACCOUNT_SIDS[idx].alias );
2914 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2915 return TRUE;
2917 return FALSE;
2921 * Helper function for LookupAccountNameW
2923 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2924 PSID Sid, LPDWORD cbSid,
2925 LPWSTR ReferencedDomainName,
2926 LPDWORD cchReferencedDomainName,
2927 PSID_NAME_USE peUse, BOOL *handled )
2929 PSID pSid;
2930 LSA_UNICODE_STRING account, domain;
2931 BOOL ret = TRUE;
2932 ULONG i;
2934 *handled = FALSE;
2935 split_domain_account( account_and_domain, &account, &domain );
2937 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2939 /* check domain first */
2940 if (domain.Buffer && !match_domain( i, &domain )) continue;
2942 if (match_account( i, &account ))
2944 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2946 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
2948 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2950 if (*cbSid < sidLen)
2952 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2953 ret = FALSE;
2955 else if (Sid)
2957 CopySid(*cbSid, Sid, pSid);
2959 *cbSid = sidLen;
2962 len = strlenW( ACCOUNT_SIDS[i].domain );
2963 if (*cchReferencedDomainName <= len || !ret)
2965 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2966 len++;
2967 ret = FALSE;
2969 else if (ReferencedDomainName)
2971 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2974 *cchReferencedDomainName = len;
2975 if (ret)
2976 *peUse = ACCOUNT_SIDS[i].name_use;
2978 heap_free(pSid);
2979 *handled = TRUE;
2980 return ret;
2983 return ret;
2986 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2987 PSID Sid, LPDWORD cbSid,
2988 LPWSTR ReferencedDomainName,
2989 LPDWORD cchReferencedDomainName,
2990 PSID_NAME_USE peUse, BOOL *handled )
2992 DWORD nameLen;
2993 LPWSTR userName = NULL;
2994 LSA_UNICODE_STRING account, domain;
2995 BOOL ret = TRUE;
2997 *handled = FALSE;
2998 split_domain_account( account_and_domain, &account, &domain );
3000 /* Let the current Unix user id masquerade as first Windows user account */
3002 nameLen = UNLEN + 1;
3003 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
3005 if (domain.Buffer)
3007 /* check to make sure this account is on this computer */
3008 if (GetComputerNameW( userName, &nameLen ) &&
3009 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
3011 SetLastError(ERROR_NONE_MAPPED);
3012 ret = FALSE;
3014 nameLen = UNLEN + 1;
3017 if (GetUserNameW( userName, &nameLen ) &&
3018 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
3020 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3021 *handled = TRUE;
3023 else
3025 nameLen = UNLEN + 1;
3026 if (GetComputerNameW( userName, &nameLen ) &&
3027 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
3029 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3030 *handled = TRUE;
3034 heap_free(userName);
3035 return ret;
3038 /******************************************************************************
3039 * LookupAccountNameW [ADVAPI32.@]
3041 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
3042 LPDWORD cbSid, LPWSTR ReferencedDomainName,
3043 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
3045 BOOL ret, handled;
3046 LSA_UNICODE_STRING account;
3048 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
3049 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
3051 if (!ADVAPI_IsLocalComputer( lpSystemName ))
3053 FIXME("remote computer not supported\n");
3054 SetLastError( RPC_S_SERVER_UNAVAILABLE );
3055 return FALSE;
3058 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
3060 lpAccountName = BUILTIN;
3063 RtlInitUnicodeString( &account, lpAccountName );
3065 /* Check well known SIDs first */
3066 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
3067 cchReferencedDomainName, peUse, &handled );
3068 if (handled)
3069 return ret;
3071 /* Check user names */
3072 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
3073 cchReferencedDomainName, peUse, &handled);
3074 if (handled)
3075 return ret;
3077 SetLastError( ERROR_NONE_MAPPED );
3078 return FALSE;
3081 /******************************************************************************
3082 * PrivilegeCheck [ADVAPI32.@]
3084 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
3086 BOOL ret;
3087 BOOLEAN Result;
3089 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
3091 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
3092 if (ret)
3093 *pfResult = Result;
3094 return ret;
3097 /******************************************************************************
3098 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
3100 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
3101 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3102 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3103 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3105 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
3106 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
3107 SecurityDescriptor, DesiredAccess, GenericMapping,
3108 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3109 return TRUE;
3112 /******************************************************************************
3113 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3115 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3116 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3117 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3118 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3120 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3121 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3122 SecurityDescriptor, DesiredAccess, GenericMapping,
3123 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3124 return TRUE;
3127 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3129 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3131 return TRUE;
3134 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3136 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3138 return TRUE;
3141 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3143 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3145 return TRUE;
3148 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3149 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3150 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3151 LPBOOL GenerateOnClose)
3153 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3154 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3155 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3156 GenerateOnClose);
3158 return TRUE;
3161 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3162 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3163 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3164 LPBOOL GenerateOnClose)
3166 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3167 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3168 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3169 GenerateOnClose);
3171 return TRUE;
3174 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3175 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3177 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3178 DesiredAccess, Privileges, AccessGranted);
3180 return TRUE;
3183 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3184 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3186 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3187 DesiredAccess, Privileges, AccessGranted);
3189 return TRUE;
3192 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3193 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3195 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3196 ClientToken, Privileges, AccessGranted);
3198 return TRUE;
3201 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3202 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3204 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3205 ClientToken, Privileges, AccessGranted);
3207 return TRUE;
3210 /******************************************************************************
3211 * GetSecurityInfo [ADVAPI32.@]
3213 * Retrieves a copy of the security descriptor associated with an object.
3215 * PARAMS
3216 * hObject [I] A handle for the object.
3217 * ObjectType [I] The type of object.
3218 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3219 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3220 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3221 * ppDacl [O] If non-null, receives a pointer to the DACL.
3222 * ppSacl [O] If non-null, receives a pointer to the SACL.
3223 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3224 * which must be freed with LocalFree.
3226 * RETURNS
3227 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3229 DWORD WINAPI GetSecurityInfo(
3230 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3231 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3232 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3233 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3236 PSECURITY_DESCRIPTOR sd;
3237 NTSTATUS status;
3238 ULONG n1, n2;
3239 BOOL present, defaulted;
3241 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3242 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3244 /* If no descriptor, we have to check that there's a pointer for the requested information */
3245 if( !ppSecurityDescriptor && (
3246 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3247 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3248 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3249 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3250 return ERROR_INVALID_PARAMETER;
3252 switch (ObjectType)
3254 case SE_SERVICE:
3255 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3256 break;
3257 default:
3258 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3259 break;
3261 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3262 return RtlNtStatusToDosError(status);
3264 sd = LocalAlloc(0, n1);
3265 if (!sd)
3266 return ERROR_NOT_ENOUGH_MEMORY;
3268 switch (ObjectType)
3270 case SE_SERVICE:
3271 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3272 break;
3273 default:
3274 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3275 break;
3277 if (status != STATUS_SUCCESS)
3279 LocalFree(sd);
3280 return RtlNtStatusToDosError(status);
3283 if (ppsidOwner)
3285 *ppsidOwner = NULL;
3286 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3288 if (ppsidGroup)
3290 *ppsidGroup = NULL;
3291 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3293 if (ppDacl)
3295 *ppDacl = NULL;
3296 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3298 if (ppSacl)
3300 *ppSacl = NULL;
3301 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3303 if (ppSecurityDescriptor)
3304 *ppSecurityDescriptor = sd;
3306 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3307 * NULL, because native happily returns the SIDs and ACLs that are requested
3308 * in this case.
3311 return ERROR_SUCCESS;
3314 /******************************************************************************
3315 * GetSecurityInfoExA [ADVAPI32.@]
3317 DWORD WINAPI GetSecurityInfoExA(
3318 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3319 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3320 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3321 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3324 FIXME("stub!\n");
3325 return ERROR_BAD_PROVIDER;
3328 /******************************************************************************
3329 * GetSecurityInfoExW [ADVAPI32.@]
3331 DWORD WINAPI GetSecurityInfoExW(
3332 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3333 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3334 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3335 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3338 FIXME("stub!\n");
3339 return ERROR_BAD_PROVIDER;
3342 /******************************************************************************
3343 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3345 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3346 LPSTR pTrusteeName, DWORD AccessPermissions,
3347 ACCESS_MODE AccessMode, DWORD Inheritance )
3349 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3350 AccessPermissions, AccessMode, Inheritance);
3352 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3353 pExplicitAccess->grfAccessMode = AccessMode;
3354 pExplicitAccess->grfInheritance = Inheritance;
3356 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3357 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3358 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3359 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3360 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3363 /******************************************************************************
3364 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3366 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3367 LPWSTR pTrusteeName, DWORD AccessPermissions,
3368 ACCESS_MODE AccessMode, DWORD Inheritance )
3370 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3371 AccessPermissions, AccessMode, Inheritance);
3373 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3374 pExplicitAccess->grfAccessMode = AccessMode;
3375 pExplicitAccess->grfInheritance = Inheritance;
3377 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3378 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3379 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3380 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3381 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3384 /******************************************************************************
3385 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3387 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3388 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3389 LPSTR InheritedObjectTypeName, LPSTR Name )
3391 DWORD ObjectsPresent = 0;
3393 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3394 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3396 /* Fill the OBJECTS_AND_NAME structure */
3397 pObjName->ObjectType = ObjectType;
3398 if (ObjectTypeName != NULL)
3400 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3403 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3404 if (InheritedObjectTypeName != NULL)
3406 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3409 pObjName->ObjectsPresent = ObjectsPresent;
3410 pObjName->ptstrName = Name;
3412 /* Fill the TRUSTEE structure */
3413 pTrustee->pMultipleTrustee = NULL;
3414 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3415 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3416 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3417 pTrustee->ptstrName = (LPSTR)pObjName;
3420 /******************************************************************************
3421 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3423 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3424 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3425 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3427 DWORD ObjectsPresent = 0;
3429 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3430 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3432 /* Fill the OBJECTS_AND_NAME structure */
3433 pObjName->ObjectType = ObjectType;
3434 if (ObjectTypeName != NULL)
3436 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3439 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3440 if (InheritedObjectTypeName != NULL)
3442 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3445 pObjName->ObjectsPresent = ObjectsPresent;
3446 pObjName->ptstrName = Name;
3448 /* Fill the TRUSTEE structure */
3449 pTrustee->pMultipleTrustee = NULL;
3450 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3451 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3452 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3453 pTrustee->ptstrName = (LPWSTR)pObjName;
3456 /******************************************************************************
3457 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3459 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3460 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3462 DWORD ObjectsPresent = 0;
3464 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3466 /* Fill the OBJECTS_AND_SID structure */
3467 if (pObjectGuid != NULL)
3469 pObjSid->ObjectTypeGuid = *pObjectGuid;
3470 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3472 else
3474 ZeroMemory(&pObjSid->ObjectTypeGuid,
3475 sizeof(GUID));
3478 if (pInheritedObjectGuid != NULL)
3480 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3481 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3483 else
3485 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3486 sizeof(GUID));
3489 pObjSid->ObjectsPresent = ObjectsPresent;
3490 pObjSid->pSid = pSid;
3492 /* Fill the TRUSTEE structure */
3493 pTrustee->pMultipleTrustee = NULL;
3494 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3495 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3496 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3497 pTrustee->ptstrName = (LPSTR) pObjSid;
3500 /******************************************************************************
3501 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3503 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3504 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3506 DWORD ObjectsPresent = 0;
3508 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3510 /* Fill the OBJECTS_AND_SID structure */
3511 if (pObjectGuid != NULL)
3513 pObjSid->ObjectTypeGuid = *pObjectGuid;
3514 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3516 else
3518 ZeroMemory(&pObjSid->ObjectTypeGuid,
3519 sizeof(GUID));
3522 if (pInheritedObjectGuid != NULL)
3524 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3525 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3527 else
3529 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3530 sizeof(GUID));
3533 pObjSid->ObjectsPresent = ObjectsPresent;
3534 pObjSid->pSid = pSid;
3536 /* Fill the TRUSTEE structure */
3537 pTrustee->pMultipleTrustee = NULL;
3538 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3539 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3540 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3541 pTrustee->ptstrName = (LPWSTR) pObjSid;
3544 /******************************************************************************
3545 * BuildTrusteeWithSidA [ADVAPI32.@]
3547 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3549 TRACE("%p %p\n", pTrustee, pSid);
3551 pTrustee->pMultipleTrustee = NULL;
3552 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3553 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3554 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3555 pTrustee->ptstrName = pSid;
3558 /******************************************************************************
3559 * BuildTrusteeWithSidW [ADVAPI32.@]
3561 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3563 TRACE("%p %p\n", pTrustee, pSid);
3565 pTrustee->pMultipleTrustee = NULL;
3566 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3567 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3568 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3569 pTrustee->ptstrName = pSid;
3572 /******************************************************************************
3573 * BuildTrusteeWithNameA [ADVAPI32.@]
3575 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3577 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3579 pTrustee->pMultipleTrustee = NULL;
3580 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3581 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3582 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3583 pTrustee->ptstrName = name;
3586 /******************************************************************************
3587 * BuildTrusteeWithNameW [ADVAPI32.@]
3589 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3591 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3593 pTrustee->pMultipleTrustee = NULL;
3594 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3595 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3596 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3597 pTrustee->ptstrName = name;
3600 /******************************************************************************
3601 * GetTrusteeFormA [ADVAPI32.@]
3603 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3605 TRACE("(%p)\n", pTrustee);
3607 if (!pTrustee)
3608 return TRUSTEE_BAD_FORM;
3610 return pTrustee->TrusteeForm;
3613 /******************************************************************************
3614 * GetTrusteeFormW [ADVAPI32.@]
3616 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3618 TRACE("(%p)\n", pTrustee);
3620 if (!pTrustee)
3621 return TRUSTEE_BAD_FORM;
3623 return pTrustee->TrusteeForm;
3626 /******************************************************************************
3627 * GetTrusteeNameA [ADVAPI32.@]
3629 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3631 TRACE("(%p)\n", pTrustee);
3633 if (!pTrustee)
3634 return NULL;
3636 return pTrustee->ptstrName;
3639 /******************************************************************************
3640 * GetTrusteeNameW [ADVAPI32.@]
3642 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3644 TRACE("(%p)\n", pTrustee);
3646 if (!pTrustee)
3647 return NULL;
3649 return pTrustee->ptstrName;
3652 /******************************************************************************
3653 * GetTrusteeTypeA [ADVAPI32.@]
3655 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3657 TRACE("(%p)\n", pTrustee);
3659 if (!pTrustee)
3660 return TRUSTEE_IS_UNKNOWN;
3662 return pTrustee->TrusteeType;
3665 /******************************************************************************
3666 * GetTrusteeTypeW [ADVAPI32.@]
3668 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3670 TRACE("(%p)\n", pTrustee);
3672 if (!pTrustee)
3673 return TRUSTEE_IS_UNKNOWN;
3675 return pTrustee->TrusteeType;
3678 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3679 DWORD nAclInformationLength,
3680 ACL_INFORMATION_CLASS dwAclInformationClass )
3682 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3683 nAclInformationLength, dwAclInformationClass);
3685 return TRUE;
3688 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3690 switch (form)
3692 case TRUSTEE_IS_NAME:
3694 *ptrustee_nameW = SERV_dup(trustee_nameA);
3695 return ERROR_SUCCESS;
3697 case TRUSTEE_IS_OBJECTS_AND_NAME:
3699 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3700 OBJECTS_AND_NAME_W *objW = NULL;
3702 if (objA)
3704 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3705 return ERROR_NOT_ENOUGH_MEMORY;
3707 objW->ObjectsPresent = objA->ObjectsPresent;
3708 objW->ObjectType = objA->ObjectType;
3709 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3710 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3711 objW->ptstrName = SERV_dup(objA->ptstrName);
3714 *ptrustee_nameW = (WCHAR *)objW;
3715 return ERROR_SUCCESS;
3717 /* These forms do not require conversion. */
3718 case TRUSTEE_IS_SID:
3719 case TRUSTEE_IS_OBJECTS_AND_SID:
3720 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3721 return ERROR_SUCCESS;
3722 default:
3723 return ERROR_INVALID_PARAMETER;
3727 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3729 switch (form)
3731 case TRUSTEE_IS_NAME:
3732 heap_free( trustee_nameW );
3733 break;
3734 case TRUSTEE_IS_OBJECTS_AND_NAME:
3736 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3738 if (objW)
3740 heap_free( objW->ptstrName );
3741 heap_free( objW->InheritedObjectTypeName );
3742 heap_free( objW->ObjectTypeName );
3743 heap_free( objW );
3746 break;
3748 /* Other forms did not require allocation, so no freeing is necessary. */
3749 default:
3750 break;
3754 /******************************************************************************
3755 * SetEntriesInAclA [ADVAPI32.@]
3757 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3758 PACL OldAcl, PACL* NewAcl )
3760 DWORD err = ERROR_SUCCESS;
3761 EXPLICIT_ACCESSW *pEntriesW;
3762 UINT alloc_index, free_index;
3764 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3766 if (NewAcl)
3767 *NewAcl = NULL;
3769 if (!count && !OldAcl)
3770 return ERROR_SUCCESS;
3772 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3773 if (!pEntriesW)
3774 return ERROR_NOT_ENOUGH_MEMORY;
3776 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3778 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3779 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3780 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3781 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3782 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3783 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3784 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3786 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3787 pEntries[alloc_index].Trustee.ptstrName,
3788 &pEntriesW[alloc_index].Trustee.ptstrName );
3789 if (err != ERROR_SUCCESS)
3791 if (err == ERROR_INVALID_PARAMETER)
3792 WARN("bad trustee form %d for trustee %d\n",
3793 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3795 goto cleanup;
3799 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3801 cleanup:
3802 /* Free any previously allocated trustee name buffers, taking into account
3803 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3804 * list. */
3805 for (free_index = 0; free_index < alloc_index; ++free_index)
3806 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3808 heap_free( pEntriesW );
3809 return err;
3812 /******************************************************************************
3813 * SetEntriesInAclW [ADVAPI32.@]
3815 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3816 PACL OldAcl, PACL* NewAcl )
3818 ULONG i;
3819 PSID *ppsid;
3820 DWORD ret = ERROR_SUCCESS;
3821 DWORD acl_size = sizeof(ACL);
3822 NTSTATUS status;
3824 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3826 if (NewAcl)
3827 *NewAcl = NULL;
3829 if (!count && !OldAcl)
3830 return ERROR_SUCCESS;
3832 /* allocate array of maximum sized sids allowed */
3833 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3834 if (!ppsid)
3835 return ERROR_OUTOFMEMORY;
3837 for (i = 0; i < count; i++)
3839 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3841 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3842 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3843 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3844 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3845 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3846 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3847 pEntries[i].Trustee.ptstrName);
3849 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3851 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3852 ret = ERROR_INVALID_PARAMETER;
3853 goto exit;
3856 switch (pEntries[i].Trustee.TrusteeForm)
3858 case TRUSTEE_IS_SID:
3859 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3860 ppsid[i], pEntries[i].Trustee.ptstrName))
3862 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3863 ret = ERROR_INVALID_PARAMETER;
3864 goto exit;
3866 break;
3867 case TRUSTEE_IS_NAME:
3869 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3870 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3871 SID_NAME_USE use;
3872 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3874 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3876 ret = GetLastError();
3877 goto exit;
3880 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3882 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3883 ret = ERROR_INVALID_PARAMETER;
3884 goto exit;
3886 break;
3888 case TRUSTEE_IS_OBJECTS_AND_SID:
3889 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3890 break;
3891 case TRUSTEE_IS_OBJECTS_AND_NAME:
3892 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3893 break;
3894 default:
3895 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3896 ret = ERROR_INVALID_PARAMETER;
3897 goto exit;
3900 /* Note: we overestimate the ACL size here as a tradeoff between
3901 * instructions (simplicity) and memory */
3902 switch (pEntries[i].grfAccessMode)
3904 case GRANT_ACCESS:
3905 case SET_ACCESS:
3906 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3907 break;
3908 case DENY_ACCESS:
3909 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3910 break;
3911 case SET_AUDIT_SUCCESS:
3912 case SET_AUDIT_FAILURE:
3913 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3914 break;
3915 case REVOKE_ACCESS:
3916 break;
3917 default:
3918 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3919 ret = ERROR_INVALID_PARAMETER;
3920 goto exit;
3924 if (OldAcl)
3926 ACL_SIZE_INFORMATION size_info;
3928 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3929 if (status != STATUS_SUCCESS)
3931 ret = RtlNtStatusToDosError(status);
3932 goto exit;
3934 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3937 *NewAcl = LocalAlloc(0, acl_size);
3938 if (!*NewAcl)
3940 ret = ERROR_OUTOFMEMORY;
3941 goto exit;
3944 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3945 if (status != STATUS_SUCCESS)
3947 ret = RtlNtStatusToDosError(status);
3948 goto exit;
3951 for (i = 0; i < count; i++)
3953 switch (pEntries[i].grfAccessMode)
3955 case GRANT_ACCESS:
3956 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3957 pEntries[i].grfInheritance,
3958 pEntries[i].grfAccessPermissions,
3959 ppsid[i]);
3960 break;
3961 case SET_ACCESS:
3963 ULONG j;
3964 BOOL add = TRUE;
3965 if (OldAcl)
3967 for (j = 0; ; j++)
3969 const ACE_HEADER *existing_ace_header;
3970 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3971 if (status != STATUS_SUCCESS)
3972 break;
3973 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3974 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3975 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3977 add = FALSE;
3978 break;
3982 if (add)
3983 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3984 pEntries[i].grfInheritance,
3985 pEntries[i].grfAccessPermissions,
3986 ppsid[i]);
3987 break;
3989 case DENY_ACCESS:
3990 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3991 pEntries[i].grfInheritance,
3992 pEntries[i].grfAccessPermissions,
3993 ppsid[i]);
3994 break;
3995 case SET_AUDIT_SUCCESS:
3996 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3997 pEntries[i].grfInheritance,
3998 pEntries[i].grfAccessPermissions,
3999 ppsid[i], TRUE, FALSE);
4000 break;
4001 case SET_AUDIT_FAILURE:
4002 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4003 pEntries[i].grfInheritance,
4004 pEntries[i].grfAccessPermissions,
4005 ppsid[i], FALSE, TRUE);
4006 break;
4007 default:
4008 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
4012 if (OldAcl)
4014 for (i = 0; ; i++)
4016 BOOL add = TRUE;
4017 ULONG j;
4018 const ACE_HEADER *old_ace_header;
4019 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
4020 if (status != STATUS_SUCCESS) break;
4021 for (j = 0; j < count; j++)
4023 if (pEntries[j].grfAccessMode == SET_ACCESS &&
4024 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4025 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4027 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
4028 add = FALSE;
4029 break;
4031 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
4033 switch (old_ace_header->AceType)
4035 case ACCESS_ALLOWED_ACE_TYPE:
4036 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4037 add = FALSE;
4038 break;
4039 case ACCESS_DENIED_ACE_TYPE:
4040 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
4041 add = FALSE;
4042 break;
4043 case SYSTEM_AUDIT_ACE_TYPE:
4044 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
4045 add = FALSE;
4046 break;
4047 case SYSTEM_ALARM_ACE_TYPE:
4048 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
4049 add = FALSE;
4050 break;
4051 default:
4052 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
4055 if (!add)
4056 break;
4059 if (add)
4060 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
4061 if (status != STATUS_SUCCESS)
4063 WARN("RtlAddAce failed with error 0x%08x\n", status);
4064 ret = RtlNtStatusToDosError(status);
4065 break;
4070 exit:
4071 heap_free(ppsid);
4072 return ret;
4075 /******************************************************************************
4076 * SetNamedSecurityInfoA [ADVAPI32.@]
4078 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
4079 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4080 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4082 LPWSTR wstr;
4083 DWORD r;
4085 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
4086 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4088 wstr = SERV_dup(pObjectName);
4089 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
4090 psidGroup, pDacl, pSacl );
4092 heap_free( wstr );
4094 return r;
4097 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
4098 PSECURITY_DESCRIPTOR ModificationDescriptor,
4099 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
4100 PGENERIC_MAPPING GenericMapping,
4101 HANDLE Token )
4103 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
4104 ObjectsSecurityDescriptor, GenericMapping, Token);
4106 return TRUE;
4109 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4111 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4114 /******************************************************************************
4115 * AreAnyAccessesGranted [ADVAPI32.@]
4117 * Determines whether or not any of a set of specified access permissions have
4118 * been granted or not.
4120 * PARAMS
4121 * GrantedAccess [I] The permissions that have been granted.
4122 * DesiredAccess [I] The permissions that you want to have.
4124 * RETURNS
4125 * Nonzero if any of the permissions have been granted, zero if none of the
4126 * permissions have been granted.
4129 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4131 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4134 /******************************************************************************
4135 * SetNamedSecurityInfoW [ADVAPI32.@]
4137 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4138 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4139 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4141 DWORD access = 0;
4142 HANDLE handle;
4143 DWORD err;
4145 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4146 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4148 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4150 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4151 access |= WRITE_OWNER;
4152 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4153 access |= WRITE_DAC;
4154 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4155 access |= ACCESS_SYSTEM_SECURITY;
4157 switch (ObjectType)
4159 case SE_SERVICE:
4160 if (!(err = get_security_service( pObjectName, access, &handle )))
4162 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4163 CloseServiceHandle( handle );
4165 break;
4166 case SE_REGISTRY_KEY:
4167 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4169 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4170 RegCloseKey( handle );
4172 break;
4173 case SE_FILE_OBJECT:
4174 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4175 access |= READ_CONTROL;
4176 if (!(err = get_security_file( pObjectName, access, &handle )))
4178 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4179 CloseHandle( handle );
4181 break;
4182 default:
4183 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4184 return ERROR_SUCCESS;
4186 return err;
4189 /******************************************************************************
4190 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4192 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4193 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4195 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4196 return ERROR_CALL_NOT_IMPLEMENTED;
4199 /******************************************************************************
4200 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4202 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4203 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4205 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4206 return ERROR_CALL_NOT_IMPLEMENTED;
4209 /******************************************************************************
4210 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4212 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4213 PACCESS_MASK pFailedAuditRights)
4215 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4216 return ERROR_CALL_NOT_IMPLEMENTED;
4220 /******************************************************************************
4221 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4223 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4224 PACCESS_MASK pFailedAuditRights)
4226 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4227 return ERROR_CALL_NOT_IMPLEMENTED;
4231 /******************************************************************************
4232 * ParseAclStringFlags
4234 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4236 DWORD flags = 0;
4237 LPCWSTR szAcl = *StringAcl;
4239 while (*szAcl != '(')
4241 if (*szAcl == 'P')
4243 flags |= SE_DACL_PROTECTED;
4245 else if (*szAcl == 'A')
4247 szAcl++;
4248 if (*szAcl == 'R')
4249 flags |= SE_DACL_AUTO_INHERIT_REQ;
4250 else if (*szAcl == 'I')
4251 flags |= SE_DACL_AUTO_INHERITED;
4253 szAcl++;
4256 *StringAcl = szAcl;
4257 return flags;
4260 /******************************************************************************
4261 * ParseAceStringType
4263 static const ACEFLAG AceType[] =
4265 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4266 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4267 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4268 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4269 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
4271 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4272 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4273 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4274 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4276 { NULL, 0 },
4279 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4281 UINT len = 0;
4282 LPCWSTR szAcl = *StringAcl;
4283 const ACEFLAG *lpaf = AceType;
4285 while (*szAcl == ' ')
4286 szAcl++;
4288 while (lpaf->wstr &&
4289 (len = strlenW(lpaf->wstr)) &&
4290 strncmpW(lpaf->wstr, szAcl, len))
4291 lpaf++;
4293 if (!lpaf->wstr)
4294 return 0;
4296 *StringAcl = szAcl + len;
4297 return lpaf->value;
4301 /******************************************************************************
4302 * ParseAceStringFlags
4304 static const ACEFLAG AceFlags[] =
4306 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4307 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4308 { SDDL_INHERITED, INHERITED_ACE },
4309 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4310 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4311 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4312 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4313 { NULL, 0 },
4316 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4318 UINT len = 0;
4319 BYTE flags = 0;
4320 LPCWSTR szAcl = *StringAcl;
4322 while (*szAcl == ' ')
4323 szAcl++;
4325 while (*szAcl != ';')
4327 const ACEFLAG *lpaf = AceFlags;
4329 while (lpaf->wstr &&
4330 (len = strlenW(lpaf->wstr)) &&
4331 strncmpW(lpaf->wstr, szAcl, len))
4332 lpaf++;
4334 if (!lpaf->wstr)
4335 return 0;
4337 flags |= lpaf->value;
4338 szAcl += len;
4341 *StringAcl = szAcl;
4342 return flags;
4346 /******************************************************************************
4347 * ParseAceStringRights
4349 static const ACEFLAG AceRights[] =
4351 { SDDL_GENERIC_ALL, GENERIC_ALL },
4352 { SDDL_GENERIC_READ, GENERIC_READ },
4353 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4354 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4356 { SDDL_READ_CONTROL, READ_CONTROL },
4357 { SDDL_STANDARD_DELETE, DELETE },
4358 { SDDL_WRITE_DAC, WRITE_DAC },
4359 { SDDL_WRITE_OWNER, WRITE_OWNER },
4361 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4362 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4363 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4364 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4365 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4366 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4367 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4368 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4369 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4371 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4372 { SDDL_FILE_READ, FILE_GENERIC_READ },
4373 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4374 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4376 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4377 { SDDL_KEY_READ, KEY_READ },
4378 { SDDL_KEY_WRITE, KEY_WRITE },
4379 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4381 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
4382 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
4383 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
4384 { NULL, 0 },
4387 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4389 UINT len = 0;
4390 DWORD rights = 0;
4391 LPCWSTR szAcl = *StringAcl;
4393 while (*szAcl == ' ')
4394 szAcl++;
4396 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4398 LPCWSTR p = szAcl;
4400 while (*p && *p != ';')
4401 p++;
4403 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4405 rights = strtoulW(szAcl, NULL, 16);
4406 szAcl = p;
4408 else
4409 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4411 else
4413 while (*szAcl != ';')
4415 const ACEFLAG *lpaf = AceRights;
4417 while (lpaf->wstr &&
4418 (len = strlenW(lpaf->wstr)) &&
4419 strncmpW(lpaf->wstr, szAcl, len))
4421 lpaf++;
4424 if (!lpaf->wstr)
4425 return 0;
4427 rights |= lpaf->value;
4428 szAcl += len;
4432 *StringAcl = szAcl;
4433 return rights;
4437 /******************************************************************************
4438 * ParseStringAclToAcl
4440 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4442 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4443 PACL pAcl, LPDWORD cBytes)
4445 DWORD val;
4446 DWORD sidlen;
4447 DWORD length = sizeof(ACL);
4448 DWORD acesize = 0;
4449 DWORD acecount = 0;
4450 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4451 DWORD error = ERROR_INVALID_ACL;
4453 TRACE("%s\n", debugstr_w(StringAcl));
4455 if (!StringAcl)
4456 return FALSE;
4458 if (pAcl) /* pAce is only useful if we're setting values */
4459 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4461 /* Parse ACL flags */
4462 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4464 /* Parse ACE */
4465 while (*StringAcl == '(')
4467 StringAcl++;
4469 /* Parse ACE type */
4470 val = ParseAceStringType(&StringAcl);
4471 if (pAce)
4472 pAce->Header.AceType = (BYTE) val;
4473 if (*StringAcl != ';')
4475 error = RPC_S_INVALID_STRING_UUID;
4476 goto lerr;
4478 StringAcl++;
4480 /* Parse ACE flags */
4481 val = ParseAceStringFlags(&StringAcl);
4482 if (pAce)
4483 pAce->Header.AceFlags = (BYTE) val;
4484 if (*StringAcl != ';')
4485 goto lerr;
4486 StringAcl++;
4488 /* Parse ACE rights */
4489 val = ParseAceStringRights(&StringAcl);
4490 if (pAce)
4491 pAce->Mask = val;
4492 if (*StringAcl != ';')
4493 goto lerr;
4494 StringAcl++;
4496 /* Parse ACE object guid */
4497 while (*StringAcl == ' ')
4498 StringAcl++;
4499 if (*StringAcl != ';')
4501 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4502 goto lerr;
4504 StringAcl++;
4506 /* Parse ACE inherit object guid */
4507 while (*StringAcl == ' ')
4508 StringAcl++;
4509 if (*StringAcl != ';')
4511 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4512 goto lerr;
4514 StringAcl++;
4516 /* Parse ACE account sid */
4517 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4519 while (*StringAcl && *StringAcl != ')')
4520 StringAcl++;
4523 if (*StringAcl != ')')
4524 goto lerr;
4525 StringAcl++;
4527 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4528 length += acesize;
4529 if (pAce)
4531 pAce->Header.AceSize = acesize;
4532 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4534 acecount++;
4537 *cBytes = length;
4539 if (length > 0xffff)
4541 ERR("ACL too large\n");
4542 goto lerr;
4545 if (pAcl)
4547 pAcl->AclRevision = ACL_REVISION;
4548 pAcl->Sbz1 = 0;
4549 pAcl->AclSize = length;
4550 pAcl->AceCount = acecount++;
4551 pAcl->Sbz2 = 0;
4553 return TRUE;
4555 lerr:
4556 SetLastError(error);
4557 WARN("Invalid ACE string format\n");
4558 return FALSE;
4562 /******************************************************************************
4563 * ParseStringSecurityDescriptorToSecurityDescriptor
4565 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4566 LPCWSTR StringSecurityDescriptor,
4567 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4568 LPDWORD cBytes)
4570 BOOL bret = FALSE;
4571 WCHAR toktype;
4572 WCHAR *tok;
4573 LPCWSTR lptoken;
4574 LPBYTE lpNext = NULL;
4575 DWORD len;
4577 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4579 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
4581 if (SecurityDescriptor)
4582 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4584 while (*StringSecurityDescriptor == ' ')
4585 StringSecurityDescriptor++;
4587 while (*StringSecurityDescriptor)
4589 toktype = *StringSecurityDescriptor;
4591 /* Expect char identifier followed by ':' */
4592 StringSecurityDescriptor++;
4593 if (*StringSecurityDescriptor != ':')
4595 SetLastError(ERROR_INVALID_PARAMETER);
4596 goto lend;
4598 StringSecurityDescriptor++;
4600 /* Extract token */
4601 lptoken = StringSecurityDescriptor;
4602 while (*lptoken && *lptoken != ':')
4603 lptoken++;
4605 if (*lptoken)
4606 lptoken--;
4608 len = lptoken - StringSecurityDescriptor;
4609 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4610 tok[len] = 0;
4612 switch (toktype)
4614 case 'O':
4616 DWORD bytes;
4618 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4619 goto lend;
4621 if (SecurityDescriptor)
4623 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4624 lpNext += bytes; /* Advance to next token */
4627 *cBytes += bytes;
4629 break;
4632 case 'G':
4634 DWORD bytes;
4636 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4637 goto lend;
4639 if (SecurityDescriptor)
4641 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4642 lpNext += bytes; /* Advance to next token */
4645 *cBytes += bytes;
4647 break;
4650 case 'D':
4652 DWORD flags;
4653 DWORD bytes;
4655 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4656 goto lend;
4658 if (SecurityDescriptor)
4660 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4661 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4662 lpNext += bytes; /* Advance to next token */
4665 *cBytes += bytes;
4667 break;
4670 case 'S':
4672 DWORD flags;
4673 DWORD bytes;
4675 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4676 goto lend;
4678 if (SecurityDescriptor)
4680 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4681 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4682 lpNext += bytes; /* Advance to next token */
4685 *cBytes += bytes;
4687 break;
4690 default:
4691 FIXME("Unknown token\n");
4692 SetLastError(ERROR_INVALID_PARAMETER);
4693 goto lend;
4696 StringSecurityDescriptor = lptoken;
4699 bret = TRUE;
4701 lend:
4702 heap_free(tok);
4703 return bret;
4706 /******************************************************************************
4707 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4709 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4710 LPCSTR StringSecurityDescriptor,
4711 DWORD StringSDRevision,
4712 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4713 PULONG SecurityDescriptorSize)
4715 BOOL ret;
4716 LPWSTR StringSecurityDescriptorW;
4718 if(!StringSecurityDescriptor)
4719 return FALSE;
4721 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4722 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4723 StringSDRevision, SecurityDescriptor,
4724 SecurityDescriptorSize);
4725 heap_free(StringSecurityDescriptorW);
4727 return ret;
4730 /******************************************************************************
4731 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4733 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4734 LPCWSTR StringSecurityDescriptor,
4735 DWORD StringSDRevision,
4736 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4737 PULONG SecurityDescriptorSize)
4739 DWORD cBytes;
4740 SECURITY_DESCRIPTOR* psd;
4741 BOOL bret = FALSE;
4743 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4745 if (GetVersion() & 0x80000000)
4747 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4748 goto lend;
4750 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4752 SetLastError(ERROR_INVALID_PARAMETER);
4753 goto lend;
4755 else if (StringSDRevision != SID_REVISION)
4757 SetLastError(ERROR_UNKNOWN_REVISION);
4758 goto lend;
4761 /* Compute security descriptor length */
4762 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4763 NULL, &cBytes))
4764 goto lend;
4766 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4767 if (!psd) goto lend;
4769 psd->Revision = SID_REVISION;
4770 psd->Control |= SE_SELF_RELATIVE;
4772 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4773 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4775 LocalFree(psd);
4776 goto lend;
4779 if (SecurityDescriptorSize)
4780 *SecurityDescriptorSize = cBytes;
4782 bret = TRUE;
4784 lend:
4785 TRACE(" ret=%d\n", bret);
4786 return bret;
4789 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4791 if (cch == -1)
4792 cch = strlenW(string);
4794 if (plen)
4795 *plen += cch;
4797 if (pwptr)
4799 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4800 *pwptr += cch;
4804 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4806 DWORD i;
4807 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4808 WCHAR subauthfmt[] = { '-','%','u',0 };
4809 WCHAR buf[26];
4810 SID *pisid = psid;
4812 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4814 SetLastError(ERROR_INVALID_SID);
4815 return FALSE;
4818 if (pisid->IdentifierAuthority.Value[0] ||
4819 pisid->IdentifierAuthority.Value[1])
4821 FIXME("not matching MS' bugs\n");
4822 SetLastError(ERROR_INVALID_SID);
4823 return FALSE;
4826 sprintfW( buf, fmt, pisid->Revision,
4827 MAKELONG(
4828 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4829 pisid->IdentifierAuthority.Value[4] ),
4830 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4831 pisid->IdentifierAuthority.Value[2] )
4832 ) );
4833 DumpString(buf, -1, pwptr, plen);
4835 for( i=0; i<pisid->SubAuthorityCount; i++ )
4837 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4838 DumpString(buf, -1, pwptr, plen);
4840 return TRUE;
4843 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4845 size_t i;
4846 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4848 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4850 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4851 return TRUE;
4855 return DumpSidNumeric(psid, pwptr, plen);
4858 static const LPCWSTR AceRightBitNames[32] = {
4859 SDDL_CREATE_CHILD, /* 0 */
4860 SDDL_DELETE_CHILD,
4861 SDDL_LIST_CHILDREN,
4862 SDDL_SELF_WRITE,
4863 SDDL_READ_PROPERTY, /* 4 */
4864 SDDL_WRITE_PROPERTY,
4865 SDDL_DELETE_TREE,
4866 SDDL_LIST_OBJECT,
4867 SDDL_CONTROL_ACCESS, /* 8 */
4868 NULL,
4869 NULL,
4870 NULL,
4871 NULL, /* 12 */
4872 NULL,
4873 NULL,
4874 NULL,
4875 SDDL_STANDARD_DELETE, /* 16 */
4876 SDDL_READ_CONTROL,
4877 SDDL_WRITE_DAC,
4878 SDDL_WRITE_OWNER,
4879 NULL, /* 20 */
4880 NULL,
4881 NULL,
4882 NULL,
4883 NULL, /* 24 */
4884 NULL,
4885 NULL,
4886 NULL,
4887 SDDL_GENERIC_ALL, /* 28 */
4888 SDDL_GENERIC_EXECUTE,
4889 SDDL_GENERIC_WRITE,
4890 SDDL_GENERIC_READ
4893 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4895 static const WCHAR fmtW[] = {'0','x','%','x',0};
4896 WCHAR buf[15];
4897 size_t i;
4899 if (mask == 0)
4900 return;
4902 /* first check if the right have name */
4903 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4905 if (AceRights[i].wstr == NULL)
4906 break;
4907 if (mask == AceRights[i].value)
4909 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4910 return;
4914 /* then check if it can be built from bit names */
4915 for (i = 0; i < 32; i++)
4917 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4919 /* can't be built from bit names */
4920 sprintfW(buf, fmtW, mask);
4921 DumpString(buf, -1, pwptr, plen);
4922 return;
4926 /* build from bit names */
4927 for (i = 0; i < 32; i++)
4928 if (mask & (1 << i))
4929 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4932 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4934 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4935 static const WCHAR openbr = '(';
4936 static const WCHAR closebr = ')';
4937 static const WCHAR semicolon = ';';
4939 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4941 SetLastError(ERROR_INVALID_ACL);
4942 return FALSE;
4945 piace = pace;
4946 DumpString(&openbr, 1, pwptr, plen);
4947 switch (piace->Header.AceType)
4949 case ACCESS_ALLOWED_ACE_TYPE:
4950 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4951 break;
4952 case ACCESS_DENIED_ACE_TYPE:
4953 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4954 break;
4955 case SYSTEM_AUDIT_ACE_TYPE:
4956 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4957 break;
4958 case SYSTEM_ALARM_ACE_TYPE:
4959 DumpString(SDDL_ALARM, -1, pwptr, plen);
4960 break;
4962 DumpString(&semicolon, 1, pwptr, plen);
4964 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4965 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4966 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4967 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4968 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4969 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4970 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4971 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4972 if (piace->Header.AceFlags & INHERITED_ACE)
4973 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4974 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4975 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4976 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4977 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4978 DumpString(&semicolon, 1, pwptr, plen);
4979 DumpRights(piace->Mask, pwptr, plen);
4980 DumpString(&semicolon, 1, pwptr, plen);
4981 /* objects not supported */
4982 DumpString(&semicolon, 1, pwptr, plen);
4983 /* objects not supported */
4984 DumpString(&semicolon, 1, pwptr, plen);
4985 if (!DumpSid(&piace->SidStart, pwptr, plen))
4986 return FALSE;
4987 DumpString(&closebr, 1, pwptr, plen);
4988 return TRUE;
4991 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4993 WORD count;
4994 UINT i;
4996 if (protected)
4997 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4998 if (autoInheritReq)
4999 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
5000 if (autoInherited)
5001 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
5003 if (pacl == NULL)
5004 return TRUE;
5006 if (!IsValidAcl(pacl))
5007 return FALSE;
5009 count = pacl->AceCount;
5010 for (i = 0; i < count; i++)
5012 LPVOID ace;
5013 if (!GetAce(pacl, i, &ace))
5014 return FALSE;
5015 if (!DumpAce(ace, pwptr, plen))
5016 return FALSE;
5019 return TRUE;
5022 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5024 static const WCHAR prefix[] = {'O',':',0};
5025 BOOL bDefaulted;
5026 PSID psid;
5028 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
5029 return FALSE;
5031 if (psid == NULL)
5032 return TRUE;
5034 DumpString(prefix, -1, pwptr, plen);
5035 if (!DumpSid(psid, pwptr, plen))
5036 return FALSE;
5037 return TRUE;
5040 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5042 static const WCHAR prefix[] = {'G',':',0};
5043 BOOL bDefaulted;
5044 PSID psid;
5046 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
5047 return FALSE;
5049 if (psid == NULL)
5050 return TRUE;
5052 DumpString(prefix, -1, pwptr, plen);
5053 if (!DumpSid(psid, pwptr, plen))
5054 return FALSE;
5055 return TRUE;
5058 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5060 static const WCHAR dacl[] = {'D',':',0};
5061 SECURITY_DESCRIPTOR_CONTROL control;
5062 BOOL present, defaulted;
5063 DWORD revision;
5064 PACL pacl;
5066 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
5067 return FALSE;
5069 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5070 return FALSE;
5072 if (!present)
5073 return TRUE;
5075 DumpString(dacl, 2, pwptr, plen);
5076 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
5077 return FALSE;
5078 return TRUE;
5081 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5083 static const WCHAR sacl[] = {'S',':',0};
5084 SECURITY_DESCRIPTOR_CONTROL control;
5085 BOOL present, defaulted;
5086 DWORD revision;
5087 PACL pacl;
5089 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
5090 return FALSE;
5092 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5093 return FALSE;
5095 if (!present)
5096 return TRUE;
5098 DumpString(sacl, 2, pwptr, plen);
5099 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
5100 return FALSE;
5101 return TRUE;
5104 /******************************************************************************
5105 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5107 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
5109 ULONG len;
5110 WCHAR *wptr, *wstr;
5112 if (SDRevision != SDDL_REVISION_1)
5114 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
5115 SetLastError(ERROR_UNKNOWN_REVISION);
5116 return FALSE;
5119 len = 0;
5120 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5121 if (!DumpOwner(SecurityDescriptor, NULL, &len))
5122 return FALSE;
5123 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5124 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5125 return FALSE;
5126 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5127 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5128 return FALSE;
5129 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5130 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5131 return FALSE;
5133 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5134 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5135 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5136 LocalFree (wstr);
5137 return FALSE;
5139 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5140 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5141 LocalFree (wstr);
5142 return FALSE;
5144 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5145 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5146 LocalFree (wstr);
5147 return FALSE;
5149 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5150 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5151 LocalFree (wstr);
5152 return FALSE;
5154 *wptr = 0;
5156 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5157 *OutputString = wstr;
5158 if (OutputLen)
5159 *OutputLen = strlenW(*OutputString)+1;
5160 return TRUE;
5163 /******************************************************************************
5164 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5166 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5168 LPWSTR wstr;
5169 ULONG len;
5170 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5172 int lenA;
5174 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5175 *OutputString = heap_alloc(lenA);
5176 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5177 LocalFree(wstr);
5179 if (OutputLen != NULL)
5180 *OutputLen = lenA;
5181 return TRUE;
5183 else
5185 *OutputString = NULL;
5186 if (OutputLen)
5187 *OutputLen = 0;
5188 return FALSE;
5192 /******************************************************************************
5193 * ConvertStringSidToSidW [ADVAPI32.@]
5195 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5197 BOOL bret = FALSE;
5198 DWORD cBytes;
5200 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5201 if (GetVersion() & 0x80000000)
5202 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5203 else if (!StringSid || !Sid)
5204 SetLastError(ERROR_INVALID_PARAMETER);
5205 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5207 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5209 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5210 if (!bret)
5211 LocalFree(*Sid);
5213 return bret;
5216 /******************************************************************************
5217 * ConvertStringSidToSidA [ADVAPI32.@]
5219 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5221 BOOL bret = FALSE;
5223 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5224 if (GetVersion() & 0x80000000)
5225 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5226 else if (!StringSid || !Sid)
5227 SetLastError(ERROR_INVALID_PARAMETER);
5228 else
5230 WCHAR *wStringSid = SERV_dup(StringSid);
5231 bret = ConvertStringSidToSidW(wStringSid, Sid);
5232 heap_free(wStringSid);
5234 return bret;
5237 /******************************************************************************
5238 * ConvertSidToStringSidW [ADVAPI32.@]
5240 * format of SID string is:
5241 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5242 * where
5243 * <rev> is the revision of the SID encoded as decimal
5244 * <auth> is the identifier authority encoded as hex
5245 * <subauthN> is the subauthority id encoded as decimal
5247 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5249 DWORD len = 0;
5250 LPWSTR wstr, wptr;
5252 TRACE("%p %p\n", pSid, pstr );
5254 len = 0;
5255 if (!DumpSidNumeric(pSid, NULL, &len))
5256 return FALSE;
5257 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5258 DumpSidNumeric(pSid, &wptr, NULL);
5259 *wptr = 0;
5261 *pstr = wstr;
5262 return TRUE;
5265 /******************************************************************************
5266 * ConvertSidToStringSidA [ADVAPI32.@]
5268 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5270 LPWSTR wstr = NULL;
5271 LPSTR str;
5272 UINT len;
5274 TRACE("%p %p\n", pSid, pstr );
5276 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5277 return FALSE;
5279 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5280 str = LocalAlloc( 0, len );
5281 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5282 LocalFree( wstr );
5284 *pstr = str;
5286 return TRUE;
5289 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5290 PSECURITY_DESCRIPTOR pdesc,
5291 PSECURITY_DESCRIPTOR cdesc,
5292 PSECURITY_DESCRIPTOR* ndesc,
5293 GUID* objtype,
5294 BOOL isdir,
5295 PGENERIC_MAPPING genmap )
5297 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5299 return FALSE;
5302 BOOL WINAPI CreatePrivateObjectSecurityEx(
5303 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5304 GUID *objtype, BOOL is_directory, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5306 SECURITY_DESCRIPTOR_RELATIVE *relative;
5307 DWORD needed, offset;
5308 BYTE *buffer;
5310 FIXME("%p %p %p %p %d %u %p %p - returns fake SECURITY_DESCRIPTOR\n", parent, creator, out,
5311 objtype, is_directory, flags, token, mapping);
5313 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5314 needed += sizeof(sidWorld);
5315 needed += sizeof(sidWorld);
5316 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5317 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5319 if (!(buffer = heap_alloc( needed ))) return FALSE;
5320 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5321 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5323 heap_free( buffer );
5324 return FALSE;
5326 relative->Control |= SE_SELF_RELATIVE;
5327 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5329 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5330 relative->Owner = offset;
5331 offset += sizeof(sidWorld);
5333 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5334 relative->Group = offset;
5335 offset += sizeof(sidWorld);
5337 GetWorldAccessACL( (ACL *)(buffer + offset) );
5338 relative->Dacl = offset;
5339 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5341 GetWorldAccessACL( (ACL *)(buffer + offset) );
5342 relative->Sacl = offset;
5344 *out = relative;
5345 return TRUE;
5348 BOOL WINAPI CreatePrivateObjectSecurity(
5349 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5350 BOOL is_container, HANDLE token, PGENERIC_MAPPING mapping)
5352 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, 0, token, mapping);
5355 BOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(
5356 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5357 GUID **types, ULONG count, BOOL is_container, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5359 FIXME(": semi-stub\n");
5360 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, flags, token, mapping);
5363 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5365 FIXME("%p - stub\n", ObjectDescriptor);
5367 heap_free( *ObjectDescriptor );
5368 return TRUE;
5371 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserA(
5372 HANDLE hToken,
5373 LPCSTR lpApplicationName,
5374 LPSTR lpCommandLine,
5375 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5376 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5377 BOOL bInheritHandles,
5378 DWORD dwCreationFlags,
5379 LPVOID lpEnvironment,
5380 LPCSTR lpCurrentDirectory,
5381 LPSTARTUPINFOA lpStartupInfo,
5382 LPPROCESS_INFORMATION lpProcessInformation )
5384 BOOL ret;
5385 WCHAR *appW, *cmdlnW, *cwdW;
5386 STARTUPINFOW sinfo;
5388 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5389 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5390 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5392 appW = SERV_dup(lpApplicationName);
5393 cmdlnW = SERV_dup(lpCommandLine);
5394 cwdW = SERV_dup(lpCurrentDirectory);
5395 sinfo.cb = sizeof(sinfo);
5396 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5397 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5398 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5399 sinfo.dwX = lpStartupInfo->dwX;
5400 sinfo.dwY = lpStartupInfo->dwY;
5401 sinfo.dwXSize = lpStartupInfo->dwXSize;
5402 sinfo.dwYSize = lpStartupInfo->dwYSize;
5403 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5404 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5405 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5406 sinfo.dwFlags = lpStartupInfo->dwFlags;
5407 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5408 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5409 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5410 sinfo.hStdInput = lpStartupInfo->hStdInput;
5411 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5412 sinfo.hStdError = lpStartupInfo->hStdError;
5413 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5414 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5415 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5416 heap_free(appW);
5417 heap_free(cmdlnW);
5418 heap_free(cwdW);
5419 heap_free(sinfo.lpReserved);
5420 heap_free(sinfo.lpDesktop);
5421 heap_free(sinfo.lpTitle);
5423 return ret;
5426 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(
5427 HANDLE hToken,
5428 LPCWSTR lpApplicationName,
5429 LPWSTR lpCommandLine,
5430 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5431 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5432 BOOL bInheritHandles,
5433 DWORD dwCreationFlags,
5434 LPVOID lpEnvironment,
5435 LPCWSTR lpCurrentDirectory,
5436 LPSTARTUPINFOW lpStartupInfo,
5437 LPPROCESS_INFORMATION lpProcessInformation )
5439 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5440 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5441 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5442 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5444 /* We should create the process with a suspended main thread */
5445 if (!CreateProcessW (lpApplicationName,
5446 lpCommandLine,
5447 lpProcessAttributes,
5448 lpThreadAttributes,
5449 bInheritHandles,
5450 dwCreationFlags, /* CREATE_SUSPENDED */
5451 lpEnvironment,
5452 lpCurrentDirectory,
5453 lpStartupInfo,
5454 lpProcessInformation))
5456 return FALSE;
5459 return TRUE;
5462 /******************************************************************************
5463 * CreateProcessWithLogonW
5465 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5466 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5467 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5469 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5470 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5471 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5472 lpStartupInfo, lpProcessInformation);
5474 return FALSE;
5477 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5478 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5479 PROCESS_INFORMATION *process_information )
5481 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5482 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5483 creation_flags, environment, debugstr_w(current_directory),
5484 startup_info, process_information);
5486 /* FIXME: check if handles should be inherited */
5487 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5488 current_directory, startup_info, process_information );
5491 /******************************************************************************
5492 * DuplicateTokenEx [ADVAPI32.@]
5494 BOOL WINAPI DuplicateTokenEx(
5495 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5496 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5497 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5498 TOKEN_TYPE TokenType,
5499 PHANDLE DuplicateTokenHandle )
5501 OBJECT_ATTRIBUTES ObjectAttributes;
5503 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5504 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5506 InitializeObjectAttributes(
5507 &ObjectAttributes,
5508 NULL,
5509 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5510 NULL,
5511 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5513 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5514 dwDesiredAccess,
5515 &ObjectAttributes,
5516 ImpersonationLevel,
5517 TokenType,
5518 DuplicateTokenHandle ) );
5521 BOOL WINAPI DuplicateToken(
5522 HANDLE ExistingTokenHandle,
5523 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5524 PHANDLE DuplicateTokenHandle )
5526 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5527 NULL, ImpersonationLevel, TokenImpersonation,
5528 DuplicateTokenHandle );
5531 /******************************************************************************
5532 * ComputeStringSidSize
5534 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5536 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5538 int ctok = 0;
5539 while (*StringSid)
5541 if (*StringSid == '-')
5542 ctok++;
5543 StringSid++;
5546 if (ctok >= 3)
5547 return GetSidLengthRequired(ctok - 2);
5549 else /* String constant format - Only available in winxp and above */
5551 unsigned int i;
5553 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5554 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5555 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5557 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5558 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5560 MAX_SID local;
5561 ADVAPI_GetComputerSid(&local);
5562 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5567 return GetSidLengthRequired(0);
5570 /******************************************************************************
5571 * ParseStringSidToSid
5573 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5575 BOOL bret = FALSE;
5576 SID* pisid=pSid;
5578 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5579 if (!StringSid)
5581 SetLastError(ERROR_INVALID_PARAMETER);
5582 TRACE("StringSid is NULL, returning FALSE\n");
5583 return FALSE;
5586 while (*StringSid == ' ')
5587 StringSid++;
5589 *cBytes = ComputeStringSidSize(StringSid);
5590 if (!pisid) /* Simply compute the size */
5592 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5593 return TRUE;
5596 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5598 DWORD i = 0, identAuth;
5599 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5601 StringSid += 2; /* Advance to Revision */
5602 pisid->Revision = atoiW(StringSid);
5604 if (pisid->Revision != SDDL_REVISION)
5606 TRACE("Revision %d is unknown\n", pisid->Revision);
5607 goto lend; /* ERROR_INVALID_SID */
5609 if (csubauth == 0)
5611 TRACE("SubAuthorityCount is 0\n");
5612 goto lend; /* ERROR_INVALID_SID */
5615 pisid->SubAuthorityCount = csubauth;
5617 /* Advance to identifier authority */
5618 while (*StringSid && *StringSid != '-')
5619 StringSid++;
5620 if (*StringSid == '-')
5621 StringSid++;
5623 /* MS' implementation can't handle values greater than 2^32 - 1, so
5624 * we don't either; assume most significant bytes are always 0
5626 pisid->IdentifierAuthority.Value[0] = 0;
5627 pisid->IdentifierAuthority.Value[1] = 0;
5628 identAuth = atoiW(StringSid);
5629 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5630 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5631 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5632 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5634 /* Advance to first sub authority */
5635 while (*StringSid && *StringSid != '-')
5636 StringSid++;
5637 if (*StringSid == '-')
5638 StringSid++;
5640 while (*StringSid)
5642 pisid->SubAuthority[i++] = atoiW(StringSid);
5644 while (*StringSid && *StringSid != '-')
5645 StringSid++;
5646 if (*StringSid == '-')
5647 StringSid++;
5650 if (i != pisid->SubAuthorityCount)
5651 goto lend; /* ERROR_INVALID_SID */
5653 bret = TRUE;
5655 else /* String constant format - Only available in winxp and above */
5657 unsigned int i;
5658 pisid->Revision = SDDL_REVISION;
5660 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5661 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5663 DWORD j;
5664 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5665 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5666 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5667 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5668 bret = TRUE;
5671 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5672 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5674 ADVAPI_GetComputerSid(pisid);
5675 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5676 pisid->SubAuthorityCount++;
5677 bret = TRUE;
5680 if (!bret)
5681 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5684 lend:
5685 if (!bret)
5686 SetLastError(ERROR_INVALID_SID);
5688 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5689 return bret;
5692 /******************************************************************************
5693 * GetNamedSecurityInfoA [ADVAPI32.@]
5695 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5696 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5697 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5698 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5700 LPWSTR wstr;
5701 DWORD r;
5703 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5704 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5706 wstr = SERV_dup(pObjectName);
5707 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5708 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5710 heap_free( wstr );
5712 return r;
5715 /******************************************************************************
5716 * GetNamedSecurityInfoW [ADVAPI32.@]
5718 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5719 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5720 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5722 DWORD access = 0;
5723 HANDLE handle;
5724 DWORD err;
5726 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5727 group, dacl, sacl, descriptor );
5729 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5730 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5732 /* If no descriptor, we have to check that there's a pointer for the requested information */
5733 if( !descriptor && (
5734 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5735 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5736 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5737 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5738 return ERROR_INVALID_PARAMETER;
5740 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5741 access |= READ_CONTROL;
5742 if (info & SACL_SECURITY_INFORMATION)
5743 access |= ACCESS_SYSTEM_SECURITY;
5745 switch (type)
5747 case SE_SERVICE:
5748 if (!(err = get_security_service( name, access, &handle )))
5750 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5751 CloseServiceHandle( handle );
5753 break;
5754 case SE_REGISTRY_KEY:
5755 if (!(err = get_security_regkey( name, access, &handle )))
5757 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5758 RegCloseKey( handle );
5760 break;
5761 case SE_FILE_OBJECT:
5762 if (!(err = get_security_file( name, access, &handle )))
5764 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5765 CloseHandle( handle );
5767 break;
5768 default:
5769 FIXME( "Object type %d is not currently supported.\n", type );
5770 if (owner) *owner = NULL;
5771 if (group) *group = NULL;
5772 if (dacl) *dacl = NULL;
5773 if (sacl) *sacl = NULL;
5774 if (descriptor) *descriptor = NULL;
5775 return ERROR_SUCCESS;
5777 return err;
5780 /******************************************************************************
5781 * GetNamedSecurityInfoExW [ADVAPI32.@]
5783 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5784 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5785 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5787 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5788 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5789 return ERROR_CALL_NOT_IMPLEMENTED;
5792 /******************************************************************************
5793 * GetNamedSecurityInfoExA [ADVAPI32.@]
5795 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5796 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5797 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5799 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5800 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5801 return ERROR_CALL_NOT_IMPLEMENTED;
5804 /******************************************************************************
5805 * DecryptFileW [ADVAPI32.@]
5807 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5809 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5810 return TRUE;
5813 /******************************************************************************
5814 * DecryptFileA [ADVAPI32.@]
5816 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5818 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5819 return TRUE;
5822 /******************************************************************************
5823 * EncryptFileW [ADVAPI32.@]
5825 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5827 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5828 return TRUE;
5831 /******************************************************************************
5832 * EncryptFileA [ADVAPI32.@]
5834 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5836 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5837 return TRUE;
5840 /******************************************************************************
5841 * FileEncryptionStatusW [ADVAPI32.@]
5843 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5845 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5846 if (!lpStatus)
5847 return FALSE;
5848 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5849 return TRUE;
5852 /******************************************************************************
5853 * FileEncryptionStatusA [ADVAPI32.@]
5855 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5857 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5858 if (!lpStatus)
5859 return FALSE;
5860 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5861 return TRUE;
5864 /******************************************************************************
5865 * SetSecurityInfo [ADVAPI32.@]
5867 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5868 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5869 PSID psidGroup, PACL pDacl, PACL pSacl)
5871 SECURITY_DESCRIPTOR sd;
5872 PACL dacl = pDacl;
5873 NTSTATUS status;
5875 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5876 return ERROR_INVALID_SECURITY_DESCR;
5878 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5879 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5880 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5881 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5882 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5884 if (ObjectType == SE_FILE_OBJECT && pDacl)
5886 SECURITY_DESCRIPTOR_CONTROL control;
5887 PSECURITY_DESCRIPTOR psd;
5888 OBJECT_NAME_INFORMATION *name_info;
5889 DWORD size, rev;
5891 status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
5892 if (status != STATUS_BUFFER_TOO_SMALL)
5893 return RtlNtStatusToDosError(status);
5895 psd = heap_alloc(size);
5896 if (!psd)
5897 return ERROR_NOT_ENOUGH_MEMORY;
5899 status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
5900 if (status)
5902 heap_free(psd);
5903 return RtlNtStatusToDosError(status);
5906 status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
5907 heap_free(psd);
5908 if (status)
5909 return RtlNtStatusToDosError(status);
5910 /* TODO: copy some control flags to new sd */
5912 /* inherit parent directory DACL */
5913 if (!(control & SE_DACL_PROTECTED))
5915 status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
5916 if (status != STATUS_INFO_LENGTH_MISMATCH)
5917 return RtlNtStatusToDosError(status);
5919 name_info = heap_alloc(size);
5920 if (!name_info)
5921 return ERROR_NOT_ENOUGH_MEMORY;
5923 status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
5924 if (status)
5926 heap_free(name_info);
5927 return RtlNtStatusToDosError(status);
5930 for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
5931 if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
5932 name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
5933 break;
5934 if (name_info->Name.Length)
5936 OBJECT_ATTRIBUTES attr;
5937 IO_STATUS_BLOCK io;
5938 HANDLE parent;
5939 PSECURITY_DESCRIPTOR parent_sd;
5940 ACL *parent_dacl;
5941 DWORD err = ERROR_ACCESS_DENIED;
5943 name_info->Name.Buffer[name_info->Name.Length/2] = 0;
5945 attr.Length = sizeof(attr);
5946 attr.RootDirectory = 0;
5947 attr.Attributes = 0;
5948 attr.ObjectName = &name_info->Name;
5949 attr.SecurityDescriptor = NULL;
5950 status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
5951 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5952 FILE_OPEN_FOR_BACKUP_INTENT);
5953 heap_free(name_info);
5954 if (!status)
5956 err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
5957 NULL, NULL, &parent_dacl, NULL, &parent_sd);
5958 CloseHandle(parent);
5961 if (!err)
5963 int i;
5965 dacl = heap_alloc_zero(pDacl->AclSize+parent_dacl->AclSize);
5966 if (!dacl)
5968 LocalFree(parent_sd);
5969 return ERROR_NOT_ENOUGH_MEMORY;
5971 memcpy(dacl, pDacl, pDacl->AclSize);
5972 dacl->AclSize = pDacl->AclSize+parent_dacl->AclSize;
5974 for (i=0; i<parent_dacl->AceCount; i++)
5976 ACE_HEADER *ace;
5978 if (!GetAce(parent_dacl, i, (void*)&ace))
5979 continue;
5980 if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
5981 continue;
5982 if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
5983 (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
5985 FIXME("unsupported flags: %x\n", ace->AceFlags);
5986 continue;
5989 if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
5990 ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
5991 ace->AceFlags &= ~INHERIT_ONLY_ACE;
5992 ace->AceFlags |= INHERITED_ACE;
5994 if(!AddAce(dacl, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
5995 WARN("error adding inherited ACE\n");
5997 LocalFree(parent_sd);
6000 else
6001 heap_free(name_info);
6005 SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
6007 if (SecurityInfo & SACL_SECURITY_INFORMATION)
6008 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
6010 switch (ObjectType)
6012 case SE_SERVICE:
6013 FIXME("stub: Service objects are not supported at this time.\n");
6014 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
6015 break;
6016 default:
6017 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
6018 break;
6020 if (dacl != pDacl)
6021 heap_free(dacl);
6022 return RtlNtStatusToDosError(status);
6025 /******************************************************************************
6026 * SaferCreateLevel [ADVAPI32.@]
6028 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
6029 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
6031 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
6033 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6034 return TRUE;
6037 /******************************************************************************
6038 * SaferComputeTokenFromLevel [ADVAPI32.@]
6040 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
6041 DWORD flags, LPVOID reserved)
6043 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
6045 *access_token = (HANDLE)0xdeadbeef;
6046 return TRUE;
6049 /******************************************************************************
6050 * SaferCloseLevel [ADVAPI32.@]
6052 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
6054 FIXME("(%p) stub\n", handle);
6055 return TRUE;
6058 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
6059 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
6060 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
6061 BOOL KeepExplicit, FN_PROGRESS fnProgress,
6062 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
6064 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
6065 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
6066 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
6068 return ERROR_SUCCESS;
6071 /******************************************************************************
6072 * SaferGetPolicyInformation [ADVAPI32.@]
6074 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
6075 PVOID buffer, PDWORD required, LPVOID lpReserved)
6077 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
6078 return FALSE;
6081 /******************************************************************************
6082 * SaferSetLevelInformation [ADVAPI32.@]
6084 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
6085 LPVOID buffer, DWORD size)
6087 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
6088 return FALSE;