From 5bfb9fd5901720f1f6b7d65d927c97a1fe72c9b1 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sun, 20 Jun 2004 22:42:36 +0000 Subject: [PATCH] make authz mode selection fully manual, plus more cleanup --- servers/slapd/back-ldap/back-ldap.h | 6 --- servers/slapd/back-ldap/bind.c | 60 +++++++++++++++++++++-------- servers/slapd/back-ldap/config.c | 30 ++++++++------- servers/slapd/back-ldap/init.c | 3 +- 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 631e4d0af1..55358621b0 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -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 { diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 15361d60a1..a2f1194f30 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -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: diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 89408dc1ed..44167c6a76 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -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 \" 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 \" 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: " diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 028ff3c2fd..e7f2fdd42e 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -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 -- 2.39.5