~ [ 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     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1919           RequestedInformation, pSecurityDescriptor,
1920           nLength, lpnLengthNeeded);
1921 
1922     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1923                                 DACL_SECURITY_INFORMATION))
1924         access |= READ_CONTROL;
1925     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1926         access |= ACCESS_SYSTEM_SECURITY;
1927 
1928     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1929                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1930     if ( hfile == INVALID_HANDLE_VALUE )
1931         return FALSE;
1932 
1933     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1934                                     nLength, lpnLengthNeeded );
1935     CloseHandle( hfile );
1936     return set_ntstatus( status );
1937 }
1938 
1939 
1940 /******************************************************************************
1941  * LookupAccountSidA [ADVAPI32.@]
1942  */
1943 BOOL WINAPI
1944 LookupAccountSidA(
1945         IN LPCSTR system,
1946         IN PSID sid,
1947         OUT LPSTR account,
1948         IN OUT LPDWORD accountSize,
1949         OUT LPSTR domain,
1950         IN OUT LPDWORD domainSize,
1951         OUT PSID_NAME_USE name_use )
1952 {
1953     DWORD len;
1954     BOOL r;
1955     LPWSTR systemW = NULL;
1956     LPWSTR accountW = NULL;
1957     LPWSTR domainW = NULL;
1958     DWORD accountSizeW = *accountSize;
1959     DWORD domainSizeW = *domainSize;
1960 
1961     if (system) {
1962         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1963         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1964         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1965     }
1966     if (account)
1967         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1968     if (domain)
1969         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1970 
1971     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1972 
1973     if (r) {
1974         if (accountW && *accountSize) {
1975             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1976             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1977             *accountSize = len;
1978         } else
1979             *accountSize = accountSizeW + 1;
1980 
1981         if (domainW && *domainSize) {
1982             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1983             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1984             *domainSize = len;
1985         } else
1986             *domainSize = domainSizeW + 1;
1987     }
1988 
1989     HeapFree( GetProcessHeap(), 0, systemW );
1990     HeapFree( GetProcessHeap(), 0, accountW );
1991     HeapFree( GetProcessHeap(), 0, domainW );
1992 
1993     return r;
1994 }
1995 
1996 /******************************************************************************
1997  * LookupAccountSidW [ADVAPI32.@]
1998  *
1999  * PARAMS
2000  *   system      []
2001  *   sid         []
2002  *   account     []
2003  *   accountSize []
2004  *   domain      []
2005  *   domainSize  []
2006  *   name_use    []
2007  */
2008 
2009 BOOL WINAPI
2010 LookupAccountSidW(
2011         IN LPCWSTR system,
2012         IN PSID sid,
2013         OUT LPWSTR account,
2014         IN OUT LPDWORD accountSize,
2015         OUT LPWSTR domain,
2016         IN OUT LPDWORD domainSize,
2017         OUT PSID_NAME_USE name_use )
2018 {
2019     unsigned int i, j;
2020     const WCHAR * ac = NULL;
2021     const WCHAR * dm = NULL;
2022     SID_NAME_USE use = 0;
2023     LPWSTR computer_name = NULL;
2024     LPWSTR account_name = NULL;
2025 
2026     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2027           debugstr_w(system),debugstr_sid(sid),
2028           account,accountSize,accountSize?*accountSize:0,
2029           domain,domainSize,domainSize?*domainSize:0,
2030           name_use);
2031 
2032     if (!ADVAPI_IsLocalComputer(system)) {
2033         FIXME("Only local computer supported!\n");
2034         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2035         return FALSE;
2036     }
2037 
2038     /* check the well known SIDs first */
2039     for (i = 0; i <= 60; i++) {
2040         if (IsWellKnownSid(sid, i)) {
2041             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2042                 if (ACCOUNT_SIDS[j].type == i) {
2043                     ac = ACCOUNT_SIDS[j].account;
2044                     dm = ACCOUNT_SIDS[j].domain;
2045                     use = ACCOUNT_SIDS[j].name_use;
2046                 }
2047             }
2048             break;
2049         }
2050     }
2051 
2052     if (dm == NULL) {
2053         MAX_SID local;
2054 
2055         /* check for the local computer next */
2056         if (ADVAPI_GetComputerSid(&local)) {
2057             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2058             BOOL result;
2059 
2060             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2061             result = GetComputerNameW(computer_name,  &size);
2062 
2063             if (result) {
2064                 if (EqualSid(sid, &local)) {
2065                     dm = computer_name;
2066                     ac = Blank;
2067                     use = 3;
2068                 } else {
2069                     local.SubAuthorityCount++;
2070 
2071                     if (EqualPrefixSid(sid, &local)) {
2072                         dm = computer_name;
2073                         use = 1;
2074                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2075                         case DOMAIN_USER_RID_ADMIN:
2076                             ac = Administrator;
2077                             break;
2078                         case DOMAIN_USER_RID_GUEST:
2079                             ac = Guest;
2080                             break;
2081                         case DOMAIN_GROUP_RID_ADMINS:
2082                             ac = Domain_Admins;
2083                             break;
2084                         case DOMAIN_GROUP_RID_USERS:
2085                             ac = Domain_Users;
2086                             break;
2087                         case DOMAIN_GROUP_RID_GUESTS:
2088                             ac = Domain_Guests;
2089                             break;
2090                         case DOMAIN_GROUP_RID_COMPUTERS:
2091                             ac = Domain_Computers;
2092                             break;
2093                         case DOMAIN_GROUP_RID_CONTROLLERS:
2094                             ac = Domain_Controllers;
2095                             break;
2096                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2097                             ac = Cert_Publishers;
2098                             break;
2099                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2100                             ac = Schema_Admins;
2101                             break;
2102                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2103                             ac = Enterprise_Admins;
2104                             break;
2105                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2106                             ac = Group_Policy_Creator_Owners;
2107                             break;
2108                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2109                             ac = RAS_and_IAS_Servers;
2110                             break;
2111                         case 1000:      /* first user account */
2112                             size = UNLEN + 1;
2113                             account_name = HeapAlloc(
2114                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2115                             if (GetUserNameW(account_name, &size))
2116                                 ac = account_name;
2117                             else
2118                                 dm = NULL;
2119 
2120                             break;
2121                         default:
2122                             dm = NULL;
2123                             break;
2124                         }
2125                     }
2126                 }
2127             }
2128         }
2129     }
2130 
2131     if (dm) {
2132         DWORD ac_len = lstrlenW(ac);
2133         DWORD dm_len = lstrlenW(dm);
2134         BOOL status = TRUE;
2135 
2136         if (*accountSize > ac_len) {
2137             if (account)
2138                 lstrcpyW(account, ac);
2139         }
2140         if (*domainSize > dm_len) {
2141             if (domain)
2142                 lstrcpyW(domain, dm);
2143         }
2144         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2145             ((*domainSize != 0) && (*domainSize < dm_len))) {
2146             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2147             status = FALSE;
2148         }
2149         if (*domainSize)
2150             *domainSize = dm_len;
2151         else
2152             *domainSize = dm_len + 1;
2153         if (*accountSize)
2154             *accountSize = ac_len;
2155         else
2156             *accountSize = ac_len + 1;
2157         *name_use = use;
2158         HeapFree(GetProcessHeap(), 0, account_name);
2159         HeapFree(GetProcessHeap(), 0, computer_name);
2160         return status;
2161     }
2162 
2163     HeapFree(GetProcessHeap(), 0, account_name);
2164     HeapFree(GetProcessHeap(), 0, computer_name);
2165     SetLastError(ERROR_NONE_MAPPED);
2166     return FALSE;
2167 }
2168 
2169 /******************************************************************************
2170  * SetFileSecurityA [ADVAPI32.@]
2171  *
2172  * See SetFileSecurityW.
2173  */
2174 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2175                                 SECURITY_INFORMATION RequestedInformation,
2176                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2177 {
2178     DWORD len;
2179     BOOL r;
2180     LPWSTR name = NULL;
2181 
2182     if( lpFileName )
2183     {
2184         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2185         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2186         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2187     }
2188 
2189     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2190     HeapFree( GetProcessHeap(), 0, name );
2191 
2192     return r;
2193 }
2194 
2195 /******************************************************************************
2196  * SetFileSecurityW [ADVAPI32.@]
2197  *
2198  * Sets the security of a file or directory.
2199  *
2200  * PARAMS
2201  *   lpFileName           []
2202  *   RequestedInformation []
2203  *   pSecurityDescriptor  []
2204  *
2205  * RETURNS
2206  *  Success: TRUE.
2207  *  Failure: FALSE.
2208  */
2209 BOOL WINAPI
2210 SetFileSecurityW( LPCWSTR lpFileName,
2211                     SECURITY_INFORMATION RequestedInformation,
2212                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2213 {
2214     HANDLE file;
2215     DWORD access = 0;
2216     NTSTATUS status;
2217 
2218     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2219           pSecurityDescriptor );
2220 
2221     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2222         RequestedInformation & GROUP_SECURITY_INFORMATION)
2223         access |= WRITE_OWNER;
2224     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2225         access |= ACCESS_SYSTEM_SECURITY;
2226     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2227         access |= WRITE_DAC;
2228 
2229     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2230                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2231     if (file == INVALID_HANDLE_VALUE)
2232         return FALSE;
2233 
2234     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2235     CloseHandle( file );
2236     return set_ntstatus( status );
2237 }
2238 
2239 /******************************************************************************
2240  * QueryWindows31FilesMigration [ADVAPI32.@]
2241  *
2242  * PARAMS
2243  *   x1 []
2244  */
2245 BOOL WINAPI
2246 QueryWindows31FilesMigration( DWORD x1 )
2247 {
2248         FIXME("(%d):stub\n",x1);
2249         return TRUE;
2250 }
2251 
2252 /******************************************************************************
2253  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2254  *
2255  * PARAMS
2256  *   x1 []
2257  *   x2 []
2258  *   x3 []
2259  *   x4 []
2260  */
2261 BOOL WINAPI
2262 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2263                                                DWORD x4 )
2264 {
2265         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2266         return TRUE;
2267 }
2268 
2269 /******************************************************************************
2270  * NotifyBootConfigStatus [ADVAPI32.@]
2271  *
2272  * PARAMS
2273  *   x1 []
2274  */
2275 BOOL WINAPI
2276 NotifyBootConfigStatus( BOOL x1 )
2277 {
2278         FIXME("(0x%08d):stub\n",x1);
2279         return 1;
2280 }
2281 
2282 /******************************************************************************
2283  * RevertToSelf [ADVAPI32.@]
2284  *
2285  * Ends the impersonation of a user.
2286  *
2287  * PARAMS
2288  *   void []
2289  *
2290  * RETURNS
2291  *  Success: TRUE.
2292  *  Failure: FALSE.
2293  */
2294 BOOL WINAPI
2295 RevertToSelf( void )
2296 {
2297     HANDLE Token = NULL;
2298     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2299         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2300 }
2301 
2302 /******************************************************************************
2303  * ImpersonateSelf [ADVAPI32.@]
2304  *
2305  * Makes an impersonation token that represents the process user and assigns
2306  * to the current thread.
2307  *
2308  * PARAMS
2309  *  ImpersonationLevel [I] Level at which to impersonate.
2310  *
2311  * RETURNS
2312  *  Success: TRUE.
2313  *  Failure: FALSE.
2314  */
2315 BOOL WINAPI
2316 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2317 {
2318     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2319 }
2320 
2321 /******************************************************************************
2322  * ImpersonateLoggedOnUser [ADVAPI32.@]
2323  */
2324 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2325 {
2326     DWORD size;
2327     NTSTATUS Status;
2328     HANDLE ImpersonationToken;
2329     TOKEN_TYPE Type;
2330     static BOOL warn = TRUE;
2331 
2332     if (warn)
2333     {
2334         FIXME( "(%p)\n", hToken );
2335         warn = FALSE;
2336     }
2337     if (!GetTokenInformation( hToken, TokenType, &Type,
2338                               sizeof(TOKEN_TYPE), &size ))
2339         return FALSE;
2340 
2341     if (Type == TokenPrimary)
2342     {
2343         OBJECT_ATTRIBUTES ObjectAttributes;
2344 
2345         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2346 
2347         Status = NtDuplicateToken( hToken,
2348                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2349                                    &ObjectAttributes,
2350                                    SecurityImpersonation,
2351                                    TokenImpersonation,
2352                                    &ImpersonationToken );
2353         if (Status != STATUS_SUCCESS)
2354         {
2355             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2356             SetLastError( RtlNtStatusToDosError( Status ) );
2357             return FALSE;
2358         }
2359     }
2360     else
2361         ImpersonationToken = hToken;
2362 
2363     Status = NtSetInformationThread( GetCurrentThread(),
2364                                      ThreadImpersonationToken,
2365                                      &ImpersonationToken,
2366                                      sizeof(ImpersonationToken) );
2367 
2368     if (Type == TokenPrimary)
2369         NtClose( ImpersonationToken );
2370 
2371     if (Status != STATUS_SUCCESS)
2372     {
2373         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2374         SetLastError( RtlNtStatusToDosError( Status ) );
2375         return FALSE;
2376     }
2377 
2378     return TRUE;
2379 }
2380 
2381 /******************************************************************************
2382  * AccessCheck [ADVAPI32.@]
2383  */
2384 BOOL WINAPI
2385 AccessCheck(
2386         PSECURITY_DESCRIPTOR SecurityDescriptor,
2387         HANDLE ClientToken,
2388         DWORD DesiredAccess,
2389         PGENERIC_MAPPING GenericMapping,
2390         PPRIVILEGE_SET PrivilegeSet,
2391         LPDWORD PrivilegeSetLength,
2392         LPDWORD GrantedAccess,
2393         LPBOOL AccessStatus)
2394 {
2395     NTSTATUS access_status;
2396     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2397                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2398                                            GrantedAccess, &access_status) );
2399     if (ret) *AccessStatus = set_ntstatus( access_status );
2400     return ret;
2401 }
2402 
2403 
2404 /******************************************************************************
2405  * AccessCheckByType [ADVAPI32.@]
2406  */
2407 BOOL WINAPI AccessCheckByType(
2408     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2409     PSID PrincipalSelfSid,
2410     HANDLE ClientToken, 
2411     DWORD DesiredAccess, 
2412     POBJECT_TYPE_LIST ObjectTypeList,
2413     DWORD ObjectTypeListLength,
2414     PGENERIC_MAPPING GenericMapping,
2415     PPRIVILEGE_SET PrivilegeSet,
2416     LPDWORD PrivilegeSetLength, 
2417     LPDWORD GrantedAccess,
2418     LPBOOL AccessStatus)
2419 {
2420         FIXME("stub\n");
2421 
2422         *AccessStatus = TRUE;
2423 
2424         return !*AccessStatus;
2425 }
2426 
2427 /******************************************************************************
2428  * MapGenericMask [ADVAPI32.@]
2429  *
2430  * Maps generic access rights into specific access rights according to the
2431  * supplied mapping.
2432  *
2433  * PARAMS
2434  *  AccessMask     [I/O] Access rights.
2435  *  GenericMapping [I] The mapping between generic and specific rights.
2436  *
2437  * RETURNS
2438  *  Nothing.
2439  */
2440 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2441 {
2442     RtlMapGenericMask( AccessMask, GenericMapping );
2443 }
2444 
2445 /*************************************************************************
2446  * SetKernelObjectSecurity [ADVAPI32.@]
2447  */
2448 BOOL WINAPI SetKernelObjectSecurity (
2449         IN HANDLE Handle,
2450         IN SECURITY_INFORMATION SecurityInformation,
2451         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2452 {
2453     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2454 }
2455 
2456 
2457 /******************************************************************************
2458  *  AddAuditAccessAce [ADVAPI32.@]
2459  */
2460 BOOL WINAPI AddAuditAccessAce(
2461     IN OUT PACL pAcl, 
2462     IN DWORD dwAceRevision, 
2463     IN DWORD dwAccessMask, 
2464     IN PSID pSid, 
2465     IN BOOL bAuditSuccess, 
2466     IN BOOL bAuditFailure) 
2467 {
2468     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2469                                               bAuditSuccess, bAuditFailure) ); 
2470 }
2471 
2472 /******************************************************************************
2473  *  AddAuditAccessAce [ADVAPI32.@]
2474  */
2475 BOOL WINAPI AddAuditAccessAceEx(
2476     IN OUT PACL pAcl,
2477     IN DWORD dwAceRevision,
2478     IN DWORD dwAceFlags,
2479     IN DWORD dwAccessMask,
2480     IN PSID pSid,
2481     IN BOOL bAuditSuccess,
2482     IN BOOL bAuditFailure)
2483 {
2484     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2485                                               bAuditSuccess, bAuditFailure) );
2486 }
2487 
2488 /******************************************************************************
2489  * LookupAccountNameA [ADVAPI32.@]
2490  */
2491 BOOL WINAPI
2492 LookupAccountNameA(
2493         IN LPCSTR system,
2494         IN LPCSTR account,
2495         OUT PSID sid,
2496         OUT LPDWORD cbSid,
2497         LPSTR ReferencedDomainName,
2498         IN OUT LPDWORD cbReferencedDomainName,
2499         OUT PSID_NAME_USE name_use )
2500 {
2501     BOOL ret;
2502     UNICODE_STRING lpSystemW;
2503     UNICODE_STRING lpAccountW;
2504     LPWSTR lpReferencedDomainNameW = NULL;
2505 
2506     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2507     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2508 
2509     if (ReferencedDomainName)
2510         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2511 
2512     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2513         cbReferencedDomainName, name_use);
2514 
2515     if (ret && lpReferencedDomainNameW)
2516     {
2517         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2518             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2519     }
2520 
2521     RtlFreeUnicodeString(&lpSystemW);
2522     RtlFreeUnicodeString(&lpAccountW);
2523     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2524 
2525     return ret;
2526 }
2527 
2528 /******************************************************************************
2529  * LookupAccountNameW [ADVAPI32.@]
2530  */
2531 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2532                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2533                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2534 {
2535     /* Default implementation: Always return a default SID */
2536     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2537     BOOL ret;
2538     PSID pSid;
2539     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2540     unsigned int i;
2541     DWORD nameLen;
2542     LPWSTR userName = NULL;
2543     LPCWSTR domainName;
2544 
2545     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2546           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2547 
2548     if (!ADVAPI_IsLocalComputer(lpSystemName))
2549     {
2550         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2551         return FALSE;
2552     }
2553 
2554     if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2555     {
2556         lpAccountName = BUILTIN;
2557     }
2558 
2559     /* Check well known SIDs first */
2560 
2561     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2562     {
2563         if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2564         {
2565             DWORD sidLen = SECURITY_MAX_SID_SIZE;
2566 
2567             pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2568 
2569             ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2570 
2571             if (ret)
2572             {
2573                 if (*cbSid < sidLen)
2574                 {
2575                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2576                     ret = FALSE;
2577                 }
2578                 else if (Sid)
2579                 {
2580                     CopySid(*cbSid, Sid, pSid);
2581                 }
2582 
2583                 *cbSid = sidLen;
2584             }
2585 
2586             domainName = ACCOUNT_SIDS[i].domain;
2587             nameLen = strlenW(domainName);
2588 
2589             if (*cchReferencedDomainName <= nameLen || !ret)
2590             {
2591                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2592                 nameLen += 1;
2593                 ret = FALSE;
2594             }
2595             else if (ReferencedDomainName && domainName)
2596             {
2597                 strcpyW(ReferencedDomainName, domainName);
2598             }
2599 
2600             *cchReferencedDomainName = nameLen;
2601 
2602             if (ret)
2603             {
2604                 *peUse = ACCOUNT_SIDS[i].name_use;
2605             }
2606 
2607             HeapFree(GetProcessHeap(), 0, pSid);
2608 
2609             return ret;
2610         }
2611     }
2612 
2613     /* Let the current Unix user id masquerade as first Windows user account */
2614 
2615     nameLen = UNLEN + 1;
2616 
2617     userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2618 
2619     ret = GetUserNameW(userName, &nameLen);
2620 
2621     if (ret && strcmpW(lpAccountName, userName) != 0)
2622     {
2623         SetLastError(ERROR_NONE_MAPPED);
2624         ret = FALSE;
2625     }
2626 
2627     HeapFree(GetProcessHeap(), 0, userName);
2628 
2629     if (!ret)
2630     {
2631         return ret;
2632     }
2633 
2634     ret = AllocateAndInitializeSid(&identifierAuthority,
2635         2,
2636         SECURITY_BUILTIN_DOMAIN_RID,
2637         DOMAIN_ALIAS_RID_ADMINS,
2638         0, 0, 0, 0, 0, 0,
2639         &pSid);
2640 
2641     if (!ret)
2642        return FALSE;
2643 
2644     if (!RtlValidSid(pSid))
2645     {
2646        FreeSid(pSid);
2647        return FALSE;
2648     }
2649 
2650     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2651        CopySid(*cbSid, Sid, pSid);
2652     if (*cbSid < GetLengthSid(pSid))
2653     {
2654        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2655        ret = FALSE;
2656     }
2657     *cbSid = GetLengthSid(pSid);
2658 
2659     domainName = dm;
2660     nameLen = strlenW(domainName);
2661 
2662     if (*cchReferencedDomainName <= nameLen || !ret)
2663     {
2664         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2665         nameLen += 1;
2666         ret = FALSE;
2667     }
2668     else if (ReferencedDomainName)
2669     {
2670         strcpyW(ReferencedDomainName, domainName);
2671     }
2672 
2673     *cchReferencedDomainName = nameLen;
2674 
2675     if (ret)
2676     {
2677         *peUse = SidTypeUser;
2678     }
2679 
2680     FreeSid(pSid);
2681 
2682     return ret;
2683 }
2684 
2685 /******************************************************************************
2686  * PrivilegeCheck [ADVAPI32.@]
2687  */
2688 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2689 {
2690     BOOL ret;
2691     BOOLEAN Result;
2692 
2693     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2694 
2695     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2696     if (ret)
2697         *pfResult = Result;
2698     return ret;
2699 }
2700 
2701 /******************************************************************************
2702  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2703  */
2704 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2705   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2706   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2707   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2708 {
2709         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2710                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2711                 SecurityDescriptor, DesiredAccess, GenericMapping,
2712                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2713         return TRUE;
2714 }
2715 
2716 /******************************************************************************
2717  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2718  */
2719 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2720   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2721   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2722   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2723 {
2724         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2725                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2726                 SecurityDescriptor, DesiredAccess, GenericMapping,
2727                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2728         return TRUE;
2729 }
2730 
2731 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2732 {
2733     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2734 
2735     return TRUE;
2736 }
2737 
2738 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2739 {
2740     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2741 
2742     return TRUE;
2743 }
2744 
2745 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2746 {
2747     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2748 
2749     return TRUE;
2750 }
2751 
2752 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2753   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2754   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2755   LPBOOL GenerateOnClose)
2756 {
2757         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2758                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2759         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2760         GenerateOnClose);
2761 
2762     return TRUE;
2763 }
2764 
2765 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2766   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2767   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2768   LPBOOL GenerateOnClose)
2769 {
2770     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2771         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2772         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2773         GenerateOnClose);
2774 
2775     return TRUE;
2776 }
2777 
2778 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2779   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2780 {
2781     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2782           DesiredAccess, Privileges, AccessGranted);
2783 
2784     return TRUE;
2785 }
2786 
2787 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2788   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2789 {
2790     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2791           DesiredAccess, Privileges, AccessGranted);
2792 
2793     return TRUE;
2794 }
2795 
2796 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2797                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2798 {
2799     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2800           ClientToken, Privileges, AccessGranted);
2801 
2802     return TRUE;
2803 }
2804 
2805 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2806                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2807 {
2808     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2809           ClientToken, Privileges, AccessGranted);
2810 
2811     return TRUE;
2812 }
2813 
2814 /******************************************************************************
2815  * GetSecurityInfo [ADVAPI32.@]
2816  *
2817  * Retrieves a copy of the security descriptor associated with an object.
2818  *
2819  * PARAMS
2820  *  hObject              [I] A handle for the object.
2821  *  ObjectType           [I] The type of object.
2822  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
2823  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
2824  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
2825  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
2826  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
2827  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2828  *                           which must be freed with LocalFree.
2829  *
2830  * RETURNS
2831  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2832  */
2833 DWORD WINAPI GetSecurityInfo(
2834     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2835     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2836     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2837     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2838 )
2839 {
2840     PSECURITY_DESCRIPTOR sd;
2841     NTSTATUS status;
2842     ULONG n1, n2;
2843     BOOL present, defaulted;
2844 
2845     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2846     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2847         return RtlNtStatusToDosError(status);
2848 
2849     sd = LocalAlloc(0, n1);
2850     if (!sd)
2851         return ERROR_NOT_ENOUGH_MEMORY;
2852 
2853     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2854     if (status != STATUS_SUCCESS)
2855     {
2856         LocalFree(sd);
2857         return RtlNtStatusToDosError(status);
2858     }
2859 
2860     if (ppsidOwner)
2861     {
2862         *ppsidOwner = NULL;
2863         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2864     }
2865     if (ppsidGroup)
2866     {
2867         *ppsidGroup = NULL;
2868         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2869     }
2870     if (ppDacl)
2871     {
2872         *ppDacl = NULL;
2873         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2874     }
2875     if (ppSacl)
2876     {
2877         *ppSacl = NULL;
2878         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2879     }
2880     if (ppSecurityDescriptor)
2881         *ppSecurityDescriptor = sd;
2882 
2883     return ERROR_SUCCESS;
2884 }
2885 
2886 /******************************************************************************
2887  * GetSecurityInfoExW [ADVAPI32.@]
2888  */
2889 DWORD WINAPI GetSecurityInfoExW(
2890         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2891         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2892         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2893         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2894 )
2895 {
2896   FIXME("stub!\n");
2897   return ERROR_BAD_PROVIDER; 
2898 }
2899 
2900 /******************************************************************************
2901  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2902  */
2903 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2904                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2905                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2906 {
2907     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2908           AccessPermissions, AccessMode, Inheritance);
2909 
2910     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2911     pExplicitAccess->grfAccessMode = AccessMode;
2912     pExplicitAccess->grfInheritance = Inheritance;
2913 
2914     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2915     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2916     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2917     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2918     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2919 }
2920 
2921 /******************************************************************************
2922  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2923  */
2924 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2925                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2926                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2927 {
2928     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2929           AccessPermissions, AccessMode, Inheritance);
2930 
2931     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2932     pExplicitAccess->grfAccessMode = AccessMode;
2933     pExplicitAccess->grfInheritance = Inheritance;
2934 
2935     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2936     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2937     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2938     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2939     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2940 }
2941 
2942 /******************************************************************************
2943  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2944  */
2945 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2946                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2947                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2948 {
2949     DWORD ObjectsPresent = 0;
2950 
2951     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2952           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2953 
2954     /* Fill the OBJECTS_AND_NAME structure */
2955     pObjName->ObjectType = ObjectType;
2956     if (ObjectTypeName != NULL)
2957     {
2958         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2959     }
2960 
2961     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2962     if (InheritedObjectTypeName != NULL)
2963     {
2964         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2965     }
2966 
2967     pObjName->ObjectsPresent = ObjectsPresent;
2968     pObjName->ptstrName = Name;
2969 
2970     /* Fill the TRUSTEE structure */
2971     pTrustee->pMultipleTrustee = NULL;
2972     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2973     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2974     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2975     pTrustee->ptstrName = (LPSTR)pObjName;
2976 }
2977 
2978 /******************************************************************************
2979  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2980  */
2981 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2982                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2983                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2984 {
2985     DWORD ObjectsPresent = 0;
2986 
2987     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2988           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2989 
2990     /* Fill the OBJECTS_AND_NAME structure */
2991     pObjName->ObjectType = ObjectType;
2992     if (ObjectTypeName != NULL)
2993     {
2994         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2995     }
2996 
2997     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2998     if (InheritedObjectTypeName != NULL)
2999     {
3000         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3001     }
3002 
3003     pObjName->ObjectsPresent = ObjectsPresent;
3004     pObjName->ptstrName = Name;
3005 
3006     /* Fill the TRUSTEE structure */
3007     pTrustee->pMultipleTrustee = NULL;
3008     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3009     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3010     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3011     pTrustee->ptstrName = (LPWSTR)pObjName;
3012 }
3013 
3014 /******************************************************************************
3015  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3016  */
3017 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3018                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3019 {
3020     DWORD ObjectsPresent = 0;
3021 
3022     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3023 
3024     /* Fill the OBJECTS_AND_SID structure */
3025     if (pObjectGuid != NULL)
3026     {
3027         pObjSid->ObjectTypeGuid = *pObjectGuid;
3028         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3029     }
3030     else
3031     {
3032         ZeroMemory(&pObjSid->ObjectTypeGuid,
3033                    sizeof(GUID));
3034     }
3035 
3036     if (pInheritedObjectGuid != NULL)
3037     {
3038         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3039         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3040     }
3041     else
3042     {
3043         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3044                    sizeof(GUID));
3045     }
3046 
3047     pObjSid->ObjectsPresent = ObjectsPresent;
3048     pObjSid->pSid = pSid;
3049 
3050     /* Fill the TRUSTEE structure */
3051     pTrustee->pMultipleTrustee = NULL;
3052     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3053     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3054     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3055     pTrustee->ptstrName = (LPSTR) pObjSid;
3056 }
3057 
3058 /******************************************************************************
3059  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3060  */
3061 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3062                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3063 {
3064     DWORD ObjectsPresent = 0;
3065 
3066     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3067 
3068     /* Fill the OBJECTS_AND_SID structure */
3069     if (pObjectGuid != NULL)
3070     {
3071         pObjSid->ObjectTypeGuid = *pObjectGuid;
3072         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3073     }
3074     else
3075     {
3076         ZeroMemory(&pObjSid->ObjectTypeGuid,
3077                    sizeof(GUID));
3078     }
3079 
3080     if (pInheritedObjectGuid != NULL)
3081     {
3082         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3083         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3084     }
3085     else
3086     {
3087         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3088                    sizeof(GUID));
3089     }
3090 
3091     pObjSid->ObjectsPresent = ObjectsPresent;
3092     pObjSid->pSid = pSid;
3093 
3094     /* Fill the TRUSTEE structure */
3095     pTrustee->pMultipleTrustee = NULL;
3096     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3097     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3098     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3099     pTrustee->ptstrName = (LPWSTR) pObjSid;
3100 }
3101 
3102 /******************************************************************************
3103  * BuildTrusteeWithSidA [ADVAPI32.@]
3104  */
3105 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3106 {
3107     TRACE("%p %p\n", pTrustee, pSid);
3108 
3109     pTrustee->pMultipleTrustee = NULL;
3110     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3111     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3112     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3113     pTrustee->ptstrName = (LPSTR) pSid;
3114 }
3115 
3116 /******************************************************************************
3117  * BuildTrusteeWithSidW [ADVAPI32.@]
3118  */
3119 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3120 {
3121     TRACE("%p %p\n", pTrustee, pSid);
3122 
3123     pTrustee->pMultipleTrustee = NULL;
3124     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3125     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3126     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3127     pTrustee->ptstrName = (LPWSTR) pSid;
3128 }
3129 
3130 /******************************************************************************
3131  * BuildTrusteeWithNameA [ADVAPI32.@]
3132  */
3133 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3134 {
3135     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3136 
3137     pTrustee->pMultipleTrustee = NULL;
3138     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3139     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3140     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3141     pTrustee->ptstrName = name;
3142 }
3143 
3144 /******************************************************************************
3145  * BuildTrusteeWithNameW [ADVAPI32.@]
3146  */
3147 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3148 {
3149     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3150 
3151     pTrustee->pMultipleTrustee = NULL;
3152     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3153     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3154     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3155     pTrustee->ptstrName = name;
3156 }
3157 
3158 /****************************************************************************** 
3159  * GetTrusteeFormA [ADVAPI32.@] 
3160  */ 
3161 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3162 {  
3163     TRACE("(%p)\n", pTrustee); 
3164   
3165     if (!pTrustee) 
3166         return TRUSTEE_BAD_FORM; 
3167   
3168     return pTrustee->TrusteeForm; 
3169 }  
3170   
3171 /****************************************************************************** 
3172  * GetTrusteeFormW [ADVAPI32.@] 
3173  */ 
3174 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3175 {  
3176     TRACE("(%p)\n", pTrustee); 
3177   
3178     if (!pTrustee) 
3179         return TRUSTEE_BAD_FORM; 
3180   
3181     return pTrustee->TrusteeForm; 
3182 }  
3183   
3184 /****************************************************************************** 
3185  * GetTrusteeNameA [ADVAPI32.@] 
3186  */ 
3187 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3188 {  
3189     TRACE("(%p)\n", pTrustee); 
3190   
3191     if (!pTrustee) 
3192         return NULL; 
3193   
3194     return pTrustee->ptstrName; 
3195 }  
3196   
3197 /****************************************************************************** 
3198  * GetTrusteeNameW [ADVAPI32.@] 
3199  */ 
3200 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3201 {  
3202     TRACE("(%p)\n", pTrustee); 
3203   
3204     if (!pTrustee) 
3205         return NULL; 
3206   
3207     return pTrustee->ptstrName; 
3208 }  
3209   
3210 /****************************************************************************** 
3211  * GetTrusteeTypeA [ADVAPI32.@] 
3212  */ 
3213 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3214 {  
3215     TRACE("(%p)\n", pTrustee); 
3216   
3217     if (!pTrustee) 
3218         return TRUSTEE_IS_UNKNOWN; 
3219   
3220     return pTrustee->TrusteeType; 
3221 }  
3222   
3223 /****************************************************************************** 
3224  * GetTrusteeTypeW [ADVAPI32.@] 
3225  */ 
3226 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3227 {  
3228     TRACE("(%p)\n", pTrustee); 
3229   
3230     if (!pTrustee) 
3231         return TRUSTEE_IS_UNKNOWN; 
3232   
3233     return pTrustee->TrusteeType; 
3234 } 
3235  
3236 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3237                                DWORD nAclInformationLength,
3238                                ACL_INFORMATION_CLASS dwAclInformationClass )
3239 {
3240     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3241           nAclInformationLength, dwAclInformationClass);
3242 
3243     return TRUE;
3244 }
3245 
3246 /******************************************************************************
3247  * SetEntriesInAclA [ADVAPI32.@]
3248  */
3249 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3250                                PACL OldAcl, PACL* NewAcl )
3251 {
3252     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3253     if (NewAcl)
3254          *NewAcl = NULL;
3255     return ERROR_SUCCESS;
3256 }
3257 
3258 /******************************************************************************
3259  * SetEntriesInAclW [ADVAPI32.@]
3260  */
3261 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3262                                PACL OldAcl, PACL* NewAcl )
3263 {
3264     ULONG i;
3265     PSID *ppsid;
3266     DWORD ret = ERROR_SUCCESS;
3267     DWORD acl_size = sizeof(ACL);
3268     NTSTATUS status;
3269 
3270     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3271 
3272     *NewAcl = NULL;
3273 
3274     if (!count && !OldAcl)
3275         return ERROR_SUCCESS;
3276 
3277     /* allocate array of maximum sized sids allowed */
3278     ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));