make authz mode selection fully manual, plus more cleanup

This commit is contained in:
Pierangelo Masarati 2004-06-20 22:42:36 +00:00
parent 176e5542bb
commit 5bfb9fd590
4 changed files with 60 additions and 39 deletions

View File

@ -94,15 +94,9 @@ struct ldapauth {
struct berval la_sasl_mech; struct berval la_sasl_mech;
struct berval la_sasl_realm; struct berval la_sasl_realm;
/* FIXME: required until I find a nice way to determine
* whether a SASL mechanism is able to authz natively */
#define LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
#define LDAP_BACK_AUTH_NONE 0x00 #define LDAP_BACK_AUTH_NONE 0x00
#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01 #define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01
int la_flags; int la_flags;
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
}; };
struct ldapinfo { struct ldapinfo {

View File

@ -389,7 +389,7 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
* otherwise we cannot do symmetric pools of servers; * otherwise we cannot do symmetric pools of servers;
* we have to live with the fact that a user can * we have to live with the fact that a user can
* authorize itself as any ID that is allowed * authorize itself as any ID that is allowed
* by the saslAuthzTo directive of the "proxyauthzdn". * by the authzTo directive of the "proxyauthzdn".
*/ */
/* /*
* NOTE: current Proxy Authorization specification * NOTE: current Proxy Authorization specification
@ -403,14 +403,15 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
* control to every operation with the dn bound * control to every operation with the dn bound
* to the connection as control value. * to the connection as control value.
*/ */
if ( op->o_conn != NULL if ( op->o_conn != NULL && ( ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) )
&& ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) { {
struct berval binddn = slap_empty_bv; struct berval binddn = slap_empty_bv;
struct berval bindcred = slap_empty_bv; struct berval bindcred = slap_empty_bv;
int dobind = 0; int dobind = 0;
/* bind as proxyauthzdn only if no idassert mode is requested, /* bind as proxyauthzdn only if no idassert mode
* or if the client's identity is authorized */ * is requested, or if the client's identity
* is authorized */
switch ( li->idassert_mode ) { switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY: case LDAP_BACK_IDASSERT_LEGACY:
if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) ) { if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
@ -448,10 +449,8 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
struct berval authzID = BER_BVNULL; struct berval authzID = BER_BVNULL;
int freeauthz = 0; int freeauthz = 0;
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
/* if SASL supports native authz, prepare for it */ /* if SASL supports native authz, prepare for it */
if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) { if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
switch ( li->idassert_mode ) { switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN: case LDAP_BACK_IDASSERT_OTHERDN:
@ -463,6 +462,12 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
break; break;
case LDAP_BACK_IDASSERT_SELF: case LDAP_BACK_IDASSERT_SELF:
if ( BER_BVISNULL( &op->o_conn->c_dn ) ) {
/* connection is not authc'd, so don't idassert */
/* FIXME: cyrus-sasl doesn't honor empty authzID!
* i.e. NULL is equivalent to ""! */
break;
}
authzID.bv_len = STRLENOF( "dn:" ) + op->o_conn->c_dn.bv_len; authzID.bv_len = STRLENOF( "dn:" ) + op->o_conn->c_dn.bv_len;
authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx ); authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
@ -474,9 +479,7 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
default: default:
break; break;
} }
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
} }
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
#if 0 /* will deal with this later... */ #if 0 /* will deal with this later... */
if ( sasl_secprops != NULL ) { if ( sasl_secprops != NULL ) {
@ -760,8 +763,8 @@ ldap_back_proxy_authz_ctrl(
* be performed with "proxyauthzdn" privileges. * be performed with "proxyauthzdn" privileges.
* *
* This might actually be too strict, since * This might actually be too strict, since
* the "proxyauthzdn" saslAuthzTo, and each entry's * the "proxyauthzdn" authzTo, and each entry's
* saslAuthzFrom attributes may be crafted * authzFrom attributes may be crafted
* to avoid unwanted proxyAuthz to take place. * to avoid unwanted proxyAuthz to take place.
*/ */
#if 0 #if 0
@ -784,14 +787,12 @@ ldap_back_proxy_authz_ctrl(
} }
} else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) { } else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) {
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ if ( ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) { && !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) )
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */ {
/* already asserted in SASL via native authz */ /* already asserted in SASL via native authz */
goto done; goto done;
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
} }
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
} else if ( li->idassert_authz ) { } else if ( li->idassert_authz ) {
int rc; int rc;
@ -807,12 +808,37 @@ ldap_back_proxy_authz_ctrl(
} }
} }
if ( op->o_proxy_authz ) {
/*
* FIXME: we can:
* 1) ignore the already set proxyAuthz control
* 2) leave it in place, and don't set ours
* 3) add both
* 4) reject the operation
*
* option (4) is very drastic
* option (3) will make the remote server reject
* the operation, thus being equivalent to (4)
* option (2) will likely break the idassert
* assumptions, so we cannot accept it;
* option (1) means that we are contradicting
* the client's reques.
*
* I think (4) is the only correct choice.
*/
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
rs->sr_text = "proxyAuthz not allowed within namingContext";
}
switch ( li->idassert_mode ) { switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY: case LDAP_BACK_IDASSERT_LEGACY:
case LDAP_BACK_IDASSERT_SELF: case LDAP_BACK_IDASSERT_SELF:
/* original behavior: /* original behavior:
* assert the client's identity */ * assert the client's identity */
assertedID = op->o_conn->c_dn; /* FIXME: we may get here if binding anonymously,
* because cyrus sasl doesn't honor empty (i.e. "")
* authzID */
assertedID = BER_BVISNULL( &op->o_conn->c_dn ) ? slap_empty_bv : op->o_conn->c_dn;
break; break;
case LDAP_BACK_IDASSERT_ANONYMOUS: case LDAP_BACK_IDASSERT_ANONYMOUS:

View File

@ -735,10 +735,14 @@ parse_idassert(
/* name to use for proxyAuthz propagation */ /* name to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0 } else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
|| strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) { || strcasecmp( argv[0], "proxyauthzdn" ) == 0 )
{
struct berval dn; struct berval dn;
int rc; int rc;
/* FIXME: "proxyauthzdn" is no longer documented, and
* temporarily supported for backwards compatibility */
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, fprintf( stderr,
"%s: line %d: missing name in \"%s <name>\" line\n", "%s: line %d: missing name in \"%s <name>\" line\n",
@ -770,7 +774,11 @@ parse_idassert(
/* password to use for proxyAuthz propagation */ /* password to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0 } else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
|| strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) { || strcasecmp( argv[0], "proxyauthzpw" ) == 0 )
{
/* FIXME: "proxyauthzpw" is no longer documented, and
* temporarily supported for backwards compatibility */
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, fprintf( stderr,
"%s: line %d: missing password in \"%s <password>\" line\n", "%s: line %d: missing password in \"%s <password>\" line\n",
@ -788,7 +796,7 @@ parse_idassert(
ber_str2bv( argv[1], 0, 1, &li->idassert_passwd ); ber_str2bv( argv[1], 0, 1, &li->idassert_passwd );
/* rules to accept identity assertion... */ /* rules to accept identity assertion... */
} else if ( strcasecmp( argv[0], "idassert-authz" ) == 0 ) { } else if ( strcasecmp( argv[0], "idassert-authzFrom" ) == 0 ) {
struct berval rule; struct berval rule;
ber_str2bv( argv[1], 0, 1, &rule ); ber_str2bv( argv[1], 0, 1, &rule );
@ -838,13 +846,6 @@ parse_idassert(
} }
ber_str2bv( val, 0, 1, &li->idassert_sasl_mech ); ber_str2bv( val, 0, 1, &li->idassert_sasl_mech );
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
/* mechs that are known to support native authz... */
if ( strcasecmp( li->idassert_sasl_mech.bv_val, "DIGEST-MD5" ) == 0 ) {
li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
}
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
} else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) { } else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "realm=" ); char *val = argv[arg] + STRLENOF( "realm=" );
@ -911,20 +912,21 @@ parse_idassert(
} }
ber_str2bv( val, 0, 1, &li->idassert_passwd ); ber_str2bv( val, 0, 1, &li->idassert_passwd );
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
} else if ( strncasecmp( argv[arg], "authz=", STRLENOF( "authz=" ) ) == 0 ) { } else if ( strncasecmp( argv[arg], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
char *val = argv[arg] + STRLENOF( "authz=" ); char *val = argv[arg] + STRLENOF( "authz=" );
if ( strcasecmp( val, "native" ) == 0 ) { if ( strcasecmp( val, "proxyauthz" ) == 0 ) {
li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
} else if ( strcasecmp( val, "native" ) == 0 ) {
li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ; li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
} else { } else {
fprintf( stderr, "%s: line %s: " fprintf( stderr, "%s: line %s: "
"unknown SASL flag \"%s\"\n", "unknown authz mode \"%s\"\n",
fname, lineno, val ); fname, lineno, val );
return 1; return 1;
} }
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
} else { } else {
fprintf( stderr, "%s: line %d: " fprintf( stderr, "%s: line %d: "

View File

@ -118,9 +118,8 @@ ldap_back_db_init(
li->idassert_ppolicy = 0; li->idassert_ppolicy = 0;
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ /* by default, use proxyAuthz control on each operation */
li->idassert_flags = LDAP_BACK_AUTH_NONE; li->idassert_flags = LDAP_BACK_AUTH_NONE;
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
#endif /* LDAP_BACK_PROXY_AUTHZ */ #endif /* LDAP_BACK_PROXY_AUTHZ */
#ifdef ENABLE_REWRITE #ifdef ENABLE_REWRITE