From 9647ccd9456b8781066dbba5a063bf6c6c9dab6d Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Thu, 18 Dec 2003 06:52:39 +0000 Subject: [PATCH] Completely untested built-in EXTERNAL implementation Needs identity mapping and proxy authorization support --- servers/slapd/connection.c | 6 +- servers/slapd/daemon.c | 28 +++++---- servers/slapd/proto-slap.h | 4 +- servers/slapd/sasl.c | 123 ++++++++++++++++++++++++++++++------- servers/slapd/slap.h | 2 +- 5 files changed, 122 insertions(+), 41 deletions(-) diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index dfd4852eb1..89233912eb 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -362,7 +362,7 @@ long connection_init( const char* peername, int flags, slap_ssf_t ssf, - const char *authid ) + struct berval *authid ) { unsigned long id; Connection *c; @@ -1336,8 +1336,8 @@ int connection_read(ber_socket_t s) s, rc, c->c_connid ); #endif } - slap_sasl_external( c, c->c_tls_ssf, authid.bv_val ); - if ( authid.bv_val ) free( authid.bv_val ); + slap_sasl_external( c, c->c_tls_ssf, &authid ); + if ( authid.bv_val ) free( authid.bv_val ); } /* if success and data is ready, fall thru to data input loop */ diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index e8bab26736..b0db47f765 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1493,7 +1493,7 @@ slapd_daemon_task( socklen_t len = sizeof(from); long id; slap_ssf_t ssf = 0; - char *authid = NULL; + struct berval authid = { 0, NULL }; #ifdef SLAPD_RLOOKUPS char hbuf[NI_MAXHOST]; #endif @@ -1501,11 +1501,12 @@ slapd_daemon_task( char *dnsname = NULL; char *peeraddr = NULL; #ifdef LDAP_PF_LOCAL - char peername[MAXPATHLEN + sizeof("PATH=")]; + char peername[MAXPATHLEN + sizeof("PATH=")]; #elif defined(LDAP_PF_INET6) - char peername[sizeof("IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")]; + char peername[sizeof( + "IP=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535")]; #else - char peername[sizeof("IP=255.255.255.255:65336")]; + char peername[sizeof("IP=255.255.255.255:65336")]; #endif /* LDAP_PF_LOCAL */ peername[0] = '\0'; @@ -1523,10 +1524,10 @@ slapd_daemon_task( * of the slapd. */ if ( slap_listeners[l]->sl_is_udp < 2 ) { - id = connection_init( - slap_listeners[l]->sl_sd, - slap_listeners[l], "", "", - CONN_IS_UDP, ssf, authid ); + id = connection_init( + slap_listeners[l]->sl_sd, + slap_listeners[l], "", "", + CONN_IS_UDP, ssf, NULL ); slap_listeners[l]->sl_is_udp++; } continue; @@ -1669,10 +1670,11 @@ slapd_daemon_task( gid_t gid; if( getpeereid( s, &uid, &gid ) == 0 ) { - authid = ch_malloc( + authid.bv_val = ch_malloc( sizeof("uidnumber=4294967295+gidnumber=4294967295," - "cn=peercred,cn=external,cn=auth")); - sprintf(authid, "uidnumber=%d+gidnumber=%d," + "cn=peercred,cn=external,cn=auth")); + authid.bv_len = sprintf( authid.bv_val, + "uidnumber=%d+gidnumber=%d," "cn=peercred,cn=external,cn=auth", (int) uid, (int) gid); } @@ -1761,9 +1763,9 @@ slapd_daemon_task( 0, #endif ssf, - authid ); + authid.bv_val ? &authid : NULL ); - if( authid ) ch_free(authid); + if( authid.bv_val ) ch_free(authid.bv_val); if( id < 0 ) { #ifdef NEW_LOGGING diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 86078658ae..c83caf886f 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -353,7 +353,7 @@ LDAP_SLAPD_F (long) connection_init LDAP_P(( const char* peername, int use_tls, slap_ssf_t ssf, - const char *id )); + struct berval *id )); LDAP_SLAPD_F (void) connection_closing LDAP_P(( Connection *c )); LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c )); @@ -958,7 +958,7 @@ LDAP_SLAPD_F (char **) slap_sasl_mechs( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_external( Connection *c, slap_ssf_t ssf, /* relative strength of external security */ - const char *authid ); /* asserted authenication id */ + struct berval *authid ); /* asserted authenication id */ LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_close( Connection *c ); diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index e2d91d2d22..14ed0b64c0 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -44,17 +44,28 @@ # define SASL_CONST # endif -static sasl_security_properties_t sasl_secprops; - #define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP) -#endif /* HAVE_CYRUS_SASL */ +static sasl_security_properties_t sasl_secprops; +#else +/* + * built-in SASL implementation + * only supports EXTERNAL + */ +typedef struct sasl_ctx { + slap_ssf_t sc_external_ssf; + struct berval sc_external_id; +} SASL_CTX; + +#endif #include "ldap_pvt.h" #include "lber_pvt.h" #include +static struct berval ext_bv = BER_BVC( "EXTERNAL" ); + int slap_sasl_config( int cargc, char **cargv, char *line, const char *fname, int lineno ) { @@ -1098,7 +1109,8 @@ int slap_sasl_init( void ) sasl_version( NULL, &rc ); if ( ((rc >> 16) != ((SASL_VERSION_MAJOR << 8)|SASL_VERSION_MINOR)) || - (rc & 0xffff) < SASL_VERSION_STEP) { + (rc & 0xffff) < SASL_VERSION_STEP) + { char version[sizeof("xxx.xxx.xxxxx")]; sprintf( version, "%u.%d.%d", (unsigned)rc >> 24, (rc >> 16) & 0xff, rc & 0xffff ); @@ -1163,7 +1175,6 @@ int slap_sasl_init( void ) 0, 0, 0 ); #endif - /* default security properties */ memset( &sasl_secprops, '\0', sizeof(sasl_secprops) ); sasl_secprops.max_ssf = INT_MAX; @@ -1187,15 +1198,17 @@ int slap_sasl_destroy( void ) int slap_sasl_open( Connection *conn, int reopen ) { - int cb, sc = LDAP_SUCCESS; -#if SASL_VERSION_MAJOR >= 2 - char *ipremoteport = NULL, *iplocalport = NULL; -#endif - + int sc = LDAP_SUCCESS; #ifdef HAVE_CYRUS_SASL + int cb; + sasl_conn_t *ctx = NULL; sasl_callback_t *session_callbacks; +#if SASL_VERSION_MAJOR >= 2 + char *ipremoteport = NULL, *iplocalport = NULL; +#endif + assert( conn->c_sasl_authctx == NULL ); if ( !reopen ) { @@ -1325,14 +1338,26 @@ int slap_sasl_open( Connection *conn, int reopen ) } sc = slap_sasl_err2ldap( sc ); + +#else + /* built-in SASL implementation */ + SASL_CTX *ctx = (SASL_CTX *) SLAP_MALLOC(sizeof(SASL_CTX)); + if( ctx == NULL ) return -1; + + ctx->sc_external_ssf = 0; + ctx->sc_external_id.bv_len = 0; + ctx->sc_external_id.bv_val = NULL; + + conn->c_sasl_authctx = ctx; #endif + return sc; } int slap_sasl_external( Connection *conn, slap_ssf_t ssf, - const char *auth_id ) + struct berval *auth_id ) { #if SASL_VERSION_MAJOR >= 2 int sc; @@ -1348,7 +1373,8 @@ int slap_sasl_external( return LDAP_OTHER; } - sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, auth_id ); + sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, + auth_id ? auth_id->bv_val : NULL ); if ( sc != SASL_OK ) { return LDAP_OTHER; @@ -1365,7 +1391,7 @@ int slap_sasl_external( memset( &extprops, '\0', sizeof(extprops) ); extprops.ssf = ssf; - extprops.auth_id = (char *) auth_id; + extprops.auth_id = auth_id ? auth_id->bv_val : NULL; sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); @@ -1373,6 +1399,20 @@ int slap_sasl_external( if ( sc != SASL_OK ) { return LDAP_OTHER; } +#else + /* built-in SASL implementation */ + SASL_CTX *ctx = conn->c_sasl_authctx; + if ( ctx == NULL ) return LDAP_UNAVAILABLE; + + ctx->sc_external_ssf = ssf; + if( auth_id ) { + ctx->sc_external_id = *auth_id; + auth_id->bv_len = 0; + auth_id->bv_val = NULL; + } else { + ctx->sc_external_id.bv_len = 0; + ctx->sc_external_id.bv_val = NULL; + } #endif return LDAP_SUCCESS; @@ -1418,6 +1458,13 @@ char ** slap_sasl_mechs( Connection *conn ) ch_free( mechstr ); #endif } +#else + /* builtin SASL implementation */ + SASL_CTX *ctx = conn->c_sasl_authctx; + if ( ctx != NULL && ctx->sc_external_id.bv_val ) { + /* should check ssf */ + mechs = ldap_str2charray( "EXTERNAL", "," ); + } #endif return mechs; @@ -1431,7 +1478,9 @@ int slap_sasl_close( Connection *conn ) if( ctx != NULL ) { sasl_dispose( &ctx ); } - if ( conn->c_sasl_sockctx && conn->c_sasl_authctx != conn->c_sasl_sockctx ) { + if ( conn->c_sasl_sockctx && + conn->c_sasl_authctx != conn->c_sasl_sockctx ) + { ctx = conn->c_sasl_sockctx; sasl_dispose( &ctx ); } @@ -1442,6 +1491,17 @@ int slap_sasl_close( Connection *conn ) free( conn->c_sasl_extra ); conn->c_sasl_extra = NULL; + +#else + SASL_CTX *ctx = conn->c_sasl_authctx; + if( ctx ) { + if( ctx->sc_external_id.bv_val ) { + free( ctx->sc_external_id.bv_val ); + ctx->sc_external_id.bv_val = NULL; + } + free( ctx ); + conn->c_sasl_authctx = NULL; + } #endif return LDAP_SUCCESS; @@ -1471,7 +1531,6 @@ int slap_sasl_bind( Operation *op, SlapReply *rs ) op->orb_cred.bv_len ); #endif - if( ctx == NULL ) { send_ldap_error( op, rs, LDAP_UNAVAILABLE, "SASL unavailable on this session" ); @@ -1602,8 +1661,32 @@ int slap_sasl_bind( Operation *op, SlapReply *rs ) #else - send_ldap_error( op, rs, LDAP_UNAVAILABLE, - "SASL not supported" ); + /* built-in SASL implementation */ + SASL_CTX *ctx = op->o_conn->c_sasl_authctx; + + if ( ctx == NULL ) { + send_ldap_error( op, rs, LDAP_OTHER, + "Internal SASL Error" ); + + } else if ( bvmatch( &ext_bv, &op->o_conn->c_sasl_bind_mech ) ) { + /* EXTERNAL */ + + if( op->orb_cred.bv_len ) { + rs->sr_text = "proxy authorization not support"; + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + send_ldap_result( op, rs ); + + } else { + op->orb_edn = ctx->sc_external_id; + rs->sr_err = LDAP_SUCCESS; + rs->sr_sasldata = NULL; + send_ldap_sasl( op, rs ); + } + + } else { + send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED, + "requested SASL mechanism not supported" ); + } #endif return rs->sr_err; @@ -1709,8 +1792,6 @@ done: #define SET_DN 1 #define SET_U 2 -static struct berval ext_bv = BER_BVC( "EXTERNAL" ); - int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len, char *user_realm, struct berval *dn, int flags ) { @@ -1759,9 +1840,7 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len, * is already normalized, so copy it and skip normalization. */ if( flags & SLAP_GETDN_AUTHCID ) { - if( mech->bv_len == ext_bv.bv_len && - strcasecmp( ext_bv.bv_val, mech->bv_val ) == 0 ) - { + if( bvmatch( mech, &ext_bv )) { /* EXTERNAL DNs are already normalized */ do_norm = 0; is_dn = SET_DN; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 99beb433f9..357858ddfa 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1085,7 +1085,7 @@ typedef enum slap_style_e { } slap_style_t; typedef struct slap_authz_info { - ber_tag_t sai_method; /* LDAP_AUTH_* from */ + ber_tag_t sai_method; /* LDAP_AUTH_* from */ struct berval sai_mech; /* SASL Mechanism */ struct berval sai_dn; /* DN for reporting purposes */ struct berval sai_ndn; /* Normalized DN */ -- 2.39.5