wine/dlls/secur32/thunks.c

900 lines
30 KiB
C

/* Copyright (C) 2004 Juan Lang
*
* This file implements thunks between wide char and multibyte functions for
* SSPs that only provide one or the other.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winternl.h"
#include "sspi.h"
#include "secur32_priv.h"
#include "thunks.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(secur32);
SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA(
SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
pvGetKeyArgument, phCredential, ptsExpiry);
if (pszPackage)
{
UNICODE_STRING principal, package;
RtlCreateUnicodeStringFromAsciiz(&principal, pszPrincipal);
RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
ret = AcquireCredentialsHandleW(principal.Buffer, package.Buffer,
fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
phCredential, ptsExpiry);
RtlFreeUnicodeString(&principal);
RtlFreeUnicodeString(&package);
}
else
ret = SEC_E_SECPKG_NOT_FOUND;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW(
SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
pvGetKeyArgument, phCredential, ptsExpiry);
if (pszPackage)
{
PSTR principal, package;
principal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
package = SECUR32_AllocMultiByteFromWide(pszPackage);
ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse,
pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
ptsExpiry);
HeapFree(GetProcessHeap(), 0, principal);
HeapFree(GetProcessHeap(), 0, package);
}
else
ret = SEC_E_SECPKG_NOT_FOUND;
return ret;
}
/* thunking is pretty dicey for these--the output type depends on ulAttribute,
* so we have to know about every type the caller does
*/
SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA(
PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
if (phCredential)
{
SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
PCredHandle cred = (PCredHandle)phCredential->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableW.QueryCredentialsAttributesW)
{
ret = package->provider->fnTableW.QueryCredentialsAttributesW(
cred, ulAttribute, pBuffer);
if (ret == SEC_E_OK)
{
switch (ulAttribute)
{
case SECPKG_CRED_ATTR_NAMES:
{
PSecPkgCredentials_NamesW names =
(PSecPkgCredentials_NamesW)pBuffer;
SEC_WCHAR *oldUser = names->sUserName;
if (oldUser)
{
names->sUserName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
package->provider->fnTableW.FreeContextBuffer(
oldUser);
}
break;
}
default:
WARN("attribute type %d unknown\n", ulAttribute);
ret = SEC_E_INTERNAL_ERROR;
}
}
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW(
PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
if (phCredential)
{
SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
PCredHandle cred = (PCredHandle)phCredential->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableA.QueryCredentialsAttributesA)
{
ret = package->provider->fnTableA.QueryCredentialsAttributesA(
cred, ulAttribute, pBuffer);
if (ret == SEC_E_OK)
{
switch (ulAttribute)
{
case SECPKG_CRED_ATTR_NAMES:
{
PSecPkgCredentials_NamesA names =
(PSecPkgCredentials_NamesA)pBuffer;
SEC_CHAR *oldUser = names->sUserName;
if (oldUser)
{
names->sUserName =
(PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
package->provider->fnTableA.FreeContextBuffer(
oldUser);
}
break;
}
default:
WARN("attribute type %d unknown\n", ulAttribute);
ret = SEC_E_INTERNAL_ERROR;
}
}
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextA(
PCredHandle phCredential, PCtxtHandle phContext,
SEC_CHAR *pszTargetName, ULONG fContextReq,
ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
if (phCredential)
{
SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
if (package && package->provider)
{
if (package->provider->fnTableW.InitializeSecurityContextW)
{
UNICODE_STRING target;
RtlCreateUnicodeStringFromAsciiz(&target, pszTargetName);
ret = package->provider->fnTableW.InitializeSecurityContextW(
phCredential, phContext, target.Buffer, fContextReq, Reserved1,
TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
pfContextAttr, ptsExpiry);
RtlFreeUnicodeString(&target);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextW(
PCredHandle phCredential, PCtxtHandle phContext,
SEC_WCHAR *pszTargetName, ULONG fContextReq,
ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
if (phCredential)
{
SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
if (package && package->provider)
{
if (package->provider->fnTableA.InitializeSecurityContextA)
{
PSTR target = SECUR32_AllocMultiByteFromWide(pszTargetName);
ret = package->provider->fnTableA.InitializeSecurityContextA(
phCredential, phContext, target, fContextReq, Reserved1,
TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
pfContextAttr, ptsExpiry);
HeapFree(GetProcessHeap(), 0, target);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials,
SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
pvGetKeyArgument, ptsExpiry);
if (hCredentials)
{
SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableW.AddCredentialsW)
{
UNICODE_STRING szPrincipal, szPackage;
RtlCreateUnicodeStringFromAsciiz(&szPrincipal, pszPrincipal);
RtlCreateUnicodeStringFromAsciiz(&szPackage, pszPackage);
ret = package->provider->fnTableW.AddCredentialsW(
cred, szPrincipal.Buffer, szPackage.Buffer, fCredentialUse,
pAuthData, pGetKeyFn, pvGetKeyArgument, ptsExpiry);
RtlFreeUnicodeString(&szPrincipal);
RtlFreeUnicodeString(&szPackage);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials,
SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
PTimeStamp ptsExpiry)
{
SECURITY_STATUS ret;
TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
pvGetKeyArgument, ptsExpiry);
if (hCredentials)
{
SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableA.AddCredentialsA)
{
PSTR szPrincipal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
PSTR szPackage = SECUR32_AllocMultiByteFromWide(pszPackage);
ret = package->provider->fnTableA.AddCredentialsA(
cred, szPrincipal, szPackage, fCredentialUse, pAuthData,
pGetKeyFn, pvGetKeyArgument, ptsExpiry);
HeapFree(GetProcessHeap(), 0, szPrincipal);
HeapFree(GetProcessHeap(), 0, szPackage);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
static PSecPkgInfoA _copyPackageInfoFlatWToA(const SecPkgInfoW *infoW)
{
PSecPkgInfoA ret;
if (infoW)
{
size_t bytesNeeded = sizeof(SecPkgInfoA);
int nameLen = 0, commentLen = 0;
if (infoW->Name)
{
nameLen = WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1,
NULL, 0, NULL, NULL);
bytesNeeded += nameLen;
}
if (infoW->Comment)
{
commentLen = WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1,
NULL, 0, NULL, NULL);
bytesNeeded += commentLen;
}
ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
if (ret)
{
PSTR nextString = (PSTR)((PBYTE)ret + sizeof(SecPkgInfoA));
memcpy(ret, infoW, sizeof(SecPkgInfoA));
if (infoW->Name)
{
ret->Name = nextString;
WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, nextString,
nameLen, NULL, NULL);
nextString += nameLen;
}
else
ret->Name = NULL;
if (infoW->Comment)
{
ret->Comment = nextString;
WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, nextString,
nameLen, NULL, NULL);
}
else
ret->Comment = NULL;
}
}
else
ret = NULL;
return ret;
}
static SECURITY_STATUS thunk_ContextAttributesWToA(SecurePackage *package,
ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret = SEC_E_OK;
if (package && pBuffer)
{
switch (ulAttribute)
{
case SECPKG_ATTR_NAMES:
{
PSecPkgContext_NamesW names = (PSecPkgContext_NamesW)pBuffer;
SEC_WCHAR *oldUser = names->sUserName;
if (oldUser)
{
names->sUserName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
package->provider->fnTableW.FreeContextBuffer(oldUser);
}
break;
}
case SECPKG_ATTR_AUTHORITY:
{
PSecPkgContext_AuthorityW names =
(PSecPkgContext_AuthorityW)pBuffer;
SEC_WCHAR *oldAuth = names->sAuthorityName;
if (oldAuth)
{
names->sAuthorityName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldAuth);
package->provider->fnTableW.FreeContextBuffer(oldAuth);
}
break;
}
case SECPKG_ATTR_KEY_INFO:
{
PSecPkgContext_KeyInfoW info = (PSecPkgContext_KeyInfoW)pBuffer;
SEC_WCHAR *oldSigAlgName = info->sSignatureAlgorithmName;
SEC_WCHAR *oldEncAlgName = info->sEncryptAlgorithmName;
if (oldSigAlgName)
{
info->sSignatureAlgorithmName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldSigAlgName);
package->provider->fnTableW.FreeContextBuffer(
oldSigAlgName);
}
if (oldEncAlgName)
{
info->sEncryptAlgorithmName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldEncAlgName);
package->provider->fnTableW.FreeContextBuffer(
oldEncAlgName);
}
break;
}
case SECPKG_ATTR_PACKAGE_INFO:
{
PSecPkgContext_PackageInfoW info =
(PSecPkgContext_PackageInfoW)pBuffer;
PSecPkgInfoW oldPkgInfo = info->PackageInfo;
if (oldPkgInfo)
{
info->PackageInfo = (PSecPkgInfoW)
_copyPackageInfoFlatWToA(oldPkgInfo);
package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
}
break;
}
case SECPKG_ATTR_NEGOTIATION_INFO:
{
PSecPkgContext_NegotiationInfoW info =
(PSecPkgContext_NegotiationInfoW)pBuffer;
PSecPkgInfoW oldPkgInfo = info->PackageInfo;
if (oldPkgInfo)
{
info->PackageInfo = (PSecPkgInfoW)
_copyPackageInfoFlatWToA(oldPkgInfo);
package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
}
break;
}
case SECPKG_ATTR_NATIVE_NAMES:
{
PSecPkgContext_NativeNamesW names =
(PSecPkgContext_NativeNamesW)pBuffer;
PWSTR oldClient = names->sClientName;
PWSTR oldServer = names->sServerName;
if (oldClient)
{
names->sClientName = (PWSTR)SECUR32_AllocMultiByteFromWide(
oldClient);
package->provider->fnTableW.FreeContextBuffer(oldClient);
}
if (oldServer)
{
names->sServerName = (PWSTR)SECUR32_AllocMultiByteFromWide(
oldServer);
package->provider->fnTableW.FreeContextBuffer(oldServer);
}
break;
}
case SECPKG_ATTR_CREDENTIAL_NAME:
{
PSecPkgContext_CredentialNameW name =
(PSecPkgContext_CredentialNameW)pBuffer;
PWSTR oldCred = name->sCredentialName;
if (oldCred)
{
name->sCredentialName =
(PWSTR)SECUR32_AllocMultiByteFromWide(oldCred);
package->provider->fnTableW.FreeContextBuffer(oldCred);
}
break;
}
/* no thunking needed: */
case SECPKG_ATTR_ACCESS_TOKEN:
case SECPKG_ATTR_DCE_INFO:
case SECPKG_ATTR_FLAGS:
case SECPKG_ATTR_LIFESPAN:
case SECPKG_ATTR_PASSWORD_EXPIRY:
case SECPKG_ATTR_SESSION_KEY:
case SECPKG_ATTR_SIZES:
case SECPKG_ATTR_STREAM_SIZES:
case SECPKG_ATTR_TARGET_INFORMATION:
break;
default:
WARN("attribute type %d unknown\n", ulAttribute);
ret = SEC_E_INTERNAL_ERROR;
}
}
else
ret = SEC_E_INVALID_TOKEN;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA(PCtxtHandle phContext,
ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
if (phContext)
{
SecurePackage *package = (SecurePackage *)phContext->dwUpper;
PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableW.QueryContextAttributesW)
{
ret = package->provider->fnTableW.QueryContextAttributesW(
ctxt, ulAttribute, pBuffer);
if (ret == SEC_E_OK)
ret = thunk_ContextAttributesWToA(package, ulAttribute,
pBuffer);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
static PSecPkgInfoW _copyPackageInfoFlatAToW(const SecPkgInfoA *infoA)
{
PSecPkgInfoW ret;
if (infoA)
{
size_t bytesNeeded = sizeof(SecPkgInfoW);
int nameLen = 0, commentLen = 0;
if (infoA->Name)
{
nameLen = MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1,
NULL, 0);
bytesNeeded += nameLen * sizeof(WCHAR);
}
if (infoA->Comment)
{
commentLen = MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1,
NULL, 0);
bytesNeeded += commentLen * sizeof(WCHAR);
}
ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
if (ret)
{
PWSTR nextString = (PWSTR)((PBYTE)ret + sizeof(SecPkgInfoW));
memcpy(ret, infoA, sizeof(SecPkgInfoA));
if (infoA->Name)
{
ret->Name = nextString;
MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, nextString,
nameLen);
nextString += nameLen;
}
else
ret->Name = NULL;
if (infoA->Comment)
{
ret->Comment = nextString;
MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, nextString,
commentLen);
}
else
ret->Comment = NULL;
}
}
else
ret = NULL;
return ret;
}
static SECURITY_STATUS thunk_ContextAttributesAToW(SecurePackage *package,
ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret = SEC_E_OK;
if (package && pBuffer)
{
switch (ulAttribute)
{
case SECPKG_ATTR_NAMES:
{
PSecPkgContext_NamesA names = (PSecPkgContext_NamesA)pBuffer;
SEC_CHAR *oldUser = names->sUserName;
if (oldUser)
{
names->sUserName =
(PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
package->provider->fnTableW.FreeContextBuffer(oldUser);
}
break;
}
case SECPKG_ATTR_AUTHORITY:
{
PSecPkgContext_AuthorityA names =
(PSecPkgContext_AuthorityA)pBuffer;
SEC_CHAR *oldAuth = names->sAuthorityName;
if (oldAuth)
{
names->sAuthorityName =
(PSTR)SECUR32_AllocWideFromMultiByte(oldAuth);
package->provider->fnTableW.FreeContextBuffer(oldAuth);
}
break;
}
case SECPKG_ATTR_KEY_INFO:
{
PSecPkgContext_KeyInfoA info = (PSecPkgContext_KeyInfoA)pBuffer;
SEC_CHAR *oldSigAlgName = info->sSignatureAlgorithmName;
SEC_CHAR *oldEncAlgName = info->sEncryptAlgorithmName;
if (oldSigAlgName)
{
info->sSignatureAlgorithmName =
(PSTR)SECUR32_AllocWideFromMultiByte(oldSigAlgName);
package->provider->fnTableW.FreeContextBuffer(
oldSigAlgName);
}
if (oldEncAlgName)
{
info->sEncryptAlgorithmName =
(PSTR)SECUR32_AllocWideFromMultiByte(
oldEncAlgName);
package->provider->fnTableW.FreeContextBuffer(
oldEncAlgName);
}
break;
}
case SECPKG_ATTR_PACKAGE_INFO:
{
PSecPkgContext_PackageInfoA info =
(PSecPkgContext_PackageInfoA)pBuffer;
PSecPkgInfoA oldPkgInfo = info->PackageInfo;
if (oldPkgInfo)
{
info->PackageInfo = (PSecPkgInfoA)
_copyPackageInfoFlatAToW(oldPkgInfo);
package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
}
break;
}
case SECPKG_ATTR_NEGOTIATION_INFO:
{
PSecPkgContext_NegotiationInfoA info =
(PSecPkgContext_NegotiationInfoA)pBuffer;
PSecPkgInfoA oldPkgInfo = info->PackageInfo;
if (oldPkgInfo)
{
info->PackageInfo = (PSecPkgInfoA)
_copyPackageInfoFlatAToW(oldPkgInfo);
package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
}
break;
}
case SECPKG_ATTR_NATIVE_NAMES:
{
PSecPkgContext_NativeNamesA names =
(PSecPkgContext_NativeNamesA)pBuffer;
PSTR oldClient = names->sClientName;
PSTR oldServer = names->sServerName;
if (oldClient)
{
names->sClientName = (PSTR)SECUR32_AllocWideFromMultiByte(
oldClient);
package->provider->fnTableW.FreeContextBuffer(oldClient);
}
if (oldServer)
{
names->sServerName = (PSTR)SECUR32_AllocWideFromMultiByte(
oldServer);
package->provider->fnTableW.FreeContextBuffer(oldServer);
}
break;
}
case SECPKG_ATTR_CREDENTIAL_NAME:
{
PSecPkgContext_CredentialNameA name =
(PSecPkgContext_CredentialNameA)pBuffer;
PSTR oldCred = name->sCredentialName;
if (oldCred)
{
name->sCredentialName =
(PSTR)SECUR32_AllocWideFromMultiByte(oldCred);
package->provider->fnTableW.FreeContextBuffer(oldCred);
}
break;
}
/* no thunking needed: */
case SECPKG_ATTR_ACCESS_TOKEN:
case SECPKG_ATTR_DCE_INFO:
case SECPKG_ATTR_FLAGS:
case SECPKG_ATTR_LIFESPAN:
case SECPKG_ATTR_PASSWORD_EXPIRY:
case SECPKG_ATTR_SESSION_KEY:
case SECPKG_ATTR_SIZES:
case SECPKG_ATTR_STREAM_SIZES:
case SECPKG_ATTR_TARGET_INFORMATION:
break;
default:
WARN("attribute type %d unknown\n", ulAttribute);
ret = SEC_E_INTERNAL_ERROR;
}
}
else
ret = SEC_E_INVALID_TOKEN;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW(PCtxtHandle phContext,
ULONG ulAttribute, void *pBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
if (phContext)
{
SecurePackage *package = (SecurePackage *)phContext->dwUpper;
PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
if (package && package->provider)
{
if (package->provider->fnTableA.QueryContextAttributesA)
{
ret = package->provider->fnTableA.QueryContextAttributesA(
ctxt, ulAttribute, pBuffer);
if (ret == SEC_E_OK)
ret = thunk_ContextAttributesAToW(package, ulAttribute,
pBuffer);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext,
ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
if (phContext)
{
SecurePackage *package = (SecurePackage *)phContext->dwUpper;
PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
if (package && package->provider && pBuffer && cbBuffer)
{
if (package->provider->fnTableW.SetContextAttributesW)
{
/* TODO: gotta validate size too! */
ret = thunk_ContextAttributesWToA(package, ulAttribute,
pBuffer);
if (ret == SEC_E_OK)
ret = package->provider->fnTableW.SetContextAttributesW(
ctxt, ulAttribute, pBuffer, cbBuffer);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext,
ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
{
SECURITY_STATUS ret;
TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
if (phContext)
{
SecurePackage *package = (SecurePackage *)phContext->dwUpper;
PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
if (package && package->provider && pBuffer && cbBuffer)
{
if (package->provider->fnTableA.SetContextAttributesA)
{
/* TODO: gotta validate size too! */
ret = thunk_ContextAttributesAToW(package, ulAttribute,
pBuffer);
if (ret == SEC_E_OK)
ret = package->provider->fnTableA.SetContextAttributesA(
ctxt, ulAttribute, pBuffer, cbBuffer);
}
else
ret = SEC_E_UNSUPPORTED_FUNCTION;
}
else
ret = SEC_E_INVALID_HANDLE;
}
else
ret = SEC_E_INVALID_HANDLE;
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA(
SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
PCtxtHandle phContext)
{
SECURITY_STATUS ret;
UNICODE_STRING package;
TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
phContext);
RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
ret = ImportSecurityContextW(package.Buffer, pPackedContext, Token,
phContext);
RtlFreeUnicodeString(&package);
return ret;
}
SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW(
SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
PCtxtHandle phContext)
{
SECURITY_STATUS ret;
PSTR package = SECUR32_AllocMultiByteFromWide(pszPackage);
TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
phContext);
ret = ImportSecurityContextA(package, pPackedContext, Token, phContext);
HeapFree(GetProcessHeap(), 0, package);
return ret;
}