Commit 9b4e3b22 authored by Luke Howard's avatar Luke Howard
Browse files

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.
parent 6fb04da5
......@@ -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 )
{
......
/* $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;