mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-06 15:00:40 +08:00
Merged in preliminary support for Cyrus SASL library;
support for DCE slash-delimited, left-to-right DNs; support for a domain socket transport (enable with --enable-ldapi); and extensions to URL parsing to support the latter transport.
This commit is contained in:
parent
6fb04da524
commit
9b4e3b2234
36
configure
vendored
36
configure
vendored
@ -40,6 +40,8 @@ ac_help="$ac_help
|
||||
--enable-referrals enable V2 Referrals extension (yes)"
|
||||
ac_help="$ac_help
|
||||
--enable-cldap enable connectionless ldap (no)"
|
||||
ac_help="$ac_help
|
||||
--enable-ldapi enable domain socket (PF_LOCAL) transport (no)"
|
||||
ac_help="$ac_help
|
||||
--enable-x-compile enable cross compiling (no)"
|
||||
ac_help="$ac_help
|
||||
@ -1305,6 +1307,26 @@ else
|
||||
ol_enable_cldap="no"
|
||||
fi
|
||||
# end --enable-cldap
|
||||
# OpenLDAP --enable-ldapi
|
||||
# Check whether --enable-ldapi or --disable-ldapi was given.
|
||||
if test "${enable_ldapi+set}" = set; then
|
||||
enableval="$enable_ldapi"
|
||||
|
||||
ol_arg=invalid
|
||||
for ol_val in auto yes no ; do
|
||||
if test "$enableval" = "$ol_val" ; then
|
||||
ol_arg="$ol_val"
|
||||
fi
|
||||
done
|
||||
if test "$ol_arg" = "invalid" ; then
|
||||
{ echo "configure: error: bad value $enableval for --enable-ldapi" 1>&2; exit 1; }
|
||||
fi
|
||||
ol_enable_ldapi="$ol_arg"
|
||||
|
||||
else
|
||||
ol_enable_ldapi="no"
|
||||
fi
|
||||
# end --enable-ldapi
|
||||
# OpenLDAP --enable-x_compile
|
||||
# Check whether --enable-x_compile or --disable-x_compile was given.
|
||||
if test "${enable_x_compile+set}" = set; then
|
||||
@ -1347,8 +1369,8 @@ else
|
||||
fi
|
||||
# end --enable-dmalloc
|
||||
|
||||
# OpenLDAP --with-cyrus_sasl
|
||||
# Check whether --with-cyrus_sasl or --without-cyrus_sasl was given.
|
||||
# OpenLDAP --with-cyrus-sasl
|
||||
# Check whether --with-cyrus-sasl or --without-cyrus_sasl was given.
|
||||
if test "${with_cyrus_sasl+set}" = set; then
|
||||
withval="$with_cyrus_sasl"
|
||||
|
||||
@ -1359,14 +1381,14 @@ if test "${with_cyrus_sasl+set}" = set; then
|
||||
fi
|
||||
done
|
||||
if test "$ol_arg" = "invalid" ; then
|
||||
{ echo "configure: error: bad value $withval for --with-cyrus_sasl" 1>&2; exit 1; }
|
||||
{ echo "configure: error: bad value $withval for --with-cyrus-sasl" 1>&2; exit 1; }
|
||||
fi
|
||||
ol_with_cyrus_sasl="$ol_arg"
|
||||
|
||||
else
|
||||
ol_with_cyrus_sasl="auto"
|
||||
fi
|
||||
# end --with-cyrus_sasl
|
||||
# end --with-cyrus-sasl
|
||||
|
||||
# OpenLDAP --with-fetch
|
||||
# Check whether --with-fetch or --without-fetch was given.
|
||||
@ -4601,6 +4623,7 @@ for ac_hdr in \
|
||||
sys/resource.h \
|
||||
sys/select.h \
|
||||
sys/socket.h \
|
||||
sys/un.h \
|
||||
sys/syslog.h \
|
||||
sys/time.h \
|
||||
sys/types.h \
|
||||
@ -14909,7 +14932,12 @@ if test "$ol_enable_cldap" != no ; then
|
||||
EOF
|
||||
|
||||
fi
|
||||
if test "$ol_enable_ldapi" != no ; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define LDAP_PF_LOCAL 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
if test "$ol_enable_crypt" != no ; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define SLAPD_CRYPT 1
|
||||
|
@ -97,6 +97,7 @@ OL_ARG_ENABLE(cache,[ --enable-cache enable caching], yes)dnl
|
||||
OL_ARG_ENABLE(dns,[ --enable-dns enable V2 DX Referrals extension], no)dnl
|
||||
OL_ARG_ENABLE(referrals,[ --enable-referrals enable V2 Referrals extension], yes)dnl
|
||||
OL_ARG_ENABLE(cldap,[ --enable-cldap enable connectionless ldap], no)dnl
|
||||
OL_ARG_ENABLE(ldapi,[ --enable-ldapi enable domain socket (PF_LOCAL) ldap], no)dnl
|
||||
OL_ARG_ENABLE(x_compile,[ --enable-x-compile enable cross compiling],
|
||||
no, [yes no])dnl
|
||||
|
||||
@ -2079,6 +2080,9 @@ fi
|
||||
if test "$ol_enable_cldap" != no ; then
|
||||
AC_DEFINE(LDAP_CONNECTIONLESS,1,[define to support CLDAP])
|
||||
fi
|
||||
if test "$ol_enable_ldapi" != no; then
|
||||
AC_DEFINE(USE_PF_LOCAL,1,[define to support PF_LOCAL transport])
|
||||
fi
|
||||
|
||||
if test "$ol_enable_crypt" != no ; then
|
||||
AC_DEFINE(SLAPD_CRYPT,1,[define to support crypt(3) passwords])
|
||||
|
@ -20,6 +20,10 @@
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
@ -487,17 +487,27 @@ typedef struct ldap_friendly {
|
||||
* types for ldap URL handling
|
||||
*/
|
||||
typedef struct ldap_url_desc {
|
||||
struct ldap_url_desc *lud_next;
|
||||
int lud_ldaps;
|
||||
struct ldap_url_desc *lud_next;
|
||||
unsigned long lud_properties;
|
||||
int lud_protocol;
|
||||
char *lud_host;
|
||||
int lud_port;
|
||||
char *lud_dn;
|
||||
char **lud_attrs;
|
||||
int lud_scope;
|
||||
char *lud_filter;
|
||||
char **lud_exts;
|
||||
char **lud_exts;
|
||||
} LDAPURLDesc;
|
||||
|
||||
/* lud_properties */
|
||||
#define LDAP_URL_USE_SSL 0x00000001
|
||||
#define LDAP_URL_USE_SSL_UNSPECIFIED 0x00000002
|
||||
|
||||
/* lud_protocol */
|
||||
#define LDAP_PROTO_TCP 0x00
|
||||
#define LDAP_PROTO_UDP 0x01
|
||||
#define LDAP_PROTO_LOCAL 0x02
|
||||
|
||||
#define LDAP_URL_SUCCESS 0x00 /* Success */
|
||||
#define LDAP_URL_ERR_MEM 0x01 /* can't allocate memory space */
|
||||
#define LDAP_URL_ERR_PARAM 0x02 /* parameter is bad */
|
||||
@ -637,6 +647,17 @@ ldap_sasl_bind LDAP_P((
|
||||
LDAPControl **clientctrls,
|
||||
int *msgidp ));
|
||||
|
||||
LIBLDAP_F( int )
|
||||
ldap_negotiated_sasl_bind_s LDAP_P((
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *dn, /* usually NULL */
|
||||
LDAP_CONST char *authorizationId,
|
||||
LDAP_CONST char *authenticationId, /* usually NULL */
|
||||
LDAP_CONST char *saslMechanism,
|
||||
struct berval *passPhrase,
|
||||
LDAPControl **serverControls,
|
||||
LDAPControl **clientControls ));
|
||||
|
||||
LIBLDAP_F( int )
|
||||
ldap_sasl_bind_s LDAP_P((
|
||||
LDAP *ld,
|
||||
@ -1126,6 +1147,11 @@ LIBLDAP_F( int )
|
||||
ldap_is_dns_dn LDAP_P(( /* deprecated */
|
||||
LDAP_CONST char *dn ));
|
||||
|
||||
LIBLDAP_F( char * )
|
||||
ldap_dn2dcedn LDAP_P(( LDAP_CONST char *dn ));
|
||||
|
||||
LIBLDAP_F( char * )
|
||||
ldap_dcedn2dn LDAP_P(( LDAP_CONST char *dce ));
|
||||
|
||||
/*
|
||||
* in getattr.c
|
||||
|
@ -100,6 +100,13 @@ LIBLDAP_F (int) ldap_pvt_unhex( int c );
|
||||
|
||||
#define LDAP_NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
/* sasl.c */
|
||||
LIBLDAP_F (int) ldap_pvt_sasl_init LDAP_P(( void )); /* clientside init */
|
||||
LIBLDAP_F (int) ldap_pvt_sasl_install LDAP_P(( Sockbuf *, void * ));
|
||||
LIBLDAP_F (int) ldap_pvt_sasl_err2ldap LDAP_P(( int ));
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
/* search.c */
|
||||
LIBLDAP_F( char * )
|
||||
ldap_pvt_find_wildcard LDAP_P(( char *s ));
|
||||
|
@ -531,6 +531,9 @@
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <sys/un.h> header file. */
|
||||
#undef HAVE_SYS_UN_H
|
||||
|
||||
/* Define if you have the <sysexits.h> header file. */
|
||||
#undef HAVE_SYSEXITS_H
|
||||
|
||||
@ -834,6 +837,9 @@
|
||||
/* define to support CLDAP */
|
||||
#undef LDAP_CONNECTIONLESS
|
||||
|
||||
/* define to support domain sockets */
|
||||
#undef LDAP_PF_LOCAL
|
||||
|
||||
/* define to support crypt(3) passwords */
|
||||
#undef SLAPD_CRYPT
|
||||
|
||||
|
@ -17,7 +17,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||
request.c getdxbyname.c os-ip.c url.c charset.c \
|
||||
init.c options.c print.c string.c util-int.c schema.c \
|
||||
charray.c digest.c tls.c dn.c
|
||||
charray.c digest.c tls.c dn.c os-local.c
|
||||
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
controls.lo messages.lo references.lo extended.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
|
||||
@ -26,7 +26,7 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
||||
request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
|
||||
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
|
||||
charray.lo digest.lo tls.lo dn.lo
|
||||
charray.lo digest.lo tls.lo dn.lo os-local.lo
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
#define DN_TYPE_LDAP_RDN 0
|
||||
#define DN_TYPE_LDAP_DN 1
|
||||
#define DN_TYPE_DCE_DN 2
|
||||
|
||||
static char **explode_name( const char *name, int notypes, int is_dn );
|
||||
|
||||
char *
|
||||
@ -180,14 +184,98 @@ ldap_explode_dn( LDAP_CONST char *dn, int notypes )
|
||||
if ( ldap_is_dns_dn( dn ) ) {
|
||||
return( ldap_explode_dns( dn ) );
|
||||
}
|
||||
return explode_name( dn, notypes, 1 );
|
||||
return explode_name( dn, notypes, DN_TYPE_LDAP_DN );
|
||||
}
|
||||
|
||||
char **
|
||||
ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
|
||||
return explode_name( rdn, notypes, 0 );
|
||||
return explode_name( rdn, notypes, DN_TYPE_LDAP_RDN );
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_dn2dcedn( LDAP_CONST char *dn )
|
||||
{
|
||||
char *dce, *q, **rdns, **p;
|
||||
int len = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
|
||||
|
||||
rdns = explode_name( dn, 0, DN_TYPE_LDAP_DN );
|
||||
if ( rdns == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for ( p = rdns; *p != NULL; p++ ) {
|
||||
len += strlen( *p ) + 1;
|
||||
}
|
||||
|
||||
q = dce = LDAP_MALLOC( len + 1 );
|
||||
if ( dce == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p--; /* get back past NULL */
|
||||
|
||||
for ( ; p != rdns; p-- ) {
|
||||
strcpy( q, "/" );
|
||||
q++;
|
||||
strcpy( q, *p );
|
||||
q += strlen( *p );
|
||||
}
|
||||
|
||||
strcpy( q, "/" );
|
||||
q++;
|
||||
strcpy( q, *p );
|
||||
|
||||
return dce;
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_dcedn2dn( LDAP_CONST char *dce )
|
||||
{
|
||||
char *dn, *q, **rdns, **p;
|
||||
int len;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
|
||||
|
||||
rdns = explode_name( dce, 0, DN_TYPE_DCE_DN );
|
||||
if ( rdns == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
|
||||
for ( p = rdns; *p != NULL; p++ ) {
|
||||
len += strlen( *p ) + 1;
|
||||
}
|
||||
|
||||
q = dn = LDAP_MALLOC( len );
|
||||
if ( dn == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p--;
|
||||
|
||||
for ( ; p != rdns; p-- ) {
|
||||
strcpy( q, *p );
|
||||
q += strlen( *p );
|
||||
strcpy( q, "," );
|
||||
q++;
|
||||
}
|
||||
|
||||
if ( *dce == '/' ) {
|
||||
/* the name was fully qualified, thus the most-significant
|
||||
* RDN was empty. trash the last comma */
|
||||
q--;
|
||||
*q = '\0';
|
||||
} else {
|
||||
/* the name was relative. copy the most significant RDN */
|
||||
strcpy( q, *p );
|
||||
}
|
||||
|
||||
return dn;
|
||||
}
|
||||
|
||||
static char **
|
||||
@ -215,14 +303,18 @@ explode_name( const char *name, int notypes, int is_dn )
|
||||
state = INQUOTE;
|
||||
break;
|
||||
case '+':
|
||||
if (!is_dn)
|
||||
if (is_dn == DN_TYPE_LDAP_RDN)
|
||||
goto end_part;
|
||||
break;
|
||||
case '/':
|
||||
if (is_dn == DN_TYPE_DCE_DN)
|
||||
goto end_part;
|
||||
break;
|
||||
case ';':
|
||||
case ',':
|
||||
if (!is_dn)
|
||||
break;
|
||||
goto end_part;
|
||||
if (is_dn == DN_TYPE_LDAP_DN)
|
||||
goto end_part;
|
||||
break;
|
||||
case '\0':
|
||||
end_part:
|
||||
if ( state == OUTQUOTE ) {
|
||||
|
@ -343,6 +343,10 @@ void ldap_int_initialize( void )
|
||||
ldap_pvt_tls_init();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
ldap_pvt_sasl_init();
|
||||
#endif
|
||||
|
||||
if ( ldap_int_tblsize == 0 )
|
||||
ldap_int_ip_init();
|
||||
|
||||
|
@ -30,12 +30,20 @@
|
||||
|
||||
#include "ldap_pvt.h"
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
#include <sasl.h>
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
LDAP_BEGIN_DECL
|
||||
|
||||
#define LDAP_URL_PREFIX "ldap://"
|
||||
#define LDAP_URL_PREFIX_LEN (sizeof(LDAP_URL_PREFIX)-1)
|
||||
#define LDAPS_URL_PREFIX "ldaps://"
|
||||
#define LDAPS_URL_PREFIX_LEN (sizeof(LDAPS_URL_PREFIX)-1)
|
||||
#define LDAPI_URL_PREFIX "ldapi://"
|
||||
#define LDAPI_URL_PREFIX_LEN (sizeof(LDAPI_URL_PREFIX)-1)
|
||||
#define LDAPIS_URL_PREFIX "ldapis://"
|
||||
#define LDAPIS_URL_PREFIX_LEN (sizeof(LDAPIS_URL_PREFIX)-1)
|
||||
#define LDAP_URL_URLCOLON "URL:"
|
||||
#define LDAP_URL_URLCOLON_LEN (sizeof(LDAP_URL_URLCOLON)-1)
|
||||
#define NULLLDAPURLDESC ((LDAPURLDesc *)NULL)
|
||||
@ -132,6 +140,7 @@ typedef struct ldap_server {
|
||||
char *lsrv_host;
|
||||
char *lsrv_dn; /* if NULL, use default */
|
||||
int lsrv_port;
|
||||
/* int lsrv_protocol; */
|
||||
struct ldap_server *lsrv_next;
|
||||
} LDAPServer;
|
||||
|
||||
@ -266,6 +275,9 @@ struct ldap {
|
||||
int (*ld_rebindproc)( struct ldap *ld, char **dnp,
|
||||
char **passwdp, int *authmethodp, int freeit );
|
||||
/* routine to get info needed for re-bind */
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
sasl_conn_t *ld_sasl_context;
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
};
|
||||
#define LDAP_VALID(ld) ( (ld)->ld_valid == LDAP_VALID_SESSION )
|
||||
|
||||
@ -355,7 +367,6 @@ LIBLDAP_F (char *) ldap_get_kerberosv4_credentials LDAP_P((
|
||||
LIBLDAP_F (int) ldap_open_defconn( LDAP *ld );
|
||||
LIBLDAP_F (int) open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srvlist, char **krbinstancep, int async );
|
||||
|
||||
|
||||
/*
|
||||
* in os-ip.c
|
||||
*/
|
||||
@ -365,7 +376,7 @@ LIBLDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host, u
|
||||
|
||||
LIBLDAP_F (void) ldap_close_connection( Sockbuf *sb );
|
||||
|
||||
#ifdef HAVE_KERBEROS
|
||||
#if defined(HAVE_KERBEROS) || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
|
||||
LIBLDAP_F (char *) ldap_host_connected_to( Sockbuf *sb );
|
||||
#endif /* HAVE_KERBEROS */
|
||||
|
||||
@ -379,6 +390,12 @@ LIBLDAP_F (void) ldap_mark_select_clear( LDAP *ld, Sockbuf *sb );
|
||||
LIBLDAP_F (int) ldap_is_read_ready( LDAP *ld, Sockbuf *sb );
|
||||
LIBLDAP_F (int) ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
/*
|
||||
* in os-local.c
|
||||
*/
|
||||
LIBLDAP_F (int) ldap_connect_to_path( LDAP *ld, Sockbuf *sb, const char *path, int async );
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
/*
|
||||
* in request.c
|
||||
@ -395,7 +412,6 @@ LIBLDAP_F (void) ldap_free_request( LDAP *ld, LDAPRequest *lr );
|
||||
LIBLDAP_F (void) ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind );
|
||||
LIBLDAP_F (void) ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
|
||||
LIBLDAP_F (void) ldap_dump_requests_and_responses( LDAP *ld );
|
||||
|
||||
LIBLDAP_F (int) ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp );
|
||||
LIBLDAP_F (int) ldap_append_referral( LDAP *ld, char **referralsp, char *s );
|
||||
|
||||
|
@ -287,7 +287,19 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
|
||||
if ( srv->lud_host == NULL || *srv->lud_host == 0 )
|
||||
addr = htonl( INADDR_LOOPBACK );
|
||||
|
||||
rc = ldap_connect_to_host( ld, sb, srv->lud_host, addr, port, async );
|
||||
switch ( srv->lud_protocol ) {
|
||||
case LDAP_PROTO_TCP:
|
||||
case LDAP_PROTO_UDP:
|
||||
rc = ldap_connect_to_host( ld, sb, srv->lud_host, addr, port, async );
|
||||
break;
|
||||
case LDAP_PROTO_LOCAL:
|
||||
rc = ldap_connect_to_path( ld, sb, srv->lud_host, async );
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc == -1 ) {
|
||||
return( rc );
|
||||
}
|
||||
@ -295,9 +307,10 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
|
||||
ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
tls = srv->lud_ldaps;
|
||||
if (tls == -1)
|
||||
tls = ld->ld_options.ldo_tls_mode;
|
||||
tls = (srv->lud_properties & LDAP_URL_USE_SSL);
|
||||
if (tls == 0)
|
||||
tls = (srv->lud_properties & LDAP_URL_USE_SSL_UNSPECIFIED);
|
||||
|
||||
if ( tls != 0 ) {
|
||||
rc = ldap_pvt_tls_start( sb, ld->ld_options.ldo_tls_ctx );
|
||||
if (rc != LDAP_SUCCESS)
|
||||
|
@ -333,7 +333,7 @@ ldap_close_connection( Sockbuf *sb )
|
||||
}
|
||||
|
||||
|
||||
#if defined( HAVE_KERBEROS ) || defined( HAVE_TLS )
|
||||
#if defined( HAVE_KERBEROS ) || defined( HAVE_TLS ) || defined( HAVE_CYRUS_SASL )
|
||||
char *
|
||||
ldap_host_connected_to( Sockbuf *sb )
|
||||
{
|
||||
|
219
libraries/libldap/os-local.c
Normal file
219
libraries/libldap/os-local.c
Normal file
@ -0,0 +1,219 @@
|
||||
/* $OpenLDAP$ */
|
||||
/*
|
||||
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
|
||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
||||
*/
|
||||
/* Portions
|
||||
* Copyright (c) 1995 Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1999 PADL Software Pty Ltd.
|
||||
* os-ip.c -- platform-specific domain socket code
|
||||
*/
|
||||
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/stdlib.h>
|
||||
|
||||
#include <ac/errno.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
#include <ac/unistd.h>
|
||||
|
||||
/* XXX non-portable */
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif /* HAVE_IO_H */
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
/* int ldap_int_tblsize = 0; */
|
||||
|
||||
#define oslocal_debug(ld,fmt,arg1,arg2,arg3) \
|
||||
do { \
|
||||
ldap_log_printf(ld, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
|
||||
} while(0)
|
||||
|
||||
static void
|
||||
ldap_pvt_set_errno(int err)
|
||||
{
|
||||
errno = err;
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_pvt_ndelay_on(LDAP *ld, int fd)
|
||||
{
|
||||
oslocal_debug(ld, "ldap_ndelay_on: %d\n",fd,0,0);
|
||||
return ber_pvt_socket_set_nonblock( fd, 1 );
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_pvt_ndelay_off(LDAP *ld, int fd)
|
||||
{
|
||||
oslocal_debug(ld, "ldap_ndelay_off: %d\n",fd,0,0);
|
||||
return ber_pvt_socket_set_nonblock( fd, 0 );
|
||||
}
|
||||
|
||||
static ber_socket_t
|
||||
ldap_pvt_socket(LDAP *ld)
|
||||
{
|
||||
ber_socket_t s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
oslocal_debug(ld, "ldap_new_socket: %d\n",s,0,0);
|
||||
return ( s );
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_pvt_close_socket(LDAP *ld, int s)
|
||||
{
|
||||
oslocal_debug(ld, "ldap_close_socket: %d\n",s,0,0);
|
||||
return tcp_close(s);
|
||||
}
|
||||
|
||||
#undef TRACE
|
||||
#define TRACE do { \
|
||||
oslocal_debug(ld, \
|
||||
"ldap_is_socket_ready: errror on socket %d: errno: %d (%s)\n", \
|
||||
s, \
|
||||
errno, \
|
||||
strerror(errno) ); \
|
||||
} while( 0 )
|
||||
|
||||
/*
|
||||
* check the socket for errors after select returned.
|
||||
*/
|
||||
static int
|
||||
ldap_pvt_is_socket_ready(LDAP *ld, int s)
|
||||
{
|
||||
oslocal_debug(ld, "ldap_is_sock_ready: %d\n",s,0,0);
|
||||
|
||||
#if defined( notyet ) /* && defined( SO_ERROR ) */
|
||||
{
|
||||
int so_errno;
|
||||
int dummy = sizeof(so_errno);
|
||||
if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &so_errno, &dummy ) == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
if ( so_errno ) {
|
||||
ldap_pvt_set_errno(so_errno);
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* error slippery */
|
||||
struct sockaddr_un sun;
|
||||
char ch;
|
||||
int dummy = sizeof(sun);
|
||||
if ( getpeername( s, (struct sockaddr *) &sun, &dummy ) == -1 ) {
|
||||
/* XXX: needs to be replace with ber_stream_read() */
|
||||
read(s, &ch, 1);
|
||||
TRACE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#undef TRACE
|
||||
|
||||
static int
|
||||
ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sun, int async)
|
||||
{
|
||||
struct timeval tv, *opt_tv=NULL;
|
||||
fd_set wfds, *z=NULL;
|
||||
|
||||
if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
|
||||
tv.tv_usec = opt_tv->tv_usec;
|
||||
tv.tv_sec = opt_tv->tv_sec;
|
||||
}
|
||||
|
||||
oslocal_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
|
||||
s, opt_tv ? tv.tv_sec : -1L, async);
|
||||
|
||||
if ( ldap_pvt_ndelay_on(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
|
||||
if ( connect(s, (struct sockaddr *) sun, sizeof(struct sockaddr_un)) == 0 )
|
||||
{
|
||||
if ( ldap_pvt_ndelay_off(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
return ( 0 );
|
||||
}
|
||||
|
||||
if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) {
|
||||
return ( -1 );
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
if ( async ) return ( -2 );
|
||||
#endif
|
||||
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(s, &wfds );
|
||||
|
||||
if ( select(ldap_int_tblsize, z, &wfds, z, opt_tv ? &tv : NULL) == -1)
|
||||
return ( -1 );
|
||||
|
||||
if ( FD_ISSET(s, &wfds) ) {
|
||||
if ( ldap_pvt_is_socket_ready(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
if ( ldap_pvt_ndelay_off(ld, s) == -1 )
|
||||
return ( -1 );
|
||||
return ( 0 );
|
||||
}
|
||||
oslocal_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
|
||||
ldap_pvt_set_errno( ETIMEDOUT );
|
||||
return ( -1 );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_connect_to_path(LDAP *ld, Sockbuf *sb, const char *path, int async)
|
||||
{
|
||||
struct sockaddr_un server;
|
||||
ber_socket_t s = AC_SOCKET_INVALID;
|
||||
int rc, i, len;
|
||||
char *ha_buf=NULL, *p, *q;
|
||||
|
||||
oslocal_debug(ld, "ldap_connect_to_path\n",0,0,0);
|
||||
|
||||
if ( (s = ldap_pvt_socket( ld )) == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( path == NULL || path[0] == '\0' ) {
|
||||
path = "/tmp/.ldap-sock";
|
||||
} else {
|
||||
if ( strlen(path) > (sizeof( server.sun_path ) - 1) ) {
|
||||
ldap_pvt_set_errno( ENAMETOOLONG );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
oslocal_debug(ld, "ldap_connect_to_path: Trying %s\n", path, 0, 0);
|
||||
|
||||
memset( &server, 0, sizeof(server) );
|
||||
server.sun_family = AF_UNIX;
|
||||
strcpy( server.sun_path, path );
|
||||
|
||||
rc = ldap_pvt_connect(ld, s, &server, async);
|
||||
|
||||
if (rc == 0) {
|
||||
ber_pvt_sb_set_desc( sb, s );
|
||||
} else {
|
||||
ldap_pvt_close_socket(ld, s);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int dummy;
|
||||
#endif /* LDAP_PF_LOCAL */
|
@ -96,7 +96,6 @@ ldap_send_initial_request(
|
||||
( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
|
||||
}
|
||||
|
||||
|
||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
|
||||
if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_DNS )
|
||||
&& ldap_is_dns_dn( dn ) )
|
||||
@ -254,7 +253,6 @@ ldap_send_server_request(
|
||||
return( msgid );
|
||||
}
|
||||
|
||||
|
||||
LDAPConn *
|
||||
ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
|
||||
int connect, int bind )
|
||||
|
@ -148,16 +148,6 @@ ldap_sasl_bind(
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* ldap_sasl_bind_s - bind to the ldap server (and X.500) using simple
|
||||
* authentication. The dn and password of the entry to which to bind are
|
||||
* supplied. LDAP_SUCCESS is returned upon success, the ldap error code
|
||||
* otherwise.
|
||||
*
|
||||
* Example:
|
||||
* ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
|
||||
* "mechanism", "secret", NULL, NULL, &servercred )
|
||||
*/
|
||||
|
||||
int
|
||||
ldap_sasl_bind_s(
|
||||
@ -221,18 +211,18 @@ ldap_sasl_bind_s(
|
||||
|
||||
|
||||
/*
|
||||
* Parse BindResponse:
|
||||
*
|
||||
* BindResponse ::= [APPLICATION 1] SEQUENCE {
|
||||
* COMPONENTS OF LDAPResult,
|
||||
* serverSaslCreds [7] OCTET STRING OPTIONAL }
|
||||
*
|
||||
* LDAPResult ::= SEQUENCE {
|
||||
* resultCode ENUMERATED,
|
||||
* matchedDN LDAPDN,
|
||||
* errorMessage LDAPString,
|
||||
* referral [3] Referral OPTIONAL }
|
||||
*/
|
||||
* Parse BindResponse:
|
||||
*
|
||||
* BindResponse ::= [APPLICATION 1] SEQUENCE {
|
||||
* COMPONENTS OF LDAPResult,
|
||||
* serverSaslCreds [7] OCTET STRING OPTIONAL }
|
||||
*
|
||||
* LDAPResult ::= SEQUENCE {
|
||||
* resultCode ENUMERATED,
|
||||
* matchedDN LDAPDN,
|
||||
* errorMessage LDAPString,
|
||||
* referral [3] Referral OPTIONAL }
|
||||
*/
|
||||
|
||||
int
|
||||
ldap_parse_sasl_bind_result(
|
||||
@ -350,3 +340,486 @@ ldap_parse_sasl_bind_result(
|
||||
|
||||
return( ld->ld_errno );
|
||||
}
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
/*
|
||||
* Various Cyrus SASL related stuff.
|
||||
*/
|
||||
|
||||
static int sasl_setup( Sockbuf *sb, void *arg );
|
||||
static int sasl_remove( Sockbuf *sb );
|
||||
static ber_slen_t sasl_read( Sockbuf *sb, void *buf, ber_len_t len );
|
||||
static ber_slen_t sasl_write( Sockbuf *sb, void *buf, ber_len_t len );
|
||||
static int sasl_close( Sockbuf *sb );
|
||||
|
||||
static Sockbuf_IO sasl_io=
|
||||
{
|
||||
sasl_setup,
|
||||
sasl_remove,
|
||||
sasl_read,
|
||||
sasl_write,
|
||||
sasl_close
|
||||
};
|
||||
|
||||
#define HAS_SASL( sb ) ((sb)->sb_io==&sasl_io)
|
||||
|
||||
static char *
|
||||
array2str( char **a )
|
||||
{
|
||||
char *s, **v, *p;
|
||||
int len = 0;
|
||||
|
||||
for ( v = a; *v != NULL; v++ ) {
|
||||
len += strlen( *v ) + 1; /* for a space */
|
||||
}
|
||||
|
||||
if ( len == 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = LDAP_MALLOC ( len ); /* last space holds \0 */
|
||||
|
||||
if ( s == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = s;
|
||||
for ( v = a; *v != NULL; v++ ) {
|
||||
int len;
|
||||
|
||||
if ( v != a ) {
|
||||
strncpy( p, " ", 1 );
|
||||
++p;
|
||||
}
|
||||
len = strlen( *v );
|
||||
strncpy( p, *v, len );
|
||||
p += len;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int ldap_pvt_sasl_init( void )
|
||||
{
|
||||
/* XXX not threadsafe */
|
||||
static int sasl_initialized = 0;
|
||||
|
||||
if ( sasl_initialized ) {
|
||||
return -1;
|
||||
}
|
||||
#ifndef CSRIMALLOC
|
||||
sasl_set_alloc( ber_memalloc, ber_memcalloc, ber_memrealloc, ber_memfree );
|
||||
#endif /* CSRIMALLOC */
|
||||
|
||||
if ( sasl_client_init( NULL ) == SASL_OK ) {
|
||||
sasl_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg )
|
||||
{
|
||||
/* don't install the stuff unless security has been negotiated */
|
||||
|
||||
if ( !HAS_SASL( sb ) ) {
|
||||
ber_pvt_sb_clear_io( sb );
|
||||
ber_pvt_sb_set_io( sb, &sasl_io, ctx_arg );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sasl_setup( Sockbuf *sb, void *arg )
|
||||
{
|
||||
sb->sb_iodata = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sasl_remove( Sockbuf *sb )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ber_slen_t sasl_read( Sockbuf *sb, void *buf, ber_len_t buflen )
|
||||
{
|
||||
char *recv_tok;
|
||||
unsigned recv_tok_len;
|
||||
sasl_conn_t *conn = (sasl_conn_t *)sb->sb_iodata;
|
||||
|
||||
if ((ber_pvt_sb_io_tcp.sbi_read)( sb, buf, buflen ) != buflen ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( sasl_decode( conn, buf, buflen, &recv_tok, &recv_tok_len ) != SASL_OK ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( recv_tok_len > buflen ) {
|
||||
LDAP_FREE( recv_tok );
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy( buf, recv_tok, recv_tok_len );
|
||||
|
||||
LDAP_FREE( recv_tok );
|
||||
|
||||
return recv_tok_len;
|
||||
}
|
||||
|
||||
static ber_slen_t sasl_write( Sockbuf *sb, void *buf, ber_len_t len )
|
||||
{
|
||||
char *wrapped_tok;
|
||||
unsigned wrapped_tok_len;
|
||||
sasl_conn_t *conn = (sasl_conn_t *)sb->sb_iodata;
|
||||
|
||||
if ( sasl_encode( conn, (const char *)buf, len,
|
||||
&wrapped_tok, &wrapped_tok_len ) != SASL_OK ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ber_pvt_sb_io_tcp.sbi_write)( sb, wrapped_tok, wrapped_tok_len ) != wrapped_tok_len ) {
|
||||
LDAP_FREE( wrapped_tok );
|
||||
return -1;
|
||||
}
|
||||
|
||||
LDAP_FREE( wrapped_tok );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int sasl_close( Sockbuf *sb )
|
||||
{
|
||||
(ber_pvt_sb_io_tcp.sbi_close)( sb );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_sasl_err2ldap( int saslerr )
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (saslerr) {
|
||||
case SASL_CONTINUE:
|
||||
rc = LDAP_SASL_BIND_IN_PROGRESS;
|
||||
break;
|
||||
case SASL_OK:
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
case SASL_FAIL:
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
break;
|
||||
case SASL_NOMEM:
|
||||
rc = LDAP_NO_MEMORY;
|
||||
break;
|
||||
case SASL_NOMECH:
|
||||
rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
|
||||
break;
|
||||
case SASL_BADAUTH:
|
||||
rc = LDAP_INVALID_CREDENTIALS;
|
||||
break;
|
||||
case SASL_NOAUTHZ:
|
||||
rc = LDAP_INSUFFICIENT_ACCESS;
|
||||
break;
|
||||
case SASL_TOOWEAK:
|
||||
case SASL_ENCRYPT:
|
||||
rc = LDAP_INAPPROPRIATE_AUTH;
|
||||
break;
|
||||
default:
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_sasl_getmechs ( LDAP *ld, LDAP_CONST char *desired, char **pmechlist )
|
||||
{
|
||||
/* we need to query the server for supported mechs anyway */
|
||||
LDAPMessage *res, *e;
|
||||
char *attrs[] = { "supportedSASLMechanisms", NULL };
|
||||
char **values, *mechlist, **p;
|
||||
int rc;
|
||||
|
||||
rc = ldap_search_s( ld, NULL, LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", attrs, 0, &res );
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
e = ldap_first_entry( ld, res );
|
||||
if ( e == NULL ) {
|
||||
if ( ld->ld_errno == LDAP_SUCCESS ) {
|
||||
ld->ld_errno = LDAP_UNAVAILABLE;
|
||||
}
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
|
||||
if ( values == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
ldap_msgfree( res );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
if ( desired != NULL ) {
|
||||
rc = LDAP_INAPPROPRIATE_AUTH;
|
||||
|
||||
for ( p = values; *p != NULL; p++ ) {
|
||||
if ( !strcmp( *p, desired ) == 0 ) {
|
||||
rc = LDAP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
/* just return this */
|
||||
*pmechlist = LDAP_STRDUP( desired );
|
||||
return LDAP_SUCCESS;
|
||||
} else {
|
||||
/* couldn't find it */
|
||||
ld->ld_errno = LDAP_INAPPROPRIATE_AUTH;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
}
|
||||
|
||||
mechlist = array2str( values );
|
||||
if ( mechlist == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
ldap_value_free( values );
|
||||
ldap_msgfree( res );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
ldap_value_free( values );
|
||||
ldap_msgfree( res );
|
||||
|
||||
*pmechlist = mechlist;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_sasl_bind(
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *dn,
|
||||
LDAP_CONST char *mechanism,
|
||||
const sasl_callback_t *callbacks,
|
||||
LDAPControl **sctrls,
|
||||
LDAPControl **cctrls )
|
||||
{
|
||||
int saslrc, rc, msgid, ssf = 0;
|
||||
struct berval ccred, *scred;
|
||||
char *mechlist = NULL;
|
||||
char *host;
|
||||
sasl_interact_t *client_interact = NULL;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_bind\n", 0, 0, 0 );
|
||||
|
||||
/* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
|
||||
if (ld->ld_version < LDAP_VERSION3) {
|
||||
ld->ld_errno = LDAP_NOT_SUPPORTED;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* This connects to the host, side effect being that
|
||||
* ldap_host_connected_to() works.
|
||||
*/
|
||||
rc = ldap_pvt_sasl_getmechs( ld, mechanism, &mechlist );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
/* XXX this doesn't work with PF_LOCAL hosts */
|
||||
host = ldap_host_connected_to( &ld->ld_sb );
|
||||
|
||||
if ( host == NULL ) {
|
||||
LDAP_FREE( mechlist );
|
||||
ld->ld_errno = LDAP_UNAVAILABLE;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
if ( ld->ld_sasl_context != NULL ) {
|
||||
LDAP_FREE( mechlist );
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
}
|
||||
|
||||
saslrc = sasl_client_new( "ldap", host, callbacks, 0, &ld->ld_sasl_context );
|
||||
|
||||
LDAP_FREE( host );
|
||||
|
||||
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
||||
LDAP_FREE( mechlist );
|
||||
ld->ld_errno = ldap_pvt_sasl_err2ldap( rc );
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
ccred.bv_val = NULL;
|
||||
ccred.bv_len = 0;
|
||||
|
||||
saslrc = sasl_client_start( ld->ld_sasl_context,
|
||||
mechlist,
|
||||
NULL,
|
||||
&client_interact,
|
||||
&ccred.bv_val,
|
||||
(unsigned int *)&ccred.bv_len,
|
||||
&mechanism );
|
||||
|
||||
LDAP_FREE( mechlist );
|
||||
|
||||
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
||||
ld->ld_errno = ldap_pvt_sasl_err2ldap( saslrc );
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
scred = NULL;
|
||||
|
||||
do {
|
||||
sasl_interact_t *client_interact = NULL;
|
||||
|
||||
rc = ldap_sasl_bind_s( ld, dn, mechanism, &ccred, sctrls, cctrls, &scred );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
break;
|
||||
} else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) {
|
||||
if ( ccred.bv_val != NULL ) {
|
||||
LDAP_FREE( ccred.bv_val );
|
||||
}
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
if ( ccred.bv_val != NULL ) {
|
||||
LDAP_FREE( ccred.bv_val );
|
||||
ccred.bv_val = NULL;
|
||||
}
|
||||
|
||||
saslrc = sasl_client_step( ld->ld_sasl_context,
|
||||
(scred == NULL) ? NULL : scred->bv_val,
|
||||
(scred == NULL) ? 0 : scred->bv_len,
|
||||
&client_interact,
|
||||
&ccred.bv_val,
|
||||
(unsigned int *)&ccred.bv_len );
|
||||
|
||||
ber_bvfree( scred );
|
||||
|
||||
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
|
||||
ld->ld_errno = ldap_pvt_sasl_err2ldap( saslrc );
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
return ld->ld_errno;
|
||||
}
|
||||
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
|
||||
|
||||
assert ( rc == LDAP_SUCCESS );
|
||||
|
||||
if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF, (void **)&ssf )
|
||||
== SASL_OK && ssf ) {
|
||||
ldap_pvt_sasl_install( &ld->ld_sb, ld->ld_sasl_context );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* based on sample/sample-client.c */
|
||||
static int
|
||||
ldap_pvt_sasl_getsecret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
|
||||
{
|
||||
struct berval *passphrase = (struct berval *)context;
|
||||
size_t len;
|
||||
|
||||
if ( conn == NULL || psecret == NULL || id != SASL_CB_PASS ) {
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
len = (passphrase != NULL) ? (size_t)passphrase->bv_len: 0;
|
||||
|
||||
*psecret = (sasl_secret_t *) LDAP_MALLOC( sizeof( sasl_secret_t ) + len );
|
||||
if ( *psecret == NULL ) {
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
(*psecret)->len = passphrase->bv_len;
|
||||
|
||||
if ( passphrase != NULL ) {
|
||||
memcpy((*psecret)->data, passphrase->bv_val, len);
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_pvt_sasl_getsimple(void *context, int id, const char **result, int *len)
|
||||
{
|
||||
const char *value = (const char *)context;
|
||||
|
||||
if ( result == NULL ) {
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
switch ( id ) {
|
||||
case SASL_CB_USER:
|
||||
case SASL_CB_AUTHNAME:
|
||||
*result = value;
|
||||
if ( len )
|
||||
*len = value ? strlen( value ) : 0;
|
||||
break;
|
||||
case SASL_CB_LANGUAGE:
|
||||
*result = NULL;
|
||||
if ( len )
|
||||
*len = 0;
|
||||
break;
|
||||
default:
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ldap_negotiated_sasl_bind_s - bind to the ldap server (and X.500) using SASL
|
||||
* authentication. The dn and password of the entry to which to bind are
|
||||
* supplied. LDAP_SUCCESS is returned upon success, the ldap error code
|
||||
* otherwise.
|
||||
*
|
||||
* Example:
|
||||
* ldap_negotiated_sasl_bind_s( ld, NULL,
|
||||
* "dn:cn=manager", NULL, "GSSAPI", NULL, NULL, NULL );
|
||||
*/
|
||||
int
|
||||
ldap_negotiated_sasl_bind_s(
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *dn, /* usually NULL */
|
||||
LDAP_CONST char *authorizationId,
|
||||
LDAP_CONST char *authenticationId,
|
||||
LDAP_CONST char *saslMechanism,
|
||||
struct berval *passPhrase,
|
||||
LDAPControl **serverControls,
|
||||
LDAPControl **clientControls)
|
||||
{
|
||||
sasl_callback_t callbacks[4];
|
||||
int rc;
|
||||
|
||||
callbacks[0].id = SASL_CB_USER;
|
||||
callbacks[0].proc = ldap_pvt_sasl_getsimple;
|
||||
callbacks[0].context = (void *)authorizationId;
|
||||
callbacks[1].id = SASL_CB_AUTHNAME;
|
||||
callbacks[1].proc = ldap_pvt_sasl_getsimple;
|
||||
callbacks[1].context = (void *)authenticationId;
|
||||
callbacks[2].id = SASL_CB_PASS;
|
||||
callbacks[2].proc = ldap_pvt_sasl_getsecret;
|
||||
callbacks[2].context = (void *)passPhrase;
|
||||
callbacks[3].id = SASL_CB_LIST_END;
|
||||
callbacks[3].proc = NULL;
|
||||
callbacks[3].context = NULL;
|
||||
|
||||
rc = ldap_pvt_sasl_bind(ld, dn, saslMechanism, callbacks, serverControls, clientControls);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
@ -139,6 +139,12 @@ ldap_ld_free(
|
||||
ld->ld_options.ldo_tm_net = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
if ( ld->ld_sasl_context != NULL ) {
|
||||
sasl_dispose( &ld->ld_sasl_context );
|
||||
}
|
||||
#endif
|
||||
|
||||
ber_pvt_sb_destroy( &(ld->ld_sb) );
|
||||
|
||||
LDAP_FREE( (char *) ld );
|
||||
|
@ -40,48 +40,51 @@
|
||||
static const char* skip_url_prefix LDAP_P((
|
||||
const char *url,
|
||||
int *enclosedp,
|
||||
int *ldaps ));
|
||||
unsigned long *properties,
|
||||
int *protocol));
|
||||
|
||||
|
||||
int
|
||||
ldap_is_ldap_url( LDAP_CONST char *url )
|
||||
{
|
||||
int enclosed;
|
||||
int ldaps;
|
||||
int enclosed, protocol;
|
||||
unsigned long properties;
|
||||
|
||||
if( url == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( skip_url_prefix( url, &enclosed, &ldaps) == NULL ) {
|
||||
if( skip_url_prefix( url, &enclosed, &properties, &protocol) == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !ldaps;
|
||||
return !(properties & LDAP_URL_USE_SSL);
|
||||
}
|
||||
|
||||
int
|
||||
ldap_is_ldaps_url( LDAP_CONST char *url )
|
||||
{
|
||||
int enclosed;
|
||||
int ldaps;
|
||||
int enclosed, protocol;
|
||||
unsigned long properties;
|
||||
|
||||
if( url == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( skip_url_prefix( url, &enclosed, &ldaps) == NULL ) {
|
||||
if( skip_url_prefix( url, &enclosed, &properties, &protocol) == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ldaps;
|
||||
return (properties & LDAP_URL_USE_SSL);
|
||||
}
|
||||
|
||||
static const char*
|
||||
skip_url_prefix(
|
||||
const char *url,
|
||||
int *enclosedp,
|
||||
int *ldaps )
|
||||
unsigned long *properties,
|
||||
int *protocol
|
||||
)
|
||||
{
|
||||
/*
|
||||
* return non-zero if this looks like a LDAP URL; zero if not
|
||||
@ -109,11 +112,13 @@ skip_url_prefix(
|
||||
p += LDAP_URL_URLCOLON_LEN;
|
||||
}
|
||||
|
||||
*properties = 0;
|
||||
|
||||
/* check for "ldap://" prefix */
|
||||
if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldap://" prefix and return success */
|
||||
p += LDAP_URL_PREFIX_LEN;
|
||||
*ldaps = 0;
|
||||
*protocol = LDAP_PROTO_TCP;
|
||||
return( p );
|
||||
}
|
||||
|
||||
@ -121,7 +126,25 @@ skip_url_prefix(
|
||||
if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldaps://" prefix and return success */
|
||||
p += LDAPS_URL_PREFIX_LEN;
|
||||
*ldaps = 1;
|
||||
*protocol = LDAP_PROTO_TCP;
|
||||
*properties |= LDAP_URL_USE_SSL;
|
||||
return( p );
|
||||
}
|
||||
|
||||
/* check for "ldapi://" prefix */
|
||||
if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldapi://" prefix and return success */
|
||||
p += LDAPI_URL_PREFIX_LEN;
|
||||
*protocol = LDAP_PROTO_LOCAL;
|
||||
return( p );
|
||||
}
|
||||
|
||||
/* check for "ldapis://" prefix: should this be legal? */
|
||||
if ( strncasecmp( p, LDAPIS_URL_PREFIX, LDAPIS_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldapis://" prefix and return success */
|
||||
p += LDAPIS_URL_PREFIX_LEN;
|
||||
*protocol = LDAP_PROTO_LOCAL;
|
||||
*properties |= LDAP_URL_USE_SSL;
|
||||
return( p );
|
||||
}
|
||||
|
||||
@ -160,7 +183,8 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
|
||||
|
||||
LDAPURLDesc *ludp;
|
||||
char *p, *q;
|
||||
int i, enclosed, ldaps;
|
||||
int i, enclosed, protocol;
|
||||
unsigned long properties;
|
||||
const char *url_tmp;
|
||||
char *url;
|
||||
|
||||
@ -172,7 +196,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
|
||||
|
||||
*ludpp = NULL; /* pessimistic */
|
||||
|
||||
url_tmp = skip_url_prefix( url_in, &enclosed, &ldaps );
|
||||
url_tmp = skip_url_prefix( url_in, &enclosed, &properties, &protocol );
|
||||
|
||||
if ( url_tmp == NULL ) {
|
||||
return LDAP_URL_ERR_NOTLDAP;
|
||||
@ -205,10 +229,11 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
|
||||
ludp->lud_next = NULL;
|
||||
ludp->lud_host = NULL;
|
||||
ludp->lud_port = 0;
|
||||
ludp->lud_dn = NULL;
|
||||
ludp->lud_attrs = NULL;
|
||||
ludp->lud_filter = NULL;
|
||||
ludp->lud_ldaps = ldaps;
|
||||
ludp->lud_dn = NULL;
|
||||
ludp->lud_attrs = NULL;
|
||||
ludp->lud_filter = NULL;
|
||||
ludp->lud_properties = properties;
|
||||
ludp->lud_protocol = protocol;
|
||||
ludp->lud_scope = LDAP_SCOPE_BASE;
|
||||
|
||||
ludp->lud_filter = LDAP_STRDUP("(objectClass=*)");
|
||||
@ -468,7 +493,6 @@ ldap_url_dup ( LDAPURLDesc *ludp )
|
||||
}
|
||||
}
|
||||
|
||||
dest->lud_ldaps = ludp->lud_ldaps;
|
||||
dest->lud_port = ludp->lud_port;
|
||||
dest->lud_scope = ludp->lud_scope;
|
||||
|
||||
@ -567,7 +591,8 @@ ldap_url_parsehosts (LDAPURLDesc **ludlist, const char *hosts )
|
||||
ludp->lud_port = atoi(p);
|
||||
}
|
||||
ldap_pvt_hex_unescape(ludp->lud_host);
|
||||
ludp->lud_ldaps = -1; /* unknown (use TLS default) */
|
||||
ludp->lud_protocol = LDAP_PROTO_TCP;
|
||||
ludp->lud_properties = LDAP_URL_USE_SSL_UNSPECIFIED;
|
||||
ludp->lud_next = *ludlist;
|
||||
*ludlist = ludp;
|
||||
}
|
||||
@ -635,7 +660,7 @@ ldap_url_list2urls (LDAPURLDesc *ludlist)
|
||||
|
||||
p = s;
|
||||
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
|
||||
p += sprintf(p, "ldap%s://%s", (ludp->lud_ldaps == 1) ? "s" : "", ludp->lud_host);
|
||||
p += sprintf(p, "ldap%s://%s", (ludp->lud_properties & LDAP_URL_USE_SSL) ? "s" : "", ludp->lud_host);
|
||||
if (ludp->lud_port != 0)
|
||||
p += sprintf(p, ":%d", ludp->lud_port);
|
||||
*p++ = '/';
|
||||
@ -767,9 +792,9 @@ void
|
||||
ldap_pvt_hex_unescape( char *s )
|
||||
{
|
||||
/*
|
||||
* Remove URL hex escapes from s... done in place. The basic concept for
|
||||
* this routine is borrowed from the WWW library HTUnEscape() routine.
|
||||
*/
|
||||
* Remove URL hex escapes from s... done in place. The basic concept for
|
||||
* this routine is borrowed from the WWW library HTUnEscape() routine.
|
||||
*/
|
||||
char *p;
|
||||
|
||||
for ( p = s; *s != '\0'; ++s ) {
|
||||
|
@ -16,7 +16,7 @@ XXSRCS = apitest.c test.c tmpltest.c extended.c \
|
||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||
request.c getdxbyname.c os-ip.c url.c charset.c \
|
||||
init.c options.c print.c string.c util-int.c schema.c \
|
||||
charray.c digest.c tls.c dn.c
|
||||
charray.c digest.c tls.c dn.c os-local.c
|
||||
SRCS = thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
|
||||
thr_pth.c thr_sleep.c thr_stub.c rdwr.c
|
||||
OBJS = extended.lo \
|
||||
@ -29,7 +29,7 @@ OBJS = extended.lo \
|
||||
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
|
||||
thr_posix.lo thr_cthreads.lo thr_thr.lo thr_lwp.lo thr_nt.lo \
|
||||
thr_pth.lo thr_sleep.lo thr_stub.lo rdwr.lo \
|
||||
charray.lo digest.lo tls.lo dn.lo
|
||||
charray.lo digest.lo tls.lo dn.lo os-local.lo
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
@ -4,12 +4,12 @@ SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c entry.c id2entry.c \
|
||||
index.c id2children.c nextid.c abandon.c compare.c group.c \
|
||||
modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
|
||||
filterindex.c unbind.c close.c alias.c tools.c \
|
||||
extended.c passwd.c
|
||||
extended.c passwd.c sasl.c
|
||||
OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo id2entry.lo \
|
||||
index.lo id2children.lo nextid.lo abandon.lo compare.lo group.lo \
|
||||
modify.lo modrdn.lo delete.lo init.lo config.lo bind.lo attr.lo \
|
||||
filterindex.lo unbind.lo close.lo alias.lo tools.lo \
|
||||
extended.lo passwd.lo
|
||||
extended.lo passwd.lo sasl.lo
|
||||
|
||||
LDAP_INCDIR= ../../../include
|
||||
LDAP_LIBDIR= ../../../libraries
|
||||
|
@ -85,6 +85,10 @@ ldbm_back_bind(
|
||||
}
|
||||
|
||||
} else if ( method == LDAP_AUTH_SASL ) {
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
rc = sasl_bind( be, conn, op,
|
||||
dn, ndn, mech, cred, edn );
|
||||
#else
|
||||
if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
|
||||
/* insert DIGEST calls here */
|
||||
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
|
||||
@ -94,7 +98,7 @@ ldbm_back_bind(
|
||||
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
|
||||
NULL, NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
} else if ( refs != NULL ) {
|
||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
||||
matched_dn, NULL, refs, NULL );
|
||||
@ -241,7 +245,7 @@ ldbm_back_bind(
|
||||
|
||||
if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
|
||||
/*
|
||||
* no krbName values present: check against DN
|
||||
* no krbname values present: check against DN
|
||||
*/
|
||||
if ( strcasecmp( dn, krbname ) == 0 ) {
|
||||
rc = 0;
|
||||
@ -252,7 +256,7 @@ ldbm_back_bind(
|
||||
rc = 1;
|
||||
goto return_results;
|
||||
|
||||
} else { /* look for krbName match */
|
||||
} else { /* look for krbname match */
|
||||
struct berval krbval;
|
||||
|
||||
krbval.bv_val = krbname;
|
||||
@ -279,7 +283,12 @@ ldbm_back_bind(
|
||||
|
||||
case LDAP_AUTH_SASL:
|
||||
/* insert SASL code here */
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
/* this may discard edn as we always prefer the SASL authzid
|
||||
* because it may be sealed.
|
||||
*/
|
||||
rc = sasl_bind( be, conn, op, dn, ndn, mech, cred, edn );
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
default:
|
||||
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
|
||||
NULL, "auth method not supported", NULL, NULL );
|
||||
|
@ -82,6 +82,12 @@ ldbm_back_initialize(
|
||||
bi->bi_tool_index_change = ldbm_tool_index_change;
|
||||
bi->bi_tool_sync = ldbm_tool_sync;
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
bi->bi_sasl_authorize = 0; /* ldbm_sasl_authorize; */
|
||||
bi->bi_sasl_getsecret = 0; /* ldbm_sasl_getsecret; */
|
||||
bi->bi_sasl_putsecret = 0; /* ldbm_sasl_putsecret; */
|
||||
#endif
|
||||
|
||||
bi->bi_connection_init = 0;
|
||||
bi->bi_connection_destroy = 0;
|
||||
|
||||
|
@ -178,6 +178,30 @@ int ldbm_modify_internal LDAP_P((Backend *be,
|
||||
Connection *conn, Operation *op,
|
||||
char *dn, LDAPModList *mods, Entry *e ));
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
/*
|
||||
* sasl.c
|
||||
*/
|
||||
int ldbm_sasl_authorize LDAP_P((
|
||||
BackendDB *be,
|
||||
const char *auth_identity,
|
||||
const char *requested_user,
|
||||
const char **user,
|
||||
const char **errstring ));
|
||||
int ldbm_sasl_getsecret LDAP_P((
|
||||
Backend *be,
|
||||
const char *mechanism,
|
||||
const char *auth_identity,
|
||||
const char *realm,
|
||||
sasl_secret_t **secret ));
|
||||
int ldbm_sasl_putsecret LDAP_P((
|
||||
Backend *be,
|
||||
const char *mechanism,
|
||||
const char *auth_identity,
|
||||
const char *realm,
|
||||
const sasl_secret_t *secret ));
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
/*
|
||||
* nextid.c
|
||||
*/
|
||||
|
59
servers/slapd/back-ldbm/sasl.c
Normal file
59
servers/slapd/back-ldbm/sasl.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* bind.c - ldbm backend bind and unbind routines */
|
||||
/* $OpenLDAP$ */
|
||||
/*
|
||||
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
|
||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/krb.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/unistd.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "back-ldbm.h"
|
||||
#include "proto-back-ldbm.h"
|
||||
|
||||
int
|
||||
back_ldbm_sasl_authorize(
|
||||
BackendDB *be,
|
||||
const char *auth_identity,
|
||||
const char *requested_user,
|
||||
const char **user,
|
||||
const char **errstring)
|
||||
{
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
int
|
||||
back_ldbm_sasl_getsecret(
|
||||
Backend *be,
|
||||
const char *mechanism,
|
||||
const char *auth_identity,
|
||||
const char *realm,
|
||||
sasl_secret_t **secret)
|
||||
{
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
int
|
||||
back_ldbm_sasl_putsecret(
|
||||
Backend *be,
|
||||
const char *mechanism,
|
||||
const char *auth_identity,
|
||||
const char *realm,
|
||||
const sasl_secret_t *secret)
|
||||
{
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
static int dummy = 1;
|
||||
#endif
|
||||
|
@ -226,7 +226,6 @@ do_bind(
|
||||
assert( conn->c_authstate == NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
@ -305,6 +304,10 @@ do_bind(
|
||||
method, mech, &cred, &edn );
|
||||
|
||||
if ( ret == 0 ) {
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
int ssf = 0;
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_cdn = dn;
|
||||
@ -326,6 +329,14 @@ do_bind(
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
||||
NULL, NULL, NULL, NULL );
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
if ( conn->c_sasl_context != NULL &&
|
||||
sasl_getprop( conn->c_sasl_context, SASL_SSF, (void **)&ssf )
|
||||
== SASL_OK && ssf ) {
|
||||
/* Enable encode/decode */
|
||||
ldap_pvt_sasl_install( conn->c_sb, conn->c_sasl_context );
|
||||
}
|
||||
#endif
|
||||
} else if (edn != NULL) {
|
||||
free( edn );
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ long connection_init(
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
c->c_sasl_context = NULL;
|
||||
#endif
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
c->c_sb = ber_sockbuf_alloc( );
|
||||
c->c_currentber = NULL;
|
||||
@ -485,6 +485,19 @@ connection_destroy( Connection *c )
|
||||
c->c_peer_domain = NULL;
|
||||
}
|
||||
if(c->c_peer_name != NULL) {
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
/*
|
||||
* If peer was a domain socket, unlink. Mind you,
|
||||
* they may be un-named. Should we leave this to
|
||||
* the client?
|
||||
*/
|
||||
if (strncmp(c->c_peer_name, "PATH=", 5) == 0) {
|
||||
char *path = c->c_peer_name + 5;
|
||||
if (path != '\0') {
|
||||
(void)unlink(path);
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
free(c->c_peer_name);
|
||||
c->c_peer_name = NULL;
|
||||
}
|
||||
@ -506,7 +519,9 @@ connection_destroy( Connection *c )
|
||||
sasl_dispose( &c->c_sasl_context );
|
||||
c->c_sasl_context = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
c->c_bind_in_progress = 0;
|
||||
|
||||
if ( c->c_currentber != NULL ) {
|
||||
ber_free( c->c_currentber, 1 );
|
||||
@ -795,7 +810,13 @@ connection_operation( void *arg_v )
|
||||
if( conn->c_conn_state == SLAP_C_BINDING) {
|
||||
conn->c_conn_state = SLAP_C_ACTIVE;
|
||||
}
|
||||
conn->c_bind_in_progress = ( rc == LDAP_SASL_BIND_IN_PROGRESS );
|
||||
/*
|
||||
* Is this ever the case? For now, rely on
|
||||
* the backend to set this.
|
||||
*/
|
||||
if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
|
||||
conn->c_bind_in_progress = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &active_threads_mutex );
|
||||
|
@ -27,10 +27,22 @@ int allow_severity = LOG_INFO;
|
||||
int deny_severity = LOG_NOTICE;
|
||||
#endif /* TCP Wrappers */
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
#include <sys/stat.h>
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
/* globals */
|
||||
time_t starttime;
|
||||
ber_socket_t dtblsize;
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
typedef union slap_sockaddr {
|
||||
struct sockaddr sa_addr;
|
||||
struct sockaddr_in sa_in_addr;
|
||||
struct sockaddr_un sa_un_addr;
|
||||
} Sockaddr;
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
typedef struct slap_listener {
|
||||
char* sl_url;
|
||||
char* sl_name;
|
||||
@ -38,7 +50,12 @@ typedef struct slap_listener {
|
||||
int sl_is_tls;
|
||||
#endif
|
||||
ber_socket_t sl_sd;
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
Sockaddr sl_sa;
|
||||
#define sl_addr sl_sa.sa_in_addr
|
||||
#else
|
||||
struct sockaddr_in sl_addr;
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
} Listener;
|
||||
|
||||
Listener **slap_listeners = NULL;
|
||||
@ -196,7 +213,7 @@ static Listener * open_listener( const char* url )
|
||||
}
|
||||
|
||||
#ifndef HAVE_TLS
|
||||
if( lud->lud_ldaps ) {
|
||||
if( lud->lud_properties & LDAP_URL_USE_SSL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: TLS not supported (%s)\n",
|
||||
url, 0, 0 );
|
||||
@ -209,13 +226,42 @@ static Listener * open_listener( const char* url )
|
||||
}
|
||||
|
||||
#else
|
||||
l.sl_is_tls = lud->lud_ldaps;
|
||||
l.sl_is_tls = (lud->lud_properties & LDAP_URL_USE_SSL);
|
||||
|
||||
if(! lud->lud_port ) {
|
||||
lud->lud_port = lud->lud_ldaps ? LDAPS_PORT : LDAP_PORT;
|
||||
lud->lud_port = (lud->lud_properties & LDAP_URL_USE_SSL) ? LDAPS_PORT : LDAP_PORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
if (lud->lud_protocol == LDAP_PROTO_LOCAL) {
|
||||
port = 0;
|
||||
(void) memset( (void *)&l.sl_sa.sa_un_addr, '\0', sizeof(l.sl_sa.sa_un_addr) );
|
||||
|
||||
l.sl_sa.sa_un_addr.sun_family = AF_UNIX;
|
||||
|
||||
/* hack: overload the host to be the path */
|
||||
if ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) {
|
||||
strcpy( l.sl_sa.sa_un_addr.sun_path, "/tmp/.ldap-sock" );
|
||||
} else {
|
||||
if ( strlen(lud->lud_host) > (sizeof(l.sl_sa.sa_un_addr.sun_path) - 1) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "domain socket path (%s) too long in URL: %s",
|
||||
lud->lud_host, url, 0);
|
||||
ldap_free_urldesc( lud );
|
||||
return NULL;
|
||||
}
|
||||
strcpy( l.sl_sa.sa_un_addr.sun_path, lud->lud_host );
|
||||
}
|
||||
unlink( l.sl_sa.sa_un_addr.sun_path );
|
||||
#if 0
|
||||
/* I don't think we need to set this. */
|
||||
l.sl_sa.sa_un_addr.sun_len = sizeof( l.sl_sa.sa_un_addr.sun_len ) +
|
||||
sizeof( l.sl_sa.sa_un_addr.sun_family ) +
|
||||
strlen( l.sl_sa.sa_un_addr.sun_path ) + 1;
|
||||
#endif
|
||||
} else {
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
port = lud->lud_port;
|
||||
|
||||
(void) memset( (void*) &l.sl_addr, '\0', sizeof(l.sl_addr) );
|
||||
@ -243,11 +289,18 @@ static Listener * open_listener( const char* url )
|
||||
sizeof( l.sl_addr.sin_addr ) );
|
||||
}
|
||||
}
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
}
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
ldap_free_urldesc( lud );
|
||||
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
l.sl_sd = socket( l.sl_sa.sa_addr.sa_family, SOCK_STREAM, 0 );
|
||||
if ( l.sl_sd == AC_SOCKET_INVALID ) {
|
||||
#else
|
||||
if ( (l.sl_sd = socket( AF_INET, SOCK_STREAM, 0 )) == AC_SOCKET_INVALID ) {
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
int err = sock_errno();
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"daemon: socket() failed errno=%d (%s)\n", err,
|
||||
@ -265,6 +318,11 @@ static Listener * open_listener( const char* url )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
/* for IP sockets only */
|
||||
if ( l.sl_sa.sa_addr.sa_family == AF_INET ) {
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
/* enable address reuse */
|
||||
tmp = 1;
|
||||
@ -302,7 +360,27 @@ static Listener * open_listener( const char* url )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
/* close conditional */
|
||||
}
|
||||
|
||||
switch ( l.sl_sa.sa_addr.sa_family ) {
|
||||
case AF_UNIX:
|
||||
rc = bind( l.sl_sd, (struct sockaddr *)&l.sl_sa,
|
||||
sizeof(l.sl_sa.sa_un_addr) );
|
||||
break;
|
||||
case AF_INET:
|
||||
rc = bind( l.sl_sd, (struct sockaddr *)&l.sl_sa,
|
||||
sizeof(l.sl_sa.sa_in_addr) );
|
||||
break;
|
||||
default:
|
||||
rc = AC_SOCKET_ERROR;
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
rc = bind( l.sl_sd, (struct sockaddr *) &l.sl_addr, sizeof(l.sl_addr) );
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
if ( rc == AC_SOCKET_ERROR ) {
|
||||
int err = sock_errno();
|
||||
Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno=%d (%s)\n",
|
||||
@ -310,13 +388,40 @@ static Listener * open_listener( const char* url )
|
||||
tcp_close( l.sl_sd );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
if ( l.sl_sa.sa_addr.sa_family == AF_UNIX ) {
|
||||
if ( chmod( l.sl_sa.sa_un_addr.sun_path, S_IRWXU ) < 0 ) {
|
||||
int err = sock_errno();
|
||||
Debug( LDAP_DEBUG_ANY, "daemon: fchmod(%ld) failed errno=%d (%s)",
|
||||
(long) l.sl_sd, err, sock_errstr(err) );
|
||||
tcp_close( l.sl_sd );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_PF_LOACL */
|
||||
l.sl_url = ch_strdup( url );
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
switch ( l.sl_sa.sa_addr.sa_family ) {
|
||||
case AF_UNIX:
|
||||
l.sl_name = ch_malloc( strlen(l.sl_sa.sa_un_addr.sun_path) + sizeof("PATH=") );
|
||||
sprintf( l.sl_name, "PATH=%s", l.sl_sa.sa_un_addr.sun_path );
|
||||
break;
|
||||
case AF_INET:
|
||||
l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") );
|
||||
s = inet_ntoa( l.sl_addr.sin_addr );
|
||||
sprintf( l.sl_name, "IP=%s:%d",
|
||||
s != NULL ? s : "unknown" , port );
|
||||
break;
|
||||
default:
|
||||
l.sl_name = ch_strdup( "UNKNOWN" );
|
||||
break;
|
||||
}
|
||||
#else
|
||||
l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") );
|
||||
s = inet_ntoa( l.sl_addr.sin_addr );
|
||||
sprintf( l.sl_name, "IP=%s:%d",
|
||||
s != NULL ? s : "unknown" , port );
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
li = ch_malloc( sizeof( Listener ) );
|
||||
*li = l;
|
||||
@ -476,8 +581,14 @@ slapd_daemon_task(
|
||||
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
Sockaddr from;
|
||||
/* minimize impact, undefine later. */
|
||||
#define sin_addr sa_in_addr.sin_addr
|
||||
#define sin_port sa_in_addr.sin_port
|
||||
#else
|
||||
struct sockaddr_in from;
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
|
||||
struct hostent *hp;
|
||||
#endif
|
||||
@ -611,9 +722,11 @@ slapd_daemon_task(
|
||||
|
||||
char *dnsname;
|
||||
char *peeraddr;
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
char peername[MAXPATHLEN + sizeof("PATH=")];
|
||||
#else
|
||||
char peername[sizeof("IP=255.255.255.255:65336")];
|
||||
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
|
||||
continue;
|
||||
|
||||
@ -668,6 +781,13 @@ slapd_daemon_task(
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
switch ( from.sa_addr.sa_family ) {
|
||||
case AF_UNIX:
|
||||
sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
|
||||
break;
|
||||
case AF_INET:
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
peeraddr = inet_ntoa( from.sin_addr );
|
||||
sprintf( peername, "IP=%s:%d",
|
||||
peeraddr != NULL ? peeraddr : "unknown",
|
||||
@ -706,6 +826,15 @@ slapd_daemon_task(
|
||||
continue;
|
||||
}
|
||||
#endif /* HAVE_TCPD */
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
break;
|
||||
default:
|
||||
slapd_close(s);
|
||||
continue;
|
||||
}
|
||||
#undef sin_addr
|
||||
#undef sin_port
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
|
||||
if( (id = connection_init(s,
|
||||
slap_listeners[l]->sl_url,
|
||||
@ -881,6 +1010,11 @@ slapd_daemon_task(
|
||||
|
||||
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
|
||||
if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
|
||||
#ifdef LDAP_PF_LOCAL
|
||||
if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_UNIX ) {
|
||||
unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
|
||||
}
|
||||
#endif /* LDAP_PF_LOCAL */
|
||||
slapd_close( slap_listeners[l]->sl_sd );
|
||||
break;
|
||||
}
|
||||
|
@ -264,6 +264,9 @@ typedef int (*SLAP_EXTOP_MAIN_FN) LDAP_P((
|
||||
typedef int (*SLAP_EXTOP_GETOID_FN) LDAP_P((
|
||||
int index, char *oid, int blen ));
|
||||
|
||||
LIBSLAPD_F (int) load_extension LDAP_P((const void *module, const char *file_name));
|
||||
LIBSLAPD_F (char *) get_supported_extension LDAP_P((int index));
|
||||
|
||||
LIBSLAPD_F (int) load_extop LDAP_P((
|
||||
const char *ext_oid,
|
||||
SLAP_EXTOP_MAIN_FN ext_main ));
|
||||
@ -424,6 +427,12 @@ LIBSLAPD_F (char **) supportedSASLMechanisms;
|
||||
|
||||
LIBSLAPD_F (int) sasl_init(void);
|
||||
LIBSLAPD_F (int) sasl_destroy(void);
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
LIBSLAPD_F (int) sasl_errldap LDAP_P(( int ));
|
||||
LIBSLAPD_F (int) sasl_bind LDAP_P((Backend *,
|
||||
Connection *, Operation *,
|
||||
char *, char *, char *, struct berval *, char **));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* schema.c
|
||||
|
@ -18,9 +18,32 @@
|
||||
char **supportedSASLMechanisms = NULL;
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
static sasl_callback_t callbacks[] = {
|
||||
{ SASL_CB_LIST_END, NULL, NULL }
|
||||
};
|
||||
static void *sasl_pvt_mutex_new(void)
|
||||
{
|
||||
ldap_pvt_thread_mutex_t *mutex;
|
||||
|
||||
mutex = (ldap_pvt_thread_mutex_t *)ch_malloc( sizeof(ldap_pvt_thread_mutex_t) );
|
||||
if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
|
||||
return mutex;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int sasl_pvt_mutex_lock(void *mutex)
|
||||
{
|
||||
return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex );
|
||||
}
|
||||
|
||||
static int sasl_pvt_mutex_unlock(void *mutex)
|
||||
{
|
||||
return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex );
|
||||
}
|
||||
|
||||
static void sasl_pvt_mutex_dispose(void *mutex)
|
||||
{
|
||||
(void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
|
||||
free( mutex );
|
||||
}
|
||||
|
||||
int sasl_init( void )
|
||||
{
|
||||
@ -28,7 +51,12 @@ int sasl_init( void )
|
||||
char *mechs;
|
||||
sasl_conn_t *server = NULL;
|
||||
|
||||
rc = sasl_server_init( callbacks, "slapd" );
|
||||
sasl_set_alloc( ch_malloc, ch_calloc, ch_realloc, ch_free );
|
||||
|
||||
sasl_set_mutex( sasl_pvt_mutex_new, sasl_pvt_mutex_lock,
|
||||
sasl_pvt_mutex_unlock, sasl_pvt_mutex_dispose );
|
||||
|
||||
rc = sasl_server_init( NULL, "slapd" );
|
||||
|
||||
if( rc != SASL_OK ) {
|
||||
Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
|
||||
@ -88,6 +116,113 @@ int sasl_destroy( void )
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
int sasl_bind(
|
||||
Backend *be,
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
char *dn,
|
||||
char *ndn,
|
||||
char *mech,
|
||||
struct berval *cred,
|
||||
char **edn)
|
||||
{
|
||||
struct berval response;
|
||||
const char *errstr;
|
||||
int sc;
|
||||
int rc = 1;
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS, "==> sasl_bind: dn=%s, mech=%s, cred->bv_len=%d\n",
|
||||
dn, mech, cred ? cred->bv_len : 0 );
|
||||
|
||||
if ( conn->c_sasl_context == NULL ) {
|
||||
sasl_callback_t callbacks[4];
|
||||
int cbnum = 0;
|
||||
|
||||
if (be->be_sasl_authorize) {
|
||||
callbacks[cbnum].id = SASL_CB_PROXY_POLICY;
|
||||
callbacks[cbnum].proc = be->be_sasl_authorize;
|
||||
callbacks[cbnum].context = be;
|
||||
++cbnum;
|
||||
}
|
||||
|
||||
if (be->be_sasl_getsecret) {
|
||||
callbacks[cbnum].id = SASL_CB_SERVER_GETSECRET;
|
||||
callbacks[cbnum].proc = be->be_sasl_getsecret;
|
||||
callbacks[cbnum].context = be;
|
||||
++cbnum;
|
||||
}
|
||||
|
||||
if (be->be_sasl_putsecret) {
|
||||
callbacks[cbnum].id = SASL_CB_SERVER_PUTSECRET;
|
||||
callbacks[cbnum].proc = be->be_sasl_putsecret;
|
||||
callbacks[cbnum].context = be;
|
||||
++cbnum;
|
||||
}
|
||||
callbacks[cbnum].id = SASL_CB_LIST_END;
|
||||
callbacks[cbnum].proc = NULL;
|
||||
callbacks[cbnum].context = NULL;
|
||||
|
||||
if ( sasl_server_new( "ldap", NULL, be->be_realm,
|
||||
callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_context ) != SASL_OK ) {
|
||||
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
|
||||
NULL, NULL, NULL, NULL );
|
||||
} else {
|
||||
conn->c_authmech = ch_strdup( mech );
|
||||
sc = sasl_server_start( conn->c_sasl_context, conn->c_authmech,
|
||||
cred->bv_val, cred->bv_len, (char **)&response.bv_val,
|
||||
(unsigned *)&response.bv_len, &errstr );
|
||||
if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
|
||||
send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
|
||||
NULL, errstr, NULL, NULL );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sc = sasl_server_step( conn->c_sasl_context, cred->bv_val, cred->bv_len,
|
||||
(char **)&response.bv_val, (unsigned *)&response.bv_len, &errstr );
|
||||
if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
|
||||
send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
|
||||
NULL, errstr, NULL, NULL );
|
||||
}
|
||||
}
|
||||
if ( sc == SASL_OK ) {
|
||||
char *authzid;
|
||||
|
||||
if ( ( sc = sasl_getprop( conn->c_sasl_context, SASL_USERNAME,
|
||||
(void **)&authzid ) ) != SASL_OK ) {
|
||||
send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
|
||||
NULL, NULL, NULL, NULL );
|
||||
} else {
|
||||
if ( *edn != NULL ) {
|
||||
free( *edn );
|
||||
}
|
||||
if ( strcasecmp( authzid, "anonymous" ) == 0 ) {
|
||||
*edn = ch_strdup( "" );
|
||||
} else {
|
||||
*edn = ch_malloc( strlen( authzid ) + sizeof( "authzid=" ) );
|
||||
strcpy( *edn, "authzid=" );
|
||||
strcat( *edn, authzid );
|
||||
}
|
||||
/* let FE send result */
|
||||
rc = 0;
|
||||
}
|
||||
} else if ( sc == SASL_CONTINUE ) {
|
||||
/*
|
||||
* We set c_bind_in_progress because it doesn't appear
|
||||
* that connection.c sets this (unless do_bind() itself
|
||||
* returns LDAP_SASL_BIND_IN_PROGRESS).
|
||||
*/
|
||||
conn->c_bind_in_progress = 1;
|
||||
send_ldap_sasl( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
|
||||
/* matched */ NULL, /* text */ NULL, /* refs */ NULL, /* controls */ NULL, &response );
|
||||
}
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: rc=%d\n", rc, 0, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
#else
|
||||
/* no SASL support */
|
||||
int sasl_init( void ) { return 0; }
|
||||
|
@ -500,6 +500,12 @@ struct slap_backend_db {
|
||||
#define be_index_attr bd_info->bi_tool_index_attr
|
||||
#define be_index_change bd_info->bi_tool_index_change
|
||||
#define be_sync bd_info->bi_tool_sync
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
#define be_sasl_authorize bd_info->bi_sasl_authorize
|
||||
#define be_sasl_getsecret bd_info->bi_sasl_getsecret
|
||||
#define be_sasl_putsecret bd_info->bi_sasl_putsecret
|
||||
#endif
|
||||
|
||||
/* these should be renamed from be_ to bd_ */
|
||||
@ -656,6 +662,18 @@ struct slap_backend_info {
|
||||
struct berval **bv, ID id, int op ));
|
||||
int (*bi_tool_sync) LDAP_P(( BackendDB *be ));
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
int (*bi_sasl_authorize) LDAP_P(( BackendDB *be,
|
||||
const char *authnid, const char *authzid,
|
||||
const char **canon_authzid, const char **errstr ));
|
||||
int (*bi_sasl_getsecret) LDAP_P(( BackendDB *be,
|
||||
const char *mechanism, const char *authzid,
|
||||
const char *realm, sasl_secret_t **secret ));
|
||||
int (*bi_sasl_putsecret) LDAP_P(( BackendDB *be,
|
||||
const char *mechanism, const char *auth_identity,
|
||||
const char *realm, const sasl_secret_t *secret ));
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
|
||||
#define SLAP_INDEX_ADD_OP 0x0001
|
||||
#define SLAP_INDEX_DELETE_OP 0x0002
|
||||
|
||||
|
@ -143,3 +143,18 @@ int sasl_init(void) {
|
||||
int sasl_destroy(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
int sasl_bind(
|
||||
Backend *be,
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
char *dn,
|
||||
char *ndn,
|
||||
char *mech,
|
||||
struct berval *cred,
|
||||
char **edn)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user