]> git.sur5r.net Git - openldap/commitdiff
Merged in preliminary support for Cyrus SASL library;
authorLuke Howard <lukeh@openldap.org>
Sun, 2 Jan 2000 01:21:25 +0000 (01:21 +0000)
committerLuke Howard <lukeh@openldap.org>
Sun, 2 Jan 2000 01:21:25 +0000 (01:21 +0000)
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.

30 files changed:
configure
configure.in
include/ac/socket.h
include/ldap.h
include/ldap_pvt.h
include/portable.h.in
libraries/libldap/Makefile.in
libraries/libldap/getdn.c
libraries/libldap/init.c
libraries/libldap/ldap-int.h
libraries/libldap/open.c
libraries/libldap/os-ip.c
libraries/libldap/os-local.c [new file with mode: 0644]
libraries/libldap/request.c
libraries/libldap/sasl.c
libraries/libldap/unbind.c
libraries/libldap/url.c
libraries/libldap_r/Makefile.in
servers/slapd/back-ldbm/Makefile.in
servers/slapd/back-ldbm/bind.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-ldbm/sasl.c [new file with mode: 0644]
servers/slapd/bind.c
servers/slapd/connection.c
servers/slapd/daemon.c
servers/slapd/proto-slap.h
servers/slapd/sasl.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c

index 12be49680c2d90ae72c3a8dfb0b591d9a7d2f11c..27d34f6d3670fd8ba9bad5b927453cca6ba0ef93 100755 (executable)
--- a/configure
+++ b/configure
@@ -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
index 8b4439f8ed56d62607cd418cd5c3db36bbc4db9f..75bbc1aeda7d205bbb82537abf07dd287542db79 100644 (file)
@@ -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])
index 35c5ba3b3556a8976aa732405a236444eeffc9ca..5e20569f54f6f3bf115464232413577a7857501a 100644 (file)
 #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
index 57ee5715b4f0d525675384cd3bfeb5e96e969cb9..d2f1a145e37f7cf5f77f0b23ecbc3cbc4d5da77a 100644 (file)
@@ -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
index 632652cd64a7afeb7a30a88d2928194dd56346fb..8e21b5df7ddd94fb605fed83ab2e25226dca7ee2 100644 (file)
@@ -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 ));
index bff5d52a4bfaaa80644bc1901fc2915cd5d3ca46..7faa3ce31686c75fcab6bc69f416cd3046cdf676 100644 (file)
 /* 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
 
 /* 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
 
index 764c29346e5cc4124f961e285154797f93ad19e4..43bd9e71615257ad4e1134d1f121f7b22245b632 100644 (file)
@@ -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
index 0110e298e719649340db1af1513c6c3e8072fc37..f03be3b455d15a1c7039cc41e20f0bb1882eca6f 100644 (file)
 
 #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 ) {
index e7a8f0174b73c2b800915ef979412694a6621a1d..5628eea1e7cb04b24f6331d7b77f139509de8e45 100644 (file)
@@ -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();
 
index 04c1b3147fbd0193db8d3230b94b742203964ef9..eca39c573f2347ef83b286b83374b06f588338cd 100644 (file)
 
 #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 );
 
index 43c7b80a92fe9fd6b3a9adf414badc2d8bf64eee..462b60b39401c20da206e3b76fecfbb827c7d623 100644 (file)
@@ -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)
index 4a908d05755ed4ff62adb235a31024223975f455..530c9299dcea66b3a1f7041b179b98205ed960a1 100644 (file)
@@ -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 )
 {
diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c
new file mode 100644 (file)
index 0000000..5d2a21f
--- /dev/null
@@ -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 */
index badd2468a6a5333705a99ec2631fa716b3c58187..30c8887beb7c9e2c08b7c011e11c6de0c6af610a 100644 (file)
@@ -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 )
index 28e36768b39b3db712ae912332def7a931ae3a57..a5cfa17675ea81ffbd032230bc85a8c9a1307006 100644 (file)
@@ -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 */
index 24c43b454caa95661c853fc8a7eb8bcdc1e44bc8..c4222fe4ab7e90978e3a44ee95c60fd9eff51688 100644 (file)
@@ -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 );
index a4309bfcf621b67c39b50cf2b4e3651fc5ee2420..9d29cc41208d5a40b658f5fcd8b87918d2498db9 100644 (file)
 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 ) {
index 7f66bac8d94665cc734c25b6060ae94d928fbbf2..3454faefeeb62d79060e02296136fdfdb2825b31 100644 (file)
@@ -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
index 15211cb0f77d4f962f91a7febe90c7b717a00c2d..ec0ecc97343d398cbdb86bc3927b80e7bb8cc529 100644 (file)
@@ -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
index 3935179bc6c3874113bd367325cbd8fd9363880a..acec9dd5a18da7c8fab53403d76005f4869acecc 100644 (file)
@@ -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 );
index 7d59f5dde0d271860d865e0aca71b2ca3eb84b07..c50800681f40c9599d2a412be64bd500238662fc 100644 (file)
@@ -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;
 
index c9ebbae66edb5932effe3f4f6cd329ff0672e3c6..85bfff8dfe0b3b589ddfc01246283289c22e2d0f 100644 (file)
@@ -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
  */
diff --git a/servers/slapd/back-ldbm/sasl.c b/servers/slapd/back-ldbm/sasl.c
new file mode 100644 (file)
index 0000000..a1dc6f6
--- /dev/null
@@ -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
+
index 9be3d11c8a2135472f92dc119a945642b0b1755e..881c2c773306b186b1e47ed614a7885056d0ad26 100644 (file)
@@ -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 );
                }
index 3f116b6eccd1a2d1c58d4fe5a251467584b488d2..6f4ebf0a63c6761da07e62d0ae2ccc08a02b9b38 100644 (file)
@@ -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 );
index 56c0afe37eb9753bbb6f1e36f94e57c842f0928c..9a55fc277b638713b1f19a7cc37c2c6f57cd37e2 100644 (file)
@@ -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;
                }
index 49d4c544e062385113534fbd431bd44387961b8d..a70cb37d31a7a436e8dd4d16e4385feda1c770bf 100644 (file)
@@ -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
index 6eb8eea57034f81b0840df2585ae18c3fe5ee995..433cb9d9e46696f6647f929e16a54166713976ab 100644 (file)
 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; }
index 6ab1017b5340210ce48b78edc3b894b869d9d14a..a9b82c60156894c8fa82065801493fb3b0a1dccb 100644 (file)
@@ -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
 
index 03d91a25a90bf15621989a8235581e072b2ead8a..3bb5fc93f7384b519d413beff0c8aeb26f279a20 100644 (file)
@@ -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