2016-07-13 10:28:30 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2016 Hans Leidekker for CodeWeavers
|
|
|
|
*
|
|
|
|
* 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 "rpc.h"
|
|
|
|
#include "sspi.h"
|
2017-01-27 10:28:41 +01:00
|
|
|
#include "wincred.h"
|
2016-07-13 10:28:30 +02:00
|
|
|
|
|
|
|
#include "wine/debug.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(sspicli);
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiEncodeStringsAsAuthIdentity (SECUR32.0)
|
|
|
|
*/
|
|
|
|
SECURITY_STATUS SEC_ENTRY SspiEncodeStringsAsAuthIdentity(
|
|
|
|
const WCHAR *username, const WCHAR *domainname, const WCHAR *creds,
|
|
|
|
PSEC_WINNT_AUTH_IDENTITY_OPAQUE *opaque_id )
|
|
|
|
{
|
|
|
|
SEC_WINNT_AUTH_IDENTITY_W *id;
|
|
|
|
DWORD len_username = 0, len_domainname = 0, len_password = 0, size;
|
|
|
|
WCHAR *ptr;
|
|
|
|
|
|
|
|
FIXME( "%s %s %s %p\n", debugstr_w(username), debugstr_w(domainname),
|
|
|
|
debugstr_w(creds), opaque_id );
|
|
|
|
|
|
|
|
if (!username && !domainname && !creds) return SEC_E_INVALID_TOKEN;
|
|
|
|
|
2019-06-21 08:48:56 +02:00
|
|
|
if (username) len_username = lstrlenW( username );
|
|
|
|
if (domainname) len_domainname = lstrlenW( domainname );
|
|
|
|
if (creds) len_password = lstrlenW( creds );
|
2016-07-13 10:28:30 +02:00
|
|
|
|
|
|
|
size = sizeof(*id);
|
|
|
|
if (username) size += (len_username + 1) * sizeof(WCHAR);
|
|
|
|
if (domainname) size += (len_domainname + 1) * sizeof(WCHAR);
|
|
|
|
if (creds) size += (len_password + 1) * sizeof(WCHAR);
|
|
|
|
if (!(id = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) return ERROR_OUTOFMEMORY;
|
|
|
|
ptr = (WCHAR *)(id + 1);
|
|
|
|
|
|
|
|
if (username)
|
|
|
|
{
|
|
|
|
memcpy( ptr, username, (len_username + 1) * sizeof(WCHAR) );
|
|
|
|
id->User = ptr;
|
|
|
|
id->UserLength = len_username;
|
|
|
|
ptr += len_username + 1;
|
|
|
|
}
|
|
|
|
if (domainname)
|
|
|
|
{
|
|
|
|
memcpy( ptr, domainname, (len_domainname + 1) * sizeof(WCHAR) );
|
|
|
|
id->Domain = ptr;
|
|
|
|
id->DomainLength = len_domainname;
|
|
|
|
ptr += len_domainname + 1;
|
|
|
|
}
|
|
|
|
if (creds)
|
|
|
|
{
|
|
|
|
memcpy( ptr, creds, (len_password + 1) * sizeof(WCHAR) );
|
|
|
|
id->Password = ptr;
|
|
|
|
id->PasswordLength = len_password;
|
|
|
|
}
|
|
|
|
|
|
|
|
*opaque_id = id;
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
2016-07-13 10:28:31 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiZeroAuthIdentity (SECUR32.0)
|
|
|
|
*/
|
|
|
|
void SEC_ENTRY SspiZeroAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id )
|
|
|
|
{
|
|
|
|
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id;
|
|
|
|
|
|
|
|
TRACE( "%p\n", opaque_id );
|
|
|
|
|
|
|
|
if (!id) return;
|
|
|
|
if (id->User) memset( id->User, 0, id->UserLength * sizeof(WCHAR) );
|
|
|
|
if (id->Domain) memset( id->Domain, 0, id->DomainLength * sizeof(WCHAR) );
|
|
|
|
if (id->Password) memset( id->Password, 0, id->PasswordLength * sizeof(WCHAR) );
|
|
|
|
memset( id, 0, sizeof(*id) );
|
|
|
|
}
|
2016-07-13 10:28:32 +02:00
|
|
|
|
|
|
|
static inline WCHAR *strdupW( const WCHAR *src )
|
|
|
|
{
|
|
|
|
WCHAR *dst;
|
|
|
|
if (!src) return NULL;
|
2019-06-21 08:48:56 +02:00
|
|
|
if ((dst = HeapAlloc( GetProcessHeap(), 0, (lstrlenW( src ) + 1) * sizeof(WCHAR) )))
|
|
|
|
lstrcpyW( dst, src );
|
2016-07-13 10:28:32 +02:00
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiEncodeAuthIdentityAsStrings (SECUR32.0)
|
|
|
|
*/
|
|
|
|
SECURITY_STATUS SEC_ENTRY SspiEncodeAuthIdentityAsStrings(
|
|
|
|
PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id, PCWSTR *username,
|
|
|
|
PCWSTR *domainname, PCWSTR *creds )
|
|
|
|
{
|
|
|
|
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id;
|
|
|
|
|
|
|
|
FIXME("%p %p %p %p\n", opaque_id, username, domainname, creds);
|
|
|
|
|
|
|
|
*username = strdupW( id->User );
|
|
|
|
*domainname = strdupW( id->Domain );
|
|
|
|
*creds = strdupW( id->Password );
|
|
|
|
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
2016-07-13 10:28:33 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiFreeAuthIdentity (SECUR32.0)
|
|
|
|
*/
|
|
|
|
void SEC_ENTRY SspiFreeAuthIdentity( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id )
|
|
|
|
{
|
|
|
|
TRACE( "%p\n", opaque_id );
|
|
|
|
HeapFree( GetProcessHeap(), 0, opaque_id );
|
|
|
|
}
|
2016-07-13 10:28:34 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiLocalFree (SECUR32.0)
|
|
|
|
*/
|
|
|
|
void SEC_ENTRY SspiLocalFree( void *ptr )
|
|
|
|
{
|
|
|
|
TRACE( "%p\n", ptr );
|
|
|
|
HeapFree( GetProcessHeap(), 0, ptr );
|
|
|
|
}
|
2017-01-27 10:28:41 +01:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* SspiPrepareForCredWrite (SECUR32.0)
|
|
|
|
*/
|
|
|
|
SECURITY_STATUS SEC_ENTRY SspiPrepareForCredWrite( PSEC_WINNT_AUTH_IDENTITY_OPAQUE opaque_id,
|
|
|
|
PCWSTR target, PULONG type, PCWSTR *targetname, PCWSTR *username, PUCHAR *blob, PULONG size )
|
|
|
|
{
|
|
|
|
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)opaque_id;
|
|
|
|
WCHAR *str, *str2;
|
|
|
|
UCHAR *password;
|
|
|
|
ULONG len;
|
|
|
|
|
|
|
|
FIXME( "%p %s %p %p %p %p %p\n", opaque_id, debugstr_w(target), type, targetname, username,
|
|
|
|
blob, size );
|
|
|
|
|
|
|
|
if (id->DomainLength)
|
|
|
|
{
|
|
|
|
len = (id->DomainLength + id->UserLength + 2) * sizeof(WCHAR);
|
|
|
|
if (!(str = HeapAlloc(GetProcessHeap(), 0 , len ))) return SEC_E_INSUFFICIENT_MEMORY;
|
|
|
|
memcpy( str, id->Domain, id->DomainLength * sizeof(WCHAR) );
|
|
|
|
str[id->DomainLength] = '\\';
|
|
|
|
memcpy( str + id->DomainLength + 1, id->User, id->UserLength * sizeof(WCHAR) );
|
|
|
|
str[id->DomainLength + 1 + id->UserLength] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = (id->UserLength + 1) * sizeof(WCHAR);
|
|
|
|
if (!(str = HeapAlloc(GetProcessHeap(), 0 , len ))) return SEC_E_INSUFFICIENT_MEMORY;
|
|
|
|
memcpy( str, id->User, id->UserLength * sizeof(WCHAR) );
|
|
|
|
str[id->UserLength] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
str2 = target ? strdupW( target ) : strdupW( str );
|
|
|
|
if (!str2)
|
|
|
|
{
|
|
|
|
HeapFree( GetProcessHeap(), 0, str );
|
|
|
|
return SEC_E_INSUFFICIENT_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = id->PasswordLength * sizeof(WCHAR);
|
|
|
|
if (!(password = HeapAlloc(GetProcessHeap(), 0 , len )))
|
|
|
|
{
|
|
|
|
HeapFree( GetProcessHeap(), 0, str );
|
|
|
|
HeapFree( GetProcessHeap(), 0, str2 );
|
|
|
|
return SEC_E_INSUFFICIENT_MEMORY;
|
|
|
|
}
|
|
|
|
memcpy( password, id->Password, len );
|
|
|
|
|
|
|
|
*type = CRED_TYPE_DOMAIN_PASSWORD;
|
|
|
|
*username = str;
|
|
|
|
*targetname = str2;
|
|
|
|
*blob = password;
|
|
|
|
*size = len;
|
|
|
|
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|