~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/advapi32/security.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
  3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
  4  * Copyright 2006 Robert Reif
  5  *
  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.
 10  *
 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.
 15  *
 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
 19  *
 20  */
 21 
 22 #include <stdarg.h>
 23 #include <string.h>
 24 
 25 #include "ntstatus.h"
 26 #define WIN32_NO_STATUS
 27 #include "windef.h"
 28 #include "winbase.h"
 29 #include "winerror.h"
 30 #include "winreg.h"
 31 #include "winsafer.h"
 32 #include "winternl.h"
 33 #include "winioctl.h"
 34 #include "ntsecapi.h"
 35 #include "accctrl.h"
 36 #include "sddl.h"
 37 #include "winsvc.h"
 38 #include "aclapi.h"
 39 #include "objbase.h"
 40 #include "iads.h"
 41 #include "advapi32_misc.h"
 42 #include "lmcons.h"
 43 
 44 #include "wine/debug.h"
 45 #include "wine/unicode.h"
 46 
 47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 48 
 49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
 50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
 51     PACL pAcl, LPDWORD cBytes);
 52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
 53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
 54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
 55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
 56     LPCWSTR StringSecurityDescriptor,
 57     SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
 58     LPDWORD cBytes);
 59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
 60 
 61 typedef struct _ACEFLAG
 62 {
 63    LPCWSTR wstr;
 64    DWORD value;
 65 } ACEFLAG, *LPACEFLAG;
 66 
 67 typedef struct _MAX_SID
 68 {
 69     /* same fields as struct _SID */
 70     BYTE Revision;
 71     BYTE SubAuthorityCount;
 72     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
 73     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
 74 } MAX_SID;
 75 
 76 typedef struct WELLKNOWNSID
 77 {
 78     WCHAR wstr[2];
 79     WELL_KNOWN_SID_TYPE Type;
 80     MAX_SID Sid;
 81 } WELLKNOWNSID;
 82 
 83 static const WELLKNOWNSID WellKnownSids[] =
 84 {
 85     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
 86     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
 87     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
 88     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
 89     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
 90     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
 91     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
 92     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
 93     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
 94     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
 95     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
 96     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
 97     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
 98     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
 99     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
128     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133     { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134     { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135     { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136     { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
137 };
138 
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
141 {
142     WELL_KNOWN_SID_TYPE Type;
143     DWORD Rid;
144 } WELLKNOWNRID;
145 
146 static const WELLKNOWNRID WellKnownRids[] = {
147     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
148     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
149     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
150     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
151     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
152     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
153     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
154     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
155     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
156     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
159     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
160 };
161 
162 
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
164 
165 typedef struct _AccountSid {
166     WELL_KNOWN_SID_TYPE type;
167     LPCWSTR account;
168     LPCWSTR domain;
169     SID_NAME_USE name_use;
170     LPCWSTR alias;
171 } AccountSid;
172 
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 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 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 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 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 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 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 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 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 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 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 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 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 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 };
216 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 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','','','',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 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 };
223 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 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 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 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 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 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
235 
236 static const AccountSid ACCOUNT_SIDS[] = {
237     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
281 };
282 /*
283  * ACE access rights
284  */
285 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
289 
290 static const WCHAR SDDL_READ_PROPERTY[]    = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[]   = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[]     = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[]     = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[]    = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[]       = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[]      = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[]      = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[]   = {'C','R',0};
299 
300 static const WCHAR SDDL_FILE_ALL[]         = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[]        = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[]       = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[]     = {'F','X',0};
304 
305 static const WCHAR SDDL_KEY_ALL[]          = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[]         = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[]        = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[]      = {'K','X',0};
309 
310 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
314 
315 /*
316  * ACL flags
317  */
318 static const WCHAR SDDL_PROTECTED[]             = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[]      = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[]        = {'A','I',0};
321 
322 /*
323  * ACE types
324  */
325 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','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_OBJECT_AUDIT[]          = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
333 
334 /*
335  * ACE flags
336  */
337 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
344 
345 const char * debugstr_sid(PSID sid)
346 {
347     int auth = 0;
348     SID * psid = sid;
349 
350     if (psid == NULL)
351         return "(null)";
352 
353     auth = psid->IdentifierAuthority.Value[5] +
354            (psid->IdentifierAuthority.Value[4] << 8) +
355            (psid->IdentifierAuthority.Value[3] << 16) +
356            (psid->IdentifierAuthority.Value[2] << 24);
357 
358     switch (psid->SubAuthorityCount) {
359     case 0:
360         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361     case 1:
362         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363             psid->SubAuthority[0]);
364     case 2:
365         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366             psid->SubAuthority[0], psid->SubAuthority[1]);
367     case 3:
368         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370     case 4:
371         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373             psid->SubAuthority[3]);
374     case 5:
375         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377             psid->SubAuthority[3], psid->SubAuthority[4]);
378     case 6:
379         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382     case 7:
383         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386             psid->SubAuthority[6]);
387     case 8:
388         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391             psid->SubAuthority[6], psid->SubAuthority[7]);
392     }
393     return "(too-big)";
394 }
395 
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
399 {
400     if (status) SetLastError( RtlNtStatusToDosError( status ));
401     return !status;
402 }
403 
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405 
406 static void GetWorldAccessACL(PACL pACL)
407 {
408     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409 
410     pACL->AclRevision = ACL_REVISION;
411     pACL->Sbz1 = 0;
412     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413     pACL->AceCount = 1;
414     pACL->Sbz2 = 0;
415 
416     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
421 }
422 
423 /************************************************************
424  *                ADVAPI_IsLocalComputer
425  *
426  * Checks whether the server name indicates local machine.
427  */
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 {
430     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431     BOOL Result;
432     LPWSTR buf;
433 
434     if (!ServerName || !ServerName[0])
435         return TRUE;
436 
437     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438     Result = GetComputerNameW(buf,  &dwSize);
439     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440         ServerName += 2;
441     Result = Result && !lstrcmpW(ServerName, buf);
442     HeapFree(GetProcessHeap(), 0, buf);
443 
444     return Result;
445 }
446 
447 /************************************************************
448  *                ADVAPI_GetComputerSid
449  *
450  * Reads the computer SID from the registry.
451  */
452 BOOL ADVAPI_GetComputerSid(PSID sid)
453 {
454     HKEY key;
455     LONG ret;
456     BOOL retval = FALSE;
457     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
458     static const WCHAR V[] = { 'V',0 };
459 
460     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461         KEY_READ, &key)) == ERROR_SUCCESS)
462     {
463         DWORD size = 0;
464         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466         {
467             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468             if (data)
469             {
470                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471                      data, &size)) == ERROR_SUCCESS)
472                 {
473                     /* the SID is in the last 24 bytes of the binary data */
474                     CopyMemory(sid, &data[size-24], 24);
475                     retval = TRUE;
476                 }
477                 HeapFree(GetProcessHeap(), 0, data);
478             }
479         }
480         RegCloseKey(key);
481     }
482 
483     if(retval == TRUE) return retval;
484 
485     /* create a new random SID */
486     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488     {
489         PSID new_sid;
490         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491         DWORD id[3];
492 
493         if (RtlGenRandom(id, sizeof(id)))
494         {
495             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496             {
497                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499 
500                 FreeSid(new_sid);
501             }
502         }
503         RegCloseKey(key);
504     }
505 
506     return retval;
507 }
508 
509 /*      ##############################
510         ######  TOKEN FUNCTIONS ######
511         ##############################
512 */
513 
514 /******************************************************************************
515  * OpenProcessToken                     [ADVAPI32.@]
516  * Opens the access token associated with a process handle.
517  *
518  * PARAMS
519  *   ProcessHandle [I] Handle to process
520  *   DesiredAccess [I] Desired access to process
521  *   TokenHandle   [O] Pointer to handle of open access token
522  *
523  * RETURNS
524  *  Success: TRUE. TokenHandle contains the access token.
525  *  Failure: FALSE.
526  *
527  * NOTES
528  *  See NtOpenProcessToken.
529  */
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532                   HANDLE *TokenHandle )
533 {
534         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
535 }
536 
537 /******************************************************************************
538  * OpenThreadToken [ADVAPI32.@]
539  *
540  * Opens the access token associated with a thread handle.
541  *
542  * PARAMS
543  *   ThreadHandle  [I] Handle to process
544  *   DesiredAccess [I] Desired access to the thread
545  *   OpenAsSelf    [I] ???
546  *   TokenHandle   [O] Destination for the token handle
547  *
548  * RETURNS
549  *  Success: TRUE. TokenHandle contains the access token.
550  *  Failure: FALSE.
551  *
552  * NOTES
553  *  See NtOpenThreadToken.
554  */
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557                  BOOL OpenAsSelf, HANDLE *TokenHandle)
558 {
559         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
560 }
561 
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 {
566     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567                                              PreviousState, ReturnLength));
568 }
569 
570 /******************************************************************************
571  * AdjustTokenPrivileges [ADVAPI32.@]
572  *
573  * Adjust the privileges of an open token handle.
574  * 
575  * PARAMS
576  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
577  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
578  *  NewState             [I]   Desired new privileges of the token
579  *  BufferLength         [I]   Length of NewState
580  *  PreviousState        [O]   Destination for the previous state
581  *  ReturnLength         [I/O] Size of PreviousState
582  *
583  *
584  * RETURNS
585  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586  *  Failure: FALSE.
587  *
588  * NOTES
589  *  See NtAdjustPrivilegesToken.
590  */
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 {
596     NTSTATUS status;
597 
598     TRACE("\n");
599     
600     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601                                                      NewState, BufferLength, PreviousState,
602                                                      ReturnLength);
603     SetLastError( RtlNtStatusToDosError( status ));
604     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605         return TRUE;
606     else
607         return FALSE;
608 }
609 
610 /******************************************************************************
611  * CheckTokenMembership [ADVAPI32.@]
612  *
613  * Determine if an access token is a member of a SID.
614  * 
615  * PARAMS
616  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617  *   SidToCheck  [I] SID that possibly contains the token
618  *   IsMember    [O] Destination for result.
619  *
620  * RETURNS
621  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622  *  Failure: FALSE.
623  */
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
626                       PBOOL IsMember )
627 {
628   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629 
630   *IsMember = TRUE;
631   return(TRUE);
632 }
633 
634 /******************************************************************************
635  * GetTokenInformation [ADVAPI32.@]
636  *
637  * Get a type of information about an access token.
638  *
639  * PARAMS
640  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
641  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
642  *   tokeninfo       [O] Destination for token information
643  *   tokeninfolength [I] Length of tokeninfo
644  *   retlen          [O] Destination for returned token information length
645  *
646  * RETURNS
647  *  Success: TRUE. tokeninfo contains retlen bytes of token information
648  *  Failure: FALSE.
649  *
650  * NOTES
651  *  See NtQueryInformationToken.
652  */
653 BOOL WINAPI
654 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
655                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 {
657     TRACE("(%p, %s, %p, %d, %p):\n",
658           token,
659           (tokeninfoclass == TokenUser) ? "TokenUser" :
660           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
661           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
662           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
663           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
664           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
665           (tokeninfoclass == TokenSource) ? "TokenSource" :
666           (tokeninfoclass == TokenType) ? "TokenType" :
667           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
668           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
669           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
670           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
671           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
672           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
673           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
674           "Unknown",
675           tokeninfo, tokeninfolength, retlen);
676     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
677                                                   tokeninfolength, retlen));
678 }
679 
680 /******************************************************************************
681  * SetTokenInformation [ADVAPI32.@]
682  *
683  * Set information for an access token.
684  *
685  * PARAMS
686  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
687  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
688  *   tokeninfo       [I] Token information to set
689  *   tokeninfolength [I] Length of tokeninfo
690  *
691  * RETURNS
692  *  Success: TRUE. The information for the token is set to tokeninfo.
693  *  Failure: FALSE.
694  */
695 BOOL WINAPI
696 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
697                      LPVOID tokeninfo, DWORD tokeninfolength )
698 {
699     TRACE("(%p, %s, %p, %d): stub\n",
700           token,
701           (tokeninfoclass == TokenUser) ? "TokenUser" :
702           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
703           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
704           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
705           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
706           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
707           (tokeninfoclass == TokenSource) ? "TokenSource" :
708           (tokeninfoclass == TokenType) ? "TokenType" :
709           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
710           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
711           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
712           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
713           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
714           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
715           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
716           "Unknown",
717           tokeninfo, tokeninfolength);
718 
719     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
720 }
721 
722 /*************************************************************************
723  * SetThreadToken [ADVAPI32.@]
724  *
725  * Assigns an 'impersonation token' to a thread so it can assume the
726  * security privileges of another thread or process.  Can also remove
727  * a previously assigned token. 
728  *
729  * PARAMS
730  *   thread          [O] Handle to thread to set the token for
731  *   token           [I] Token to set
732  *
733  * RETURNS
734  *  Success: TRUE. The threads access token is set to token
735  *  Failure: FALSE.
736  *
737  * NOTES
738  *  Only supported on NT or higher. On Win9X this function does nothing.
739  *  See SetTokenInformation.
740  */
741 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 {
743     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
744                                                  ThreadImpersonationToken, &token, sizeof token ));
745 }
746 
747 /*************************************************************************
748  * CreateRestrictedToken [ADVAPI32.@]
749  *
750  * Create a new more restricted token from an existing token.
751  *
752  * PARAMS
753  *   baseToken       [I] Token to base the new restricted token on
754  *   flags           [I] Options
755  *   nDisableSids    [I] Length of disableSids array
756  *   disableSids     [I] Array of SIDs to disable in the new token
757  *   nDeletePrivs    [I] Length of deletePrivs array
758  *   deletePrivs     [I] Array of privileges to delete in the new token
759  *   nRestrictSids   [I] Length of restrictSids array
760  *   restrictSids    [I] Array of SIDs to restrict in the new token
761  *   newToken        [O] Address where the new token is stored
762  *
763  * RETURNS
764  *  Success: TRUE
765  *  Failure: FALSE
766  */
767 BOOL WINAPI CreateRestrictedToken(
768     HANDLE baseToken,
769     DWORD flags,
770     DWORD nDisableSids,
771     PSID_AND_ATTRIBUTES disableSids,
772     DWORD nDeletePrivs,
773     PLUID_AND_ATTRIBUTES deletePrivs,
774     DWORD nRestrictSids,
775     PSID_AND_ATTRIBUTES restrictSids,
776     PHANDLE newToken)
777 {
778     FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
779           baseToken, flags, nDisableSids, disableSids,
780           nDeletePrivs, deletePrivs,
781           nRestrictSids, restrictSids,
782           newToken);
783     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
784     return FALSE;
785 }
786 
787 /*      ##############################
788         ######  SID FUNCTIONS   ######
789         ##############################
790 */
791 
792 /******************************************************************************
793  * AllocateAndInitializeSid [ADVAPI32.@]
794  *
795  * PARAMS
796  *   pIdentifierAuthority []
797  *   nSubAuthorityCount   []
798  *   nSubAuthority0       []
799  *   nSubAuthority1       []
800  *   nSubAuthority2       []
801  *   nSubAuthority3       []
802  *   nSubAuthority4       []
803  *   nSubAuthority5       []
804  *   nSubAuthority6       []
805  *   nSubAuthority7       []
806  *   pSid                 []
807  */
808 BOOL WINAPI
809 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
810                           BYTE nSubAuthorityCount,
811                           DWORD nSubAuthority0, DWORD nSubAuthority1,
812                           DWORD nSubAuthority2, DWORD nSubAuthority3,
813                           DWORD nSubAuthority4, DWORD nSubAuthority5,
814                           DWORD nSubAuthority6, DWORD nSubAuthority7,
815                           PSID *pSid )
816 {
817     return set_ntstatus( RtlAllocateAndInitializeSid(
818                              pIdentifierAuthority, nSubAuthorityCount,
819                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
820                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
821                              pSid ));
822 }
823 
824 /******************************************************************************
825  * FreeSid [ADVAPI32.@]
826  *
827  * PARAMS
828  *   pSid []
829  */
830 PVOID WINAPI
831 FreeSid( PSID pSid )
832 {
833         RtlFreeSid(pSid);
834         return NULL; /* is documented like this */
835 }
836 
837 /******************************************************************************
838  * CopySid [ADVAPI32.@]
839  *
840  * PARAMS
841  *   nDestinationSidLength []
842  *   pDestinationSid       []
843  *   pSourceSid            []
844  */
845 BOOL WINAPI
846 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 {
848         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
849 }
850 
851 /******************************************************************************
852  * CreateWellKnownSid [ADVAPI32.@]
853  */
854 BOOL WINAPI
855 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
856                     PSID DomainSid,
857                     PSID pSid,
858                     DWORD* cbSid)
859 {
860     unsigned int i;
861     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862 
863     if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
864     {
865         SetLastError(ERROR_INVALID_PARAMETER);
866         return FALSE;
867     }
868 
869     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
870         if (WellKnownSids[i].Type == WellKnownSidType) {
871             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
872 
873             if (*cbSid < length)
874             {
875                 *cbSid = length;
876                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
877                 return FALSE;
878             }
879             if (!pSid)
880             {
881                 SetLastError(ERROR_INVALID_PARAMETER);
882                 return FALSE;
883             }
884             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
885             *cbSid = length;
886             return TRUE;
887         }
888     }
889 
890     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
891     {
892         SetLastError(ERROR_INVALID_PARAMETER);
893         return FALSE;
894     }
895 
896     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
897         if (WellKnownRids[i].Type == WellKnownSidType) {
898             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
899             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
900             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
901 
902             if (*cbSid < output_sid_length)
903             {
904                 *cbSid = output_sid_length;
905                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
906                 return FALSE;
907             }
908             if (!pSid)
909             {
910                 SetLastError(ERROR_INVALID_PARAMETER);
911                 return FALSE;
912             }
913             CopyMemory(pSid, DomainSid, domain_sid_length);
914             (*GetSidSubAuthorityCount(pSid))++;
915             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
916             *cbSid = output_sid_length;
917             return TRUE;
918         }
919 
920     SetLastError(ERROR_INVALID_PARAMETER);
921     return FALSE;
922 }
923 
924 /******************************************************************************
925  * IsWellKnownSid [ADVAPI32.@]
926  */
927 BOOL WINAPI
928 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
929 {
930     unsigned int i;
931     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
932 
933     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
934         if (WellKnownSids[i].Type == WellKnownSidType)
935             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
936                 return TRUE;
937 
938     return FALSE;
939 }
940 
941 BOOL WINAPI
942 IsTokenRestricted( HANDLE TokenHandle )
943 {
944     TOKEN_GROUPS *groups;
945     DWORD size;
946     NTSTATUS status;
947     BOOL restricted;
948 
949     TRACE("(%p)\n", TokenHandle);
950  
951     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
952     if (status != STATUS_BUFFER_TOO_SMALL)
953         return FALSE;
954  
955     groups = HeapAlloc(GetProcessHeap(), 0, size);
956     if (!groups)
957     {
958         SetLastError(ERROR_OUTOFMEMORY);
959         return FALSE;
960     }
961  
962     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
963     if (status != STATUS_SUCCESS)
964     {
965         HeapFree(GetProcessHeap(), 0, groups);
966         return set_ntstatus(status);
967     }
968  
969     if (groups->GroupCount)
970         restricted = TRUE;
971     else
972         restricted = FALSE;
973      
974     HeapFree(GetProcessHeap(), 0, groups);
975  
976     return restricted;
977 }
978 
979 /******************************************************************************
980  * IsValidSid [ADVAPI32.@]
981  *
982  * PARAMS
983  *   pSid []
984  */
985 BOOL WINAPI
986 IsValidSid( PSID pSid )
987 {
988         return RtlValidSid( pSid );
989 }
990 
991 /******************************************************************************
992  * EqualSid [ADVAPI32.@]
993  *
994  * PARAMS
995  *   pSid1 []
996  *   pSid2 []
997  */
998 BOOL WINAPI
999 EqualSid( PSID pSid1, PSID pSid2 )
1000 {
1001         return RtlEqualSid( pSid1, pSid2 );
1002 }
1003 
1004 /******************************************************************************
1005  * EqualPrefixSid [ADVAPI32.@]
1006  */
1007 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1008 {
1009         return RtlEqualPrefixSid(pSid1, pSid2);
1010 }
1011 
1012 /******************************************************************************
1013  * GetSidLengthRequired [ADVAPI32.@]
1014  *
1015  * PARAMS
1016  *   nSubAuthorityCount []
1017  */
1018 DWORD WINAPI
1019 GetSidLengthRequired( BYTE nSubAuthorityCount )
1020 {
1021         return RtlLengthRequiredSid(nSubAuthorityCount);
1022 }
1023 
1024 /******************************************************************************
1025  * InitializeSid [ADVAPI32.@]
1026  *
1027  * PARAMS
1028  *   pIdentifierAuthority []
1029  */
1030 BOOL WINAPI
1031 InitializeSid (
1032         PSID pSid,
1033         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1034         BYTE nSubAuthorityCount)
1035 {
1036         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1037 }
1038 
1039 DWORD WINAPI
1040 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1041 {
1042     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1043 
1044     return 1;
1045 }
1046 
1047 DWORD WINAPI
1048 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1049 {
1050     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1051 
1052     return 1;
1053 }
1054 
1055 /******************************************************************************
1056  * GetSidIdentifierAuthority [ADVAPI32.@]
1057  *
1058  * PARAMS
1059  *   pSid []
1060  */
1061 PSID_IDENTIFIER_AUTHORITY WINAPI
1062 GetSidIdentifierAuthority( PSID pSid )
1063 {
1064         return RtlIdentifierAuthoritySid(pSid);
1065 }
1066 
1067 /******************************************************************************
1068  * GetSidSubAuthority [ADVAPI32.@]
1069  *
1070  * PARAMS
1071  *   pSid          []
1072  *   nSubAuthority []
1073  */
1074 PDWORD WINAPI
1075 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1076 {
1077         SetLastError(ERROR_SUCCESS);
1078         return RtlSubAuthoritySid(pSid, nSubAuthority);
1079 }
1080 
1081 /******************************************************************************
1082  * GetSidSubAuthorityCount [ADVAPI32.@]
1083  *
1084  * PARAMS
1085  *   pSid []
1086  */
1087 PUCHAR WINAPI
1088 GetSidSubAuthorityCount (PSID pSid)
1089 {
1090         SetLastError(ERROR_SUCCESS);
1091         return RtlSubAuthorityCountSid(pSid);
1092 }
1093 
1094 /******************************************************************************
1095  * GetLengthSid [ADVAPI32.@]
1096  *
1097  * PARAMS
1098  *   pSid []
1099  */
1100 DWORD WINAPI
1101 GetLengthSid (PSID pSid)
1102 {
1103         return RtlLengthSid(pSid);
1104 }
1105 
1106 /*      ##############################################
1107         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1108         ##############################################
1109 */
1110 
1111  /****************************************************************************** 
1112  * BuildSecurityDescriptorA [ADVAPI32.@]
1113  *
1114  * Builds a SD from 
1115  *
1116  * PARAMS
1117  *  pOwner                [I]
1118  *  pGroup                [I]
1119  *  cCountOfAccessEntries [I]
1120  *  pListOfAccessEntries  [I]
1121  *  cCountOfAuditEntries  [I]
1122  *  pListofAuditEntries   [I]
1123  *  pOldSD                [I]
1124  *  lpdwBufferLength      [I/O]
1125  *  pNewSD                [O]
1126  *
1127  * RETURNS
1128  *  Success: ERROR_SUCCESS
1129  *  Failure: nonzero error code from Winerror.h
1130  */
1131 DWORD WINAPI BuildSecurityDescriptorA(
1132     IN PTRUSTEEA pOwner,
1133     IN PTRUSTEEA pGroup,
1134     IN ULONG cCountOfAccessEntries,
1135     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1136     IN ULONG cCountOfAuditEntries,
1137     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1138     IN PSECURITY_DESCRIPTOR pOldSD,
1139     IN OUT PULONG lpdwBufferLength,
1140     OUT PSECURITY_DESCRIPTOR* pNewSD)
1141 { 
1142     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145  
1146     return ERROR_CALL_NOT_IMPLEMENTED;
1147 } 
1148  
1149 /******************************************************************************
1150  * BuildSecurityDescriptorW [ADVAPI32.@]
1151  *
1152  * See BuildSecurityDescriptorA.
1153  */
1154 DWORD WINAPI BuildSecurityDescriptorW(
1155     IN PTRUSTEEW pOwner,
1156     IN PTRUSTEEW pGroup,
1157     IN ULONG cCountOfAccessEntries,
1158     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1159     IN ULONG cCountOfAuditEntries,
1160     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1161     IN PSECURITY_DESCRIPTOR pOldSD,
1162     IN OUT PULONG lpdwBufferLength,
1163     OUT PSECURITY_DESCRIPTOR* pNewSD)
1164 { 
1165     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1166           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1167           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1168  
1169     return ERROR_CALL_NOT_IMPLEMENTED;
1170 } 
1171 
1172 /******************************************************************************
1173  * InitializeSecurityDescriptor [ADVAPI32.@]
1174  *
1175  * PARAMS
1176  *   pDescr   []
1177  *   revision []
1178  */
1179 BOOL WINAPI
1180 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1181 {
1182         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1183 }
1184 
1185 
1186 /******************************************************************************
1187  * MakeAbsoluteSD [ADVAPI32.@]
1188  */
1189 BOOL WINAPI MakeAbsoluteSD (
1190         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1191         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1192         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1193         OUT PACL pDacl,
1194         OUT LPDWORD lpdwDaclSize,
1195         OUT PACL pSacl,
1196         OUT LPDWORD lpdwSaclSize,
1197         OUT PSID pOwner,
1198         OUT LPDWORD lpdwOwnerSize,
1199         OUT PSID pPrimaryGroup,
1200         OUT LPDWORD lpdwPrimaryGroupSize)
1201 {
1202     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1203                                                      pAbsoluteSecurityDescriptor,
1204                                                      lpdwAbsoluteSecurityDescriptorSize,
1205                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1206                                                      pOwner, lpdwOwnerSize,
1207                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1208 }
1209 
1210 /******************************************************************************
1211  * GetKernelObjectSecurity [ADVAPI32.@]
1212  */
1213 BOOL WINAPI GetKernelObjectSecurity(
1214         HANDLE Handle,
1215         SECURITY_INFORMATION RequestedInformation,
1216         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1217         DWORD nLength,
1218         LPDWORD lpnLengthNeeded )
1219 {
1220     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1221           pSecurityDescriptor, nLength, lpnLengthNeeded);
1222 
1223     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1224                                                nLength, lpnLengthNeeded ));
1225 }
1226 
1227 /******************************************************************************
1228  * GetPrivateObjectSecurity [ADVAPI32.@]
1229  */
1230 BOOL WINAPI GetPrivateObjectSecurity(
1231         PSECURITY_DESCRIPTOR ObjectDescriptor,
1232         SECURITY_INFORMATION SecurityInformation,
1233         PSECURITY_DESCRIPTOR ResultantDescriptor,
1234         DWORD DescriptorLength,
1235         PDWORD ReturnLength )
1236 {
1237     SECURITY_DESCRIPTOR desc;
1238     BOOL defaulted, present;
1239     PACL pacl;
1240     PSID psid;
1241 
1242     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1243           ResultantDescriptor, DescriptorLength, ReturnLength);
1244 
1245     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1246         return FALSE;
1247 
1248     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1249     {
1250         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1251             return FALSE;
1252         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1253     }
1254 
1255     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1256     {
1257         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1258             return FALSE;
1259         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1260     }
1261 
1262     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1263     {
1264         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1265             return FALSE;
1266         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1267     }
1268 
1269     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1270     {
1271         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1272             return FALSE;
1273         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1274     }
1275 
1276     *ReturnLength = DescriptorLength;
1277     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1278 }
1279 
1280 /******************************************************************************
1281  * GetSecurityDescriptorLength [ADVAPI32.@]
1282  */
1283 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1284 {
1285         return RtlLengthSecurityDescriptor(pDescr);
1286 }
1287 
1288 /******************************************************************************
1289  * GetSecurityDescriptorOwner [ADVAPI32.@]
1290  *
1291  * PARAMS
1292  *   pOwner            []
1293  *   lpbOwnerDefaulted []
1294  */
1295 BOOL WINAPI
1296 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1297                             LPBOOL lpbOwnerDefaulted )
1298 {
1299     BOOLEAN defaulted;
1300     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1301     *lpbOwnerDefaulted = defaulted;
1302     return ret;
1303 }
1304 
1305 /******************************************************************************
1306  * SetSecurityDescriptorOwner [ADVAPI32.@]
1307  *
1308  * PARAMS
1309  */
1310 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1311                                    PSID pOwner, BOOL bOwnerDefaulted)
1312 {
1313     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1314 }
1315 /******************************************************************************
1316  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1317  */
1318 BOOL WINAPI GetSecurityDescriptorGroup(
1319         PSECURITY_DESCRIPTOR SecurityDescriptor,
1320         PSID *Group,
1321         LPBOOL GroupDefaulted)
1322 {
1323     BOOLEAN defaulted;
1324     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1325     *GroupDefaulted = defaulted;
1326     return ret;
1327 }
1328 /******************************************************************************
1329  * SetSecurityDescriptorGroup [ADVAPI32.@]
1330  */
1331 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1332                                            PSID Group, BOOL GroupDefaulted)
1333 {
1334     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1335 }
1336 
1337 /******************************************************************************
1338  * IsValidSecurityDescriptor [ADVAPI32.@]
1339  *
1340  * PARAMS
1341  *   lpsecdesc []
1342  */
1343 BOOL WINAPI
1344 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1345 {
1346     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1347 }
1348 
1349 /******************************************************************************
1350  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1351  */
1352 BOOL WINAPI GetSecurityDescriptorDacl(
1353         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1354         OUT LPBOOL lpbDaclPresent,
1355         OUT PACL *pDacl,
1356         OUT LPBOOL lpbDaclDefaulted)
1357 {
1358     BOOLEAN present, defaulted;
1359     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1360     *lpbDaclPresent = present;
1361     *lpbDaclDefaulted = defaulted;
1362     return ret;
1363 }
1364 
1365 /******************************************************************************
1366  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1367  */
1368 BOOL WINAPI
1369 SetSecurityDescriptorDacl (
1370         PSECURITY_DESCRIPTOR lpsd,
1371         BOOL daclpresent,
1372         PACL dacl,
1373         BOOL dacldefaulted )
1374 {
1375     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1376 }
1377 /******************************************************************************
1378  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1379  */
1380 BOOL WINAPI GetSecurityDescriptorSacl(
1381         IN PSECURITY_DESCRIPTOR lpsd,
1382         OUT LPBOOL lpbSaclPresent,
1383         OUT PACL *pSacl,
1384         OUT LPBOOL lpbSaclDefaulted)
1385 {
1386     BOOLEAN present, defaulted;
1387     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1388     *lpbSaclPresent = present;
1389     *lpbSaclDefaulted = defaulted;
1390     return ret;
1391 }
1392 
1393 /**************************************************************************
1394  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1395  */
1396 BOOL WINAPI SetSecurityDescriptorSacl (
1397         PSECURITY_DESCRIPTOR lpsd,
1398         BOOL saclpresent,
1399         PACL lpsacl,
1400         BOOL sacldefaulted)
1401 {
1402     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1403 }
1404 /******************************************************************************
1405  * MakeSelfRelativeSD [ADVAPI32.@]
1406  *
1407  * PARAMS
1408  *   lpabssecdesc  []
1409  *   lpselfsecdesc []
1410  *   lpbuflen      []
1411  */
1412 BOOL WINAPI
1413 MakeSelfRelativeSD(
1414         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1415         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1416         IN OUT LPDWORD lpdwBufferLength)
1417 {
1418     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1419                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1420 }
1421 
1422 /******************************************************************************
1423  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1424  */
1425 
1426 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1427                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1428 {
1429     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1430 }
1431 
1432 /******************************************************************************
1433  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1434  */
1435 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1436   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1437   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1438 {
1439     return set_ntstatus( RtlSetControlSecurityDescriptor(
1440         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1441 }
1442 
1443 /*      ##############################
1444         ######  ACL FUNCTIONS   ######
1445         ##############################
1446 */
1447 
1448 /*************************************************************************
1449  * InitializeAcl [ADVAPI32.@]
1450  */
1451 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1452 {
1453     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1454 }
1455 
1456 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1457 {
1458     IO_STATUS_BLOCK io_block;
1459 
1460     TRACE("(%p)\n", hNamedPipe);
1461 
1462     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1463                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1464 }
1465 
1466 /******************************************************************************
1467  *  AddAccessAllowedAce [ADVAPI32.@]
1468  */
1469 BOOL WINAPI AddAccessAllowedAce(
1470         IN OUT PACL pAcl,
1471         IN DWORD dwAceRevision,
1472         IN DWORD AccessMask,
1473         IN PSID pSid)
1474 {
1475     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1476 }
1477 
1478 /******************************************************************************
1479  *  AddAccessAllowedAceEx [ADVAPI32.@]
1480  */
1481 BOOL WINAPI AddAccessAllowedAceEx(
1482         IN OUT PACL pAcl,
1483         IN DWORD dwAceRevision,
1484         IN DWORD AceFlags,
1485         IN DWORD AccessMask,
1486         IN PSID pSid)
1487 {
1488     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1489 }
1490 
1491 /******************************************************************************
1492  *  AddAccessDeniedAce [ADVAPI32.@]
1493  */
1494 BOOL WINAPI AddAccessDeniedAce(
1495         IN OUT PACL pAcl,
1496         IN DWORD dwAceRevision,
1497         IN DWORD AccessMask,
1498         IN PSID pSid)
1499 {
1500     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1501 }
1502 
1503 /******************************************************************************
1504  *  AddAccessDeniedAceEx [ADVAPI32.@]
1505  */
1506 BOOL WINAPI AddAccessDeniedAceEx(
1507         IN OUT PACL pAcl,
1508         IN DWORD dwAceRevision,
1509         IN DWORD AceFlags,
1510         IN DWORD AccessMask,
1511         IN PSID pSid)
1512 {
1513     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1514 }
1515 
1516 /******************************************************************************
1517  *  AddAce [ADVAPI32.@]
1518  */
1519 BOOL WINAPI AddAce(
1520         IN OUT PACL pAcl,
1521         IN DWORD dwAceRevision,
1522         IN DWORD dwStartingAceIndex,
1523         LPVOID pAceList,
1524         DWORD nAceListLength)
1525 {
1526     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1527 }
1528 
1529 /******************************************************************************
1530  * DeleteAce [ADVAPI32.@]
1531  */
1532 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1533 {
1534     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1535 }
1536 
1537 /******************************************************************************
1538  *  FindFirstFreeAce [ADVAPI32.@]
1539  */
1540 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1541 {
1542         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1543 }
1544 
1545 /******************************************************************************
1546  * GetAce [ADVAPI32.@]
1547  */
1548 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1549 {
1550     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1551 }
1552 
1553 /******************************************************************************
1554  * GetAclInformation [ADVAPI32.@]
1555  */
1556 BOOL WINAPI GetAclInformation(
1557   PACL pAcl,
1558   LPVOID pAclInformation,
1559   DWORD nAclInformationLength,
1560   ACL_INFORMATION_CLASS dwAclInformationClass)
1561 {
1562     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1563                                                nAclInformationLength, dwAclInformationClass));
1564 }
1565 
1566 /******************************************************************************
1567  *  IsValidAcl [ADVAPI32.@]
1568  */
1569 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1570 {
1571         return RtlValidAcl(pAcl);
1572 }
1573 
1574 /*      ##############################
1575         ######  MISC FUNCTIONS  ######
1576         ##############################
1577 */
1578 
1579 /******************************************************************************
1580  * AllocateLocallyUniqueId [ADVAPI32.@]
1581  *
1582  * PARAMS
1583  *   lpLuid []
1584  */
1585 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1586 {
1587     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1588 }
1589 
1590 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1591  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1593  { '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 };
1594 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1595  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1597  { '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 };
1598 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1599  { '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 };
1600 static const WCHAR SE_TCB_NAME_W[] =
1601  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_SECURITY_NAME_W[] =
1603  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1605  { '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 };
1606 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1607  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1609  { '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 };
1610 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1611  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1613  { '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 };
1614 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1615  { '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 };
1616 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1617  { '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 };
1618 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1619  { '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 };
1620 static const WCHAR SE_BACKUP_NAME_W[] =
1621  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_RESTORE_NAME_W[] =
1623  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1625  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1626 static const WCHAR SE_DEBUG_NAME_W[] =
1627  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_AUDIT_NAME_W[] =
1629  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1631  { '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 };
1632 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1633  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1634 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1635  { '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 };
1636 static const WCHAR SE_UNDOCK_NAME_W[] =
1637  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1638 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1639  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1640 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1641  { '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 };
1642 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1643  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1644 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1645  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1647  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1648 
1649 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1650 {
1651     NULL,
1652     NULL,
1653     SE_CREATE_TOKEN_NAME_W,
1654     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1655     SE_LOCK_MEMORY_NAME_W,
1656     SE_INCREASE_QUOTA_NAME_W,
1657     SE_MACHINE_ACCOUNT_NAME_W,
1658     SE_TCB_NAME_W,
1659     SE_SECURITY_NAME_W,
1660     SE_TAKE_OWNERSHIP_NAME_W,
1661     SE_LOAD_DRIVER_NAME_W,
1662     SE_SYSTEM_PROFILE_NAME_W,
1663     SE_SYSTEMTIME_NAME_W,
1664     SE_PROF_SINGLE_PROCESS_NAME_W,
1665     SE_INC_BASE_PRIORITY_NAME_W,
1666     SE_CREATE_PAGEFILE_NAME_W,
1667     SE_CREATE_PERMANENT_NAME_W,
1668     SE_BACKUP_NAME_W,
1669     SE_RESTORE_NAME_W,
1670     SE_SHUTDOWN_NAME_W,
1671     SE_DEBUG_NAME_W,
1672     SE_AUDIT_NAME_W,
1673     SE_SYSTEM_ENVIRONMENT_NAME_W,
1674     SE_CHANGE_NOTIFY_NAME_W,
1675     SE_REMOTE_SHUTDOWN_NAME_W,
1676     SE_UNDOCK_NAME_W,
1677     SE_SYNC_AGENT_NAME_W,
1678     SE_ENABLE_DELEGATION_NAME_W,
1679     SE_MANAGE_VOLUME_NAME_W,
1680     SE_IMPERSONATE_NAME_W,
1681     SE_CREATE_GLOBAL_NAME_W,
1682 };
1683 
1684 /******************************************************************************
1685  * LookupPrivilegeValueW                        [ADVAPI32.@]
1686  *
1687  * See LookupPrivilegeValueA.
1688  */
1689 BOOL WINAPI
1690 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1691 {
1692     UINT i;
1693 
1694     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1695 
1696     if (!ADVAPI_IsLocalComputer(lpSystemName))
1697     {
1698         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1699         return FALSE;
1700     }
1701     if (!lpName)
1702     {
1703         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1704         return FALSE;
1705     }
1706     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1707     {
1708         if( !WellKnownPrivNames[i] )
1709             continue;
1710         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1711             continue;
1712         lpLuid->LowPart = i;
1713         lpLuid->HighPart = 0;
1714         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1715                lpLuid->HighPart, lpLuid->LowPart );
1716         return TRUE;
1717     }
1718     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1719     return FALSE;
1720 }
1721 
1722 /******************************************************************************
1723  * LookupPrivilegeValueA                        [ADVAPI32.@]
1724  *
1725  * Retrieves LUID used on a system to represent the privilege name.
1726  *
1727  * PARAMS
1728  *  lpSystemName [I] Name of the system
1729  *  lpName       [I] Name of the privilege
1730  *  lpLuid       [O] Destination for the resulting LUID
1731  *
1732  * RETURNS
1733  *  Success: TRUE. lpLuid contains the requested LUID.
1734  *  Failure: FALSE.
1735  */
1736 BOOL WINAPI
1737 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1738 {
1739     UNICODE_STRING lpSystemNameW;
1740     UNICODE_STRING lpNameW;
1741     BOOL ret;
1742 
1743     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1744     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1745     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1746     RtlFreeUnicodeString(&lpNameW);
1747     RtlFreeUnicodeString(&lpSystemNameW);
1748     return ret;
1749 }
1750 
1751 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1752                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1753 {
1754     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1755           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1756 
1757     return FALSE;
1758 }
1759 
1760 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1761                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1762 {
1763     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1764           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1765 
1766     return FALSE;
1767 }
1768 
1769 /******************************************************************************
1770  * LookupPrivilegeNameA                 [ADVAPI32.@]
1771  *
1772  * See LookupPrivilegeNameW.
1773  */
1774 BOOL WINAPI
1775 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1776  LPDWORD cchName)
1777 {
1778     UNICODE_STRING lpSystemNameW;
1779     BOOL ret;
1780     DWORD wLen = 0;
1781 
1782     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1783 
1784     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1785     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1786     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1787     {
1788         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1789 
1790         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1791          &wLen);
1792         if (ret)
1793         {
1794             /* Windows crashes if cchName is NULL, so will I */
1795             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1796              *cchName, NULL, NULL);
1797 
1798             if (len == 0)
1799             {
1800                 /* WideCharToMultiByte failed */
1801                 ret = FALSE;
1802             }
1803             else if (len > *cchName)
1804             {
1805                 *cchName = len;
1806                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1807                 ret = FALSE;
1808             }
1809             else
1810             {
1811                 /* WideCharToMultiByte succeeded, output length needs to be
1812                  * length not including NULL terminator
1813                  */
1814                 *cchName = len - 1;
1815             }
1816         }
1817         HeapFree(GetProcessHeap(), 0, lpNameW);
1818     }
1819     RtlFreeUnicodeString(&lpSystemNameW);
1820     return ret;
1821 }
1822 
1823 /******************************************************************************
1824  * LookupPrivilegeNameW                 [ADVAPI32.@]
1825  *
1826  * Retrieves the privilege name referred to by the LUID lpLuid.
1827  *
1828  * PARAMS
1829  *  lpSystemName [I]   Name of the system
1830  *  lpLuid       [I]   Privilege value
1831  *  lpName       [O]   Name of the privilege
1832  *  cchName      [I/O] Number of characters in lpName.
1833  *
1834  * RETURNS
1835  *  Success: TRUE. lpName contains the name of the privilege whose value is
1836  *  *lpLuid.
1837  *  Failure: FALSE.
1838  *
1839  * REMARKS
1840  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1841  *  using this function.
1842  *  If the length of lpName is too small, on return *cchName will contain the
1843  *  number of WCHARs needed to contain the privilege, including the NULL
1844  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1845  *  On success, *cchName will contain the number of characters stored in
1846  *  lpName, NOT including the NULL terminator.
1847  */
1848 BOOL WINAPI
1849 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1850  LPDWORD cchName)
1851 {
1852     size_t privNameLen;
1853 
1854     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1855 
1856     if (!ADVAPI_IsLocalComputer(lpSystemName))
1857     {
1858         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1859         return FALSE;
1860     }
1861     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1862      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1863     {
1864         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1865         return FALSE;
1866     }
1867     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1868     /* Windows crashes if cchName is NULL, so will I */
1869     if (*cchName <= privNameLen)
1870     {
1871         *cchName = privNameLen + 1;
1872         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1873         return FALSE;
1874     }
1875     else
1876     {
1877         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1878         *cchName = privNameLen;
1879         return TRUE;
1880     }
1881 }
1882 
1883 /******************************************************************************
1884  * GetFileSecurityA [ADVAPI32.@]
1885  *
1886  * Obtains Specified information about the security of a file or directory.
1887  *
1888  * PARAMS
1889  *  lpFileName           [I] Name of the file to get info for
1890  *  RequestedInformation [I] SE_ flags from "winnt.h"
1891  *  pSecurityDescriptor  [O] Destination for security information
1892  *  nLength              [I] Length of pSecurityDescriptor
1893  *  lpnLengthNeeded      [O] Destination for length of returned security information
1894  *
1895  * RETURNS
1896  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1897  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1898  *
1899  * NOTES
1900  *  The information returned is constrained by the callers access rights and
1901  *  privileges.
1902  */
1903 BOOL WINAPI
1904 GetFileSecurityA( LPCSTR lpFileName,
1905                     SECURITY_INFORMATION RequestedInformation,
1906                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1907                     DWORD nLength, LPDWORD lpnLengthNeeded )
1908 {
1909     DWORD len;
1910     BOOL r;
1911     LPWSTR name = NULL;
1912 
1913     if( lpFileName )
1914     {
1915         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1916         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1917         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1918     }
1919 
1920     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1921                           nLength, lpnLengthNeeded );
1922     HeapFree( GetProcessHeap(), 0, name );
1923 
1924     return r;
1925 }
1926 
1927 /******************************************************************************
1928  * GetFileSecurityW [ADVAPI32.@]
1929  *
1930  * See GetFileSecurityA.
1931  */
1932 BOOL WINAPI
1933 GetFileSecurityW( LPCWSTR lpFileName,
1934                     SECURITY_INFORMATION RequestedInformation,
1935                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936                     DWORD nLength, LPDWORD lpnLengthNeeded )
1937 {
1938     HANDLE hfile;
1939     NTSTATUS status;
1940     DWORD access = 0;
1941 
1942     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1943           RequestedInformation, pSecurityDescriptor,
1944           nLength, lpnLengthNeeded);
1945 
1946     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1947                                 DACL_SECURITY_INFORMATION))
1948         access |= READ_CONTROL;
1949     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1950         access |= ACCESS_SYSTEM_SECURITY;
1951 
1952     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1953                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1954     if ( hfile == INVALID_HANDLE_VALUE )
1955         return FALSE;
1956 
1957     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1958                                     nLength, lpnLengthNeeded );
1959     CloseHandle( hfile );
1960     return set_ntstatus( status );
1961 }
1962 
1963 
1964 /******************************************************************************
1965  * LookupAccountSidA [ADVAPI32.@]
1966  */
1967 BOOL WINAPI
1968 LookupAccountSidA(
1969         IN LPCSTR system,
1970         IN PSID sid,
1971         OUT LPSTR account,
1972         IN OUT LPDWORD accountSize,
1973         OUT LPSTR domain,
1974         IN OUT LPDWORD domainSize,
1975         OUT PSID_NAME_USE name_use )
1976 {
1977     DWORD len;
1978     BOOL r;
1979     LPWSTR systemW = NULL;
1980     LPWSTR accountW = NULL;
1981     LPWSTR domainW = NULL;
1982     DWORD accountSizeW = *accountSize;
1983     DWORD domainSizeW = *domainSize;
1984 
1985     if (system) {
1986         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1987         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1988         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1989     }
1990     if (account)
1991         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1992     if (domain)
1993         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1994 
1995     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1996 
1997     if (r) {
1998         if (accountW && *accountSize) {
1999             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2000             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2001             *accountSize = len;
2002         } else
2003             *accountSize = accountSizeW + 1;
2004 
2005         if (domainW && *domainSize) {
2006             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2007             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2008             *domainSize = len;
2009         } else
2010             *domainSize = domainSizeW + 1;
2011     }
2012 
2013     HeapFree( GetProcessHeap(), 0, systemW );
2014     HeapFree( GetProcessHeap(), 0, accountW );
2015     HeapFree( GetProcessHeap(), 0, domainW );
2016 
2017     return r;
2018 }
2019 
2020 /******************************************************************************
2021  * LookupAccountSidW [ADVAPI32.@]
2022  *
2023  * PARAMS
2024  *   system      []
2025  *   sid         []
2026  *   account     []
2027  *   accountSize []
2028  *   domain      []
2029  *   domainSize  []
2030  *   name_use    []
2031  */
2032 
2033 BOOL WINAPI
2034 LookupAccountSidW(
2035         IN LPCWSTR system,
2036         IN PSID sid,
2037         OUT LPWSTR account,
2038         IN OUT LPDWORD accountSize,
2039         OUT LPWSTR domain,
2040         IN OUT LPDWORD domainSize,
2041         OUT PSID_NAME_USE name_use )
2042 {
2043     unsigned int i, j;
2044     const WCHAR * ac = NULL;
2045     const WCHAR * dm = NULL;
2046     SID_NAME_USE use = 0;
2047     LPWSTR computer_name = NULL;
2048     LPWSTR account_name = NULL;
2049 
2050     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2051           debugstr_w(system),debugstr_sid(sid),
2052           account,accountSize,accountSize?*accountSize:0,
2053           domain,domainSize,domainSize?*domainSize:0,
2054           name_use);
2055 
2056     if (!ADVAPI_IsLocalComputer(system)) {
2057         FIXME("Only local computer supported!\n");
2058         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2059         return FALSE;
2060     }
2061 
2062     /* check the well known SIDs first */
2063     for (i = 0; i <= 60; i++) {
2064         if (IsWellKnownSid(sid, i)) {
2065             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2066                 if (ACCOUNT_SIDS[j].type == i) {
2067                     ac = ACCOUNT_SIDS[j].account;
2068                     dm = ACCOUNT_SIDS[j].domain;
2069                     use = ACCOUNT_SIDS[j].name_use;
2070                 }
2071             }
2072             break;
2073         }
2074     }
2075 
2076     if (dm == NULL) {
2077         MAX_SID local;
2078 
2079         /* check for the local computer next */
2080         if (ADVAPI_GetComputerSid(&local)) {
2081             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2082             BOOL result;
2083 
2084             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2085             result = GetComputerNameW(computer_name,  &size);
2086 
2087             if (result) {
2088                 if (EqualSid(sid, &local)) {
2089                     dm = computer_name;
2090                     ac = Blank;
2091                     use = 3;
2092                 } else {
2093                     local.SubAuthorityCount++;
2094 
2095                     if (EqualPrefixSid(sid, &local)) {
2096                         dm = computer_name;
2097                         use = 1;
2098                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2099                         case DOMAIN_USER_RID_ADMIN:
2100                             ac = Administrator;
2101                             break;
2102                         case DOMAIN_USER_RID_GUEST:
2103                             ac = Guest;
2104                             break;
2105                         case DOMAIN_GROUP_RID_ADMINS:
2106                             ac = Domain_Admins;
2107                             break;
2108                         case DOMAIN_GROUP_RID_USERS:
2109                             ac = Domain_Users;
2110                             break;
2111                         case DOMAIN_GROUP_RID_GUESTS:
2112                             ac = Domain_Guests;
2113                             break;
2114                         case DOMAIN_GROUP_RID_COMPUTERS:
2115                             ac = Domain_Computers;
2116                             break;
2117                         case DOMAIN_GROUP_RID_CONTROLLERS:
2118                             ac = Domain_Controllers;
2119                             break;
2120                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2121                             ac = Cert_Publishers;
2122                             break;
2123                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2124                             ac = Schema_Admins;
2125                             break;
2126                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2127                             ac = Enterprise_Admins;
2128                             break;
2129                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2130                             ac = Group_Policy_Creator_Owners;
2131                             break;
2132                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2133                             ac = RAS_and_IAS_Servers;
2134                             break;
2135                         case 1000:      /* first user account */
2136                             size = UNLEN + 1;
2137                             account_name = HeapAlloc(
2138                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2139                             if (GetUserNameW(account_name, &size))
2140                                 ac = account_name;
2141                             else
2142                                 dm = NULL;
2143 
2144                             break;
2145                         default:
2146                             dm = NULL;
2147                             break;
2148                         }
2149                     }
2150                 }
2151             }
2152         }
2153     }
2154 
2155     if (dm) {
2156         DWORD ac_len = lstrlenW(ac);
2157         DWORD dm_len = lstrlenW(dm);
2158         BOOL status = TRUE;
2159 
2160         if (*accountSize > ac_len) {
2161             if (account)
2162                 lstrcpyW(account, ac);
2163         }
2164         if (*domainSize > dm_len) {
2165             if (domain)
2166                 lstrcpyW(domain, dm);
2167         }
2168         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2169             ((*domainSize != 0) && (*domainSize < dm_len))) {
2170             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2171             status = FALSE;
2172         }
2173         if (*domainSize)
2174             *domainSize = dm_len;
2175         else
2176             *domainSize = dm_len + 1;
2177         if (*accountSize)
2178             *accountSize = ac_len;
2179         else
2180             *accountSize = ac_len + 1;
2181         *name_use = use;
2182         HeapFree(GetProcessHeap(), 0, account_name);
2183         HeapFree(GetProcessHeap(), 0, computer_name);
2184         return status;
2185     }
2186 
2187     HeapFree(GetProcessHeap(), 0, account_name);
2188     HeapFree(GetProcessHeap(), 0, computer_name);
2189     SetLastError(ERROR_NONE_MAPPED);
2190     return FALSE;
2191 }
2192 
2193 /******************************************************************************
2194  * SetFileSecurityA [ADVAPI32.@]
2195  *
2196  * See SetFileSecurityW.
2197  */
2198 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2199                                 SECURITY_INFORMATION RequestedInformation,
2200                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2201 {
2202     DWORD len;
2203     BOOL r;
2204     LPWSTR name = NULL;
2205 
2206     if( lpFileName )
2207     {
2208         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2209         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2210         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2211     }
2212 
2213     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2214     HeapFree( GetProcessHeap(), 0, name );
2215 
2216     return r;
2217 }
2218 
2219 /******************************************************************************
2220  * SetFileSecurityW [ADVAPI32.@]
2221  *
2222  * Sets the security of a file or directory.
2223  *
2224  * PARAMS
2225  *   lpFileName           []
2226  *   RequestedInformation []
2227  *   pSecurityDescriptor  []
2228  *
2229  * RETURNS
2230  *  Success: TRUE.
2231  *  Failure: FALSE.
2232  */
2233 BOOL WINAPI
2234 SetFileSecurityW( LPCWSTR lpFileName,
2235                     SECURITY_INFORMATION RequestedInformation,
2236                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2237 {
2238     HANDLE file;
2239     DWORD access = 0;
2240     NTSTATUS status;
2241 
2242     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2243           pSecurityDescriptor );
2244 
2245     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2246         RequestedInformation & GROUP_SECURITY_INFORMATION)
2247         access |= WRITE_OWNER;
2248     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2249         access |= ACCESS_SYSTEM_SECURITY;
2250     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2251         access |= WRITE_DAC;
2252 
2253     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2254                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2255     if (file == INVALID_HANDLE_VALUE)
2256         return FALSE;
2257 
2258     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2259     CloseHandle( file );
2260     return set_ntstatus( status );
2261 }
2262 
2263 /******************************************************************************
2264  * QueryWindows31FilesMigration [ADVAPI32.@]
2265  *
2266  * PARAMS
2267  *   x1 []
2268  */
2269 BOOL WINAPI
2270 QueryWindows31FilesMigration( DWORD x1 )
2271 {
2272         FIXME("(%d):stub\n",x1);
2273         return TRUE;
2274 }
2275 
2276 /******************************************************************************
2277  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2278  *
2279  * PARAMS
2280  *   x1 []
2281  *   x2 []
2282  *   x3 []
2283  *   x4 []
2284  */
2285 BOOL WINAPI
2286 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2287                                                DWORD x4 )
2288 {
2289         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2290         return TRUE;
2291 }
2292 
2293 /******************************************************************************
2294  * NotifyBootConfigStatus [ADVAPI32.@]
2295  *
2296  * PARAMS
2297  *   x1 []
2298  */
2299 BOOL WINAPI
2300 NotifyBootConfigStatus( BOOL x1 )
2301 {
2302         FIXME("(0x%08d):stub\n",x1);
2303         return 1;
2304 }
2305 
2306 /******************************************************************************
2307  * RevertToSelf [ADVAPI32.@]
2308  *
2309  * Ends the impersonation of a user.
2310  *
2311  * PARAMS
2312  *   void []
2313  *
2314  * RETURNS
2315  *  Success: TRUE.
2316  *  Failure: FALSE.
2317  */
2318 BOOL WINAPI
2319 RevertToSelf( void )
2320 {
2321     HANDLE Token = NULL;
2322     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2323         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2324 }
2325 
2326 /******************************************************************************
2327  * ImpersonateSelf [ADVAPI32.@]
2328  *
2329  * Makes an impersonation token that represents the process user and assigns
2330  * to the current thread.
2331  *
2332  * PARAMS
2333  *  ImpersonationLevel [I] Level at which to impersonate.
2334  *
2335  * RETURNS
2336  *  Success: TRUE.
2337  *  Failure: FALSE.
2338  */
2339 BOOL WINAPI
2340 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2341 {
2342     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2343 }
2344 
2345 /******************************************************************************
2346  * ImpersonateLoggedOnUser [ADVAPI32.@]
2347  */
2348 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2349 {
2350     DWORD size;
2351     NTSTATUS Status;
2352     HANDLE ImpersonationToken;
2353     TOKEN_TYPE Type;
2354     static BOOL warn = TRUE;
2355 
2356     if (warn)
2357     {
2358         FIXME( "(%p)\n", hToken );
2359         warn = FALSE;
2360     }
2361     if (!GetTokenInformation( hToken, TokenType, &Type,
2362                               sizeof(TOKEN_TYPE), &size ))
2363         return FALSE;
2364 
2365     if (Type == TokenPrimary)
2366     {
2367         OBJECT_ATTRIBUTES ObjectAttributes;
2368 
2369         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2370 
2371         Status = NtDuplicateToken( hToken,
2372                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2373                                    &ObjectAttributes,
2374                                    SecurityImpersonation,
2375                                    TokenImpersonation,
2376                                    &ImpersonationToken );
2377         if (Status != STATUS_SUCCESS)
2378         {
2379             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2380             SetLastError( RtlNtStatusToDosError( Status ) );
2381             return FALSE;
2382         }
2383     }
2384     else
2385         ImpersonationToken = hToken;
2386 
2387     Status = NtSetInformationThread( GetCurrentThread(),
2388                                      ThreadImpersonationToken,
2389                                      &ImpersonationToken,
2390                                      sizeof(ImpersonationToken) );
2391 
2392     if (Type == TokenPrimary)
2393         NtClose( ImpersonationToken );
2394 
2395     if (Status != STATUS_SUCCESS)
2396     {
2397         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2398         SetLastError( RtlNtStatusToDosError( Status ) );
2399         return FALSE;
2400     }
2401 
2402     return TRUE;
2403 }
2404 
2405 /******************************************************************************
2406  * AccessCheck [ADVAPI32.@]
2407  */
2408 BOOL WINAPI
2409 AccessCheck(
2410         PSECURITY_DESCRIPTOR SecurityDescriptor,
2411         HANDLE ClientToken,
2412         DWORD DesiredAccess,
2413         PGENERIC_MAPPING GenericMapping,
2414         PPRIVILEGE_SET PrivilegeSet,
2415         LPDWORD PrivilegeSetLength,
2416         LPDWORD GrantedAccess,
2417         LPBOOL AccessStatus)
2418 {
2419     NTSTATUS access_status;
2420     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2421                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2422                                            GrantedAccess, &access_status) );
2423     if (ret) *AccessStatus = set_ntstatus( access_status );
2424     return ret;
2425 }
2426 
2427 
2428 /******************************************************************************
2429  * AccessCheckByType [ADVAPI32.@]
2430  */
2431 BOOL WINAPI AccessCheckByType(
2432     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2433     PSID PrincipalSelfSid,
2434     HANDLE ClientToken, 
2435     DWORD DesiredAccess, 
2436     POBJECT_TYPE_LIST ObjectTypeList,
2437     DWORD ObjectTypeListLength,
2438     PGENERIC_MAPPING GenericMapping,
2439     PPRIVILEGE_SET PrivilegeSet,
2440     LPDWORD PrivilegeSetLength, 
2441     LPDWORD GrantedAccess,
2442     LPBOOL AccessStatus)
2443 {
2444         FIXME("stub\n");
2445 
2446         *AccessStatus = TRUE;
2447 
2448         return !*AccessStatus;
2449 }
2450 
2451 /******************************************************************************
2452  * MapGenericMask [ADVAPI32.@]
2453  *
2454  * Maps generic access rights into specific access rights according to the
2455  * supplied mapping.
2456  *
2457  * PARAMS
2458  *  AccessMask     [I/O] Access rights.
2459  *  GenericMapping [I] The mapping between generic and specific rights.
2460  *
2461  * RETURNS
2462  *  Nothing.
2463  */
2464 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2465 {
2466     RtlMapGenericMask( AccessMask, GenericMapping );
2467 }
2468 
2469 /*************************************************************************
2470  * SetKernelObjectSecurity [ADVAPI32.@]
2471  */
2472 BOOL WINAPI SetKernelObjectSecurity (
2473         IN HANDLE Handle,
2474         IN SECURITY_INFORMATION SecurityInformation,
2475         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2476 {
2477     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2478 }
2479 
2480 
2481 /******************************************************************************
2482  *  AddAuditAccessAce [ADVAPI32.@]
2483  */
2484 BOOL WINAPI AddAuditAccessAce(
2485     IN OUT PACL pAcl, 
2486     IN DWORD dwAceRevision, 
2487     IN DWORD dwAccessMask, 
2488     IN PSID pSid, 
2489     IN BOOL bAuditSuccess, 
2490     IN BOOL bAuditFailure) 
2491 {
2492     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2493                                               bAuditSuccess, bAuditFailure) ); 
2494 }
2495 
2496 /******************************************************************************
2497  *  AddAuditAccessAce [ADVAPI32.@]
2498  */
2499 BOOL WINAPI AddAuditAccessAceEx(
2500     IN OUT PACL pAcl,
2501     IN DWORD dwAceRevision,
2502     IN DWORD dwAceFlags,
2503     IN DWORD dwAccessMask,
2504     IN PSID pSid,
2505     IN BOOL bAuditSuccess,
2506     IN BOOL bAuditFailure)
2507 {
2508     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2509                                               bAuditSuccess, bAuditFailure) );
2510 }
2511 
2512 /******************************************************************************
2513  * LookupAccountNameA [ADVAPI32.@]
2514  */
2515 BOOL WINAPI
2516 LookupAccountNameA(
2517         IN LPCSTR system,
2518         IN LPCSTR account,
2519         OUT PSID sid,
2520         OUT LPDWORD cbSid,
2521         LPSTR ReferencedDomainName,
2522         IN OUT LPDWORD cbReferencedDomainName,
2523         OUT PSID_NAME_USE name_use )
2524 {
2525     BOOL ret;
2526     UNICODE_STRING lpSystemW;
2527     UNICODE_STRING lpAccountW;
2528     LPWSTR lpReferencedDomainNameW = NULL;
2529 
2530     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2531     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2532 
2533     if (ReferencedDomainName)
2534         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2535 
2536     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2537         cbReferencedDomainName, name_use);
2538 
2539     if (ret && lpReferencedDomainNameW)
2540     {
2541         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2542             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2543     }
2544 
2545     RtlFreeUnicodeString(&lpSystemW);
2546     RtlFreeUnicodeString(&lpAccountW);
2547     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2548 
2549     return ret;
2550 }
2551 
2552 /******************************************************************************
2553  * lookup_user_account_name
2554  */
2555 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2556                                      LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2557 {
2558     /* Default implementation: Always return a default SID */
2559     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2560     BOOL ret;
2561     PSID pSid;
2562     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2563     DWORD nameLen;
2564     LPCWSTR domainName;
2565 
2566     ret = AllocateAndInitializeSid(&identifierAuthority,
2567         2,
2568         SECURITY_BUILTIN_DOMAIN_RID,
2569         DOMAIN_ALIAS_RID_ADMINS,
2570         0, 0, 0, 0, 0, 0,
2571         &pSid);
2572 
2573     if (!ret)
2574        return FALSE;
2575 
2576     if (!RtlValidSid(pSid))
2577     {
2578        FreeSid(pSid);
2579        return FALSE;
2580     }
2581 
2582     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2583        CopySid(*cbSid, Sid, pSid);
2584     if (*cbSid < GetLengthSid(pSid))
2585     {
2586        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2587        ret = FALSE;
2588     }
2589     *cbSid = GetLengthSid(pSid);
2590 
2591     domainName = dm;
2592     nameLen = strlenW(domainName);
2593 
2594     if (*cchReferencedDomainName <= nameLen || !ret)
2595     {
2596         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2597         nameLen += 1;
2598         ret = FALSE;
2599     }
2600     else if (ReferencedDomainName)
2601         strcpyW(ReferencedDomainName, domainName);
2602 
2603     *cchReferencedDomainName = nameLen;
2604 
2605     if (ret)
2606         *peUse = SidTypeUser;
2607 
2608     FreeSid(pSid);
2609 
2610     return ret;
2611 }
2612 
2613 /******************************************************************************
2614  * lookup_computer_account_name
2615  */
2616 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2617                                          LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2618 {
2619     MAX_SID local;
2620     BOOL ret;
2621     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2622     DWORD nameLen;
2623     LPCWSTR domainName;
2624 
2625     if ((ret = ADVAPI_GetComputerSid(&local)))
2626     {
2627         if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2628            CopySid(*cbSid, Sid, &local);
2629         if (*cbSid < GetLengthSid(&local))
2630         {
2631            SetLastError(ERROR_INSUFFICIENT_BUFFER);
2632            ret = FALSE;
2633         }
2634         *cbSid = GetLengthSid(&local);
2635     }
2636 
2637     domainName = dm;
2638     nameLen = strlenW(domainName);
2639 
2640     if (*cchReferencedDomainName <= nameLen || !ret)
2641     {
2642         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2643         nameLen += 1;
2644         ret = FALSE;
2645     }
2646     else if (ReferencedDomainName)
2647         strcpyW(ReferencedDomainName, domainName);
2648 
2649     *cchReferencedDomainName = nameLen;
2650 
2651     if (ret)
2652         *peUse = SidTypeDomain;
2653 
2654     return ret;
2655 }
2656 
2657 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2658                                   LSA_UNICODE_STRING *domain )
2659 {
2660     WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2661 
2662     while (p > str->Buffer && *p != '\\') p--;
2663 
2664     if (*p == '\\')
2665     {
2666         domain->Buffer = str->Buffer;
2667         domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2668 
2669         account->Buffer = p + 1;
2670         account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2671     }
2672     else
2673     {
2674         domain->Buffer = NULL;
2675         domain->Length = 0;
2676 
2677         account->Buffer = str->Buffer;
2678         account->Length = str->Length;
2679     }
2680 }
2681 
2682 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2683 {
2684     ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2685 
2686     if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2687         return TRUE;
2688 
2689     return FALSE;
2690 }
2691 
2692 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2693 {
2694     ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2695 
2696     if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2697         return TRUE;
2698 
2699     if (ACCOUNT_SIDS[idx].alias)
2700     {
2701         len = strlenW( ACCOUNT_SIDS[idx].alias );
2702         if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2703             return TRUE;
2704     }
2705     return FALSE;
2706 }
2707 
2708 /*
2709  * Helper function for LookupAccountNameW
2710  */
2711 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2712                                   PSID Sid, LPDWORD cbSid,
2713                                   LPWSTR ReferencedDomainName,
2714                                   LPDWORD cchReferencedDomainName,
2715                                   PSID_NAME_USE peUse, BOOL *handled )
2716 {
2717     PSID pSid;
2718     LSA_UNICODE_STRING account, domain;
2719     BOOL ret = TRUE;
2720     ULONG i;
2721 
2722     *handled = FALSE;
2723     split_domain_account( account_and_domain, &account, &domain );
2724 
2725     for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2726     {
2727         /* check domain first */
2728         if (domain.Buffer && !match_domain( i, &domain )) continue;
2729 
2730         if (match_account( i, &account ))
2731         {
2732             DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2733 
2734             if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2735 
2736             if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2737             {
2738                 if (*cbSid < sidLen)
2739                 {
2740                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2741                     ret = FALSE;
2742                 }
2743                 else if (Sid)
2744                 {
2745                     CopySid(*cbSid, Sid, pSid);
2746                 }
2747                 *cbSid = sidLen;
2748             }
2749 
2750             len = strlenW( ACCOUNT_SIDS[i].domain );
2751             if (*cchReferencedDomainName <= len || !ret)
2752             {
2753                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2754                 len++;
2755                 ret = FALSE;
2756             }
2757             else if (ReferencedDomainName)
2758             {
2759                 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2760             }
2761 
2762             *cchReferencedDomainName = len;
2763             if (ret)
2764                 *peUse = ACCOUNT_SIDS[i].name_use;
2765 
2766             HeapFree(GetProcessHeap(), 0, pSid);
2767             *handled = TRUE;
2768             return ret;
2769         }
2770     }
2771     return ret;
2772 }
2773 
2774 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2775                              PSID Sid, LPDWORD cbSid,
2776                              LPWSTR ReferencedDomainName,
2777                              LPDWORD cchReferencedDomainName,
2778                              PSID_NAME_USE peUse, BOOL *handled )
2779 {
2780     DWORD nameLen;
2781     LPWSTR userName = NULL;
2782     LSA_UNICODE_STRING account, domain;
2783     BOOL ret = TRUE;
2784 
2785     *handled = FALSE;
2786     split_domain_account( account_and_domain, &account, &domain );
2787 
2788     /* Let the current Unix user id masquerade as first Windows user account */
2789 
2790     nameLen = UNLEN + 1;
2791     if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2792 
2793     if (domain.Buffer)
2794     {
2795         /* check to make sure this account is on this computer */
2796         if (GetComputerNameW( userName, &nameLen ) &&
2797             (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2798         {
2799             SetLastError(ERROR_NONE_MAPPED);
2800             ret = FALSE;
2801         }
2802         nameLen = UNLEN + 1;
2803     }
2804 
2805     if (GetUserNameW( userName, &nameLen ) &&
2806         account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2807     {
2808             ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2809             *handled = TRUE;
2810     }
2811     else
2812     {
2813         nameLen = UNLEN + 1;
2814         if (GetComputerNameW( userName, &nameLen ) &&
2815             account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2816         {
2817             ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2818             *handled = TRUE;
2819         }
2820     }
2821 
2822     HeapFree(GetProcessHeap(), 0, userName);
2823     return ret;
2824 }
2825 
2826 /******************************************************************************
2827  * LookupAccountNameW [ADVAPI32.@]
2828  */
2829 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2830                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2831                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2832 {
2833     BOOL ret, handled;
2834     LSA_UNICODE_STRING account;
2835 
2836     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2837           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2838 
2839     if (!ADVAPI_IsLocalComputer( lpSystemName ))
2840     {
2841         SetLastError( RPC_S_SERVER_UNAVAILABLE );
2842         return FALSE;
2843     }
2844 
2845     if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2846     {
2847         lpAccountName = BUILTIN;
2848     }
2849 
2850     RtlInitUnicodeString( &account, lpAccountName );
2851 
2852     /* Check well known SIDs first */
2853     ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2854                                        cchReferencedDomainName, peUse, &handled );
2855     if (handled)
2856         return ret;
2857 
2858     /* Check user names */
2859     ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2860                                   cchReferencedDomainName, peUse, &handled);
2861     if (handled)
2862         return ret;
2863 
2864     SetLastError( ERROR_NONE_MAPPED );
2865     return FALSE;
2866 }
2867 
2868 /******************************************************************************
2869  * PrivilegeCheck [ADVAPI32.@]
2870  */
2871 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2872 {
2873     BOOL ret;
2874     BOOLEAN Result;
2875 
2876     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2877 
2878     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2879     if (ret)
2880         *pfResult = Result;
2881     return ret;
2882 }
2883 
2884 /******************************************************************************
2885  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2886  */
2887 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2888   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2889   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2890   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2891 {
2892         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2893                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2894                 SecurityDescriptor, DesiredAccess, GenericMapping,
2895                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2896         return TRUE;
2897 }
2898 
2899 /******************************************************************************
2900  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2901  */
2902 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2903   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2904   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2905   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2906 {
2907         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2908                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2909                 SecurityDescriptor, DesiredAccess, GenericMapping,
2910                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2911         return TRUE;
2912 }
2913 
2914 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2915 {
2916     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2917 
2918     return TRUE;
2919 }
2920 
2921 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2922 {
2923     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2924 
2925     return TRUE;
2926 }
2927 
2928 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2929 {
2930     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2931 
2932     return TRUE;
2933 }
2934 
2935 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2936   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2937   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2938   LPBOOL GenerateOnClose)
2939 {
2940         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2941                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2942         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2943         GenerateOnClose);
2944 
2945     return TRUE;
2946 }
2947 
2948 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2949   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2950   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2951   LPBOOL GenerateOnClose)
2952 {
2953     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2954         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2955         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2956         GenerateOnClose);
2957 
2958     return TRUE;
2959 }
2960 
2961 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2962   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2963 {
2964     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2965           DesiredAccess, Privileges, AccessGranted);
2966 
2967     return TRUE;
2968 }
2969 
2970 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2971   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2972 {
2973     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2974           DesiredAccess, Privileges, AccessGranted);
2975 
2976     return TRUE;
2977 }
2978 
2979 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2980                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2981 {
2982     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2983           ClientToken, Privileges, AccessGranted);
2984 
2985     return TRUE;
2986 }
2987 
2988 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2989                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2990 {
2991     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2992           ClientToken, Privileges, AccessGranted);
2993 
2994     return TRUE;
2995 }
2996 
2997 /******************************************************************************
2998  * GetSecurityInfo [ADVAPI32.@]
2999  *
3000  * Retrieves a copy of the security descriptor associated with an object.
3001  *
3002  * PARAMS
3003  *  hObject              [I] A handle for the object.
3004  *  ObjectType           [I] The type of object.
3005  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
3006  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
3007  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
3008  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
3009  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
3010  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3011  *                           which must be freed with LocalFree.
3012  *
3013  * RETURNS
3014  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3015  */
3016 DWORD WINAPI GetSecurityInfo(
3017     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3018     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3019     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3020     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3021 )
3022 {
3023     PSECURITY_DESCRIPTOR sd;
3024     NTSTATUS status;
3025     ULONG n1, n2;
3026     BOOL present, defaulted;
3027 
3028     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3029     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3030         return RtlNtStatusToDosError(status);
3031 
3032     sd = LocalAlloc(0, n1);
3033     if (!sd)
3034         return ERROR_NOT_ENOUGH_MEMORY;
3035 
3036     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3037     if (status != STATUS_SUCCESS)
3038     {
3039         LocalFree(sd);
3040         return RtlNtStatusToDosError(status);
3041     }
3042 
3043     if (ppsidOwner)
3044     {
3045         *ppsidOwner = NULL;
3046         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3047     }
3048     if (ppsidGroup)
3049     {
3050         *ppsidGroup = NULL;
3051         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3052     }
3053     if (ppDacl)
3054     {
3055         *ppDacl = NULL;
3056         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3057     }
3058     if (ppSacl)
3059     {
3060         *ppSacl = NULL;
3061         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3062     }
3063     if (ppSecurityDescriptor)
3064         *ppSecurityDescriptor = sd;
3065 
3066     return ERROR_SUCCESS;
3067 }
3068 
3069 /******************************************************************************
3070  * GetSecurityInfoExA [ADVAPI32.@]
3071  */
3072 DWORD WINAPI GetSecurityInfoExA(
3073         HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3074         SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3075         LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3076         PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3077 )
3078 {
3079   FIXME("stub!\n");
3080   return ERROR_BAD_PROVIDER;
3081 }
3082 
3083 /******************************************************************************
3084  * GetSecurityInfoExW [ADVAPI32.@]
3085  */
3086 DWORD WINAPI GetSecurityInfoExW(
3087         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
3088         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3089         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
3090         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3091 )
3092 {
3093   FIXME("stub!\n");
3094   return ERROR_BAD_PROVIDER; 
3095 }
3096 
3097 /******************************************************************************
3098  * BuildExplicitAccessWithNameA [ADVAPI32.@]
3099  */
3100 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3101                                           LPSTR pTrusteeName, DWORD AccessPermissions,
3102                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3103 {
3104     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3105           AccessPermissions, AccessMode, Inheritance);
3106 
3107     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3108     pExplicitAccess->grfAccessMode = AccessMode;
3109     pExplicitAccess->grfInheritance = Inheritance;
3110 
3111     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3112     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3113     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3114     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3115     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3116 }
3117 
3118 /******************************************************************************
3119  * BuildExplicitAccessWithNameW [ADVAPI32.@]
3120  */
3121 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3122                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
3123                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3124 {
3125     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3126           AccessPermissions, AccessMode, Inheritance);
3127 
3128     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3129     pExplicitAccess->grfAccessMode = AccessMode;
3130     pExplicitAccess->grfInheritance = Inheritance;
3131 
3132     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3133     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3134     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3135     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3136     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3137 }
3138 
3139 /******************************************************************************
3140  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3141  */
3142 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3143                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3144                                              LPSTR InheritedObjectTypeName, LPSTR Name )
3145 {
3146     DWORD ObjectsPresent = 0;
3147 
3148     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3149           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3150 
3151     /* Fill the OBJECTS_AND_NAME structure */
3152     pObjName->ObjectType = ObjectType;
3153     if (ObjectTypeName != NULL)
3154     {
3155         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3156     }
3157 
3158     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3159     if (InheritedObjectTypeName != NULL)
3160     {
3161         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3162     }
3163 
3164     pObjName->ObjectsPresent = ObjectsPresent;
3165     pObjName->ptstrName = Name;
3166 
3167     /* Fill the TRUSTEE structure */
3168     pTrustee->pMultipleTrustee = NULL;
3169     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3170     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3171     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3172     pTrustee->ptstrName = (LPSTR)pObjName;
3173 }
3174 
3175 /******************************************************************************
3176  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3177  */
3178 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3179                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3180                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
3181 {
3182     DWORD ObjectsPresent = 0;
3183 
3184     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3185           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3186 
3187     /* Fill the OBJECTS_AND_NAME structure */
3188     pObjName->ObjectType = ObjectType;
3189     if (ObjectTypeName != NULL)
3190     {
3191         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3192     }
3193 
3194     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3195     if (InheritedObjectTypeName != NULL)
3196     {
3197         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3198     }
3199 
3200     pObjName->ObjectsPresent = ObjectsPresent;
3201     pObjName->ptstrName = Name;
3202 
3203     /* Fill the TRUSTEE structure */
3204     pTrustee->pMultipleT