Completely untested built-in EXTERNAL implementation

Needs identity mapping and proxy authorization support
This commit is contained in:
Kurt Zeilenga 2003-12-18 06:52:39 +00:00
parent e4b899df95
commit 9647ccd945
5 changed files with 122 additions and 41 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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 );

View file

@ -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 <lutil.h>
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;
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
#ifdef HAVE_CYRUS_SASL
sasl_conn_t *ctx = NULL;
sasl_callback_t *session_callbacks;
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;

View file

@ -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 <ldap.h> */
ber_tag_t sai_method; /* LDAP_AUTH_* from <ldap.h> */
struct berval sai_mech; /* SASL Mechanism */
struct berval sai_dn; /* DN for reporting purposes */
struct berval sai_ndn; /* Normalized DN */