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