wined3d: Drop support for WINED3DFMT_D32_UNORM.
[wine.git] / dlls / advapi32 / security.c
blob2030ebf638b40c85b1d7208ecf03150cd7b7801b
1 /*
2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
24 #include <stdarg.h>
25 #include <string.h>
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "winreg.h"
33 #include "winsafer.h"
34 #include "winternl.h"
35 #include "winioctl.h"
36 #include "accctrl.h"
37 #include "sddl.h"
38 #include "winsvc.h"
39 #include "aclapi.h"
40 #include "objbase.h"
41 #include "iads.h"
42 #include "advapi32_misc.h"
43 #include "lmcons.h"
45 #include "wine/debug.h"
46 #include "wine/unicode.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
50 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
51 static DWORD trustee_to_sid(DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee);
53 typedef struct _ACEFLAG
55 LPCWSTR wstr;
56 DWORD value;
57 } ACEFLAG, *LPACEFLAG;
59 typedef struct _MAX_SID
61 /* same fields as struct _SID */
62 BYTE Revision;
63 BYTE SubAuthorityCount;
64 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
65 DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
66 } MAX_SID;
68 typedef struct WELLKNOWNSID
70 WCHAR wstr[2];
71 WELL_KNOWN_SID_TYPE Type;
72 MAX_SID Sid;
73 } WELLKNOWNSID;
75 static const WELLKNOWNSID WellKnownSids[] =
77 { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
78 { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
79 { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
80 { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
81 { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
82 { {'O','W'}, WinCreatorOwnerRightsSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RIGHTS_RID } } },
83 { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
84 { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
85 { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
86 { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
87 { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
88 { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
89 { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
90 { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
91 { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
92 { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
93 { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
94 { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
95 { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
96 { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
97 { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
98 { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
99 { {0,0}, WinLogonIdsSid, { SID_REVISION, SECURITY_LOGON_IDS_RID_COUNT, { SECURITY_NT_AUTHORITY }, { SECURITY_LOGON_IDS_RID } } },
100 { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
101 { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
102 { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
103 { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
104 { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
105 { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
106 { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
107 { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
108 { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
109 { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
110 { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
111 { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
112 { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
113 { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
114 { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
115 { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
116 { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
117 { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
118 { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
119 { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
120 { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
121 { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
122 { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
123 { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
124 { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
125 { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
126 { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
127 { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
128 { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
129 { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
130 { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
131 { {'A','C'}, WinBuiltinAnyPackageSid, { SID_REVISION, 2, { SECURITY_APP_PACKAGE_AUTHORITY }, { SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE } } },
134 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
135 typedef struct WELLKNOWNRID
137 WCHAR wstr[2];
138 WELL_KNOWN_SID_TYPE Type;
139 DWORD Rid;
140 } WELLKNOWNRID;
142 static const WELLKNOWNRID WellKnownRids[] = {
143 { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
144 { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
145 { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
146 { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
147 { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
148 { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
149 { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
150 { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
151 { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
152 { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
153 { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
154 { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
155 { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
159 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
161 typedef struct _AccountSid {
162 WELL_KNOWN_SID_TYPE type;
163 LPCWSTR account;
164 LPCWSTR domain;
165 SID_NAME_USE name_use;
166 LPCWSTR alias;
167 } AccountSid;
169 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
170 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
171 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
172 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 };
173 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
174 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 };
175 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
176 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
177 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
178 static const WCHAR Blank[] = { 0 };
179 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
180 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
181 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
182 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 };
183 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
184 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 };
185 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
186 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
187 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 };
188 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
189 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
190 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
191 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
192 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
193 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
194 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 };
195 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
196 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 };
197 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
198 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
199 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
200 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
201 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
202 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
203 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
204 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 };
205 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
207 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
208 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
209 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
210 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
211 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
212 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 };
213 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 };
214 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
215 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 };
216 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
217 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
218 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
219 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 };
220 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 };
221 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
222 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
223 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 };
224 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
225 static const WCHAR SELF[] = { 'S','E','L','F',0 };
226 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
227 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
228 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
229 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 };
230 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
231 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
233 static const AccountSid ACCOUNT_SIDS[] = {
234 { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
235 { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
236 { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
237 { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
238 { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
239 { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
240 { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
241 { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
242 { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
243 { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
244 { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
245 { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
246 { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
247 { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
248 { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
249 { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
250 { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
251 { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
252 { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
253 { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
254 { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
255 { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
256 { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
257 { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
258 { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
259 { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
260 { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
261 { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
262 { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
263 { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
264 { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
265 { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
266 { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
267 { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
268 { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
269 { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
270 { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
271 { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
272 { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
273 { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
274 { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
275 { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
276 { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
277 { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
278 { WinBuiltinAnyPackageSid, ALL_APPLICATION_PACKAGES, APPLICATION_PACKAGE_AUTHORITY, SidTypeWellKnownGroup },
281 * ACE access rights
283 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
284 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
285 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
286 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
288 static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
289 static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
290 static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
291 static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
292 static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
293 static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
294 static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
295 static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
296 static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
298 static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
299 static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
300 static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
301 static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
303 static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
304 static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
305 static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
306 static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
308 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
309 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
310 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
311 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
313 static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0};
314 static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0};
315 static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0};
318 * ACL flags
320 static const WCHAR SDDL_PROTECTED[] = {'P',0};
321 static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
322 static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
325 * ACE types
327 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
328 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
329 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
330 static const WCHAR SDDL_ALARM[] = {'A','L',0};
331 static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0};
334 * ACE flags
336 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
337 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
338 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
339 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
340 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
341 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
342 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
344 const char * debugstr_sid(PSID sid)
346 int auth = 0;
347 SID * psid = sid;
349 if (psid == NULL)
350 return "(null)";
352 auth = psid->IdentifierAuthority.Value[5] +
353 (psid->IdentifierAuthority.Value[4] << 8) +
354 (psid->IdentifierAuthority.Value[3] << 16) +
355 (psid->IdentifierAuthority.Value[2] << 24);
357 switch (psid->SubAuthorityCount) {
358 case 0:
359 return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
360 case 1:
361 return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
362 psid->SubAuthority[0]);
363 case 2:
364 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
365 psid->SubAuthority[0], psid->SubAuthority[1]);
366 case 3:
367 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
368 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
369 case 4:
370 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
371 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
372 psid->SubAuthority[3]);
373 case 5:
374 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
375 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
376 psid->SubAuthority[3], psid->SubAuthority[4]);
377 case 6:
378 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
379 psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
380 psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
381 case 7:
382 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
383 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
384 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
385 psid->SubAuthority[6]);
386 case 8:
387 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
388 psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
389 psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
390 psid->SubAuthority[6], psid->SubAuthority[7]);
392 return "(too-big)";
395 /* set last error code from NT status and get the proper boolean return value */
396 /* used for functions that are a simple wrapper around the corresponding ntdll API */
397 static inline BOOL set_ntstatus( NTSTATUS status )
399 if (status) SetLastError( RtlNtStatusToDosError( status ));
400 return !status;
403 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
404 static inline DWORD get_security_file( LPCWSTR full_file_name, DWORD access, HANDLE *file )
406 UNICODE_STRING file_nameW;
407 OBJECT_ATTRIBUTES attr;
408 IO_STATUS_BLOCK io;
409 NTSTATUS status;
411 if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
412 return ERROR_PATH_NOT_FOUND;
413 attr.Length = sizeof(attr);
414 attr.RootDirectory = 0;
415 attr.Attributes = OBJ_CASE_INSENSITIVE;
416 attr.ObjectName = &file_nameW;
417 attr.SecurityDescriptor = NULL;
418 status = NtCreateFile( file, access|SYNCHRONIZE, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
419 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
420 FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
421 RtlFreeUnicodeString( &file_nameW );
422 return RtlNtStatusToDosError( status );
425 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
426 static inline DWORD get_security_service( LPWSTR full_service_name, DWORD access, HANDLE *service )
428 SC_HANDLE manager = 0;
429 DWORD err;
431 err = SERV_OpenSCManagerW( NULL, NULL, access, (SC_HANDLE *)&manager );
432 if (err == ERROR_SUCCESS)
434 err = SERV_OpenServiceW( manager, full_service_name, access, (SC_HANDLE *)service );
435 CloseServiceHandle( manager );
437 return err;
440 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
441 static inline DWORD get_security_regkey( LPWSTR full_key_name, DWORD access, HANDLE *key )
443 static const WCHAR classes_rootW[] = {'C','L','A','S','S','E','S','_','R','O','O','T',0};
444 static const WCHAR current_userW[] = {'C','U','R','R','E','N','T','_','U','S','E','R',0};
445 static const WCHAR machineW[] = {'M','A','C','H','I','N','E',0};
446 static const WCHAR usersW[] = {'U','S','E','R','S',0};
447 LPWSTR p = strchrW(full_key_name, '\\');
448 int len = p-full_key_name;
449 HKEY hParent;
451 if (!p) return ERROR_INVALID_PARAMETER;
452 if (strncmpW( full_key_name, classes_rootW, len ) == 0)
453 hParent = HKEY_CLASSES_ROOT;
454 else if (strncmpW( full_key_name, current_userW, len ) == 0)
455 hParent = HKEY_CURRENT_USER;
456 else if (strncmpW( full_key_name, machineW, len ) == 0)
457 hParent = HKEY_LOCAL_MACHINE;
458 else if (strncmpW( full_key_name, usersW, len ) == 0)
459 hParent = HKEY_USERS;
460 else
461 return ERROR_INVALID_PARAMETER;
462 return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
465 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
467 static void GetWorldAccessACL(PACL pACL)
469 PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
471 pACL->AclRevision = ACL_REVISION;
472 pACL->Sbz1 = 0;
473 pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
474 pACL->AceCount = 1;
475 pACL->Sbz2 = 0;
477 pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
478 pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
479 pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
480 pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
481 memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
484 /************************************************************
485 * ADVAPI_IsLocalComputer
487 * Checks whether the server name indicates local machine.
489 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
491 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
492 BOOL Result;
493 LPWSTR buf;
495 if (!ServerName || !ServerName[0])
496 return TRUE;
498 buf = heap_alloc(dwSize * sizeof(WCHAR));
499 Result = GetComputerNameW(buf, &dwSize);
500 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
501 ServerName += 2;
502 Result = Result && !lstrcmpW(ServerName, buf);
503 heap_free(buf);
505 return Result;
508 /************************************************************
509 * ADVAPI_GetComputerSid
511 BOOL ADVAPI_GetComputerSid(PSID sid)
513 static const struct /* same fields as struct SID */
515 BYTE Revision;
516 BYTE SubAuthorityCount;
517 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
518 DWORD SubAuthority[4];
519 } computer_sid =
520 { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
522 memcpy( sid, &computer_sid, sizeof(computer_sid) );
523 return TRUE;
526 /* ##############################
527 ###### TOKEN FUNCTIONS ######
528 ##############################
531 /******************************************************************************
532 * OpenProcessToken [ADVAPI32.@]
533 * Opens the access token associated with a process handle.
535 * PARAMS
536 * ProcessHandle [I] Handle to process
537 * DesiredAccess [I] Desired access to process
538 * TokenHandle [O] Pointer to handle of open access token
540 * RETURNS
541 * Success: TRUE. TokenHandle contains the access token.
542 * Failure: FALSE.
544 * NOTES
545 * See NtOpenProcessToken.
547 BOOL WINAPI
548 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
549 HANDLE *TokenHandle )
551 return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
554 /******************************************************************************
555 * OpenThreadToken [ADVAPI32.@]
557 * Opens the access token associated with a thread handle.
559 * PARAMS
560 * ThreadHandle [I] Handle to process
561 * DesiredAccess [I] Desired access to the thread
562 * OpenAsSelf [I] ???
563 * TokenHandle [O] Destination for the token handle
565 * RETURNS
566 * Success: TRUE. TokenHandle contains the access token.
567 * Failure: FALSE.
569 * NOTES
570 * See NtOpenThreadToken.
572 BOOL WINAPI
573 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
574 BOOL OpenAsSelf, HANDLE *TokenHandle)
576 return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
579 BOOL WINAPI
580 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
581 DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
583 return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
584 PreviousState, ReturnLength));
587 /******************************************************************************
588 * AdjustTokenPrivileges [ADVAPI32.@]
590 * Adjust the privileges of an open token handle.
592 * PARAMS
593 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
594 * DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
595 * NewState [I] Desired new privileges of the token
596 * BufferLength [I] Length of NewState
597 * PreviousState [O] Destination for the previous state
598 * ReturnLength [I/O] Size of PreviousState
601 * RETURNS
602 * Success: TRUE. Privileges are set to NewState and PreviousState is updated.
603 * Failure: FALSE.
605 * NOTES
606 * See NtAdjustPrivilegesToken.
608 BOOL WINAPI
609 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
610 PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
611 PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
613 NTSTATUS status;
615 TRACE("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
616 PreviousState, ReturnLength);
618 status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
619 NewState, BufferLength, PreviousState,
620 ReturnLength);
621 SetLastError( RtlNtStatusToDosError( status ));
622 if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
623 return TRUE;
624 else
625 return FALSE;
628 /******************************************************************************
629 * CheckTokenMembership [ADVAPI32.@]
631 * Determine if an access token is a member of a SID.
633 * PARAMS
634 * TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
635 * SidToCheck [I] SID that possibly contains the token
636 * IsMember [O] Destination for result.
638 * RETURNS
639 * Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
640 * Failure: FALSE.
642 BOOL WINAPI
643 CheckTokenMembership( HANDLE token, PSID sid_to_check,
644 PBOOL is_member )
646 PTOKEN_GROUPS token_groups = NULL;
647 HANDLE thread_token = NULL;
648 DWORD size, i;
649 BOOL ret;
651 TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
653 *is_member = FALSE;
655 if (!token)
657 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
659 HANDLE process_token;
660 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
661 if (!ret)
662 goto exit;
663 ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
664 NULL, SecurityImpersonation, TokenImpersonation,
665 &thread_token);
666 CloseHandle(process_token);
667 if (!ret)
668 goto exit;
670 token = thread_token;
672 else
674 TOKEN_TYPE type;
676 ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
677 if (!ret) goto exit;
679 if (type == TokenPrimary)
681 SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
682 return FALSE;
686 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
687 if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
688 goto exit;
690 token_groups = heap_alloc(size);
691 if (!token_groups)
693 ret = FALSE;
694 goto exit;
697 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
698 if (!ret)
699 goto exit;
701 for (i = 0; i < token_groups->GroupCount; i++)
703 TRACE("Groups[%d]: {0x%x, %s}\n", i,
704 token_groups->Groups[i].Attributes,
705 debugstr_sid(token_groups->Groups[i].Sid));
706 if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
707 EqualSid(sid_to_check, token_groups->Groups[i].Sid))
709 *is_member = TRUE;
710 TRACE("sid enabled and found in token\n");
711 break;
715 exit:
716 heap_free(token_groups);
717 if (thread_token != NULL) CloseHandle(thread_token);
719 return ret;
722 /******************************************************************************
723 * GetTokenInformation [ADVAPI32.@]
725 * Get a type of information about an access token.
727 * PARAMS
728 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
729 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
730 * tokeninfo [O] Destination for token information
731 * tokeninfolength [I] Length of tokeninfo
732 * retlen [O] Destination for returned token information length
734 * RETURNS
735 * Success: TRUE. tokeninfo contains retlen bytes of token information
736 * Failure: FALSE.
738 * NOTES
739 * See NtQueryInformationToken.
741 BOOL WINAPI
742 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
743 LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
745 TRACE("(%p, %s, %p, %d, %p):\n",
746 token,
747 (tokeninfoclass == TokenUser) ? "TokenUser" :
748 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
749 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
750 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
751 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
752 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
753 (tokeninfoclass == TokenSource) ? "TokenSource" :
754 (tokeninfoclass == TokenType) ? "TokenType" :
755 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
756 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
757 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
758 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
759 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
760 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
761 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
762 "Unknown",
763 tokeninfo, tokeninfolength, retlen);
764 return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
765 tokeninfolength, retlen));
768 /******************************************************************************
769 * SetTokenInformation [ADVAPI32.@]
771 * Set information for an access token.
773 * PARAMS
774 * token [I] Handle from OpenProcessToken() or OpenThreadToken()
775 * tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
776 * tokeninfo [I] Token information to set
777 * tokeninfolength [I] Length of tokeninfo
779 * RETURNS
780 * Success: TRUE. The information for the token is set to tokeninfo.
781 * Failure: FALSE.
783 BOOL WINAPI
784 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
785 LPVOID tokeninfo, DWORD tokeninfolength )
787 TRACE("(%p, %s, %p, %d)\n",
788 token,
789 (tokeninfoclass == TokenUser) ? "TokenUser" :
790 (tokeninfoclass == TokenGroups) ? "TokenGroups" :
791 (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
792 (tokeninfoclass == TokenOwner) ? "TokenOwner" :
793 (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
794 (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
795 (tokeninfoclass == TokenSource) ? "TokenSource" :
796 (tokeninfoclass == TokenType) ? "TokenType" :
797 (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
798 (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
799 (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
800 (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
801 (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
802 (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
803 (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
804 "Unknown",
805 tokeninfo, tokeninfolength);
807 return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
810 /*************************************************************************
811 * SetThreadToken [ADVAPI32.@]
813 * Assigns an 'impersonation token' to a thread so it can assume the
814 * security privileges of another thread or process. Can also remove
815 * a previously assigned token.
817 * PARAMS
818 * thread [O] Handle to thread to set the token for
819 * token [I] Token to set
821 * RETURNS
822 * Success: TRUE. The threads access token is set to token
823 * Failure: FALSE.
825 * NOTES
826 * Only supported on NT or higher. On Win9X this function does nothing.
827 * See SetTokenInformation.
829 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
831 return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
832 ThreadImpersonationToken, &token, sizeof token ));
835 /*************************************************************************
836 * CreateRestrictedToken [ADVAPI32.@]
838 * Create a new more restricted token from an existing token.
840 * PARAMS
841 * baseToken [I] Token to base the new restricted token on
842 * flags [I] Options
843 * nDisableSids [I] Length of disableSids array
844 * disableSids [I] Array of SIDs to disable in the new token
845 * nDeletePrivs [I] Length of deletePrivs array
846 * deletePrivs [I] Array of privileges to delete in the new token
847 * nRestrictSids [I] Length of restrictSids array
848 * restrictSids [I] Array of SIDs to restrict in the new token
849 * newToken [O] Address where the new token is stored
851 * RETURNS
852 * Success: TRUE
853 * Failure: FALSE
855 BOOL WINAPI CreateRestrictedToken(
856 HANDLE baseToken,
857 DWORD flags,
858 DWORD nDisableSids,
859 PSID_AND_ATTRIBUTES disableSids,
860 DWORD nDeletePrivs,
861 PLUID_AND_ATTRIBUTES deletePrivs,
862 DWORD nRestrictSids,
863 PSID_AND_ATTRIBUTES restrictSids,
864 PHANDLE newToken)
866 TOKEN_TYPE type;
867 SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
868 DWORD size;
870 FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
871 baseToken, flags, nDisableSids, disableSids,
872 nDeletePrivs, deletePrivs,
873 nRestrictSids, restrictSids,
874 newToken);
876 size = sizeof(type);
877 if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
878 if (type == TokenImpersonation)
880 size = sizeof(level);
881 if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
882 return FALSE;
884 return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
887 /* ##############################
888 ###### SID FUNCTIONS ######
889 ##############################
892 /******************************************************************************
893 * AllocateAndInitializeSid [ADVAPI32.@]
895 * PARAMS
896 * pIdentifierAuthority []
897 * nSubAuthorityCount []
898 * nSubAuthority0 []
899 * nSubAuthority1 []
900 * nSubAuthority2 []
901 * nSubAuthority3 []
902 * nSubAuthority4 []
903 * nSubAuthority5 []
904 * nSubAuthority6 []
905 * nSubAuthority7 []
906 * pSid []
908 BOOL WINAPI
909 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
910 BYTE nSubAuthorityCount,
911 DWORD nSubAuthority0, DWORD nSubAuthority1,
912 DWORD nSubAuthority2, DWORD nSubAuthority3,
913 DWORD nSubAuthority4, DWORD nSubAuthority5,
914 DWORD nSubAuthority6, DWORD nSubAuthority7,
915 PSID *pSid )
917 return set_ntstatus( RtlAllocateAndInitializeSid(
918 pIdentifierAuthority, nSubAuthorityCount,
919 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
920 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
921 pSid ));
924 /******************************************************************************
925 * FreeSid [ADVAPI32.@]
927 * PARAMS
928 * pSid []
930 PVOID WINAPI
931 FreeSid( PSID pSid )
933 RtlFreeSid(pSid);
934 return NULL; /* is documented like this */
937 /******************************************************************************
938 * CopySid [ADVAPI32.@]
940 * PARAMS
941 * nDestinationSidLength []
942 * pDestinationSid []
943 * pSourceSid []
945 BOOL WINAPI
946 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
948 return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
951 /******************************************************************************
952 * CreateWellKnownSid [ADVAPI32.@]
954 BOOL WINAPI
955 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
956 PSID DomainSid,
957 PSID pSid,
958 DWORD* cbSid)
960 unsigned int i;
961 TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
963 if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
965 SetLastError(ERROR_INVALID_PARAMETER);
966 return FALSE;
969 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++) {
970 if (WellKnownSids[i].Type == WellKnownSidType) {
971 DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
973 if (*cbSid < length)
975 *cbSid = length;
976 SetLastError(ERROR_INSUFFICIENT_BUFFER);
977 return FALSE;
979 if (!pSid)
981 SetLastError(ERROR_INVALID_PARAMETER);
982 return FALSE;
984 CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
985 *cbSid = length;
986 return TRUE;
990 if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
992 SetLastError(ERROR_INVALID_PARAMETER);
993 return FALSE;
996 for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
997 if (WellKnownRids[i].Type == WellKnownSidType) {
998 UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
999 DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
1000 DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
1002 if (*cbSid < output_sid_length)
1004 *cbSid = output_sid_length;
1005 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1006 return FALSE;
1008 if (!pSid)
1010 SetLastError(ERROR_INVALID_PARAMETER);
1011 return FALSE;
1013 CopyMemory(pSid, DomainSid, domain_sid_length);
1014 (*GetSidSubAuthorityCount(pSid))++;
1015 (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
1016 *cbSid = output_sid_length;
1017 return TRUE;
1020 SetLastError(ERROR_INVALID_PARAMETER);
1021 return FALSE;
1024 /******************************************************************************
1025 * IsWellKnownSid [ADVAPI32.@]
1027 BOOL WINAPI
1028 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
1030 unsigned int i;
1031 TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
1033 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
1034 if (WellKnownSids[i].Type == WellKnownSidType)
1035 if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
1036 return TRUE;
1038 return FALSE;
1041 BOOL WINAPI
1042 IsTokenRestricted( HANDLE TokenHandle )
1044 TOKEN_GROUPS *groups;
1045 DWORD size;
1046 NTSTATUS status;
1047 BOOL restricted;
1049 TRACE("(%p)\n", TokenHandle);
1051 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
1052 if (status != STATUS_BUFFER_TOO_SMALL)
1053 return FALSE;
1055 groups = heap_alloc(size);
1056 if (!groups)
1058 SetLastError(ERROR_OUTOFMEMORY);
1059 return FALSE;
1062 status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
1063 if (status != STATUS_SUCCESS)
1065 heap_free(groups);
1066 return set_ntstatus(status);
1069 restricted = groups->GroupCount > 0;
1070 heap_free(groups);
1072 return restricted;
1075 /******************************************************************************
1076 * IsValidSid [ADVAPI32.@]
1078 * PARAMS
1079 * pSid []
1081 BOOL WINAPI
1082 IsValidSid( PSID pSid )
1084 return RtlValidSid( pSid );
1087 /******************************************************************************
1088 * EqualSid [ADVAPI32.@]
1090 * PARAMS
1091 * pSid1 []
1092 * pSid2 []
1094 BOOL WINAPI
1095 EqualSid( PSID pSid1, PSID pSid2 )
1097 BOOL ret = RtlEqualSid( pSid1, pSid2 );
1098 SetLastError(ERROR_SUCCESS);
1099 return ret;
1102 /******************************************************************************
1103 * EqualPrefixSid [ADVAPI32.@]
1105 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1107 return RtlEqualPrefixSid(pSid1, pSid2);
1110 /******************************************************************************
1111 * GetSidLengthRequired [ADVAPI32.@]
1113 * PARAMS
1114 * nSubAuthorityCount []
1116 DWORD WINAPI
1117 GetSidLengthRequired( BYTE nSubAuthorityCount )
1119 return RtlLengthRequiredSid(nSubAuthorityCount);
1122 /******************************************************************************
1123 * InitializeSid [ADVAPI32.@]
1125 * PARAMS
1126 * pIdentifierAuthority []
1128 BOOL WINAPI
1129 InitializeSid (
1130 PSID pSid,
1131 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1132 BYTE nSubAuthorityCount)
1134 return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1137 DWORD WINAPI
1138 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1140 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1142 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1143 return 0;
1146 DWORD WINAPI
1147 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1149 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1151 return 1;
1154 /******************************************************************************
1155 * GetSidIdentifierAuthority [ADVAPI32.@]
1157 * PARAMS
1158 * pSid []
1160 PSID_IDENTIFIER_AUTHORITY WINAPI
1161 GetSidIdentifierAuthority( PSID pSid )
1163 SetLastError(ERROR_SUCCESS);
1164 return RtlIdentifierAuthoritySid(pSid);
1167 /******************************************************************************
1168 * GetSidSubAuthority [ADVAPI32.@]
1170 * PARAMS
1171 * pSid []
1172 * nSubAuthority []
1174 PDWORD WINAPI
1175 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1177 SetLastError(ERROR_SUCCESS);
1178 return RtlSubAuthoritySid(pSid, nSubAuthority);
1181 /******************************************************************************
1182 * GetSidSubAuthorityCount [ADVAPI32.@]
1184 * PARAMS
1185 * pSid []
1187 PUCHAR WINAPI
1188 GetSidSubAuthorityCount (PSID pSid)
1190 SetLastError(ERROR_SUCCESS);
1191 return RtlSubAuthorityCountSid(pSid);
1194 /******************************************************************************
1195 * GetLengthSid [ADVAPI32.@]
1197 * PARAMS
1198 * pSid []
1200 DWORD WINAPI
1201 GetLengthSid (PSID pSid)
1203 return RtlLengthSid(pSid);
1206 /* ##############################################
1207 ###### SECURITY DESCRIPTOR FUNCTIONS ######
1208 ##############################################
1211 /******************************************************************************
1212 * BuildSecurityDescriptorA [ADVAPI32.@]
1214 * Builds a SD from
1216 * PARAMS
1217 * pOwner [I]
1218 * pGroup [I]
1219 * cCountOfAccessEntries [I]
1220 * pListOfAccessEntries [I]
1221 * cCountOfAuditEntries [I]
1222 * pListofAuditEntries [I]
1223 * pOldSD [I]
1224 * lpdwBufferLength [I/O]
1225 * pNewSD [O]
1227 * RETURNS
1228 * Success: ERROR_SUCCESS
1229 * Failure: nonzero error code from Winerror.h
1231 DWORD WINAPI BuildSecurityDescriptorA(
1232 IN PTRUSTEEA pOwner,
1233 IN PTRUSTEEA pGroup,
1234 IN ULONG cCountOfAccessEntries,
1235 IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1236 IN ULONG cCountOfAuditEntries,
1237 IN PEXPLICIT_ACCESSA pListofAuditEntries,
1238 IN PSECURITY_DESCRIPTOR pOldSD,
1239 IN OUT PULONG lpdwBufferLength,
1240 OUT PSECURITY_DESCRIPTOR* pNewSD)
1242 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1243 cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1244 pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1246 return ERROR_CALL_NOT_IMPLEMENTED;
1249 /******************************************************************************
1250 * BuildSecurityDescriptorW [ADVAPI32.@]
1252 * See BuildSecurityDescriptorA.
1254 DWORD WINAPI BuildSecurityDescriptorW(
1255 IN PTRUSTEEW pOwner,
1256 IN PTRUSTEEW pGroup,
1257 IN ULONG cCountOfAccessEntries,
1258 IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1259 IN ULONG cCountOfAuditEntries,
1260 IN PEXPLICIT_ACCESSW pListOfAuditEntries,
1261 IN PSECURITY_DESCRIPTOR pOldSD,
1262 IN OUT PULONG lpdwBufferLength,
1263 OUT PSECURITY_DESCRIPTOR* pNewSD)
1265 SECURITY_DESCRIPTOR desc;
1266 NTSTATUS status;
1267 DWORD ret = ERROR_SUCCESS;
1269 TRACE("(%p,%p,%d,%p,%d,%p,%p,%p,%p)\n", pOwner, pGroup,
1270 cCountOfAccessEntries, pListOfAccessEntries, cCountOfAuditEntries,
1271 pListOfAuditEntries, pOldSD, lpdwBufferLength, pNewSD);
1273 if (pOldSD)
1275 SECURITY_DESCRIPTOR_CONTROL control;
1276 DWORD desc_size, dacl_size = 0, sacl_size = 0, owner_size = 0, group_size = 0;
1277 PACL dacl = NULL, sacl = NULL;
1278 PSID owner = NULL, group = NULL;
1279 DWORD revision;
1281 if ((status = RtlGetControlSecurityDescriptor( pOldSD, &control, &revision )) != STATUS_SUCCESS)
1282 return RtlNtStatusToDosError( status );
1283 if (!(control & SE_SELF_RELATIVE))
1284 return ERROR_INVALID_SECURITY_DESCR;
1286 desc_size = sizeof(desc);
1287 status = RtlSelfRelativeToAbsoluteSD( pOldSD, &desc, &desc_size, dacl, &dacl_size, sacl, &sacl_size,
1288 owner, &owner_size, group, &group_size );
1289 if (status == STATUS_BUFFER_TOO_SMALL)
1291 if (dacl_size)
1292 dacl = LocalAlloc( LMEM_FIXED, dacl_size );
1293 if (sacl_size)
1294 sacl = LocalAlloc( LMEM_FIXED, sacl_size );
1295 if (owner_size)
1296 owner = LocalAlloc( LMEM_FIXED, owner_size );
1297 if (group_size)
1298 group = LocalAlloc( LMEM_FIXED, group_size );
1300 desc_size = sizeof(desc);
1301 status = RtlSelfRelativeToAbsoluteSD( pOldSD, &desc, &desc_size, dacl, &dacl_size, sacl, &sacl_size,
1302 owner, &owner_size, group, &group_size );
1304 if (status != STATUS_SUCCESS)
1306 LocalFree( dacl );
1307 LocalFree( sacl );
1308 LocalFree( owner );
1309 LocalFree( group );
1310 return RtlNtStatusToDosError( status );
1313 else
1315 if ((status = RtlCreateSecurityDescriptor( &desc, SECURITY_DESCRIPTOR_REVISION )) != STATUS_SUCCESS)
1316 return RtlNtStatusToDosError( status );
1319 if (pOwner)
1321 LocalFree( desc.Owner );
1322 desc.Owner = LocalAlloc( LMEM_FIXED, sizeof(MAX_SID) );
1323 if ((ret = trustee_to_sid( sizeof(MAX_SID), desc.Owner, pOwner )))
1324 goto done;
1327 if (pGroup)
1329 LocalFree( desc.Group );
1330 desc.Group = LocalAlloc( LMEM_FIXED, sizeof(MAX_SID) );
1331 if ((ret = trustee_to_sid( sizeof(MAX_SID), desc.Group, pGroup )))
1332 goto done;
1335 if (pListOfAccessEntries)
1337 PACL new_dacl;
1339 if ((ret = SetEntriesInAclW( cCountOfAccessEntries, pListOfAccessEntries, desc.Dacl, &new_dacl )))
1340 goto done;
1342 LocalFree( desc.Dacl );
1343 desc.Dacl = new_dacl;
1344 desc.Control |= SE_DACL_PRESENT;
1347 if (pListOfAuditEntries)
1349 PACL new_sacl;
1351 if ((ret = SetEntriesInAclW( cCountOfAuditEntries, pListOfAuditEntries, desc.Sacl, &new_sacl )))
1352 goto done;
1354 LocalFree( desc.Sacl );
1355 desc.Sacl = new_sacl;
1356 desc.Control |= SE_SACL_PRESENT;
1359 *lpdwBufferLength = RtlLengthSecurityDescriptor( &desc );
1360 *pNewSD = LocalAlloc( LMEM_FIXED, *lpdwBufferLength );
1362 if ((status = RtlMakeSelfRelativeSD( &desc, *pNewSD, lpdwBufferLength )) != STATUS_SUCCESS)
1364 ret = RtlNtStatusToDosError( status );
1365 LocalFree( *pNewSD );
1366 *pNewSD = NULL;
1369 done:
1370 /* free absolute descriptor */
1371 LocalFree( desc.Owner );
1372 LocalFree( desc.Group );
1373 LocalFree( desc.Sacl );
1374 LocalFree( desc.Dacl );
1375 return ret;
1378 /******************************************************************************
1379 * InitializeSecurityDescriptor [ADVAPI32.@]
1381 * PARAMS
1382 * pDescr []
1383 * revision []
1385 BOOL WINAPI
1386 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1388 return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1392 /******************************************************************************
1393 * MakeAbsoluteSD [ADVAPI32.@]
1395 BOOL WINAPI MakeAbsoluteSD (
1396 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1397 OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1398 OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1399 OUT PACL pDacl,
1400 OUT LPDWORD lpdwDaclSize,
1401 OUT PACL pSacl,
1402 OUT LPDWORD lpdwSaclSize,
1403 OUT PSID pOwner,
1404 OUT LPDWORD lpdwOwnerSize,
1405 OUT PSID pPrimaryGroup,
1406 OUT LPDWORD lpdwPrimaryGroupSize)
1408 return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1409 pAbsoluteSecurityDescriptor,
1410 lpdwAbsoluteSecurityDescriptorSize,
1411 pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1412 pOwner, lpdwOwnerSize,
1413 pPrimaryGroup, lpdwPrimaryGroupSize));
1416 /******************************************************************************
1417 * GetKernelObjectSecurity [ADVAPI32.@]
1419 BOOL WINAPI GetKernelObjectSecurity(
1420 HANDLE Handle,
1421 SECURITY_INFORMATION RequestedInformation,
1422 PSECURITY_DESCRIPTOR pSecurityDescriptor,
1423 DWORD nLength,
1424 LPDWORD lpnLengthNeeded )
1426 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1427 pSecurityDescriptor, nLength, lpnLengthNeeded);
1429 return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1430 nLength, lpnLengthNeeded ));
1433 /******************************************************************************
1434 * GetPrivateObjectSecurity [ADVAPI32.@]
1436 BOOL WINAPI GetPrivateObjectSecurity(
1437 PSECURITY_DESCRIPTOR ObjectDescriptor,
1438 SECURITY_INFORMATION SecurityInformation,
1439 PSECURITY_DESCRIPTOR ResultantDescriptor,
1440 DWORD DescriptorLength,
1441 PDWORD ReturnLength )
1443 SECURITY_DESCRIPTOR desc;
1444 BOOL defaulted, present;
1445 PACL pacl;
1446 PSID psid;
1448 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1449 ResultantDescriptor, DescriptorLength, ReturnLength);
1451 if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1452 return FALSE;
1454 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1456 if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1457 return FALSE;
1458 SetSecurityDescriptorOwner(&desc, psid, defaulted);
1461 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1463 if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1464 return FALSE;
1465 SetSecurityDescriptorGroup(&desc, psid, defaulted);
1468 if (SecurityInformation & DACL_SECURITY_INFORMATION)
1470 if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1471 return FALSE;
1472 SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1475 if (SecurityInformation & SACL_SECURITY_INFORMATION)
1477 if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1478 return FALSE;
1479 SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1482 *ReturnLength = DescriptorLength;
1483 return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1486 /******************************************************************************
1487 * GetSecurityDescriptorLength [ADVAPI32.@]
1489 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1491 return RtlLengthSecurityDescriptor(pDescr);
1494 /******************************************************************************
1495 * GetSecurityDescriptorOwner [ADVAPI32.@]
1497 * PARAMS
1498 * pOwner []
1499 * lpbOwnerDefaulted []
1501 BOOL WINAPI
1502 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1503 LPBOOL lpbOwnerDefaulted )
1505 BOOLEAN defaulted;
1506 BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1507 *lpbOwnerDefaulted = defaulted;
1508 return ret;
1511 /******************************************************************************
1512 * SetSecurityDescriptorOwner [ADVAPI32.@]
1514 * PARAMS
1516 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1517 PSID pOwner, BOOL bOwnerDefaulted)
1519 return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1521 /******************************************************************************
1522 * GetSecurityDescriptorGroup [ADVAPI32.@]
1524 BOOL WINAPI GetSecurityDescriptorGroup(
1525 PSECURITY_DESCRIPTOR SecurityDescriptor,
1526 PSID *Group,
1527 LPBOOL GroupDefaulted)
1529 BOOLEAN defaulted;
1530 BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1531 *GroupDefaulted = defaulted;
1532 return ret;
1534 /******************************************************************************
1535 * SetSecurityDescriptorGroup [ADVAPI32.@]
1537 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1538 PSID Group, BOOL GroupDefaulted)
1540 return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1543 /******************************************************************************
1544 * IsValidSecurityDescriptor [ADVAPI32.@]
1546 * PARAMS
1547 * lpsecdesc []
1549 BOOL WINAPI
1550 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1552 return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1555 /******************************************************************************
1556 * GetSecurityDescriptorDacl [ADVAPI32.@]
1558 BOOL WINAPI GetSecurityDescriptorDacl(
1559 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1560 OUT LPBOOL lpbDaclPresent,
1561 OUT PACL *pDacl,
1562 OUT LPBOOL lpbDaclDefaulted)
1564 BOOLEAN present, defaulted;
1565 BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1566 *lpbDaclPresent = present;
1567 *lpbDaclDefaulted = defaulted;
1568 return ret;
1571 /******************************************************************************
1572 * SetSecurityDescriptorDacl [ADVAPI32.@]
1574 BOOL WINAPI
1575 SetSecurityDescriptorDacl (
1576 PSECURITY_DESCRIPTOR lpsd,
1577 BOOL daclpresent,
1578 PACL dacl,
1579 BOOL dacldefaulted )
1581 return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1583 /******************************************************************************
1584 * GetSecurityDescriptorSacl [ADVAPI32.@]
1586 BOOL WINAPI GetSecurityDescriptorSacl(
1587 IN PSECURITY_DESCRIPTOR lpsd,
1588 OUT LPBOOL lpbSaclPresent,
1589 OUT PACL *pSacl,
1590 OUT LPBOOL lpbSaclDefaulted)
1592 BOOLEAN present, defaulted;
1593 BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1594 *lpbSaclPresent = present;
1595 *lpbSaclDefaulted = defaulted;
1596 return ret;
1599 /**************************************************************************
1600 * SetSecurityDescriptorSacl [ADVAPI32.@]
1602 BOOL WINAPI SetSecurityDescriptorSacl (
1603 PSECURITY_DESCRIPTOR lpsd,
1604 BOOL saclpresent,
1605 PACL lpsacl,
1606 BOOL sacldefaulted)
1608 return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1610 /******************************************************************************
1611 * MakeSelfRelativeSD [ADVAPI32.@]
1613 * PARAMS
1614 * lpabssecdesc []
1615 * lpselfsecdesc []
1616 * lpbuflen []
1618 BOOL WINAPI
1619 MakeSelfRelativeSD(
1620 IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1621 IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1622 IN OUT LPDWORD lpdwBufferLength)
1624 return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1625 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1628 /******************************************************************************
1629 * GetSecurityDescriptorControl [ADVAPI32.@]
1632 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1633 PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1635 return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1638 /******************************************************************************
1639 * SetSecurityDescriptorControl [ADVAPI32.@]
1641 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1642 SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1643 SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1645 return set_ntstatus( RtlSetControlSecurityDescriptor(
1646 pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1649 /******************************************************************************
1650 * GetWindowsAccountDomainSid [ADVAPI32.@]
1652 BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
1654 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
1655 DWORD required_size;
1656 int i;
1658 FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
1660 if (!sid || !IsValidSid( sid ))
1662 SetLastError( ERROR_INVALID_SID );
1663 return FALSE;
1666 if (!size)
1668 SetLastError( ERROR_INVALID_PARAMETER );
1669 return FALSE;
1672 if (*GetSidSubAuthorityCount( sid ) < 4)
1674 SetLastError( ERROR_INVALID_SID );
1675 return FALSE;
1678 required_size = GetSidLengthRequired( 4 );
1679 if (*size < required_size || !domain_sid)
1681 *size = required_size;
1682 SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
1683 ERROR_INVALID_PARAMETER );
1684 return FALSE;
1687 InitializeSid( domain_sid, &domain_ident, 4 );
1688 for (i = 0; i < 4; i++)
1689 *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
1691 *size = required_size;
1692 return TRUE;
1695 /* ##############################
1696 ###### ACL FUNCTIONS ######
1697 ##############################
1700 /*************************************************************************
1701 * InitializeAcl [ADVAPI32.@]
1703 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1705 return set_ntstatus( RtlCreateAcl(acl, size, rev));
1708 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1710 IO_STATUS_BLOCK io_block;
1712 TRACE("(%p)\n", hNamedPipe);
1714 return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1715 &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1718 /******************************************************************************
1719 * AddAccessAllowedAce [ADVAPI32.@]
1721 BOOL WINAPI AddAccessAllowedAce(
1722 IN OUT PACL pAcl,
1723 IN DWORD dwAceRevision,
1724 IN DWORD AccessMask,
1725 IN PSID pSid)
1727 return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1730 /******************************************************************************
1731 * AddAccessAllowedAceEx [ADVAPI32.@]
1733 BOOL WINAPI AddAccessAllowedAceEx(
1734 IN OUT PACL pAcl,
1735 IN DWORD dwAceRevision,
1736 IN DWORD AceFlags,
1737 IN DWORD AccessMask,
1738 IN PSID pSid)
1740 return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1743 /******************************************************************************
1744 * AddAccessAllowedObjectAce [ADVAPI32.@]
1746 BOOL WINAPI AddAccessAllowedObjectAce(
1747 IN OUT PACL pAcl,
1748 IN DWORD dwAceRevision,
1749 IN DWORD dwAceFlags,
1750 IN DWORD dwAccessMask,
1751 IN GUID* pObjectTypeGuid,
1752 IN GUID* pInheritedObjectTypeGuid,
1753 IN PSID pSid)
1755 return set_ntstatus(RtlAddAccessAllowedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1756 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid));
1759 /******************************************************************************
1760 * AddAccessDeniedAce [ADVAPI32.@]
1762 BOOL WINAPI AddAccessDeniedAce(
1763 IN OUT PACL pAcl,
1764 IN DWORD dwAceRevision,
1765 IN DWORD AccessMask,
1766 IN PSID pSid)
1768 return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1771 /******************************************************************************
1772 * AddAccessDeniedAceEx [ADVAPI32.@]
1774 BOOL WINAPI AddAccessDeniedAceEx(
1775 IN OUT PACL pAcl,
1776 IN DWORD dwAceRevision,
1777 IN DWORD AceFlags,
1778 IN DWORD AccessMask,
1779 IN PSID pSid)
1781 return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1784 /******************************************************************************
1785 * AddAccessDeniedObjectAce [ADVAPI32.@]
1787 BOOL WINAPI AddAccessDeniedObjectAce(
1788 IN OUT PACL pAcl,
1789 IN DWORD dwAceRevision,
1790 IN DWORD dwAceFlags,
1791 IN DWORD dwAccessMask,
1792 IN GUID* pObjectTypeGuid,
1793 IN GUID* pInheritedObjectTypeGuid,
1794 IN PSID pSid)
1796 return set_ntstatus( RtlAddAccessDeniedObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
1797 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid) );
1800 /******************************************************************************
1801 * AddAce [ADVAPI32.@]
1803 BOOL WINAPI AddAce(
1804 IN OUT PACL pAcl,
1805 IN DWORD dwAceRevision,
1806 IN DWORD dwStartingAceIndex,
1807 LPVOID pAceList,
1808 DWORD nAceListLength)
1810 return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1813 /******************************************************************************
1814 * AddMandatoryAce [ADVAPI32.@]
1816 BOOL WINAPI AddMandatoryAce(ACL *acl, DWORD ace_revision, DWORD ace_flags, DWORD mandatory_policy, PSID label_sid)
1818 return set_ntstatus(RtlAddMandatoryAce(acl, ace_revision, ace_flags, mandatory_policy,
1819 SYSTEM_MANDATORY_LABEL_ACE_TYPE, label_sid));
1822 /******************************************************************************
1823 * DeleteAce [ADVAPI32.@]
1825 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1827 return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1830 /******************************************************************************
1831 * FindFirstFreeAce [ADVAPI32.@]
1833 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1835 return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1838 /******************************************************************************
1839 * GetAce [ADVAPI32.@]
1841 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1843 return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1846 /******************************************************************************
1847 * GetAclInformation [ADVAPI32.@]
1849 BOOL WINAPI GetAclInformation(
1850 PACL pAcl,
1851 LPVOID pAclInformation,
1852 DWORD nAclInformationLength,
1853 ACL_INFORMATION_CLASS dwAclInformationClass)
1855 return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1856 nAclInformationLength, dwAclInformationClass));
1859 /******************************************************************************
1860 * IsValidAcl [ADVAPI32.@]
1862 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1864 return RtlValidAcl(pAcl);
1867 /* ##############################
1868 ###### MISC FUNCTIONS ######
1869 ##############################
1872 /******************************************************************************
1873 * AllocateLocallyUniqueId [ADVAPI32.@]
1875 * PARAMS
1876 * lpLuid []
1878 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1880 return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1883 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1884 { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1885 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1886 { '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 };
1887 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1888 { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1889 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1890 { '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 };
1891 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1892 { '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 };
1893 static const WCHAR SE_TCB_NAME_W[] =
1894 { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1895 static const WCHAR SE_SECURITY_NAME_W[] =
1896 { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1897 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1898 { '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 };
1899 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1900 { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1901 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1902 { '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 };
1903 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1904 { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1905 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1906 { '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 };
1907 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1908 { '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 };
1909 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1910 { '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 };
1911 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1912 { '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 };
1913 static const WCHAR SE_BACKUP_NAME_W[] =
1914 { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1915 static const WCHAR SE_RESTORE_NAME_W[] =
1916 { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1917 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1918 { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1919 static const WCHAR SE_DEBUG_NAME_W[] =
1920 { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1921 static const WCHAR SE_AUDIT_NAME_W[] =
1922 { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1923 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1924 { '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 };
1925 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1926 { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1927 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1928 { '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 };
1929 static const WCHAR SE_UNDOCK_NAME_W[] =
1930 { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1931 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1932 { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1933 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1934 { '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 };
1935 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1936 { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1937 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1938 { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1939 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1940 { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1942 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1944 NULL,
1945 NULL,
1946 SE_CREATE_TOKEN_NAME_W,
1947 SE_ASSIGNPRIMARYTOKEN_NAME_W,
1948 SE_LOCK_MEMORY_NAME_W,
1949 SE_INCREASE_QUOTA_NAME_W,
1950 SE_MACHINE_ACCOUNT_NAME_W,
1951 SE_TCB_NAME_W,
1952 SE_SECURITY_NAME_W,
1953 SE_TAKE_OWNERSHIP_NAME_W,
1954 SE_LOAD_DRIVER_NAME_W,
1955 SE_SYSTEM_PROFILE_NAME_W,
1956 SE_SYSTEMTIME_NAME_W,
1957 SE_PROF_SINGLE_PROCESS_NAME_W,
1958 SE_INC_BASE_PRIORITY_NAME_W,
1959 SE_CREATE_PAGEFILE_NAME_W,
1960 SE_CREATE_PERMANENT_NAME_W,
1961 SE_BACKUP_NAME_W,
1962 SE_RESTORE_NAME_W,
1963 SE_SHUTDOWN_NAME_W,
1964 SE_DEBUG_NAME_W,
1965 SE_AUDIT_NAME_W,
1966 SE_SYSTEM_ENVIRONMENT_NAME_W,
1967 SE_CHANGE_NOTIFY_NAME_W,
1968 SE_REMOTE_SHUTDOWN_NAME_W,
1969 SE_UNDOCK_NAME_W,
1970 SE_SYNC_AGENT_NAME_W,
1971 SE_ENABLE_DELEGATION_NAME_W,
1972 SE_MANAGE_VOLUME_NAME_W,
1973 SE_IMPERSONATE_NAME_W,
1974 SE_CREATE_GLOBAL_NAME_W,
1977 const WCHAR *get_wellknown_privilege_name(const LUID *luid)
1979 if (luid->HighPart || luid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1980 luid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || !WellKnownPrivNames[luid->LowPart])
1981 return NULL;
1983 return WellKnownPrivNames[luid->LowPart];
1986 /******************************************************************************
1987 * LookupPrivilegeValueW [ADVAPI32.@]
1989 * See LookupPrivilegeValueA.
1991 BOOL WINAPI
1992 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1994 UINT i;
1996 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1998 if (!ADVAPI_IsLocalComputer(lpSystemName))
2000 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2001 return FALSE;
2003 if (!lpName)
2005 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
2006 return FALSE;
2008 for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
2010 if( !WellKnownPrivNames[i] )
2011 continue;
2012 if( strcmpiW( WellKnownPrivNames[i], lpName) )
2013 continue;
2014 lpLuid->LowPart = i;
2015 lpLuid->HighPart = 0;
2016 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
2017 lpLuid->HighPart, lpLuid->LowPart );
2018 return TRUE;
2020 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
2021 return FALSE;
2024 /******************************************************************************
2025 * LookupPrivilegeValueA [ADVAPI32.@]
2027 * Retrieves LUID used on a system to represent the privilege name.
2029 * PARAMS
2030 * lpSystemName [I] Name of the system
2031 * lpName [I] Name of the privilege
2032 * lpLuid [O] Destination for the resulting LUID
2034 * RETURNS
2035 * Success: TRUE. lpLuid contains the requested LUID.
2036 * Failure: FALSE.
2038 BOOL WINAPI
2039 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
2041 UNICODE_STRING lpSystemNameW;
2042 UNICODE_STRING lpNameW;
2043 BOOL ret;
2045 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
2046 RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
2047 ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
2048 RtlFreeUnicodeString(&lpNameW);
2049 RtlFreeUnicodeString(&lpSystemNameW);
2050 return ret;
2053 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
2054 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
2056 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
2057 debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
2059 return FALSE;
2062 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
2063 LPDWORD cchDisplayName, LPDWORD lpLanguageId )
2065 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
2066 debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
2068 return FALSE;
2071 /******************************************************************************
2072 * LookupPrivilegeNameA [ADVAPI32.@]
2074 * See LookupPrivilegeNameW.
2076 BOOL WINAPI
2077 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
2078 LPDWORD cchName)
2080 UNICODE_STRING lpSystemNameW;
2081 BOOL ret;
2082 DWORD wLen = 0;
2084 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
2086 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
2087 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
2088 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2090 LPWSTR lpNameW = heap_alloc(wLen * sizeof(WCHAR));
2092 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
2093 &wLen);
2094 if (ret)
2096 /* Windows crashes if cchName is NULL, so will I */
2097 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
2098 *cchName, NULL, NULL);
2100 if (len == 0)
2102 /* WideCharToMultiByte failed */
2103 ret = FALSE;
2105 else if (len > *cchName)
2107 *cchName = len;
2108 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2109 ret = FALSE;
2111 else
2113 /* WideCharToMultiByte succeeded, output length needs to be
2114 * length not including NULL terminator
2116 *cchName = len - 1;
2119 heap_free(lpNameW);
2121 RtlFreeUnicodeString(&lpSystemNameW);
2122 return ret;
2125 /******************************************************************************
2126 * LookupPrivilegeNameW [ADVAPI32.@]
2128 * Retrieves the privilege name referred to by the LUID lpLuid.
2130 * PARAMS
2131 * lpSystemName [I] Name of the system
2132 * lpLuid [I] Privilege value
2133 * lpName [O] Name of the privilege
2134 * cchName [I/O] Number of characters in lpName.
2136 * RETURNS
2137 * Success: TRUE. lpName contains the name of the privilege whose value is
2138 * *lpLuid.
2139 * Failure: FALSE.
2141 * REMARKS
2142 * Only well-known privilege names (those defined in winnt.h) can be retrieved
2143 * using this function.
2144 * If the length of lpName is too small, on return *cchName will contain the
2145 * number of WCHARs needed to contain the privilege, including the NULL
2146 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
2147 * On success, *cchName will contain the number of characters stored in
2148 * lpName, NOT including the NULL terminator.
2150 BOOL WINAPI
2151 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
2152 LPDWORD cchName)
2154 size_t privNameLen;
2156 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
2158 if (!ADVAPI_IsLocalComputer(lpSystemName))
2160 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2161 return FALSE;
2163 if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
2164 lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
2166 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
2167 return FALSE;
2169 privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
2170 /* Windows crashes if cchName is NULL, so will I */
2171 if (*cchName <= privNameLen)
2173 *cchName = privNameLen + 1;
2174 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2175 return FALSE;
2177 else
2179 strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
2180 *cchName = privNameLen;
2181 return TRUE;
2185 /******************************************************************************
2186 * GetFileSecurityA [ADVAPI32.@]
2188 * Obtains Specified information about the security of a file or directory.
2190 * PARAMS
2191 * lpFileName [I] Name of the file to get info for
2192 * RequestedInformation [I] SE_ flags from "winnt.h"
2193 * pSecurityDescriptor [O] Destination for security information
2194 * nLength [I] Length of pSecurityDescriptor
2195 * lpnLengthNeeded [O] Destination for length of returned security information
2197 * RETURNS
2198 * Success: TRUE. pSecurityDescriptor contains the requested information.
2199 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
2201 * NOTES
2202 * The information returned is constrained by the callers access rights and
2203 * privileges.
2205 BOOL WINAPI
2206 GetFileSecurityA( LPCSTR lpFileName,
2207 SECURITY_INFORMATION RequestedInformation,
2208 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2209 DWORD nLength, LPDWORD lpnLengthNeeded )
2211 BOOL r;
2212 LPWSTR name;
2214 name = SERV_dup(lpFileName);
2215 r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
2216 nLength, lpnLengthNeeded );
2217 heap_free( name );
2219 return r;
2222 /******************************************************************************
2223 * GetFileSecurityW [ADVAPI32.@]
2225 * See GetFileSecurityA.
2227 BOOL WINAPI
2228 GetFileSecurityW( LPCWSTR lpFileName,
2229 SECURITY_INFORMATION RequestedInformation,
2230 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2231 DWORD nLength, LPDWORD lpnLengthNeeded )
2233 HANDLE hfile;
2234 NTSTATUS status;
2235 DWORD access = 0, err;
2237 TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
2238 RequestedInformation, pSecurityDescriptor,
2239 nLength, lpnLengthNeeded);
2241 if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
2242 DACL_SECURITY_INFORMATION))
2243 access |= READ_CONTROL;
2244 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2245 access |= ACCESS_SYSTEM_SECURITY;
2247 err = get_security_file( lpFileName, access, &hfile);
2248 if (err)
2250 SetLastError(err);
2251 return FALSE;
2254 status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
2255 nLength, lpnLengthNeeded );
2256 CloseHandle( hfile );
2257 return set_ntstatus( status );
2261 /******************************************************************************
2262 * LookupAccountSidA [ADVAPI32.@]
2264 BOOL WINAPI
2265 LookupAccountSidA(
2266 IN LPCSTR system,
2267 IN PSID sid,
2268 OUT LPSTR account,
2269 IN OUT LPDWORD accountSize,
2270 OUT LPSTR domain,
2271 IN OUT LPDWORD domainSize,
2272 OUT PSID_NAME_USE name_use )
2274 DWORD len;
2275 BOOL r;
2276 LPWSTR systemW;
2277 LPWSTR accountW = NULL;
2278 LPWSTR domainW = NULL;
2279 DWORD accountSizeW = *accountSize;
2280 DWORD domainSizeW = *domainSize;
2282 systemW = SERV_dup(system);
2283 if (account)
2284 accountW = heap_alloc( accountSizeW * sizeof(WCHAR) );
2285 if (domain)
2286 domainW = heap_alloc( domainSizeW * sizeof(WCHAR) );
2288 r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2290 if (r) {
2291 if (accountW && *accountSize) {
2292 len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2293 WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2294 *accountSize = len;
2295 } else
2296 *accountSize = accountSizeW + 1;
2298 if (domainW && *domainSize) {
2299 len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2300 WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2301 *domainSize = len;
2302 } else
2303 *domainSize = domainSizeW + 1;
2305 else
2307 *accountSize = accountSizeW + 1;
2308 *domainSize = domainSizeW + 1;
2311 heap_free( systemW );
2312 heap_free( accountW );
2313 heap_free( domainW );
2315 return r;
2318 /******************************************************************************
2319 * LookupAccountSidLocalA [ADVAPI32.@]
2321 BOOL WINAPI
2322 LookupAccountSidLocalA(
2323 PSID sid,
2324 LPSTR account,
2325 LPDWORD accountSize,
2326 LPSTR domain,
2327 LPDWORD domainSize,
2328 PSID_NAME_USE name_use )
2330 return LookupAccountSidA(NULL, sid, account, accountSize, domain, domainSize, name_use);
2333 /******************************************************************************
2334 * LookupAccountSidW [ADVAPI32.@]
2336 * PARAMS
2337 * system []
2338 * sid []
2339 * account []
2340 * accountSize []
2341 * domain []
2342 * domainSize []
2343 * name_use []
2346 BOOL WINAPI
2347 LookupAccountSidW(
2348 IN LPCWSTR system,
2349 IN PSID sid,
2350 OUT LPWSTR account,
2351 IN OUT LPDWORD accountSize,
2352 OUT LPWSTR domain,
2353 IN OUT LPDWORD domainSize,
2354 OUT PSID_NAME_USE name_use )
2356 unsigned int i, j;
2357 const WCHAR * ac = NULL;
2358 const WCHAR * dm = NULL;
2359 SID_NAME_USE use = 0;
2360 LPWSTR computer_name = NULL;
2361 LPWSTR account_name = NULL;
2363 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2364 debugstr_w(system),debugstr_sid(sid),
2365 account,accountSize,accountSize?*accountSize:0,
2366 domain,domainSize,domainSize?*domainSize:0,
2367 name_use);
2369 if (!ADVAPI_IsLocalComputer(system)) {
2370 FIXME("Only local computer supported!\n");
2371 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2372 return FALSE;
2375 /* check the well known SIDs first */
2376 for (i = 0; i <= WinAccountProtectedUsersSid; i++) {
2377 if (IsWellKnownSid(sid, i)) {
2378 for (j = 0; j < ARRAY_SIZE(ACCOUNT_SIDS); j++) {
2379 if (ACCOUNT_SIDS[j].type == i) {
2380 ac = ACCOUNT_SIDS[j].account;
2381 dm = ACCOUNT_SIDS[j].domain;
2382 use = ACCOUNT_SIDS[j].name_use;
2385 break;
2389 if (dm == NULL) {
2390 MAX_SID local;
2392 /* check for the local computer next */
2393 if (ADVAPI_GetComputerSid(&local)) {
2394 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2395 BOOL result;
2397 computer_name = heap_alloc(size * sizeof(WCHAR));
2398 result = GetComputerNameW(computer_name, &size);
2400 if (result) {
2401 if (EqualSid(sid, &local)) {
2402 dm = computer_name;
2403 ac = Blank;
2404 use = 3;
2405 } else {
2406 local.SubAuthorityCount++;
2408 if (EqualPrefixSid(sid, &local)) {
2409 dm = computer_name;
2410 use = 1;
2411 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2412 case DOMAIN_USER_RID_ADMIN:
2413 ac = Administrator;
2414 break;
2415 case DOMAIN_USER_RID_GUEST:
2416 ac = Guest;
2417 break;
2418 case DOMAIN_GROUP_RID_ADMINS:
2419 ac = Domain_Admins;
2420 break;
2421 case DOMAIN_GROUP_RID_USERS:
2422 ac = Domain_Users;
2423 break;
2424 case DOMAIN_GROUP_RID_GUESTS:
2425 ac = Domain_Guests;
2426 break;
2427 case DOMAIN_GROUP_RID_COMPUTERS:
2428 ac = Domain_Computers;
2429 break;
2430 case DOMAIN_GROUP_RID_CONTROLLERS:
2431 ac = Domain_Controllers;
2432 break;
2433 case DOMAIN_GROUP_RID_CERT_ADMINS:
2434 ac = Cert_Publishers;
2435 break;
2436 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2437 ac = Schema_Admins;
2438 break;
2439 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2440 ac = Enterprise_Admins;
2441 break;
2442 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2443 ac = Group_Policy_Creator_Owners;
2444 break;
2445 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2446 ac = RAS_and_IAS_Servers;
2447 break;
2448 case 1000: /* first user account */
2449 size = UNLEN + 1;
2450 account_name = heap_alloc(size * sizeof(WCHAR));
2451 if (GetUserNameW(account_name, &size))
2452 ac = account_name;
2453 else
2454 dm = NULL;
2456 break;
2457 default:
2458 dm = NULL;
2459 break;
2467 if (dm) {
2468 DWORD ac_len = lstrlenW(ac);
2469 DWORD dm_len = lstrlenW(dm);
2470 BOOL status = TRUE;
2472 if (*accountSize > ac_len) {
2473 if (account)
2474 lstrcpyW(account, ac);
2476 if (*domainSize > dm_len) {
2477 if (domain)
2478 lstrcpyW(domain, dm);
2480 if ((*accountSize && *accountSize < ac_len) ||
2481 (!account && !*accountSize && ac_len) ||
2482 (*domainSize && *domainSize < dm_len) ||
2483 (!domain && !*domainSize && dm_len))
2485 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2486 status = FALSE;
2488 if (*domainSize)
2489 *domainSize = dm_len;
2490 else
2491 *domainSize = dm_len + 1;
2492 if (*accountSize)
2493 *accountSize = ac_len;
2494 else
2495 *accountSize = ac_len + 1;
2497 heap_free(account_name);
2498 heap_free(computer_name);
2499 if (status) *name_use = use;
2500 return status;
2503 heap_free(account_name);
2504 heap_free(computer_name);
2505 SetLastError(ERROR_NONE_MAPPED);
2506 return FALSE;
2509 /******************************************************************************
2510 * LookupAccountSidLocalW [ADVAPI32.@]
2512 BOOL WINAPI
2513 LookupAccountSidLocalW(
2514 PSID sid,
2515 LPWSTR account,
2516 LPDWORD accountSize,
2517 LPWSTR domain,
2518 LPDWORD domainSize,
2519 PSID_NAME_USE name_use )
2521 return LookupAccountSidW(NULL, sid, account, accountSize, domain, domainSize, name_use);
2524 /******************************************************************************
2525 * SetFileSecurityA [ADVAPI32.@]
2527 * See SetFileSecurityW.
2529 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2530 SECURITY_INFORMATION RequestedInformation,
2531 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2533 BOOL r;
2534 LPWSTR name;
2536 name = SERV_dup(lpFileName);
2537 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2538 heap_free( name );
2540 return r;
2543 /******************************************************************************
2544 * SetFileSecurityW [ADVAPI32.@]
2546 * Sets the security of a file or directory.
2548 * PARAMS
2549 * lpFileName []
2550 * RequestedInformation []
2551 * pSecurityDescriptor []
2553 * RETURNS
2554 * Success: TRUE.
2555 * Failure: FALSE.
2557 BOOL WINAPI
2558 SetFileSecurityW( LPCWSTR lpFileName,
2559 SECURITY_INFORMATION RequestedInformation,
2560 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2562 HANDLE file;
2563 DWORD access = 0, err;
2564 NTSTATUS status;
2566 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2567 pSecurityDescriptor );
2569 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2570 RequestedInformation & GROUP_SECURITY_INFORMATION)
2571 access |= WRITE_OWNER;
2572 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2573 access |= ACCESS_SYSTEM_SECURITY;
2574 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2575 access |= WRITE_DAC;
2577 err = get_security_file( lpFileName, access, &file);
2578 if (err)
2580 SetLastError(err);
2581 return FALSE;
2584 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2585 CloseHandle( file );
2586 return set_ntstatus( status );
2589 /******************************************************************************
2590 * QueryWindows31FilesMigration [ADVAPI32.@]
2592 * PARAMS
2593 * x1 []
2595 BOOL WINAPI
2596 QueryWindows31FilesMigration( DWORD x1 )
2598 FIXME("(%d):stub\n",x1);
2599 return TRUE;
2602 /******************************************************************************
2603 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2605 * PARAMS
2606 * x1 []
2607 * x2 []
2608 * x3 []
2609 * x4 []
2611 BOOL WINAPI
2612 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2613 DWORD x4 )
2615 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2616 return TRUE;
2619 /******************************************************************************
2620 * NotifyBootConfigStatus [ADVAPI32.@]
2622 * PARAMS
2623 * x1 []
2625 BOOL WINAPI
2626 NotifyBootConfigStatus( BOOL x1 )
2628 FIXME("(0x%08d):stub\n",x1);
2629 return TRUE;
2632 /******************************************************************************
2633 * RevertToSelf [ADVAPI32.@]
2635 * Ends the impersonation of a user.
2637 * PARAMS
2638 * void []
2640 * RETURNS
2641 * Success: TRUE.
2642 * Failure: FALSE.
2644 BOOL WINAPI
2645 RevertToSelf( void )
2647 HANDLE Token = NULL;
2648 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2649 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2652 /******************************************************************************
2653 * ImpersonateSelf [ADVAPI32.@]
2655 * Makes an impersonation token that represents the process user and assigns
2656 * to the current thread.
2658 * PARAMS
2659 * ImpersonationLevel [I] Level at which to impersonate.
2661 * RETURNS
2662 * Success: TRUE.
2663 * Failure: FALSE.
2665 BOOL WINAPI
2666 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2668 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2671 /******************************************************************************
2672 * ImpersonateLoggedOnUser [ADVAPI32.@]
2674 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2676 DWORD size;
2677 NTSTATUS Status;
2678 HANDLE ImpersonationToken;
2679 TOKEN_TYPE Type;
2680 static BOOL warn = TRUE;
2682 if (warn)
2684 FIXME( "(%p)\n", hToken );
2685 warn = FALSE;
2687 if (!GetTokenInformation( hToken, TokenType, &Type,
2688 sizeof(TOKEN_TYPE), &size ))
2689 return FALSE;
2691 if (Type == TokenPrimary)
2693 OBJECT_ATTRIBUTES ObjectAttributes;
2695 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2697 Status = NtDuplicateToken( hToken,
2698 TOKEN_IMPERSONATE | TOKEN_QUERY,
2699 &ObjectAttributes,
2700 SecurityImpersonation,
2701 TokenImpersonation,
2702 &ImpersonationToken );
2703 if (Status != STATUS_SUCCESS)
2705 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2706 SetLastError( RtlNtStatusToDosError( Status ) );
2707 return FALSE;
2710 else
2711 ImpersonationToken = hToken;
2713 Status = NtSetInformationThread( GetCurrentThread(),
2714 ThreadImpersonationToken,
2715 &ImpersonationToken,
2716 sizeof(ImpersonationToken) );
2718 if (Type == TokenPrimary)
2719 NtClose( ImpersonationToken );
2721 if (Status != STATUS_SUCCESS)
2723 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2724 SetLastError( RtlNtStatusToDosError( Status ) );
2725 return FALSE;
2728 return TRUE;
2731 /******************************************************************************
2732 * ImpersonateAnonymousToken [ADVAPI32.@]
2734 BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
2736 TRACE("(%p)\n", thread);
2737 return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
2740 /******************************************************************************
2741 * AccessCheck [ADVAPI32.@]
2743 BOOL WINAPI
2744 AccessCheck(
2745 PSECURITY_DESCRIPTOR SecurityDescriptor,
2746 HANDLE ClientToken,
2747 DWORD DesiredAccess,
2748 PGENERIC_MAPPING GenericMapping,
2749 PPRIVILEGE_SET PrivilegeSet,
2750 LPDWORD PrivilegeSetLength,
2751 LPDWORD GrantedAccess,
2752 LPBOOL AccessStatus)
2754 NTSTATUS access_status;
2755 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2756 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2757 GrantedAccess, &access_status) );
2758 if (ret) *AccessStatus = set_ntstatus( access_status );
2759 return ret;
2763 /******************************************************************************
2764 * AccessCheckByType [ADVAPI32.@]
2766 BOOL WINAPI AccessCheckByType(
2767 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2768 PSID PrincipalSelfSid,
2769 HANDLE ClientToken,
2770 DWORD DesiredAccess,
2771 POBJECT_TYPE_LIST ObjectTypeList,
2772 DWORD ObjectTypeListLength,
2773 PGENERIC_MAPPING GenericMapping,
2774 PPRIVILEGE_SET PrivilegeSet,
2775 LPDWORD PrivilegeSetLength,
2776 LPDWORD GrantedAccess,
2777 LPBOOL AccessStatus)
2779 FIXME("stub\n");
2781 *AccessStatus = TRUE;
2783 return !*AccessStatus;
2786 /******************************************************************************
2787 * MapGenericMask [ADVAPI32.@]
2789 * Maps generic access rights into specific access rights according to the
2790 * supplied mapping.
2792 * PARAMS
2793 * AccessMask [I/O] Access rights.
2794 * GenericMapping [I] The mapping between generic and specific rights.
2796 * RETURNS
2797 * Nothing.
2799 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2801 RtlMapGenericMask( AccessMask, GenericMapping );
2804 /*************************************************************************
2805 * SetKernelObjectSecurity [ADVAPI32.@]
2807 BOOL WINAPI SetKernelObjectSecurity (
2808 IN HANDLE Handle,
2809 IN SECURITY_INFORMATION SecurityInformation,
2810 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2812 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2816 /******************************************************************************
2817 * AddAuditAccessAce [ADVAPI32.@]
2819 BOOL WINAPI AddAuditAccessAce(
2820 IN OUT PACL pAcl,
2821 IN DWORD dwAceRevision,
2822 IN DWORD dwAccessMask,
2823 IN PSID pSid,
2824 IN BOOL bAuditSuccess,
2825 IN BOOL bAuditFailure)
2827 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2828 bAuditSuccess, bAuditFailure) );
2831 /******************************************************************************
2832 * AddAuditAccessAceEx [ADVAPI32.@]
2834 BOOL WINAPI AddAuditAccessAceEx(
2835 IN OUT PACL pAcl,
2836 IN DWORD dwAceRevision,
2837 IN DWORD dwAceFlags,
2838 IN DWORD dwAccessMask,
2839 IN PSID pSid,
2840 IN BOOL bAuditSuccess,
2841 IN BOOL bAuditFailure)
2843 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2844 bAuditSuccess, bAuditFailure) );
2847 /******************************************************************************
2848 * AddAuditAccessObjectAce [ADVAPI32.@]
2850 BOOL WINAPI AddAuditAccessObjectAce(
2851 IN OUT PACL pAcl,
2852 IN DWORD dwAceRevision,
2853 IN DWORD dwAceFlags,
2854 IN DWORD dwAccessMask,
2855 IN GUID* pObjectTypeGuid,
2856 IN GUID* pInheritedObjectTypeGuid,
2857 IN PSID pSid,
2858 IN BOOL bAuditSuccess,
2859 IN BOOL bAuditFailure)
2861 return set_ntstatus( RtlAddAuditAccessObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
2862 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid, bAuditSuccess, bAuditFailure) );
2865 /******************************************************************************
2866 * LookupAccountNameA [ADVAPI32.@]
2868 BOOL WINAPI
2869 LookupAccountNameA(
2870 IN LPCSTR system,
2871 IN LPCSTR account,
2872 OUT PSID sid,
2873 OUT LPDWORD cbSid,
2874 LPSTR ReferencedDomainName,
2875 IN OUT LPDWORD cbReferencedDomainName,
2876 OUT PSID_NAME_USE name_use )
2878 BOOL ret;
2879 UNICODE_STRING lpSystemW;
2880 UNICODE_STRING lpAccountW;
2881 LPWSTR lpReferencedDomainNameW = NULL;
2883 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2884 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2886 if (ReferencedDomainName)
2887 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2889 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2890 cbReferencedDomainName, name_use);
2892 if (ret && lpReferencedDomainNameW)
2894 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2895 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2898 RtlFreeUnicodeString(&lpSystemW);
2899 RtlFreeUnicodeString(&lpAccountW);
2900 heap_free(lpReferencedDomainNameW);
2902 return ret;
2905 /******************************************************************************
2906 * lookup_user_account_name
2908 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2909 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2911 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2912 DWORD len = sizeof(buffer);
2913 HANDLE token;
2914 BOOL ret;
2915 PSID pSid;
2916 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2917 DWORD nameLen;
2919 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2921 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2922 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2925 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2926 CloseHandle( token );
2928 if (!ret) return FALSE;
2930 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2932 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2933 CopySid(*cbSid, Sid, pSid);
2934 if (*cbSid < GetLengthSid(pSid))
2936 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2937 ret = FALSE;
2939 *cbSid = GetLengthSid(pSid);
2941 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2942 if (!GetComputerNameW(domainName, &nameLen))
2944 domainName[0] = 0;
2945 nameLen = 0;
2947 if (*cchReferencedDomainName <= nameLen || !ret)
2949 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2950 nameLen += 1;
2951 ret = FALSE;
2953 else if (ReferencedDomainName)
2954 strcpyW(ReferencedDomainName, domainName);
2956 *cchReferencedDomainName = nameLen;
2958 if (ret)
2959 *peUse = SidTypeUser;
2961 return ret;
2964 /******************************************************************************
2965 * lookup_computer_account_name
2967 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2968 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2970 MAX_SID local;
2971 BOOL ret;
2972 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2973 DWORD nameLen;
2975 if ((ret = ADVAPI_GetComputerSid(&local)))
2977 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2978 CopySid(*cbSid, Sid, &local);
2979 if (*cbSid < GetLengthSid(&local))
2981 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2982 ret = FALSE;
2984 *cbSid = GetLengthSid(&local);
2987 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2988 if (!GetComputerNameW(domainName, &nameLen))
2990 domainName[0] = 0;
2991 nameLen = 0;
2993 if (*cchReferencedDomainName <= nameLen || !ret)
2995 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2996 nameLen += 1;
2997 ret = FALSE;
2999 else if (ReferencedDomainName)
3000 strcpyW(ReferencedDomainName, domainName);
3002 *cchReferencedDomainName = nameLen;
3004 if (ret)
3005 *peUse = SidTypeDomain;
3007 return ret;
3010 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
3011 LSA_UNICODE_STRING *domain )
3013 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
3015 while (p > str->Buffer && *p != '\\') p--;
3017 if (*p == '\\')
3019 domain->Buffer = str->Buffer;
3020 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
3022 account->Buffer = p + 1;
3023 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
3025 else
3027 domain->Buffer = NULL;
3028 domain->Length = 0;
3030 account->Buffer = str->Buffer;
3031 account->Length = str->Length;
3035 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
3037 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
3039 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
3040 return TRUE;
3042 return FALSE;
3045 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
3047 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
3049 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
3050 return TRUE;
3052 if (ACCOUNT_SIDS[idx].alias)
3054 len = strlenW( ACCOUNT_SIDS[idx].alias );
3055 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
3056 return TRUE;
3058 return FALSE;
3062 * Helper function for LookupAccountNameW
3064 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
3065 PSID Sid, LPDWORD cbSid,
3066 LPWSTR ReferencedDomainName,
3067 LPDWORD cchReferencedDomainName,
3068 PSID_NAME_USE peUse, BOOL *handled )
3070 PSID pSid;
3071 LSA_UNICODE_STRING account, domain;
3072 BOOL ret = TRUE;
3073 ULONG i;
3075 *handled = FALSE;
3076 split_domain_account( account_and_domain, &account, &domain );
3078 for (i = 0; i < ARRAY_SIZE(ACCOUNT_SIDS); i++)
3080 /* check domain first */
3081 if (domain.Buffer && !match_domain( i, &domain )) continue;
3083 if (match_account( i, &account ))
3085 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
3087 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
3089 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
3091 if (*cbSid < sidLen)
3093 SetLastError(ERROR_INSUFFICIENT_BUFFER);
3094 ret = FALSE;
3096 else if (Sid)
3098 CopySid(*cbSid, Sid, pSid);
3100 *cbSid = sidLen;
3103 len = strlenW( ACCOUNT_SIDS[i].domain );
3104 if (*cchReferencedDomainName <= len || !ret)
3106 SetLastError(ERROR_INSUFFICIENT_BUFFER);
3107 len++;
3108 ret = FALSE;
3110 else if (ReferencedDomainName)
3112 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
3115 *cchReferencedDomainName = len;
3116 if (ret)
3117 *peUse = ACCOUNT_SIDS[i].name_use;
3119 heap_free(pSid);
3120 *handled = TRUE;
3121 return ret;
3124 return ret;
3127 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
3128 PSID Sid, LPDWORD cbSid,
3129 LPWSTR ReferencedDomainName,
3130 LPDWORD cchReferencedDomainName,
3131 PSID_NAME_USE peUse, BOOL *handled )
3133 DWORD nameLen;
3134 LPWSTR userName = NULL;
3135 LSA_UNICODE_STRING account, domain;
3136 BOOL ret = TRUE;
3138 *handled = FALSE;
3139 split_domain_account( account_and_domain, &account, &domain );
3141 /* Let the current Unix user id masquerade as first Windows user account */
3143 nameLen = UNLEN + 1;
3144 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
3146 if (domain.Buffer)
3148 /* check to make sure this account is on this computer */
3149 if (GetComputerNameW( userName, &nameLen ) &&
3150 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
3152 SetLastError(ERROR_NONE_MAPPED);
3153 ret = FALSE;
3155 nameLen = UNLEN + 1;
3158 if (GetUserNameW( userName, &nameLen ) &&
3159 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
3161 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3162 *handled = TRUE;
3164 else
3166 nameLen = UNLEN + 1;
3167 if (GetComputerNameW( userName, &nameLen ) &&
3168 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
3170 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3171 *handled = TRUE;
3175 heap_free(userName);
3176 return ret;
3179 /******************************************************************************
3180 * LookupAccountNameW [ADVAPI32.@]
3182 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
3183 LPDWORD cbSid, LPWSTR ReferencedDomainName,
3184 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
3186 BOOL ret, handled;
3187 LSA_UNICODE_STRING account;
3189 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
3190 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
3192 if (!ADVAPI_IsLocalComputer( lpSystemName ))
3194 FIXME("remote computer not supported\n");
3195 SetLastError( RPC_S_SERVER_UNAVAILABLE );
3196 return FALSE;
3199 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
3201 lpAccountName = BUILTIN;
3204 RtlInitUnicodeString( &account, lpAccountName );
3206 /* Check well known SIDs first */
3207 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
3208 cchReferencedDomainName, peUse, &handled );
3209 if (handled)
3210 return ret;
3212 /* Check user names */
3213 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
3214 cchReferencedDomainName, peUse, &handled);
3215 if (handled)
3216 return ret;
3218 SetLastError( ERROR_NONE_MAPPED );
3219 return FALSE;
3222 /******************************************************************************
3223 * PrivilegeCheck [ADVAPI32.@]
3225 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
3227 BOOL ret;
3228 BOOLEAN Result;
3230 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
3232 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
3233 if (ret)
3234 *pfResult = Result;
3235 return ret;
3238 /******************************************************************************
3239 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
3241 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
3242 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3243 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3244 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3246 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
3247 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
3248 SecurityDescriptor, DesiredAccess, GenericMapping,
3249 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3250 return TRUE;
3253 /******************************************************************************
3254 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3256 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3257 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3258 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3259 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3261 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3262 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3263 SecurityDescriptor, DesiredAccess, GenericMapping,
3264 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3265 return TRUE;
3268 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3270 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3272 return TRUE;
3275 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3277 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3279 return TRUE;
3282 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3284 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3286 return TRUE;
3289 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3290 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3291 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3292 LPBOOL GenerateOnClose)
3294 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3295 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3296 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3297 GenerateOnClose);
3299 return TRUE;
3302 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3303 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3304 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3305 LPBOOL GenerateOnClose)
3307 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3308 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3309 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3310 GenerateOnClose);
3312 return TRUE;
3315 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3316 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3318 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3319 DesiredAccess, Privileges, AccessGranted);
3321 return TRUE;
3324 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3325 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3327 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3328 DesiredAccess, Privileges, AccessGranted);
3330 return TRUE;
3333 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3334 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3336 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3337 ClientToken, Privileges, AccessGranted);
3339 return TRUE;
3342 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3343 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3345 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3346 ClientToken, Privileges, AccessGranted);
3348 return TRUE;
3351 /******************************************************************************
3352 * GetSecurityInfo [ADVAPI32.@]
3354 * Retrieves a copy of the security descriptor associated with an object.
3356 * PARAMS
3357 * hObject [I] A handle for the object.
3358 * ObjectType [I] The type of object.
3359 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3360 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3361 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3362 * ppDacl [O] If non-null, receives a pointer to the DACL.
3363 * ppSacl [O] If non-null, receives a pointer to the SACL.
3364 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3365 * which must be freed with LocalFree.
3367 * RETURNS
3368 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3370 DWORD WINAPI GetSecurityInfo(
3371 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3372 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3373 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3374 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3377 PSECURITY_DESCRIPTOR sd;
3378 NTSTATUS status;
3379 ULONG n1, n2;
3380 BOOL present, defaulted;
3382 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3383 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3385 /* If no descriptor, we have to check that there's a pointer for the requested information */
3386 if( !ppSecurityDescriptor && (
3387 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3388 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3389 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3390 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3391 return ERROR_INVALID_PARAMETER;
3393 switch (ObjectType)
3395 case SE_SERVICE:
3396 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3397 break;
3398 default:
3399 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3400 break;
3402 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3403 return RtlNtStatusToDosError(status);
3405 sd = LocalAlloc(0, n1);
3406 if (!sd)
3407 return ERROR_NOT_ENOUGH_MEMORY;
3409 switch (ObjectType)
3411 case SE_SERVICE:
3412 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3413 break;
3414 default:
3415 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3416 break;
3418 if (status != STATUS_SUCCESS)
3420 LocalFree(sd);
3421 return RtlNtStatusToDosError(status);
3424 if (ppsidOwner)
3426 *ppsidOwner = NULL;
3427 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3429 if (ppsidGroup)
3431 *ppsidGroup = NULL;
3432 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3434 if (ppDacl)
3436 *ppDacl = NULL;
3437 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3439 if (ppSacl)
3441 *ppSacl = NULL;
3442 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3444 if (ppSecurityDescriptor)
3445 *ppSecurityDescriptor = sd;
3447 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3448 * NULL, because native happily returns the SIDs and ACLs that are requested
3449 * in this case.
3452 return ERROR_SUCCESS;
3455 /******************************************************************************
3456 * GetSecurityInfoExA [ADVAPI32.@]
3458 DWORD WINAPI GetSecurityInfoExA(
3459 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3460 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3461 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3462 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3465 FIXME("stub!\n");
3466 return ERROR_BAD_PROVIDER;
3469 /******************************************************************************
3470 * GetSecurityInfoExW [ADVAPI32.@]
3472 DWORD WINAPI GetSecurityInfoExW(
3473 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3474 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3475 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3476 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3479 FIXME("stub!\n");
3480 return ERROR_BAD_PROVIDER;
3483 /******************************************************************************
3484 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3486 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3487 LPSTR pTrusteeName, DWORD AccessPermissions,
3488 ACCESS_MODE AccessMode, DWORD Inheritance )
3490 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3491 AccessPermissions, AccessMode, Inheritance);
3493 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3494 pExplicitAccess->grfAccessMode = AccessMode;
3495 pExplicitAccess->grfInheritance = Inheritance;
3497 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3498 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3499 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3500 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3501 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3504 /******************************************************************************
3505 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3507 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3508 LPWSTR pTrusteeName, DWORD AccessPermissions,
3509 ACCESS_MODE AccessMode, DWORD Inheritance )
3511 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3512 AccessPermissions, AccessMode, Inheritance);
3514 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3515 pExplicitAccess->grfAccessMode = AccessMode;
3516 pExplicitAccess->grfInheritance = Inheritance;
3518 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3519 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3520 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3521 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3522 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3525 /******************************************************************************
3526 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3528 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3529 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3530 LPSTR InheritedObjectTypeName, LPSTR Name )
3532 DWORD ObjectsPresent = 0;
3534 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3535 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3537 /* Fill the OBJECTS_AND_NAME structure */
3538 pObjName->ObjectType = ObjectType;
3539 if (ObjectTypeName != NULL)
3541 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3544 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3545 if (InheritedObjectTypeName != NULL)
3547 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3550 pObjName->ObjectsPresent = ObjectsPresent;
3551 pObjName->ptstrName = Name;
3553 /* Fill the TRUSTEE structure */
3554 pTrustee->pMultipleTrustee = NULL;
3555 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3556 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3557 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3558 pTrustee->ptstrName = (LPSTR)pObjName;
3561 /******************************************************************************
3562 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3564 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3565 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3566 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3568 DWORD ObjectsPresent = 0;
3570 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3571 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3573 /* Fill the OBJECTS_AND_NAME structure */
3574 pObjName->ObjectType = ObjectType;
3575 if (ObjectTypeName != NULL)
3577 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3580 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3581 if (InheritedObjectTypeName != NULL)
3583 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3586 pObjName->ObjectsPresent = ObjectsPresent;
3587 pObjName->ptstrName = Name;
3589 /* Fill the TRUSTEE structure */
3590 pTrustee->pMultipleTrustee = NULL;
3591 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3592 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3593 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3594 pTrustee->ptstrName = (LPWSTR)pObjName;
3597 /******************************************************************************
3598 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3600 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3601 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3603 DWORD ObjectsPresent = 0;
3605 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3607 /* Fill the OBJECTS_AND_SID structure */
3608 if (pObjectGuid != NULL)
3610 pObjSid->ObjectTypeGuid = *pObjectGuid;
3611 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3613 else
3615 ZeroMemory(&pObjSid->ObjectTypeGuid,
3616 sizeof(GUID));
3619 if (pInheritedObjectGuid != NULL)
3621 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3622 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3624 else
3626 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3627 sizeof(GUID));
3630 pObjSid->ObjectsPresent = ObjectsPresent;
3631 pObjSid->pSid = pSid;
3633 /* Fill the TRUSTEE structure */
3634 pTrustee->pMultipleTrustee = NULL;
3635 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3636 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3637 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3638 pTrustee->ptstrName = (LPSTR) pObjSid;
3641 /******************************************************************************
3642 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3644 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3645 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3647 DWORD ObjectsPresent = 0;
3649 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3651 /* Fill the OBJECTS_AND_SID structure */
3652 if (pObjectGuid != NULL)
3654 pObjSid->ObjectTypeGuid = *pObjectGuid;
3655 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3657 else
3659 ZeroMemory(&pObjSid->ObjectTypeGuid,
3660 sizeof(GUID));
3663 if (pInheritedObjectGuid != NULL)
3665 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3666 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3668 else
3670 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3671 sizeof(GUID));
3674 pObjSid->ObjectsPresent = ObjectsPresent;
3675 pObjSid->pSid = pSid;
3677 /* Fill the TRUSTEE structure */
3678 pTrustee->pMultipleTrustee = NULL;
3679 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3680 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3681 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3682 pTrustee->ptstrName = (LPWSTR) pObjSid;
3685 /******************************************************************************
3686 * BuildTrusteeWithSidA [ADVAPI32.@]
3688 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3690 TRACE("%p %p\n", pTrustee, pSid);
3692 pTrustee->pMultipleTrustee = NULL;
3693 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3694 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3695 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3696 pTrustee->ptstrName = pSid;
3699 /******************************************************************************
3700 * BuildTrusteeWithSidW [ADVAPI32.@]
3702 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3704 TRACE("%p %p\n", pTrustee, pSid);
3706 pTrustee->pMultipleTrustee = NULL;
3707 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3708 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3709 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3710 pTrustee->ptstrName = pSid;
3713 /******************************************************************************
3714 * BuildTrusteeWithNameA [ADVAPI32.@]
3716 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3718 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3720 pTrustee->pMultipleTrustee = NULL;
3721 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3722 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3723 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3724 pTrustee->ptstrName = name;
3727 /******************************************************************************
3728 * BuildTrusteeWithNameW [ADVAPI32.@]
3730 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3732 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3734 pTrustee->pMultipleTrustee = NULL;
3735 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3736 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3737 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3738 pTrustee->ptstrName = name;
3741 /******************************************************************************
3742 * GetTrusteeFormA [ADVAPI32.@]
3744 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3746 TRACE("(%p)\n", pTrustee);
3748 if (!pTrustee)
3749 return TRUSTEE_BAD_FORM;
3751 return pTrustee->TrusteeForm;
3754 /******************************************************************************
3755 * GetTrusteeFormW [ADVAPI32.@]
3757 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3759 TRACE("(%p)\n", pTrustee);
3761 if (!pTrustee)
3762 return TRUSTEE_BAD_FORM;
3764 return pTrustee->TrusteeForm;
3767 /******************************************************************************
3768 * GetTrusteeNameA [ADVAPI32.@]
3770 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3772 TRACE("(%p)\n", pTrustee);
3774 if (!pTrustee)
3775 return NULL;
3777 return pTrustee->ptstrName;
3780 /******************************************************************************
3781 * GetTrusteeNameW [ADVAPI32.@]
3783 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3785 TRACE("(%p)\n", pTrustee);
3787 if (!pTrustee)
3788 return NULL;
3790 return pTrustee->ptstrName;
3793 /******************************************************************************
3794 * GetTrusteeTypeA [ADVAPI32.@]
3796 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3798 TRACE("(%p)\n", pTrustee);
3800 if (!pTrustee)
3801 return TRUSTEE_IS_UNKNOWN;
3803 return pTrustee->TrusteeType;
3806 /******************************************************************************
3807 * GetTrusteeTypeW [ADVAPI32.@]
3809 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3811 TRACE("(%p)\n", pTrustee);
3813 if (!pTrustee)
3814 return TRUSTEE_IS_UNKNOWN;
3816 return pTrustee->TrusteeType;
3819 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3820 DWORD nAclInformationLength,
3821 ACL_INFORMATION_CLASS dwAclInformationClass )
3823 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3824 nAclInformationLength, dwAclInformationClass);
3826 return TRUE;
3829 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3831 switch (form)
3833 case TRUSTEE_IS_NAME:
3835 *ptrustee_nameW = SERV_dup(trustee_nameA);
3836 return ERROR_SUCCESS;
3838 case TRUSTEE_IS_OBJECTS_AND_NAME:
3840 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3841 OBJECTS_AND_NAME_W *objW = NULL;
3843 if (objA)
3845 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3846 return ERROR_NOT_ENOUGH_MEMORY;
3848 objW->ObjectsPresent = objA->ObjectsPresent;
3849 objW->ObjectType = objA->ObjectType;
3850 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3851 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3852 objW->ptstrName = SERV_dup(objA->ptstrName);
3855 *ptrustee_nameW = (WCHAR *)objW;
3856 return ERROR_SUCCESS;
3858 /* These forms do not require conversion. */
3859 case TRUSTEE_IS_SID:
3860 case TRUSTEE_IS_OBJECTS_AND_SID:
3861 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3862 return ERROR_SUCCESS;
3863 default:
3864 return ERROR_INVALID_PARAMETER;
3868 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3870 switch (form)
3872 case TRUSTEE_IS_NAME:
3873 heap_free( trustee_nameW );
3874 break;
3875 case TRUSTEE_IS_OBJECTS_AND_NAME:
3877 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3879 if (objW)
3881 heap_free( objW->ptstrName );
3882 heap_free( objW->InheritedObjectTypeName );
3883 heap_free( objW->ObjectTypeName );
3884 heap_free( objW );
3887 break;
3889 /* Other forms did not require allocation, so no freeing is necessary. */
3890 default:
3891 break;
3895 static DWORD trustee_to_sid( DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee )
3897 if (pTrustee->MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3899 WARN("bad multiple trustee operation %d\n", pTrustee->MultipleTrusteeOperation);
3900 return ERROR_INVALID_PARAMETER;
3903 switch (pTrustee->TrusteeForm)
3905 case TRUSTEE_IS_SID:
3906 if (!CopySid(nDestinationSidLength, pDestinationSid, pTrustee->ptstrName))
3908 WARN("bad sid %p\n", pTrustee->ptstrName);
3909 return ERROR_INVALID_PARAMETER;
3911 break;
3912 case TRUSTEE_IS_NAME:
3914 DWORD sid_size = nDestinationSidLength;
3915 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3916 SID_NAME_USE use;
3917 if (!strcmpW( pTrustee->ptstrName, CURRENT_USER ))
3919 if (!lookup_user_account_name( pDestinationSid, &sid_size, NULL, &domain_size, &use ))
3921 return GetLastError();
3924 else if (!LookupAccountNameW(NULL, pTrustee->ptstrName, pDestinationSid, &sid_size, NULL, &domain_size, &use))
3926 WARN("bad user name %s\n", debugstr_w(pTrustee->ptstrName));
3927 return ERROR_INVALID_PARAMETER;
3929 break;
3931 case TRUSTEE_IS_OBJECTS_AND_SID:
3932 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3933 break;
3934 case TRUSTEE_IS_OBJECTS_AND_NAME:
3935 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3936 break;
3937 default:
3938 WARN("bad trustee form %d\n", pTrustee->TrusteeForm);
3939 return ERROR_INVALID_PARAMETER;
3942 return ERROR_SUCCESS;
3945 /******************************************************************************
3946 * SetEntriesInAclA [ADVAPI32.@]
3948 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3949 PACL OldAcl, PACL* NewAcl )
3951 DWORD err = ERROR_SUCCESS;
3952 EXPLICIT_ACCESSW *pEntriesW;
3953 UINT alloc_index, free_index;
3955 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3957 if (NewAcl)
3958 *NewAcl = NULL;
3960 if (!count && !OldAcl)
3961 return ERROR_SUCCESS;
3963 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3964 if (!pEntriesW)
3965 return ERROR_NOT_ENOUGH_MEMORY;
3967 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3969 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3970 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3971 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3972 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3973 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3974 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3975 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3977 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3978 pEntries[alloc_index].Trustee.ptstrName,
3979 &pEntriesW[alloc_index].Trustee.ptstrName );
3980 if (err != ERROR_SUCCESS)
3982 if (err == ERROR_INVALID_PARAMETER)
3983 WARN("bad trustee form %d for trustee %d\n",
3984 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3986 goto cleanup;
3990 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3992 cleanup:
3993 /* Free any previously allocated trustee name buffers, taking into account
3994 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3995 * list. */
3996 for (free_index = 0; free_index < alloc_index; ++free_index)
3997 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3999 heap_free( pEntriesW );
4000 return err;
4003 /******************************************************************************
4004 * SetEntriesInAclW [ADVAPI32.@]
4006 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
4007 PACL OldAcl, PACL* NewAcl )
4009 ULONG i;
4010 PSID *ppsid;
4011 DWORD ret = ERROR_SUCCESS;
4012 DWORD acl_size = sizeof(ACL);
4013 NTSTATUS status;
4015 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
4017 if (NewAcl)
4018 *NewAcl = NULL;
4020 if (!count && !OldAcl)
4021 return ERROR_SUCCESS;
4023 /* allocate array of maximum sized sids allowed */
4024 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
4025 if (!ppsid)
4026 return ERROR_OUTOFMEMORY;
4028 for (i = 0; i < count; i++)
4030 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
4032 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
4033 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
4034 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
4035 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
4036 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
4037 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
4038 pEntries[i].Trustee.ptstrName);
4040 ret = trustee_to_sid( FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]), ppsid[i], &pEntries[i].Trustee);
4041 if (ret)
4042 goto exit;
4044 /* Note: we overestimate the ACL size here as a tradeoff between
4045 * instructions (simplicity) and memory */
4046 switch (pEntries[i].grfAccessMode)
4048 case GRANT_ACCESS:
4049 case SET_ACCESS:
4050 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
4051 break;
4052 case DENY_ACCESS:
4053 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
4054 break;
4055 case SET_AUDIT_SUCCESS:
4056 case SET_AUDIT_FAILURE:
4057 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
4058 break;
4059 case REVOKE_ACCESS:
4060 break;
4061 default:
4062 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
4063 ret = ERROR_INVALID_PARAMETER;
4064 goto exit;
4068 if (OldAcl)
4070 ACL_SIZE_INFORMATION size_info;
4072 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
4073 if (status != STATUS_SUCCESS)
4075 ret = RtlNtStatusToDosError(status);
4076 goto exit;
4078 acl_size += size_info.AclBytesInUse - sizeof(ACL);
4081 *NewAcl = LocalAlloc(0, acl_size);
4082 if (!*NewAcl)
4084 ret = ERROR_OUTOFMEMORY;
4085 goto exit;
4088 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
4089 if (status != STATUS_SUCCESS)
4091 ret = RtlNtStatusToDosError(status);
4092 goto exit;
4095 for (i = 0; i < count; i++)
4097 switch (pEntries[i].grfAccessMode)
4099 case GRANT_ACCESS:
4100 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
4101 pEntries[i].grfInheritance,
4102 pEntries[i].grfAccessPermissions,
4103 ppsid[i]);
4104 break;
4105 case SET_ACCESS:
4107 ULONG j;
4108 BOOL add = TRUE;
4109 if (OldAcl)
4111 for (j = 0; ; j++)
4113 const ACE_HEADER *existing_ace_header;
4114 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
4115 if (status != STATUS_SUCCESS)
4116 break;
4117 if (pEntries[i].grfAccessMode == SET_ACCESS &&
4118 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4119 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
4121 add = FALSE;
4122 break;
4126 if (add)
4127 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
4128 pEntries[i].grfInheritance,
4129 pEntries[i].grfAccessPermissions,
4130 ppsid[i]);
4131 break;
4133 case DENY_ACCESS:
4134 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
4135 pEntries[i].grfInheritance,
4136 pEntries[i].grfAccessPermissions,
4137 ppsid[i]);
4138 break;
4139 case SET_AUDIT_SUCCESS:
4140 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4141 pEntries[i].grfInheritance,
4142 pEntries[i].grfAccessPermissions,
4143 ppsid[i], TRUE, FALSE);
4144 break;
4145 case SET_AUDIT_FAILURE:
4146 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4147 pEntries[i].grfInheritance,
4148 pEntries[i].grfAccessPermissions,
4149 ppsid[i], FALSE, TRUE);
4150 break;
4151 default:
4152 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
4156 if (OldAcl)
4158 for (i = 0; ; i++)
4160 BOOL add = TRUE;
4161 ULONG j;
4162 const ACE_HEADER *old_ace_header;
4163 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
4164 if (status != STATUS_SUCCESS) break;
4165 for (j = 0; j < count; j++)
4167 if (pEntries[j].grfAccessMode == SET_ACCESS &&
4168 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4169 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4171 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
4172 add = FALSE;
4173 break;
4175 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
4177 switch (old_ace_header->AceType)
4179 case ACCESS_ALLOWED_ACE_TYPE:
4180 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4181 add = FALSE;
4182 break;
4183 case ACCESS_DENIED_ACE_TYPE:
4184 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
4185 add = FALSE;
4186 break;
4187 case SYSTEM_AUDIT_ACE_TYPE:
4188 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
4189 add = FALSE;
4190 break;
4191 case SYSTEM_ALARM_ACE_TYPE:
4192 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
4193 add = FALSE;
4194 break;
4195 default:
4196 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
4199 if (!add)
4200 break;
4203 if (add)
4204 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
4205 if (status != STATUS_SUCCESS)
4207 WARN("RtlAddAce failed with error 0x%08x\n", status);
4208 ret = RtlNtStatusToDosError(status);
4209 break;
4214 exit:
4215 heap_free(ppsid);
4216 return ret;
4219 /******************************************************************************
4220 * SetNamedSecurityInfoA [ADVAPI32.@]
4222 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
4223 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4224 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4226 LPWSTR wstr;
4227 DWORD r;
4229 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
4230 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4232 wstr = SERV_dup(pObjectName);
4233 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
4234 psidGroup, pDacl, pSacl );
4236 heap_free( wstr );
4238 return r;
4241 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
4242 PSECURITY_DESCRIPTOR ModificationDescriptor,
4243 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
4244 PGENERIC_MAPPING GenericMapping,
4245 HANDLE Token )
4247 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
4248 ObjectsSecurityDescriptor, GenericMapping, Token);
4250 return TRUE;
4253 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4255 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4258 /******************************************************************************
4259 * AreAnyAccessesGranted [ADVAPI32.@]
4261 * Determines whether or not any of a set of specified access permissions have
4262 * been granted or not.
4264 * PARAMS
4265 * GrantedAccess [I] The permissions that have been granted.
4266 * DesiredAccess [I] The permissions that you want to have.
4268 * RETURNS
4269 * Nonzero if any of the permissions have been granted, zero if none of the
4270 * permissions have been granted.
4273 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4275 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4278 /******************************************************************************
4279 * SetNamedSecurityInfoW [ADVAPI32.@]
4281 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4282 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4283 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4285 DWORD access = 0;
4286 HANDLE handle;
4287 DWORD err;
4289 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4290 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4292 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4294 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4295 access |= WRITE_OWNER;
4296 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4297 access |= WRITE_DAC;
4298 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4299 access |= ACCESS_SYSTEM_SECURITY;
4301 switch (ObjectType)
4303 case SE_SERVICE:
4304 if (!(err = get_security_service( pObjectName, access, &handle )))
4306 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4307 CloseServiceHandle( handle );
4309 break;
4310 case SE_REGISTRY_KEY:
4311 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4313 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4314 RegCloseKey( handle );
4316 break;
4317 case SE_FILE_OBJECT:
4318 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4319 access |= READ_CONTROL;
4320 if (!(err = get_security_file( pObjectName, access, &handle )))
4322 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4323 CloseHandle( handle );
4325 break;
4326 default:
4327 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4328 return ERROR_SUCCESS;
4330 return err;
4333 /******************************************************************************
4334 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4336 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4337 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4339 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4340 return ERROR_CALL_NOT_IMPLEMENTED;
4343 /******************************************************************************
4344 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4346 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG count, PEXPLICIT_ACCESSW *list )
4348 ACL_SIZE_INFORMATION sizeinfo;
4349 EXPLICIT_ACCESSW *entries;
4350 MAX_SID *sid_entries;
4351 ACE_HEADER *ace;
4352 NTSTATUS status;
4353 int i;
4355 TRACE("%p %p %p\n",pacl, count, list);
4357 if (!count || !list)
4358 return ERROR_INVALID_PARAMETER;
4360 status = RtlQueryInformationAcl(pacl, &sizeinfo, sizeof(sizeinfo), AclSizeInformation);
4361 if (status) return RtlNtStatusToDosError(status);
4363 if (!sizeinfo.AceCount)
4365 *count = 0;
4366 *list = NULL;
4367 return ERROR_SUCCESS;
4370 entries = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (sizeof(EXPLICIT_ACCESSW) + sizeof(MAX_SID)) * sizeinfo.AceCount);
4371 if (!entries) return ERROR_OUTOFMEMORY;
4372 sid_entries = (MAX_SID *)(entries + sizeinfo.AceCount);
4374 for (i = 0; i < sizeinfo.AceCount; i++)
4376 status = RtlGetAce(pacl, i, (void**)&ace);
4377 if (status) goto error;
4379 switch (ace->AceType)
4381 case ACCESS_ALLOWED_ACE_TYPE:
4383 ACCESS_ALLOWED_ACE *allow = (ACCESS_ALLOWED_ACE *)ace;
4384 entries[i].grfAccessMode = GRANT_ACCESS;
4385 entries[i].grfInheritance = ace->AceFlags;
4386 entries[i].grfAccessPermissions = allow->Mask;
4388 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&allow->SidStart);
4389 entries[i].Trustee.pMultipleTrustee = NULL;
4390 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4391 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4392 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4393 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4394 break;
4397 case ACCESS_DENIED_ACE_TYPE:
4399 ACCESS_DENIED_ACE *deny = (ACCESS_DENIED_ACE *)ace;
4400 entries[i].grfAccessMode = DENY_ACCESS;
4401 entries[i].grfInheritance = ace->AceFlags;
4402 entries[i].grfAccessPermissions = deny->Mask;
4404 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&deny->SidStart);
4405 entries[i].Trustee.pMultipleTrustee = NULL;
4406 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4407 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4408 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4409 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4410 break;
4413 default:
4414 FIXME("Unhandled ace type %d\n", ace->AceType);
4415 entries[i].grfAccessMode = NOT_USED_ACCESS;
4416 continue;
4420 *count = sizeinfo.AceCount;
4421 *list = entries;
4422 return ERROR_SUCCESS;
4424 error:
4425 LocalFree(entries);
4426 return RtlNtStatusToDosError(status);
4429 /******************************************************************************
4430 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4432 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4433 PACCESS_MASK pFailedAuditRights)
4435 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4436 return ERROR_CALL_NOT_IMPLEMENTED;
4440 /******************************************************************************
4441 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4443 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4444 PACCESS_MASK pFailedAuditRights)
4446 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4447 return ERROR_CALL_NOT_IMPLEMENTED;
4451 /******************************************************************************
4452 * ParseAclStringFlags
4454 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4456 DWORD flags = 0;
4457 LPCWSTR szAcl = *StringAcl;
4459 while (*szAcl && *szAcl != '(')
4461 if (*szAcl == 'P')
4463 flags |= SE_DACL_PROTECTED;
4465 else if (*szAcl == 'A')
4467 szAcl++;
4468 if (*szAcl == 'R')
4469 flags |= SE_DACL_AUTO_INHERIT_REQ;
4470 else if (*szAcl == 'I')
4471 flags |= SE_DACL_AUTO_INHERITED;
4473 szAcl++;
4476 *StringAcl = szAcl;
4477 return flags;
4480 /******************************************************************************
4481 * ParseAceStringType
4483 static const ACEFLAG AceType[] =
4485 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4486 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4487 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4488 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4489 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
4491 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4492 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4493 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4494 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4496 { NULL, 0 },
4499 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4501 UINT len = 0;
4502 LPCWSTR szAcl = *StringAcl;
4503 const ACEFLAG *lpaf = AceType;
4505 while (*szAcl == ' ')
4506 szAcl++;
4508 while (lpaf->wstr &&
4509 (len = strlenW(lpaf->wstr)) &&
4510 strncmpW(lpaf->wstr, szAcl, len))
4511 lpaf++;
4513 if (!lpaf->wstr)
4514 return 0;
4516 *StringAcl = szAcl + len;
4517 return lpaf->value;
4521 /******************************************************************************
4522 * ParseAceStringFlags
4524 static const ACEFLAG AceFlags[] =
4526 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4527 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4528 { SDDL_INHERITED, INHERITED_ACE },
4529 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4530 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4531 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4532 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4533 { NULL, 0 },
4536 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4538 UINT len = 0;
4539 BYTE flags = 0;
4540 LPCWSTR szAcl = *StringAcl;
4542 while (*szAcl == ' ')
4543 szAcl++;
4545 while (*szAcl != ';')
4547 const ACEFLAG *lpaf = AceFlags;
4549 while (lpaf->wstr &&
4550 (len = strlenW(lpaf->wstr)) &&
4551 strncmpW(lpaf->wstr, szAcl, len))
4552 lpaf++;
4554 if (!lpaf->wstr)
4555 return 0;
4557 flags |= lpaf->value;
4558 szAcl += len;
4561 *StringAcl = szAcl;
4562 return flags;
4566 /******************************************************************************
4567 * ParseAceStringRights
4569 static const ACEFLAG AceRights[] =
4571 { SDDL_GENERIC_ALL, GENERIC_ALL },
4572 { SDDL_GENERIC_READ, GENERIC_READ },
4573 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4574 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4576 { SDDL_READ_CONTROL, READ_CONTROL },
4577 { SDDL_STANDARD_DELETE, DELETE },
4578 { SDDL_WRITE_DAC, WRITE_DAC },
4579 { SDDL_WRITE_OWNER, WRITE_OWNER },
4581 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4582 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4583 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4584 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4585 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4586 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4587 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4588 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4589 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4591 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4592 { SDDL_FILE_READ, FILE_GENERIC_READ },
4593 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4594 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4596 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4597 { SDDL_KEY_READ, KEY_READ },
4598 { SDDL_KEY_WRITE, KEY_WRITE },
4599 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4601 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
4602 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
4603 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
4604 { NULL, 0 },
4607 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4609 UINT len = 0;
4610 DWORD rights = 0;
4611 LPCWSTR szAcl = *StringAcl;
4613 while (*szAcl == ' ')
4614 szAcl++;
4616 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4618 LPCWSTR p = szAcl;
4620 while (*p && *p != ';')
4621 p++;
4623 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4625 rights = strtoulW(szAcl, NULL, 16);
4626 szAcl = p;
4628 else
4629 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4631 else
4633 while (*szAcl != ';')
4635 const ACEFLAG *lpaf = AceRights;
4637 while (lpaf->wstr &&
4638 (len = strlenW(lpaf->wstr)) &&
4639 strncmpW(lpaf->wstr, szAcl, len))
4641 lpaf++;
4644 if (!lpaf->wstr)
4645 return 0;
4647 rights |= lpaf->value;
4648 szAcl += len;
4652 *StringAcl = szAcl;
4653 return rights;
4657 /******************************************************************************
4658 * ParseStringAclToAcl
4660 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4662 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4663 PACL pAcl, LPDWORD cBytes)
4665 DWORD val;
4666 DWORD sidlen;
4667 DWORD length = sizeof(ACL);
4668 DWORD acesize = 0;
4669 DWORD acecount = 0;
4670 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4671 DWORD error = ERROR_INVALID_ACL;
4673 TRACE("%s\n", debugstr_w(StringAcl));
4675 if (!StringAcl)
4676 return FALSE;
4678 if (pAcl) /* pAce is only useful if we're setting values */
4679 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4681 /* Parse ACL flags */
4682 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4684 /* Parse ACE */
4685 while (*StringAcl == '(')
4687 StringAcl++;
4689 /* Parse ACE type */
4690 val = ParseAceStringType(&StringAcl);
4691 if (pAce)
4692 pAce->Header.AceType = (BYTE) val;
4693 if (*StringAcl != ';')
4695 error = RPC_S_INVALID_STRING_UUID;
4696 goto lerr;
4698 StringAcl++;
4700 /* Parse ACE flags */
4701 val = ParseAceStringFlags(&StringAcl);
4702 if (pAce)
4703 pAce->Header.AceFlags = (BYTE) val;
4704 if (*StringAcl != ';')
4705 goto lerr;
4706 StringAcl++;
4708 /* Parse ACE rights */
4709 val = ParseAceStringRights(&StringAcl);
4710 if (pAce)
4711 pAce->Mask = val;
4712 if (*StringAcl != ';')
4713 goto lerr;
4714 StringAcl++;
4716 /* Parse ACE object guid */
4717 while (*StringAcl == ' ')
4718 StringAcl++;
4719 if (*StringAcl != ';')
4721 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4722 goto lerr;
4724 StringAcl++;
4726 /* Parse ACE inherit object guid */
4727 while (*StringAcl == ' ')
4728 StringAcl++;
4729 if (*StringAcl != ';')
4731 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4732 goto lerr;
4734 StringAcl++;
4736 /* Parse ACE account sid */
4737 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4739 while (*StringAcl && *StringAcl != ')')
4740 StringAcl++;
4743 if (*StringAcl != ')')
4744 goto lerr;
4745 StringAcl++;
4747 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4748 length += acesize;
4749 if (pAce)
4751 pAce->Header.AceSize = acesize;
4752 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4754 acecount++;
4757 *cBytes = length;
4759 if (length > 0xffff)
4761 ERR("ACL too large\n");
4762 goto lerr;
4765 if (pAcl)
4767 pAcl->AclRevision = ACL_REVISION;
4768 pAcl->Sbz1 = 0;
4769 pAcl->AclSize = length;
4770 pAcl->AceCount = acecount;
4771 pAcl->Sbz2 = 0;
4773 return TRUE;
4775 lerr:
4776 SetLastError(error);
4777 WARN("Invalid ACE string format\n");
4778 return FALSE;
4782 /******************************************************************************
4783 * ParseStringSecurityDescriptorToSecurityDescriptor
4785 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4786 LPCWSTR StringSecurityDescriptor,
4787 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4788 LPDWORD cBytes)
4790 BOOL bret = FALSE;
4791 WCHAR toktype;
4792 WCHAR *tok;
4793 LPCWSTR lptoken;
4794 LPBYTE lpNext = NULL;
4795 DWORD len;
4797 *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4799 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
4801 if (SecurityDescriptor)
4802 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4804 while (*StringSecurityDescriptor == ' ')
4805 StringSecurityDescriptor++;
4807 while (*StringSecurityDescriptor)
4809 toktype = *StringSecurityDescriptor;
4811 /* Expect char identifier followed by ':' */
4812 StringSecurityDescriptor++;
4813 if (*StringSecurityDescriptor != ':')
4815 SetLastError(ERROR_INVALID_PARAMETER);
4816 goto lend;
4818 StringSecurityDescriptor++;
4820 /* Extract token */
4821 lptoken = StringSecurityDescriptor;
4822 while (*lptoken && *lptoken != ':')
4823 lptoken++;
4825 if (*lptoken)
4826 lptoken--;
4828 len = lptoken - StringSecurityDescriptor;
4829 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4830 tok[len] = 0;
4832 switch (toktype)
4834 case 'O':
4836 DWORD bytes;
4838 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4839 goto lend;
4841 if (SecurityDescriptor)
4843 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4844 lpNext += bytes; /* Advance to next token */
4847 *cBytes += bytes;
4849 break;
4852 case 'G':
4854 DWORD bytes;
4856 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4857 goto lend;
4859 if (SecurityDescriptor)
4861 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4862 lpNext += bytes; /* Advance to next token */
4865 *cBytes += bytes;
4867 break;
4870 case 'D':
4872 DWORD flags;
4873 DWORD bytes;
4875 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4876 goto lend;
4878 if (SecurityDescriptor)
4880 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4881 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4882 lpNext += bytes; /* Advance to next token */
4885 *cBytes += bytes;
4887 break;
4890 case 'S':
4892 DWORD flags;
4893 DWORD bytes;
4895 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4896 goto lend;
4898 if (SecurityDescriptor)
4900 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4901 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4902 lpNext += bytes; /* Advance to next token */
4905 *cBytes += bytes;
4907 break;
4910 default:
4911 FIXME("Unknown token\n");
4912 SetLastError(ERROR_INVALID_PARAMETER);
4913 goto lend;
4916 StringSecurityDescriptor = lptoken;
4919 bret = TRUE;
4921 lend:
4922 heap_free(tok);
4923 return bret;
4926 /******************************************************************************
4927 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4929 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4930 LPCSTR StringSecurityDescriptor,
4931 DWORD StringSDRevision,
4932 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4933 PULONG SecurityDescriptorSize)
4935 BOOL ret;
4936 LPWSTR StringSecurityDescriptorW;
4938 TRACE("%s, %u, %p, %p\n", debugstr_a(StringSecurityDescriptor), StringSDRevision,
4939 SecurityDescriptor, SecurityDescriptorSize);
4941 if(!StringSecurityDescriptor)
4942 return FALSE;
4944 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4945 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4946 StringSDRevision, SecurityDescriptor,
4947 SecurityDescriptorSize);
4948 heap_free(StringSecurityDescriptorW);
4950 return ret;
4953 /******************************************************************************
4954 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4956 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4957 LPCWSTR StringSecurityDescriptor,
4958 DWORD StringSDRevision,
4959 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4960 PULONG SecurityDescriptorSize)
4962 DWORD cBytes;
4963 SECURITY_DESCRIPTOR* psd;
4964 BOOL bret = FALSE;
4966 TRACE("%s, %u, %p, %p\n", debugstr_w(StringSecurityDescriptor), StringSDRevision,
4967 SecurityDescriptor, SecurityDescriptorSize);
4969 if (GetVersion() & 0x80000000)
4971 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4972 goto lend;
4974 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4976 SetLastError(ERROR_INVALID_PARAMETER);
4977 goto lend;
4979 else if (StringSDRevision != SID_REVISION)
4981 SetLastError(ERROR_UNKNOWN_REVISION);
4982 goto lend;
4985 /* Compute security descriptor length */
4986 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4987 NULL, &cBytes))
4988 goto lend;
4990 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4991 if (!psd) goto lend;
4993 psd->Revision = SID_REVISION;
4994 psd->Control |= SE_SELF_RELATIVE;
4996 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4997 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4999 LocalFree(psd);
5000 goto lend;
5003 if (SecurityDescriptorSize)
5004 *SecurityDescriptorSize = cBytes;
5006 bret = TRUE;
5008 lend:
5009 TRACE(" ret=%d\n", bret);
5010 return bret;
5013 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
5015 if (cch == -1)
5016 cch = strlenW(string);
5018 if (plen)
5019 *plen += cch;
5021 if (pwptr)
5023 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
5024 *pwptr += cch;
5028 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
5030 static const WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
5031 static const WCHAR subauthfmt[] = { '-','%','u',0 };
5032 DWORD i;
5033 WCHAR buf[26];
5034 SID *pisid = psid;
5036 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
5038 SetLastError(ERROR_INVALID_SID);
5039 return FALSE;
5042 if (pisid->IdentifierAuthority.Value[0] ||
5043 pisid->IdentifierAuthority.Value[1])
5045 FIXME("not matching MS' bugs\n");
5046 SetLastError(ERROR_INVALID_SID);
5047 return FALSE;
5050 sprintfW( buf, fmt, pisid->Revision,
5051 MAKELONG(
5052 MAKEWORD( pisid->IdentifierAuthority.Value[5],
5053 pisid->IdentifierAuthority.Value[4] ),
5054 MAKEWORD( pisid->IdentifierAuthority.Value[3],
5055 pisid->IdentifierAuthority.Value[2] )
5056 ) );
5057 DumpString(buf, -1, pwptr, plen);
5059 for( i=0; i<pisid->SubAuthorityCount; i++ )
5061 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
5062 DumpString(buf, -1, pwptr, plen);
5064 return TRUE;
5067 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
5069 size_t i;
5070 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5072 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
5074 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
5075 return TRUE;
5079 return DumpSidNumeric(psid, pwptr, plen);
5082 static const LPCWSTR AceRightBitNames[32] = {
5083 SDDL_CREATE_CHILD, /* 0 */
5084 SDDL_DELETE_CHILD,
5085 SDDL_LIST_CHILDREN,
5086 SDDL_SELF_WRITE,
5087 SDDL_READ_PROPERTY, /* 4 */
5088 SDDL_WRITE_PROPERTY,
5089 SDDL_DELETE_TREE,
5090 SDDL_LIST_OBJECT,
5091 SDDL_CONTROL_ACCESS, /* 8 */
5092 NULL,
5093 NULL,
5094 NULL,
5095 NULL, /* 12 */
5096 NULL,
5097 NULL,
5098 NULL,
5099 SDDL_STANDARD_DELETE, /* 16 */
5100 SDDL_READ_CONTROL,
5101 SDDL_WRITE_DAC,
5102 SDDL_WRITE_OWNER,
5103 NULL, /* 20 */
5104 NULL,
5105 NULL,
5106 NULL,
5107 NULL, /* 24 */
5108 NULL,
5109 NULL,
5110 NULL,
5111 SDDL_GENERIC_ALL, /* 28 */
5112 SDDL_GENERIC_EXECUTE,
5113 SDDL_GENERIC_WRITE,
5114 SDDL_GENERIC_READ
5117 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
5119 static const WCHAR fmtW[] = {'0','x','%','x',0};
5120 WCHAR buf[15];
5121 size_t i;
5123 if (mask == 0)
5124 return;
5126 /* first check if the right have name */
5127 for (i = 0; i < ARRAY_SIZE(AceRights); i++)
5129 if (AceRights[i].wstr == NULL)
5130 break;
5131 if (mask == AceRights[i].value)
5133 DumpString(AceRights[i].wstr, -1, pwptr, plen);
5134 return;
5138 /* then check if it can be built from bit names */
5139 for (i = 0; i < 32; i++)
5141 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
5143 /* can't be built from bit names */
5144 sprintfW(buf, fmtW, mask);
5145 DumpString(buf, -1, pwptr, plen);
5146 return;
5150 /* build from bit names */
5151 for (i = 0; i < 32; i++)
5152 if (mask & (1 << i))
5153 DumpString(AceRightBitNames[i], -1, pwptr, plen);
5156 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
5158 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
5159 static const WCHAR openbr = '(';
5160 static const WCHAR closebr = ')';
5161 static const WCHAR semicolon = ';';
5163 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
5165 SetLastError(ERROR_INVALID_ACL);
5166 return FALSE;
5169 piace = pace;
5170 DumpString(&openbr, 1, pwptr, plen);
5171 switch (piace->Header.AceType)
5173 case ACCESS_ALLOWED_ACE_TYPE:
5174 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
5175 break;
5176 case ACCESS_DENIED_ACE_TYPE:
5177 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
5178 break;
5179 case SYSTEM_AUDIT_ACE_TYPE:
5180 DumpString(SDDL_AUDIT, -1, pwptr, plen);
5181 break;
5182 case SYSTEM_ALARM_ACE_TYPE:
5183 DumpString(SDDL_ALARM, -1, pwptr, plen);
5184 break;
5186 DumpString(&semicolon, 1, pwptr, plen);
5188 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
5189 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
5190 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
5191 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
5192 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
5193 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
5194 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
5195 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
5196 if (piace->Header.AceFlags & INHERITED_ACE)
5197 DumpString(SDDL_INHERITED, -1, pwptr, plen);
5198 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
5199 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
5200 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
5201 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
5202 DumpString(&semicolon, 1, pwptr, plen);
5203 DumpRights(piace->Mask, pwptr, plen);
5204 DumpString(&semicolon, 1, pwptr, plen);
5205 /* objects not supported */
5206 DumpString(&semicolon, 1, pwptr, plen);
5207 /* objects not supported */
5208 DumpString(&semicolon, 1, pwptr, plen);
5209 if (!DumpSid(&piace->SidStart, pwptr, plen))
5210 return FALSE;
5211 DumpString(&closebr, 1, pwptr, plen);
5212 return TRUE;
5215 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
5217 WORD count;
5218 UINT i;
5220 if (protected)
5221 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
5222 if (autoInheritReq)
5223 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
5224 if (autoInherited)
5225 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
5227 if (pacl == NULL)
5228 return TRUE;
5230 if (!IsValidAcl(pacl))
5231 return FALSE;
5233 count = pacl->AceCount;
5234 for (i = 0; i < count; i++)
5236 LPVOID ace;
5237 if (!GetAce(pacl, i, &ace))
5238 return FALSE;
5239 if (!DumpAce(ace, pwptr, plen))
5240 return FALSE;
5243 return TRUE;
5246 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5248 static const WCHAR prefix[] = {'O',':',0};
5249 BOOL bDefaulted;
5250 PSID psid;
5252 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
5253 return FALSE;
5255 if (psid == NULL)
5256 return TRUE;
5258 DumpString(prefix, -1, pwptr, plen);
5259 if (!DumpSid(psid, pwptr, plen))
5260 return FALSE;
5261 return TRUE;
5264 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5266 static const WCHAR prefix[] = {'G',':',0};
5267 BOOL bDefaulted;
5268 PSID psid;
5270 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
5271 return FALSE;
5273 if (psid == NULL)
5274 return TRUE;
5276 DumpString(prefix, -1, pwptr, plen);
5277 if (!DumpSid(psid, pwptr, plen))
5278 return FALSE;
5279 return TRUE;
5282 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5284 static const WCHAR dacl[] = {'D',':',0};
5285 SECURITY_DESCRIPTOR_CONTROL control;
5286 BOOL present, defaulted;
5287 DWORD revision;
5288 PACL pacl;
5290 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
5291 return FALSE;
5293 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5294 return FALSE;
5296 if (!present)
5297 return TRUE;
5299 DumpString(dacl, 2, pwptr, plen);
5300 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
5301 return FALSE;
5302 return TRUE;
5305 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5307 static const WCHAR sacl[] = {'S',':',0};
5308 SECURITY_DESCRIPTOR_CONTROL control;
5309 BOOL present, defaulted;
5310 DWORD revision;
5311 PACL pacl;
5313 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
5314 return FALSE;
5316 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5317 return FALSE;
5319 if (!present)
5320 return TRUE;
5322 DumpString(sacl, 2, pwptr, plen);
5323 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
5324 return FALSE;
5325 return TRUE;
5328 /******************************************************************************
5329 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5331 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
5333 ULONG len;
5334 WCHAR *wptr, *wstr;
5336 if (SDRevision != SDDL_REVISION_1)
5338 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
5339 SetLastError(ERROR_UNKNOWN_REVISION);
5340 return FALSE;
5343 len = 0;
5344 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5345 if (!DumpOwner(SecurityDescriptor, NULL, &len))
5346 return FALSE;
5347 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5348 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5349 return FALSE;
5350 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5351 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5352 return FALSE;
5353 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5354 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5355 return FALSE;
5357 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5358 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5359 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5360 LocalFree (wstr);
5361 return FALSE;
5363 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5364 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5365 LocalFree (wstr);
5366 return FALSE;
5368 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5369 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5370 LocalFree (wstr);
5371 return FALSE;
5373 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5374 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5375 LocalFree (wstr);
5376 return FALSE;
5378 *wptr = 0;
5380 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5381 *OutputString = wstr;
5382 if (OutputLen)
5383 *OutputLen = strlenW(*OutputString)+1;
5384 return TRUE;
5387 /******************************************************************************
5388 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5390 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5392 LPWSTR wstr;
5393 ULONG len;
5394 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5396 int lenA;
5398 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5399 *OutputString = heap_alloc(lenA);
5400 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5401 LocalFree(wstr);
5403 if (OutputLen != NULL)
5404 *OutputLen = lenA;
5405 return TRUE;
5407 else
5409 *OutputString = NULL;
5410 if (OutputLen)
5411 *OutputLen = 0;
5412 return FALSE;
5416 /******************************************************************************
5417 * ConvertStringSidToSidW [ADVAPI32.@]
5419 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5421 BOOL bret = FALSE;
5422 DWORD cBytes;
5424 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5425 if (GetVersion() & 0x80000000)
5426 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5427 else if (!StringSid || !Sid)
5428 SetLastError(ERROR_INVALID_PARAMETER);
5429 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5431 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5433 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5434 if (!bret)
5435 LocalFree(*Sid);
5437 return bret;
5440 /******************************************************************************
5441 * ConvertStringSidToSidA [ADVAPI32.@]
5443 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5445 BOOL bret = FALSE;
5447 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5448 if (GetVersion() & 0x80000000)
5449 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5450 else if (!StringSid || !Sid)
5451 SetLastError(ERROR_INVALID_PARAMETER);
5452 else
5454 WCHAR *wStringSid = SERV_dup(StringSid);
5455 bret = ConvertStringSidToSidW(wStringSid, Sid);
5456 heap_free(wStringSid);
5458 return bret;
5461 /******************************************************************************
5462 * ConvertSidToStringSidW [ADVAPI32.@]
5464 * format of SID string is:
5465 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5466 * where
5467 * <rev> is the revision of the SID encoded as decimal
5468 * <auth> is the identifier authority encoded as hex
5469 * <subauthN> is the subauthority id encoded as decimal
5471 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5473 DWORD len = 0;
5474 LPWSTR wstr, wptr;
5476 TRACE("%p %p\n", pSid, pstr );
5478 len = 0;
5479 if (!DumpSidNumeric(pSid, NULL, &len))
5480 return FALSE;
5481 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5482 DumpSidNumeric(pSid, &wptr, NULL);
5483 *wptr = 0;
5485 *pstr = wstr;
5486 return TRUE;
5489 /******************************************************************************
5490 * ConvertSidToStringSidA [ADVAPI32.@]
5492 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5494 LPWSTR wstr = NULL;
5495 LPSTR str;
5496 UINT len;
5498 TRACE("%p %p\n", pSid, pstr );
5500 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5501 return FALSE;
5503 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5504 str = LocalAlloc( 0, len );
5505 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5506 LocalFree( wstr );
5508 *pstr = str;
5510 return TRUE;
5513 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5514 PSECURITY_DESCRIPTOR pdesc,
5515 PSECURITY_DESCRIPTOR cdesc,
5516 PSECURITY_DESCRIPTOR* ndesc,
5517 GUID* objtype,
5518 BOOL isdir,
5519 PGENERIC_MAPPING genmap )
5521 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5523 return FALSE;
5526 BOOL WINAPI CreatePrivateObjectSecurityEx(
5527 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5528 GUID *objtype, BOOL is_directory, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5530 SECURITY_DESCRIPTOR_RELATIVE *relative;
5531 DWORD needed, offset;
5532 BYTE *buffer;
5534 FIXME("%p %p %p %p %d %u %p %p - returns fake SECURITY_DESCRIPTOR\n", parent, creator, out,
5535 objtype, is_directory, flags, token, mapping);
5537 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5538 needed += sizeof(sidWorld);
5539 needed += sizeof(sidWorld);
5540 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5541 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5543 if (!(buffer = heap_alloc( needed ))) return FALSE;
5544 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5545 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5547 heap_free( buffer );
5548 return FALSE;
5550 relative->Control |= SE_SELF_RELATIVE;
5551 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5553 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5554 relative->Owner = offset;
5555 offset += sizeof(sidWorld);
5557 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5558 relative->Group = offset;
5559 offset += sizeof(sidWorld);
5561 GetWorldAccessACL( (ACL *)(buffer + offset) );
5562 relative->Dacl = offset;
5563 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5565 GetWorldAccessACL( (ACL *)(buffer + offset) );
5566 relative->Sacl = offset;
5568 *out = relative;
5569 return TRUE;
5572 BOOL WINAPI CreatePrivateObjectSecurity(
5573 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5574 BOOL is_container, HANDLE token, PGENERIC_MAPPING mapping)
5576 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, 0, token, mapping);
5579 BOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(
5580 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5581 GUID **types, ULONG count, BOOL is_container, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5583 FIXME(": semi-stub\n");
5584 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, flags, token, mapping);
5587 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5589 FIXME("%p - stub\n", ObjectDescriptor);
5591 heap_free( *ObjectDescriptor );
5592 return TRUE;
5595 /******************************************************************************
5596 * CreateProcessWithLogonW
5598 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5599 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5600 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5602 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5603 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5604 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5605 lpStartupInfo, lpProcessInformation);
5607 return FALSE;
5610 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5611 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5612 PROCESS_INFORMATION *process_information )
5614 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5615 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5616 creation_flags, environment, debugstr_w(current_directory),
5617 startup_info, process_information);
5619 /* FIXME: check if handles should be inherited */
5620 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5621 current_directory, startup_info, process_information );
5624 /******************************************************************************
5625 * DuplicateTokenEx [ADVAPI32.@]
5627 BOOL WINAPI DuplicateTokenEx(
5628 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5629 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5630 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5631 TOKEN_TYPE TokenType,
5632 PHANDLE DuplicateTokenHandle )
5634 OBJECT_ATTRIBUTES ObjectAttributes;
5636 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5637 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5639 InitializeObjectAttributes(
5640 &ObjectAttributes,
5641 NULL,
5642 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5643 NULL,
5644 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5646 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5647 dwDesiredAccess,
5648 &ObjectAttributes,
5649 ImpersonationLevel,
5650 TokenType,
5651 DuplicateTokenHandle ) );
5654 BOOL WINAPI DuplicateToken(
5655 HANDLE ExistingTokenHandle,
5656 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5657 PHANDLE DuplicateTokenHandle )
5659 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5660 NULL, ImpersonationLevel, TokenImpersonation,
5661 DuplicateTokenHandle );
5664 /******************************************************************************
5665 * ComputeStringSidSize
5667 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5669 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5671 int ctok = 0;
5672 while (*StringSid)
5674 if (*StringSid == '-')
5675 ctok++;
5676 StringSid++;
5679 if (ctok >= 3)
5680 return GetSidLengthRequired(ctok - 2);
5682 else /* String constant format - Only available in winxp and above */
5684 unsigned int i;
5686 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5687 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5688 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5690 for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
5691 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5693 MAX_SID local;
5694 ADVAPI_GetComputerSid(&local);
5695 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5700 return GetSidLengthRequired(0);
5703 /******************************************************************************
5704 * ParseStringSidToSid
5706 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5708 BOOL bret = FALSE;
5709 SID* pisid=pSid;
5711 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5712 if (!StringSid)
5714 SetLastError(ERROR_INVALID_PARAMETER);
5715 TRACE("StringSid is NULL, returning FALSE\n");
5716 return FALSE;
5719 while (*StringSid == ' ')
5720 StringSid++;
5722 *cBytes = ComputeStringSidSize(StringSid);
5723 if (!pisid) /* Simply compute the size */
5725 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5726 return TRUE;
5729 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5731 DWORD i = 0, identAuth;
5732 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5734 StringSid += 2; /* Advance to Revision */
5735 pisid->Revision = atoiW(StringSid);
5737 if (pisid->Revision != SDDL_REVISION)
5739 TRACE("Revision %d is unknown\n", pisid->Revision);
5740 goto lend; /* ERROR_INVALID_SID */
5742 if (csubauth == 0)
5744 TRACE("SubAuthorityCount is 0\n");
5745 goto lend; /* ERROR_INVALID_SID */
5748 pisid->SubAuthorityCount = csubauth;
5750 /* Advance to identifier authority */
5751 while (*StringSid && *StringSid != '-')
5752 StringSid++;
5753 if (*StringSid == '-')
5754 StringSid++;
5756 /* MS' implementation can't handle values greater than 2^32 - 1, so
5757 * we don't either; assume most significant bytes are always 0
5759 pisid->IdentifierAuthority.Value[0] = 0;
5760 pisid->IdentifierAuthority.Value[1] = 0;
5761 identAuth = atoiW(StringSid);
5762 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5763 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5764 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5765 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5767 /* Advance to first sub authority */
5768 while (*StringSid && *StringSid != '-')
5769 StringSid++;
5770 if (*StringSid == '-')
5771 StringSid++;
5773 while (*StringSid)
5775 pisid->SubAuthority[i++] = atoiW(StringSid);
5777 while (*StringSid && *StringSid != '-')
5778 StringSid++;
5779 if (*StringSid == '-')
5780 StringSid++;
5783 if (i != pisid->SubAuthorityCount)
5784 goto lend; /* ERROR_INVALID_SID */
5786 bret = TRUE;
5788 else /* String constant format - Only available in winxp and above */
5790 unsigned int i;
5791 pisid->Revision = SDDL_REVISION;
5793 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5794 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5796 DWORD j;
5797 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5798 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5799 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5800 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5801 bret = TRUE;
5804 for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
5805 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5807 ADVAPI_GetComputerSid(pisid);
5808 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5809 pisid->SubAuthorityCount++;
5810 bret = TRUE;
5813 if (!bret)
5814 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5817 lend:
5818 if (!bret)
5819 SetLastError(ERROR_INVALID_SID);
5821 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5822 return bret;
5825 /******************************************************************************
5826 * GetNamedSecurityInfoA [ADVAPI32.@]
5828 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5829 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5830 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5831 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5833 LPWSTR wstr;
5834 DWORD r;
5836 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5837 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5839 wstr = SERV_dup(pObjectName);
5840 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5841 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5843 heap_free( wstr );
5845 return r;
5848 /******************************************************************************
5849 * GetNamedSecurityInfoW [ADVAPI32.@]
5851 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5852 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5853 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5855 DWORD access = 0;
5856 HANDLE handle;
5857 DWORD err;
5859 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5860 group, dacl, sacl, descriptor );
5862 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5863 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5865 /* If no descriptor, we have to check that there's a pointer for the requested information */
5866 if( !descriptor && (
5867 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5868 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5869 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5870 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5871 return ERROR_INVALID_PARAMETER;
5873 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5874 access |= READ_CONTROL;
5875 if (info & SACL_SECURITY_INFORMATION)
5876 access |= ACCESS_SYSTEM_SECURITY;
5878 switch (type)
5880 case SE_SERVICE:
5881 if (!(err = get_security_service( name, access, &handle )))
5883 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5884 CloseServiceHandle( handle );
5886 break;
5887 case SE_REGISTRY_KEY:
5888 if (!(err = get_security_regkey( name, access, &handle )))
5890 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5891 RegCloseKey( handle );
5893 break;
5894 case SE_FILE_OBJECT:
5895 if (!(err = get_security_file( name, access, &handle )))
5897 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5898 CloseHandle( handle );
5900 break;
5901 default:
5902 FIXME( "Object type %d is not currently supported.\n", type );
5903 if (owner) *owner = NULL;
5904 if (group) *group = NULL;
5905 if (dacl) *dacl = NULL;
5906 if (sacl) *sacl = NULL;
5907 if (descriptor) *descriptor = NULL;
5908 return ERROR_SUCCESS;
5910 return err;
5913 /******************************************************************************
5914 * GetNamedSecurityInfoExW [ADVAPI32.@]
5916 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5917 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5918 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5920 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5921 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5922 return ERROR_CALL_NOT_IMPLEMENTED;
5925 /******************************************************************************
5926 * GetNamedSecurityInfoExA [ADVAPI32.@]
5928 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5929 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5930 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5932 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5933 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5934 return ERROR_CALL_NOT_IMPLEMENTED;
5937 /******************************************************************************
5938 * DecryptFileW [ADVAPI32.@]
5940 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5942 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5943 return TRUE;
5946 /******************************************************************************
5947 * DecryptFileA [ADVAPI32.@]
5949 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5951 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5952 return TRUE;
5955 /******************************************************************************
5956 * EncryptFileW [ADVAPI32.@]
5958 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5960 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5961 return TRUE;
5964 /******************************************************************************
5965 * EncryptFileA [ADVAPI32.@]
5967 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5969 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5970 return TRUE;
5973 /******************************************************************************
5974 * FileEncryptionStatusW [ADVAPI32.@]
5976 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5978 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5979 if (!lpStatus)
5980 return FALSE;
5981 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5982 return TRUE;
5985 /******************************************************************************
5986 * FileEncryptionStatusA [ADVAPI32.@]
5988 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5990 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5991 if (!lpStatus)
5992 return FALSE;
5993 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5994 return TRUE;
5997 static NTSTATUS combine_dacls(ACL *parent, ACL *child, ACL **result)
5999 NTSTATUS status;
6000 ACL *combined;
6001 int i;
6003 /* initialize a combined DACL containing both inherited and new ACEs */
6004 combined = heap_alloc_zero(child->AclSize+parent->AclSize);
6005 if (!combined)
6006 return STATUS_NO_MEMORY;
6008 status = RtlCreateAcl(combined, parent->AclSize+child->AclSize, ACL_REVISION);
6009 if (status != STATUS_SUCCESS)
6011 heap_free(combined);
6012 return status;
6015 /* copy the new ACEs */
6016 for (i=0; i<child->AceCount; i++)
6018 ACE_HEADER *ace;
6020 if (!GetAce(child, i, (void*)&ace))
6021 continue;
6022 if (!AddAce(combined, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
6023 WARN("error adding new ACE\n");
6026 /* copy the inherited ACEs */
6027 for (i=0; i<parent->AceCount; i++)
6029 ACE_HEADER *ace;
6031 if (!GetAce(parent, i, (void*)&ace))
6032 continue;
6033 if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
6034 continue;
6035 if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
6036 (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
6038 FIXME("unsupported flags: %x\n", ace->AceFlags);
6039 continue;
6042 if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
6043 ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
6044 ace->AceFlags &= ~INHERIT_ONLY_ACE;
6045 ace->AceFlags |= INHERITED_ACE;
6047 if (!AddAce(combined, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
6048 WARN("error adding inherited ACE\n");
6051 *result = combined;
6052 return STATUS_SUCCESS;
6055 /******************************************************************************
6056 * SetSecurityInfo [ADVAPI32.@]
6058 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
6059 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
6060 PSID psidGroup, PACL pDacl, PACL pSacl)
6062 SECURITY_DESCRIPTOR sd;
6063 PACL dacl = pDacl;
6064 NTSTATUS status;
6066 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
6067 return ERROR_INVALID_SECURITY_DESCR;
6069 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
6070 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
6071 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
6072 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
6073 if (SecurityInfo & DACL_SECURITY_INFORMATION)
6075 if (ObjectType == SE_FILE_OBJECT && pDacl)
6077 SECURITY_DESCRIPTOR_CONTROL control;
6078 PSECURITY_DESCRIPTOR psd;
6079 OBJECT_NAME_INFORMATION *name_info;
6080 DWORD size, rev;
6082 status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
6083 if (status != STATUS_BUFFER_TOO_SMALL)
6084 return RtlNtStatusToDosError(status);
6086 psd = heap_alloc(size);
6087 if (!psd)
6088 return ERROR_NOT_ENOUGH_MEMORY;
6090 status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
6091 if (status)
6093 heap_free(psd);
6094 return RtlNtStatusToDosError(status);
6097 status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
6098 heap_free(psd);
6099 if (status)
6100 return RtlNtStatusToDosError(status);
6101 /* TODO: copy some control flags to new sd */
6103 /* inherit parent directory DACL */
6104 if (!(control & SE_DACL_PROTECTED))
6106 status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
6107 if (status != STATUS_INFO_LENGTH_MISMATCH)
6108 return RtlNtStatusToDosError(status);
6110 name_info = heap_alloc(size);
6111 if (!name_info)
6112 return ERROR_NOT_ENOUGH_MEMORY;
6114 status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
6115 if (status)
6117 heap_free(name_info);
6118 return RtlNtStatusToDosError(status);
6121 for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
6122 if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
6123 name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
6124 break;
6125 if (name_info->Name.Length)
6127 OBJECT_ATTRIBUTES attr;
6128 IO_STATUS_BLOCK io;
6129 HANDLE parent;
6130 PSECURITY_DESCRIPTOR parent_sd;
6131 ACL *parent_dacl;
6132 DWORD err = ERROR_ACCESS_DENIED;
6134 name_info->Name.Buffer[name_info->Name.Length/2] = 0;
6136 attr.Length = sizeof(attr);
6137 attr.RootDirectory = 0;
6138 attr.Attributes = 0;
6139 attr.ObjectName = &name_info->Name;
6140 attr.SecurityDescriptor = NULL;
6141 status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
6142 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6143 FILE_OPEN_FOR_BACKUP_INTENT);
6144 heap_free(name_info);
6145 if (!status)
6147 err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
6148 NULL, NULL, &parent_dacl, NULL, &parent_sd);
6149 CloseHandle(parent);
6152 if (!err)
6154 status = combine_dacls(parent_dacl, pDacl, &dacl);
6155 LocalFree(parent_sd);
6156 if (status != STATUS_SUCCESS)
6157 return RtlNtStatusToDosError(status);
6160 else
6161 heap_free(name_info);
6165 SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
6167 if (SecurityInfo & SACL_SECURITY_INFORMATION)
6168 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
6170 switch (ObjectType)
6172 case SE_SERVICE:
6173 FIXME("stub: Service objects are not supported at this time.\n");
6174 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
6175 break;
6176 default:
6177 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
6178 break;
6180 if (dacl != pDacl)
6181 heap_free(dacl);
6182 return RtlNtStatusToDosError(status);
6185 /******************************************************************************
6186 * SaferCreateLevel [ADVAPI32.@]
6188 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
6189 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
6191 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
6193 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6194 return TRUE;
6197 /******************************************************************************
6198 * SaferComputeTokenFromLevel [ADVAPI32.@]
6200 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
6201 DWORD flags, LPVOID reserved)
6203 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
6205 *access_token = (flags & SAFER_TOKEN_NULL_IF_EQUAL) ? NULL : (HANDLE)0xdeadbeef;
6206 return TRUE;
6209 /******************************************************************************
6210 * SaferCloseLevel [ADVAPI32.@]
6212 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
6214 FIXME("(%p) stub\n", handle);
6215 return TRUE;
6218 /******************************************************************************
6219 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
6221 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
6222 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
6223 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
6224 BOOL KeepExplicit, FN_PROGRESS fnProgress,
6225 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
6227 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
6228 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
6229 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
6231 return ERROR_SUCCESS;
6234 /******************************************************************************
6235 * SaferGetPolicyInformation [ADVAPI32.@]
6237 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
6238 PVOID buffer, PDWORD required, LPVOID lpReserved)
6240 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
6241 return FALSE;
6244 /******************************************************************************
6245 * SaferIdentifyLevel [ADVAPI32.@]
6247 BOOL WINAPI SaferIdentifyLevel(DWORD count, SAFER_CODE_PROPERTIES *properties, SAFER_LEVEL_HANDLE *handle,
6248 void *reserved)
6250 FIXME("(%u %p %p %p) stub\n", count, properties, handle, reserved);
6251 *handle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6252 return TRUE;
6255 /******************************************************************************
6256 * SaferSetLevelInformation [ADVAPI32.@]
6258 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
6259 LPVOID buffer, DWORD size)
6261 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
6262 return FALSE;
6265 /******************************************************************************
6266 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
6268 DWORD WINAPI LookupSecurityDescriptorPartsA(TRUSTEEA *owner, TRUSTEEA *group, ULONG *access_count,
6269 EXPLICIT_ACCESSA *access_list, ULONG *audit_count,
6270 EXPLICIT_ACCESSA *audit_list, SECURITY_DESCRIPTOR *descriptor)
6272 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6273 access_list, audit_count, audit_list, descriptor);
6274 return ERROR_CALL_NOT_IMPLEMENTED;
6277 /******************************************************************************
6278 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
6280 DWORD WINAPI LookupSecurityDescriptorPartsW(TRUSTEEW *owner, TRUSTEEW *group, ULONG *access_count,
6281 EXPLICIT_ACCESSW *access_list, ULONG *audit_count,
6282 EXPLICIT_ACCESSW *audit_list, SECURITY_DESCRIPTOR *descriptor)
6284 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6285 access_list, audit_count, audit_list, descriptor);
6286 return ERROR_CALL_NOT_IMPLEMENTED;