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