From 4a5498351e32070d150c49ac0dcd33ff510fc2fa Mon Sep 17 00:00:00 2001 From: Mark Adamson Date: Thu, 17 Aug 2000 16:30:37 +0000 Subject: [PATCH] Added SASL authentication to slurpd for connecting to slave LDAP servers. --- doc/man/man5/slapd.conf.5 | 30 ++++++++++++++++++++++++------ servers/slurpd/config.c | 37 +++++++++++++++++++++++++++++-------- servers/slurpd/ldap_op.c | 23 ++++++++++++++++++++++- servers/slurpd/ri.c | 2 +- servers/slurpd/slurp.h | 12 +++++++++--- 5 files changed, 85 insertions(+), 19 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index a86c8aa22d..d83e0321d8 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -285,14 +285,32 @@ This option puts the database into "read-only" mode. Any attempts to modify the database will return an "unwilling to perform" error. By default, readonly is off. .HP -.B replica host=[:port] "binddn=" bindmethod=simple |\ - kerberos [credentials=] [srvtab= ] +.B replica host=[:port] bindmethod=simple|sasl +.B [binddn=] [credentials=] +.B [saslmech=] [authcId=] .RS -Specify a replication site for this database. Refer to "The SLAPD and -SLURPD Administrator's Guide" for detailed information on setting up -a replicated +Specify a replication site for this database. Refer to "The OpenLDAP +Administrator's Guide" for detailed information on setting up a replicated .B slapd -directory service. +directory service. A +.B bindmethod +of +.B simple +requires the options +.B binddn +and +.B credentials +and should only be used when adequate security services +(e.g TLS or IPSEC) are in place. A +.B bindmethod +of +.B sasl +requires the option +.B saslmech. +If the +.B mechanism +will use Kerberos, a kerberos instance should be given in +.B authcId. .RE .TP .B replogfile diff --git a/servers/slurpd/config.c b/servers/slurpd/config.c index 670ceeb8ae..e14a9e9f3c 100644 --- a/servers/slurpd/config.c +++ b/servers/slurpd/config.c @@ -319,6 +319,8 @@ add_replica( #define GOT_DN 2 #define GOT_METHOD 4 #define GOT_ALL ( GOT_HOST | GOT_DN | GOT_METHOD ) +#define GOT_MECH 8 + static int parse_replica_line( char **cargv, @@ -359,15 +361,26 @@ parse_replica_line( } else if ( !strcasecmp( val, SIMPLESTR )) { ri->ri_bind_method = AUTH_SIMPLE; gots |= GOT_METHOD; + } else if ( !strcasecmp( val, SASLSTR )) { + ri->ri_bind_method = AUTH_SASL; + gots |= GOT_METHOD; } else { ri->ri_bind_method = -1; } + } else if ( !strncasecmp( cargv[ i ], SASLMECHSTR, strlen( SASLMECHSTR ))) { + val = cargv[ i ] + strlen( SASLMECHSTR ) + 1; + gots |= GOT_MECH; + ri->ri_saslmech = strdup( val ); } else if ( !strncasecmp( cargv[ i ], CREDSTR, strlen( CREDSTR ))) { val = cargv[ i ] + strlen( CREDSTR ) + 1; ri->ri_password = strdup( val ); - } else if ( !strncasecmp( cargv[ i ], BINDPSTR, strlen( BINDPSTR ))) { - val = cargv[ i ] + strlen( BINDPSTR ) + 1; - ri->ri_principal = strdup( val ); + } else if ( !strncasecmp( cargv[ i ], AUTHCSTR, strlen( AUTHCSTR ))) { + val = cargv[ i ] + strlen( AUTHCSTR ) + 1; + ri->ri_authcId = strdup( val ); + } else if ( !strncasecmp( cargv[ i ], OLDAUTHCSTR, strlen( OLDAUTHCSTR ))) { + /* Old authcID is provided for some backwards compatibility */ + val = cargv[ i ] + strlen( OLDAUTHCSTR ) + 1; + ri->ri_authcId = strdup( val ); } else if ( !strncasecmp( cargv[ i ], SRVTABSTR, strlen( SRVTABSTR ))) { val = cargv[ i ] + strlen( SRVTABSTR ) + 1; if ( ri->ri_srvtab != NULL ) { @@ -380,11 +393,19 @@ parse_replica_line( cargv[ i ] ); } } - if ( gots != GOT_ALL ) { - fprintf( stderr, "Error: Malformed \"replica\" line in slapd " ); - fprintf( stderr, "config file, line %d\n", lineno ); - return -1; - } + + if ( ri->ri_bind_method == AUTH_SASL) { + if ((gots & GOT_MECH) == 0) { + fprintf( stderr, "Error: \"replica\" line needs SASLmech flag in " ); + fprintf( stderr, "slapd config file, line %d\n", lineno ); + return -1; + } + } + else if ( gots != GOT_ALL ) { + fprintf( stderr, "Error: Malformed \"replica\" line in slapd " ); + fprintf( stderr, "config file, line %d\n", lineno ); + return -1; + } return 0; } diff --git a/servers/slurpd/ldap_op.c b/servers/slurpd/ldap_op.c index 1673a12e78..9662554cdb 100644 --- a/servers/slurpd/ldap_op.c +++ b/servers/slurpd/ldap_op.c @@ -28,7 +28,7 @@ #include #include - +#include "lutil_ldap.h" #include "slurp.h" /* Forward references */ @@ -609,6 +609,8 @@ do_bind( ) { int ldrc; + void *defaults; + *lderr = 0; @@ -691,6 +693,25 @@ do_bind( return( BIND_ERR_SIMPLE_FAILED ); } break; + + case AUTH_SASL: + Debug( LDAP_DEBUG_ARGS, "bind to %s as %s via %s (SASL)\n", + ri->ri_hostname, ri->ri_authcId, ri->ri_saslmech ); + + defaults = lutil_sasl_defaults( ri->ri_ldp, ri->ri_saslmech, + NULL, ri->ri_authcId, NULL, NULL ); + ldrc = ldap_sasl_interactive_bind_s( ri->ri_ldp, ri->ri_bind_dn, + ri->ri_saslmech, NULL, NULL, + LDAP_SASL_AUTOMATIC, lutil_sasl_interact, defaults ); + if ( ldrc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, "Error: LDAP SASL for %s:%d failed: %s\n", + ri->ri_hostname, ri->ri_port, ldap_err2string( ldrc )); + *lderr = ldrc; + ldap_unbind( ri->ri_ldp ); + ri->ri_ldp = NULL; + return( BIND_ERR_SASL_FAILED ); + } + break; default: Debug( LDAP_DEBUG_ANY, "Error: do_bind: unknown auth type \"%d\" for %s:%d\n", diff --git a/servers/slurpd/ri.c b/servers/slurpd/ri.c index 5335943ff5..de6d7b5a88 100644 --- a/servers/slurpd/ri.c +++ b/servers/slurpd/ri.c @@ -177,7 +177,7 @@ Ri_init( (*ri)->ri_bind_method = 0; (*ri)->ri_bind_dn = NULL; (*ri)->ri_password = NULL; - (*ri)->ri_principal = NULL; + (*ri)->ri_authcId = NULL; (*ri)->ri_srvtab = NULL; (*ri)->ri_curr = NULL; diff --git a/servers/slurpd/slurp.h b/servers/slurpd/slurp.h index f1f54b35c0..5b6b19138a 100644 --- a/servers/slurpd/slurp.h +++ b/servers/slurpd/slurp.h @@ -66,9 +66,10 @@ /* Maximum line length we can read from replication log */ #define REPLBUFLEN 256 -/* We support simple (plaintext password) and kerberos authentication */ +/* We support simple (plaintext password) and SASL authentication */ #define AUTH_SIMPLE 1 #define AUTH_KERBEROS 2 +#define AUTH_SASL 3 /* Rejection records are prefaced with this string */ #define ERROR_STR "ERROR" @@ -113,9 +114,12 @@ #define BINDMETHSTR "bindmethod" #define KERBEROSSTR "kerberos" #define SIMPLESTR "simple" +#define SASLSTR "sasl" #define CREDSTR "credentials" -#define BINDPSTR "bindprincipal" +#define OLDAUTHCSTR "bindprincipal" +#define AUTHCSTR "authcID" #define SRVTABSTR "srvtab" +#define SASLMECHSTR "saslmech" #define REPLICA_SLEEP_TIME ( 10 ) @@ -130,6 +134,7 @@ #define BIND_ERR_VERSION 7 #define BIND_ERR_REFERRALS 8 #define BIND_ERR_MANAGEDSAIT 9 +#define BIND_ERR_SASL_FAILED 10 /* Return codes for do_ldap() */ #define DO_LDAP_OK 0 @@ -187,8 +192,9 @@ struct ri { int ri_bind_method; /* AUTH_SIMPLE or AUTH_KERBEROS */ char *ri_bind_dn; /* DN to bind as when replicating */ char *ri_password; /* Password for AUTH_SIMPLE */ - char *ri_principal; /* principal for kerberos bind */ + char *ri_authcId; /* authentication ID for any mechanism */ char *ri_srvtab; /* srvtab file for kerberos bind */ + char *ri_saslmech; /* SASL mechanism to use */ struct re *ri_curr; /* current repl entry being processed */ struct stel *ri_stel; /* pointer to Stel for this replica */ unsigned long -- 2.39.5