winemaker: Remove trailing semicolon from PreprocessorDefinitions.
[wine.git] / dlls / advapi32 / security.c
blobe36792cff4b1a2feb35a17db719b4462ad0d2565
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 /******************************************************************************
1715 * AddMandatoryAce [ADVAPI32.@]
1717 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1719 return set_ntstatus(RtlAddMandatoryAce(acl, ace_revision, ace_flags, mandatory_policy,
1720 SYSTEM_MANDATORY_LABEL_ACE_TYPE, label_sid));
1723 /******************************************************************************
1724 * DeleteAce [ADVAPI32.@]
1726 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1728 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1731 /******************************************************************************
1732 * FindFirstFreeAce [ADVAPI32.@]
1734 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1736 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1739 /******************************************************************************
1740 * GetAce [ADVAPI32.@]
1742 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1744 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1747 /******************************************************************************
1748 * GetAclInformation [ADVAPI32.@]
1750 BOOL WINAPI GetAclInformation(
1751 PACL pAcl,
1752 LPVOID pAclInformation,
1753 DWORD nAclInformationLength,
1754 ACL_INFORMATION_CLASS dwAclInformationClass)
1756 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1757 nAclInformationLength, dwAclInformationClass));
1760 /******************************************************************************
1761 * IsValidAcl [ADVAPI32.@]
1763 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1765 return RtlValidAcl(pAcl);
1768 /* ##############################
1769 ###### MISC FUNCTIONS ######
1770 ##############################
1773 /******************************************************************************
1774 * AllocateLocallyUniqueId [ADVAPI32.@]
1776 * PARAMS
1777 * lpLuid []
1779 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1781 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1784 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1785 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1786 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1787 { '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 };
1788 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1789 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1790 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1791 { '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 };
1792 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1793 { '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 };
1794 static const WCHAR SE_TCB_NAME_W[] =
1795 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1796 static const WCHAR SE_SECURITY_NAME_W[] =
1797 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1798 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1799 { '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 };
1800 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1801 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1802 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1803 { '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 };
1804 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1805 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1806 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1807 { '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 };
1808 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1809 { '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 };
1810 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1811 { '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 };
1812 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1813 { '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 };
1814 static const WCHAR SE_BACKUP_NAME_W[] =
1815 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1816 static const WCHAR SE_RESTORE_NAME_W[] =
1817 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1818 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1819 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1820 static const WCHAR SE_DEBUG_NAME_W[] =
1821 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1822 static const WCHAR SE_AUDIT_NAME_W[] =
1823 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1824 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1825 { '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 };
1826 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1827 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1828 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1829 { '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 };
1830 static const WCHAR SE_UNDOCK_NAME_W[] =
1831 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1832 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1833 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1834 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1835 { '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 };
1836 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1837 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1838 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1839 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1840 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1841 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1843 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1845 NULL,
1846 NULL,
1847 SE_CREATE_TOKEN_NAME_W,
1848 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1849 SE_LOCK_MEMORY_NAME_W,
1850 SE_INCREASE_QUOTA_NAME_W,
1851 SE_MACHINE_ACCOUNT_NAME_W,
1852 SE_TCB_NAME_W,
1853 SE_SECURITY_NAME_W,
1854 SE_TAKE_OWNERSHIP_NAME_W,
1855 SE_LOAD_DRIVER_NAME_W,
1856 SE_SYSTEM_PROFILE_NAME_W,
1857 SE_SYSTEMTIME_NAME_W,
1858 SE_PROF_SINGLE_PROCESS_NAME_W,
1859 SE_INC_BASE_PRIORITY_NAME_W,
1860 SE_CREATE_PAGEFILE_NAME_W,
1861 SE_CREATE_PERMANENT_NAME_W,
1862 SE_BACKUP_NAME_W,
1863 SE_RESTORE_NAME_W,
1864 SE_SHUTDOWN_NAME_W,
1865 SE_DEBUG_NAME_W,
1866 SE_AUDIT_NAME_W,
1867 SE_SYSTEM_ENVIRONMENT_NAME_W,
1868 SE_CHANGE_NOTIFY_NAME_W,
1869 SE_REMOTE_SHUTDOWN_NAME_W,
1870 SE_UNDOCK_NAME_W,
1871 SE_SYNC_AGENT_NAME_W,
1872 SE_ENABLE_DELEGATION_NAME_W,
1873 SE_MANAGE_VOLUME_NAME_W,
1874 SE_IMPERSONATE_NAME_W,
1875 SE_CREATE_GLOBAL_NAME_W,
1878 /******************************************************************************
1879 * LookupPrivilegeValueW [ADVAPI32.@]
1881 * See LookupPrivilegeValueA.
1883 BOOL WINAPI
1884 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1886 UINT i;
1888 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1890 if (!ADVAPI_IsLocalComputer(lpSystemName))
1892 SetLastError(RPC_S_SERVER_UNAVAILABLE);
1893 return FALSE;
1895 if (!lpName)
1897 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1898 return FALSE;
1900 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1902 if( !WellKnownPrivNames[i] )
1903 continue;
1904 if( strcmpiW( WellKnownPrivNames[i], lpName) )
1905 continue;
1906 lpLuid->LowPart = i;
1907 lpLuid->HighPart = 0;
1908 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1909 lpLuid->HighPart, lpLuid->LowPart );
1910 return TRUE;
1912 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1913 return FALSE;
1916 /******************************************************************************
1917 * LookupPrivilegeValueA [ADVAPI32.@]
1919 * Retrieves LUID used on a system to represent the privilege name.
1921 * PARAMS
1922 * lpSystemName [I] Name of the system
1923 * lpName [I] Name of the privilege
1924 * lpLuid [O] Destination for the resulting LUID
1926 * RETURNS
1927 * Success: TRUE. lpLuid contains the requested LUID.
1928 * Failure: FALSE.
1930 BOOL WINAPI
1931 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1933 UNICODE_STRING lpSystemNameW;
1934 UNICODE_STRING lpNameW;
1935 BOOL ret;
1937 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1938 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1939 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1940 RtlFreeUnicodeString(&lpNameW);
1941 RtlFreeUnicodeString(&lpSystemNameW);
1942 return ret;
1945 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1946 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1948 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1949 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1951 return FALSE;
1954 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1955 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1957 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1958 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1960 return FALSE;
1963 /******************************************************************************
1964 * LookupPrivilegeNameA [ADVAPI32.@]
1966 * See LookupPrivilegeNameW.
1968 BOOL WINAPI
1969 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1970 LPDWORD cchName)
1972 UNICODE_STRING lpSystemNameW;
1973 BOOL ret;
1974 DWORD wLen = 0;
1976 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1978 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1979 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1980 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1982 LPWSTR lpNameW = heap_alloc(wLen * sizeof(WCHAR));
1984 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1985 &wLen);
1986 if (ret)
1988 /* Windows crashes if cchName is NULL, so will I */
1989 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1990 *cchName, NULL, NULL);
1992 if (len == 0)
1994 /* WideCharToMultiByte failed */
1995 ret = FALSE;
1997 else if (len > *cchName)
1999 *cchName = len;
2000 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2001 ret = FALSE;
2003 else
2005 /* WideCharToMultiByte succeeded, output length needs to be
2006 * length not including NULL terminator
2008 *cchName = len - 1;
2011 heap_free(lpNameW);
2013 RtlFreeUnicodeString(&lpSystemNameW);
2014 return ret;
2017 /******************************************************************************
2018 * LookupPrivilegeNameW [ADVAPI32.@]
2020 * Retrieves the privilege name referred to by the LUID lpLuid.
2022 * PARAMS
2023 * lpSystemName [I] Name of the system
2024 * lpLuid [I] Privilege value
2025 * lpName [O] Name of the privilege
2026 * cchName [I/O] Number of characters in lpName.
2028 * RETURNS
2029 * Success: TRUE. lpName contains the name of the privilege whose value is
2030 * *lpLuid.
2031 * Failure: FALSE.
2033 * REMARKS
2034 * Only well-known privilege names (those defined in winnt.h) can be retrieved
2035 * using this function.
2036 * If the length of lpName is too small, on return *cchName will contain the
2037 * number of WCHARs needed to contain the privilege, including the NULL
2038 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
2039 * On success, *cchName will contain the number of characters stored in
2040 * lpName, NOT including the NULL terminator.
2042 BOOL WINAPI
2043 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
2044 LPDWORD cchName)
2046 size_t privNameLen;
2048 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
2050 if (!ADVAPI_IsLocalComputer(lpSystemName))
2052 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2053 return FALSE;
2055 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
2056 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
2058 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
2059 return FALSE;
2061 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
2062 /* Windows crashes if cchName is NULL, so will I */
2063 if (*cchName <= privNameLen)
2065 *cchName = privNameLen + 1;
2066 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2067 return FALSE;
2069 else
2071 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
2072 *cchName = privNameLen;
2073 return TRUE;
2077 /******************************************************************************
2078 * GetFileSecurityA [ADVAPI32.@]
2080 * Obtains Specified information about the security of a file or directory.
2082 * PARAMS
2083 * lpFileName [I] Name of the file to get info for
2084 * RequestedInformation [I] SE_ flags from "winnt.h"
2085 * pSecurityDescriptor [O] Destination for security information
2086 * nLength [I] Length of pSecurityDescriptor
2087 * lpnLengthNeeded [O] Destination for length of returned security information
2089 * RETURNS
2090 * Success: TRUE. pSecurityDescriptor contains the requested information.
2091 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2093 * NOTES
2094 * The information returned is constrained by the callers access rights and
2095 * privileges.
2097 BOOL WINAPI
2098 GetFileSecurityA( LPCSTR lpFileName,
2099 SECURITY_INFORMATION RequestedInformation,
2100 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2101 DWORD nLength, LPDWORD lpnLengthNeeded )
2103 BOOL r;
2104 LPWSTR name;
2106 name = SERV_dup(lpFileName);
2107 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2108 nLength, lpnLengthNeeded );
2109 heap_free( name );
2111 return r;
2114 /******************************************************************************
2115 * GetFileSecurityW [ADVAPI32.@]
2117 * See GetFileSecurityA.
2119 BOOL WINAPI
2120 GetFileSecurityW( LPCWSTR lpFileName,
2121 SECURITY_INFORMATION RequestedInformation,
2122 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2123 DWORD nLength, LPDWORD lpnLengthNeeded )
2125 HANDLE hfile;
2126 NTSTATUS status;
2127 DWORD access = 0, err;
2129 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2130 RequestedInformation, pSecurityDescriptor,
2131 nLength, lpnLengthNeeded);
2133 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2134 DACL_SECURITY_INFORMATION))
2135 access |= READ_CONTROL;
2136 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2137 access |= ACCESS_SYSTEM_SECURITY;
2139 err = get_security_file( lpFileName, access, &hfile);
2140 if (err)
2142 SetLastError(err);
2143 return FALSE;
2146 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2147 nLength, lpnLengthNeeded );
2148 CloseHandle( hfile );
2149 return set_ntstatus( status );
2153 /******************************************************************************
2154 * LookupAccountSidA [ADVAPI32.@]
2156 BOOL WINAPI
2157 LookupAccountSidA(
2158 IN LPCSTR system,
2159 IN PSID sid,
2160 OUT LPSTR account,
2161 IN OUT LPDWORD accountSize,
2162 OUT LPSTR domain,
2163 IN OUT LPDWORD domainSize,
2164 OUT PSID_NAME_USE name_use )
2166 DWORD len;
2167 BOOL r;
2168 LPWSTR systemW;
2169 LPWSTR accountW = NULL;
2170 LPWSTR domainW = NULL;
2171 DWORD accountSizeW = *accountSize;
2172 DWORD domainSizeW = *domainSize;
2174 systemW = SERV_dup(system);
2175 if (account)
2176 accountW = heap_alloc( accountSizeW * sizeof(WCHAR) );
2177 if (domain)
2178 domainW = heap_alloc( domainSizeW * sizeof(WCHAR) );
2180 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2182 if (r) {
2183 if (accountW && *accountSize) {
2184 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2185 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2186 *accountSize = len;
2187 } else
2188 *accountSize = accountSizeW + 1;
2190 if (domainW && *domainSize) {
2191 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2192 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2193 *domainSize = len;
2194 } else
2195 *domainSize = domainSizeW + 1;
2197 else
2199 *accountSize = accountSizeW + 1;
2200 *domainSize = domainSizeW + 1;
2203 heap_free( systemW );
2204 heap_free( accountW );
2205 heap_free( domainW );
2207 return r;
2210 /******************************************************************************
2211 * LookupAccountSidW [ADVAPI32.@]
2213 * PARAMS
2214 * system []
2215 * sid []
2216 * account []
2217 * accountSize []
2218 * domain []
2219 * domainSize []
2220 * name_use []
2223 BOOL WINAPI
2224 LookupAccountSidW(
2225 IN LPCWSTR system,
2226 IN PSID sid,
2227 OUT LPWSTR account,
2228 IN OUT LPDWORD accountSize,
2229 OUT LPWSTR domain,
2230 IN OUT LPDWORD domainSize,
2231 OUT PSID_NAME_USE name_use )
2233 unsigned int i, j;
2234 const WCHAR * ac = NULL;
2235 const WCHAR * dm = NULL;
2236 SID_NAME_USE use = 0;
2237 LPWSTR computer_name = NULL;
2238 LPWSTR account_name = NULL;
2240 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2241 debugstr_w(system),debugstr_sid(sid),
2242 account,accountSize,accountSize?*accountSize:0,
2243 domain,domainSize,domainSize?*domainSize:0,
2244 name_use);
2246 if (!ADVAPI_IsLocalComputer(system)) {
2247 FIXME("Only local computer supported!\n");
2248 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2249 return FALSE;
2252 /* check the well known SIDs first */
2253 for (i = 0; i <= WinAccountProtectedUsersSid; i++) {
2254 if (IsWellKnownSid(sid, i)) {
2255 for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2256 if (ACCOUNT_SIDS[j].type == i) {
2257 ac = ACCOUNT_SIDS[j].account;
2258 dm = ACCOUNT_SIDS[j].domain;
2259 use = ACCOUNT_SIDS[j].name_use;
2262 break;
2266 if (dm == NULL) {
2267 MAX_SID local;
2269 /* check for the local computer next */
2270 if (ADVAPI_GetComputerSid(&local)) {
2271 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2272 BOOL result;
2274 computer_name = heap_alloc(size * sizeof(WCHAR));
2275 result = GetComputerNameW(computer_name, &size);
2277 if (result) {
2278 if (EqualSid(sid, &local)) {
2279 dm = computer_name;
2280 ac = Blank;
2281 use = 3;
2282 } else {
2283 local.SubAuthorityCount++;
2285 if (EqualPrefixSid(sid, &local)) {
2286 dm = computer_name;
2287 use = 1;
2288 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2289 case DOMAIN_USER_RID_ADMIN:
2290 ac = Administrator;
2291 break;
2292 case DOMAIN_USER_RID_GUEST:
2293 ac = Guest;
2294 break;
2295 case DOMAIN_GROUP_RID_ADMINS:
2296 ac = Domain_Admins;
2297 break;
2298 case DOMAIN_GROUP_RID_USERS:
2299 ac = Domain_Users;
2300 break;
2301 case DOMAIN_GROUP_RID_GUESTS:
2302 ac = Domain_Guests;
2303 break;
2304 case DOMAIN_GROUP_RID_COMPUTERS:
2305 ac = Domain_Computers;
2306 break;
2307 case DOMAIN_GROUP_RID_CONTROLLERS:
2308 ac = Domain_Controllers;
2309 break;
2310 case DOMAIN_GROUP_RID_CERT_ADMINS:
2311 ac = Cert_Publishers;
2312 break;
2313 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2314 ac = Schema_Admins;
2315 break;
2316 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2317 ac = Enterprise_Admins;
2318 break;
2319 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2320 ac = Group_Policy_Creator_Owners;
2321 break;
2322 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2323 ac = RAS_and_IAS_Servers;
2324 break;
2325 case 1000: /* first user account */
2326 size = UNLEN + 1;
2327 account_name = heap_alloc(size * sizeof(WCHAR));
2328 if (GetUserNameW(account_name, &size))
2329 ac = account_name;
2330 else
2331 dm = NULL;
2333 break;
2334 default:
2335 dm = NULL;
2336 break;
2344 if (dm) {
2345 DWORD ac_len = lstrlenW(ac);
2346 DWORD dm_len = lstrlenW(dm);
2347 BOOL status = TRUE;
2349 if (*accountSize > ac_len) {
2350 if (account)
2351 lstrcpyW(account, ac);
2353 if (*domainSize > dm_len) {
2354 if (domain)
2355 lstrcpyW(domain, dm);
2357 if ((*accountSize && *accountSize < ac_len) ||
2358 (!account && !*accountSize && ac_len) ||
2359 (*domainSize && *domainSize < dm_len) ||
2360 (!domain && !*domainSize && dm_len))
2362 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2363 status = FALSE;
2365 if (*domainSize)
2366 *domainSize = dm_len;
2367 else
2368 *domainSize = dm_len + 1;
2369 if (*accountSize)
2370 *accountSize = ac_len;
2371 else
2372 *accountSize = ac_len + 1;
2374 heap_free(account_name);
2375 heap_free(computer_name);
2376 if (status) *name_use = use;
2377 return status;
2380 heap_free(account_name);
2381 heap_free(computer_name);
2382 SetLastError(ERROR_NONE_MAPPED);
2383 return FALSE;
2386 /******************************************************************************
2387 * SetFileSecurityA [ADVAPI32.@]
2389 * See SetFileSecurityW.
2391 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2392 SECURITY_INFORMATION RequestedInformation,
2393 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2395 BOOL r;
2396 LPWSTR name;
2398 name = SERV_dup(lpFileName);
2399 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2400 heap_free( name );
2402 return r;
2405 /******************************************************************************
2406 * SetFileSecurityW [ADVAPI32.@]
2408 * Sets the security of a file or directory.
2410 * PARAMS
2411 * lpFileName []
2412 * RequestedInformation []
2413 * pSecurityDescriptor []
2415 * RETURNS
2416 * Success: TRUE.
2417 * Failure: FALSE.
2419 BOOL WINAPI
2420 SetFileSecurityW( LPCWSTR lpFileName,
2421 SECURITY_INFORMATION RequestedInformation,
2422 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2424 HANDLE file;
2425 DWORD access = 0, err;
2426 NTSTATUS status;
2428 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2429 pSecurityDescriptor );
2431 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2432 RequestedInformation & GROUP_SECURITY_INFORMATION)
2433 access |= WRITE_OWNER;
2434 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2435 access |= ACCESS_SYSTEM_SECURITY;
2436 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2437 access |= WRITE_DAC;
2439 err = get_security_file( lpFileName, access, &file);
2440 if (err)
2442 SetLastError(err);
2443 return FALSE;
2446 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2447 CloseHandle( file );
2448 return set_ntstatus( status );
2451 /******************************************************************************
2452 * QueryWindows31FilesMigration [ADVAPI32.@]
2454 * PARAMS
2455 * x1 []
2457 BOOL WINAPI
2458 QueryWindows31FilesMigration( DWORD x1 )
2460 FIXME("(%d):stub\n",x1);
2461 return TRUE;
2464 /******************************************************************************
2465 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2467 * PARAMS
2468 * x1 []
2469 * x2 []
2470 * x3 []
2471 * x4 []
2473 BOOL WINAPI
2474 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2475 DWORD x4 )
2477 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2478 return TRUE;
2481 /******************************************************************************
2482 * NotifyBootConfigStatus [ADVAPI32.@]
2484 * PARAMS
2485 * x1 []
2487 BOOL WINAPI
2488 NotifyBootConfigStatus( BOOL x1 )
2490 FIXME("(0x%08d):stub\n",x1);
2491 return TRUE;
2494 /******************************************************************************
2495 * RevertToSelf [ADVAPI32.@]
2497 * Ends the impersonation of a user.
2499 * PARAMS
2500 * void []
2502 * RETURNS
2503 * Success: TRUE.
2504 * Failure: FALSE.
2506 BOOL WINAPI
2507 RevertToSelf( void )
2509 HANDLE Token = NULL;
2510 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2511 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2514 /******************************************************************************
2515 * ImpersonateSelf [ADVAPI32.@]
2517 * Makes an impersonation token that represents the process user and assigns
2518 * to the current thread.
2520 * PARAMS
2521 * ImpersonationLevel [I] Level at which to impersonate.
2523 * RETURNS
2524 * Success: TRUE.
2525 * Failure: FALSE.
2527 BOOL WINAPI
2528 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2530 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2533 /******************************************************************************
2534 * ImpersonateLoggedOnUser [ADVAPI32.@]
2536 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2538 DWORD size;
2539 NTSTATUS Status;
2540 HANDLE ImpersonationToken;
2541 TOKEN_TYPE Type;
2542 static BOOL warn = TRUE;
2544 if (warn)
2546 FIXME( "(%p)\n", hToken );
2547 warn = FALSE;
2549 if (!GetTokenInformation( hToken, TokenType, &Type,
2550 sizeof(TOKEN_TYPE), &size ))
2551 return FALSE;
2553 if (Type == TokenPrimary)
2555 OBJECT_ATTRIBUTES ObjectAttributes;
2557 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2559 Status = NtDuplicateToken( hToken,
2560 TOKEN_IMPERSONATE | TOKEN_QUERY,
2561 &ObjectAttributes,
2562 SecurityImpersonation,
2563 TokenImpersonation,
2564 &ImpersonationToken );
2565 if (Status != STATUS_SUCCESS)
2567 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2568 SetLastError( RtlNtStatusToDosError( Status ) );
2569 return FALSE;
2572 else
2573 ImpersonationToken = hToken;
2575 Status = NtSetInformationThread( GetCurrentThread(),
2576 ThreadImpersonationToken,
2577 &ImpersonationToken,
2578 sizeof(ImpersonationToken) );
2580 if (Type == TokenPrimary)
2581 NtClose( ImpersonationToken );
2583 if (Status != STATUS_SUCCESS)
2585 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2586 SetLastError( RtlNtStatusToDosError( Status ) );
2587 return FALSE;
2590 return TRUE;
2593 /******************************************************************************
2594 * ImpersonateAnonymousToken [ADVAPI32.@]
2596 BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
2598 TRACE("(%p)\n", thread);
2599 return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
2602 /******************************************************************************
2603 * AccessCheck [ADVAPI32.@]
2605 BOOL WINAPI
2606 AccessCheck(
2607 PSECURITY_DESCRIPTOR SecurityDescriptor,
2608 HANDLE ClientToken,
2609 DWORD DesiredAccess,
2610 PGENERIC_MAPPING GenericMapping,
2611 PPRIVILEGE_SET PrivilegeSet,
2612 LPDWORD PrivilegeSetLength,
2613 LPDWORD GrantedAccess,
2614 LPBOOL AccessStatus)
2616 NTSTATUS access_status;
2617 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2618 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2619 GrantedAccess, &access_status) );
2620 if (ret) *AccessStatus = set_ntstatus( access_status );
2621 return ret;
2625 /******************************************************************************
2626 * AccessCheckByType [ADVAPI32.@]
2628 BOOL WINAPI AccessCheckByType(
2629 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2630 PSID PrincipalSelfSid,
2631 HANDLE ClientToken,
2632 DWORD DesiredAccess,
2633 POBJECT_TYPE_LIST ObjectTypeList,
2634 DWORD ObjectTypeListLength,
2635 PGENERIC_MAPPING GenericMapping,
2636 PPRIVILEGE_SET PrivilegeSet,
2637 LPDWORD PrivilegeSetLength,
2638 LPDWORD GrantedAccess,
2639 LPBOOL AccessStatus)
2641 FIXME("stub\n");
2643 *AccessStatus = TRUE;
2645 return !*AccessStatus;
2648 /******************************************************************************
2649 * MapGenericMask [ADVAPI32.@]
2651 * Maps generic access rights into specific access rights according to the
2652 * supplied mapping.
2654 * PARAMS
2655 * AccessMask [I/O] Access rights.
2656 * GenericMapping [I] The mapping between generic and specific rights.
2658 * RETURNS
2659 * Nothing.
2661 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2663 RtlMapGenericMask( AccessMask, GenericMapping );
2666 /*************************************************************************
2667 * SetKernelObjectSecurity [ADVAPI32.@]
2669 BOOL WINAPI SetKernelObjectSecurity (
2670 IN HANDLE Handle,
2671 IN SECURITY_INFORMATION SecurityInformation,
2672 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2674 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2678 /******************************************************************************
2679 * AddAuditAccessAce [ADVAPI32.@]
2681 BOOL WINAPI AddAuditAccessAce(
2682 IN OUT PACL pAcl,
2683 IN DWORD dwAceRevision,
2684 IN DWORD dwAccessMask,
2685 IN PSID pSid,
2686 IN BOOL bAuditSuccess,
2687 IN BOOL bAuditFailure)
2689 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2690 bAuditSuccess, bAuditFailure) );
2693 /******************************************************************************
2694 * AddAuditAccessAceEx [ADVAPI32.@]
2696 BOOL WINAPI AddAuditAccessAceEx(
2697 IN OUT PACL pAcl,
2698 IN DWORD dwAceRevision,
2699 IN DWORD dwAceFlags,
2700 IN DWORD dwAccessMask,
2701 IN PSID pSid,
2702 IN BOOL bAuditSuccess,
2703 IN BOOL bAuditFailure)
2705 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2706 bAuditSuccess, bAuditFailure) );
2709 /******************************************************************************
2710 * AddAuditAccessObjectAce [ADVAPI32.@]
2712 BOOL WINAPI AddAuditAccessObjectAce(
2713 IN OUT PACL pAcl,
2714 IN DWORD dwAceRevision,
2715 IN DWORD dwAceFlags,
2716 IN DWORD dwAccessMask,
2717 IN GUID* pObjectTypeGuid,
2718 IN GUID* pInheritedObjectTypeGuid,
2719 IN PSID pSid,
2720 IN BOOL bAuditSuccess,
2721 IN BOOL bAuditFailure)
2723 return set_ntstatus( RtlAddAuditAccessObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
2724 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid, bAuditSuccess, bAuditFailure) );
2727 /******************************************************************************
2728 * LookupAccountNameA [ADVAPI32.@]
2730 BOOL WINAPI
2731 LookupAccountNameA(
2732 IN LPCSTR system,
2733 IN LPCSTR account,
2734 OUT PSID sid,
2735 OUT LPDWORD cbSid,
2736 LPSTR ReferencedDomainName,
2737 IN OUT LPDWORD cbReferencedDomainName,
2738 OUT PSID_NAME_USE name_use )
2740 BOOL ret;
2741 UNICODE_STRING lpSystemW;
2742 UNICODE_STRING lpAccountW;
2743 LPWSTR lpReferencedDomainNameW = NULL;
2745 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2746 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2748 if (ReferencedDomainName)
2749 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2751 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2752 cbReferencedDomainName, name_use);
2754 if (ret && lpReferencedDomainNameW)
2756 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2757 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2760 RtlFreeUnicodeString(&lpSystemW);
2761 RtlFreeUnicodeString(&lpAccountW);
2762 heap_free(lpReferencedDomainNameW);
2764 return ret;
2767 /******************************************************************************
2768 * lookup_user_account_name
2770 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2771 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2773 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2774 DWORD len = sizeof(buffer);
2775 HANDLE token;
2776 BOOL ret;
2777 PSID pSid;
2778 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2779 DWORD nameLen;
2781 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2783 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2784 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2787 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2788 CloseHandle( token );
2790 if (!ret) return FALSE;
2792 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2794 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2795 CopySid(*cbSid, Sid, pSid);
2796 if (*cbSid < GetLengthSid(pSid))
2798 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2799 ret = FALSE;
2801 *cbSid = GetLengthSid(pSid);
2803 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2804 if (!GetComputerNameW(domainName, &nameLen))
2806 domainName[0] = 0;
2807 nameLen = 0;
2809 if (*cchReferencedDomainName <= nameLen || !ret)
2811 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2812 nameLen += 1;
2813 ret = FALSE;
2815 else if (ReferencedDomainName)
2816 strcpyW(ReferencedDomainName, domainName);
2818 *cchReferencedDomainName = nameLen;
2820 if (ret)
2821 *peUse = SidTypeUser;
2823 return ret;
2826 /******************************************************************************
2827 * lookup_computer_account_name
2829 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2830 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2832 MAX_SID local;
2833 BOOL ret;
2834 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2835 DWORD nameLen;
2837 if ((ret = ADVAPI_GetComputerSid(&local)))
2839 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2840 CopySid(*cbSid, Sid, &local);
2841 if (*cbSid < GetLengthSid(&local))
2843 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2844 ret = FALSE;
2846 *cbSid = GetLengthSid(&local);
2849 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2850 if (!GetComputerNameW(domainName, &nameLen))
2852 domainName[0] = 0;
2853 nameLen = 0;
2855 if (*cchReferencedDomainName <= nameLen || !ret)
2857 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2858 nameLen += 1;
2859 ret = FALSE;
2861 else if (ReferencedDomainName)
2862 strcpyW(ReferencedDomainName, domainName);
2864 *cchReferencedDomainName = nameLen;
2866 if (ret)
2867 *peUse = SidTypeDomain;
2869 return ret;
2872 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2873 LSA_UNICODE_STRING *domain )
2875 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2877 while (p > str->Buffer && *p != '\\') p--;
2879 if (*p == '\\')
2881 domain->Buffer = str->Buffer;
2882 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2884 account->Buffer = p + 1;
2885 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2887 else
2889 domain->Buffer = NULL;
2890 domain->Length = 0;
2892 account->Buffer = str->Buffer;
2893 account->Length = str->Length;
2897 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2899 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2901 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2902 return TRUE;
2904 return FALSE;
2907 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2909 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2911 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2912 return TRUE;
2914 if (ACCOUNT_SIDS[idx].alias)
2916 len = strlenW( ACCOUNT_SIDS[idx].alias );
2917 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2918 return TRUE;
2920 return FALSE;
2924 * Helper function for LookupAccountNameW
2926 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2927 PSID Sid, LPDWORD cbSid,
2928 LPWSTR ReferencedDomainName,
2929 LPDWORD cchReferencedDomainName,
2930 PSID_NAME_USE peUse, BOOL *handled )
2932 PSID pSid;
2933 LSA_UNICODE_STRING account, domain;
2934 BOOL ret = TRUE;
2935 ULONG i;
2937 *handled = FALSE;
2938 split_domain_account( account_and_domain, &account, &domain );
2940 for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2942 /* check domain first */
2943 if (domain.Buffer && !match_domain( i, &domain )) continue;
2945 if (match_account( i, &account ))
2947 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2949 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
2951 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2953 if (*cbSid < sidLen)
2955 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2956 ret = FALSE;
2958 else if (Sid)
2960 CopySid(*cbSid, Sid, pSid);
2962 *cbSid = sidLen;
2965 len = strlenW( ACCOUNT_SIDS[i].domain );
2966 if (*cchReferencedDomainName <= len || !ret)
2968 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2969 len++;
2970 ret = FALSE;
2972 else if (ReferencedDomainName)
2974 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2977 *cchReferencedDomainName = len;
2978 if (ret)
2979 *peUse = ACCOUNT_SIDS[i].name_use;
2981 heap_free(pSid);
2982 *handled = TRUE;
2983 return ret;
2986 return ret;
2989 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2990 PSID Sid, LPDWORD cbSid,
2991 LPWSTR ReferencedDomainName,
2992 LPDWORD cchReferencedDomainName,
2993 PSID_NAME_USE peUse, BOOL *handled )
2995 DWORD nameLen;
2996 LPWSTR userName = NULL;
2997 LSA_UNICODE_STRING account, domain;
2998 BOOL ret = TRUE;
3000 *handled = FALSE;
3001 split_domain_account( account_and_domain, &account, &domain );
3003 /* Let the current Unix user id masquerade as first Windows user account */
3005 nameLen = UNLEN + 1;
3006 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
3008 if (domain.Buffer)
3010 /* check to make sure this account is on this computer */
3011 if (GetComputerNameW( userName, &nameLen ) &&
3012 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
3014 SetLastError(ERROR_NONE_MAPPED);
3015 ret = FALSE;
3017 nameLen = UNLEN + 1;
3020 if (GetUserNameW( userName, &nameLen ) &&
3021 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
3023 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3024 *handled = TRUE;
3026 else
3028 nameLen = UNLEN + 1;
3029 if (GetComputerNameW( userName, &nameLen ) &&
3030 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
3032 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3033 *handled = TRUE;
3037 heap_free(userName);
3038 return ret;
3041 /******************************************************************************
3042 * LookupAccountNameW [ADVAPI32.@]
3044 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
3045 LPDWORD cbSid, LPWSTR ReferencedDomainName,
3046 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
3048 BOOL ret, handled;
3049 LSA_UNICODE_STRING account;
3051 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
3052 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
3054 if (!ADVAPI_IsLocalComputer( lpSystemName ))
3056 FIXME("remote computer not supported\n");
3057 SetLastError( RPC_S_SERVER_UNAVAILABLE );
3058 return FALSE;
3061 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
3063 lpAccountName = BUILTIN;
3066 RtlInitUnicodeString( &account, lpAccountName );
3068 /* Check well known SIDs first */
3069 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
3070 cchReferencedDomainName, peUse, &handled );
3071 if (handled)
3072 return ret;
3074 /* Check user names */
3075 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
3076 cchReferencedDomainName, peUse, &handled);
3077 if (handled)
3078 return ret;
3080 SetLastError( ERROR_NONE_MAPPED );
3081 return FALSE;
3084 /******************************************************************************
3085 * PrivilegeCheck [ADVAPI32.@]
3087 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
3089 BOOL ret;
3090 BOOLEAN Result;
3092 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
3094 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
3095 if (ret)
3096 *pfResult = Result;
3097 return ret;
3100 /******************************************************************************
3101 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
3103 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
3104 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3105 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3106 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3108 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
3109 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
3110 SecurityDescriptor, DesiredAccess, GenericMapping,
3111 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3112 return TRUE;
3115 /******************************************************************************
3116 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3118 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3119 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3120 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3121 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3123 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3124 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3125 SecurityDescriptor, DesiredAccess, GenericMapping,
3126 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3127 return TRUE;
3130 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3132 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3134 return TRUE;
3137 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3139 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3141 return TRUE;
3144 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3146 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3148 return TRUE;
3151 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3152 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3153 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3154 LPBOOL GenerateOnClose)
3156 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3157 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3158 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3159 GenerateOnClose);
3161 return TRUE;
3164 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3165 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3166 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3167 LPBOOL GenerateOnClose)
3169 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3170 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3171 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3172 GenerateOnClose);
3174 return TRUE;
3177 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3178 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3180 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3181 DesiredAccess, Privileges, AccessGranted);
3183 return TRUE;
3186 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3187 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3189 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3190 DesiredAccess, Privileges, AccessGranted);
3192 return TRUE;
3195 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3196 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3198 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3199 ClientToken, Privileges, AccessGranted);
3201 return TRUE;
3204 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3205 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3207 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3208 ClientToken, Privileges, AccessGranted);
3210 return TRUE;
3213 /******************************************************************************
3214 * GetSecurityInfo [ADVAPI32.@]
3216 * Retrieves a copy of the security descriptor associated with an object.
3218 * PARAMS
3219 * hObject [I] A handle for the object.
3220 * ObjectType [I] The type of object.
3221 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3222 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3223 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3224 * ppDacl [O] If non-null, receives a pointer to the DACL.
3225 * ppSacl [O] If non-null, receives a pointer to the SACL.
3226 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3227 * which must be freed with LocalFree.
3229 * RETURNS
3230 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3232 DWORD WINAPI GetSecurityInfo(
3233 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3234 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3235 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3236 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3239 PSECURITY_DESCRIPTOR sd;
3240 NTSTATUS status;
3241 ULONG n1, n2;
3242 BOOL present, defaulted;
3244 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3245 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3247 /* If no descriptor, we have to check that there's a pointer for the requested information */
3248 if( !ppSecurityDescriptor && (
3249 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3250 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3251 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3252 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3253 return ERROR_INVALID_PARAMETER;
3255 switch (ObjectType)
3257 case SE_SERVICE:
3258 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3259 break;
3260 default:
3261 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3262 break;
3264 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3265 return RtlNtStatusToDosError(status);
3267 sd = LocalAlloc(0, n1);
3268 if (!sd)
3269 return ERROR_NOT_ENOUGH_MEMORY;
3271 switch (ObjectType)
3273 case SE_SERVICE:
3274 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3275 break;
3276 default:
3277 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3278 break;
3280 if (status != STATUS_SUCCESS)
3282 LocalFree(sd);
3283 return RtlNtStatusToDosError(status);
3286 if (ppsidOwner)
3288 *ppsidOwner = NULL;
3289 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3291 if (ppsidGroup)
3293 *ppsidGroup = NULL;
3294 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3296 if (ppDacl)
3298 *ppDacl = NULL;
3299 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3301 if (ppSacl)
3303 *ppSacl = NULL;
3304 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3306 if (ppSecurityDescriptor)
3307 *ppSecurityDescriptor = sd;
3309 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3310 * NULL, because native happily returns the SIDs and ACLs that are requested
3311 * in this case.
3314 return ERROR_SUCCESS;
3317 /******************************************************************************
3318 * GetSecurityInfoExA [ADVAPI32.@]
3320 DWORD WINAPI GetSecurityInfoExA(
3321 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3322 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3323 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3324 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3327 FIXME("stub!\n");
3328 return ERROR_BAD_PROVIDER;
3331 /******************************************************************************
3332 * GetSecurityInfoExW [ADVAPI32.@]
3334 DWORD WINAPI GetSecurityInfoExW(
3335 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3336 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3337 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3338 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3341 FIXME("stub!\n");
3342 return ERROR_BAD_PROVIDER;
3345 /******************************************************************************
3346 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3348 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3349 LPSTR pTrusteeName, DWORD AccessPermissions,
3350 ACCESS_MODE AccessMode, DWORD Inheritance )
3352 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3353 AccessPermissions, AccessMode, Inheritance);
3355 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3356 pExplicitAccess->grfAccessMode = AccessMode;
3357 pExplicitAccess->grfInheritance = Inheritance;
3359 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3360 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3361 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3362 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3363 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3366 /******************************************************************************
3367 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3369 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3370 LPWSTR pTrusteeName, DWORD AccessPermissions,
3371 ACCESS_MODE AccessMode, DWORD Inheritance )
3373 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3374 AccessPermissions, AccessMode, Inheritance);
3376 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3377 pExplicitAccess->grfAccessMode = AccessMode;
3378 pExplicitAccess->grfInheritance = Inheritance;
3380 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3381 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3382 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3383 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3384 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3387 /******************************************************************************
3388 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3390 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3391 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3392 LPSTR InheritedObjectTypeName, LPSTR Name )
3394 DWORD ObjectsPresent = 0;
3396 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3397 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3399 /* Fill the OBJECTS_AND_NAME structure */
3400 pObjName->ObjectType = ObjectType;
3401 if (ObjectTypeName != NULL)
3403 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3406 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3407 if (InheritedObjectTypeName != NULL)
3409 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3412 pObjName->ObjectsPresent = ObjectsPresent;
3413 pObjName->ptstrName = Name;
3415 /* Fill the TRUSTEE structure */
3416 pTrustee->pMultipleTrustee = NULL;
3417 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3418 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3419 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3420 pTrustee->ptstrName = (LPSTR)pObjName;
3423 /******************************************************************************
3424 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3426 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3427 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3428 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3430 DWORD ObjectsPresent = 0;
3432 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3433 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3435 /* Fill the OBJECTS_AND_NAME structure */
3436 pObjName->ObjectType = ObjectType;
3437 if (ObjectTypeName != NULL)
3439 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3442 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3443 if (InheritedObjectTypeName != NULL)
3445 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3448 pObjName->ObjectsPresent = ObjectsPresent;
3449 pObjName->ptstrName = Name;
3451 /* Fill the TRUSTEE structure */
3452 pTrustee->pMultipleTrustee = NULL;
3453 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3454 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3455 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3456 pTrustee->ptstrName = (LPWSTR)pObjName;
3459 /******************************************************************************
3460 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3462 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3463 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3465 DWORD ObjectsPresent = 0;
3467 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3469 /* Fill the OBJECTS_AND_SID structure */
3470 if (pObjectGuid != NULL)
3472 pObjSid->ObjectTypeGuid = *pObjectGuid;
3473 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3475 else
3477 ZeroMemory(&pObjSid->ObjectTypeGuid,
3478 sizeof(GUID));
3481 if (pInheritedObjectGuid != NULL)
3483 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3484 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3486 else
3488 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3489 sizeof(GUID));
3492 pObjSid->ObjectsPresent = ObjectsPresent;
3493 pObjSid->pSid = pSid;
3495 /* Fill the TRUSTEE structure */
3496 pTrustee->pMultipleTrustee = NULL;
3497 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3498 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3499 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3500 pTrustee->ptstrName = (LPSTR) pObjSid;
3503 /******************************************************************************
3504 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3506 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3507 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3509 DWORD ObjectsPresent = 0;
3511 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3513 /* Fill the OBJECTS_AND_SID structure */
3514 if (pObjectGuid != NULL)
3516 pObjSid->ObjectTypeGuid = *pObjectGuid;
3517 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3519 else
3521 ZeroMemory(&pObjSid->ObjectTypeGuid,
3522 sizeof(GUID));
3525 if (pInheritedObjectGuid != NULL)
3527 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3528 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3530 else
3532 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3533 sizeof(GUID));
3536 pObjSid->ObjectsPresent = ObjectsPresent;
3537 pObjSid->pSid = pSid;
3539 /* Fill the TRUSTEE structure */
3540 pTrustee->pMultipleTrustee = NULL;
3541 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3542 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3543 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3544 pTrustee->ptstrName = (LPWSTR) pObjSid;
3547 /******************************************************************************
3548 * BuildTrusteeWithSidA [ADVAPI32.@]
3550 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3552 TRACE("%p %p\n", pTrustee, pSid);
3554 pTrustee->pMultipleTrustee = NULL;
3555 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3556 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3557 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3558 pTrustee->ptstrName = pSid;
3561 /******************************************************************************
3562 * BuildTrusteeWithSidW [ADVAPI32.@]
3564 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3566 TRACE("%p %p\n", pTrustee, pSid);
3568 pTrustee->pMultipleTrustee = NULL;
3569 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3570 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3571 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3572 pTrustee->ptstrName = pSid;
3575 /******************************************************************************
3576 * BuildTrusteeWithNameA [ADVAPI32.@]
3578 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3580 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3582 pTrustee->pMultipleTrustee = NULL;
3583 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3584 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3585 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3586 pTrustee->ptstrName = name;
3589 /******************************************************************************
3590 * BuildTrusteeWithNameW [ADVAPI32.@]
3592 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3594 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3596 pTrustee->pMultipleTrustee = NULL;
3597 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3598 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3599 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3600 pTrustee->ptstrName = name;
3603 /******************************************************************************
3604 * GetTrusteeFormA [ADVAPI32.@]
3606 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3608 TRACE("(%p)\n", pTrustee);
3610 if (!pTrustee)
3611 return TRUSTEE_BAD_FORM;
3613 return pTrustee->TrusteeForm;
3616 /******************************************************************************
3617 * GetTrusteeFormW [ADVAPI32.@]
3619 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3621 TRACE("(%p)\n", pTrustee);
3623 if (!pTrustee)
3624 return TRUSTEE_BAD_FORM;
3626 return pTrustee->TrusteeForm;
3629 /******************************************************************************
3630 * GetTrusteeNameA [ADVAPI32.@]
3632 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3634 TRACE("(%p)\n", pTrustee);
3636 if (!pTrustee)
3637 return NULL;
3639 return pTrustee->ptstrName;
3642 /******************************************************************************
3643 * GetTrusteeNameW [ADVAPI32.@]
3645 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3647 TRACE("(%p)\n", pTrustee);
3649 if (!pTrustee)
3650 return NULL;
3652 return pTrustee->ptstrName;
3655 /******************************************************************************
3656 * GetTrusteeTypeA [ADVAPI32.@]
3658 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3660 TRACE("(%p)\n", pTrustee);
3662 if (!pTrustee)
3663 return TRUSTEE_IS_UNKNOWN;
3665 return pTrustee->TrusteeType;
3668 /******************************************************************************
3669 * GetTrusteeTypeW [ADVAPI32.@]
3671 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3673 TRACE("(%p)\n", pTrustee);
3675 if (!pTrustee)
3676 return TRUSTEE_IS_UNKNOWN;
3678 return pTrustee->TrusteeType;
3681 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3682 DWORD nAclInformationLength,
3683 ACL_INFORMATION_CLASS dwAclInformationClass )
3685 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3686 nAclInformationLength, dwAclInformationClass);
3688 return TRUE;
3691 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3693 switch (form)
3695 case TRUSTEE_IS_NAME:
3697 *ptrustee_nameW = SERV_dup(trustee_nameA);
3698 return ERROR_SUCCESS;
3700 case TRUSTEE_IS_OBJECTS_AND_NAME:
3702 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3703 OBJECTS_AND_NAME_W *objW = NULL;
3705 if (objA)
3707 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3708 return ERROR_NOT_ENOUGH_MEMORY;
3710 objW->ObjectsPresent = objA->ObjectsPresent;
3711 objW->ObjectType = objA->ObjectType;
3712 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3713 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3714 objW->ptstrName = SERV_dup(objA->ptstrName);
3717 *ptrustee_nameW = (WCHAR *)objW;
3718 return ERROR_SUCCESS;
3720 /* These forms do not require conversion. */
3721 case TRUSTEE_IS_SID:
3722 case TRUSTEE_IS_OBJECTS_AND_SID:
3723 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3724 return ERROR_SUCCESS;
3725 default:
3726 return ERROR_INVALID_PARAMETER;
3730 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3732 switch (form)
3734 case TRUSTEE_IS_NAME:
3735 heap_free( trustee_nameW );
3736 break;
3737 case TRUSTEE_IS_OBJECTS_AND_NAME:
3739 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3741 if (objW)
3743 heap_free( objW->ptstrName );
3744 heap_free( objW->InheritedObjectTypeName );
3745 heap_free( objW->ObjectTypeName );
3746 heap_free( objW );
3749 break;
3751 /* Other forms did not require allocation, so no freeing is necessary. */
3752 default:
3753 break;
3757 /******************************************************************************
3758 * SetEntriesInAclA [ADVAPI32.@]
3760 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3761 PACL OldAcl, PACL* NewAcl )
3763 DWORD err = ERROR_SUCCESS;
3764 EXPLICIT_ACCESSW *pEntriesW;
3765 UINT alloc_index, free_index;
3767 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3769 if (NewAcl)
3770 *NewAcl = NULL;
3772 if (!count && !OldAcl)
3773 return ERROR_SUCCESS;
3775 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3776 if (!pEntriesW)
3777 return ERROR_NOT_ENOUGH_MEMORY;
3779 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3781 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3782 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3783 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3784 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3785 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3786 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3787 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3789 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3790 pEntries[alloc_index].Trustee.ptstrName,
3791 &pEntriesW[alloc_index].Trustee.ptstrName );
3792 if (err != ERROR_SUCCESS)
3794 if (err == ERROR_INVALID_PARAMETER)
3795 WARN("bad trustee form %d for trustee %d\n",
3796 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3798 goto cleanup;
3802 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3804 cleanup:
3805 /* Free any previously allocated trustee name buffers, taking into account
3806 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3807 * list. */
3808 for (free_index = 0; free_index < alloc_index; ++free_index)
3809 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3811 heap_free( pEntriesW );
3812 return err;
3815 /******************************************************************************
3816 * SetEntriesInAclW [ADVAPI32.@]
3818 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3819 PACL OldAcl, PACL* NewAcl )
3821 ULONG i;
3822 PSID *ppsid;
3823 DWORD ret = ERROR_SUCCESS;
3824 DWORD acl_size = sizeof(ACL);
3825 NTSTATUS status;
3827 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3829 if (NewAcl)
3830 *NewAcl = NULL;
3832 if (!count && !OldAcl)
3833 return ERROR_SUCCESS;
3835 /* allocate array of maximum sized sids allowed */
3836 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3837 if (!ppsid)
3838 return ERROR_OUTOFMEMORY;
3840 for (i = 0; i < count; i++)
3842 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3844 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3845 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3846 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3847 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3848 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3849 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3850 pEntries[i].Trustee.ptstrName);
3852 if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3854 WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3855 ret = ERROR_INVALID_PARAMETER;
3856 goto exit;
3859 switch (pEntries[i].Trustee.TrusteeForm)
3861 case TRUSTEE_IS_SID:
3862 if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3863 ppsid[i], pEntries[i].Trustee.ptstrName))
3865 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3866 ret = ERROR_INVALID_PARAMETER;
3867 goto exit;
3869 break;
3870 case TRUSTEE_IS_NAME:
3872 DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3873 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3874 SID_NAME_USE use;
3875 if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3877 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3879 ret = GetLastError();
3880 goto exit;
3883 else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3885 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3886 ret = ERROR_INVALID_PARAMETER;
3887 goto exit;
3889 break;
3891 case TRUSTEE_IS_OBJECTS_AND_SID:
3892 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3893 break;
3894 case TRUSTEE_IS_OBJECTS_AND_NAME:
3895 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3896 break;
3897 default:
3898 WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3899 ret = ERROR_INVALID_PARAMETER;
3900 goto exit;
3903 /* Note: we overestimate the ACL size here as a tradeoff between
3904 * instructions (simplicity) and memory */
3905 switch (pEntries[i].grfAccessMode)
3907 case GRANT_ACCESS:
3908 case SET_ACCESS:
3909 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3910 break;
3911 case DENY_ACCESS:
3912 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3913 break;
3914 case SET_AUDIT_SUCCESS:
3915 case SET_AUDIT_FAILURE:
3916 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3917 break;
3918 case REVOKE_ACCESS:
3919 break;
3920 default:
3921 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3922 ret = ERROR_INVALID_PARAMETER;
3923 goto exit;
3927 if (OldAcl)
3929 ACL_SIZE_INFORMATION size_info;
3931 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3932 if (status != STATUS_SUCCESS)
3934 ret = RtlNtStatusToDosError(status);
3935 goto exit;
3937 acl_size += size_info.AclBytesInUse - sizeof(ACL);
3940 *NewAcl = LocalAlloc(0, acl_size);
3941 if (!*NewAcl)
3943 ret = ERROR_OUTOFMEMORY;
3944 goto exit;
3947 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3948 if (status != STATUS_SUCCESS)
3950 ret = RtlNtStatusToDosError(status);
3951 goto exit;
3954 for (i = 0; i < count; i++)
3956 switch (pEntries[i].grfAccessMode)
3958 case GRANT_ACCESS:
3959 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3960 pEntries[i].grfInheritance,
3961 pEntries[i].grfAccessPermissions,
3962 ppsid[i]);
3963 break;
3964 case SET_ACCESS:
3966 ULONG j;
3967 BOOL add = TRUE;
3968 if (OldAcl)
3970 for (j = 0; ; j++)
3972 const ACE_HEADER *existing_ace_header;
3973 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3974 if (status != STATUS_SUCCESS)
3975 break;
3976 if (pEntries[i].grfAccessMode == SET_ACCESS &&
3977 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3978 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3980 add = FALSE;
3981 break;
3985 if (add)
3986 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3987 pEntries[i].grfInheritance,
3988 pEntries[i].grfAccessPermissions,
3989 ppsid[i]);
3990 break;
3992 case DENY_ACCESS:
3993 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3994 pEntries[i].grfInheritance,
3995 pEntries[i].grfAccessPermissions,
3996 ppsid[i]);
3997 break;
3998 case SET_AUDIT_SUCCESS:
3999 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4000 pEntries[i].grfInheritance,
4001 pEntries[i].grfAccessPermissions,
4002 ppsid[i], TRUE, FALSE);
4003 break;
4004 case SET_AUDIT_FAILURE:
4005 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4006 pEntries[i].grfInheritance,
4007 pEntries[i].grfAccessPermissions,
4008 ppsid[i], FALSE, TRUE);
4009 break;
4010 default:
4011 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
4015 if (OldAcl)
4017 for (i = 0; ; i++)
4019 BOOL add = TRUE;
4020 ULONG j;
4021 const ACE_HEADER *old_ace_header;
4022 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
4023 if (status != STATUS_SUCCESS) break;
4024 for (j = 0; j < count; j++)
4026 if (pEntries[j].grfAccessMode == SET_ACCESS &&
4027 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4028 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4030 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
4031 add = FALSE;
4032 break;
4034 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
4036 switch (old_ace_header->AceType)
4038 case ACCESS_ALLOWED_ACE_TYPE:
4039 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4040 add = FALSE;
4041 break;
4042 case ACCESS_DENIED_ACE_TYPE:
4043 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
4044 add = FALSE;
4045 break;
4046 case SYSTEM_AUDIT_ACE_TYPE:
4047 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
4048 add = FALSE;
4049 break;
4050 case SYSTEM_ALARM_ACE_TYPE:
4051 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
4052 add = FALSE;
4053 break;
4054 default:
4055 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
4058 if (!add)
4059 break;
4062 if (add)
4063 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
4064 if (status != STATUS_SUCCESS)
4066 WARN("RtlAddAce failed with error 0x%08x\n", status);
4067 ret = RtlNtStatusToDosError(status);
4068 break;
4073 exit:
4074 heap_free(ppsid);
4075 return ret;
4078 /******************************************************************************
4079 * SetNamedSecurityInfoA [ADVAPI32.@]
4081 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
4082 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4083 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4085 LPWSTR wstr;
4086 DWORD r;
4088 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
4089 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4091 wstr = SERV_dup(pObjectName);
4092 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
4093 psidGroup, pDacl, pSacl );
4095 heap_free( wstr );
4097 return r;
4100 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
4101 PSECURITY_DESCRIPTOR ModificationDescriptor,
4102 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
4103 PGENERIC_MAPPING GenericMapping,
4104 HANDLE Token )
4106 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
4107 ObjectsSecurityDescriptor, GenericMapping, Token);
4109 return TRUE;
4112 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4114 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4117 /******************************************************************************
4118 * AreAnyAccessesGranted [ADVAPI32.@]
4120 * Determines whether or not any of a set of specified access permissions have
4121 * been granted or not.
4123 * PARAMS
4124 * GrantedAccess [I] The permissions that have been granted.
4125 * DesiredAccess [I] The permissions that you want to have.
4127 * RETURNS
4128 * Nonzero if any of the permissions have been granted, zero if none of the
4129 * permissions have been granted.
4132 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4134 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4137 /******************************************************************************
4138 * SetNamedSecurityInfoW [ADVAPI32.@]
4140 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4141 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4142 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4144 DWORD access = 0;
4145 HANDLE handle;
4146 DWORD err;
4148 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4149 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4151 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4153 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4154 access |= WRITE_OWNER;
4155 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4156 access |= WRITE_DAC;
4157 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4158 access |= ACCESS_SYSTEM_SECURITY;
4160 switch (ObjectType)
4162 case SE_SERVICE:
4163 if (!(err = get_security_service( pObjectName, access, &handle )))
4165 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4166 CloseServiceHandle( handle );
4168 break;
4169 case SE_REGISTRY_KEY:
4170 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4172 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4173 RegCloseKey( handle );
4175 break;
4176 case SE_FILE_OBJECT:
4177 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4178 access |= READ_CONTROL;
4179 if (!(err = get_security_file( pObjectName, access, &handle )))
4181 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4182 CloseHandle( handle );
4184 break;
4185 default:
4186 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4187 return ERROR_SUCCESS;
4189 return err;
4192 /******************************************************************************
4193 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4195 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4196 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4198 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4199 return ERROR_CALL_NOT_IMPLEMENTED;
4202 /******************************************************************************
4203 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4205 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4206 PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4208 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4209 return ERROR_CALL_NOT_IMPLEMENTED;
4212 /******************************************************************************
4213 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4215 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4216 PACCESS_MASK pFailedAuditRights)
4218 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4219 return ERROR_CALL_NOT_IMPLEMENTED;
4223 /******************************************************************************
4224 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4226 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4227 PACCESS_MASK pFailedAuditRights)
4229 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4230 return ERROR_CALL_NOT_IMPLEMENTED;
4234 /******************************************************************************
4235 * ParseAclStringFlags
4237 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4239 DWORD flags = 0;
4240 LPCWSTR szAcl = *StringAcl;
4242 while (*szAcl != '(')
4244 if (*szAcl == 'P')
4246 flags |= SE_DACL_PROTECTED;
4248 else if (*szAcl == 'A')
4250 szAcl++;
4251 if (*szAcl == 'R')
4252 flags |= SE_DACL_AUTO_INHERIT_REQ;
4253 else if (*szAcl == 'I')
4254 flags |= SE_DACL_AUTO_INHERITED;
4256 szAcl++;
4259 *StringAcl = szAcl;
4260 return flags;
4263 /******************************************************************************
4264 * ParseAceStringType
4266 static const ACEFLAG AceType[] =
4268 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4269 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4270 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4271 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4272 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
4274 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4275 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4276 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4277 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4279 { NULL, 0 },
4282 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4284 UINT len = 0;
4285 LPCWSTR szAcl = *StringAcl;
4286 const ACEFLAG *lpaf = AceType;
4288 while (*szAcl == ' ')
4289 szAcl++;
4291 while (lpaf->wstr &&
4292 (len = strlenW(lpaf->wstr)) &&
4293 strncmpW(lpaf->wstr, szAcl, len))
4294 lpaf++;
4296 if (!lpaf->wstr)
4297 return 0;
4299 *StringAcl = szAcl + len;
4300 return lpaf->value;
4304 /******************************************************************************
4305 * ParseAceStringFlags
4307 static const ACEFLAG AceFlags[] =
4309 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4310 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4311 { SDDL_INHERITED, INHERITED_ACE },
4312 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4313 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4314 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4315 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4316 { NULL, 0 },
4319 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4321 UINT len = 0;
4322 BYTE flags = 0;
4323 LPCWSTR szAcl = *StringAcl;
4325 while (*szAcl == ' ')
4326 szAcl++;
4328 while (*szAcl != ';')
4330 const ACEFLAG *lpaf = AceFlags;
4332 while (lpaf->wstr &&
4333 (len = strlenW(lpaf->wstr)) &&
4334 strncmpW(lpaf->wstr, szAcl, len))
4335 lpaf++;
4337 if (!lpaf->wstr)
4338 return 0;
4340 flags |= lpaf->value;
4341 szAcl += len;
4344 *StringAcl = szAcl;
4345 return flags;
4349 /******************************************************************************
4350 * ParseAceStringRights
4352 static const ACEFLAG AceRights[] =
4354 { SDDL_GENERIC_ALL, GENERIC_ALL },
4355 { SDDL_GENERIC_READ, GENERIC_READ },
4356 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4357 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4359 { SDDL_READ_CONTROL, READ_CONTROL },
4360 { SDDL_STANDARD_DELETE, DELETE },
4361 { SDDL_WRITE_DAC, WRITE_DAC },
4362 { SDDL_WRITE_OWNER, WRITE_OWNER },
4364 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4365 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4366 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4367 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4368 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4369 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4370 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4371 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4372 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4374 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4375 { SDDL_FILE_READ, FILE_GENERIC_READ },
4376 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4377 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4379 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4380 { SDDL_KEY_READ, KEY_READ },
4381 { SDDL_KEY_WRITE, KEY_WRITE },
4382 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4384 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
4385 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
4386 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
4387 { NULL, 0 },
4390 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4392 UINT len = 0;
4393 DWORD rights = 0;
4394 LPCWSTR szAcl = *StringAcl;
4396 while (*szAcl == ' ')
4397 szAcl++;
4399 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4401 LPCWSTR p = szAcl;
4403 while (*p && *p != ';')
4404 p++;
4406 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4408 rights = strtoulW(szAcl, NULL, 16);
4409 szAcl = p;
4411 else
4412 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4414 else
4416 while (*szAcl != ';')
4418 const ACEFLAG *lpaf = AceRights;
4420 while (lpaf->wstr &&
4421 (len = strlenW(lpaf->wstr)) &&
4422 strncmpW(lpaf->wstr, szAcl, len))
4424 lpaf++;
4427 if (!lpaf->wstr)
4428 return 0;
4430 rights |= lpaf->value;
4431 szAcl += len;
4435 *StringAcl = szAcl;
4436 return rights;
4440 /******************************************************************************
4441 * ParseStringAclToAcl
4443 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4445 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4446 PACL pAcl, LPDWORD cBytes)
4448 DWORD val;
4449 DWORD sidlen;
4450 DWORD length = sizeof(ACL);
4451 DWORD acesize = 0;
4452 DWORD acecount = 0;
4453 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4454 DWORD error = ERROR_INVALID_ACL;
4456 TRACE("%s\n", debugstr_w(StringAcl));
4458 if (!StringAcl)
4459 return FALSE;
4461 if (pAcl) /* pAce is only useful if we're setting values */
4462 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4464 /* Parse ACL flags */
4465 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4467 /* Parse ACE */
4468 while (*StringAcl == '(')
4470 StringAcl++;
4472 /* Parse ACE type */
4473 val = ParseAceStringType(&StringAcl);
4474 if (pAce)
4475 pAce->Header.AceType = (BYTE) val;
4476 if (*StringAcl != ';')
4478 error = RPC_S_INVALID_STRING_UUID;
4479 goto lerr;
4481 StringAcl++;
4483 /* Parse ACE flags */
4484 val = ParseAceStringFlags(&StringAcl);
4485 if (pAce)
4486 pAce->Header.AceFlags = (BYTE) val;
4487 if (*StringAcl != ';')
4488 goto lerr;
4489 StringAcl++;
4491 /* Parse ACE rights */
4492 val = ParseAceStringRights(&StringAcl);
4493 if (pAce)
4494 pAce->Mask = val;
4495 if (*StringAcl != ';')
4496 goto lerr;
4497 StringAcl++;
4499 /* Parse ACE object guid */
4500 while (*StringAcl == ' ')
4501 StringAcl++;
4502 if (*StringAcl != ';')
4504 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4505 goto lerr;
4507 StringAcl++;
4509 /* Parse ACE inherit object guid */
4510 while (*StringAcl == ' ')
4511 StringAcl++;
4512 if (*StringAcl != ';')
4514 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4515 goto lerr;
4517 StringAcl++;
4519 /* Parse ACE account sid */
4520 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4522 while (*StringAcl && *StringAcl != ')')
4523 StringAcl++;
4526 if (*StringAcl != ')')
4527 goto lerr;
4528 StringAcl++;
4530 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4531 length += acesize;
4532 if (pAce)
4534 pAce->Header.AceSize = acesize;
4535 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4537 acecount++;
4540 *cBytes = length;
4542 if (length > 0xffff)
4544 ERR("ACL too large\n");
4545 goto lerr;
4548 if (pAcl)
4550 pAcl->AclRevision = ACL_REVISION;
4551 pAcl->Sbz1 = 0;
4552 pAcl->AclSize = length;
4553 pAcl->AceCount = acecount++;
4554 pAcl->Sbz2 = 0;
4556 return TRUE;
4558 lerr:
4559 SetLastError(error);
4560 WARN("Invalid ACE string format\n");
4561 return FALSE;
4565 /******************************************************************************
4566 * ParseStringSecurityDescriptorToSecurityDescriptor
4568 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4569 LPCWSTR StringSecurityDescriptor,
4570 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4571 LPDWORD cBytes)
4573 BOOL bret = FALSE;
4574 WCHAR toktype;
4575 WCHAR *tok;
4576 LPCWSTR lptoken;
4577 LPBYTE lpNext = NULL;
4578 DWORD len;
4580 *cBytes = sizeof(SECURITY_DESCRIPTOR);
4582 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
4584 if (SecurityDescriptor)
4585 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4587 while (*StringSecurityDescriptor == ' ')
4588 StringSecurityDescriptor++;
4590 while (*StringSecurityDescriptor)
4592 toktype = *StringSecurityDescriptor;
4594 /* Expect char identifier followed by ':' */
4595 StringSecurityDescriptor++;
4596 if (*StringSecurityDescriptor != ':')
4598 SetLastError(ERROR_INVALID_PARAMETER);
4599 goto lend;
4601 StringSecurityDescriptor++;
4603 /* Extract token */
4604 lptoken = StringSecurityDescriptor;
4605 while (*lptoken && *lptoken != ':')
4606 lptoken++;
4608 if (*lptoken)
4609 lptoken--;
4611 len = lptoken - StringSecurityDescriptor;
4612 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4613 tok[len] = 0;
4615 switch (toktype)
4617 case 'O':
4619 DWORD bytes;
4621 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4622 goto lend;
4624 if (SecurityDescriptor)
4626 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4627 lpNext += bytes; /* Advance to next token */
4630 *cBytes += bytes;
4632 break;
4635 case 'G':
4637 DWORD bytes;
4639 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4640 goto lend;
4642 if (SecurityDescriptor)
4644 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4645 lpNext += bytes; /* Advance to next token */
4648 *cBytes += bytes;
4650 break;
4653 case 'D':
4655 DWORD flags;
4656 DWORD bytes;
4658 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4659 goto lend;
4661 if (SecurityDescriptor)
4663 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4664 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4665 lpNext += bytes; /* Advance to next token */
4668 *cBytes += bytes;
4670 break;
4673 case 'S':
4675 DWORD flags;
4676 DWORD bytes;
4678 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4679 goto lend;
4681 if (SecurityDescriptor)
4683 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4684 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4685 lpNext += bytes; /* Advance to next token */
4688 *cBytes += bytes;
4690 break;
4693 default:
4694 FIXME("Unknown token\n");
4695 SetLastError(ERROR_INVALID_PARAMETER);
4696 goto lend;
4699 StringSecurityDescriptor = lptoken;
4702 bret = TRUE;
4704 lend:
4705 heap_free(tok);
4706 return bret;
4709 /******************************************************************************
4710 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4712 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4713 LPCSTR StringSecurityDescriptor,
4714 DWORD StringSDRevision,
4715 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4716 PULONG SecurityDescriptorSize)
4718 BOOL ret;
4719 LPWSTR StringSecurityDescriptorW;
4721 if(!StringSecurityDescriptor)
4722 return FALSE;
4724 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4725 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4726 StringSDRevision, SecurityDescriptor,
4727 SecurityDescriptorSize);
4728 heap_free(StringSecurityDescriptorW);
4730 return ret;
4733 /******************************************************************************
4734 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4736 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4737 LPCWSTR StringSecurityDescriptor,
4738 DWORD StringSDRevision,
4739 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4740 PULONG SecurityDescriptorSize)
4742 DWORD cBytes;
4743 SECURITY_DESCRIPTOR* psd;
4744 BOOL bret = FALSE;
4746 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4748 if (GetVersion() & 0x80000000)
4750 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4751 goto lend;
4753 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4755 SetLastError(ERROR_INVALID_PARAMETER);
4756 goto lend;
4758 else if (StringSDRevision != SID_REVISION)
4760 SetLastError(ERROR_UNKNOWN_REVISION);
4761 goto lend;
4764 /* Compute security descriptor length */
4765 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4766 NULL, &cBytes))
4767 goto lend;
4769 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4770 if (!psd) goto lend;
4772 psd->Revision = SID_REVISION;
4773 psd->Control |= SE_SELF_RELATIVE;
4775 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4776 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4778 LocalFree(psd);
4779 goto lend;
4782 if (SecurityDescriptorSize)
4783 *SecurityDescriptorSize = cBytes;
4785 bret = TRUE;
4787 lend:
4788 TRACE(" ret=%d\n", bret);
4789 return bret;
4792 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4794 if (cch == -1)
4795 cch = strlenW(string);
4797 if (plen)
4798 *plen += cch;
4800 if (pwptr)
4802 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4803 *pwptr += cch;
4807 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4809 DWORD i;
4810 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4811 WCHAR subauthfmt[] = { '-','%','u',0 };
4812 WCHAR buf[26];
4813 SID *pisid = psid;
4815 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4817 SetLastError(ERROR_INVALID_SID);
4818 return FALSE;
4821 if (pisid->IdentifierAuthority.Value[0] ||
4822 pisid->IdentifierAuthority.Value[1])
4824 FIXME("not matching MS' bugs\n");
4825 SetLastError(ERROR_INVALID_SID);
4826 return FALSE;
4829 sprintfW( buf, fmt, pisid->Revision,
4830 MAKELONG(
4831 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4832 pisid->IdentifierAuthority.Value[4] ),
4833 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4834 pisid->IdentifierAuthority.Value[2] )
4835 ) );
4836 DumpString(buf, -1, pwptr, plen);
4838 for( i=0; i<pisid->SubAuthorityCount; i++ )
4840 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4841 DumpString(buf, -1, pwptr, plen);
4843 return TRUE;
4846 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4848 size_t i;
4849 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4851 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4853 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4854 return TRUE;
4858 return DumpSidNumeric(psid, pwptr, plen);
4861 static const LPCWSTR AceRightBitNames[32] = {
4862 SDDL_CREATE_CHILD, /* 0 */
4863 SDDL_DELETE_CHILD,
4864 SDDL_LIST_CHILDREN,
4865 SDDL_SELF_WRITE,
4866 SDDL_READ_PROPERTY, /* 4 */
4867 SDDL_WRITE_PROPERTY,
4868 SDDL_DELETE_TREE,
4869 SDDL_LIST_OBJECT,
4870 SDDL_CONTROL_ACCESS, /* 8 */
4871 NULL,
4872 NULL,
4873 NULL,
4874 NULL, /* 12 */
4875 NULL,
4876 NULL,
4877 NULL,
4878 SDDL_STANDARD_DELETE, /* 16 */
4879 SDDL_READ_CONTROL,
4880 SDDL_WRITE_DAC,
4881 SDDL_WRITE_OWNER,
4882 NULL, /* 20 */
4883 NULL,
4884 NULL,
4885 NULL,
4886 NULL, /* 24 */
4887 NULL,
4888 NULL,
4889 NULL,
4890 SDDL_GENERIC_ALL, /* 28 */
4891 SDDL_GENERIC_EXECUTE,
4892 SDDL_GENERIC_WRITE,
4893 SDDL_GENERIC_READ
4896 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4898 static const WCHAR fmtW[] = {'0','x','%','x',0};
4899 WCHAR buf[15];
4900 size_t i;
4902 if (mask == 0)
4903 return;
4905 /* first check if the right have name */
4906 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4908 if (AceRights[i].wstr == NULL)
4909 break;
4910 if (mask == AceRights[i].value)
4912 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4913 return;
4917 /* then check if it can be built from bit names */
4918 for (i = 0; i < 32; i++)
4920 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4922 /* can't be built from bit names */
4923 sprintfW(buf, fmtW, mask);
4924 DumpString(buf, -1, pwptr, plen);
4925 return;
4929 /* build from bit names */
4930 for (i = 0; i < 32; i++)
4931 if (mask & (1 << i))
4932 DumpString(AceRightBitNames[i], -1, pwptr, plen);
4935 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4937 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4938 static const WCHAR openbr = '(';
4939 static const WCHAR closebr = ')';
4940 static const WCHAR semicolon = ';';
4942 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4944 SetLastError(ERROR_INVALID_ACL);
4945 return FALSE;
4948 piace = pace;
4949 DumpString(&openbr, 1, pwptr, plen);
4950 switch (piace->Header.AceType)
4952 case ACCESS_ALLOWED_ACE_TYPE:
4953 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4954 break;
4955 case ACCESS_DENIED_ACE_TYPE:
4956 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4957 break;
4958 case SYSTEM_AUDIT_ACE_TYPE:
4959 DumpString(SDDL_AUDIT, -1, pwptr, plen);
4960 break;
4961 case SYSTEM_ALARM_ACE_TYPE:
4962 DumpString(SDDL_ALARM, -1, pwptr, plen);
4963 break;
4965 DumpString(&semicolon, 1, pwptr, plen);
4967 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4968 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4969 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4970 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4971 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4972 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4973 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4974 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4975 if (piace->Header.AceFlags & INHERITED_ACE)
4976 DumpString(SDDL_INHERITED, -1, pwptr, plen);
4977 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4978 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4979 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4980 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4981 DumpString(&semicolon, 1, pwptr, plen);
4982 DumpRights(piace->Mask, pwptr, plen);
4983 DumpString(&semicolon, 1, pwptr, plen);
4984 /* objects not supported */
4985 DumpString(&semicolon, 1, pwptr, plen);
4986 /* objects not supported */
4987 DumpString(&semicolon, 1, pwptr, plen);
4988 if (!DumpSid(&piace->SidStart, pwptr, plen))
4989 return FALSE;
4990 DumpString(&closebr, 1, pwptr, plen);
4991 return TRUE;
4994 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4996 WORD count;
4997 UINT i;
4999 if (protected)
5000 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
5001 if (autoInheritReq)
5002 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
5003 if (autoInherited)
5004 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
5006 if (pacl == NULL)
5007 return TRUE;
5009 if (!IsValidAcl(pacl))
5010 return FALSE;
5012 count = pacl->AceCount;
5013 for (i = 0; i < count; i++)
5015 LPVOID ace;
5016 if (!GetAce(pacl, i, &ace))
5017 return FALSE;
5018 if (!DumpAce(ace, pwptr, plen))
5019 return FALSE;
5022 return TRUE;
5025 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5027 static const WCHAR prefix[] = {'O',':',0};
5028 BOOL bDefaulted;
5029 PSID psid;
5031 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
5032 return FALSE;
5034 if (psid == NULL)
5035 return TRUE;
5037 DumpString(prefix, -1, pwptr, plen);
5038 if (!DumpSid(psid, pwptr, plen))
5039 return FALSE;
5040 return TRUE;
5043 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5045 static const WCHAR prefix[] = {'G',':',0};
5046 BOOL bDefaulted;
5047 PSID psid;
5049 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
5050 return FALSE;
5052 if (psid == NULL)
5053 return TRUE;
5055 DumpString(prefix, -1, pwptr, plen);
5056 if (!DumpSid(psid, pwptr, plen))
5057 return FALSE;
5058 return TRUE;
5061 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5063 static const WCHAR dacl[] = {'D',':',0};
5064 SECURITY_DESCRIPTOR_CONTROL control;
5065 BOOL present, defaulted;
5066 DWORD revision;
5067 PACL pacl;
5069 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
5070 return FALSE;
5072 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5073 return FALSE;
5075 if (!present)
5076 return TRUE;
5078 DumpString(dacl, 2, pwptr, plen);
5079 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
5080 return FALSE;
5081 return TRUE;
5084 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5086 static const WCHAR sacl[] = {'S',':',0};
5087 SECURITY_DESCRIPTOR_CONTROL control;
5088 BOOL present, defaulted;
5089 DWORD revision;
5090 PACL pacl;
5092 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
5093 return FALSE;
5095 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5096 return FALSE;
5098 if (!present)
5099 return TRUE;
5101 DumpString(sacl, 2, pwptr, plen);
5102 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
5103 return FALSE;
5104 return TRUE;
5107 /******************************************************************************
5108 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5110 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
5112 ULONG len;
5113 WCHAR *wptr, *wstr;
5115 if (SDRevision != SDDL_REVISION_1)
5117 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
5118 SetLastError(ERROR_UNKNOWN_REVISION);
5119 return FALSE;
5122 len = 0;
5123 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5124 if (!DumpOwner(SecurityDescriptor, NULL, &len))
5125 return FALSE;
5126 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5127 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5128 return FALSE;
5129 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5130 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5131 return FALSE;
5132 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5133 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5134 return FALSE;
5136 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5137 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5138 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5139 LocalFree (wstr);
5140 return FALSE;
5142 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5143 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5144 LocalFree (wstr);
5145 return FALSE;
5147 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5148 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5149 LocalFree (wstr);
5150 return FALSE;
5152 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5153 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5154 LocalFree (wstr);
5155 return FALSE;
5157 *wptr = 0;
5159 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5160 *OutputString = wstr;
5161 if (OutputLen)
5162 *OutputLen = strlenW(*OutputString)+1;
5163 return TRUE;
5166 /******************************************************************************
5167 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5169 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5171 LPWSTR wstr;
5172 ULONG len;
5173 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5175 int lenA;
5177 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5178 *OutputString = heap_alloc(lenA);
5179 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5180 LocalFree(wstr);
5182 if (OutputLen != NULL)
5183 *OutputLen = lenA;
5184 return TRUE;
5186 else
5188 *OutputString = NULL;
5189 if (OutputLen)
5190 *OutputLen = 0;
5191 return FALSE;
5195 /******************************************************************************
5196 * ConvertStringSidToSidW [ADVAPI32.@]
5198 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5200 BOOL bret = FALSE;
5201 DWORD cBytes;
5203 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5204 if (GetVersion() & 0x80000000)
5205 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5206 else if (!StringSid || !Sid)
5207 SetLastError(ERROR_INVALID_PARAMETER);
5208 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5210 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5212 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5213 if (!bret)
5214 LocalFree(*Sid);
5216 return bret;
5219 /******************************************************************************
5220 * ConvertStringSidToSidA [ADVAPI32.@]
5222 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5224 BOOL bret = FALSE;
5226 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5227 if (GetVersion() & 0x80000000)
5228 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5229 else if (!StringSid || !Sid)
5230 SetLastError(ERROR_INVALID_PARAMETER);
5231 else
5233 WCHAR *wStringSid = SERV_dup(StringSid);
5234 bret = ConvertStringSidToSidW(wStringSid, Sid);
5235 heap_free(wStringSid);
5237 return bret;
5240 /******************************************************************************
5241 * ConvertSidToStringSidW [ADVAPI32.@]
5243 * format of SID string is:
5244 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5245 * where
5246 * <rev> is the revision of the SID encoded as decimal
5247 * <auth> is the identifier authority encoded as hex
5248 * <subauthN> is the subauthority id encoded as decimal
5250 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5252 DWORD len = 0;
5253 LPWSTR wstr, wptr;
5255 TRACE("%p %p\n", pSid, pstr );
5257 len = 0;
5258 if (!DumpSidNumeric(pSid, NULL, &len))
5259 return FALSE;
5260 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5261 DumpSidNumeric(pSid, &wptr, NULL);
5262 *wptr = 0;
5264 *pstr = wstr;
5265 return TRUE;
5268 /******************************************************************************
5269 * ConvertSidToStringSidA [ADVAPI32.@]
5271 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5273 LPWSTR wstr = NULL;
5274 LPSTR str;
5275 UINT len;
5277 TRACE("%p %p\n", pSid, pstr );
5279 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5280 return FALSE;
5282 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5283 str = LocalAlloc( 0, len );
5284 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5285 LocalFree( wstr );
5287 *pstr = str;
5289 return TRUE;
5292 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5293 PSECURITY_DESCRIPTOR pdesc,
5294 PSECURITY_DESCRIPTOR cdesc,
5295 PSECURITY_DESCRIPTOR* ndesc,
5296 GUID* objtype,
5297 BOOL isdir,
5298 PGENERIC_MAPPING genmap )
5300 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5302 return FALSE;
5305 BOOL WINAPI CreatePrivateObjectSecurityEx(
5306 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5307 GUID *objtype, BOOL is_directory, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5309 SECURITY_DESCRIPTOR_RELATIVE *relative;
5310 DWORD needed, offset;
5311 BYTE *buffer;
5313 FIXME("%p %p %p %p %d %u %p %p - returns fake SECURITY_DESCRIPTOR\n", parent, creator, out,
5314 objtype, is_directory, flags, token, mapping);
5316 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5317 needed += sizeof(sidWorld);
5318 needed += sizeof(sidWorld);
5319 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5320 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5322 if (!(buffer = heap_alloc( needed ))) return FALSE;
5323 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5324 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5326 heap_free( buffer );
5327 return FALSE;
5329 relative->Control |= SE_SELF_RELATIVE;
5330 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5332 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5333 relative->Owner = offset;
5334 offset += sizeof(sidWorld);
5336 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5337 relative->Group = offset;
5338 offset += sizeof(sidWorld);
5340 GetWorldAccessACL( (ACL *)(buffer + offset) );
5341 relative->Dacl = offset;
5342 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5344 GetWorldAccessACL( (ACL *)(buffer + offset) );
5345 relative->Sacl = offset;
5347 *out = relative;
5348 return TRUE;
5351 BOOL WINAPI CreatePrivateObjectSecurity(
5352 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5353 BOOL is_container, HANDLE token, PGENERIC_MAPPING mapping)
5355 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, 0, token, mapping);
5358 BOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(
5359 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5360 GUID **types, ULONG count, BOOL is_container, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5362 FIXME(": semi-stub\n");
5363 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, flags, token, mapping);
5366 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5368 FIXME("%p - stub\n", ObjectDescriptor);
5370 heap_free( *ObjectDescriptor );
5371 return TRUE;
5374 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserA(
5375 HANDLE hToken,
5376 LPCSTR lpApplicationName,
5377 LPSTR lpCommandLine,
5378 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5379 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5380 BOOL bInheritHandles,
5381 DWORD dwCreationFlags,
5382 LPVOID lpEnvironment,
5383 LPCSTR lpCurrentDirectory,
5384 LPSTARTUPINFOA lpStartupInfo,
5385 LPPROCESS_INFORMATION lpProcessInformation )
5387 BOOL ret;
5388 WCHAR *appW, *cmdlnW, *cwdW;
5389 STARTUPINFOW sinfo;
5391 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5392 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5393 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5395 appW = SERV_dup(lpApplicationName);
5396 cmdlnW = SERV_dup(lpCommandLine);
5397 cwdW = SERV_dup(lpCurrentDirectory);
5398 sinfo.cb = sizeof(sinfo);
5399 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5400 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5401 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5402 sinfo.dwX = lpStartupInfo->dwX;
5403 sinfo.dwY = lpStartupInfo->dwY;
5404 sinfo.dwXSize = lpStartupInfo->dwXSize;
5405 sinfo.dwYSize = lpStartupInfo->dwYSize;
5406 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5407 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5408 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5409 sinfo.dwFlags = lpStartupInfo->dwFlags;
5410 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5411 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5412 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5413 sinfo.hStdInput = lpStartupInfo->hStdInput;
5414 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5415 sinfo.hStdError = lpStartupInfo->hStdError;
5416 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5417 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5418 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5419 heap_free(appW);
5420 heap_free(cmdlnW);
5421 heap_free(cwdW);
5422 heap_free(sinfo.lpReserved);
5423 heap_free(sinfo.lpDesktop);
5424 heap_free(sinfo.lpTitle);
5426 return ret;
5429 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(
5430 HANDLE hToken,
5431 LPCWSTR lpApplicationName,
5432 LPWSTR lpCommandLine,
5433 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5434 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5435 BOOL bInheritHandles,
5436 DWORD dwCreationFlags,
5437 LPVOID lpEnvironment,
5438 LPCWSTR lpCurrentDirectory,
5439 LPSTARTUPINFOW lpStartupInfo,
5440 LPPROCESS_INFORMATION lpProcessInformation )
5442 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5443 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5444 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5445 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5447 /* We should create the process with a suspended main thread */
5448 if (!CreateProcessW (lpApplicationName,
5449 lpCommandLine,
5450 lpProcessAttributes,
5451 lpThreadAttributes,
5452 bInheritHandles,
5453 dwCreationFlags, /* CREATE_SUSPENDED */
5454 lpEnvironment,
5455 lpCurrentDirectory,
5456 lpStartupInfo,
5457 lpProcessInformation))
5459 return FALSE;
5462 return TRUE;
5465 /******************************************************************************
5466 * CreateProcessWithLogonW
5468 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5469 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5470 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5472 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5473 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5474 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5475 lpStartupInfo, lpProcessInformation);
5477 return FALSE;
5480 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5481 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5482 PROCESS_INFORMATION *process_information )
5484 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5485 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5486 creation_flags, environment, debugstr_w(current_directory),
5487 startup_info, process_information);
5489 /* FIXME: check if handles should be inherited */
5490 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5491 current_directory, startup_info, process_information );
5494 /******************************************************************************
5495 * DuplicateTokenEx [ADVAPI32.@]
5497 BOOL WINAPI DuplicateTokenEx(
5498 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5499 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5500 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5501 TOKEN_TYPE TokenType,
5502 PHANDLE DuplicateTokenHandle )
5504 OBJECT_ATTRIBUTES ObjectAttributes;
5506 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5507 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5509 InitializeObjectAttributes(
5510 &ObjectAttributes,
5511 NULL,
5512 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5513 NULL,
5514 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5516 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5517 dwDesiredAccess,
5518 &ObjectAttributes,
5519 ImpersonationLevel,
5520 TokenType,
5521 DuplicateTokenHandle ) );
5524 BOOL WINAPI DuplicateToken(
5525 HANDLE ExistingTokenHandle,
5526 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5527 PHANDLE DuplicateTokenHandle )
5529 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5530 NULL, ImpersonationLevel, TokenImpersonation,
5531 DuplicateTokenHandle );
5534 /******************************************************************************
5535 * ComputeStringSidSize
5537 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5539 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5541 int ctok = 0;
5542 while (*StringSid)
5544 if (*StringSid == '-')
5545 ctok++;
5546 StringSid++;
5549 if (ctok >= 3)
5550 return GetSidLengthRequired(ctok - 2);
5552 else /* String constant format - Only available in winxp and above */
5554 unsigned int i;
5556 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5557 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5558 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5560 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5561 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5563 MAX_SID local;
5564 ADVAPI_GetComputerSid(&local);
5565 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5570 return GetSidLengthRequired(0);
5573 /******************************************************************************
5574 * ParseStringSidToSid
5576 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5578 BOOL bret = FALSE;
5579 SID* pisid=pSid;
5581 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5582 if (!StringSid)
5584 SetLastError(ERROR_INVALID_PARAMETER);
5585 TRACE("StringSid is NULL, returning FALSE\n");
5586 return FALSE;
5589 while (*StringSid == ' ')
5590 StringSid++;
5592 *cBytes = ComputeStringSidSize(StringSid);
5593 if (!pisid) /* Simply compute the size */
5595 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5596 return TRUE;
5599 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5601 DWORD i = 0, identAuth;
5602 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5604 StringSid += 2; /* Advance to Revision */
5605 pisid->Revision = atoiW(StringSid);
5607 if (pisid->Revision != SDDL_REVISION)
5609 TRACE("Revision %d is unknown\n", pisid->Revision);
5610 goto lend; /* ERROR_INVALID_SID */
5612 if (csubauth == 0)
5614 TRACE("SubAuthorityCount is 0\n");
5615 goto lend; /* ERROR_INVALID_SID */
5618 pisid->SubAuthorityCount = csubauth;
5620 /* Advance to identifier authority */
5621 while (*StringSid && *StringSid != '-')
5622 StringSid++;
5623 if (*StringSid == '-')
5624 StringSid++;
5626 /* MS' implementation can't handle values greater than 2^32 - 1, so
5627 * we don't either; assume most significant bytes are always 0
5629 pisid->IdentifierAuthority.Value[0] = 0;
5630 pisid->IdentifierAuthority.Value[1] = 0;
5631 identAuth = atoiW(StringSid);
5632 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5633 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5634 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5635 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5637 /* Advance to first sub authority */
5638 while (*StringSid && *StringSid != '-')
5639 StringSid++;
5640 if (*StringSid == '-')
5641 StringSid++;
5643 while (*StringSid)
5645 pisid->SubAuthority[i++] = atoiW(StringSid);
5647 while (*StringSid && *StringSid != '-')
5648 StringSid++;
5649 if (*StringSid == '-')
5650 StringSid++;
5653 if (i != pisid->SubAuthorityCount)
5654 goto lend; /* ERROR_INVALID_SID */
5656 bret = TRUE;
5658 else /* String constant format - Only available in winxp and above */
5660 unsigned int i;
5661 pisid->Revision = SDDL_REVISION;
5663 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5664 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5666 DWORD j;
5667 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5668 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5669 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5670 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5671 bret = TRUE;
5674 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5675 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5677 ADVAPI_GetComputerSid(pisid);
5678 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5679 pisid->SubAuthorityCount++;
5680 bret = TRUE;
5683 if (!bret)
5684 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5687 lend:
5688 if (!bret)
5689 SetLastError(ERROR_INVALID_SID);
5691 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5692 return bret;
5695 /******************************************************************************
5696 * GetNamedSecurityInfoA [ADVAPI32.@]
5698 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5699 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5700 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5701 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5703 LPWSTR wstr;
5704 DWORD r;
5706 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5707 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5709 wstr = SERV_dup(pObjectName);
5710 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5711 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5713 heap_free( wstr );
5715 return r;
5718 /******************************************************************************
5719 * GetNamedSecurityInfoW [ADVAPI32.@]
5721 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5722 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5723 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5725 DWORD access = 0;
5726 HANDLE handle;
5727 DWORD err;
5729 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5730 group, dacl, sacl, descriptor );
5732 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5733 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5735 /* If no descriptor, we have to check that there's a pointer for the requested information */
5736 if( !descriptor && (
5737 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5738 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5739 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5740 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5741 return ERROR_INVALID_PARAMETER;
5743 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5744 access |= READ_CONTROL;
5745 if (info & SACL_SECURITY_INFORMATION)
5746 access |= ACCESS_SYSTEM_SECURITY;
5748 switch (type)
5750 case SE_SERVICE:
5751 if (!(err = get_security_service( name, access, &handle )))
5753 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5754 CloseServiceHandle( handle );
5756 break;
5757 case SE_REGISTRY_KEY:
5758 if (!(err = get_security_regkey( name, access, &handle )))
5760 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5761 RegCloseKey( handle );
5763 break;
5764 case SE_FILE_OBJECT:
5765 if (!(err = get_security_file( name, access, &handle )))
5767 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5768 CloseHandle( handle );
5770 break;
5771 default:
5772 FIXME( "Object type %d is not currently supported.\n", type );
5773 if (owner) *owner = NULL;
5774 if (group) *group = NULL;
5775 if (dacl) *dacl = NULL;
5776 if (sacl) *sacl = NULL;
5777 if (descriptor) *descriptor = NULL;
5778 return ERROR_SUCCESS;
5780 return err;
5783 /******************************************************************************
5784 * GetNamedSecurityInfoExW [ADVAPI32.@]
5786 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5787 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5788 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5790 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5791 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5792 return ERROR_CALL_NOT_IMPLEMENTED;
5795 /******************************************************************************
5796 * GetNamedSecurityInfoExA [ADVAPI32.@]
5798 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5799 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5800 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5802 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5803 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5804 return ERROR_CALL_NOT_IMPLEMENTED;
5807 /******************************************************************************
5808 * DecryptFileW [ADVAPI32.@]
5810 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5812 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5813 return TRUE;
5816 /******************************************************************************
5817 * DecryptFileA [ADVAPI32.@]
5819 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5821 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5822 return TRUE;
5825 /******************************************************************************
5826 * EncryptFileW [ADVAPI32.@]
5828 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5830 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5831 return TRUE;
5834 /******************************************************************************
5835 * EncryptFileA [ADVAPI32.@]
5837 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5839 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5840 return TRUE;
5843 /******************************************************************************
5844 * FileEncryptionStatusW [ADVAPI32.@]
5846 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5848 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5849 if (!lpStatus)
5850 return FALSE;
5851 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5852 return TRUE;
5855 /******************************************************************************
5856 * FileEncryptionStatusA [ADVAPI32.@]
5858 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5860 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5861 if (!lpStatus)
5862 return FALSE;
5863 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5864 return TRUE;
5867 /******************************************************************************
5868 * SetSecurityInfo [ADVAPI32.@]
5870 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5871 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5872 PSID psidGroup, PACL pDacl, PACL pSacl)
5874 SECURITY_DESCRIPTOR sd;
5875 PACL dacl = pDacl;
5876 NTSTATUS status;
5878 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5879 return ERROR_INVALID_SECURITY_DESCR;
5881 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5882 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5883 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5884 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5885 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5887 if (ObjectType == SE_FILE_OBJECT && pDacl)
5889 SECURITY_DESCRIPTOR_CONTROL control;
5890 PSECURITY_DESCRIPTOR psd;
5891 OBJECT_NAME_INFORMATION *name_info;
5892 DWORD size, rev;
5894 status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
5895 if (status != STATUS_BUFFER_TOO_SMALL)
5896 return RtlNtStatusToDosError(status);
5898 psd = heap_alloc(size);
5899 if (!psd)
5900 return ERROR_NOT_ENOUGH_MEMORY;
5902 status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
5903 if (status)
5905 heap_free(psd);
5906 return RtlNtStatusToDosError(status);
5909 status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
5910 heap_free(psd);
5911 if (status)
5912 return RtlNtStatusToDosError(status);
5913 /* TODO: copy some control flags to new sd */
5915 /* inherit parent directory DACL */
5916 if (!(control & SE_DACL_PROTECTED))
5918 status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
5919 if (status != STATUS_INFO_LENGTH_MISMATCH)
5920 return RtlNtStatusToDosError(status);
5922 name_info = heap_alloc(size);
5923 if (!name_info)
5924 return ERROR_NOT_ENOUGH_MEMORY;
5926 status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
5927 if (status)
5929 heap_free(name_info);
5930 return RtlNtStatusToDosError(status);
5933 for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
5934 if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
5935 name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
5936 break;
5937 if (name_info->Name.Length)
5939 OBJECT_ATTRIBUTES attr;
5940 IO_STATUS_BLOCK io;
5941 HANDLE parent;
5942 PSECURITY_DESCRIPTOR parent_sd;
5943 ACL *parent_dacl;
5944 DWORD err = ERROR_ACCESS_DENIED;
5946 name_info->Name.Buffer[name_info->Name.Length/2] = 0;
5948 attr.Length = sizeof(attr);
5949 attr.RootDirectory = 0;
5950 attr.Attributes = 0;
5951 attr.ObjectName = &name_info->Name;
5952 attr.SecurityDescriptor = NULL;
5953 status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
5954 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5955 FILE_OPEN_FOR_BACKUP_INTENT);
5956 heap_free(name_info);
5957 if (!status)
5959 err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
5960 NULL, NULL, &parent_dacl, NULL, &parent_sd);
5961 CloseHandle(parent);
5964 if (!err)
5966 int i;
5968 dacl = heap_alloc_zero(pDacl->AclSize+parent_dacl->AclSize);
5969 if (!dacl)
5971 LocalFree(parent_sd);
5972 return ERROR_NOT_ENOUGH_MEMORY;
5974 memcpy(dacl, pDacl, pDacl->AclSize);
5975 dacl->AclSize = pDacl->AclSize+parent_dacl->AclSize;
5977 for (i=0; i<parent_dacl->AceCount; i++)
5979 ACE_HEADER *ace;
5981 if (!GetAce(parent_dacl, i, (void*)&ace))
5982 continue;
5983 if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
5984 continue;
5985 if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
5986 (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
5988 FIXME("unsupported flags: %x\n", ace->AceFlags);
5989 continue;
5992 if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
5993 ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
5994 ace->AceFlags &= ~INHERIT_ONLY_ACE;
5995 ace->AceFlags |= INHERITED_ACE;
5997 if(!AddAce(dacl, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
5998 WARN("error adding inherited ACE\n");
6000 LocalFree(parent_sd);
6003 else
6004 heap_free(name_info);
6008 SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
6010 if (SecurityInfo & SACL_SECURITY_INFORMATION)
6011 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
6013 switch (ObjectType)
6015 case SE_SERVICE:
6016 FIXME("stub: Service objects are not supported at this time.\n");
6017 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
6018 break;
6019 default:
6020 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
6021 break;
6023 if (dacl != pDacl)
6024 heap_free(dacl);
6025 return RtlNtStatusToDosError(status);
6028 /******************************************************************************
6029 * SaferCreateLevel [ADVAPI32.@]
6031 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
6032 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
6034 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
6036 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6037 return TRUE;
6040 /******************************************************************************
6041 * SaferComputeTokenFromLevel [ADVAPI32.@]
6043 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
6044 DWORD flags, LPVOID reserved)
6046 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
6048 *access_token = (HANDLE)0xdeadbeef;
6049 return TRUE;
6052 /******************************************************************************
6053 * SaferCloseLevel [ADVAPI32.@]
6055 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
6057 FIXME("(%p) stub\n", handle);
6058 return TRUE;
6061 /******************************************************************************
6062 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
6064 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
6065 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
6066 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
6067 BOOL KeepExplicit, FN_PROGRESS fnProgress,
6068 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
6070 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
6071 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
6072 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
6074 return ERROR_SUCCESS;
6077 /******************************************************************************
6078 * SaferGetPolicyInformation [ADVAPI32.@]
6080 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
6081 PVOID buffer, PDWORD required, LPVOID lpReserved)
6083 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
6084 return FALSE;
6087 /******************************************************************************
6088 * SaferSetLevelInformation [ADVAPI32.@]
6090 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
6091 LPVOID buffer, DWORD size)
6093 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
6094 return FALSE;
6097 /******************************************************************************
6098 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
6100 DWORD WINAPI LookupSecurityDescriptorPartsA(TRUSTEEA *owner, TRUSTEEA *group, ULONG *access_count,
6101 EXPLICIT_ACCESSA *access_list, ULONG *audit_count,
6102 EXPLICIT_ACCESSA *audit_list, SECURITY_DESCRIPTOR *descriptor)
6104 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6105 access_list, audit_count, audit_list, descriptor);
6106 return ERROR_CALL_NOT_IMPLEMENTED;
6109 /******************************************************************************
6110 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
6112 DWORD WINAPI LookupSecurityDescriptorPartsW(TRUSTEEW *owner, TRUSTEEW *group, ULONG *access_count,
6113 EXPLICIT_ACCESSW *access_list, ULONG *audit_count,
6114 EXPLICIT_ACCESSW *audit_list, SECURITY_DESCRIPTOR *descriptor)
6116 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6117 access_list, audit_count, audit_list, descriptor);
6118 return ERROR_CALL_NOT_IMPLEMENTED;