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_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_NATIVE_AUTHZ 0x01
int la_flags;
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
};
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;
* we have to live with the fact that a user can
* 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
@ -403,14 +403,15 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
* control to every operation with the dn bound
* to the connection as control value.
*/
if ( op->o_conn != NULL
&& ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) {
if ( op->o_conn != NULL && ( ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) )
{
struct berval binddn = slap_empty_bv;
struct berval bindcred = slap_empty_bv;
int dobind = 0;
/* bind as proxyauthzdn only if no idassert mode is requested,
* or if the client's identity is authorized */
/* bind as proxyauthzdn only if no idassert mode
* is requested, 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 ) ) {
@ -448,10 +449,8 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
struct berval authzID = BER_BVNULL;
int freeauthz = 0;
#ifdef LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ
/* if SASL supports native authz, prepare for it */
if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) {
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
@ -463,6 +462,12 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
break;
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_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
@ -474,9 +479,7 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
default:
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 ( sasl_secprops != NULL ) {
@ -760,8 +763,8 @@ ldap_back_proxy_authz_ctrl(
* be performed with "proxyauthzdn" privileges.
*
* This might actually be too strict, since
* the "proxyauthzdn" saslAuthzTo, and each entry's
* saslAuthzFrom attributes may be crafted
* the "proxyauthzdn" authzTo, and each entry's
* authzFrom attributes may be crafted
* to avoid unwanted proxyAuthz to take place.
*/
#if 0
@ -784,14 +787,12 @@ ldap_back_proxy_authz_ctrl(
}
} 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 ) {
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_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 ) )
{
/* already asserted in SASL via native authz */
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 ) {
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 ) {
case LDAP_BACK_IDASSERT_LEGACY:
case LDAP_BACK_IDASSERT_SELF:
/* original behavior:
* 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;
case LDAP_BACK_IDASSERT_ANONYMOUS:

View File

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

View File

@ -118,9 +118,8 @@ ldap_back_db_init(
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;
#endif /* LDAP_BACK_HOW_TO_DETECT_SASL_NATIVE_AUTHZ */
#endif /* LDAP_BACK_PROXY_AUTHZ */
#ifdef ENABLE_REWRITE