kernel32: Add GetEnabledXStateFeatures() stub.
[wine.git] / dlls / advapi32 / security.c
blob6f4fb44ae9581d14a532e05623c8b4366c108a15
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);
52 typedef struct _ACEFLAG
54 LPCWSTR wstr;
55 DWORD value;
56 } ACEFLAG, *LPACEFLAG;
58 typedef struct _MAX_SID
60 /* same fields as struct _SID */
61 BYTE Revision;
62 BYTE SubAuthorityCount;
63 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
64 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
65 } MAX_SID;
67 typedef struct WELLKNOWNSID
69 WCHAR wstr[2];
70 WELL_KNOWN_SID_TYPE Type;
71 MAX_SID Sid;
72 } WELLKNOWNSID;
74 static const WELLKNOWNSID WellKnownSids[] =
76 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
77 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
78 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
79 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
80 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
81 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
82 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
83 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
84 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
85 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
86 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
87 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
88 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
89 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
90 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
91 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
92 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
93 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
94 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
95 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
96 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
97 { {0,0}, WinLogonIdsSid, { SID_REVISION, SECURITY_LOGON_IDS_RID_COUNT, { SECURITY_NT_AUTHORITY }, { SECURITY_LOGON_IDS_RID } } },
98 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
99 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
100 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
101 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
102 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
103 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
104 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
105 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
106 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
107 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
108 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
109 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
110 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
111 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
112 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
113 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
114 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
115 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
116 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
117 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
118 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
119 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
120 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
121 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
122 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
123 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
124 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
125 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
126 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
127 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
128 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
129 { {0,0}, WinBuiltinAnyPackageSid, { SID_REVISION, 2, { SECURITY_APP_PACKAGE_AUTHORITY }, { SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE } } },
132 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
133 typedef struct WELLKNOWNRID
135 WCHAR wstr[2];
136 WELL_KNOWN_SID_TYPE Type;
137 DWORD Rid;
138 } WELLKNOWNRID;
140 static const WELLKNOWNRID WellKnownRids[] = {
141 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
142 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
143 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
144 { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
145 { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
146 { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
147 { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
148 { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
149 { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
150 { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
151 { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
152 { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
153 { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
157 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
159 typedef struct _AccountSid {
160 WELL_KNOWN_SID_TYPE type;
161 LPCWSTR account;
162 LPCWSTR domain;
163 SID_NAME_USE name_use;
164 LPCWSTR alias;
165 } AccountSid;
167 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
168 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
169 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
170 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 };
171 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
172 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 };
173 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
174 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
175 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
176 static const WCHAR Blank[] = { 0 };
177 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
178 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
179 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
180 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 };
181 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
182 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 };
183 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
184 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
185 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 };
186 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
187 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
188 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
189 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
190 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
191 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
192 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 };
193 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
194 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 };
195 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
196 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
197 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
198 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
199 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
200 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
201 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
202 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 };
203 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
204 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
205 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
206 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
207 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
208 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
209 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
210 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 };
211 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 };
212 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
213 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 };
214 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
215 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
216 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
217 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 };
218 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 };
219 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
220 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
221 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 };
222 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
223 static const WCHAR SELF[] = { 'S','E','L','F',0 };
224 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
225 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
226 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
227 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 };
228 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
229 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
231 static const AccountSid ACCOUNT_SIDS[] = {
232 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
233 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
234 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
235 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
236 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
237 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
238 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
239 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
240 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
241 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
242 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
255 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
256 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
257 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
258 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
259 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
260 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
261 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
262 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
263 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
264 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
265 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
266 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
267 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
268 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
269 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
270 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
271 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
272 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
273 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
275 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
276 { WinBuiltinAnyPackageSid, ALL_APPLICATION_PACKAGES, APPLICATION_PACKAGE_AUTHORITY, SidTypeWellKnownGroup },
279 * ACE access rights
281 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
282 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
283 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
284 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
286 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
287 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
288 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
289 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
290 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
291 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
292 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
293 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
294 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
296 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
297 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
298 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
299 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
301 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
302 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
303 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
304 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
306 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
307 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
308 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
309 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
311 static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0};
312 static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0};
313 static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0};
316 * ACL flags
318 static const WCHAR SDDL_PROTECTED[] = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
323 * ACE types
325 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
327 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
328 static const WCHAR SDDL_ALARM[] = {'A','L',0};
329 static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0};
332 * ACE flags
334 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
335 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
336 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
337 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
338 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
339 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
340 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
342 const char * debugstr_sid(PSID sid)
344 int auth = 0;
345 SID * psid = sid;
347 if (psid == NULL)
348 return "(null)";
350 auth = psid->IdentifierAuthority.Value[5] +
351 (psid->IdentifierAuthority.Value[4] << 8) +
352 (psid->IdentifierAuthority.Value[3] << 16) +
353 (psid->IdentifierAuthority.Value[2] << 24);
355 switch (psid->SubAuthorityCount) {
356 case 0:
357 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
358 case 1:
359 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
360 psid->SubAuthority[0]);
361 case 2:
362 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
363 psid->SubAuthority[0], psid->SubAuthority[1]);
364 case 3:
365 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
366 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
367 case 4:
368 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
369 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
370 psid->SubAuthority[3]);
371 case 5:
372 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
373 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
374 psid->SubAuthority[3], psid->SubAuthority[4]);
375 case 6:
376 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
377 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
378 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
379 case 7:
380 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
381 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
382 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
383 psid->SubAuthority[6]);
384 case 8:
385 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
386 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
387 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
388 psid->SubAuthority[6], psid->SubAuthority[7]);
390 return "(too-big)";
393 /* set last error code from NT status and get the proper boolean return value */
394 /* used for functions that are a simple wrapper around the corresponding ntdll API */
395 static inline BOOL set_ntstatus( NTSTATUS status )
397 if (status) SetLastError( RtlNtStatusToDosError( status ));
398 return !status;
401 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
402 static inline DWORD get_security_file( LPCWSTR full_file_name, DWORD access, HANDLE *file )
404 UNICODE_STRING file_nameW;
405 OBJECT_ATTRIBUTES attr;
406 IO_STATUS_BLOCK io;
407 NTSTATUS status;
409 if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
410 return ERROR_PATH_NOT_FOUND;
411 attr.Length = sizeof(attr);
412 attr.RootDirectory = 0;
413 attr.Attributes = OBJ_CASE_INSENSITIVE;
414 attr.ObjectName = &file_nameW;
415 attr.SecurityDescriptor = NULL;
416 status = NtCreateFile( file, access|SYNCHRONIZE, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
417 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
418 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
419 RtlFreeUnicodeString( &file_nameW );
420 return RtlNtStatusToDosError( status );
423 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
424 static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service )
426 SC_HANDLE manager = 0;
427 DWORD err;
429 err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager );
430 if (err == ERROR_SUCCESS)
432 err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service );
433 CloseServiceHandle( manager );
435 return err;
438 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
439 static inline DWORD get_security_regkey( LPWSTR full_key_name, DWORD access, HANDLE *key )
441 WCHAR classes_rootW[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
442 WCHAR current_userW[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
443 WCHAR machineW[] = {'M','A','C','H','I','N','E',0};
444 WCHAR usersW[] = {'U','S','E','R','S',0};
445 LPWSTR p = strchrW(full_key_name, '\\');
446 int len = p-full_key_name;
447 HKEY hParent;
449 if (!p) return ERROR_INVALID_PARAMETER;
450 if (strncmpW( full_key_name, classes_rootW, len ) == 0)
451 hParent = HKEY_CLASSES_ROOT;
452 else if (strncmpW( full_key_name, current_userW, len ) == 0)
453 hParent = HKEY_CURRENT_USER;
454 else if (strncmpW( full_key_name, machineW, len ) == 0)
455 hParent = HKEY_LOCAL_MACHINE;
456 else if (strncmpW( full_key_name, usersW, len ) == 0)
457 hParent = HKEY_USERS;
458 else
459 return ERROR_INVALID_PARAMETER;
460 return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
463 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
465 static void GetWorldAccessACL(PACL pACL)
467 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
469 pACL->AclRevision = ACL_REVISION;
470 pACL->Sbz1 = 0;
471 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
472 pACL->AceCount = 1;
473 pACL->Sbz2 = 0;
475 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
476 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
477 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
478 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
479 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
482 /************************************************************
483 * ADVAPI_IsLocalComputer
485 * Checks whether the server name indicates local machine.
487 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
489 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
490 BOOL Result;
491 LPWSTR buf;
493 if (!ServerName || !ServerName[0])
494 return TRUE;
496 buf = heap_alloc(dwSize * sizeof(WCHAR));
497 Result = GetComputerNameW(buf, &dwSize);
498 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
499 ServerName += 2;
500 Result = Result && !lstrcmpW(ServerName, buf);
501 heap_free(buf);
503 return Result;
506 /************************************************************
507 * ADVAPI_GetComputerSid
509 BOOL ADVAPI_GetComputerSid(PSID sid)
511 static const struct /* same fields as struct SID */
513 BYTE Revision;
514 BYTE SubAuthorityCount;
515 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
516 DWORD SubAuthority[4];
517 } computer_sid =
518 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
520 memcpy( sid, &computer_sid, sizeof(computer_sid) );
521 return TRUE;
524 /* ##############################
525 ###### TOKEN FUNCTIONS ######
526 ##############################
529 /******************************************************************************
530 * OpenProcessToken [ADVAPI32.@]
531 * Opens the access token associated with a process handle.
533 * PARAMS
534 * ProcessHandle [I] Handle to process
535 * DesiredAccess [I] Desired access to process
536 * TokenHandle [O] Pointer to handle of open access token
538 * RETURNS
539 * Success: TRUE. TokenHandle contains the access token.
540 * Failure: FALSE.
542 * NOTES
543 * See NtOpenProcessToken.
545 BOOL WINAPI
546 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
547 HANDLE *TokenHandle )
549 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
552 /******************************************************************************
553 * OpenThreadToken [ADVAPI32.@]
555 * Opens the access token associated with a thread handle.
557 * PARAMS
558 * ThreadHandle [I] Handle to process
559 * DesiredAccess [I] Desired access to the thread
560 * OpenAsSelf [I] ???
561 * TokenHandle [O] Destination for the token handle
563 * RETURNS
564 * Success: TRUE. TokenHandle contains the access token.
565 * Failure: FALSE.
567 * NOTES
568 * See NtOpenThreadToken.
570 BOOL WINAPI
571 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
572 BOOL OpenAsSelf, HANDLE *TokenHandle)
574 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
577 BOOL WINAPI
578 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
579 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
581 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
582 PreviousState, ReturnLength));
585 /******************************************************************************
586 * AdjustTokenPrivileges [ADVAPI32.@]
588 * Adjust the privileges of an open token handle.
590 * PARAMS
591 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
592 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
593 * NewState [I] Desired new privileges of the token
594 * BufferLength [I] Length of NewState
595 * PreviousState [O] Destination for the previous state
596 * ReturnLength [I/O] Size of PreviousState
599 * RETURNS
600 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
601 * Failure: FALSE.
603 * NOTES
604 * See NtAdjustPrivilegesToken.
606 BOOL WINAPI
607 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
608 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
609 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
611 NTSTATUS status;
613 TRACE("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
614 PreviousState, ReturnLength);
616 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
617 NewState, BufferLength, PreviousState,
618 ReturnLength);
619 SetLastError( RtlNtStatusToDosError( status ));
620 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
621 return TRUE;
622 else
623 return FALSE;
626 /******************************************************************************
627 * CheckTokenMembership [ADVAPI32.@]
629 * Determine if an access token is a member of a SID.
631 * PARAMS
632 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
633 * SidToCheck [I] SID that possibly contains the token
634 * IsMember [O] Destination for result.
636 * RETURNS
637 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
638 * Failure: FALSE.
640 BOOL WINAPI
641 CheckTokenMembership( HANDLE token, PSID sid_to_check,
642 PBOOL is_member )
644 PTOKEN_GROUPS token_groups = NULL;
645 HANDLE thread_token = NULL;
646 DWORD size, i;
647 BOOL ret;
649 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
651 *is_member = FALSE;
653 if (!token)
655 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
657 HANDLE process_token;
658 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
659 if (!ret)
660 goto exit;
661 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
662 NULL, SecurityImpersonation, TokenImpersonation,
663 &thread_token);
664 CloseHandle(process_token);
665 if (!ret)
666 goto exit;
668 token = thread_token;
670 else
672 TOKEN_TYPE type;
674 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
675 if (!ret) goto exit;
677 if (type == TokenPrimary)
679 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
680 return FALSE;
684 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
685 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
686 goto exit;
688 token_groups = heap_alloc(size);
689 if (!token_groups)
691 ret = FALSE;
692 goto exit;
695 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
696 if (!ret)
697 goto exit;
699 for (i = 0; i < token_groups->GroupCount; i++)
701 TRACE("Groups[%d]: {0x%x, %s}\n", i,
702 token_groups->Groups[i].Attributes,
703 debugstr_sid(token_groups->Groups[i].Sid));
704 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
705 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
707 *is_member = TRUE;
708 TRACE("sid enabled and found in token\n");
709 break;
713 exit:
714 heap_free(token_groups);
715 if (thread_token != NULL) CloseHandle(thread_token);
717 return ret;
720 /******************************************************************************
721 * GetTokenInformation [ADVAPI32.@]
723 * Get a type of information about an access token.
725 * PARAMS
726 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
727 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
728 * tokeninfo [O] Destination for token information
729 * tokeninfolength [I] Length of tokeninfo
730 * retlen [O] Destination for returned token information length
732 * RETURNS
733 * Success: TRUE. tokeninfo contains retlen bytes of token information
734 * Failure: FALSE.
736 * NOTES
737 * See NtQueryInformationToken.
739 BOOL WINAPI
740 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
741 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
743 TRACE("(%p, %s, %p, %d, %p):\n",
744 token,
745 (tokeninfoclass == TokenUser) ? "TokenUser" :
746 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
747 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
748 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
749 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
750 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
751 (tokeninfoclass == TokenSource) ? "TokenSource" :
752 (tokeninfoclass == TokenType) ? "TokenType" :
753 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
754 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
755 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
756 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
757 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
758 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
759 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
760 "Unknown",
761 tokeninfo, tokeninfolength, retlen);
762 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
763 tokeninfolength, retlen));
766 /******************************************************************************
767 * SetTokenInformation [ADVAPI32.@]
769 * Set information for an access token.
771 * PARAMS
772 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
773 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
774 * tokeninfo [I] Token information to set
775 * tokeninfolength [I] Length of tokeninfo
777 * RETURNS
778 * Success: TRUE. The information for the token is set to tokeninfo.
779 * Failure: FALSE.
781 BOOL WINAPI
782 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
783 LPVOID tokeninfo, DWORD tokeninfolength )
785 TRACE("(%p, %s, %p, %d)\n",
786 token,
787 (tokeninfoclass == TokenUser) ? "TokenUser" :
788 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
789 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
790 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
791 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
792 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
793 (tokeninfoclass == TokenSource) ? "TokenSource" :
794 (tokeninfoclass == TokenType) ? "TokenType" :
795 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
796 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
797 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
798 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
799 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
800 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
801 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
802 "Unknown",
803 tokeninfo, tokeninfolength);
805 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
808 /*************************************************************************
809 * SetThreadToken [ADVAPI32.@]
811 * Assigns an 'impersonation token' to a thread so it can assume the
812 * security privileges of another thread or process. Can also remove
813 * a previously assigned token.
815 * PARAMS
816 * thread [O] Handle to thread to set the token for
817 * token [I] Token to set
819 * RETURNS
820 * Success: TRUE. The threads access token is set to token
821 * Failure: FALSE.
823 * NOTES
824 * Only supported on NT or higher. On Win9X this function does nothing.
825 * See SetTokenInformation.
827 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
829 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
830 ThreadImpersonationToken, &token, sizeof token ));
833 /*************************************************************************
834 * CreateRestrictedToken [ADVAPI32.@]
836 * Create a new more restricted token from an existing token.
838 * PARAMS
839 * baseToken [I] Token to base the new restricted token on
840 * flags [I] Options
841 * nDisableSids [I] Length of disableSids array
842 * disableSids [I] Array of SIDs to disable in the new token
843 * nDeletePrivs [I] Length of deletePrivs array
844 * deletePrivs [I] Array of privileges to delete in the new token
845 * nRestrictSids [I] Length of restrictSids array
846 * restrictSids [I] Array of SIDs to restrict in the new token
847 * newToken [O] Address where the new token is stored
849 * RETURNS
850 * Success: TRUE
851 * Failure: FALSE
853 BOOL WINAPI CreateRestrictedToken(
854 HANDLE baseToken,
855 DWORD flags,
856 DWORD nDisableSids,
857 PSID_AND_ATTRIBUTES disableSids,
858 DWORD nDeletePrivs,
859 PLUID_AND_ATTRIBUTES deletePrivs,
860 DWORD nRestrictSids,
861 PSID_AND_ATTRIBUTES restrictSids,
862 PHANDLE newToken)
864 TOKEN_TYPE type;
865 SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
866 DWORD size;
868 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
869 baseToken, flags, nDisableSids, disableSids,
870 nDeletePrivs, deletePrivs,
871 nRestrictSids, restrictSids,
872 newToken);
874 size = sizeof(type);
875 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
876 if (type == TokenImpersonation)
878 size = sizeof(level);
879 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
880 return FALSE;
882 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
885 /* ##############################
886 ###### SID FUNCTIONS ######
887 ##############################
890 /******************************************************************************
891 * AllocateAndInitializeSid [ADVAPI32.@]
893 * PARAMS
894 * pIdentifierAuthority []
895 * nSubAuthorityCount []
896 * nSubAuthority0 []
897 * nSubAuthority1 []
898 * nSubAuthority2 []
899 * nSubAuthority3 []
900 * nSubAuthority4 []
901 * nSubAuthority5 []
902 * nSubAuthority6 []
903 * nSubAuthority7 []
904 * pSid []
906 BOOL WINAPI
907 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
908 BYTE nSubAuthorityCount,
909 DWORD nSubAuthority0, DWORD nSubAuthority1,
910 DWORD nSubAuthority2, DWORD nSubAuthority3,
911 DWORD nSubAuthority4, DWORD nSubAuthority5,
912 DWORD nSubAuthority6, DWORD nSubAuthority7,
913 PSID *pSid )
915 return set_ntstatus( RtlAllocateAndInitializeSid(
916 pIdentifierAuthority, nSubAuthorityCount,
917 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
918 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
919 pSid ));
922 /******************************************************************************
923 * FreeSid [ADVAPI32.@]
925 * PARAMS
926 * pSid []
928 PVOID WINAPI
929 FreeSid( PSID pSid )
931 RtlFreeSid(pSid);
932 return NULL; /* is documented like this */
935 /******************************************************************************
936 * CopySid [ADVAPI32.@]
938 * PARAMS
939 * nDestinationSidLength []
940 * pDestinationSid []
941 * pSourceSid []
943 BOOL WINAPI
944 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
946 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
949 /******************************************************************************
950 * CreateWellKnownSid [ADVAPI32.@]
952 BOOL WINAPI
953 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
954 PSID DomainSid,
955 PSID pSid,
956 DWORD* cbSid)
958 unsigned int i;
959 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
961 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
963 SetLastError(ERROR_INVALID_PARAMETER);
964 return FALSE;
967 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
968 if (WellKnownSids[i].Type == WellKnownSidType) {
969 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
971 if (*cbSid < length)
973 *cbSid = length;
974 SetLastError(ERROR_INSUFFICIENT_BUFFER);
975 return FALSE;
977 if (!pSid)
979 SetLastError(ERROR_INVALID_PARAMETER);
980 return FALSE;
982 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
983 *cbSid = length;
984 return TRUE;
988 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
990 SetLastError(ERROR_INVALID_PARAMETER);
991 return FALSE;
994 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
995 if (WellKnownRids[i].Type == WellKnownSidType) {
996 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
997 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
998 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
1000 if (*cbSid < output_sid_length)
1002 *cbSid = output_sid_length;
1003 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1004 return FALSE;
1006 if (!pSid)
1008 SetLastError(ERROR_INVALID_PARAMETER);
1009 return FALSE;
1011 CopyMemory(pSid, DomainSid, domain_sid_length);
1012 (*GetSidSubAuthorityCount(pSid))++;
1013 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1014 *cbSid = output_sid_length;
1015 return TRUE;
1018 SetLastError(ERROR_INVALID_PARAMETER);
1019 return FALSE;
1022 /******************************************************************************
1023 * IsWellKnownSid [ADVAPI32.@]
1025 BOOL WINAPI
1026 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1028 unsigned int i;
1029 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1031 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
1032 if (WellKnownSids[i].Type == WellKnownSidType)
1033 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1034 return TRUE;
1036 return FALSE;
1039 BOOL WINAPI
1040 IsTokenRestricted( HANDLE TokenHandle )
1042 TOKEN_GROUPS *groups;
1043 DWORD size;
1044 NTSTATUS status;
1045 BOOL restricted;
1047 TRACE("(%p)\n", TokenHandle);
1049 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1050 if (status != STATUS_BUFFER_TOO_SMALL)
1051 return FALSE;
1053 groups = heap_alloc(size);
1054 if (!groups)
1056 SetLastError(ERROR_OUTOFMEMORY);
1057 return FALSE;
1060 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1061 if (status != STATUS_SUCCESS)
1063 heap_free(groups);
1064 return set_ntstatus(status);
1067 restricted = groups->GroupCount > 0;
1068 heap_free(groups);
1070 return restricted;
1073 /******************************************************************************
1074 * IsValidSid [ADVAPI32.@]
1076 * PARAMS
1077 * pSid []
1079 BOOL WINAPI
1080 IsValidSid( PSID pSid )
1082 return RtlValidSid( pSid );
1085 /******************************************************************************
1086 * EqualSid [ADVAPI32.@]
1088 * PARAMS
1089 * pSid1 []
1090 * pSid2 []
1092 BOOL WINAPI
1093 EqualSid( PSID pSid1, PSID pSid2 )
1095 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1096 SetLastError(ERROR_SUCCESS);
1097 return ret;
1100 /******************************************************************************
1101 * EqualPrefixSid [ADVAPI32.@]
1103 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1105 return RtlEqualPrefixSid(pSid1, pSid2);
1108 /******************************************************************************
1109 * GetSidLengthRequired [ADVAPI32.@]
1111 * PARAMS
1112 * nSubAuthorityCount []
1114 DWORD WINAPI
1115 GetSidLengthRequired( BYTE nSubAuthorityCount )
1117 return RtlLengthRequiredSid(nSubAuthorityCount);
1120 /******************************************************************************
1121 * InitializeSid [ADVAPI32.@]
1123 * PARAMS
1124 * pIdentifierAuthority []
1126 BOOL WINAPI
1127 InitializeSid (
1128 PSID pSid,
1129 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1130 BYTE nSubAuthorityCount)
1132 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1135 DWORD WINAPI
1136 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1138 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1140 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1141 return 0;
1144 DWORD WINAPI
1145 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1147 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1149 return 1;
1152 /******************************************************************************
1153 * GetSidIdentifierAuthority [ADVAPI32.@]
1155 * PARAMS
1156 * pSid []
1158 PSID_IDENTIFIER_AUTHORITY WINAPI
1159 GetSidIdentifierAuthority( PSID pSid )
1161 SetLastError(ERROR_SUCCESS);
1162 return RtlIdentifierAuthoritySid(pSid);
1165 /******************************************************************************
1166 * GetSidSubAuthority [ADVAPI32.@]
1168 * PARAMS
1169 * pSid []
1170 * nSubAuthority []
1172 PDWORD WINAPI
1173 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1175 SetLastError(ERROR_SUCCESS);
1176 return RtlSubAuthoritySid(pSid, nSubAuthority);
1179 /******************************************************************************
1180 * GetSidSubAuthorityCount [ADVAPI32.@]
1182 * PARAMS
1183 * pSid []
1185 PUCHAR WINAPI
1186 GetSidSubAuthorityCount (PSID pSid)
1188 SetLastError(ERROR_SUCCESS);
1189 return RtlSubAuthorityCountSid(pSid);
1192 /******************************************************************************
1193 * GetLengthSid [ADVAPI32.@]
1195 * PARAMS
1196 * pSid []
1198 DWORD WINAPI
1199 GetLengthSid (PSID pSid)
1201 return RtlLengthSid(pSid);
1204 /* ##############################################
1205 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1206 ##############################################
1209 /******************************************************************************
1210 * BuildSecurityDescriptorA [ADVAPI32.@]
1212 * Builds a SD from
1214 * PARAMS
1215 * pOwner [I]
1216 * pGroup [I]
1217 * cCountOfAccessEntries [I]
1218 * pListOfAccessEntries [I]
1219 * cCountOfAuditEntries [I]
1220 * pListofAuditEntries [I]
1221 * pOldSD [I]
1222 * lpdwBufferLength [I/O]
1223 * pNewSD [O]
1225 * RETURNS
1226 * Success: ERROR_SUCCESS
1227 * Failure: nonzero error code from Winerror.h
1229 DWORD WINAPI BuildSecurityDescriptorA(
1230 IN PTRUSTEEA pOwner,
1231 IN PTRUSTEEA pGroup,
1232 IN ULONG cCountOfAccessEntries,
1233 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1234 IN ULONG cCountOfAuditEntries,
1235 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1236 IN PSECURITY_DESCRIPTOR pOldSD,
1237 IN OUT PULONG lpdwBufferLength,
1238 OUT PSECURITY_DESCRIPTOR* pNewSD)
1240 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1241 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1242 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1244 return ERROR_CALL_NOT_IMPLEMENTED;
1247 /******************************************************************************
1248 * BuildSecurityDescriptorW [ADVAPI32.@]
1250 * See BuildSecurityDescriptorA.
1252 DWORD WINAPI BuildSecurityDescriptorW(
1253 IN PTRUSTEEW pOwner,
1254 IN PTRUSTEEW pGroup,
1255 IN ULONG cCountOfAccessEntries,
1256 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1257 IN ULONG cCountOfAuditEntries,
1258 IN PEXPLICIT_ACCESSW pListofAuditEntries,
1259 IN PSECURITY_DESCRIPTOR pOldSD,
1260 IN OUT PULONG lpdwBufferLength,
1261 OUT PSECURITY_DESCRIPTOR* pNewSD)
1263 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1264 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1265 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1267 return ERROR_CALL_NOT_IMPLEMENTED;
1270 /******************************************************************************
1271 * InitializeSecurityDescriptor [ADVAPI32.@]
1273 * PARAMS
1274 * pDescr []
1275 * revision []
1277 BOOL WINAPI
1278 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1280 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1284 /******************************************************************************
1285 * MakeAbsoluteSD [ADVAPI32.@]
1287 BOOL WINAPI MakeAbsoluteSD (
1288 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1289 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1290 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1291 OUT PACL pDacl,
1292 OUT LPDWORD lpdwDaclSize,
1293 OUT PACL pSacl,
1294 OUT LPDWORD lpdwSaclSize,
1295 OUT PSID pOwner,
1296 OUT LPDWORD lpdwOwnerSize,
1297 OUT PSID pPrimaryGroup,
1298 OUT LPDWORD lpdwPrimaryGroupSize)
1300 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1301 pAbsoluteSecurityDescriptor,
1302 lpdwAbsoluteSecurityDescriptorSize,
1303 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1304 pOwner, lpdwOwnerSize,
1305 pPrimaryGroup, lpdwPrimaryGroupSize));
1308 /******************************************************************************
1309 * GetKernelObjectSecurity [ADVAPI32.@]
1311 BOOL WINAPI GetKernelObjectSecurity(
1312 HANDLE Handle,
1313 SECURITY_INFORMATION RequestedInformation,
1314 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1315 DWORD nLength,
1316 LPDWORD lpnLengthNeeded )
1318 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1319 pSecurityDescriptor, nLength, lpnLengthNeeded);
1321 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1322 nLength, lpnLengthNeeded ));
1325 /******************************************************************************
1326 * GetPrivateObjectSecurity [ADVAPI32.@]
1328 BOOL WINAPI GetPrivateObjectSecurity(
1329 PSECURITY_DESCRIPTOR ObjectDescriptor,
1330 SECURITY_INFORMATION SecurityInformation,
1331 PSECURITY_DESCRIPTOR ResultantDescriptor,
1332 DWORD DescriptorLength,
1333 PDWORD ReturnLength )
1335 SECURITY_DESCRIPTOR desc;
1336 BOOL defaulted, present;
1337 PACL pacl;
1338 PSID psid;
1340 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1341 ResultantDescriptor, DescriptorLength, ReturnLength);
1343 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1344 return FALSE;
1346 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1348 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1349 return FALSE;
1350 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1353 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1355 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1356 return FALSE;
1357 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1360 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1362 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1363 return FALSE;
1364 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1367 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1369 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1370 return FALSE;
1371 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1374 *ReturnLength = DescriptorLength;
1375 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1378 /******************************************************************************
1379 * GetSecurityDescriptorLength [ADVAPI32.@]
1381 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1383 return RtlLengthSecurityDescriptor(pDescr);
1386 /******************************************************************************
1387 * GetSecurityDescriptorOwner [ADVAPI32.@]
1389 * PARAMS
1390 * pOwner []
1391 * lpbOwnerDefaulted []
1393 BOOL WINAPI
1394 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1395 LPBOOL lpbOwnerDefaulted )
1397 BOOLEAN defaulted;
1398 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1399 *lpbOwnerDefaulted = defaulted;
1400 return ret;
1403 /******************************************************************************
1404 * SetSecurityDescriptorOwner [ADVAPI32.@]
1406 * PARAMS
1408 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1409 PSID pOwner, BOOL bOwnerDefaulted)
1411 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1413 /******************************************************************************
1414 * GetSecurityDescriptorGroup [ADVAPI32.@]
1416 BOOL WINAPI GetSecurityDescriptorGroup(
1417 PSECURITY_DESCRIPTOR SecurityDescriptor,
1418 PSID *Group,
1419 LPBOOL GroupDefaulted)
1421 BOOLEAN defaulted;
1422 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1423 *GroupDefaulted = defaulted;
1424 return ret;
1426 /******************************************************************************
1427 * SetSecurityDescriptorGroup [ADVAPI32.@]
1429 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1430 PSID Group, BOOL GroupDefaulted)
1432 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1435 /******************************************************************************
1436 * IsValidSecurityDescriptor [ADVAPI32.@]
1438 * PARAMS
1439 * lpsecdesc []
1441 BOOL WINAPI
1442 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1444 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1447 /******************************************************************************
1448 * GetSecurityDescriptorDacl [ADVAPI32.@]
1450 BOOL WINAPI GetSecurityDescriptorDacl(
1451 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1452 OUT LPBOOL lpbDaclPresent,
1453 OUT PACL *pDacl,
1454 OUT LPBOOL lpbDaclDefaulted)
1456 BOOLEAN present, defaulted;
1457 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1458 *lpbDaclPresent = present;
1459 *lpbDaclDefaulted = defaulted;
1460 return ret;
1463 /******************************************************************************
1464 * SetSecurityDescriptorDacl [ADVAPI32.@]
1466 BOOL WINAPI
1467 SetSecurityDescriptorDacl (
1468 PSECURITY_DESCRIPTOR lpsd,
1469 BOOL daclpresent,
1470 PACL dacl,
1471 BOOL dacldefaulted )
1473 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1475 /******************************************************************************
1476 * GetSecurityDescriptorSacl [ADVAPI32.@]
1478 BOOL WINAPI GetSecurityDescriptorSacl(
1479 IN PSECURITY_DESCRIPTOR lpsd,
1480 OUT LPBOOL lpbSaclPresent,
1481 OUT PACL *pSacl,
1482 OUT LPBOOL lpbSaclDefaulted)
1484 BOOLEAN present, defaulted;
1485 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1486 *lpbSaclPresent = present;
1487 *lpbSaclDefaulted = defaulted;
1488 return ret;
1491 /**************************************************************************
1492 * SetSecurityDescriptorSacl [ADVAPI32.@]
1494 BOOL WINAPI SetSecurityDescriptorSacl (
1495 PSECURITY_DESCRIPTOR lpsd,
1496 BOOL saclpresent,
1497 PACL lpsacl,
1498 BOOL sacldefaulted)
1500 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1502 /******************************************************************************
1503 * MakeSelfRelativeSD [ADVAPI32.@]
1505 * PARAMS
1506 * lpabssecdesc []
1507 * lpselfsecdesc []
1508 * lpbuflen []
1510 BOOL WINAPI
1511 MakeSelfRelativeSD(
1512 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1513 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1514 IN OUT LPDWORD lpdwBufferLength)
1516 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1517 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1520 /******************************************************************************
1521 * GetSecurityDescriptorControl [ADVAPI32.@]
1524 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1525 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1527 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1530 /******************************************************************************
1531 * SetSecurityDescriptorControl [ADVAPI32.@]
1533 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1534 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1535 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1537 return set_ntstatus( RtlSetControlSecurityDescriptor(
1538 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1541 /******************************************************************************
1542 * GetWindowsAccountDomainSid [ADVAPI32.@]
1544 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
1546 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
1547 DWORD required_size;
1548 int i;
1550 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
1552 if (!sid || !IsValidSid( sid ))
1554 SetLastError( ERROR_INVALID_SID );
1555 return FALSE;
1558 if (!size)
1560 SetLastError( ERROR_INVALID_PARAMETER );
1561 return FALSE;
1564 if (*GetSidSubAuthorityCount( sid ) < 4)
1566 SetLastError( ERROR_INVALID_SID );
1567 return FALSE;
1570 required_size = GetSidLengthRequired( 4 );
1571 if (*size < required_size || !domain_sid)
1573 *size = required_size;
1574 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
1575 ERROR_INVALID_PARAMETER );
1576 return FALSE;
1579 InitializeSid( domain_sid, &domain_ident, 4 );
1580 for (i = 0; i < 4; i++)
1581 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
1583 *size = required_size;
1584 return TRUE;
1587 /* ##############################
1588 ###### ACL FUNCTIONS ######
1589 ##############################
1592 /*************************************************************************
1593 * InitializeAcl [ADVAPI32.@]
1595 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1597 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1600 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1602 IO_STATUS_BLOCK io_block;
1604 TRACE("(%p)\n", hNamedPipe);
1606 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1607 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1610 /******************************************************************************
1611 * AddAccessAllowedAce [ADVAPI32.@]
1613 BOOL WINAPI AddAccessAllowedAce(
1614 IN OUT PACL pAcl,
1615 IN DWORD dwAceRevision,
1616 IN DWORD AccessMask,
1617 IN PSID pSid)
1619 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1622 /******************************************************************************
1623 * AddAccessAllowedAceEx [ADVAPI32.@]
1625 BOOL WINAPI AddAccessAllowedAceEx(
1626 IN OUT PACL pAcl,
1627 IN DWORD dwAceRevision,
1628 IN DWORD AceFlags,
1629 IN DWORD AccessMask,
1630 IN PSID pSid)
1632 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1635 /******************************************************************************
1636 * AddAccessAllowedObjectAce [ADVAPI32.@]
1638 BOOL WINAPI AddAccessAllowedObjectAce(
1639 IN OUT PACL pAcl,
1640 IN DWORD dwAceRevision,
1641 IN DWORD dwAceFlags,
1642 IN DWORD dwAccessMask,
1643 IN GUID* pObjectTypeGuid,
1644 IN GUID* pInheritedObjectTypeGuid,
1645 IN PSID pSid)
1647 return set_ntstatus(RtlAddAccessAllowedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1648 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid));
1651 /******************************************************************************
1652 * AddAccessDeniedAce [ADVAPI32.@]
1654 BOOL WINAPI AddAccessDeniedAce(
1655 IN OUT PACL pAcl,
1656 IN DWORD dwAceRevision,
1657 IN DWORD AccessMask,
1658 IN PSID pSid)
1660 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1663 /******************************************************************************
1664 * AddAccessDeniedAceEx [ADVAPI32.@]
1666 BOOL WINAPI AddAccessDeniedAceEx(
1667 IN OUT PACL pAcl,
1668 IN DWORD dwAceRevision,
1669 IN DWORD AceFlags,
1670 IN DWORD AccessMask,
1671 IN PSID pSid)
1673 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1676 /******************************************************************************
1677 * AddAccessDeniedObjectAce [ADVAPI32.@]
1679 BOOL WINAPI AddAccessDeniedObjectAce(
1680 IN OUT PACL pAcl,
1681 IN DWORD dwAceRevision,
1682 IN DWORD dwAceFlags,
1683 IN DWORD dwAccessMask,
1684 IN GUID* pObjectTypeGuid,
1685 IN GUID* pInheritedObjectTypeGuid,
1686 IN PSID pSid)
1688 return set_ntstatus( RtlAddAccessDeniedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1689 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid) );
1692 /******************************************************************************
1693 * AddAce [ADVAPI32.@]
1695 BOOL WINAPI AddAce(
1696 IN OUT PACL pAcl,
1697 IN DWORD dwAceRevision,
1698 IN DWORD dwStartingAceIndex,
1699 LPVOID pAceList,
1700 DWORD nAceListLength)
1702 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1705 /******************************************************************************
1706 * AddMandatoryAce [ADVAPI32.@]
1708 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1710 return set_ntstatus(RtlAddMandatoryAce(acl, ace_revision, ace_flags, mandatory_policy,
1711 SYSTEM_MANDATORY_LABEL_ACE_TYPE, label_sid));
1714 /******************************************************************************
1715 * DeleteAce [ADVAPI32.@]
1717 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1719 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1722 /******************************************************************************
1723 * FindFirstFreeAce [ADVAPI32.@]
1725 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1727 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1730 /******************************************************************************
1731 * GetAce [ADVAPI32.@]
1733 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1735 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1738 /******************************************************************************
1739 * GetAclInformation [ADVAPI32.@]
1741 BOOL WINAPI GetAclInformation(
1742 PACL pAcl,
1743 LPVOID pAclInformation,
1744 DWORD nAclInformationLength,
1745 ACL_INFORMATION_CLASS dwAclInformationClass)
1747 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1748 nAclInformationLength, dwAclInformationClass));
1751 /******************************************************************************
1752 * IsValidAcl [ADVAPI32.@]
1754 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1756 return RtlValidAcl(pAcl);
1759 /* ##############################
1760 ###### MISC FUNCTIONS ######
1761 ##############################
1764 /******************************************************************************
1765 * AllocateLocallyUniqueId [ADVAPI32.@]
1767 * PARAMS
1768 * lpLuid []
1770 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1772 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1775 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1776 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1777 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1778 { '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 };
1779 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1780 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1781 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1782 { '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 };
1783 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1784 { '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 };
1785 static const WCHAR SE_TCB_NAME_W[] =
1786 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1787 static const WCHAR SE_SECURITY_NAME_W[] =
1788 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1789 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1790 { '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 };
1791 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1792 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1793 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1794 { '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 };
1795 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1796 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1797 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1798 { '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 };
1799 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1800 { '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 };
1801 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1802 { '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 };
1803 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1804 { '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 };
1805 static const WCHAR SE_BACKUP_NAME_W[] =
1806 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1807 static const WCHAR SE_RESTORE_NAME_W[] =
1808 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1809 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1810 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1811 static const WCHAR SE_DEBUG_NAME_W[] =
1812 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1813 static const WCHAR SE_AUDIT_NAME_W[] =
1814 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1815 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1816 { '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 };
1817 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1818 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1819 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1820 { '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 };
1821 static const WCHAR SE_UNDOCK_NAME_W[] =
1822 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1823 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1824 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1825 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1826 { '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 };
1827 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1828 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1829 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1830 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1831 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1832 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1834 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1836 NULL,
1837 NULL,
1838 SE_CREATE_TOKEN_NAME_W,
1839 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1840 SE_LOCK_MEMORY_NAME_W,
1841 SE_INCREASE_QUOTA_NAME_W,
1842 SE_MACHINE_ACCOUNT_NAME_W,
1843 SE_TCB_NAME_W,
1844 SE_SECURITY_NAME_W,
1845 SE_TAKE_OWNERSHIP_NAME_W,
1846 SE_LOAD_DRIVER_NAME_W,
1847 SE_SYSTEM_PROFILE_NAME_W,
1848 SE_SYSTEMTIME_NAME_W,
1849 SE_PROF_SINGLE_PROCESS_NAME_W,
1850 SE_INC_BASE_PRIORITY_NAME_W,
1851 SE_CREATE_PAGEFILE_NAME_W,
1852 SE_CREATE_PERMANENT_NAME_W,
1853 SE_BACKUP_NAME_W,
1854 SE_RESTORE_NAME_W,
1855 SE_SHUTDOWN_NAME_W,
1856 SE_DEBUG_NAME_W,
1857 SE_AUDIT_NAME_W,
1858 SE_SYSTEM_ENVIRONMENT_NAME_W,
1859 SE_CHANGE_NOTIFY_NAME_W,
1860 SE_REMOTE_SHUTDOWN_NAME_W,
1861 SE_UNDOCK_NAME_W,
1862 SE_SYNC_AGENT_NAME_W,
1863 SE_ENABLE_DELEGATION_NAME_W,
1864 SE_MANAGE_VOLUME_NAME_W,
1865 SE_IMPERSONATE_NAME_W,
1866 SE_CREATE_GLOBAL_NAME_W,
1869 const WCHAR *get_wellknown_privilege_name(const LUID *luid)
1871 if (luid->HighPart || luid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1872 luid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || !WellKnownPrivNames[luid->LowPart])
1873 return NULL;
1875 return WellKnownPrivNames[luid->LowPart];
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 count, PEXPLICIT_ACCESSW *list )
4207 ACL_SIZE_INFORMATION sizeinfo;
4208 EXPLICIT_ACCESSW *entries;
4209 MAX_SID *sid_entries;
4210 ACE_HEADER *ace;
4211 NTSTATUS status;
4212 int i;
4214 TRACE("%p %p %p\n",pacl, count, list);
4216 if (!count || !list)
4217 return ERROR_INVALID_PARAMETER;
4219 status = RtlQueryInformationAcl(pacl, &sizeinfo, sizeof(sizeinfo), AclSizeInformation);
4220 if (status) return RtlNtStatusToDosError(status);
4222 if (!sizeinfo.AceCount)
4224 *count = 0;
4225 *list = NULL;
4226 return ERROR_SUCCESS;
4229 entries = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (sizeof(EXPLICIT_ACCESSW) + sizeof(MAX_SID)) * sizeinfo.AceCount);
4230 if (!entries) return ERROR_OUTOFMEMORY;
4231 sid_entries = (MAX_SID *)(entries + sizeinfo.AceCount);
4233 for (i = 0; i < sizeinfo.AceCount; i++)
4235 status = RtlGetAce(pacl, i, (void**)&ace);
4236 if (status) goto error;
4238 switch (ace->AceType)
4240 case ACCESS_ALLOWED_ACE_TYPE:
4242 ACCESS_ALLOWED_ACE *allow = (ACCESS_ALLOWED_ACE *)ace;
4243 entries[i].grfAccessMode = GRANT_ACCESS;
4244 entries[i].grfInheritance = ace->AceFlags;
4245 entries[i].grfAccessPermissions = allow->Mask;
4247 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&allow->SidStart);
4248 entries[i].Trustee.pMultipleTrustee = NULL;
4249 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4250 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4251 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4252 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4253 break;
4256 case ACCESS_DENIED_ACE_TYPE:
4258 ACCESS_DENIED_ACE *deny = (ACCESS_DENIED_ACE *)ace;
4259 entries[i].grfAccessMode = DENY_ACCESS;
4260 entries[i].grfInheritance = ace->AceFlags;
4261 entries[i].grfAccessPermissions = deny->Mask;
4263 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&deny->SidStart);
4264 entries[i].Trustee.pMultipleTrustee = NULL;
4265 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4266 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4267 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4268 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4269 break;
4272 default:
4273 FIXME("Unhandled ace type %d\n", ace->AceType);
4274 entries[i].grfAccessMode = NOT_USED_ACCESS;
4275 continue;
4279 *count = sizeinfo.AceCount;
4280 *list = entries;
4281 return ERROR_SUCCESS;
4283 error:
4284 LocalFree(entries);
4285 return RtlNtStatusToDosError(status);
4288 /******************************************************************************
4289 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4291 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4292 PACCESS_MASK pFailedAuditRights)
4294 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4295 return ERROR_CALL_NOT_IMPLEMENTED;
4299 /******************************************************************************
4300 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4302 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4303 PACCESS_MASK pFailedAuditRights)
4305 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4306 return ERROR_CALL_NOT_IMPLEMENTED;
4310 /******************************************************************************
4311 * ParseAclStringFlags
4313 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4315 DWORD flags = 0;
4316 LPCWSTR szAcl = *StringAcl;
4318 while (*szAcl && *szAcl != '(')
4320 if (*szAcl == 'P')
4322 flags |= SE_DACL_PROTECTED;
4324 else if (*szAcl == 'A')
4326 szAcl++;
4327 if (*szAcl == 'R')
4328 flags |= SE_DACL_AUTO_INHERIT_REQ;
4329 else if (*szAcl == 'I')
4330 flags |= SE_DACL_AUTO_INHERITED;
4332 szAcl++;
4335 *StringAcl = szAcl;
4336 return flags;
4339 /******************************************************************************
4340 * ParseAceStringType
4342 static const ACEFLAG AceType[] =
4344 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4345 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4346 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4347 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4348 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
4350 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4351 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4352 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4353 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4355 { NULL, 0 },
4358 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4360 UINT len = 0;
4361 LPCWSTR szAcl = *StringAcl;
4362 const ACEFLAG *lpaf = AceType;
4364 while (*szAcl == ' ')
4365 szAcl++;
4367 while (lpaf->wstr &&
4368 (len = strlenW(lpaf->wstr)) &&
4369 strncmpW(lpaf->wstr, szAcl, len))
4370 lpaf++;
4372 if (!lpaf->wstr)
4373 return 0;
4375 *StringAcl = szAcl + len;
4376 return lpaf->value;
4380 /******************************************************************************
4381 * ParseAceStringFlags
4383 static const ACEFLAG AceFlags[] =
4385 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4386 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4387 { SDDL_INHERITED, INHERITED_ACE },
4388 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4389 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4390 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4391 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4392 { NULL, 0 },
4395 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4397 UINT len = 0;
4398 BYTE flags = 0;
4399 LPCWSTR szAcl = *StringAcl;
4401 while (*szAcl == ' ')
4402 szAcl++;
4404 while (*szAcl != ';')
4406 const ACEFLAG *lpaf = AceFlags;
4408 while (lpaf->wstr &&
4409 (len = strlenW(lpaf->wstr)) &&
4410 strncmpW(lpaf->wstr, szAcl, len))
4411 lpaf++;
4413 if (!lpaf->wstr)
4414 return 0;
4416 flags |= lpaf->value;
4417 szAcl += len;
4420 *StringAcl = szAcl;
4421 return flags;
4425 /******************************************************************************
4426 * ParseAceStringRights
4428 static const ACEFLAG AceRights[] =
4430 { SDDL_GENERIC_ALL, GENERIC_ALL },
4431 { SDDL_GENERIC_READ, GENERIC_READ },
4432 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4433 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4435 { SDDL_READ_CONTROL, READ_CONTROL },
4436 { SDDL_STANDARD_DELETE, DELETE },
4437 { SDDL_WRITE_DAC, WRITE_DAC },
4438 { SDDL_WRITE_OWNER, WRITE_OWNER },
4440 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4441 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4442 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4443 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4444 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4445 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4446 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4447 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4448 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4450 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4451 { SDDL_FILE_READ, FILE_GENERIC_READ },
4452 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4453 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4455 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4456 { SDDL_KEY_READ, KEY_READ },
4457 { SDDL_KEY_WRITE, KEY_WRITE },
4458 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4460 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
4461 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
4462 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
4463 { NULL, 0 },
4466 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4468 UINT len = 0;
4469 DWORD rights = 0;
4470 LPCWSTR szAcl = *StringAcl;
4472 while (*szAcl == ' ')
4473 szAcl++;
4475 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4477 LPCWSTR p = szAcl;
4479 while (*p && *p != ';')
4480 p++;
4482 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4484 rights = strtoulW(szAcl, NULL, 16);
4485 szAcl = p;
4487 else
4488 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4490 else
4492 while (*szAcl != ';')
4494 const ACEFLAG *lpaf = AceRights;
4496 while (lpaf->wstr &&
4497 (len = strlenW(lpaf->wstr)) &&
4498 strncmpW(lpaf->wstr, szAcl, len))
4500 lpaf++;
4503 if (!lpaf->wstr)
4504 return 0;
4506 rights |= lpaf->value;
4507 szAcl += len;
4511 *StringAcl = szAcl;
4512 return rights;
4516 /******************************************************************************
4517 * ParseStringAclToAcl
4519 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4521 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4522 PACL pAcl, LPDWORD cBytes)
4524 DWORD val;
4525 DWORD sidlen;
4526 DWORD length = sizeof(ACL);
4527 DWORD acesize = 0;
4528 DWORD acecount = 0;
4529 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4530 DWORD error = ERROR_INVALID_ACL;
4532 TRACE("%s\n", debugstr_w(StringAcl));
4534 if (!StringAcl)
4535 return FALSE;
4537 if (pAcl) /* pAce is only useful if we're setting values */
4538 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4540 /* Parse ACL flags */
4541 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4543 /* Parse ACE */
4544 while (*StringAcl == '(')
4546 StringAcl++;
4548 /* Parse ACE type */
4549 val = ParseAceStringType(&StringAcl);
4550 if (pAce)
4551 pAce->Header.AceType = (BYTE) val;
4552 if (*StringAcl != ';')
4554 error = RPC_S_INVALID_STRING_UUID;
4555 goto lerr;
4557 StringAcl++;
4559 /* Parse ACE flags */
4560 val = ParseAceStringFlags(&StringAcl);
4561 if (pAce)
4562 pAce->Header.AceFlags = (BYTE) val;
4563 if (*StringAcl != ';')
4564 goto lerr;
4565 StringAcl++;
4567 /* Parse ACE rights */
4568 val = ParseAceStringRights(&StringAcl);
4569 if (pAce)
4570 pAce->Mask = val;
4571 if (*StringAcl != ';')
4572 goto lerr;
4573 StringAcl++;
4575 /* Parse ACE object guid */
4576 while (*StringAcl == ' ')
4577 StringAcl++;
4578 if (*StringAcl != ';')
4580 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4581 goto lerr;
4583 StringAcl++;
4585 /* Parse ACE inherit object guid */
4586 while (*StringAcl == ' ')
4587 StringAcl++;
4588 if (*StringAcl != ';')
4590 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4591 goto lerr;
4593 StringAcl++;
4595 /* Parse ACE account sid */
4596 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4598 while (*StringAcl && *StringAcl != ')')
4599 StringAcl++;
4602 if (*StringAcl != ')')
4603 goto lerr;
4604 StringAcl++;
4606 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4607 length += acesize;
4608 if (pAce)
4610 pAce->Header.AceSize = acesize;
4611 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4613 acecount++;
4616 *cBytes = length;
4618 if (length > 0xffff)
4620 ERR("ACL too large\n");
4621 goto lerr;
4624 if (pAcl)
4626 pAcl->AclRevision = ACL_REVISION;
4627 pAcl->Sbz1 = 0;
4628 pAcl->AclSize = length;
4629 pAcl->AceCount = acecount;
4630 pAcl->Sbz2 = 0;
4632 return TRUE;
4634 lerr:
4635 SetLastError(error);
4636 WARN("Invalid ACE string format\n");
4637 return FALSE;
4641 /******************************************************************************
4642 * ParseStringSecurityDescriptorToSecurityDescriptor
4644 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4645 LPCWSTR StringSecurityDescriptor,
4646 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4647 LPDWORD cBytes)
4649 BOOL bret = FALSE;
4650 WCHAR toktype;
4651 WCHAR *tok;
4652 LPCWSTR lptoken;
4653 LPBYTE lpNext = NULL;
4654 DWORD len;
4656 *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4658 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
4660 if (SecurityDescriptor)
4661 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4663 while (*StringSecurityDescriptor == ' ')
4664 StringSecurityDescriptor++;
4666 while (*StringSecurityDescriptor)
4668 toktype = *StringSecurityDescriptor;
4670 /* Expect char identifier followed by ':' */
4671 StringSecurityDescriptor++;
4672 if (*StringSecurityDescriptor != ':')
4674 SetLastError(ERROR_INVALID_PARAMETER);
4675 goto lend;
4677 StringSecurityDescriptor++;
4679 /* Extract token */
4680 lptoken = StringSecurityDescriptor;
4681 while (*lptoken && *lptoken != ':')
4682 lptoken++;
4684 if (*lptoken)
4685 lptoken--;
4687 len = lptoken - StringSecurityDescriptor;
4688 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4689 tok[len] = 0;
4691 switch (toktype)
4693 case 'O':
4695 DWORD bytes;
4697 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4698 goto lend;
4700 if (SecurityDescriptor)
4702 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4703 lpNext += bytes; /* Advance to next token */
4706 *cBytes += bytes;
4708 break;
4711 case 'G':
4713 DWORD bytes;
4715 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4716 goto lend;
4718 if (SecurityDescriptor)
4720 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4721 lpNext += bytes; /* Advance to next token */
4724 *cBytes += bytes;
4726 break;
4729 case 'D':
4731 DWORD flags;
4732 DWORD bytes;
4734 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4735 goto lend;
4737 if (SecurityDescriptor)
4739 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4740 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4741 lpNext += bytes; /* Advance to next token */
4744 *cBytes += bytes;
4746 break;
4749 case 'S':
4751 DWORD flags;
4752 DWORD bytes;
4754 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4755 goto lend;
4757 if (SecurityDescriptor)
4759 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4760 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4761 lpNext += bytes; /* Advance to next token */
4764 *cBytes += bytes;
4766 break;
4769 default:
4770 FIXME("Unknown token\n");
4771 SetLastError(ERROR_INVALID_PARAMETER);
4772 goto lend;
4775 StringSecurityDescriptor = lptoken;
4778 bret = TRUE;
4780 lend:
4781 heap_free(tok);
4782 return bret;
4785 /******************************************************************************
4786 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4788 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4789 LPCSTR StringSecurityDescriptor,
4790 DWORD StringSDRevision,
4791 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4792 PULONG SecurityDescriptorSize)
4794 BOOL ret;
4795 LPWSTR StringSecurityDescriptorW;
4797 TRACE("%s, %u, %p, %p\n", debugstr_a(StringSecurityDescriptor), StringSDRevision,
4798 SecurityDescriptor, SecurityDescriptorSize);
4800 if(!StringSecurityDescriptor)
4801 return FALSE;
4803 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4804 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4805 StringSDRevision, SecurityDescriptor,
4806 SecurityDescriptorSize);
4807 heap_free(StringSecurityDescriptorW);
4809 return ret;
4812 /******************************************************************************
4813 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4815 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4816 LPCWSTR StringSecurityDescriptor,
4817 DWORD StringSDRevision,
4818 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4819 PULONG SecurityDescriptorSize)
4821 DWORD cBytes;
4822 SECURITY_DESCRIPTOR* psd;
4823 BOOL bret = FALSE;
4825 TRACE("%s, %u, %p, %p\n", debugstr_w(StringSecurityDescriptor), StringSDRevision,
4826 SecurityDescriptor, SecurityDescriptorSize);
4828 if (GetVersion() & 0x80000000)
4830 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4831 goto lend;
4833 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4835 SetLastError(ERROR_INVALID_PARAMETER);
4836 goto lend;
4838 else if (StringSDRevision != SID_REVISION)
4840 SetLastError(ERROR_UNKNOWN_REVISION);
4841 goto lend;
4844 /* Compute security descriptor length */
4845 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4846 NULL, &cBytes))
4847 goto lend;
4849 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4850 if (!psd) goto lend;
4852 psd->Revision = SID_REVISION;
4853 psd->Control |= SE_SELF_RELATIVE;
4855 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4856 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4858 LocalFree(psd);
4859 goto lend;
4862 if (SecurityDescriptorSize)
4863 *SecurityDescriptorSize = cBytes;
4865 bret = TRUE;
4867 lend:
4868 TRACE(" ret=%d\n", bret);
4869 return bret;
4872 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4874 if (cch == -1)
4875 cch = strlenW(string);
4877 if (plen)
4878 *plen += cch;
4880 if (pwptr)
4882 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4883 *pwptr += cch;
4887 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4889 DWORD i;
4890 WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4891 WCHAR subauthfmt[] = { '-','%','u',0 };
4892 WCHAR buf[26];
4893 SID *pisid = psid;
4895 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4897 SetLastError(ERROR_INVALID_SID);
4898 return FALSE;
4901 if (pisid->IdentifierAuthority.Value[0] ||
4902 pisid->IdentifierAuthority.Value[1])
4904 FIXME("not matching MS' bugs\n");
4905 SetLastError(ERROR_INVALID_SID);
4906 return FALSE;
4909 sprintfW( buf, fmt, pisid->Revision,
4910 MAKELONG(
4911 MAKEWORD( pisid->IdentifierAuthority.Value[5],
4912 pisid->IdentifierAuthority.Value[4] ),
4913 MAKEWORD( pisid->IdentifierAuthority.Value[3],
4914 pisid->IdentifierAuthority.Value[2] )
4915 ) );
4916 DumpString(buf, -1, pwptr, plen);
4918 for( i=0; i<pisid->SubAuthorityCount; i++ )
4920 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4921 DumpString(buf, -1, pwptr, plen);
4923 return TRUE;
4926 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4928 size_t i;
4929 for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4931 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4933 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4934 return TRUE;
4938 return DumpSidNumeric(psid, pwptr, plen);
4941 static const LPCWSTR AceRightBitNames[32] = {
4942 SDDL_CREATE_CHILD, /* 0 */
4943 SDDL_DELETE_CHILD,
4944 SDDL_LIST_CHILDREN,
4945 SDDL_SELF_WRITE,
4946 SDDL_READ_PROPERTY, /* 4 */
4947 SDDL_WRITE_PROPERTY,
4948 SDDL_DELETE_TREE,
4949 SDDL_LIST_OBJECT,
4950 SDDL_CONTROL_ACCESS, /* 8 */
4951 NULL,
4952 NULL,
4953 NULL,
4954 NULL, /* 12 */
4955 NULL,
4956 NULL,
4957 NULL,
4958 SDDL_STANDARD_DELETE, /* 16 */
4959 SDDL_READ_CONTROL,
4960 SDDL_WRITE_DAC,
4961 SDDL_WRITE_OWNER,
4962 NULL, /* 20 */
4963 NULL,
4964 NULL,
4965 NULL,
4966 NULL, /* 24 */
4967 NULL,
4968 NULL,
4969 NULL,
4970 SDDL_GENERIC_ALL, /* 28 */
4971 SDDL_GENERIC_EXECUTE,
4972 SDDL_GENERIC_WRITE,
4973 SDDL_GENERIC_READ
4976 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4978 static const WCHAR fmtW[] = {'0','x','%','x',0};
4979 WCHAR buf[15];
4980 size_t i;
4982 if (mask == 0)
4983 return;
4985 /* first check if the right have name */
4986 for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4988 if (AceRights[i].wstr == NULL)
4989 break;
4990 if (mask == AceRights[i].value)
4992 DumpString(AceRights[i].wstr, -1, pwptr, plen);
4993 return;
4997 /* then check if it can be built from bit names */
4998 for (i = 0; i < 32; i++)
5000 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
5002 /* can't be built from bit names */
5003 sprintfW(buf, fmtW, mask);
5004 DumpString(buf, -1, pwptr, plen);
5005 return;
5009 /* build from bit names */
5010 for (i = 0; i < 32; i++)
5011 if (mask & (1 << i))
5012 DumpString(AceRightBitNames[i], -1, pwptr, plen);
5015 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
5017 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
5018 static const WCHAR openbr = '(';
5019 static const WCHAR closebr = ')';
5020 static const WCHAR semicolon = ';';
5022 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
5024 SetLastError(ERROR_INVALID_ACL);
5025 return FALSE;
5028 piace = pace;
5029 DumpString(&openbr, 1, pwptr, plen);
5030 switch (piace->Header.AceType)
5032 case ACCESS_ALLOWED_ACE_TYPE:
5033 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
5034 break;
5035 case ACCESS_DENIED_ACE_TYPE:
5036 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
5037 break;
5038 case SYSTEM_AUDIT_ACE_TYPE:
5039 DumpString(SDDL_AUDIT, -1, pwptr, plen);
5040 break;
5041 case SYSTEM_ALARM_ACE_TYPE:
5042 DumpString(SDDL_ALARM, -1, pwptr, plen);
5043 break;
5045 DumpString(&semicolon, 1, pwptr, plen);
5047 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
5048 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
5049 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
5050 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
5051 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
5052 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
5053 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
5054 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
5055 if (piace->Header.AceFlags & INHERITED_ACE)
5056 DumpString(SDDL_INHERITED, -1, pwptr, plen);
5057 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
5058 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
5059 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
5060 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
5061 DumpString(&semicolon, 1, pwptr, plen);
5062 DumpRights(piace->Mask, pwptr, plen);
5063 DumpString(&semicolon, 1, pwptr, plen);
5064 /* objects not supported */
5065 DumpString(&semicolon, 1, pwptr, plen);
5066 /* objects not supported */
5067 DumpString(&semicolon, 1, pwptr, plen);
5068 if (!DumpSid(&piace->SidStart, pwptr, plen))
5069 return FALSE;
5070 DumpString(&closebr, 1, pwptr, plen);
5071 return TRUE;
5074 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
5076 WORD count;
5077 UINT i;
5079 if (protected)
5080 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
5081 if (autoInheritReq)
5082 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
5083 if (autoInherited)
5084 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
5086 if (pacl == NULL)
5087 return TRUE;
5089 if (!IsValidAcl(pacl))
5090 return FALSE;
5092 count = pacl->AceCount;
5093 for (i = 0; i < count; i++)
5095 LPVOID ace;
5096 if (!GetAce(pacl, i, &ace))
5097 return FALSE;
5098 if (!DumpAce(ace, pwptr, plen))
5099 return FALSE;
5102 return TRUE;
5105 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5107 static const WCHAR prefix[] = {'O',':',0};
5108 BOOL bDefaulted;
5109 PSID psid;
5111 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
5112 return FALSE;
5114 if (psid == NULL)
5115 return TRUE;
5117 DumpString(prefix, -1, pwptr, plen);
5118 if (!DumpSid(psid, pwptr, plen))
5119 return FALSE;
5120 return TRUE;
5123 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5125 static const WCHAR prefix[] = {'G',':',0};
5126 BOOL bDefaulted;
5127 PSID psid;
5129 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
5130 return FALSE;
5132 if (psid == NULL)
5133 return TRUE;
5135 DumpString(prefix, -1, pwptr, plen);
5136 if (!DumpSid(psid, pwptr, plen))
5137 return FALSE;
5138 return TRUE;
5141 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5143 static const WCHAR dacl[] = {'D',':',0};
5144 SECURITY_DESCRIPTOR_CONTROL control;
5145 BOOL present, defaulted;
5146 DWORD revision;
5147 PACL pacl;
5149 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
5150 return FALSE;
5152 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5153 return FALSE;
5155 if (!present)
5156 return TRUE;
5158 DumpString(dacl, 2, pwptr, plen);
5159 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
5160 return FALSE;
5161 return TRUE;
5164 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5166 static const WCHAR sacl[] = {'S',':',0};
5167 SECURITY_DESCRIPTOR_CONTROL control;
5168 BOOL present, defaulted;
5169 DWORD revision;
5170 PACL pacl;
5172 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
5173 return FALSE;
5175 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5176 return FALSE;
5178 if (!present)
5179 return TRUE;
5181 DumpString(sacl, 2, pwptr, plen);
5182 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
5183 return FALSE;
5184 return TRUE;
5187 /******************************************************************************
5188 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5190 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
5192 ULONG len;
5193 WCHAR *wptr, *wstr;
5195 if (SDRevision != SDDL_REVISION_1)
5197 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
5198 SetLastError(ERROR_UNKNOWN_REVISION);
5199 return FALSE;
5202 len = 0;
5203 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5204 if (!DumpOwner(SecurityDescriptor, NULL, &len))
5205 return FALSE;
5206 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5207 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5208 return FALSE;
5209 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5210 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5211 return FALSE;
5212 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5213 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5214 return FALSE;
5216 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5217 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5218 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5219 LocalFree (wstr);
5220 return FALSE;
5222 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5223 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5224 LocalFree (wstr);
5225 return FALSE;
5227 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5228 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5229 LocalFree (wstr);
5230 return FALSE;
5232 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5233 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5234 LocalFree (wstr);
5235 return FALSE;
5237 *wptr = 0;
5239 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5240 *OutputString = wstr;
5241 if (OutputLen)
5242 *OutputLen = strlenW(*OutputString)+1;
5243 return TRUE;
5246 /******************************************************************************
5247 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5249 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5251 LPWSTR wstr;
5252 ULONG len;
5253 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5255 int lenA;
5257 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5258 *OutputString = heap_alloc(lenA);
5259 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5260 LocalFree(wstr);
5262 if (OutputLen != NULL)
5263 *OutputLen = lenA;
5264 return TRUE;
5266 else
5268 *OutputString = NULL;
5269 if (OutputLen)
5270 *OutputLen = 0;
5271 return FALSE;
5275 /******************************************************************************
5276 * ConvertStringSidToSidW [ADVAPI32.@]
5278 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5280 BOOL bret = FALSE;
5281 DWORD cBytes;
5283 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5284 if (GetVersion() & 0x80000000)
5285 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5286 else if (!StringSid || !Sid)
5287 SetLastError(ERROR_INVALID_PARAMETER);
5288 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5290 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5292 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5293 if (!bret)
5294 LocalFree(*Sid);
5296 return bret;
5299 /******************************************************************************
5300 * ConvertStringSidToSidA [ADVAPI32.@]
5302 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5304 BOOL bret = FALSE;
5306 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5307 if (GetVersion() & 0x80000000)
5308 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5309 else if (!StringSid || !Sid)
5310 SetLastError(ERROR_INVALID_PARAMETER);
5311 else
5313 WCHAR *wStringSid = SERV_dup(StringSid);
5314 bret = ConvertStringSidToSidW(wStringSid, Sid);
5315 heap_free(wStringSid);
5317 return bret;
5320 /******************************************************************************
5321 * ConvertSidToStringSidW [ADVAPI32.@]
5323 * format of SID string is:
5324 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5325 * where
5326 * <rev> is the revision of the SID encoded as decimal
5327 * <auth> is the identifier authority encoded as hex
5328 * <subauthN> is the subauthority id encoded as decimal
5330 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5332 DWORD len = 0;
5333 LPWSTR wstr, wptr;
5335 TRACE("%p %p\n", pSid, pstr );
5337 len = 0;
5338 if (!DumpSidNumeric(pSid, NULL, &len))
5339 return FALSE;
5340 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5341 DumpSidNumeric(pSid, &wptr, NULL);
5342 *wptr = 0;
5344 *pstr = wstr;
5345 return TRUE;
5348 /******************************************************************************
5349 * ConvertSidToStringSidA [ADVAPI32.@]
5351 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5353 LPWSTR wstr = NULL;
5354 LPSTR str;
5355 UINT len;
5357 TRACE("%p %p\n", pSid, pstr );
5359 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5360 return FALSE;
5362 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5363 str = LocalAlloc( 0, len );
5364 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5365 LocalFree( wstr );
5367 *pstr = str;
5369 return TRUE;
5372 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5373 PSECURITY_DESCRIPTOR pdesc,
5374 PSECURITY_DESCRIPTOR cdesc,
5375 PSECURITY_DESCRIPTOR* ndesc,
5376 GUID* objtype,
5377 BOOL isdir,
5378 PGENERIC_MAPPING genmap )
5380 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5382 return FALSE;
5385 BOOL WINAPI CreatePrivateObjectSecurityEx(
5386 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5387 GUID *objtype, BOOL is_directory, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5389 SECURITY_DESCRIPTOR_RELATIVE *relative;
5390 DWORD needed, offset;
5391 BYTE *buffer;
5393 FIXME("%p %p %p %p %d %u %p %p - returns fake SECURITY_DESCRIPTOR\n", parent, creator, out,
5394 objtype, is_directory, flags, token, mapping);
5396 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5397 needed += sizeof(sidWorld);
5398 needed += sizeof(sidWorld);
5399 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5400 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5402 if (!(buffer = heap_alloc( needed ))) return FALSE;
5403 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5404 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5406 heap_free( buffer );
5407 return FALSE;
5409 relative->Control |= SE_SELF_RELATIVE;
5410 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5412 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5413 relative->Owner = offset;
5414 offset += sizeof(sidWorld);
5416 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5417 relative->Group = offset;
5418 offset += sizeof(sidWorld);
5420 GetWorldAccessACL( (ACL *)(buffer + offset) );
5421 relative->Dacl = offset;
5422 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5424 GetWorldAccessACL( (ACL *)(buffer + offset) );
5425 relative->Sacl = offset;
5427 *out = relative;
5428 return TRUE;
5431 BOOL WINAPI CreatePrivateObjectSecurity(
5432 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5433 BOOL is_container, HANDLE token, PGENERIC_MAPPING mapping)
5435 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, 0, token, mapping);
5438 BOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(
5439 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5440 GUID **types, ULONG count, BOOL is_container, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5442 FIXME(": semi-stub\n");
5443 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, flags, token, mapping);
5446 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5448 FIXME("%p - stub\n", ObjectDescriptor);
5450 heap_free( *ObjectDescriptor );
5451 return TRUE;
5454 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserA(
5455 HANDLE hToken,
5456 LPCSTR lpApplicationName,
5457 LPSTR lpCommandLine,
5458 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5459 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5460 BOOL bInheritHandles,
5461 DWORD dwCreationFlags,
5462 LPVOID lpEnvironment,
5463 LPCSTR lpCurrentDirectory,
5464 LPSTARTUPINFOA lpStartupInfo,
5465 LPPROCESS_INFORMATION lpProcessInformation )
5467 BOOL ret;
5468 WCHAR *appW, *cmdlnW, *cwdW;
5469 STARTUPINFOW sinfo;
5471 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
5472 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5473 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5475 appW = SERV_dup(lpApplicationName);
5476 cmdlnW = SERV_dup(lpCommandLine);
5477 cwdW = SERV_dup(lpCurrentDirectory);
5478 sinfo.cb = sizeof(sinfo);
5479 sinfo.lpReserved = SERV_dup(lpStartupInfo->lpReserved);
5480 sinfo.lpDesktop = SERV_dup(lpStartupInfo->lpDesktop);
5481 sinfo.lpTitle = SERV_dup(lpStartupInfo->lpTitle);
5482 sinfo.dwX = lpStartupInfo->dwX;
5483 sinfo.dwY = lpStartupInfo->dwY;
5484 sinfo.dwXSize = lpStartupInfo->dwXSize;
5485 sinfo.dwYSize = lpStartupInfo->dwYSize;
5486 sinfo.dwXCountChars = lpStartupInfo->dwXCountChars;
5487 sinfo.dwYCountChars = lpStartupInfo->dwYCountChars;
5488 sinfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
5489 sinfo.dwFlags = lpStartupInfo->dwFlags;
5490 sinfo.wShowWindow = lpStartupInfo->wShowWindow;
5491 sinfo.cbReserved2 = lpStartupInfo->cbReserved2;
5492 sinfo.lpReserved2 = lpStartupInfo->lpReserved2;
5493 sinfo.hStdInput = lpStartupInfo->hStdInput;
5494 sinfo.hStdOutput = lpStartupInfo->hStdOutput;
5495 sinfo.hStdError = lpStartupInfo->hStdError;
5496 ret = CreateProcessAsUserW(hToken, appW, cmdlnW, lpProcessAttributes,
5497 lpThreadAttributes, bInheritHandles, dwCreationFlags,
5498 lpEnvironment, cwdW, &sinfo, lpProcessInformation);
5499 heap_free(appW);
5500 heap_free(cmdlnW);
5501 heap_free(cwdW);
5502 heap_free(sinfo.lpReserved);
5503 heap_free(sinfo.lpDesktop);
5504 heap_free(sinfo.lpTitle);
5506 return ret;
5509 BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(
5510 HANDLE hToken,
5511 LPCWSTR lpApplicationName,
5512 LPWSTR lpCommandLine,
5513 LPSECURITY_ATTRIBUTES lpProcessAttributes,
5514 LPSECURITY_ATTRIBUTES lpThreadAttributes,
5515 BOOL bInheritHandles,
5516 DWORD dwCreationFlags,
5517 LPVOID lpEnvironment,
5518 LPCWSTR lpCurrentDirectory,
5519 LPSTARTUPINFOW lpStartupInfo,
5520 LPPROCESS_INFORMATION lpProcessInformation )
5522 FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi-stub\n", hToken,
5523 debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5524 lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
5525 debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5527 /* We should create the process with a suspended main thread */
5528 if (!CreateProcessW (lpApplicationName,
5529 lpCommandLine,
5530 lpProcessAttributes,
5531 lpThreadAttributes,
5532 bInheritHandles,
5533 dwCreationFlags, /* CREATE_SUSPENDED */
5534 lpEnvironment,
5535 lpCurrentDirectory,
5536 lpStartupInfo,
5537 lpProcessInformation))
5539 return FALSE;
5542 return TRUE;
5545 /******************************************************************************
5546 * CreateProcessWithLogonW
5548 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5549 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5550 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5552 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5553 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5554 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5555 lpStartupInfo, lpProcessInformation);
5557 return FALSE;
5560 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5561 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5562 PROCESS_INFORMATION *process_information )
5564 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5565 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5566 creation_flags, environment, debugstr_w(current_directory),
5567 startup_info, process_information);
5569 /* FIXME: check if handles should be inherited */
5570 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5571 current_directory, startup_info, process_information );
5574 /******************************************************************************
5575 * DuplicateTokenEx [ADVAPI32.@]
5577 BOOL WINAPI DuplicateTokenEx(
5578 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5579 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5580 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5581 TOKEN_TYPE TokenType,
5582 PHANDLE DuplicateTokenHandle )
5584 OBJECT_ATTRIBUTES ObjectAttributes;
5586 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5587 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5589 InitializeObjectAttributes(
5590 &ObjectAttributes,
5591 NULL,
5592 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5593 NULL,
5594 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5596 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5597 dwDesiredAccess,
5598 &ObjectAttributes,
5599 ImpersonationLevel,
5600 TokenType,
5601 DuplicateTokenHandle ) );
5604 BOOL WINAPI DuplicateToken(
5605 HANDLE ExistingTokenHandle,
5606 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5607 PHANDLE DuplicateTokenHandle )
5609 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5610 NULL, ImpersonationLevel, TokenImpersonation,
5611 DuplicateTokenHandle );
5614 /******************************************************************************
5615 * ComputeStringSidSize
5617 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5619 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5621 int ctok = 0;
5622 while (*StringSid)
5624 if (*StringSid == '-')
5625 ctok++;
5626 StringSid++;
5629 if (ctok >= 3)
5630 return GetSidLengthRequired(ctok - 2);
5632 else /* String constant format - Only available in winxp and above */
5634 unsigned int i;
5636 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5637 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5638 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5640 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5641 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5643 MAX_SID local;
5644 ADVAPI_GetComputerSid(&local);
5645 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5650 return GetSidLengthRequired(0);
5653 /******************************************************************************
5654 * ParseStringSidToSid
5656 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5658 BOOL bret = FALSE;
5659 SID* pisid=pSid;
5661 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5662 if (!StringSid)
5664 SetLastError(ERROR_INVALID_PARAMETER);
5665 TRACE("StringSid is NULL, returning FALSE\n");
5666 return FALSE;
5669 while (*StringSid == ' ')
5670 StringSid++;
5672 *cBytes = ComputeStringSidSize(StringSid);
5673 if (!pisid) /* Simply compute the size */
5675 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5676 return TRUE;
5679 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5681 DWORD i = 0, identAuth;
5682 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5684 StringSid += 2; /* Advance to Revision */
5685 pisid->Revision = atoiW(StringSid);
5687 if (pisid->Revision != SDDL_REVISION)
5689 TRACE("Revision %d is unknown\n", pisid->Revision);
5690 goto lend; /* ERROR_INVALID_SID */
5692 if (csubauth == 0)
5694 TRACE("SubAuthorityCount is 0\n");
5695 goto lend; /* ERROR_INVALID_SID */
5698 pisid->SubAuthorityCount = csubauth;
5700 /* Advance to identifier authority */
5701 while (*StringSid && *StringSid != '-')
5702 StringSid++;
5703 if (*StringSid == '-')
5704 StringSid++;
5706 /* MS' implementation can't handle values greater than 2^32 - 1, so
5707 * we don't either; assume most significant bytes are always 0
5709 pisid->IdentifierAuthority.Value[0] = 0;
5710 pisid->IdentifierAuthority.Value[1] = 0;
5711 identAuth = atoiW(StringSid);
5712 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5713 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5714 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5715 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5717 /* Advance to first sub authority */
5718 while (*StringSid && *StringSid != '-')
5719 StringSid++;
5720 if (*StringSid == '-')
5721 StringSid++;
5723 while (*StringSid)
5725 pisid->SubAuthority[i++] = atoiW(StringSid);
5727 while (*StringSid && *StringSid != '-')
5728 StringSid++;
5729 if (*StringSid == '-')
5730 StringSid++;
5733 if (i != pisid->SubAuthorityCount)
5734 goto lend; /* ERROR_INVALID_SID */
5736 bret = TRUE;
5738 else /* String constant format - Only available in winxp and above */
5740 unsigned int i;
5741 pisid->Revision = SDDL_REVISION;
5743 for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5744 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5746 DWORD j;
5747 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5748 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5749 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5750 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5751 bret = TRUE;
5754 for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
5755 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5757 ADVAPI_GetComputerSid(pisid);
5758 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5759 pisid->SubAuthorityCount++;
5760 bret = TRUE;
5763 if (!bret)
5764 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5767 lend:
5768 if (!bret)
5769 SetLastError(ERROR_INVALID_SID);
5771 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5772 return bret;
5775 /******************************************************************************
5776 * GetNamedSecurityInfoA [ADVAPI32.@]
5778 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5779 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5780 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5781 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5783 LPWSTR wstr;
5784 DWORD r;
5786 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5787 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5789 wstr = SERV_dup(pObjectName);
5790 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5791 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5793 heap_free( wstr );
5795 return r;
5798 /******************************************************************************
5799 * GetNamedSecurityInfoW [ADVAPI32.@]
5801 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5802 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5803 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5805 DWORD access = 0;
5806 HANDLE handle;
5807 DWORD err;
5809 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5810 group, dacl, sacl, descriptor );
5812 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5813 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5815 /* If no descriptor, we have to check that there's a pointer for the requested information */
5816 if( !descriptor && (
5817 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5818 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5819 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5820 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5821 return ERROR_INVALID_PARAMETER;
5823 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5824 access |= READ_CONTROL;
5825 if (info & SACL_SECURITY_INFORMATION)
5826 access |= ACCESS_SYSTEM_SECURITY;
5828 switch (type)
5830 case SE_SERVICE:
5831 if (!(err = get_security_service( name, access, &handle )))
5833 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5834 CloseServiceHandle( handle );
5836 break;
5837 case SE_REGISTRY_KEY:
5838 if (!(err = get_security_regkey( name, access, &handle )))
5840 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5841 RegCloseKey( handle );
5843 break;
5844 case SE_FILE_OBJECT:
5845 if (!(err = get_security_file( name, access, &handle )))
5847 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5848 CloseHandle( handle );
5850 break;
5851 default:
5852 FIXME( "Object type %d is not currently supported.\n", type );
5853 if (owner) *owner = NULL;
5854 if (group) *group = NULL;
5855 if (dacl) *dacl = NULL;
5856 if (sacl) *sacl = NULL;
5857 if (descriptor) *descriptor = NULL;
5858 return ERROR_SUCCESS;
5860 return err;
5863 /******************************************************************************
5864 * GetNamedSecurityInfoExW [ADVAPI32.@]
5866 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5867 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5868 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5870 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5871 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5872 return ERROR_CALL_NOT_IMPLEMENTED;
5875 /******************************************************************************
5876 * GetNamedSecurityInfoExA [ADVAPI32.@]
5878 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5879 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5880 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5882 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5883 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5884 return ERROR_CALL_NOT_IMPLEMENTED;
5887 /******************************************************************************
5888 * DecryptFileW [ADVAPI32.@]
5890 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5892 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5893 return TRUE;
5896 /******************************************************************************
5897 * DecryptFileA [ADVAPI32.@]
5899 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5901 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5902 return TRUE;
5905 /******************************************************************************
5906 * EncryptFileW [ADVAPI32.@]
5908 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5910 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5911 return TRUE;
5914 /******************************************************************************
5915 * EncryptFileA [ADVAPI32.@]
5917 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5919 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5920 return TRUE;
5923 /******************************************************************************
5924 * FileEncryptionStatusW [ADVAPI32.@]
5926 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5928 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5929 if (!lpStatus)
5930 return FALSE;
5931 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5932 return TRUE;
5935 /******************************************************************************
5936 * FileEncryptionStatusA [ADVAPI32.@]
5938 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5940 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5941 if (!lpStatus)
5942 return FALSE;
5943 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5944 return TRUE;
5947 /******************************************************************************
5948 * SetSecurityInfo [ADVAPI32.@]
5950 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5951 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5952 PSID psidGroup, PACL pDacl, PACL pSacl)
5954 SECURITY_DESCRIPTOR sd;
5955 PACL dacl = pDacl;
5956 NTSTATUS status;
5958 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5959 return ERROR_INVALID_SECURITY_DESCR;
5961 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5962 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5963 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5964 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5965 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5967 if (ObjectType == SE_FILE_OBJECT && pDacl)
5969 SECURITY_DESCRIPTOR_CONTROL control;
5970 PSECURITY_DESCRIPTOR psd;
5971 OBJECT_NAME_INFORMATION *name_info;
5972 DWORD size, rev;
5974 status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
5975 if (status != STATUS_BUFFER_TOO_SMALL)
5976 return RtlNtStatusToDosError(status);
5978 psd = heap_alloc(size);
5979 if (!psd)
5980 return ERROR_NOT_ENOUGH_MEMORY;
5982 status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
5983 if (status)
5985 heap_free(psd);
5986 return RtlNtStatusToDosError(status);
5989 status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
5990 heap_free(psd);
5991 if (status)
5992 return RtlNtStatusToDosError(status);
5993 /* TODO: copy some control flags to new sd */
5995 /* inherit parent directory DACL */
5996 if (!(control & SE_DACL_PROTECTED))
5998 status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
5999 if (status != STATUS_INFO_LENGTH_MISMATCH)
6000 return RtlNtStatusToDosError(status);
6002 name_info = heap_alloc(size);
6003 if (!name_info)
6004 return ERROR_NOT_ENOUGH_MEMORY;
6006 status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
6007 if (status)
6009 heap_free(name_info);
6010 return RtlNtStatusToDosError(status);
6013 for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
6014 if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
6015 name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
6016 break;
6017 if (name_info->Name.Length)
6019 OBJECT_ATTRIBUTES attr;
6020 IO_STATUS_BLOCK io;
6021 HANDLE parent;
6022 PSECURITY_DESCRIPTOR parent_sd;
6023 ACL *parent_dacl;
6024 DWORD err = ERROR_ACCESS_DENIED;
6026 name_info->Name.Buffer[name_info->Name.Length/2] = 0;
6028 attr.Length = sizeof(attr);
6029 attr.RootDirectory = 0;
6030 attr.Attributes = 0;
6031 attr.ObjectName = &name_info->Name;
6032 attr.SecurityDescriptor = NULL;
6033 status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
6034 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6035 FILE_OPEN_FOR_BACKUP_INTENT);
6036 heap_free(name_info);
6037 if (!status)
6039 err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
6040 NULL, NULL, &parent_dacl, NULL, &parent_sd);
6041 CloseHandle(parent);
6044 if (!err)
6046 int i;
6048 dacl = heap_alloc_zero(pDacl->AclSize+parent_dacl->AclSize);
6049 if (!dacl)
6051 LocalFree(parent_sd);
6052 return ERROR_NOT_ENOUGH_MEMORY;
6054 memcpy(dacl, pDacl, pDacl->AclSize);
6055 dacl->AclSize = pDacl->AclSize+parent_dacl->AclSize;
6057 for (i=0; i<parent_dacl->AceCount; i++)
6059 ACE_HEADER *ace;
6061 if (!GetAce(parent_dacl, i, (void*)&ace))
6062 continue;
6063 if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
6064 continue;
6065 if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
6066 (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
6068 FIXME("unsupported flags: %x\n", ace->AceFlags);
6069 continue;
6072 if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
6073 ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
6074 ace->AceFlags &= ~INHERIT_ONLY_ACE;
6075 ace->AceFlags |= INHERITED_ACE;
6077 if(!AddAce(dacl, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
6078 WARN("error adding inherited ACE\n");
6080 LocalFree(parent_sd);
6083 else
6084 heap_free(name_info);
6088 SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
6090 if (SecurityInfo & SACL_SECURITY_INFORMATION)
6091 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
6093 switch (ObjectType)
6095 case SE_SERVICE:
6096 FIXME("stub: Service objects are not supported at this time.\n");
6097 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
6098 break;
6099 default:
6100 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
6101 break;
6103 if (dacl != pDacl)
6104 heap_free(dacl);
6105 return RtlNtStatusToDosError(status);
6108 /******************************************************************************
6109 * SaferCreateLevel [ADVAPI32.@]
6111 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
6112 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
6114 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
6116 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6117 return TRUE;
6120 /******************************************************************************
6121 * SaferComputeTokenFromLevel [ADVAPI32.@]
6123 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
6124 DWORD flags, LPVOID reserved)
6126 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
6128 *access_token = (HANDLE)0xdeadbeef;
6129 return TRUE;
6132 /******************************************************************************
6133 * SaferCloseLevel [ADVAPI32.@]
6135 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
6137 FIXME("(%p) stub\n", handle);
6138 return TRUE;
6141 /******************************************************************************
6142 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
6144 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
6145 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
6146 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
6147 BOOL KeepExplicit, FN_PROGRESS fnProgress,
6148 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
6150 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
6151 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
6152 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
6154 return ERROR_SUCCESS;
6157 /******************************************************************************
6158 * SaferGetPolicyInformation [ADVAPI32.@]
6160 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
6161 PVOID buffer, PDWORD required, LPVOID lpReserved)
6163 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
6164 return FALSE;
6167 /******************************************************************************
6168 * SaferSetLevelInformation [ADVAPI32.@]
6170 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
6171 LPVOID buffer, DWORD size)
6173 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
6174 return FALSE;
6177 /******************************************************************************
6178 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
6180 DWORD WINAPI LookupSecurityDescriptorPartsA(TRUSTEEA *owner, TRUSTEEA *group, ULONG *access_count,
6181 EXPLICIT_ACCESSA *access_list, ULONG *audit_count,
6182 EXPLICIT_ACCESSA *audit_list, SECURITY_DESCRIPTOR *descriptor)
6184 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6185 access_list, audit_count, audit_list, descriptor);
6186 return ERROR_CALL_NOT_IMPLEMENTED;
6189 /******************************************************************************
6190 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
6192 DWORD WINAPI LookupSecurityDescriptorPartsW(TRUSTEEW *owner, TRUSTEEW *group, ULONG *access_count,
6193 EXPLICIT_ACCESSW *access_list, ULONG *audit_count,
6194 EXPLICIT_ACCESSW *audit_list, SECURITY_DESCRIPTOR *descriptor)
6196 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6197 access_list, audit_count, audit_list, descriptor);
6198 return ERROR_CALL_NOT_IMPLEMENTED;