wldap32: Add support for ldap_bind_s(LDAP_AUTH_NEGOTIATE).
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3d37d45ed0
commit
364ac6787a
|
@ -7427,6 +7427,7 @@ for ac_header in \
|
|||
port.h \
|
||||
pthread.h \
|
||||
pwd.h \
|
||||
sasl/sasl.h \
|
||||
sched.h \
|
||||
scsi/scsi.h \
|
||||
scsi/scsi_ioctl.h \
|
||||
|
|
|
@ -487,6 +487,7 @@ AC_CHECK_HEADERS(\
|
|||
port.h \
|
||||
pthread.h \
|
||||
pwd.h \
|
||||
sasl/sasl.h \
|
||||
sched.h \
|
||||
scsi/scsi.h \
|
||||
scsi/scsi_ioctl.h \
|
||||
|
|
|
@ -25,10 +25,14 @@
|
|||
#ifdef HAVE_LDAP_H
|
||||
#include <ldap.h>
|
||||
#endif
|
||||
#ifdef HAVE_SASL_SASL_H
|
||||
#include <sasl/sasl.h>
|
||||
#endif
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "rpc.h"
|
||||
|
||||
#include "winldap_private.h"
|
||||
#include "wldap32.h"
|
||||
|
@ -156,20 +160,67 @@ ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
|
|||
if (!dnW) goto exit;
|
||||
}
|
||||
if (cred) {
|
||||
credW = strAtoW( cred );
|
||||
if (!credW) goto exit;
|
||||
if (method == LDAP_AUTH_SIMPLE)
|
||||
{
|
||||
credW = strAtoW( cred );
|
||||
if (!credW) goto exit;
|
||||
}
|
||||
else
|
||||
credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
|
||||
}
|
||||
|
||||
ret = ldap_bind_sW( ld, dnW, credW, method );
|
||||
|
||||
exit:
|
||||
strfreeW( dnW );
|
||||
strfreeW( credW );
|
||||
if (credW != (WCHAR *)cred) strfreeW( credW );
|
||||
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LDAP_H
|
||||
|
||||
static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
|
||||
{
|
||||
#ifdef HAVE_SASL_SASL_H
|
||||
SEC_WINNT_AUTH_IDENTITY_A *id = defaults;
|
||||
sasl_interact_t *sasl = interact;
|
||||
|
||||
TRACE( "%p,%08x,%p,%p\n", ld, flags, defaults, interact );
|
||||
|
||||
while (sasl->id != SASL_CB_LIST_END)
|
||||
{
|
||||
TRACE("sasl->id = %04lx\n", sasl->id);
|
||||
|
||||
if (sasl->id == SASL_CB_GETREALM)
|
||||
{
|
||||
sasl->result = id->Domain;
|
||||
sasl->len = id->DomainLength;
|
||||
}
|
||||
else if (sasl->id == SASL_CB_USER)
|
||||
{
|
||||
sasl->result = id->User;
|
||||
sasl->len = id->UserLength;
|
||||
}
|
||||
else if (sasl->id == SASL_CB_PASS)
|
||||
{
|
||||
sasl->result = id->Password;
|
||||
sasl->len = id->PasswordLength;
|
||||
}
|
||||
|
||||
sasl++;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
#else
|
||||
FIXME( "%p,%08x,%p,%p: stub\n", ld, flags, defaults, interact );
|
||||
return LDAP_SUCCESS;
|
||||
#endif /* HAVE_SASL_SASL_H */
|
||||
}
|
||||
|
||||
#endif /* HAVE_LDAP_H */
|
||||
|
||||
/***********************************************************************
|
||||
* ldap_bind_sW (WLDAP32.@)
|
||||
*
|
||||
|
@ -197,21 +248,71 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
|
|||
TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
|
||||
|
||||
if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
|
||||
if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
|
||||
|
||||
if (dn) {
|
||||
dnU = strWtoU( dn );
|
||||
if (!dnU) goto exit;
|
||||
if (method == LDAP_AUTH_SIMPLE)
|
||||
{
|
||||
if (dn)
|
||||
{
|
||||
dnU = strWtoU( dn );
|
||||
if (!dnU) goto exit;
|
||||
}
|
||||
if (cred)
|
||||
{
|
||||
credU = strWtoU( cred );
|
||||
if (!credU) goto exit;
|
||||
|
||||
pwd.bv_len = strlen( credU );
|
||||
pwd.bv_val = credU;
|
||||
}
|
||||
|
||||
ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
|
||||
}
|
||||
if (cred) {
|
||||
credU = strWtoU( cred );
|
||||
if (!credU) goto exit;
|
||||
else if (method == WLDAP32_LDAP_AUTH_NEGOTIATE)
|
||||
{
|
||||
SEC_WINNT_AUTH_IDENTITY_A idU;
|
||||
SEC_WINNT_AUTH_IDENTITY_W idW;
|
||||
SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
|
||||
|
||||
pwd.bv_len = strlen( credU );
|
||||
pwd.bv_val = credU;
|
||||
memset( &idU, 0, sizeof(idU) );
|
||||
|
||||
if (id)
|
||||
{
|
||||
if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
{
|
||||
idW.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
idW.Domain = (unsigned short *)strnAtoW( (char *)id->Domain, id->DomainLength, &idW.DomainLength );
|
||||
idW.User = (unsigned short *)strnAtoW( (char *)id->User, id->UserLength, &idW.UserLength );
|
||||
idW.Password = (unsigned short *)strnAtoW( (char *)id->Password, id->PasswordLength, &idW.PasswordLength );
|
||||
|
||||
id = &idW;
|
||||
}
|
||||
|
||||
idU.Domain = (unsigned char *)strnWtoU( id->Domain, id->DomainLength, &idU.DomainLength );
|
||||
idU.User = (unsigned char *)strnWtoU( id->User, id->UserLength, &idU.UserLength );
|
||||
idU.Password = (unsigned char *)strnWtoU( id->Password, id->PasswordLength, &idU.PasswordLength );
|
||||
}
|
||||
|
||||
ret = map_error( ldap_sasl_interactive_bind_s( ld,
|
||||
NULL /* server will ignore DN anyway */,
|
||||
NULL /* query supportedSASLMechanisms */,
|
||||
NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &idU ));
|
||||
|
||||
if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
|
||||
{
|
||||
strfreeW( (WCHAR *)idW.Domain );
|
||||
strfreeW( (WCHAR *)idW.User );
|
||||
strfreeW( (WCHAR *)idW.Password );
|
||||
}
|
||||
|
||||
strfreeU( (char *)idU.Domain );
|
||||
strfreeU( (char *)idU.User );
|
||||
strfreeU( (char *)idU.Password );
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME( "method %#x not supported\n", method );
|
||||
return WLDAP32_LDAP_PARAM_ERROR;
|
||||
}
|
||||
|
||||
ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
|
||||
|
||||
exit:
|
||||
strfreeU( dnU );
|
||||
|
|
|
@ -101,6 +101,8 @@ typedef struct berelement
|
|||
#define WLDAP32_LDAP_OPT_SECURITY_CONTEXT 0x99
|
||||
#define WLDAP32_LDAP_OPT_ROOTDSE_CACHE 0x9a
|
||||
|
||||
#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
|
||||
|
||||
typedef struct ldap
|
||||
{
|
||||
struct
|
||||
|
|
|
@ -93,6 +93,38 @@ static inline LPWSTR strUtoW( char *str )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline LPWSTR strnAtoW( LPCSTR str, DWORD inlen, DWORD *outlen )
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
*outlen = 0;
|
||||
if (str)
|
||||
{
|
||||
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, inlen, NULL, 0 );
|
||||
if ((ret = heap_alloc( len * sizeof(WCHAR) )))
|
||||
{
|
||||
MultiByteToWideChar( CP_ACP, 0, str, inlen, ret, len );
|
||||
*outlen = len;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *strnWtoU( LPCWSTR str, DWORD inlen, DWORD *outlen )
|
||||
{
|
||||
LPSTR ret = NULL;
|
||||
*outlen = 0;
|
||||
if (str)
|
||||
{
|
||||
DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, inlen, NULL, 0, NULL, NULL );
|
||||
if ((ret = heap_alloc( len )))
|
||||
{
|
||||
WideCharToMultiByte( CP_UTF8, 0, str, inlen, ret, len, NULL, NULL );
|
||||
*outlen = len;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void strfreeA( LPSTR str )
|
||||
{
|
||||
heap_free( str );
|
||||
|
|
|
@ -779,6 +779,9 @@
|
|||
/* Define to 1 if you have the `roundf' function. */
|
||||
#undef HAVE_ROUNDF
|
||||
|
||||
/* Define to 1 if you have the <sasl/sasl.h> header file. */
|
||||
#undef HAVE_SASL_SASL_H
|
||||
|
||||
/* Define to 1 if you have the <sched.h> header file. */
|
||||
#undef HAVE_SCHED_H
|
||||
|
||||
|
|
Loading…
Reference in New Issue