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