more on idassert: SASL bind/authz

This commit is contained in:
Pierangelo Masarati 2004-05-15 10:11:10 +00:00
parent 46b27edc3b
commit cdebc4d376
4 changed files with 315 additions and 56 deletions

View File

@ -89,9 +89,6 @@ struct ldapinfo {
struct berval binddn;
struct berval bindpw;
#ifdef LDAP_BACK_PROXY_AUTHZ
struct berval proxyauthzdn;
struct berval proxyauthzpw;
/* ID assert stuff */
int idassert_mode;
#define LDAP_BACK_IDASSERT_LEGACY 0
@ -100,8 +97,20 @@ struct ldapinfo {
#define LDAP_BACK_IDASSERT_SELF 3
#define LDAP_BACK_IDASSERT_OTHERDN 4
#define LDAP_BACK_IDASSERT_OTHERID 5
struct berval idassert_id;
struct berval idassert_authcID;
struct berval idassert_authcDN;
struct berval idassert_passwd;
struct berval idassert_authzID;
BerVarray idassert_authz;
int idassert_authmethod;
int idassert_sasl_flags;
struct berval idassert_sasl_mech;
struct berval idassert_sasl_realm;
int idassert_ppolicy;
/* end of ID assert stuff */
#endif /* LDAP_BACK_PROXY_AUTHZ */

View File

@ -28,11 +28,12 @@
#include <ac/socket.h>
#include <ac/string.h>
#define AVL_INTERNAL
#include "slap.h"
#include "back-ldap.h"
#include <lutil_ldap.h>
#define PRINT_CONNTREE 0
static LDAP_REBIND_PROC ldap_back_rebind;
@ -408,11 +409,13 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
* or if the client's identity is authorized */
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY:
if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn )
&& !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn ) )
{
binddn = li->proxyauthzdn;
bindcred = li->proxyauthzpw;
if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
if ( li->idassert_authmethod != LDAP_AUTH_SASL
&& !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
{
binddn = li->idassert_authcDN;
bindcred = li->idassert_passwd;
}
}
break;
@ -428,13 +431,85 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
goto done;
}
}
binddn = li->proxyauthzdn;
bindcred = li->proxyauthzpw;
if ( li->idassert_authmethod != LDAP_AUTH_SASL ) {
binddn = li->idassert_authcDN;
}
bindcred = li->idassert_passwd;
break;
}
rs->sr_err = ldap_sasl_bind(lc->ld, binddn.bv_val,
LDAP_SASL_SIMPLE, &bindcred, NULL, NULL, &msgid);
/* NOTE: essentially copied from clients/tools/common.c :) */
switch ( li->idassert_authmethod ) {
#ifdef HAVE_CYRUS_SASL
case LDAP_AUTH_SASL:
{
void *defaults = NULL;
struct berval authzID = BER_BVNULL;
#if 0 /* will deal with this later... */
if ( sasl_secprops != NULL ) {
rs->sr_err = ldap_set_option( lc->ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
send_ldap_result( op, rs );
lc->bound = 0;
goto done;
}
}
#endif
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
authzID = li->idassert_authzID;
}
defaults = lutil_sasl_defaults( lc->ld,
li->idassert_sasl_mech.bv_val,
li->idassert_sasl_realm.bv_val,
li->idassert_authcID.bv_val,
li->idassert_passwd.bv_val,
authzID.bv_val );
rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, NULL,
li->idassert_sasl_mech.bv_val, NULL, NULL,
li->idassert_sasl_flags, lutil_sasl_interact,
defaults );
lutil_sasl_freedefs( defaults );
rs->sr_err = slap_map_api2result( rs );
if ( rs->sr_err != LDAP_SUCCESS ) {
lc->bound = 0;
send_ldap_result( op, rs );
} else {
lc->bound = 1;
}
goto done;
}
#endif /* HAVE_CYRUS_SASL */
case LDAP_AUTH_SIMPLE:
rs->sr_err = ldap_sasl_bind(lc->ld,
binddn.bv_val, LDAP_SASL_SIMPLE,
&bindcred, NULL, NULL, &msgid);
break;
case LDAP_AUTH_NONE:
lc->bound = 1;
goto done;
default:
/* unsupported! */
lc->bound = 0;
rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
send_ldap_result( op, rs );
goto done;
}
} else
#endif /* LDAP_BACK_PROXY_AUTHZ */
@ -639,7 +714,7 @@ ldap_back_proxy_authz_ctrl(
*pctrls = NULL;
if ( BER_BVISNULL( &li->proxyauthzdn ) ) {
if ( BER_BVISNULL( &li->idassert_authcID ) ) {
goto done;
}
@ -674,10 +749,14 @@ ldap_back_proxy_authz_ctrl(
goto done;
}
if ( BER_BVISEMPTY( &li->proxyauthzdn ) ) {
if ( BER_BVISEMPTY( &li->idassert_authcID ) ) {
goto done;
}
} else if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID && li->idassert_authmethod == LDAP_AUTH_SASL ) {
/* already asserted in SASL */
goto done;
} else if ( li->idassert_authz ) {
int rc;
struct berval authcDN = BER_BVISNULL( &op->o_conn->c_dn ) ? slap_empty_bv : op->o_conn->c_dn;
@ -712,7 +791,7 @@ ldap_back_proxy_authz_ctrl(
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
/* assert idassert DN */
assertedID = li->idassert_id;
assertedID = li->idassert_authzID;
break;
default:
@ -729,17 +808,21 @@ ldap_back_proxy_authz_ctrl(
ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
ctrls[ 0 ]->ldctl_iscritical = 1;
/* already in u:ID form */
if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID ) {
switch ( li->idassert_mode ) {
/* already in u:ID or dn:DN form */
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
ber_dupbv( &ctrls[ 0 ]->ldctl_value, &assertedID );
break;
/* needs the dn: prefix */
} else {
default:
ctrls[ 0 ]->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
ctrls[ 0 ]->ldctl_value.bv_val = ch_malloc( ctrls[ 0 ]->ldctl_value.bv_len + 1 );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val + STRLENOF( "dn:" ),
assertedID.bv_val, assertedID.bv_len + 1 );
break;
}
if ( op->o_ctrls ) {

View File

@ -153,28 +153,9 @@ ldap_back_db_config(
ber_str2bv( argv[1], 0, 1, &li->bindpw );
#ifdef LDAP_BACK_PROXY_AUTHZ
/* name to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
if (argc != 2) {
fprintf( stderr,
"%s: line %d: missing name in \"proxyauthzdn <name>\" line\n",
fname, lineno );
return( 1 );
}
ber_str2bv( argv[1], 0, 1, &li->proxyauthzdn );
/* password to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) {
if (argc != 2) {
fprintf( stderr,
"%s: line %d: missing password in \"proxyauthzpw <password>\" line\n",
fname, lineno );
return( 1 );
}
ber_str2bv( argv[1], 0, 1, &li->proxyauthzpw );
/* identity assertion stuff... */
} else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0 ) {
} else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0
|| strncasecmp( argv[0], "proxyauthz", STRLENOF( "proxyauthz" ) ) == 0 ) {
return parse_idassert( be, fname, lineno, argc, argv );
#endif /* LDAP_BACK_PROXY_AUTHZ */
@ -673,6 +654,7 @@ parse_idassert(
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
/* identity assertion mode */
if ( strcasecmp( argv[0], "idassert-mode" ) == 0 ) {
if ( argc != 2 ) {
#ifdef NEW_LOGGING
@ -714,16 +696,18 @@ parse_idassert(
/* force lowercase... */
id.bv_val[0] = 'u';
li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
ber_dupbv( &li->idassert_id, &id );
ber_dupbv( &li->idassert_authzID, &id );
} else {
struct berval dn;
/* default is DN? */
if ( strncasecmp( id.bv_val, "dn:", STRLENOF( "dn:" ) ) == 0 ) {
id.bv_val += STRLENOF( "dn:" );
id.bv_len -= STRLENOF( "dn:" );
}
rc = dnNormalize( 0, NULL, NULL, &id, &li->idassert_id, NULL );
rc = dnNormalize( 0, NULL, NULL, &id, &dn, NULL );
if ( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
@ -737,10 +721,61 @@ parse_idassert(
return 1;
}
li->idassert_authzID.bv_val = ch_malloc( STRLENOF( "dn:" ) + dn.bv_len + 1 );
AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], dn.bv_val, dn.bv_len + 1 );
ch_free( dn.bv_val );
li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
}
}
/* name to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
|| strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: missing name in \"%s <name>\" line\n",
fname, lineno, argv[0] );
return( 1 );
}
if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
fprintf( stderr,
"%s: line %d: authcDN incompatible with previously defined authcID\n",
fname, lineno );
return( 1 );
}
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
fprintf( stderr, "%s: line %d: "
"authcDN already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_authcDN.bv_val );
}
ber_str2bv( argv[1], 0, 1, &li->idassert_authcDN );
/* password to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
|| strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) {
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: missing password in \"%s <password>\" line\n",
fname, lineno, argv[0] );
return( 1 );
}
if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
fprintf( stderr, "%s: line %d: "
"passwd already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_passwd.bv_val );
}
ber_str2bv( argv[1], 0, 1, &li->idassert_passwd );
/* rules to accept identity assertion... */
} else if ( strcasecmp( argv[0], "idassert-authz" ) == 0 ) {
struct berval rule;
@ -748,6 +783,116 @@ parse_idassert(
ber_bvarray_add( &li->idassert_authz, &rule );
} else if ( strcasecmp( argv[0], "idassert-method" ) == 0 ) {
if ( argc < 2 ) {
fprintf( stderr,
"%s: line %d: missing method in \"%s <method>\" line\n",
fname, lineno, argv[0] );
return( 1 );
}
if ( strcasecmp( argv[1], "none" ) == 0 ) {
/* FIXME: is this useful? */
li->idassert_authmethod = LDAP_AUTH_NONE;
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "simple" ) == 0 ) {
li->idassert_authmethod = LDAP_AUTH_SIMPLE;
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "sasl" ) == 0 ) {
#ifdef HAVE_CYRUS_SASL
int arg;
for ( arg = 2; arg < argc; arg++ ) {
if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "mech=" );
if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
fprintf( stderr, "%s: line %d: "
"SASL mech already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_sasl_mech.bv_val );
}
ber_str2bv( val, 0, 1, &li->idassert_sasl_mech );
} else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "realm=" );
if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
fprintf( stderr, "%s: line %d: "
"SASL realm already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_sasl_realm.bv_val );
}
ber_str2bv( val, 0, 1, &li->idassert_sasl_realm );
} else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "authcid=" );
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
fprintf( stderr,
"%s: line %d: SASL authcID incompatible with previously defined authcDN\n",
fname, lineno );
return( 1 );
}
if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
fprintf( stderr, "%s: line %d: "
"SASL authcID already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_authcID.bv_val );
}
if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) {
val += STRLENOF( "u:" );
}
ber_str2bv( val, 0, 1, &li->idassert_authcID );
} else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "cred=" );
if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
fprintf( stderr, "%s: line %d: "
"SASL cred already defined; replacing...\n",
fname, lineno );
ch_free( li->idassert_passwd.bv_val );
}
ber_str2bv( val, 0, 1, &li->idassert_passwd );
} else {
fprintf( stderr, "%s: line %d: "
"unknown SASL parameter %s\n",
fname, lineno, argv[arg] );
return 1;
}
}
li->idassert_authmethod = LDAP_AUTH_SASL;
#else /* !HAVE_CYRUS_SASL */
fprintf( stderr, "%s: line %d: "
"compile --with-cyrus-sasl to enable SASL auth\n",
fname, lineno );
return 1;
#endif /* !HAVE_CYRUS_SASL */
} else {
fprintf( stderr, "%s: line %d: "
"unhandled auth method %s\n",
fname, lineno );
return 1;
}
} else {
return SLAP_CONF_UNKNOWN;
}

View File

@ -102,11 +102,21 @@ ldap_back_db_init(
BER_BVZERO( &li->bindpw );
#ifdef LDAP_BACK_PROXY_AUTHZ
BER_BVZERO( &li->proxyauthzdn );
BER_BVZERO( &li->proxyauthzpw );
li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
BER_BVZERO( &li->idassert_id );
BER_BVZERO( &li->idassert_authcID );
BER_BVZERO( &li->idassert_authcDN );
BER_BVZERO( &li->idassert_passwd );
BER_BVZERO( &li->idassert_authzID );
li->idassert_authz = NULL;
li->idassert_authmethod = LDAP_AUTH_SIMPLE;
li->idassert_sasl_flags = LDAP_SASL_QUIET;
BER_BVZERO( &li->idassert_sasl_mech );
BER_BVZERO( &li->idassert_sasl_realm );
li->idassert_ppolicy = 0;
#endif /* LDAP_BACK_PROXY_AUTHZ */
#ifdef ENABLE_REWRITE
@ -209,17 +219,29 @@ ldap_back_db_destroy(
BER_BVZERO( &li->bindpw );
}
#ifdef LDAP_BACK_PROXY_AUTHZ
if ( !BER_BVISNULL( &li->proxyauthzdn ) ) {
ch_free( li->proxyauthzdn.bv_val );
BER_BVZERO( &li->proxyauthzdn );
if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
ch_free( li->idassert_authcID.bv_val );
BER_BVZERO( &li->idassert_authcID );
}
if ( !BER_BVISNULL( &li->proxyauthzpw ) ) {
ch_free( li->proxyauthzpw.bv_val );
BER_BVZERO( &li->proxyauthzpw );
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
ch_free( li->idassert_authcDN.bv_val );
BER_BVZERO( &li->idassert_authcDN );
}
if ( !BER_BVISNULL( &li->idassert_id ) ) {
ch_free( li->idassert_id.bv_val );
BER_BVZERO( &li->idassert_id );
if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
ch_free( li->idassert_passwd.bv_val );
BER_BVZERO( &li->idassert_passwd );
}
if ( !BER_BVISNULL( &li->idassert_authzID ) ) {
ch_free( li->idassert_authzID.bv_val );
BER_BVZERO( &li->idassert_authzID );
}
if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
ch_free( li->idassert_sasl_mech.bv_val );
BER_BVZERO( &li->idassert_sasl_mech );
}
if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
ch_free( li->idassert_sasl_realm.bv_val );
BER_BVZERO( &li->idassert_sasl_realm );
}
#endif /* LDAP_BACK_PROXY_AUTHZ */
if (li->conntree) {