wined3d: Split clears for different size resources in ffp_blitter_clear().
[wine.git] / dlls / advapi32 / security.c
blob70e2da40e7ac191eae3317c5756c7912afe96e21
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 * LookupAccountSidW [ADVAPI32.@]
2321 * PARAMS
2322 * system []
2323 * sid []
2324 * account []
2325 * accountSize []
2326 * domain []
2327 * domainSize []
2328 * name_use []
2331 BOOL WINAPI
2332 LookupAccountSidW(
2333 IN LPCWSTR system,
2334 IN PSID sid,
2335 OUT LPWSTR account,
2336 IN OUT LPDWORD accountSize,
2337 OUT LPWSTR domain,
2338 IN OUT LPDWORD domainSize,
2339 OUT PSID_NAME_USE name_use )
2341 unsigned int i, j;
2342 const WCHAR * ac = NULL;
2343 const WCHAR * dm = NULL;
2344 SID_NAME_USE use = 0;
2345 LPWSTR computer_name = NULL;
2346 LPWSTR account_name = NULL;
2348 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2349 debugstr_w(system),debugstr_sid(sid),
2350 account,accountSize,accountSize?*accountSize:0,
2351 domain,domainSize,domainSize?*domainSize:0,
2352 name_use);
2354 if (!ADVAPI_IsLocalComputer(system)) {
2355 FIXME("Only local computer supported!\n");
2356 SetLastError(RPC_S_SERVER_UNAVAILABLE);
2357 return FALSE;
2360 /* check the well known SIDs first */
2361 for (i = 0; i <= WinAccountProtectedUsersSid; i++) {
2362 if (IsWellKnownSid(sid, i)) {
2363 for (j = 0; j < ARRAY_SIZE(ACCOUNT_SIDS); j++) {
2364 if (ACCOUNT_SIDS[j].type == i) {
2365 ac = ACCOUNT_SIDS[j].account;
2366 dm = ACCOUNT_SIDS[j].domain;
2367 use = ACCOUNT_SIDS[j].name_use;
2370 break;
2374 if (dm == NULL) {
2375 MAX_SID local;
2377 /* check for the local computer next */
2378 if (ADVAPI_GetComputerSid(&local)) {
2379 DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2380 BOOL result;
2382 computer_name = heap_alloc(size * sizeof(WCHAR));
2383 result = GetComputerNameW(computer_name, &size);
2385 if (result) {
2386 if (EqualSid(sid, &local)) {
2387 dm = computer_name;
2388 ac = Blank;
2389 use = 3;
2390 } else {
2391 local.SubAuthorityCount++;
2393 if (EqualPrefixSid(sid, &local)) {
2394 dm = computer_name;
2395 use = 1;
2396 switch (((MAX_SID *)sid)->SubAuthority[4]) {
2397 case DOMAIN_USER_RID_ADMIN:
2398 ac = Administrator;
2399 break;
2400 case DOMAIN_USER_RID_GUEST:
2401 ac = Guest;
2402 break;
2403 case DOMAIN_GROUP_RID_ADMINS:
2404 ac = Domain_Admins;
2405 break;
2406 case DOMAIN_GROUP_RID_USERS:
2407 ac = Domain_Users;
2408 break;
2409 case DOMAIN_GROUP_RID_GUESTS:
2410 ac = Domain_Guests;
2411 break;
2412 case DOMAIN_GROUP_RID_COMPUTERS:
2413 ac = Domain_Computers;
2414 break;
2415 case DOMAIN_GROUP_RID_CONTROLLERS:
2416 ac = Domain_Controllers;
2417 break;
2418 case DOMAIN_GROUP_RID_CERT_ADMINS:
2419 ac = Cert_Publishers;
2420 break;
2421 case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2422 ac = Schema_Admins;
2423 break;
2424 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2425 ac = Enterprise_Admins;
2426 break;
2427 case DOMAIN_GROUP_RID_POLICY_ADMINS:
2428 ac = Group_Policy_Creator_Owners;
2429 break;
2430 case DOMAIN_ALIAS_RID_RAS_SERVERS:
2431 ac = RAS_and_IAS_Servers;
2432 break;
2433 case 1000: /* first user account */
2434 size = UNLEN + 1;
2435 account_name = heap_alloc(size * sizeof(WCHAR));
2436 if (GetUserNameW(account_name, &size))
2437 ac = account_name;
2438 else
2439 dm = NULL;
2441 break;
2442 default:
2443 dm = NULL;
2444 break;
2452 if (dm) {
2453 DWORD ac_len = lstrlenW(ac);
2454 DWORD dm_len = lstrlenW(dm);
2455 BOOL status = TRUE;
2457 if (*accountSize > ac_len) {
2458 if (account)
2459 lstrcpyW(account, ac);
2461 if (*domainSize > dm_len) {
2462 if (domain)
2463 lstrcpyW(domain, dm);
2465 if ((*accountSize && *accountSize < ac_len) ||
2466 (!account && !*accountSize && ac_len) ||
2467 (*domainSize && *domainSize < dm_len) ||
2468 (!domain && !*domainSize && dm_len))
2470 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2471 status = FALSE;
2473 if (*domainSize)
2474 *domainSize = dm_len;
2475 else
2476 *domainSize = dm_len + 1;
2477 if (*accountSize)
2478 *accountSize = ac_len;
2479 else
2480 *accountSize = ac_len + 1;
2482 heap_free(account_name);
2483 heap_free(computer_name);
2484 if (status) *name_use = use;
2485 return status;
2488 heap_free(account_name);
2489 heap_free(computer_name);
2490 SetLastError(ERROR_NONE_MAPPED);
2491 return FALSE;
2494 /******************************************************************************
2495 * SetFileSecurityA [ADVAPI32.@]
2497 * See SetFileSecurityW.
2499 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2500 SECURITY_INFORMATION RequestedInformation,
2501 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2503 BOOL r;
2504 LPWSTR name;
2506 name = SERV_dup(lpFileName);
2507 r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2508 heap_free( name );
2510 return r;
2513 /******************************************************************************
2514 * SetFileSecurityW [ADVAPI32.@]
2516 * Sets the security of a file or directory.
2518 * PARAMS
2519 * lpFileName []
2520 * RequestedInformation []
2521 * pSecurityDescriptor []
2523 * RETURNS
2524 * Success: TRUE.
2525 * Failure: FALSE.
2527 BOOL WINAPI
2528 SetFileSecurityW( LPCWSTR lpFileName,
2529 SECURITY_INFORMATION RequestedInformation,
2530 PSECURITY_DESCRIPTOR pSecurityDescriptor )
2532 HANDLE file;
2533 DWORD access = 0, err;
2534 NTSTATUS status;
2536 TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2537 pSecurityDescriptor );
2539 if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2540 RequestedInformation & GROUP_SECURITY_INFORMATION)
2541 access |= WRITE_OWNER;
2542 if (RequestedInformation & SACL_SECURITY_INFORMATION)
2543 access |= ACCESS_SYSTEM_SECURITY;
2544 if (RequestedInformation & DACL_SECURITY_INFORMATION)
2545 access |= WRITE_DAC;
2547 err = get_security_file( lpFileName, access, &file);
2548 if (err)
2550 SetLastError(err);
2551 return FALSE;
2554 status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2555 CloseHandle( file );
2556 return set_ntstatus( status );
2559 /******************************************************************************
2560 * QueryWindows31FilesMigration [ADVAPI32.@]
2562 * PARAMS
2563 * x1 []
2565 BOOL WINAPI
2566 QueryWindows31FilesMigration( DWORD x1 )
2568 FIXME("(%d):stub\n",x1);
2569 return TRUE;
2572 /******************************************************************************
2573 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2575 * PARAMS
2576 * x1 []
2577 * x2 []
2578 * x3 []
2579 * x4 []
2581 BOOL WINAPI
2582 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2583 DWORD x4 )
2585 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2586 return TRUE;
2589 /******************************************************************************
2590 * NotifyBootConfigStatus [ADVAPI32.@]
2592 * PARAMS
2593 * x1 []
2595 BOOL WINAPI
2596 NotifyBootConfigStatus( BOOL x1 )
2598 FIXME("(0x%08d):stub\n",x1);
2599 return TRUE;
2602 /******************************************************************************
2603 * RevertToSelf [ADVAPI32.@]
2605 * Ends the impersonation of a user.
2607 * PARAMS
2608 * void []
2610 * RETURNS
2611 * Success: TRUE.
2612 * Failure: FALSE.
2614 BOOL WINAPI
2615 RevertToSelf( void )
2617 HANDLE Token = NULL;
2618 return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2619 ThreadImpersonationToken, &Token, sizeof(Token) ) );
2622 /******************************************************************************
2623 * ImpersonateSelf [ADVAPI32.@]
2625 * Makes an impersonation token that represents the process user and assigns
2626 * to the current thread.
2628 * PARAMS
2629 * ImpersonationLevel [I] Level at which to impersonate.
2631 * RETURNS
2632 * Success: TRUE.
2633 * Failure: FALSE.
2635 BOOL WINAPI
2636 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2638 return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2641 /******************************************************************************
2642 * ImpersonateLoggedOnUser [ADVAPI32.@]
2644 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2646 DWORD size;
2647 NTSTATUS Status;
2648 HANDLE ImpersonationToken;
2649 TOKEN_TYPE Type;
2650 static BOOL warn = TRUE;
2652 if (warn)
2654 FIXME( "(%p)\n", hToken );
2655 warn = FALSE;
2657 if (!GetTokenInformation( hToken, TokenType, &Type,
2658 sizeof(TOKEN_TYPE), &size ))
2659 return FALSE;
2661 if (Type == TokenPrimary)
2663 OBJECT_ATTRIBUTES ObjectAttributes;
2665 InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2667 Status = NtDuplicateToken( hToken,
2668 TOKEN_IMPERSONATE | TOKEN_QUERY,
2669 &ObjectAttributes,
2670 SecurityImpersonation,
2671 TokenImpersonation,
2672 &ImpersonationToken );
2673 if (Status != STATUS_SUCCESS)
2675 ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2676 SetLastError( RtlNtStatusToDosError( Status ) );
2677 return FALSE;
2680 else
2681 ImpersonationToken = hToken;
2683 Status = NtSetInformationThread( GetCurrentThread(),
2684 ThreadImpersonationToken,
2685 &ImpersonationToken,
2686 sizeof(ImpersonationToken) );
2688 if (Type == TokenPrimary)
2689 NtClose( ImpersonationToken );
2691 if (Status != STATUS_SUCCESS)
2693 ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2694 SetLastError( RtlNtStatusToDosError( Status ) );
2695 return FALSE;
2698 return TRUE;
2701 /******************************************************************************
2702 * ImpersonateAnonymousToken [ADVAPI32.@]
2704 BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
2706 TRACE("(%p)\n", thread);
2707 return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
2710 /******************************************************************************
2711 * AccessCheck [ADVAPI32.@]
2713 BOOL WINAPI
2714 AccessCheck(
2715 PSECURITY_DESCRIPTOR SecurityDescriptor,
2716 HANDLE ClientToken,
2717 DWORD DesiredAccess,
2718 PGENERIC_MAPPING GenericMapping,
2719 PPRIVILEGE_SET PrivilegeSet,
2720 LPDWORD PrivilegeSetLength,
2721 LPDWORD GrantedAccess,
2722 LPBOOL AccessStatus)
2724 NTSTATUS access_status;
2725 BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2726 GenericMapping, PrivilegeSet, PrivilegeSetLength,
2727 GrantedAccess, &access_status) );
2728 if (ret) *AccessStatus = set_ntstatus( access_status );
2729 return ret;
2733 /******************************************************************************
2734 * AccessCheckByType [ADVAPI32.@]
2736 BOOL WINAPI AccessCheckByType(
2737 PSECURITY_DESCRIPTOR pSecurityDescriptor,
2738 PSID PrincipalSelfSid,
2739 HANDLE ClientToken,
2740 DWORD DesiredAccess,
2741 POBJECT_TYPE_LIST ObjectTypeList,
2742 DWORD ObjectTypeListLength,
2743 PGENERIC_MAPPING GenericMapping,
2744 PPRIVILEGE_SET PrivilegeSet,
2745 LPDWORD PrivilegeSetLength,
2746 LPDWORD GrantedAccess,
2747 LPBOOL AccessStatus)
2749 FIXME("stub\n");
2751 *AccessStatus = TRUE;
2753 return !*AccessStatus;
2756 /******************************************************************************
2757 * MapGenericMask [ADVAPI32.@]
2759 * Maps generic access rights into specific access rights according to the
2760 * supplied mapping.
2762 * PARAMS
2763 * AccessMask [I/O] Access rights.
2764 * GenericMapping [I] The mapping between generic and specific rights.
2766 * RETURNS
2767 * Nothing.
2769 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2771 RtlMapGenericMask( AccessMask, GenericMapping );
2774 /*************************************************************************
2775 * SetKernelObjectSecurity [ADVAPI32.@]
2777 BOOL WINAPI SetKernelObjectSecurity (
2778 IN HANDLE Handle,
2779 IN SECURITY_INFORMATION SecurityInformation,
2780 IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2782 return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2786 /******************************************************************************
2787 * AddAuditAccessAce [ADVAPI32.@]
2789 BOOL WINAPI AddAuditAccessAce(
2790 IN OUT PACL pAcl,
2791 IN DWORD dwAceRevision,
2792 IN DWORD dwAccessMask,
2793 IN PSID pSid,
2794 IN BOOL bAuditSuccess,
2795 IN BOOL bAuditFailure)
2797 return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid,
2798 bAuditSuccess, bAuditFailure) );
2801 /******************************************************************************
2802 * AddAuditAccessAceEx [ADVAPI32.@]
2804 BOOL WINAPI AddAuditAccessAceEx(
2805 IN OUT PACL pAcl,
2806 IN DWORD dwAceRevision,
2807 IN DWORD dwAceFlags,
2808 IN DWORD dwAccessMask,
2809 IN PSID pSid,
2810 IN BOOL bAuditSuccess,
2811 IN BOOL bAuditFailure)
2813 return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2814 bAuditSuccess, bAuditFailure) );
2817 /******************************************************************************
2818 * AddAuditAccessObjectAce [ADVAPI32.@]
2820 BOOL WINAPI AddAuditAccessObjectAce(
2821 IN OUT PACL pAcl,
2822 IN DWORD dwAceRevision,
2823 IN DWORD dwAceFlags,
2824 IN DWORD dwAccessMask,
2825 IN GUID* pObjectTypeGuid,
2826 IN GUID* pInheritedObjectTypeGuid,
2827 IN PSID pSid,
2828 IN BOOL bAuditSuccess,
2829 IN BOOL bAuditFailure)
2831 return set_ntstatus( RtlAddAuditAccessObjectAce(pAcl, dwAceRevision, dwAceFlags, dwAccessMask,
2832 pObjectTypeGuid, pInheritedObjectTypeGuid, pSid, bAuditSuccess, bAuditFailure) );
2835 /******************************************************************************
2836 * LookupAccountNameA [ADVAPI32.@]
2838 BOOL WINAPI
2839 LookupAccountNameA(
2840 IN LPCSTR system,
2841 IN LPCSTR account,
2842 OUT PSID sid,
2843 OUT LPDWORD cbSid,
2844 LPSTR ReferencedDomainName,
2845 IN OUT LPDWORD cbReferencedDomainName,
2846 OUT PSID_NAME_USE name_use )
2848 BOOL ret;
2849 UNICODE_STRING lpSystemW;
2850 UNICODE_STRING lpAccountW;
2851 LPWSTR lpReferencedDomainNameW = NULL;
2853 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2854 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2856 if (ReferencedDomainName)
2857 lpReferencedDomainNameW = heap_alloc(*cbReferencedDomainName * sizeof(WCHAR));
2859 ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2860 cbReferencedDomainName, name_use);
2862 if (ret && lpReferencedDomainNameW)
2864 WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2865 ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2868 RtlFreeUnicodeString(&lpSystemW);
2869 RtlFreeUnicodeString(&lpAccountW);
2870 heap_free(lpReferencedDomainNameW);
2872 return ret;
2875 /******************************************************************************
2876 * lookup_user_account_name
2878 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2879 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2881 char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2882 DWORD len = sizeof(buffer);
2883 HANDLE token;
2884 BOOL ret;
2885 PSID pSid;
2886 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2887 DWORD nameLen;
2889 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2891 if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2892 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2895 ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2896 CloseHandle( token );
2898 if (!ret) return FALSE;
2900 pSid = ((TOKEN_USER *)buffer)->User.Sid;
2902 if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2903 CopySid(*cbSid, Sid, pSid);
2904 if (*cbSid < GetLengthSid(pSid))
2906 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2907 ret = FALSE;
2909 *cbSid = GetLengthSid(pSid);
2911 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2912 if (!GetComputerNameW(domainName, &nameLen))
2914 domainName[0] = 0;
2915 nameLen = 0;
2917 if (*cchReferencedDomainName <= nameLen || !ret)
2919 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2920 nameLen += 1;
2921 ret = FALSE;
2923 else if (ReferencedDomainName)
2924 strcpyW(ReferencedDomainName, domainName);
2926 *cchReferencedDomainName = nameLen;
2928 if (ret)
2929 *peUse = SidTypeUser;
2931 return ret;
2934 /******************************************************************************
2935 * lookup_computer_account_name
2937 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2938 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2940 MAX_SID local;
2941 BOOL ret;
2942 WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2943 DWORD nameLen;
2945 if ((ret = ADVAPI_GetComputerSid(&local)))
2947 if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2948 CopySid(*cbSid, Sid, &local);
2949 if (*cbSid < GetLengthSid(&local))
2951 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2952 ret = FALSE;
2954 *cbSid = GetLengthSid(&local);
2957 nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2958 if (!GetComputerNameW(domainName, &nameLen))
2960 domainName[0] = 0;
2961 nameLen = 0;
2963 if (*cchReferencedDomainName <= nameLen || !ret)
2965 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2966 nameLen += 1;
2967 ret = FALSE;
2969 else if (ReferencedDomainName)
2970 strcpyW(ReferencedDomainName, domainName);
2972 *cchReferencedDomainName = nameLen;
2974 if (ret)
2975 *peUse = SidTypeDomain;
2977 return ret;
2980 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2981 LSA_UNICODE_STRING *domain )
2983 WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2985 while (p > str->Buffer && *p != '\\') p--;
2987 if (*p == '\\')
2989 domain->Buffer = str->Buffer;
2990 domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2992 account->Buffer = p + 1;
2993 account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2995 else
2997 domain->Buffer = NULL;
2998 domain->Length = 0;
3000 account->Buffer = str->Buffer;
3001 account->Length = str->Length;
3005 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
3007 ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
3009 if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
3010 return TRUE;
3012 return FALSE;
3015 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
3017 ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
3019 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
3020 return TRUE;
3022 if (ACCOUNT_SIDS[idx].alias)
3024 len = strlenW( ACCOUNT_SIDS[idx].alias );
3025 if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
3026 return TRUE;
3028 return FALSE;
3032 * Helper function for LookupAccountNameW
3034 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
3035 PSID Sid, LPDWORD cbSid,
3036 LPWSTR ReferencedDomainName,
3037 LPDWORD cchReferencedDomainName,
3038 PSID_NAME_USE peUse, BOOL *handled )
3040 PSID pSid;
3041 LSA_UNICODE_STRING account, domain;
3042 BOOL ret = TRUE;
3043 ULONG i;
3045 *handled = FALSE;
3046 split_domain_account( account_and_domain, &account, &domain );
3048 for (i = 0; i < ARRAY_SIZE(ACCOUNT_SIDS); i++)
3050 /* check domain first */
3051 if (domain.Buffer && !match_domain( i, &domain )) continue;
3053 if (match_account( i, &account ))
3055 DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
3057 if (!(pSid = heap_alloc( sidLen ))) return FALSE;
3059 if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
3061 if (*cbSid < sidLen)
3063 SetLastError(ERROR_INSUFFICIENT_BUFFER);
3064 ret = FALSE;
3066 else if (Sid)
3068 CopySid(*cbSid, Sid, pSid);
3070 *cbSid = sidLen;
3073 len = strlenW( ACCOUNT_SIDS[i].domain );
3074 if (*cchReferencedDomainName <= len || !ret)
3076 SetLastError(ERROR_INSUFFICIENT_BUFFER);
3077 len++;
3078 ret = FALSE;
3080 else if (ReferencedDomainName)
3082 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
3085 *cchReferencedDomainName = len;
3086 if (ret)
3087 *peUse = ACCOUNT_SIDS[i].name_use;
3089 heap_free(pSid);
3090 *handled = TRUE;
3091 return ret;
3094 return ret;
3097 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
3098 PSID Sid, LPDWORD cbSid,
3099 LPWSTR ReferencedDomainName,
3100 LPDWORD cchReferencedDomainName,
3101 PSID_NAME_USE peUse, BOOL *handled )
3103 DWORD nameLen;
3104 LPWSTR userName = NULL;
3105 LSA_UNICODE_STRING account, domain;
3106 BOOL ret = TRUE;
3108 *handled = FALSE;
3109 split_domain_account( account_and_domain, &account, &domain );
3111 /* Let the current Unix user id masquerade as first Windows user account */
3113 nameLen = UNLEN + 1;
3114 if (!(userName = heap_alloc( nameLen * sizeof(WCHAR) ))) return FALSE;
3116 if (domain.Buffer)
3118 /* check to make sure this account is on this computer */
3119 if (GetComputerNameW( userName, &nameLen ) &&
3120 (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
3122 SetLastError(ERROR_NONE_MAPPED);
3123 ret = FALSE;
3125 nameLen = UNLEN + 1;
3128 if (GetUserNameW( userName, &nameLen ) &&
3129 account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
3131 ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3132 *handled = TRUE;
3134 else
3136 nameLen = UNLEN + 1;
3137 if (GetComputerNameW( userName, &nameLen ) &&
3138 account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
3140 ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
3141 *handled = TRUE;
3145 heap_free(userName);
3146 return ret;
3149 /******************************************************************************
3150 * LookupAccountNameW [ADVAPI32.@]
3152 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
3153 LPDWORD cbSid, LPWSTR ReferencedDomainName,
3154 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
3156 BOOL ret, handled;
3157 LSA_UNICODE_STRING account;
3159 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
3160 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
3162 if (!ADVAPI_IsLocalComputer( lpSystemName ))
3164 FIXME("remote computer not supported\n");
3165 SetLastError( RPC_S_SERVER_UNAVAILABLE );
3166 return FALSE;
3169 if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
3171 lpAccountName = BUILTIN;
3174 RtlInitUnicodeString( &account, lpAccountName );
3176 /* Check well known SIDs first */
3177 ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
3178 cchReferencedDomainName, peUse, &handled );
3179 if (handled)
3180 return ret;
3182 /* Check user names */
3183 ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
3184 cchReferencedDomainName, peUse, &handled);
3185 if (handled)
3186 return ret;
3188 SetLastError( ERROR_NONE_MAPPED );
3189 return FALSE;
3192 /******************************************************************************
3193 * PrivilegeCheck [ADVAPI32.@]
3195 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
3197 BOOL ret;
3198 BOOLEAN Result;
3200 TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
3202 ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
3203 if (ret)
3204 *pfResult = Result;
3205 return ret;
3208 /******************************************************************************
3209 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
3211 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
3212 LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3213 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3214 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3216 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
3217 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
3218 SecurityDescriptor, DesiredAccess, GenericMapping,
3219 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3220 return TRUE;
3223 /******************************************************************************
3224 * AccessCheckAndAuditAlarmW [ADVAPI32.@]
3226 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
3227 LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
3228 PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
3229 LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
3231 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
3232 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
3233 SecurityDescriptor, DesiredAccess, GenericMapping,
3234 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
3235 return TRUE;
3238 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3240 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
3242 return TRUE;
3245 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3247 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3249 return TRUE;
3252 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
3254 FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
3256 return TRUE;
3259 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
3260 LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3261 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3262 LPBOOL GenerateOnClose)
3264 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
3265 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
3266 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3267 GenerateOnClose);
3269 return TRUE;
3272 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
3273 LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
3274 DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
3275 LPBOOL GenerateOnClose)
3277 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
3278 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
3279 ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
3280 GenerateOnClose);
3282 return TRUE;
3285 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3286 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3288 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3289 DesiredAccess, Privileges, AccessGranted);
3291 return TRUE;
3294 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3295 DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3297 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3298 DesiredAccess, Privileges, AccessGranted);
3300 return TRUE;
3303 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3304 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3306 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3307 ClientToken, Privileges, AccessGranted);
3309 return TRUE;
3312 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3313 PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3315 FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3316 ClientToken, Privileges, AccessGranted);
3318 return TRUE;
3321 /******************************************************************************
3322 * GetSecurityInfo [ADVAPI32.@]
3324 * Retrieves a copy of the security descriptor associated with an object.
3326 * PARAMS
3327 * hObject [I] A handle for the object.
3328 * ObjectType [I] The type of object.
3329 * SecurityInfo [I] A bitmask indicating what info to retrieve.
3330 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
3331 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
3332 * ppDacl [O] If non-null, receives a pointer to the DACL.
3333 * ppSacl [O] If non-null, receives a pointer to the SACL.
3334 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3335 * which must be freed with LocalFree.
3337 * RETURNS
3338 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3340 DWORD WINAPI GetSecurityInfo(
3341 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3342 SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3343 PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3344 PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3347 PSECURITY_DESCRIPTOR sd;
3348 NTSTATUS status;
3349 ULONG n1, n2;
3350 BOOL present, defaulted;
3352 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
3353 if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
3355 /* If no descriptor, we have to check that there's a pointer for the requested information */
3356 if( !ppSecurityDescriptor && (
3357 ((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
3358 || ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
3359 || ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
3360 || ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
3361 return ERROR_INVALID_PARAMETER;
3363 switch (ObjectType)
3365 case SE_SERVICE:
3366 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, NULL, 0, &n1);
3367 break;
3368 default:
3369 status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3370 break;
3372 if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3373 return RtlNtStatusToDosError(status);
3375 sd = LocalAlloc(0, n1);
3376 if (!sd)
3377 return ERROR_NOT_ENOUGH_MEMORY;
3379 switch (ObjectType)
3381 case SE_SERVICE:
3382 status = SERV_QueryServiceObjectSecurity(hObject, SecurityInfo, sd, n1, &n2);
3383 break;
3384 default:
3385 status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3386 break;
3388 if (status != STATUS_SUCCESS)
3390 LocalFree(sd);
3391 return RtlNtStatusToDosError(status);
3394 if (ppsidOwner)
3396 *ppsidOwner = NULL;
3397 GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3399 if (ppsidGroup)
3401 *ppsidGroup = NULL;
3402 GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3404 if (ppDacl)
3406 *ppDacl = NULL;
3407 GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3409 if (ppSacl)
3411 *ppSacl = NULL;
3412 GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3414 if (ppSecurityDescriptor)
3415 *ppSecurityDescriptor = sd;
3417 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3418 * NULL, because native happily returns the SIDs and ACLs that are requested
3419 * in this case.
3422 return ERROR_SUCCESS;
3425 /******************************************************************************
3426 * GetSecurityInfoExA [ADVAPI32.@]
3428 DWORD WINAPI GetSecurityInfoExA(
3429 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3430 SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3431 LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3432 PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3435 FIXME("stub!\n");
3436 return ERROR_BAD_PROVIDER;
3439 /******************************************************************************
3440 * GetSecurityInfoExW [ADVAPI32.@]
3442 DWORD WINAPI GetSecurityInfoExW(
3443 HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3444 SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3445 LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
3446 PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3449 FIXME("stub!\n");
3450 return ERROR_BAD_PROVIDER;
3453 /******************************************************************************
3454 * BuildExplicitAccessWithNameA [ADVAPI32.@]
3456 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3457 LPSTR pTrusteeName, DWORD AccessPermissions,
3458 ACCESS_MODE AccessMode, DWORD Inheritance )
3460 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3461 AccessPermissions, AccessMode, Inheritance);
3463 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3464 pExplicitAccess->grfAccessMode = AccessMode;
3465 pExplicitAccess->grfInheritance = Inheritance;
3467 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3468 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3469 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3470 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3471 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3474 /******************************************************************************
3475 * BuildExplicitAccessWithNameW [ADVAPI32.@]
3477 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3478 LPWSTR pTrusteeName, DWORD AccessPermissions,
3479 ACCESS_MODE AccessMode, DWORD Inheritance )
3481 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3482 AccessPermissions, AccessMode, Inheritance);
3484 pExplicitAccess->grfAccessPermissions = AccessPermissions;
3485 pExplicitAccess->grfAccessMode = AccessMode;
3486 pExplicitAccess->grfInheritance = Inheritance;
3488 pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3489 pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3490 pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3491 pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3492 pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3495 /******************************************************************************
3496 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3498 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3499 SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3500 LPSTR InheritedObjectTypeName, LPSTR Name )
3502 DWORD ObjectsPresent = 0;
3504 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3505 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3507 /* Fill the OBJECTS_AND_NAME structure */
3508 pObjName->ObjectType = ObjectType;
3509 if (ObjectTypeName != NULL)
3511 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3514 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3515 if (InheritedObjectTypeName != NULL)
3517 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3520 pObjName->ObjectsPresent = ObjectsPresent;
3521 pObjName->ptstrName = Name;
3523 /* Fill the TRUSTEE structure */
3524 pTrustee->pMultipleTrustee = NULL;
3525 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3526 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3527 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3528 pTrustee->ptstrName = (LPSTR)pObjName;
3531 /******************************************************************************
3532 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3534 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3535 SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3536 LPWSTR InheritedObjectTypeName, LPWSTR Name )
3538 DWORD ObjectsPresent = 0;
3540 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3541 ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3543 /* Fill the OBJECTS_AND_NAME structure */
3544 pObjName->ObjectType = ObjectType;
3545 if (ObjectTypeName != NULL)
3547 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3550 pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3551 if (InheritedObjectTypeName != NULL)
3553 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3556 pObjName->ObjectsPresent = ObjectsPresent;
3557 pObjName->ptstrName = Name;
3559 /* Fill the TRUSTEE structure */
3560 pTrustee->pMultipleTrustee = NULL;
3561 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3562 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3563 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3564 pTrustee->ptstrName = (LPWSTR)pObjName;
3567 /******************************************************************************
3568 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3570 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3571 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3573 DWORD ObjectsPresent = 0;
3575 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3577 /* Fill the OBJECTS_AND_SID structure */
3578 if (pObjectGuid != NULL)
3580 pObjSid->ObjectTypeGuid = *pObjectGuid;
3581 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3583 else
3585 ZeroMemory(&pObjSid->ObjectTypeGuid,
3586 sizeof(GUID));
3589 if (pInheritedObjectGuid != NULL)
3591 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3592 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3594 else
3596 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3597 sizeof(GUID));
3600 pObjSid->ObjectsPresent = ObjectsPresent;
3601 pObjSid->pSid = pSid;
3603 /* Fill the TRUSTEE structure */
3604 pTrustee->pMultipleTrustee = NULL;
3605 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3606 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3607 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3608 pTrustee->ptstrName = (LPSTR) pObjSid;
3611 /******************************************************************************
3612 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3614 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3615 GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3617 DWORD ObjectsPresent = 0;
3619 TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3621 /* Fill the OBJECTS_AND_SID structure */
3622 if (pObjectGuid != NULL)
3624 pObjSid->ObjectTypeGuid = *pObjectGuid;
3625 ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3627 else
3629 ZeroMemory(&pObjSid->ObjectTypeGuid,
3630 sizeof(GUID));
3633 if (pInheritedObjectGuid != NULL)
3635 pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3636 ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3638 else
3640 ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3641 sizeof(GUID));
3644 pObjSid->ObjectsPresent = ObjectsPresent;
3645 pObjSid->pSid = pSid;
3647 /* Fill the TRUSTEE structure */
3648 pTrustee->pMultipleTrustee = NULL;
3649 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3650 pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3651 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3652 pTrustee->ptstrName = (LPWSTR) pObjSid;
3655 /******************************************************************************
3656 * BuildTrusteeWithSidA [ADVAPI32.@]
3658 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3660 TRACE("%p %p\n", pTrustee, pSid);
3662 pTrustee->pMultipleTrustee = NULL;
3663 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3664 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3665 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3666 pTrustee->ptstrName = pSid;
3669 /******************************************************************************
3670 * BuildTrusteeWithSidW [ADVAPI32.@]
3672 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3674 TRACE("%p %p\n", pTrustee, pSid);
3676 pTrustee->pMultipleTrustee = NULL;
3677 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3678 pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3679 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3680 pTrustee->ptstrName = pSid;
3683 /******************************************************************************
3684 * BuildTrusteeWithNameA [ADVAPI32.@]
3686 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3688 TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3690 pTrustee->pMultipleTrustee = NULL;
3691 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3692 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3693 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3694 pTrustee->ptstrName = name;
3697 /******************************************************************************
3698 * BuildTrusteeWithNameW [ADVAPI32.@]
3700 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3702 TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3704 pTrustee->pMultipleTrustee = NULL;
3705 pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3706 pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3707 pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3708 pTrustee->ptstrName = name;
3711 /******************************************************************************
3712 * GetTrusteeFormA [ADVAPI32.@]
3714 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
3716 TRACE("(%p)\n", pTrustee);
3718 if (!pTrustee)
3719 return TRUSTEE_BAD_FORM;
3721 return pTrustee->TrusteeForm;
3724 /******************************************************************************
3725 * GetTrusteeFormW [ADVAPI32.@]
3727 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
3729 TRACE("(%p)\n", pTrustee);
3731 if (!pTrustee)
3732 return TRUSTEE_BAD_FORM;
3734 return pTrustee->TrusteeForm;
3737 /******************************************************************************
3738 * GetTrusteeNameA [ADVAPI32.@]
3740 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
3742 TRACE("(%p)\n", pTrustee);
3744 if (!pTrustee)
3745 return NULL;
3747 return pTrustee->ptstrName;
3750 /******************************************************************************
3751 * GetTrusteeNameW [ADVAPI32.@]
3753 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
3755 TRACE("(%p)\n", pTrustee);
3757 if (!pTrustee)
3758 return NULL;
3760 return pTrustee->ptstrName;
3763 /******************************************************************************
3764 * GetTrusteeTypeA [ADVAPI32.@]
3766 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
3768 TRACE("(%p)\n", pTrustee);
3770 if (!pTrustee)
3771 return TRUSTEE_IS_UNKNOWN;
3773 return pTrustee->TrusteeType;
3776 /******************************************************************************
3777 * GetTrusteeTypeW [ADVAPI32.@]
3779 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
3781 TRACE("(%p)\n", pTrustee);
3783 if (!pTrustee)
3784 return TRUSTEE_IS_UNKNOWN;
3786 return pTrustee->TrusteeType;
3789 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3790 DWORD nAclInformationLength,
3791 ACL_INFORMATION_CLASS dwAclInformationClass )
3793 FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3794 nAclInformationLength, dwAclInformationClass);
3796 return TRUE;
3799 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3801 switch (form)
3803 case TRUSTEE_IS_NAME:
3805 *ptrustee_nameW = SERV_dup(trustee_nameA);
3806 return ERROR_SUCCESS;
3808 case TRUSTEE_IS_OBJECTS_AND_NAME:
3810 OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3811 OBJECTS_AND_NAME_W *objW = NULL;
3813 if (objA)
3815 if (!(objW = heap_alloc( sizeof(OBJECTS_AND_NAME_W) )))
3816 return ERROR_NOT_ENOUGH_MEMORY;
3818 objW->ObjectsPresent = objA->ObjectsPresent;
3819 objW->ObjectType = objA->ObjectType;
3820 objW->ObjectTypeName = SERV_dup(objA->ObjectTypeName);
3821 objW->InheritedObjectTypeName = SERV_dup(objA->InheritedObjectTypeName);
3822 objW->ptstrName = SERV_dup(objA->ptstrName);
3825 *ptrustee_nameW = (WCHAR *)objW;
3826 return ERROR_SUCCESS;
3828 /* These forms do not require conversion. */
3829 case TRUSTEE_IS_SID:
3830 case TRUSTEE_IS_OBJECTS_AND_SID:
3831 *ptrustee_nameW = (WCHAR *)trustee_nameA;
3832 return ERROR_SUCCESS;
3833 default:
3834 return ERROR_INVALID_PARAMETER;
3838 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3840 switch (form)
3842 case TRUSTEE_IS_NAME:
3843 heap_free( trustee_nameW );
3844 break;
3845 case TRUSTEE_IS_OBJECTS_AND_NAME:
3847 OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3849 if (objW)
3851 heap_free( objW->ptstrName );
3852 heap_free( objW->InheritedObjectTypeName );
3853 heap_free( objW->ObjectTypeName );
3854 heap_free( objW );
3857 break;
3859 /* Other forms did not require allocation, so no freeing is necessary. */
3860 default:
3861 break;
3865 static DWORD trustee_to_sid( DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee )
3867 if (pTrustee->MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3869 WARN("bad multiple trustee operation %d\n", pTrustee->MultipleTrusteeOperation);
3870 return ERROR_INVALID_PARAMETER;
3873 switch (pTrustee->TrusteeForm)
3875 case TRUSTEE_IS_SID:
3876 if (!CopySid(nDestinationSidLength, pDestinationSid, pTrustee->ptstrName))
3878 WARN("bad sid %p\n", pTrustee->ptstrName);
3879 return ERROR_INVALID_PARAMETER;
3881 break;
3882 case TRUSTEE_IS_NAME:
3884 DWORD sid_size = nDestinationSidLength;
3885 DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3886 SID_NAME_USE use;
3887 if (!strcmpW( pTrustee->ptstrName, CURRENT_USER ))
3889 if (!lookup_user_account_name( pDestinationSid, &sid_size, NULL, &domain_size, &use ))
3891 return GetLastError();
3894 else if (!LookupAccountNameW(NULL, pTrustee->ptstrName, pDestinationSid, &sid_size, NULL, &domain_size, &use))
3896 WARN("bad user name %s\n", debugstr_w(pTrustee->ptstrName));
3897 return ERROR_INVALID_PARAMETER;
3899 break;
3901 case TRUSTEE_IS_OBJECTS_AND_SID:
3902 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3903 break;
3904 case TRUSTEE_IS_OBJECTS_AND_NAME:
3905 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3906 break;
3907 default:
3908 WARN("bad trustee form %d\n", pTrustee->TrusteeForm);
3909 return ERROR_INVALID_PARAMETER;
3912 return ERROR_SUCCESS;
3915 /******************************************************************************
3916 * SetEntriesInAclA [ADVAPI32.@]
3918 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3919 PACL OldAcl, PACL* NewAcl )
3921 DWORD err = ERROR_SUCCESS;
3922 EXPLICIT_ACCESSW *pEntriesW;
3923 UINT alloc_index, free_index;
3925 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3927 if (NewAcl)
3928 *NewAcl = NULL;
3930 if (!count && !OldAcl)
3931 return ERROR_SUCCESS;
3933 pEntriesW = heap_alloc( count * sizeof(EXPLICIT_ACCESSW) );
3934 if (!pEntriesW)
3935 return ERROR_NOT_ENOUGH_MEMORY;
3937 for (alloc_index = 0; alloc_index < count; ++alloc_index)
3939 pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3940 pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3941 pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3942 pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3943 pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3944 pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3945 pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3947 err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3948 pEntries[alloc_index].Trustee.ptstrName,
3949 &pEntriesW[alloc_index].Trustee.ptstrName );
3950 if (err != ERROR_SUCCESS)
3952 if (err == ERROR_INVALID_PARAMETER)
3953 WARN("bad trustee form %d for trustee %d\n",
3954 pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3956 goto cleanup;
3960 err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3962 cleanup:
3963 /* Free any previously allocated trustee name buffers, taking into account
3964 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3965 * list. */
3966 for (free_index = 0; free_index < alloc_index; ++free_index)
3967 free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3969 heap_free( pEntriesW );
3970 return err;
3973 /******************************************************************************
3974 * SetEntriesInAclW [ADVAPI32.@]
3976 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3977 PACL OldAcl, PACL* NewAcl )
3979 ULONG i;
3980 PSID *ppsid;
3981 DWORD ret = ERROR_SUCCESS;
3982 DWORD acl_size = sizeof(ACL);
3983 NTSTATUS status;
3985 TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3987 if (NewAcl)
3988 *NewAcl = NULL;
3990 if (!count && !OldAcl)
3991 return ERROR_SUCCESS;
3993 /* allocate array of maximum sized sids allowed */
3994 ppsid = heap_alloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3995 if (!ppsid)
3996 return ERROR_OUTOFMEMORY;
3998 for (i = 0; i < count; i++)
4000 ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
4002 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
4003 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
4004 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
4005 pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
4006 pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
4007 pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
4008 pEntries[i].Trustee.ptstrName);
4010 ret = trustee_to_sid( FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]), ppsid[i], &pEntries[i].Trustee);
4011 if (ret)
4012 goto exit;
4014 /* Note: we overestimate the ACL size here as a tradeoff between
4015 * instructions (simplicity) and memory */
4016 switch (pEntries[i].grfAccessMode)
4018 case GRANT_ACCESS:
4019 case SET_ACCESS:
4020 acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
4021 break;
4022 case DENY_ACCESS:
4023 acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
4024 break;
4025 case SET_AUDIT_SUCCESS:
4026 case SET_AUDIT_FAILURE:
4027 acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
4028 break;
4029 case REVOKE_ACCESS:
4030 break;
4031 default:
4032 WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
4033 ret = ERROR_INVALID_PARAMETER;
4034 goto exit;
4038 if (OldAcl)
4040 ACL_SIZE_INFORMATION size_info;
4042 status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
4043 if (status != STATUS_SUCCESS)
4045 ret = RtlNtStatusToDosError(status);
4046 goto exit;
4048 acl_size += size_info.AclBytesInUse - sizeof(ACL);
4051 *NewAcl = LocalAlloc(0, acl_size);
4052 if (!*NewAcl)
4054 ret = ERROR_OUTOFMEMORY;
4055 goto exit;
4058 status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
4059 if (status != STATUS_SUCCESS)
4061 ret = RtlNtStatusToDosError(status);
4062 goto exit;
4065 for (i = 0; i < count; i++)
4067 switch (pEntries[i].grfAccessMode)
4069 case GRANT_ACCESS:
4070 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
4071 pEntries[i].grfInheritance,
4072 pEntries[i].grfAccessPermissions,
4073 ppsid[i]);
4074 break;
4075 case SET_ACCESS:
4077 ULONG j;
4078 BOOL add = TRUE;
4079 if (OldAcl)
4081 for (j = 0; ; j++)
4083 const ACE_HEADER *existing_ace_header;
4084 status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
4085 if (status != STATUS_SUCCESS)
4086 break;
4087 if (pEntries[i].grfAccessMode == SET_ACCESS &&
4088 existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4089 EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
4091 add = FALSE;
4092 break;
4096 if (add)
4097 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
4098 pEntries[i].grfInheritance,
4099 pEntries[i].grfAccessPermissions,
4100 ppsid[i]);
4101 break;
4103 case DENY_ACCESS:
4104 status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
4105 pEntries[i].grfInheritance,
4106 pEntries[i].grfAccessPermissions,
4107 ppsid[i]);
4108 break;
4109 case SET_AUDIT_SUCCESS:
4110 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4111 pEntries[i].grfInheritance,
4112 pEntries[i].grfAccessPermissions,
4113 ppsid[i], TRUE, FALSE);
4114 break;
4115 case SET_AUDIT_FAILURE:
4116 status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
4117 pEntries[i].grfInheritance,
4118 pEntries[i].grfAccessPermissions,
4119 ppsid[i], FALSE, TRUE);
4120 break;
4121 default:
4122 FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
4126 if (OldAcl)
4128 for (i = 0; ; i++)
4130 BOOL add = TRUE;
4131 ULONG j;
4132 const ACE_HEADER *old_ace_header;
4133 status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
4134 if (status != STATUS_SUCCESS) break;
4135 for (j = 0; j < count; j++)
4137 if (pEntries[j].grfAccessMode == SET_ACCESS &&
4138 old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
4139 EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4141 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
4142 add = FALSE;
4143 break;
4145 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
4147 switch (old_ace_header->AceType)
4149 case ACCESS_ALLOWED_ACE_TYPE:
4150 if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
4151 add = FALSE;
4152 break;
4153 case ACCESS_DENIED_ACE_TYPE:
4154 if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
4155 add = FALSE;
4156 break;
4157 case SYSTEM_AUDIT_ACE_TYPE:
4158 if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
4159 add = FALSE;
4160 break;
4161 case SYSTEM_ALARM_ACE_TYPE:
4162 if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
4163 add = FALSE;
4164 break;
4165 default:
4166 FIXME("unhandled ace type %d\n", old_ace_header->AceType);
4169 if (!add)
4170 break;
4173 if (add)
4174 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
4175 if (status != STATUS_SUCCESS)
4177 WARN("RtlAddAce failed with error 0x%08x\n", status);
4178 ret = RtlNtStatusToDosError(status);
4179 break;
4184 exit:
4185 heap_free(ppsid);
4186 return ret;
4189 /******************************************************************************
4190 * SetNamedSecurityInfoA [ADVAPI32.@]
4192 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
4193 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4194 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4196 LPWSTR wstr;
4197 DWORD r;
4199 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
4200 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4202 wstr = SERV_dup(pObjectName);
4203 r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
4204 psidGroup, pDacl, pSacl );
4206 heap_free( wstr );
4208 return r;
4211 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
4212 PSECURITY_DESCRIPTOR ModificationDescriptor,
4213 PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
4214 PGENERIC_MAPPING GenericMapping,
4215 HANDLE Token )
4217 FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
4218 ObjectsSecurityDescriptor, GenericMapping, Token);
4220 return TRUE;
4223 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4225 return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
4228 /******************************************************************************
4229 * AreAnyAccessesGranted [ADVAPI32.@]
4231 * Determines whether or not any of a set of specified access permissions have
4232 * been granted or not.
4234 * PARAMS
4235 * GrantedAccess [I] The permissions that have been granted.
4236 * DesiredAccess [I] The permissions that you want to have.
4238 * RETURNS
4239 * Nonzero if any of the permissions have been granted, zero if none of the
4240 * permissions have been granted.
4243 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
4245 return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
4248 /******************************************************************************
4249 * SetNamedSecurityInfoW [ADVAPI32.@]
4251 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
4252 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4253 PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
4255 DWORD access = 0;
4256 HANDLE handle;
4257 DWORD err;
4259 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
4260 SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
4262 if (!pObjectName) return ERROR_INVALID_PARAMETER;
4264 if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
4265 access |= WRITE_OWNER;
4266 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4267 access |= WRITE_DAC;
4268 if (SecurityInfo & SACL_SECURITY_INFORMATION)
4269 access |= ACCESS_SYSTEM_SECURITY;
4271 switch (ObjectType)
4273 case SE_SERVICE:
4274 if (!(err = get_security_service( pObjectName, access, &handle )))
4276 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4277 CloseServiceHandle( handle );
4279 break;
4280 case SE_REGISTRY_KEY:
4281 if (!(err = get_security_regkey( pObjectName, access, &handle )))
4283 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4284 RegCloseKey( handle );
4286 break;
4287 case SE_FILE_OBJECT:
4288 if (SecurityInfo & DACL_SECURITY_INFORMATION)
4289 access |= READ_CONTROL;
4290 if (!(err = get_security_file( pObjectName, access, &handle )))
4292 err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
4293 CloseHandle( handle );
4295 break;
4296 default:
4297 FIXME( "Object type %d is not currently supported.\n", ObjectType );
4298 return ERROR_SUCCESS;
4300 return err;
4303 /******************************************************************************
4304 * GetExplicitEntriesFromAclA [ADVAPI32.@]
4306 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
4307 PEXPLICIT_ACCESSA* pListOfExplicitEntries)
4309 FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4310 return ERROR_CALL_NOT_IMPLEMENTED;
4313 /******************************************************************************
4314 * GetExplicitEntriesFromAclW [ADVAPI32.@]
4316 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG count, PEXPLICIT_ACCESSW *list )
4318 ACL_SIZE_INFORMATION sizeinfo;
4319 EXPLICIT_ACCESSW *entries;
4320 MAX_SID *sid_entries;
4321 ACE_HEADER *ace;
4322 NTSTATUS status;
4323 int i;
4325 TRACE("%p %p %p\n",pacl, count, list);
4327 if (!count || !list)
4328 return ERROR_INVALID_PARAMETER;
4330 status = RtlQueryInformationAcl(pacl, &sizeinfo, sizeof(sizeinfo), AclSizeInformation);
4331 if (status) return RtlNtStatusToDosError(status);
4333 if (!sizeinfo.AceCount)
4335 *count = 0;
4336 *list = NULL;
4337 return ERROR_SUCCESS;
4340 entries = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (sizeof(EXPLICIT_ACCESSW) + sizeof(MAX_SID)) * sizeinfo.AceCount);
4341 if (!entries) return ERROR_OUTOFMEMORY;
4342 sid_entries = (MAX_SID *)(entries + sizeinfo.AceCount);
4344 for (i = 0; i < sizeinfo.AceCount; i++)
4346 status = RtlGetAce(pacl, i, (void**)&ace);
4347 if (status) goto error;
4349 switch (ace->AceType)
4351 case ACCESS_ALLOWED_ACE_TYPE:
4353 ACCESS_ALLOWED_ACE *allow = (ACCESS_ALLOWED_ACE *)ace;
4354 entries[i].grfAccessMode = GRANT_ACCESS;
4355 entries[i].grfInheritance = ace->AceFlags;
4356 entries[i].grfAccessPermissions = allow->Mask;
4358 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&allow->SidStart);
4359 entries[i].Trustee.pMultipleTrustee = NULL;
4360 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4361 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4362 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4363 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4364 break;
4367 case ACCESS_DENIED_ACE_TYPE:
4369 ACCESS_DENIED_ACE *deny = (ACCESS_DENIED_ACE *)ace;
4370 entries[i].grfAccessMode = DENY_ACCESS;
4371 entries[i].grfInheritance = ace->AceFlags;
4372 entries[i].grfAccessPermissions = deny->Mask;
4374 CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&deny->SidStart);
4375 entries[i].Trustee.pMultipleTrustee = NULL;
4376 entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
4377 entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4378 entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
4379 entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
4380 break;
4383 default:
4384 FIXME("Unhandled ace type %d\n", ace->AceType);
4385 entries[i].grfAccessMode = NOT_USED_ACCESS;
4386 continue;
4390 *count = sizeinfo.AceCount;
4391 *list = entries;
4392 return ERROR_SUCCESS;
4394 error:
4395 LocalFree(entries);
4396 return RtlNtStatusToDosError(status);
4399 /******************************************************************************
4400 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4402 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4403 PACCESS_MASK pFailedAuditRights)
4405 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4406 return ERROR_CALL_NOT_IMPLEMENTED;
4410 /******************************************************************************
4411 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4413 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4414 PACCESS_MASK pFailedAuditRights)
4416 FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4417 return ERROR_CALL_NOT_IMPLEMENTED;
4421 /******************************************************************************
4422 * ParseAclStringFlags
4424 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4426 DWORD flags = 0;
4427 LPCWSTR szAcl = *StringAcl;
4429 while (*szAcl && *szAcl != '(')
4431 if (*szAcl == 'P')
4433 flags |= SE_DACL_PROTECTED;
4435 else if (*szAcl == 'A')
4437 szAcl++;
4438 if (*szAcl == 'R')
4439 flags |= SE_DACL_AUTO_INHERIT_REQ;
4440 else if (*szAcl == 'I')
4441 flags |= SE_DACL_AUTO_INHERITED;
4443 szAcl++;
4446 *StringAcl = szAcl;
4447 return flags;
4450 /******************************************************************************
4451 * ParseAceStringType
4453 static const ACEFLAG AceType[] =
4455 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
4456 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
4457 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4458 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
4459 { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
4461 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4462 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
4463 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
4464 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4466 { NULL, 0 },
4469 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4471 UINT len = 0;
4472 LPCWSTR szAcl = *StringAcl;
4473 const ACEFLAG *lpaf = AceType;
4475 while (*szAcl == ' ')
4476 szAcl++;
4478 while (lpaf->wstr &&
4479 (len = strlenW(lpaf->wstr)) &&
4480 strncmpW(lpaf->wstr, szAcl, len))
4481 lpaf++;
4483 if (!lpaf->wstr)
4484 return 0;
4486 *StringAcl = szAcl + len;
4487 return lpaf->value;
4491 /******************************************************************************
4492 * ParseAceStringFlags
4494 static const ACEFLAG AceFlags[] =
4496 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4497 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
4498 { SDDL_INHERITED, INHERITED_ACE },
4499 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
4500 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
4501 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
4502 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
4503 { NULL, 0 },
4506 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4508 UINT len = 0;
4509 BYTE flags = 0;
4510 LPCWSTR szAcl = *StringAcl;
4512 while (*szAcl == ' ')
4513 szAcl++;
4515 while (*szAcl != ';')
4517 const ACEFLAG *lpaf = AceFlags;
4519 while (lpaf->wstr &&
4520 (len = strlenW(lpaf->wstr)) &&
4521 strncmpW(lpaf->wstr, szAcl, len))
4522 lpaf++;
4524 if (!lpaf->wstr)
4525 return 0;
4527 flags |= lpaf->value;
4528 szAcl += len;
4531 *StringAcl = szAcl;
4532 return flags;
4536 /******************************************************************************
4537 * ParseAceStringRights
4539 static const ACEFLAG AceRights[] =
4541 { SDDL_GENERIC_ALL, GENERIC_ALL },
4542 { SDDL_GENERIC_READ, GENERIC_READ },
4543 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
4544 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4546 { SDDL_READ_CONTROL, READ_CONTROL },
4547 { SDDL_STANDARD_DELETE, DELETE },
4548 { SDDL_WRITE_DAC, WRITE_DAC },
4549 { SDDL_WRITE_OWNER, WRITE_OWNER },
4551 { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
4552 { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
4553 { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
4554 { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
4555 { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
4556 { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
4557 { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
4558 { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
4559 { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
4561 { SDDL_FILE_ALL, FILE_ALL_ACCESS },
4562 { SDDL_FILE_READ, FILE_GENERIC_READ },
4563 { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
4564 { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
4566 { SDDL_KEY_ALL, KEY_ALL_ACCESS },
4567 { SDDL_KEY_READ, KEY_READ },
4568 { SDDL_KEY_WRITE, KEY_WRITE },
4569 { SDDL_KEY_EXECUTE, KEY_EXECUTE },
4571 { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
4572 { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
4573 { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
4574 { NULL, 0 },
4577 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4579 UINT len = 0;
4580 DWORD rights = 0;
4581 LPCWSTR szAcl = *StringAcl;
4583 while (*szAcl == ' ')
4584 szAcl++;
4586 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
4588 LPCWSTR p = szAcl;
4590 while (*p && *p != ';')
4591 p++;
4593 if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4595 rights = strtoulW(szAcl, NULL, 16);
4596 szAcl = p;
4598 else
4599 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4601 else
4603 while (*szAcl != ';')
4605 const ACEFLAG *lpaf = AceRights;
4607 while (lpaf->wstr &&
4608 (len = strlenW(lpaf->wstr)) &&
4609 strncmpW(lpaf->wstr, szAcl, len))
4611 lpaf++;
4614 if (!lpaf->wstr)
4615 return 0;
4617 rights |= lpaf->value;
4618 szAcl += len;
4622 *StringAcl = szAcl;
4623 return rights;
4627 /******************************************************************************
4628 * ParseStringAclToAcl
4630 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
4632 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
4633 PACL pAcl, LPDWORD cBytes)
4635 DWORD val;
4636 DWORD sidlen;
4637 DWORD length = sizeof(ACL);
4638 DWORD acesize = 0;
4639 DWORD acecount = 0;
4640 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4641 DWORD error = ERROR_INVALID_ACL;
4643 TRACE("%s\n", debugstr_w(StringAcl));
4645 if (!StringAcl)
4646 return FALSE;
4648 if (pAcl) /* pAce is only useful if we're setting values */
4649 pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4651 /* Parse ACL flags */
4652 *lpdwFlags = ParseAclStringFlags(&StringAcl);
4654 /* Parse ACE */
4655 while (*StringAcl == '(')
4657 StringAcl++;
4659 /* Parse ACE type */
4660 val = ParseAceStringType(&StringAcl);
4661 if (pAce)
4662 pAce->Header.AceType = (BYTE) val;
4663 if (*StringAcl != ';')
4665 error = RPC_S_INVALID_STRING_UUID;
4666 goto lerr;
4668 StringAcl++;
4670 /* Parse ACE flags */
4671 val = ParseAceStringFlags(&StringAcl);
4672 if (pAce)
4673 pAce->Header.AceFlags = (BYTE) val;
4674 if (*StringAcl != ';')
4675 goto lerr;
4676 StringAcl++;
4678 /* Parse ACE rights */
4679 val = ParseAceStringRights(&StringAcl);
4680 if (pAce)
4681 pAce->Mask = val;
4682 if (*StringAcl != ';')
4683 goto lerr;
4684 StringAcl++;
4686 /* Parse ACE object guid */
4687 while (*StringAcl == ' ')
4688 StringAcl++;
4689 if (*StringAcl != ';')
4691 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4692 goto lerr;
4694 StringAcl++;
4696 /* Parse ACE inherit object guid */
4697 while (*StringAcl == ' ')
4698 StringAcl++;
4699 if (*StringAcl != ';')
4701 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4702 goto lerr;
4704 StringAcl++;
4706 /* Parse ACE account sid */
4707 if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4709 while (*StringAcl && *StringAcl != ')')
4710 StringAcl++;
4713 if (*StringAcl != ')')
4714 goto lerr;
4715 StringAcl++;
4717 acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4718 length += acesize;
4719 if (pAce)
4721 pAce->Header.AceSize = acesize;
4722 pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4724 acecount++;
4727 *cBytes = length;
4729 if (length > 0xffff)
4731 ERR("ACL too large\n");
4732 goto lerr;
4735 if (pAcl)
4737 pAcl->AclRevision = ACL_REVISION;
4738 pAcl->Sbz1 = 0;
4739 pAcl->AclSize = length;
4740 pAcl->AceCount = acecount;
4741 pAcl->Sbz2 = 0;
4743 return TRUE;
4745 lerr:
4746 SetLastError(error);
4747 WARN("Invalid ACE string format\n");
4748 return FALSE;
4752 /******************************************************************************
4753 * ParseStringSecurityDescriptorToSecurityDescriptor
4755 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4756 LPCWSTR StringSecurityDescriptor,
4757 SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4758 LPDWORD cBytes)
4760 BOOL bret = FALSE;
4761 WCHAR toktype;
4762 WCHAR *tok;
4763 LPCWSTR lptoken;
4764 LPBYTE lpNext = NULL;
4765 DWORD len;
4767 *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4769 tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
4771 if (SecurityDescriptor)
4772 lpNext = (LPBYTE)(SecurityDescriptor + 1);
4774 while (*StringSecurityDescriptor == ' ')
4775 StringSecurityDescriptor++;
4777 while (*StringSecurityDescriptor)
4779 toktype = *StringSecurityDescriptor;
4781 /* Expect char identifier followed by ':' */
4782 StringSecurityDescriptor++;
4783 if (*StringSecurityDescriptor != ':')
4785 SetLastError(ERROR_INVALID_PARAMETER);
4786 goto lend;
4788 StringSecurityDescriptor++;
4790 /* Extract token */
4791 lptoken = StringSecurityDescriptor;
4792 while (*lptoken && *lptoken != ':')
4793 lptoken++;
4795 if (*lptoken)
4796 lptoken--;
4798 len = lptoken - StringSecurityDescriptor;
4799 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4800 tok[len] = 0;
4802 switch (toktype)
4804 case 'O':
4806 DWORD bytes;
4808 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4809 goto lend;
4811 if (SecurityDescriptor)
4813 SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4814 lpNext += bytes; /* Advance to next token */
4817 *cBytes += bytes;
4819 break;
4822 case 'G':
4824 DWORD bytes;
4826 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4827 goto lend;
4829 if (SecurityDescriptor)
4831 SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4832 lpNext += bytes; /* Advance to next token */
4835 *cBytes += bytes;
4837 break;
4840 case 'D':
4842 DWORD flags;
4843 DWORD bytes;
4845 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4846 goto lend;
4848 if (SecurityDescriptor)
4850 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4851 SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4852 lpNext += bytes; /* Advance to next token */
4855 *cBytes += bytes;
4857 break;
4860 case 'S':
4862 DWORD flags;
4863 DWORD bytes;
4865 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4866 goto lend;
4868 if (SecurityDescriptor)
4870 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4871 SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4872 lpNext += bytes; /* Advance to next token */
4875 *cBytes += bytes;
4877 break;
4880 default:
4881 FIXME("Unknown token\n");
4882 SetLastError(ERROR_INVALID_PARAMETER);
4883 goto lend;
4886 StringSecurityDescriptor = lptoken;
4889 bret = TRUE;
4891 lend:
4892 heap_free(tok);
4893 return bret;
4896 /******************************************************************************
4897 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4899 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4900 LPCSTR StringSecurityDescriptor,
4901 DWORD StringSDRevision,
4902 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4903 PULONG SecurityDescriptorSize)
4905 BOOL ret;
4906 LPWSTR StringSecurityDescriptorW;
4908 TRACE("%s, %u, %p, %p\n", debugstr_a(StringSecurityDescriptor), StringSDRevision,
4909 SecurityDescriptor, SecurityDescriptorSize);
4911 if(!StringSecurityDescriptor)
4912 return FALSE;
4914 StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor);
4915 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4916 StringSDRevision, SecurityDescriptor,
4917 SecurityDescriptorSize);
4918 heap_free(StringSecurityDescriptorW);
4920 return ret;
4923 /******************************************************************************
4924 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4926 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4927 LPCWSTR StringSecurityDescriptor,
4928 DWORD StringSDRevision,
4929 PSECURITY_DESCRIPTOR* SecurityDescriptor,
4930 PULONG SecurityDescriptorSize)
4932 DWORD cBytes;
4933 SECURITY_DESCRIPTOR* psd;
4934 BOOL bret = FALSE;
4936 TRACE("%s, %u, %p, %p\n", debugstr_w(StringSecurityDescriptor), StringSDRevision,
4937 SecurityDescriptor, SecurityDescriptorSize);
4939 if (GetVersion() & 0x80000000)
4941 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4942 goto lend;
4944 else if (!StringSecurityDescriptor || !SecurityDescriptor)
4946 SetLastError(ERROR_INVALID_PARAMETER);
4947 goto lend;
4949 else if (StringSDRevision != SID_REVISION)
4951 SetLastError(ERROR_UNKNOWN_REVISION);
4952 goto lend;
4955 /* Compute security descriptor length */
4956 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4957 NULL, &cBytes))
4958 goto lend;
4960 psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4961 if (!psd) goto lend;
4963 psd->Revision = SID_REVISION;
4964 psd->Control |= SE_SELF_RELATIVE;
4966 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4967 (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4969 LocalFree(psd);
4970 goto lend;
4973 if (SecurityDescriptorSize)
4974 *SecurityDescriptorSize = cBytes;
4976 bret = TRUE;
4978 lend:
4979 TRACE(" ret=%d\n", bret);
4980 return bret;
4983 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4985 if (cch == -1)
4986 cch = strlenW(string);
4988 if (plen)
4989 *plen += cch;
4991 if (pwptr)
4993 memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4994 *pwptr += cch;
4998 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
5000 static const WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
5001 static const WCHAR subauthfmt[] = { '-','%','u',0 };
5002 DWORD i;
5003 WCHAR buf[26];
5004 SID *pisid = psid;
5006 if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
5008 SetLastError(ERROR_INVALID_SID);
5009 return FALSE;
5012 if (pisid->IdentifierAuthority.Value[0] ||
5013 pisid->IdentifierAuthority.Value[1])
5015 FIXME("not matching MS' bugs\n");
5016 SetLastError(ERROR_INVALID_SID);
5017 return FALSE;
5020 sprintfW( buf, fmt, pisid->Revision,
5021 MAKELONG(
5022 MAKEWORD( pisid->IdentifierAuthority.Value[5],
5023 pisid->IdentifierAuthority.Value[4] ),
5024 MAKEWORD( pisid->IdentifierAuthority.Value[3],
5025 pisid->IdentifierAuthority.Value[2] )
5026 ) );
5027 DumpString(buf, -1, pwptr, plen);
5029 for( i=0; i<pisid->SubAuthorityCount; i++ )
5031 sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
5032 DumpString(buf, -1, pwptr, plen);
5034 return TRUE;
5037 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
5039 size_t i;
5040 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5042 if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
5044 DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
5045 return TRUE;
5049 return DumpSidNumeric(psid, pwptr, plen);
5052 static const LPCWSTR AceRightBitNames[32] = {
5053 SDDL_CREATE_CHILD, /* 0 */
5054 SDDL_DELETE_CHILD,
5055 SDDL_LIST_CHILDREN,
5056 SDDL_SELF_WRITE,
5057 SDDL_READ_PROPERTY, /* 4 */
5058 SDDL_WRITE_PROPERTY,
5059 SDDL_DELETE_TREE,
5060 SDDL_LIST_OBJECT,
5061 SDDL_CONTROL_ACCESS, /* 8 */
5062 NULL,
5063 NULL,
5064 NULL,
5065 NULL, /* 12 */
5066 NULL,
5067 NULL,
5068 NULL,
5069 SDDL_STANDARD_DELETE, /* 16 */
5070 SDDL_READ_CONTROL,
5071 SDDL_WRITE_DAC,
5072 SDDL_WRITE_OWNER,
5073 NULL, /* 20 */
5074 NULL,
5075 NULL,
5076 NULL,
5077 NULL, /* 24 */
5078 NULL,
5079 NULL,
5080 NULL,
5081 SDDL_GENERIC_ALL, /* 28 */
5082 SDDL_GENERIC_EXECUTE,
5083 SDDL_GENERIC_WRITE,
5084 SDDL_GENERIC_READ
5087 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
5089 static const WCHAR fmtW[] = {'0','x','%','x',0};
5090 WCHAR buf[15];
5091 size_t i;
5093 if (mask == 0)
5094 return;
5096 /* first check if the right have name */
5097 for (i = 0; i < ARRAY_SIZE(AceRights); i++)
5099 if (AceRights[i].wstr == NULL)
5100 break;
5101 if (mask == AceRights[i].value)
5103 DumpString(AceRights[i].wstr, -1, pwptr, plen);
5104 return;
5108 /* then check if it can be built from bit names */
5109 for (i = 0; i < 32; i++)
5111 if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
5113 /* can't be built from bit names */
5114 sprintfW(buf, fmtW, mask);
5115 DumpString(buf, -1, pwptr, plen);
5116 return;
5120 /* build from bit names */
5121 for (i = 0; i < 32; i++)
5122 if (mask & (1 << i))
5123 DumpString(AceRightBitNames[i], -1, pwptr, plen);
5126 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
5128 ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
5129 static const WCHAR openbr = '(';
5130 static const WCHAR closebr = ')';
5131 static const WCHAR semicolon = ';';
5133 if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
5135 SetLastError(ERROR_INVALID_ACL);
5136 return FALSE;
5139 piace = pace;
5140 DumpString(&openbr, 1, pwptr, plen);
5141 switch (piace->Header.AceType)
5143 case ACCESS_ALLOWED_ACE_TYPE:
5144 DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
5145 break;
5146 case ACCESS_DENIED_ACE_TYPE:
5147 DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
5148 break;
5149 case SYSTEM_AUDIT_ACE_TYPE:
5150 DumpString(SDDL_AUDIT, -1, pwptr, plen);
5151 break;
5152 case SYSTEM_ALARM_ACE_TYPE:
5153 DumpString(SDDL_ALARM, -1, pwptr, plen);
5154 break;
5156 DumpString(&semicolon, 1, pwptr, plen);
5158 if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
5159 DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
5160 if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
5161 DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
5162 if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
5163 DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
5164 if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
5165 DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
5166 if (piace->Header.AceFlags & INHERITED_ACE)
5167 DumpString(SDDL_INHERITED, -1, pwptr, plen);
5168 if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
5169 DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
5170 if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
5171 DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
5172 DumpString(&semicolon, 1, pwptr, plen);
5173 DumpRights(piace->Mask, pwptr, plen);
5174 DumpString(&semicolon, 1, pwptr, plen);
5175 /* objects not supported */
5176 DumpString(&semicolon, 1, pwptr, plen);
5177 /* objects not supported */
5178 DumpString(&semicolon, 1, pwptr, plen);
5179 if (!DumpSid(&piace->SidStart, pwptr, plen))
5180 return FALSE;
5181 DumpString(&closebr, 1, pwptr, plen);
5182 return TRUE;
5185 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
5187 WORD count;
5188 UINT i;
5190 if (protected)
5191 DumpString(SDDL_PROTECTED, -1, pwptr, plen);
5192 if (autoInheritReq)
5193 DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
5194 if (autoInherited)
5195 DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
5197 if (pacl == NULL)
5198 return TRUE;
5200 if (!IsValidAcl(pacl))
5201 return FALSE;
5203 count = pacl->AceCount;
5204 for (i = 0; i < count; i++)
5206 LPVOID ace;
5207 if (!GetAce(pacl, i, &ace))
5208 return FALSE;
5209 if (!DumpAce(ace, pwptr, plen))
5210 return FALSE;
5213 return TRUE;
5216 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5218 static const WCHAR prefix[] = {'O',':',0};
5219 BOOL bDefaulted;
5220 PSID psid;
5222 if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
5223 return FALSE;
5225 if (psid == NULL)
5226 return TRUE;
5228 DumpString(prefix, -1, pwptr, plen);
5229 if (!DumpSid(psid, pwptr, plen))
5230 return FALSE;
5231 return TRUE;
5234 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5236 static const WCHAR prefix[] = {'G',':',0};
5237 BOOL bDefaulted;
5238 PSID psid;
5240 if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
5241 return FALSE;
5243 if (psid == NULL)
5244 return TRUE;
5246 DumpString(prefix, -1, pwptr, plen);
5247 if (!DumpSid(psid, pwptr, plen))
5248 return FALSE;
5249 return TRUE;
5252 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5254 static const WCHAR dacl[] = {'D',':',0};
5255 SECURITY_DESCRIPTOR_CONTROL control;
5256 BOOL present, defaulted;
5257 DWORD revision;
5258 PACL pacl;
5260 if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
5261 return FALSE;
5263 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5264 return FALSE;
5266 if (!present)
5267 return TRUE;
5269 DumpString(dacl, 2, pwptr, plen);
5270 if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
5271 return FALSE;
5272 return TRUE;
5275 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
5277 static const WCHAR sacl[] = {'S',':',0};
5278 SECURITY_DESCRIPTOR_CONTROL control;
5279 BOOL present, defaulted;
5280 DWORD revision;
5281 PACL pacl;
5283 if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
5284 return FALSE;
5286 if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
5287 return FALSE;
5289 if (!present)
5290 return TRUE;
5292 DumpString(sacl, 2, pwptr, plen);
5293 if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
5294 return FALSE;
5295 return TRUE;
5298 /******************************************************************************
5299 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5301 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
5303 ULONG len;
5304 WCHAR *wptr, *wstr;
5306 if (SDRevision != SDDL_REVISION_1)
5308 ERR("Program requested unknown SDDL revision %d\n", SDRevision);
5309 SetLastError(ERROR_UNKNOWN_REVISION);
5310 return FALSE;
5313 len = 0;
5314 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5315 if (!DumpOwner(SecurityDescriptor, NULL, &len))
5316 return FALSE;
5317 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5318 if (!DumpGroup(SecurityDescriptor, NULL, &len))
5319 return FALSE;
5320 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5321 if (!DumpDacl(SecurityDescriptor, NULL, &len))
5322 return FALSE;
5323 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5324 if (!DumpSacl(SecurityDescriptor, NULL, &len))
5325 return FALSE;
5327 wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
5328 if (RequestedInformation & OWNER_SECURITY_INFORMATION)
5329 if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
5330 LocalFree (wstr);
5331 return FALSE;
5333 if (RequestedInformation & GROUP_SECURITY_INFORMATION)
5334 if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
5335 LocalFree (wstr);
5336 return FALSE;
5338 if (RequestedInformation & DACL_SECURITY_INFORMATION)
5339 if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
5340 LocalFree (wstr);
5341 return FALSE;
5343 if (RequestedInformation & SACL_SECURITY_INFORMATION)
5344 if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
5345 LocalFree (wstr);
5346 return FALSE;
5348 *wptr = 0;
5350 TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
5351 *OutputString = wstr;
5352 if (OutputLen)
5353 *OutputLen = strlenW(*OutputString)+1;
5354 return TRUE;
5357 /******************************************************************************
5358 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
5360 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
5362 LPWSTR wstr;
5363 ULONG len;
5364 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
5366 int lenA;
5368 lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
5369 *OutputString = heap_alloc(lenA);
5370 WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
5371 LocalFree(wstr);
5373 if (OutputLen != NULL)
5374 *OutputLen = lenA;
5375 return TRUE;
5377 else
5379 *OutputString = NULL;
5380 if (OutputLen)
5381 *OutputLen = 0;
5382 return FALSE;
5386 /******************************************************************************
5387 * ConvertStringSidToSidW [ADVAPI32.@]
5389 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
5391 BOOL bret = FALSE;
5392 DWORD cBytes;
5394 TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
5395 if (GetVersion() & 0x80000000)
5396 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5397 else if (!StringSid || !Sid)
5398 SetLastError(ERROR_INVALID_PARAMETER);
5399 else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5401 PSID pSid = *Sid = LocalAlloc(0, cBytes);
5403 bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5404 if (!bret)
5405 LocalFree(*Sid);
5407 return bret;
5410 /******************************************************************************
5411 * ConvertStringSidToSidA [ADVAPI32.@]
5413 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5415 BOOL bret = FALSE;
5417 TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5418 if (GetVersion() & 0x80000000)
5419 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5420 else if (!StringSid || !Sid)
5421 SetLastError(ERROR_INVALID_PARAMETER);
5422 else
5424 WCHAR *wStringSid = SERV_dup(StringSid);
5425 bret = ConvertStringSidToSidW(wStringSid, Sid);
5426 heap_free(wStringSid);
5428 return bret;
5431 /******************************************************************************
5432 * ConvertSidToStringSidW [ADVAPI32.@]
5434 * format of SID string is:
5435 * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5436 * where
5437 * <rev> is the revision of the SID encoded as decimal
5438 * <auth> is the identifier authority encoded as hex
5439 * <subauthN> is the subauthority id encoded as decimal
5441 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5443 DWORD len = 0;
5444 LPWSTR wstr, wptr;
5446 TRACE("%p %p\n", pSid, pstr );
5448 len = 0;
5449 if (!DumpSidNumeric(pSid, NULL, &len))
5450 return FALSE;
5451 wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5452 DumpSidNumeric(pSid, &wptr, NULL);
5453 *wptr = 0;
5455 *pstr = wstr;
5456 return TRUE;
5459 /******************************************************************************
5460 * ConvertSidToStringSidA [ADVAPI32.@]
5462 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5464 LPWSTR wstr = NULL;
5465 LPSTR str;
5466 UINT len;
5468 TRACE("%p %p\n", pSid, pstr );
5470 if( !ConvertSidToStringSidW( pSid, &wstr ) )
5471 return FALSE;
5473 len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5474 str = LocalAlloc( 0, len );
5475 WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5476 LocalFree( wstr );
5478 *pstr = str;
5480 return TRUE;
5483 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5484 PSECURITY_DESCRIPTOR pdesc,
5485 PSECURITY_DESCRIPTOR cdesc,
5486 PSECURITY_DESCRIPTOR* ndesc,
5487 GUID* objtype,
5488 BOOL isdir,
5489 PGENERIC_MAPPING genmap )
5491 FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5493 return FALSE;
5496 BOOL WINAPI CreatePrivateObjectSecurityEx(
5497 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5498 GUID *objtype, BOOL is_directory, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5500 SECURITY_DESCRIPTOR_RELATIVE *relative;
5501 DWORD needed, offset;
5502 BYTE *buffer;
5504 FIXME("%p %p %p %p %d %u %p %p - returns fake SECURITY_DESCRIPTOR\n", parent, creator, out,
5505 objtype, is_directory, flags, token, mapping);
5507 needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5508 needed += sizeof(sidWorld);
5509 needed += sizeof(sidWorld);
5510 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5511 needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5513 if (!(buffer = heap_alloc( needed ))) return FALSE;
5514 relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5515 if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5517 heap_free( buffer );
5518 return FALSE;
5520 relative->Control |= SE_SELF_RELATIVE;
5521 offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5523 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5524 relative->Owner = offset;
5525 offset += sizeof(sidWorld);
5527 memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5528 relative->Group = offset;
5529 offset += sizeof(sidWorld);
5531 GetWorldAccessACL( (ACL *)(buffer + offset) );
5532 relative->Dacl = offset;
5533 offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5535 GetWorldAccessACL( (ACL *)(buffer + offset) );
5536 relative->Sacl = offset;
5538 *out = relative;
5539 return TRUE;
5542 BOOL WINAPI CreatePrivateObjectSecurity(
5543 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5544 BOOL is_container, HANDLE token, PGENERIC_MAPPING mapping)
5546 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, 0, token, mapping);
5549 BOOL WINAPI CreatePrivateObjectSecurityWithMultipleInheritance(
5550 PSECURITY_DESCRIPTOR parent, PSECURITY_DESCRIPTOR creator, PSECURITY_DESCRIPTOR *out,
5551 GUID **types, ULONG count, BOOL is_container, ULONG flags, HANDLE token, PGENERIC_MAPPING mapping)
5553 FIXME(": semi-stub\n");
5554 return CreatePrivateObjectSecurityEx(parent, creator, out, NULL, is_container, flags, token, mapping);
5557 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5559 FIXME("%p - stub\n", ObjectDescriptor);
5561 heap_free( *ObjectDescriptor );
5562 return TRUE;
5565 /******************************************************************************
5566 * CreateProcessWithLogonW
5568 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5569 LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5570 LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5572 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5573 debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5574 debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5575 lpStartupInfo, lpProcessInformation);
5577 return FALSE;
5580 BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
5581 DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
5582 PROCESS_INFORMATION *process_information )
5584 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
5585 logon_flags, debugstr_w(application_name), debugstr_w(command_line),
5586 creation_flags, environment, debugstr_w(current_directory),
5587 startup_info, process_information);
5589 /* FIXME: check if handles should be inherited */
5590 return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
5591 current_directory, startup_info, process_information );
5594 /******************************************************************************
5595 * DuplicateTokenEx [ADVAPI32.@]
5597 BOOL WINAPI DuplicateTokenEx(
5598 HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5599 LPSECURITY_ATTRIBUTES lpTokenAttributes,
5600 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5601 TOKEN_TYPE TokenType,
5602 PHANDLE DuplicateTokenHandle )
5604 OBJECT_ATTRIBUTES ObjectAttributes;
5606 TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5607 ImpersonationLevel, TokenType, DuplicateTokenHandle);
5609 InitializeObjectAttributes(
5610 &ObjectAttributes,
5611 NULL,
5612 (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5613 NULL,
5614 lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5616 return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5617 dwDesiredAccess,
5618 &ObjectAttributes,
5619 ImpersonationLevel,
5620 TokenType,
5621 DuplicateTokenHandle ) );
5624 BOOL WINAPI DuplicateToken(
5625 HANDLE ExistingTokenHandle,
5626 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5627 PHANDLE DuplicateTokenHandle )
5629 return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5630 NULL, ImpersonationLevel, TokenImpersonation,
5631 DuplicateTokenHandle );
5634 /******************************************************************************
5635 * ComputeStringSidSize
5637 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5639 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5641 int ctok = 0;
5642 while (*StringSid)
5644 if (*StringSid == '-')
5645 ctok++;
5646 StringSid++;
5649 if (ctok >= 3)
5650 return GetSidLengthRequired(ctok - 2);
5652 else /* String constant format - Only available in winxp and above */
5654 unsigned int i;
5656 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5657 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5658 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5660 for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
5661 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5663 MAX_SID local;
5664 ADVAPI_GetComputerSid(&local);
5665 return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
5670 return GetSidLengthRequired(0);
5673 /******************************************************************************
5674 * ParseStringSidToSid
5676 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5678 BOOL bret = FALSE;
5679 SID* pisid=pSid;
5681 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5682 if (!StringSid)
5684 SetLastError(ERROR_INVALID_PARAMETER);
5685 TRACE("StringSid is NULL, returning FALSE\n");
5686 return FALSE;
5689 while (*StringSid == ' ')
5690 StringSid++;
5692 *cBytes = ComputeStringSidSize(StringSid);
5693 if (!pisid) /* Simply compute the size */
5695 TRACE("only size requested, returning TRUE with %d\n", *cBytes);
5696 return TRUE;
5699 if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5701 DWORD i = 0, identAuth;
5702 DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5704 StringSid += 2; /* Advance to Revision */
5705 pisid->Revision = atoiW(StringSid);
5707 if (pisid->Revision != SDDL_REVISION)
5709 TRACE("Revision %d is unknown\n", pisid->Revision);
5710 goto lend; /* ERROR_INVALID_SID */
5712 if (csubauth == 0)
5714 TRACE("SubAuthorityCount is 0\n");
5715 goto lend; /* ERROR_INVALID_SID */
5718 pisid->SubAuthorityCount = csubauth;
5720 /* Advance to identifier authority */
5721 while (*StringSid && *StringSid != '-')
5722 StringSid++;
5723 if (*StringSid == '-')
5724 StringSid++;
5726 /* MS' implementation can't handle values greater than 2^32 - 1, so
5727 * we don't either; assume most significant bytes are always 0
5729 pisid->IdentifierAuthority.Value[0] = 0;
5730 pisid->IdentifierAuthority.Value[1] = 0;
5731 identAuth = atoiW(StringSid);
5732 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5733 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5734 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5735 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5737 /* Advance to first sub authority */
5738 while (*StringSid && *StringSid != '-')
5739 StringSid++;
5740 if (*StringSid == '-')
5741 StringSid++;
5743 while (*StringSid)
5745 pisid->SubAuthority[i++] = atoiW(StringSid);
5747 while (*StringSid && *StringSid != '-')
5748 StringSid++;
5749 if (*StringSid == '-')
5750 StringSid++;
5753 if (i != pisid->SubAuthorityCount)
5754 goto lend; /* ERROR_INVALID_SID */
5756 bret = TRUE;
5758 else /* String constant format - Only available in winxp and above */
5760 unsigned int i;
5761 pisid->Revision = SDDL_REVISION;
5763 for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
5764 if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5766 DWORD j;
5767 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5768 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5769 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5770 pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5771 bret = TRUE;
5774 for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
5775 if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
5777 ADVAPI_GetComputerSid(pisid);
5778 pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
5779 pisid->SubAuthorityCount++;
5780 bret = TRUE;
5783 if (!bret)
5784 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5787 lend:
5788 if (!bret)
5789 SetLastError(ERROR_INVALID_SID);
5791 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5792 return bret;
5795 /******************************************************************************
5796 * GetNamedSecurityInfoA [ADVAPI32.@]
5798 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5799 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5800 PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5801 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5803 LPWSTR wstr;
5804 DWORD r;
5806 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5807 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5809 wstr = SERV_dup(pObjectName);
5810 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5811 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5813 heap_free( wstr );
5815 return r;
5818 /******************************************************************************
5819 * GetNamedSecurityInfoW [ADVAPI32.@]
5821 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5822 SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5823 PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5825 DWORD access = 0;
5826 HANDLE handle;
5827 DWORD err;
5829 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5830 group, dacl, sacl, descriptor );
5832 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5833 if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5835 /* If no descriptor, we have to check that there's a pointer for the requested information */
5836 if( !descriptor && (
5837 ((info & OWNER_SECURITY_INFORMATION) && !owner)
5838 || ((info & GROUP_SECURITY_INFORMATION) && !group)
5839 || ((info & DACL_SECURITY_INFORMATION) && !dacl)
5840 || ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
5841 return ERROR_INVALID_PARAMETER;
5843 if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
5844 access |= READ_CONTROL;
5845 if (info & SACL_SECURITY_INFORMATION)
5846 access |= ACCESS_SYSTEM_SECURITY;
5848 switch (type)
5850 case SE_SERVICE:
5851 if (!(err = get_security_service( name, access, &handle )))
5853 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5854 CloseServiceHandle( handle );
5856 break;
5857 case SE_REGISTRY_KEY:
5858 if (!(err = get_security_regkey( name, access, &handle )))
5860 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5861 RegCloseKey( handle );
5863 break;
5864 case SE_FILE_OBJECT:
5865 if (!(err = get_security_file( name, access, &handle )))
5867 err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
5868 CloseHandle( handle );
5870 break;
5871 default:
5872 FIXME( "Object type %d is not currently supported.\n", type );
5873 if (owner) *owner = NULL;
5874 if (group) *group = NULL;
5875 if (dacl) *dacl = NULL;
5876 if (sacl) *sacl = NULL;
5877 if (descriptor) *descriptor = NULL;
5878 return ERROR_SUCCESS;
5880 return err;
5883 /******************************************************************************
5884 * GetNamedSecurityInfoExW [ADVAPI32.@]
5886 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5887 SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5888 PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5890 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5891 debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5892 return ERROR_CALL_NOT_IMPLEMENTED;
5895 /******************************************************************************
5896 * GetNamedSecurityInfoExA [ADVAPI32.@]
5898 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5899 SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5900 PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5902 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5903 debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5904 return ERROR_CALL_NOT_IMPLEMENTED;
5907 /******************************************************************************
5908 * DecryptFileW [ADVAPI32.@]
5910 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5912 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName), dwReserved);
5913 return TRUE;
5916 /******************************************************************************
5917 * DecryptFileA [ADVAPI32.@]
5919 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5921 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName), dwReserved);
5922 return TRUE;
5925 /******************************************************************************
5926 * EncryptFileW [ADVAPI32.@]
5928 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5930 FIXME("(%s): stub\n", debugstr_w(lpFileName));
5931 return TRUE;
5934 /******************************************************************************
5935 * EncryptFileA [ADVAPI32.@]
5937 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5939 FIXME("(%s): stub\n", debugstr_a(lpFileName));
5940 return TRUE;
5943 /******************************************************************************
5944 * FileEncryptionStatusW [ADVAPI32.@]
5946 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5948 FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5949 if (!lpStatus)
5950 return FALSE;
5951 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5952 return TRUE;
5955 /******************************************************************************
5956 * FileEncryptionStatusA [ADVAPI32.@]
5958 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5960 FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5961 if (!lpStatus)
5962 return FALSE;
5963 *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5964 return TRUE;
5967 /******************************************************************************
5968 * SetSecurityInfo [ADVAPI32.@]
5970 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
5971 SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5972 PSID psidGroup, PACL pDacl, PACL pSacl)
5974 SECURITY_DESCRIPTOR sd;
5975 PACL dacl = pDacl;
5976 NTSTATUS status;
5978 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
5979 return ERROR_INVALID_SECURITY_DESCR;
5981 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
5982 SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
5983 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
5984 SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
5985 if (SecurityInfo & DACL_SECURITY_INFORMATION)
5987 if (ObjectType == SE_FILE_OBJECT && pDacl)
5989 SECURITY_DESCRIPTOR_CONTROL control;
5990 PSECURITY_DESCRIPTOR psd;
5991 OBJECT_NAME_INFORMATION *name_info;
5992 DWORD size, rev;
5994 status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
5995 if (status != STATUS_BUFFER_TOO_SMALL)
5996 return RtlNtStatusToDosError(status);
5998 psd = heap_alloc(size);
5999 if (!psd)
6000 return ERROR_NOT_ENOUGH_MEMORY;
6002 status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
6003 if (status)
6005 heap_free(psd);
6006 return RtlNtStatusToDosError(status);
6009 status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
6010 heap_free(psd);
6011 if (status)
6012 return RtlNtStatusToDosError(status);
6013 /* TODO: copy some control flags to new sd */
6015 /* inherit parent directory DACL */
6016 if (!(control & SE_DACL_PROTECTED))
6018 status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
6019 if (status != STATUS_INFO_LENGTH_MISMATCH)
6020 return RtlNtStatusToDosError(status);
6022 name_info = heap_alloc(size);
6023 if (!name_info)
6024 return ERROR_NOT_ENOUGH_MEMORY;
6026 status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
6027 if (status)
6029 heap_free(name_info);
6030 return RtlNtStatusToDosError(status);
6033 for (name_info->Name.Length-=2; name_info->Name.Length>0; name_info->Name.Length-=2)
6034 if (name_info->Name.Buffer[name_info->Name.Length/2-1]=='\\' ||
6035 name_info->Name.Buffer[name_info->Name.Length/2-1]=='/')
6036 break;
6037 if (name_info->Name.Length)
6039 OBJECT_ATTRIBUTES attr;
6040 IO_STATUS_BLOCK io;
6041 HANDLE parent;
6042 PSECURITY_DESCRIPTOR parent_sd;
6043 ACL *parent_dacl;
6044 DWORD err = ERROR_ACCESS_DENIED;
6046 name_info->Name.Buffer[name_info->Name.Length/2] = 0;
6048 attr.Length = sizeof(attr);
6049 attr.RootDirectory = 0;
6050 attr.Attributes = 0;
6051 attr.ObjectName = &name_info->Name;
6052 attr.SecurityDescriptor = NULL;
6053 status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
6054 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6055 FILE_OPEN_FOR_BACKUP_INTENT);
6056 heap_free(name_info);
6057 if (!status)
6059 err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
6060 NULL, NULL, &parent_dacl, NULL, &parent_sd);
6061 CloseHandle(parent);
6064 if (!err)
6066 int i;
6068 dacl = heap_alloc_zero(pDacl->AclSize+parent_dacl->AclSize);
6069 if (!dacl)
6071 LocalFree(parent_sd);
6072 return ERROR_NOT_ENOUGH_MEMORY;
6074 memcpy(dacl, pDacl, pDacl->AclSize);
6075 dacl->AclSize = pDacl->AclSize+parent_dacl->AclSize;
6077 for (i=0; i<parent_dacl->AceCount; i++)
6079 ACE_HEADER *ace;
6081 if (!GetAce(parent_dacl, i, (void*)&ace))
6082 continue;
6083 if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
6084 continue;
6085 if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
6086 (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
6088 FIXME("unsupported flags: %x\n", ace->AceFlags);
6089 continue;
6092 if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
6093 ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
6094 ace->AceFlags &= ~INHERIT_ONLY_ACE;
6095 ace->AceFlags |= INHERITED_ACE;
6097 if(!AddAce(dacl, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
6098 WARN("error adding inherited ACE\n");
6100 LocalFree(parent_sd);
6103 else
6104 heap_free(name_info);
6108 SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
6110 if (SecurityInfo & SACL_SECURITY_INFORMATION)
6111 SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
6113 switch (ObjectType)
6115 case SE_SERVICE:
6116 FIXME("stub: Service objects are not supported at this time.\n");
6117 status = STATUS_SUCCESS; /* Implement SetServiceObjectSecurity */
6118 break;
6119 default:
6120 status = NtSetSecurityObject(handle, SecurityInfo, &sd);
6121 break;
6123 if (dacl != pDacl)
6124 heap_free(dacl);
6125 return RtlNtStatusToDosError(status);
6128 /******************************************************************************
6129 * SaferCreateLevel [ADVAPI32.@]
6131 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
6132 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
6134 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
6136 *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
6137 return TRUE;
6140 /******************************************************************************
6141 * SaferComputeTokenFromLevel [ADVAPI32.@]
6143 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
6144 DWORD flags, LPVOID reserved)
6146 FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
6148 *access_token = (HANDLE)0xdeadbeef;
6149 return TRUE;
6152 /******************************************************************************
6153 * SaferCloseLevel [ADVAPI32.@]
6155 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
6157 FIXME("(%p) stub\n", handle);
6158 return TRUE;
6161 /******************************************************************************
6162 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
6164 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
6165 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
6166 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
6167 BOOL KeepExplicit, FN_PROGRESS fnProgress,
6168 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
6170 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
6171 debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
6172 pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
6174 return ERROR_SUCCESS;
6177 /******************************************************************************
6178 * SaferGetPolicyInformation [ADVAPI32.@]
6180 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
6181 PVOID buffer, PDWORD required, LPVOID lpReserved)
6183 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
6184 return FALSE;
6187 /******************************************************************************
6188 * SaferSetLevelInformation [ADVAPI32.@]
6190 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
6191 LPVOID buffer, DWORD size)
6193 FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
6194 return FALSE;
6197 /******************************************************************************
6198 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
6200 DWORD WINAPI LookupSecurityDescriptorPartsA(TRUSTEEA *owner, TRUSTEEA *group, ULONG *access_count,
6201 EXPLICIT_ACCESSA *access_list, ULONG *audit_count,
6202 EXPLICIT_ACCESSA *audit_list, SECURITY_DESCRIPTOR *descriptor)
6204 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6205 access_list, audit_count, audit_list, descriptor);
6206 return ERROR_CALL_NOT_IMPLEMENTED;
6209 /******************************************************************************
6210 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
6212 DWORD WINAPI LookupSecurityDescriptorPartsW(TRUSTEEW *owner, TRUSTEEW *group, ULONG *access_count,
6213 EXPLICIT_ACCESSW *access_list, ULONG *audit_count,
6214 EXPLICIT_ACCESSW *audit_list, SECURITY_DESCRIPTOR *descriptor)
6216 FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
6217 access_list, audit_count, audit_list, descriptor);
6218 return ERROR_CALL_NOT_IMPLEMENTED;