From 2e13824d0d07b4eb8d91c4e3d785000d7410c073 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 8 Sep 2000 22:59:01 +0000 Subject: [PATCH] Add "allow tls_2_anon" to allow StartTLS to force session to anonymous. Add "disallow tls_authc" to disallow StartTLS when session is authenticated. Create and use connection2anonymous routine for consistency. --- doc/man/man5/slapd.conf.5 | 11 ++++++++++ servers/slapd/bind.c | 23 ++------------------- servers/slapd/config.c | 41 ++++++++++++++++++++++++++++++++++++- servers/slapd/connection.c | 39 ++++++++++++++++++++++++----------- servers/slapd/proto-slap.h | 3 +++ servers/slapd/slap.h | 8 +++++++- servers/slapd/starttls.c | 15 ++++++++++++++ servers/slapd/tools/mimic.c | 4 ++++ 8 files changed, 109 insertions(+), 35 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 064b6b2f9a..25563576ee 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -72,6 +72,13 @@ attributes (specified by ) by one or more requestors (specified by ). See the "OpenLDAP's Administrator's Guide" for details. .TP +.B allow +Specify a set of features (separated by white space) to allow. +.B tls_2_anon +allows Start TLS to force session to anonymous status (see also +.B disallow +.BR tls_authc ). +.TP .B argsfile The ( absolute ) name of a file that will hold the .B slapd @@ -136,6 +143,10 @@ disables anonymous bind creditials are not empty (e.g. when DN is empty). .B bind_anon_dn disables anonymous bind when DN is not empty. +.B tls_authc +disables StartTLS if authenticated (see also +.B allow +.BR tls_2_anon ). .TP .B idletimeout Specify the number of seconds to wait before forcibly closing diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index e825eeb850..c9a00d9421 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -53,30 +53,11 @@ do_bind( mech = NULL; cred.bv_val = NULL; - ldap_pvt_thread_mutex_lock( &conn->c_mutex ); - /* * Force to connection to "anonymous" until bind succeeds. */ - - if ( conn->c_authmech != NULL ) { - free( conn->c_authmech ); - conn->c_authmech = NULL; - } - - if ( conn->c_cdn != NULL ) { - free( conn->c_cdn ); - conn->c_cdn = NULL; - } - - if ( conn->c_dn != NULL ) { - free( conn->c_dn ); - conn->c_dn = NULL; - } - - conn->c_authc_backend = NULL; - conn->c_authz_backend = NULL; - + ldap_pvt_thread_mutex_lock( &conn->c_mutex ); + connection2anonymous( conn ); ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); if ( op->o_dn != NULL ) { diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 142eb6c864..a95f014157 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -26,6 +26,7 @@ int deftime = SLAPD_DEFAULT_TIMELIMIT; AccessControl *global_acl = NULL; slap_access_t global_default_access = ACL_READ; slap_mask_t global_restrictops = 0; +slap_mask_t global_allows = 0; slap_mask_t global_disallows = 0; slap_mask_t global_requires = 0; slap_ssf_set_t global_ssf_set; @@ -506,6 +507,41 @@ read_config( const char *fname ) } + /* allow these features */ + } else if ( strcasecmp( cargv[0], "allows" ) == 0 || + strcasecmp( cargv[0], "allow" ) == 0 ) + { + slap_mask_t allows; + + if ( be != NULL ) { + Debug( LDAP_DEBUG_ANY, +"%s: line %d: allow line must appear prior to database definitions\n", + fname, lineno, 0 ); + } + + if ( cargc < 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing feature(s) in \"allow \" line\n", + fname, lineno, 0 ); + return( 1 ); + } + + allows = 0; + + for( i=1; i < cargc; i++ ) { + if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) { + allows |= SLAP_ALLOW_TLS_2_ANON; + + } else if( strcasecmp( cargv[i], "none" ) != 0 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unknown feature %s in \"allow \" line\n", + fname, lineno, cargv[i] ); + return( 1 ); + } + } + + global_allows = allows; + /* disallow these features */ } else if ( strcasecmp( cargv[0], "disallows" ) == 0 || strcasecmp( cargv[0], "disallow" ) == 0 ) @@ -520,7 +556,7 @@ read_config( const char *fname ) if ( cargc < 2 ) { Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing feature(s) in \"disallows \" line\n", + "%s: line %d: missing feature(s) in \"disallow \" line\n", fname, lineno, 0 ); return( 1 ); } @@ -540,6 +576,9 @@ read_config( const char *fname ) } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) { disallows |= SLAP_DISALLOW_BIND_ANON_DN; + } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) { + disallows |= SLAP_DISALLOW_TLS_AUTHC; + } else if( strcasecmp( cargv[i], "none" ) != 0 ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: unknown feature %s in \"disallow \" line\n", diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index e41e239d31..d03a7c9a79 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -473,6 +473,30 @@ long connection_init( return id; } +void connection2anonymous( Connection *c ) +{ + assert( connections != NULL ); + assert( c != NULL ); + + if(c->c_authmech != NULL ) { + free(c->c_authmech); + c->c_authmech = NULL; + } + + if(c->c_dn != NULL) { + free(c->c_dn); + c->c_dn = NULL; + } + + if(c->c_cdn != NULL) { + free(c->c_cdn); + c->c_cdn = NULL; + } + + c->c_authc_backend = NULL; + c->c_authz_backend = NULL; +} + static void connection_destroy( Connection *c ) { @@ -492,22 +516,13 @@ connection_destroy( Connection *c ) c->c_activitytime = c->c_starttime = 0; - if(c->c_authmech != NULL ) { - free(c->c_authmech); - c->c_authmech = NULL; - } - if(c->c_dn != NULL) { - free(c->c_dn); - c->c_dn = NULL; - } - if(c->c_cdn != NULL) { - free(c->c_cdn); - c->c_cdn = NULL; - } + connection2anonymous( c ); + if(c->c_listener_url != NULL) { free(c->c_listener_url); c->c_listener_url = NULL; } + if(c->c_peer_domain != NULL) { free(c->c_peer_domain); c->c_peer_domain = NULL; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index c324adf296..1172140607 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -286,6 +286,8 @@ LDAP_SLAPD_F (Connection *) connection_first LDAP_P((ber_socket_t *)); LDAP_SLAPD_F (Connection *) connection_next LDAP_P((Connection *, ber_socket_t *)); LDAP_SLAPD_F (void) connection_done LDAP_P((Connection *)); +LDAP_SLAPD_F (void) connection2anonymous LDAP_P((Connection *)); + /* * dn.c */ @@ -753,6 +755,7 @@ LDAP_SLAPD_F (int) krbv4_ldap_auth(); */ LDAP_SLAPD_F (slap_mask_t) global_restrictops; +LDAP_SLAPD_F (slap_mask_t) global_allows; LDAP_SLAPD_F (slap_mask_t) global_disallows; LDAP_SLAPD_F (slap_mask_t) global_requires; LDAP_SLAPD_F (slap_ssf_set_t) global_ssf_set; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 76bf82d2ff..f986489477 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -854,6 +854,8 @@ struct slap_backend_db { | SLAP_RESTRICT_OP_MODIFY \ | SLAP_RESTRICT_OP_RENAME ) +#define SLAP_ALLOW_TLS_2_ANON 0x0001U /* StartTLS -> Anonymous */ + #define SLAP_DISALLOW_BIND_V2 0x0001U /* LDAPv2 bind */ #define SLAP_DISALLOW_BIND_ANON 0x0002U /* no anonymous */ #define SLAP_DISALLOW_BIND_ANON_CRED \ @@ -861,6 +863,11 @@ struct slap_backend_db { #define SLAP_DISALLOW_BIND_ANON_DN \ 0x0008U /* dn should be empty */ +#define SLAP_DISALLOW_BIND_SIMPLE 0x0010U /* simple authentication */ +#define SLAP_DISALLOW_BIND_KERBEROS 0x0020U /* Kerberos authentication */ + +#define SLAP_DISALLOW_TLS_AUTHC 0x0100U /* TLS while authenticated */ + slap_mask_t be_requires; /* pre-operation requirements */ #define SLAP_REQUIRE_BIND 0x0001U /* bind before op */ #define SLAP_REQUIRE_LDAP_V3 0x0002U /* LDAPv3 before op */ @@ -868,7 +875,6 @@ struct slap_backend_db { #define SLAP_REQUIRE_SASL 0x0008U /* SASL before op */ #define SLAP_REQUIRE_STRONG 0x0010U /* strong authentication before op */ - /* Required Security Strength Factor */ slap_ssf_set_t be_ssf_set; diff --git a/servers/slapd/starttls.c b/servers/slapd/starttls.c index bd12f32c73..97bbab084a 100644 --- a/servers/slapd/starttls.c +++ b/servers/slapd/starttls.c @@ -59,6 +59,21 @@ starttls_extop ( goto done; } + if ( ( global_disallows & SLAP_DISALLOW_TLS_AUTHC ) && + ( conn->c_dn != NULL ) ) + { + *text = "cannot start TLS after authentication"; + rc = LDAP_OPERATIONS_ERROR; + goto done; + } + + if ( ( global_allows & SLAP_ALLOW_TLS_2_ANON ) && + ( conn->c_dn != NULL ) ) + { + /* force to anonymous */ + connection2anonymous( conn ); + } + /* fail if TLS could not be initialized */ if (ldap_pvt_tls_get_option(NULL, LDAP_OPT_X_TLS_CERT, &ctx) != 0 || ctx == NULL) diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index 2398308aca..555a1b31cc 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -152,3 +152,7 @@ char * slap_sasl_secprops( const char *in ) return NULL; } +void connection2anonymous( Connection *c ) +{ + assert(0); +} -- 2.39.5