diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index be5ddf1c05..53f5b4886b 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -68,21 +68,22 @@ should have read access on the target server to attributes used on the proxy for acl checking. There is no risk of giving away such values; they are only used to check permissions. -.RS -Note: the -.B binddn -/ -.B bindpw -values are also used to propagate user authorization by means of the -.B proxyAuthz -mechanism when operations performed by users bound to another backend -are propagated to back-ldap. +.TP +.B bindpw +Password used with the bind DN above. +.TP +.B proxyauthzdn "" +DN which is used to propagate the client's identity to the target +by means of the proxyAuthz control when the client does not +belong to the DIT fragment that is being proxyied by back-ldap. +This is useful when operations performed by users bound to another +backend are propagated through back-ldap. This requires the entry with -.B binddn -DN on the remote server to have +.B proxyauthzdn +identity on the remote server to have .B proxyAuthz privileges on a wide set of DNs, e.g. -.BR saslAuthzTo=regex:.* , +.BR saslAuthzTo=dn.regex:.* , and the remote server to have .B sasl-authz-policy set to @@ -93,10 +94,9 @@ See .BR slapd.conf (5) for details on these statements and for remarks and drawbacks about their usage. -.RE .TP -.B bindpw -Password used with the bind DN above. +.B proxyauthzpw +Password used with the proxy authz DN above. .TP .B proxy-whoami Turns on proxying of the WhoAmI extended operation. If this option is diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index c29555905c..9f9661562b 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -83,6 +83,10 @@ struct ldapinfo { char *url; struct berval binddn; struct berval bindpw; +#ifdef LDAP_BACK_PROXY_AUTHZ + struct berval proxyauthzdn; + struct berval proxyauthzpw; +#endif /* LDAP_BACK_PROXY_AUTHZ */ ldap_pvt_thread_mutex_t conn_mutex; int savecred; Avlnode *conntree; diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 248e9bec93..73e6e82057 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -390,7 +390,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 "binddn". + * by the saslAuthzTo directive of the "proxyauthzdn". */ /* * NOTE: current Proxy Authorization specification @@ -402,16 +402,17 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs ) /* * if no bind took place yet, but the connection is bound - * and the binddn is set, then bind with binddn and - * explicitly add proxyAuthz control to every operation - * with the dn bound to the connection as control value. + * and the "proxyauthzdn" is set, then bind as + * "proxyauthzdn" and explicitly add the proxyAuthz + * control to every operation with the dn bound + * to the connection as control value. */ if ( ( lc->bound_dn.bv_val == NULL || lc->bound_dn.bv_len == 0 ) && ( op->o_conn && op->o_conn->c_dn.bv_val != NULL && op->o_conn->c_dn.bv_len != 0 ) - && ( li->binddn.bv_val != NULL && li->binddn.bv_len != 0 ) + && ( li->proxyauthzdn.bv_val != NULL && li->proxyauthzdn.bv_len != 0 ) && ! gotit ) { - rs->sr_err = ldap_sasl_bind(lc->ld, li->binddn.bv_val, - LDAP_SASL_SIMPLE, &li->bindpw, NULL, NULL, &msgid); + rs->sr_err = ldap_sasl_bind(lc->ld, li->proxyauthzdn.bv_val, + LDAP_SASL_SIMPLE, &li->proxyauthzpw, NULL, NULL, &msgid); } else #endif /* LDAP_BACK_PROXY_AUTHZ */ @@ -572,8 +573,8 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, * it might return some error if it failed. * * if no bind took place yet, but the connection is bound - * and the binddn is set, then bind with binddn and - * explicitly add proxyAuthz control to every operation + * and the "proxyauthzdn" is set, then bind as "proxyauthzdn" + * and explicitly add proxyAuthz the control to every operation * with the dn bound to the connection as control value. * * If no server-side controls are defined for the operation, @@ -596,7 +597,7 @@ ldap_back_proxy_authz_ctrl( if ( ( lc->bound_dn.bv_val == NULL || lc->bound_dn.bv_len == 0 ) && ( op->o_conn && op->o_conn->c_dn.bv_val != NULL && op->o_conn->c_dn.bv_len != 0 ) - && ( li->binddn.bv_val != NULL && li->binddn.bv_len != 0 ) ) { + && ( li->proxyauthzdn.bv_val != NULL && li->proxyauthzdn.bv_len != 0 ) ) { int i = 0; if ( !op->o_proxy_authz ) { @@ -622,10 +623,10 @@ ldap_back_proxy_authz_ctrl( /* * FIXME: we do not want to perform proxyAuthz * on behalf of the client, because this would - * be performed with "binddn" privileges. + * be performed with "proxyauthzdn" privileges. * * This might actually be too strict, since - * the "binddn" saslAuthzTo, and each entry's + * the "proxyauthzdn" saslAuthzTo, and each entry's * saslAuthzFrom attributes may be crafted * to avoid unwanted proxyAuthz to take place. */ diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index fedc477b90..e5541a2a61 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -99,7 +99,29 @@ ldap_back_db_config( return( 1 ); } 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 \" 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 \" line\n", + fname, lineno ); + return( 1 ); + } + ber_str2bv( argv[1], 0, 1, &li->proxyauthzpw ); +#endif /* LDAP_BACK_PROXY_AUTHZ */ + /* save bind creds for referral rebinds? */ } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) { if (argc != 1) { diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 8005887e8c..7ef19fd755 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -105,6 +105,13 @@ ldap_back_db_init( li->bindpw.bv_val = NULL; li->bindpw.bv_len = 0; +#ifdef LDAP_BACK_PROXY_AUTHZ + li->proxyauthzdn.bv_val = NULL; + li->proxyauthzdn.bv_len = 0; + li->proxyauthzpw.bv_val = NULL; + li->proxyauthzpw.bv_len = 0; +#endif /* LDAP_BACK_PROXY_AUTHZ */ + #ifdef ENABLE_REWRITE li->rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT ); if ( li->rwmap.rwm_rw == NULL ) { @@ -179,6 +186,16 @@ ldap_back_db_destroy( ch_free(li->bindpw.bv_val); li->bindpw.bv_val = NULL; } +#ifdef LDAP_BACK_PROXY_AUTHZ + if (li->proxyauthzdn.bv_val) { + ch_free(li->proxyauthzdn.bv_val); + li->proxyauthzdn.bv_val = NULL; + } + if (li->proxyauthzpw.bv_val) { + ch_free(li->proxyauthzpw.bv_val); + li->proxyauthzpw.bv_val = NULL; + } +#endif /* LDAP_BACK_PROXY_AUTHZ */ if (li->conntree) { avl_free( li->conntree, ldap_back_conn_free ); }