mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-03 20:40:05 -05:00
Completely untested built-in EXTERNAL implementation
Needs identity mapping and proxy authorization support
This commit is contained in:
parent
e4b899df95
commit
9647ccd945
5 changed files with 122 additions and 41 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue