mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
port identity assertion to back-meta; share as much code as possible with back-ldap; misc cleanup
This commit is contained in:
parent
3f9201e95b
commit
3ebb40c4dd
@ -93,7 +93,8 @@ ldap_back_add(
|
||||
attrs[ i ] = NULL;
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rs->sr_err = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rs->sr_err = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
@ -44,18 +44,23 @@ typedef struct ldapconn_t {
|
||||
struct berval lc_bound_ndn;
|
||||
struct berval lc_local_ndn;
|
||||
unsigned lc_lcflags;
|
||||
#define LDAP_BACK_CONN_ISSET(lc,f) ((lc)->lc_lcflags & (f))
|
||||
#define LDAP_BACK_CONN_SET(lc,f) ((lc)->lc_lcflags |= (f))
|
||||
#define LDAP_BACK_CONN_CLEAR(lc,f) ((lc)->lc_lcflags &= ~(f))
|
||||
#define LDAP_BACK_CONN_CPY(lc,f,mlc) \
|
||||
#define LDAP_BACK_CONN_ISSET_F(fp,f) (*(fp) & (f))
|
||||
#define LDAP_BACK_CONN_SET_F(fp,f) (*(fp) |= (f))
|
||||
#define LDAP_BACK_CONN_CLEAR_F(fp,f) (*(fp) &= ~(f))
|
||||
#define LDAP_BACK_CONN_CPY_F(fp,f,mfp) \
|
||||
do { \
|
||||
if ( ((f) & (mlc)->lc_lcflags) == (f) ) { \
|
||||
(lc)->lc_lcflags |= (f); \
|
||||
if ( ((f) & *(mfp)) == (f) ) { \
|
||||
*(fp) |= (f); \
|
||||
} else { \
|
||||
(lc)->lc_lcflags &= ~(f); \
|
||||
*(fp) &= ~(f); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define LDAP_BACK_CONN_ISSET(lc,f) LDAP_BACK_CONN_ISSET_F(&(lc)->lc_lcflags, (f))
|
||||
#define LDAP_BACK_CONN_SET(lc,f) LDAP_BACK_CONN_SET_F(&(lc)->lc_lcflags, (f))
|
||||
#define LDAP_BACK_CONN_CLEAR(lc,f) LDAP_BACK_CONN_CLEAR_F(&(lc)->lc_lcflags, (f))
|
||||
#define LDAP_BACK_CONN_CPY(lc,f,mlc) LDAP_BACK_CONN_CPY_F(&(lc)->lc_lcflags, (f), &(mlc)->lc_lcflags)
|
||||
|
||||
#define LDAP_BACK_FCONN_ISBOUND (0x00000001U)
|
||||
#define LDAP_BACK_FCONN_ISANON (0x00000002U)
|
||||
#define LDAP_BACK_FCONN_ISBMASK (LDAP_BACK_FCONN_ISBOUND|LDAP_BACK_FCONN_ISANON)
|
||||
@ -96,18 +101,6 @@ typedef struct ldapconn_t {
|
||||
time_t lc_time;
|
||||
} ldapconn_t;
|
||||
|
||||
/*
|
||||
* identity assertion modes
|
||||
*/
|
||||
enum {
|
||||
LDAP_BACK_IDASSERT_LEGACY = 1,
|
||||
LDAP_BACK_IDASSERT_NOASSERT,
|
||||
LDAP_BACK_IDASSERT_ANONYMOUS,
|
||||
LDAP_BACK_IDASSERT_SELF,
|
||||
LDAP_BACK_IDASSERT_OTHERDN,
|
||||
LDAP_BACK_IDASSERT_OTHERID
|
||||
};
|
||||
|
||||
/*
|
||||
* operation enumeration for timeouts
|
||||
*/
|
||||
@ -137,6 +130,47 @@ typedef struct slap_retry_info_t {
|
||||
#define SLAP_RETRYNUM_FINITE(n) ((n) > SLAP_RETRYNUM_FOREVER) /* not forever */
|
||||
} slap_retry_info_t;
|
||||
|
||||
/*
|
||||
* identity assertion modes
|
||||
*/
|
||||
typedef enum {
|
||||
LDAP_BACK_IDASSERT_LEGACY = 1,
|
||||
LDAP_BACK_IDASSERT_NOASSERT,
|
||||
LDAP_BACK_IDASSERT_ANONYMOUS,
|
||||
LDAP_BACK_IDASSERT_SELF,
|
||||
LDAP_BACK_IDASSERT_OTHERDN,
|
||||
LDAP_BACK_IDASSERT_OTHERID
|
||||
} slap_idassert_mode_t;
|
||||
|
||||
/* ID assert stuff */
|
||||
typedef struct slap_idassert_t {
|
||||
slap_idassert_mode_t si_mode;
|
||||
#define li_idassert_mode li_idassert.si_mode
|
||||
|
||||
slap_bindconf si_bc;
|
||||
#define li_idassert_authcID li_idassert.si_bc.sb_authcId
|
||||
#define li_idassert_authcDN li_idassert.si_bc.sb_binddn
|
||||
#define li_idassert_passwd li_idassert.si_bc.sb_cred
|
||||
#define li_idassert_authzID li_idassert.si_bc.sb_authzId
|
||||
#define li_idassert_authmethod li_idassert.si_bc.sb_method
|
||||
#define li_idassert_sasl_mech li_idassert.si_bc.sb_saslmech
|
||||
#define li_idassert_sasl_realm li_idassert.si_bc.sb_realm
|
||||
#define li_idassert_secprops li_idassert.si_bc.sb_secprops
|
||||
#define li_idassert_tls li_idassert.si_bc.sb_tls
|
||||
|
||||
unsigned si_flags;
|
||||
#define LDAP_BACK_AUTH_NONE 0x00U
|
||||
#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U
|
||||
#define LDAP_BACK_AUTH_OVERRIDE 0x02U
|
||||
#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U
|
||||
#define LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ 0x08U
|
||||
#define LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND 0x10U
|
||||
#define li_idassert_flags li_idassert.si_flags
|
||||
|
||||
BerVarray si_authz;
|
||||
#define li_idassert_authz li_idassert.si_authz
|
||||
} slap_idassert_t;
|
||||
|
||||
/*
|
||||
* Hook to allow mucking with ldapinfo_t when quarantine is over
|
||||
*/
|
||||
@ -166,27 +200,7 @@ typedef struct ldapinfo_t {
|
||||
#define li_acl_secprops li_acl.sb_secprops
|
||||
|
||||
/* ID assert stuff */
|
||||
int li_idassert_mode;
|
||||
|
||||
slap_bindconf li_idassert;
|
||||
#define li_idassert_authcID li_idassert.sb_authcId
|
||||
#define li_idassert_authcDN li_idassert.sb_binddn
|
||||
#define li_idassert_passwd li_idassert.sb_cred
|
||||
#define li_idassert_authzID li_idassert.sb_authzId
|
||||
#define li_idassert_authmethod li_idassert.sb_method
|
||||
#define li_idassert_sasl_mech li_idassert.sb_saslmech
|
||||
#define li_idassert_sasl_realm li_idassert.sb_realm
|
||||
#define li_idassert_secprops li_idassert.sb_secprops
|
||||
|
||||
unsigned li_idassert_flags;
|
||||
#define LDAP_BACK_AUTH_NONE 0x00U
|
||||
#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U
|
||||
#define LDAP_BACK_AUTH_OVERRIDE 0x02U
|
||||
#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U
|
||||
#define LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ 0x08U
|
||||
#define LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND 0x10U
|
||||
|
||||
BerVarray li_idassert_authz;
|
||||
slap_idassert_t li_idassert;
|
||||
/* end of ID assert stuff */
|
||||
|
||||
int li_nretries;
|
||||
|
@ -971,24 +971,6 @@ retry_lock:;
|
||||
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
#if 0
|
||||
while ( lc->lc_refcnt > 1 ) {
|
||||
ldap_pvt_thread_yield();
|
||||
rc = LDAP_BACK_CONN_ISBOUND( lc );
|
||||
if ( rc ) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
|
||||
}
|
||||
LDAP_BACK_CONN_BINDING_SET( lc );
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: we need to let clients use proxyAuthz
|
||||
* otherwise we cannot do symmetric pools of servers;
|
||||
@ -1743,14 +1725,15 @@ done:;
|
||||
int
|
||||
ldap_back_proxy_authz_ctrl(
|
||||
struct berval *bound_ndn,
|
||||
int version,
|
||||
slap_idassert_t *si,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl ***pctrls )
|
||||
{
|
||||
ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
|
||||
LDAPControl **ctrls = NULL;
|
||||
int i = 0,
|
||||
mode;
|
||||
int i = 0;
|
||||
slap_idassert_mode_t mode;
|
||||
struct berval assertedID,
|
||||
ndn;
|
||||
|
||||
@ -1759,7 +1742,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
|
||||
/* don't proxyAuthz if protocol is not LDAPv3 */
|
||||
switch ( li->li_version ) {
|
||||
switch ( version ) {
|
||||
case LDAP_VERSION3:
|
||||
break;
|
||||
|
||||
@ -1776,8 +1759,8 @@ ldap_back_proxy_authz_ctrl(
|
||||
/* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
|
||||
* but if it is not set this test fails. We need a different
|
||||
* means to detect if idassert is enabled */
|
||||
if ( ( BER_BVISNULL( &li->li_idassert_authcID ) || BER_BVISEMPTY( &li->li_idassert_authcID ) )
|
||||
&& ( BER_BVISNULL( &li->li_idassert_authcDN ) || BER_BVISEMPTY( &li->li_idassert_authcDN ) ) )
|
||||
if ( ( BER_BVISNULL( &si->si_bc.sb_authcId ) || BER_BVISEMPTY( &si->si_bc.sb_authcId ) )
|
||||
&& ( BER_BVISNULL( &si->si_bc.sb_binddn ) || BER_BVISEMPTY( &si->si_bc.sb_binddn ) ) )
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
@ -1796,7 +1779,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
ndn = op->o_ndn;
|
||||
}
|
||||
|
||||
if ( li->li_idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
|
||||
if ( si->si_mode == LDAP_BACK_IDASSERT_LEGACY ) {
|
||||
if ( op->o_proxy_authz ) {
|
||||
/*
|
||||
* FIXME: we do not want to perform proxyAuthz
|
||||
@ -1823,18 +1806,18 @@ ldap_back_proxy_authz_ctrl(
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( BER_BVISNULL( &li->li_idassert_authcDN ) ) {
|
||||
if ( BER_BVISNULL( &si->si_bc.sb_binddn ) ) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
|
||||
if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
|
||||
} else if ( si->si_bc.sb_method == LDAP_AUTH_SASL ) {
|
||||
if ( ( si->si_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
|
||||
{
|
||||
/* already asserted in SASL via native authz */
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else if ( li->li_idassert_authz && !be_isroot( op ) ) {
|
||||
} else if ( si->si_authz && !be_isroot( op ) ) {
|
||||
int rc;
|
||||
struct berval authcDN;
|
||||
|
||||
@ -1843,11 +1826,10 @@ ldap_back_proxy_authz_ctrl(
|
||||
} else {
|
||||
authcDN = ndn;
|
||||
}
|
||||
rc = slap_sasl_matches( op, li->li_idassert_authz,
|
||||
rc = slap_sasl_matches( op, si->si_authz,
|
||||
&authcDN, & authcDN );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE )
|
||||
{
|
||||
if ( si->si_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
|
||||
/* ndn is not authorized
|
||||
* to use idassert */
|
||||
rs->sr_err = rc;
|
||||
@ -1882,7 +1864,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
mode = LDAP_BACK_IDASSERT_NOASSERT;
|
||||
|
||||
} else {
|
||||
mode = li->li_idassert_mode;
|
||||
mode = si->si_mode;
|
||||
}
|
||||
|
||||
switch ( mode ) {
|
||||
@ -1915,7 +1897,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
case LDAP_BACK_IDASSERT_OTHERID:
|
||||
case LDAP_BACK_IDASSERT_OTHERDN:
|
||||
/* assert idassert DN */
|
||||
assertedID = li->li_idassert_authzID;
|
||||
assertedID = si->si_bc.sb_authzId;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1943,7 +1925,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
|
||||
ctrls[ 0 ]->ldctl_iscritical = 1;
|
||||
|
||||
switch ( li->li_idassert_mode ) {
|
||||
switch ( si->si_mode ) {
|
||||
/* already in u:ID or dn:DN form */
|
||||
case LDAP_BACK_IDASSERT_OTHERID:
|
||||
case LDAP_BACK_IDASSERT_OTHERDN:
|
||||
@ -1965,7 +1947,7 @@ ldap_back_proxy_authz_ctrl(
|
||||
* to encode the value of the authzID (and called it proxyDN);
|
||||
* this hack provides compatibility with those DSAs that
|
||||
* implement it this way */
|
||||
if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
|
||||
if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
|
||||
struct berval authzID = ctrls[ 0 ]->ldctl_value;
|
||||
BerElementBuffer berbuf;
|
||||
BerElement *ber = (BerElement *)&berbuf;
|
||||
@ -1995,7 +1977,7 @@ free_ber:;
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
|
||||
} else if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
|
||||
struct berval authzID = ctrls[ 0 ]->ldctl_value,
|
||||
tmp;
|
||||
BerElementBuffer berbuf;
|
||||
|
@ -36,6 +36,8 @@ ldap_back_compare(
|
||||
Operation *op,
|
||||
SlapReply *rs )
|
||||
{
|
||||
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
|
||||
|
||||
ldapconn_t *lc;
|
||||
ber_int_t msgid;
|
||||
int do_retry = 1;
|
||||
@ -49,7 +51,8 @@ ldap_back_compare(
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
@ -512,6 +512,181 @@ slap_retry_info_destroy(
|
||||
ri->ri_num = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si )
|
||||
{
|
||||
ldapinfo_t *li = ( ldapinfo_t * )c->be->be_private;
|
||||
struct berval bv;
|
||||
struct berval in;
|
||||
int rc;
|
||||
|
||||
ber_str2bv( c->argv[ 1 ], 0, 0, &in );
|
||||
rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-authzFrom <authz>\": "
|
||||
"invalid syntax" );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
ber_bvarray_add( &li->li_idassert_authz, &bv );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
slap_idassert_parse( ConfigArgs *c, slap_idassert_t *si )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 1; i < c->argc; i++ ) {
|
||||
if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "mode=" );
|
||||
int j;
|
||||
|
||||
j = verb_to_mask( argvi, idassert_mode );
|
||||
if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown mode \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
si->si_mode = idassert_mode[ j ].mask;
|
||||
|
||||
} else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "authz=" );
|
||||
|
||||
if ( strcasecmp( argvi, "native" ) == 0 ) {
|
||||
if ( si->si_bc.sb_method != LDAP_AUTH_SASL ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"authz=\"native\" incompatible "
|
||||
"with auth method" );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
si->si_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
|
||||
|
||||
} else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
|
||||
si->si_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
|
||||
|
||||
} else {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown authz \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "flags=" );
|
||||
char **flags = ldap_str2charray( argvi, "," );
|
||||
int j, err = 0;
|
||||
|
||||
if ( flags == NULL ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unable to parse flags \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( j = 0; flags[ j ] != NULL; j++ ) {
|
||||
|
||||
if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
|
||||
si->si_flags |= LDAP_BACK_AUTH_OVERRIDE;
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
|
||||
si->si_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
|
||||
si->si_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) {
|
||||
if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: \"obsolete-proxy-authz\" flag "
|
||||
"in \"idassert-mode <args>\" "
|
||||
"incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
|
||||
c->log, 0, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
|
||||
} else {
|
||||
si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
|
||||
}
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) {
|
||||
if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: \"obsolete-encoding-workaround\" flag "
|
||||
"in \"idassert-mode <args>\" "
|
||||
"incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
|
||||
c->log, 0, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
|
||||
} else {
|
||||
si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
|
||||
}
|
||||
|
||||
} else {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown flag \"%s\"",
|
||||
flags[ j ] );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_charray_free( flags );
|
||||
if ( err ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( bindconf_parse( c->argv[ i ], &si->si_bc ) ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NOTE: temporary, until back-meta is ported to back-config */
|
||||
int
|
||||
slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si )
|
||||
{
|
||||
ConfigArgs c = { 0 };
|
||||
char *argv[ 2 ];
|
||||
|
||||
snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
|
||||
c.argc = 2;
|
||||
c.argv = argv;
|
||||
argv[ 0 ] = arg;
|
||||
argv[ 1 ] = NULL;
|
||||
|
||||
return slap_idassert_authzfrom_parse( &c, si );
|
||||
}
|
||||
|
||||
int
|
||||
slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si )
|
||||
{
|
||||
ConfigArgs c = { 0 };
|
||||
|
||||
snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
|
||||
c.argc = argc;
|
||||
c.argv = argv;
|
||||
|
||||
return slap_idassert_parse( &c, si );
|
||||
}
|
||||
|
||||
static int
|
||||
ldap_back_cf_gen( ConfigArgs *c )
|
||||
{
|
||||
@ -689,7 +864,7 @@ ldap_back_cf_gen( ConfigArgs *c )
|
||||
/* end-of-flags */
|
||||
}
|
||||
|
||||
bindconf_unparse( &li->li_idassert, &bc );
|
||||
bindconf_unparse( &li->li_idassert.si_bc, &bc );
|
||||
|
||||
if ( !BER_BVISNULL( &bv ) ) {
|
||||
ber_len_t len = bv.bv_len + bc.bv_len;
|
||||
@ -912,7 +1087,7 @@ ldap_back_cf_gen( ConfigArgs *c )
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_IDASSERT_BIND:
|
||||
bindconf_free( &li->li_idassert );
|
||||
bindconf_free( &li->li_idassert.si_bc );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_REBIND:
|
||||
@ -1315,22 +1490,9 @@ done_url:;
|
||||
ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
|
||||
struct berval bv;
|
||||
struct berval in;
|
||||
int rc;
|
||||
|
||||
ber_str2bv( c->argv[ 1 ], 0, 0, &in );
|
||||
rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-authzFrom <authz>\": "
|
||||
"invalid syntax" );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
ber_bvarray_add( &li->li_idassert_authz, &bv );
|
||||
} break;
|
||||
case LDAP_BACK_CFG_IDASSERT_AUTHZFROM:
|
||||
rc = slap_idassert_authzfrom_parse( c, &li->li_idassert );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_IDASSERT_METHOD:
|
||||
/* no longer supported */
|
||||
@ -1341,122 +1503,7 @@ done_url:;
|
||||
return 1;
|
||||
|
||||
case LDAP_BACK_CFG_IDASSERT_BIND:
|
||||
for ( i = 1; i < c->argc; i++ ) {
|
||||
if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "mode=" );
|
||||
int j;
|
||||
|
||||
j = verb_to_mask( argvi, idassert_mode );
|
||||
if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown mode \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
li->li_idassert_mode = idassert_mode[ j ].mask;
|
||||
|
||||
} else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "authz=" );
|
||||
|
||||
if ( strcasecmp( argvi, "native" ) == 0 ) {
|
||||
if ( li->li_idassert_authmethod != LDAP_AUTH_SASL ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"authz=\"native\" incompatible "
|
||||
"with auth method" );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
li->li_idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ;
|
||||
|
||||
} else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) {
|
||||
li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
|
||||
|
||||
} else {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown authz \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
|
||||
char *argvi = c->argv[ i ] + STRLENOF( "flags=" );
|
||||
char **flags = ldap_str2charray( argvi, "," );
|
||||
int j, err = 0;
|
||||
|
||||
if ( flags == NULL ) {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unable to parse flags \"%s\"",
|
||||
argvi );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( j = 0; flags[ j ] != NULL; j++ ) {
|
||||
|
||||
if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
|
||||
li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
|
||||
li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
|
||||
li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) {
|
||||
if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"obsolete-proxy-authz\" flag "
|
||||
"in \"idassert-mode <args>\" "
|
||||
"incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
|
||||
c->fname, c->lineno, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
|
||||
} else {
|
||||
li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
|
||||
}
|
||||
|
||||
} else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) {
|
||||
if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"obsolete-encoding-workaround\" flag "
|
||||
"in \"idassert-mode <args>\" "
|
||||
"incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
|
||||
c->fname, c->lineno, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
|
||||
} else {
|
||||
li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
|
||||
}
|
||||
|
||||
} else {
|
||||
snprintf( c->msg, sizeof( c->msg ),
|
||||
"\"idassert-bind <args>\": "
|
||||
"unknown flag \"%s\"",
|
||||
flags[ j ] );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_charray_free( flags );
|
||||
if ( err ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( bindconf_parse( c->argv[ i ], &li->li_idassert ) ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
rc = slap_idassert_parse( c, &li->li_idassert );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_CFG_REBIND:
|
||||
|
@ -51,7 +51,8 @@ ldap_back_delete(
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
rc = rs->sr_err;
|
||||
|
@ -42,6 +42,8 @@ static struct exop {
|
||||
static int
|
||||
ldap_back_extended_one( Operation *op, SlapReply *rs, BI_op_extended exop )
|
||||
{
|
||||
ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
|
||||
|
||||
ldapconn_t *lc;
|
||||
LDAPControl **oldctrls = NULL;
|
||||
int rc;
|
||||
@ -56,7 +58,9 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, BI_op_extended exop )
|
||||
}
|
||||
|
||||
oldctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &op->o_ctrls ) ) {
|
||||
if ( ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &op->o_ctrls ) )
|
||||
{
|
||||
op->o_ctrls = oldctrls;
|
||||
send_ldap_extended( op, rs );
|
||||
rs->sr_text = NULL;
|
||||
|
@ -126,7 +126,7 @@ ldap_back_db_init( Backend *be )
|
||||
|
||||
li->li_idassert_authmethod = LDAP_AUTH_NONE;
|
||||
BER_BVZERO( &li->li_idassert_sasl_mech );
|
||||
li->li_idassert.sb_tls = SB_TLS_DEFAULT;
|
||||
li->li_idassert_tls = SB_TLS_DEFAULT;
|
||||
|
||||
/* by default, use proxyAuthz control on each operation */
|
||||
li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
|
||||
|
@ -99,7 +99,8 @@ ldap_back_modify(
|
||||
modv[ i ] = 0;
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
rc = -1;
|
||||
|
@ -74,7 +74,8 @@ ldap_back_modrdn(
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
rc = -1;
|
||||
|
@ -68,6 +68,8 @@ extern void ldap_back_conn_free( void *c );
|
||||
extern int
|
||||
ldap_back_proxy_authz_ctrl(
|
||||
struct berval *bound_ndn,
|
||||
int version,
|
||||
slap_idassert_t *si,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
LDAPControl ***pctrls );
|
||||
@ -87,6 +89,8 @@ extern int slap_retry_info_parse( char *in, slap_retry_info_t *ri,
|
||||
char *buf, ber_len_t buflen );
|
||||
extern int slap_retry_info_unparse( slap_retry_info_t *ri, struct berval *bvout );
|
||||
|
||||
extern int slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si );
|
||||
extern int slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si );
|
||||
|
||||
extern int chain_initialize( void );
|
||||
#ifdef LDAP_DEVEL
|
||||
|
@ -203,7 +203,8 @@ ldap_back_search(
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
@ -708,9 +709,10 @@ ldap_back_entry_get(
|
||||
ObjectClass *oc,
|
||||
AttributeDescription *at,
|
||||
int rw,
|
||||
Entry **ent
|
||||
)
|
||||
Entry **ent )
|
||||
{
|
||||
ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
|
||||
|
||||
ldapconn_t *lc;
|
||||
int rc = 1,
|
||||
do_not_cache;
|
||||
@ -760,7 +762,8 @@ ldap_back_entry_get(
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn, op, &rs, &ctrls );
|
||||
rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
|
||||
li->li_version, &li->li_idassert, op, &rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ int
|
||||
meta_back_add( Operation *op, SlapReply *rs )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt;
|
||||
metaconn_t *mc;
|
||||
int i, candidate = -1;
|
||||
int isupdate;
|
||||
@ -45,6 +46,7 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
int maperr = 1;
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",
|
||||
@ -63,7 +65,8 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the add dn, if needed
|
||||
*/
|
||||
dc.target = mi->mi_targets[ candidate ];
|
||||
mt = mi->mi_targets[ candidate ];
|
||||
dc.target = mt;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "addDN";
|
||||
@ -96,7 +99,7 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
mapped = a->a_desc->ad_cname;
|
||||
|
||||
} else {
|
||||
ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
|
||||
ldap_back_map( &mt->mt_rwmap.rwm_at,
|
||||
&a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
|
||||
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
|
||||
continue;
|
||||
@ -121,11 +124,11 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
|
||||
struct ldapmapping *mapping;
|
||||
|
||||
ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
|
||||
ldap_back_mapping( &mt->mt_rwmap.rwm_oc,
|
||||
&a->a_vals[ j ], &mapping, BACKLDAP_MAP );
|
||||
|
||||
if ( mapping == NULL ) {
|
||||
if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
|
||||
if ( mt->mt_rwmap.rwm_oc.drop_missing ) {
|
||||
continue;
|
||||
}
|
||||
attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
|
||||
@ -165,9 +168,17 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
}
|
||||
attrs[ i ] = NULL;
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
|
||||
{
|
||||
maperr = 0;
|
||||
goto sendres;
|
||||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
attrs, op->o_ctrls, NULL, &msgid );
|
||||
attrs, ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
@ -180,8 +191,8 @@ retry:;
|
||||
LDAPMessage *res = NULL;
|
||||
int rc;
|
||||
|
||||
if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_ADD ];
|
||||
if ( mt->mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
|
||||
tv.tv_sec = mt->mt_timeout[ LDAP_BACK_OP_ADD ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
@ -201,6 +212,7 @@ retry:;
|
||||
break;
|
||||
|
||||
case LDAP_RES_ADD:
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
res, &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
@ -215,13 +227,16 @@ retry:;
|
||||
}
|
||||
}
|
||||
|
||||
sendres:;
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( maperr ) {
|
||||
rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
|
||||
if ( META_BACK_TGT_QUARANTINE( mt ) ) {
|
||||
meta_back_quarantine( op, rs, candidate );
|
||||
}
|
||||
}
|
||||
|
@ -229,8 +229,19 @@ typedef struct metatarget_t {
|
||||
struct berval mt_binddn;
|
||||
struct berval mt_bindpw;
|
||||
|
||||
struct berval mt_pseudorootdn;
|
||||
struct berval mt_pseudorootpw;
|
||||
slap_idassert_t mt_idassert;
|
||||
#define mt_idassert_mode mt_idassert.si_mode
|
||||
#define mt_idassert_authcID mt_idassert.si_bc.sb_authcId
|
||||
#define mt_idassert_authcDN mt_idassert.si_bc.sb_binddn
|
||||
#define mt_idassert_passwd mt_idassert.si_bc.sb_cred
|
||||
#define mt_idassert_authzID mt_idassert.si_bc.sb_authzId
|
||||
#define mt_idassert_authmethod mt_idassert.si_bc.sb_method
|
||||
#define mt_idassert_sasl_mech mt_idassert.si_bc.sb_saslmech
|
||||
#define mt_idassert_sasl_realm mt_idassert.si_bc.sb_realm
|
||||
#define mt_idassert_secprops mt_idassert.si_bc.sb_secprops
|
||||
#define mt_idassert_tls mt_idassert.si_bc.sb_tls
|
||||
#define mt_idassert_flags mt_idassert.si_flags
|
||||
#define mt_idassert_authz mt_idassert.si_authz
|
||||
|
||||
int mt_nretries;
|
||||
#define META_RETRY_UNDEFINED (-2)
|
||||
@ -400,6 +411,17 @@ meta_back_single_dobind(
|
||||
int retries,
|
||||
int dolock );
|
||||
|
||||
extern int
|
||||
meta_back_proxy_authz_cred(
|
||||
metaconn_t *mc,
|
||||
int candidate,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
ldap_back_send_t sendok,
|
||||
struct berval *binddn,
|
||||
struct berval *bindcred,
|
||||
int *method );
|
||||
|
||||
extern int
|
||||
meta_back_cancel(
|
||||
metaconn_t *mc,
|
||||
|
@ -34,6 +34,16 @@
|
||||
#include "../back-ldap/back-ldap.h"
|
||||
#include "back-meta.h"
|
||||
|
||||
#include "lutil_ldap.h"
|
||||
|
||||
static int
|
||||
meta_back_proxy_authz_bind(
|
||||
metaconn_t *mc,
|
||||
int candidate,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
ldap_back_send_t sendok );
|
||||
|
||||
int
|
||||
meta_back_bind( Operation *op, SlapReply *rs )
|
||||
{
|
||||
@ -140,7 +150,8 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
}
|
||||
|
||||
if ( isroot ) {
|
||||
if ( BER_BVISNULL( &mt->mt_pseudorootdn ) )
|
||||
if ( mt->mt_idassert_authmethod == LDAP_AUTH_NONE
|
||||
|| BER_BVISNULL( &mt->mt_idassert_authcDN ) )
|
||||
{
|
||||
metasingleconn_t *msc = &mc->mc_conns[ i ];
|
||||
|
||||
@ -163,9 +174,14 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
continue;
|
||||
}
|
||||
|
||||
op2.o_req_dn = mt->mt_pseudorootdn;
|
||||
op2.o_req_ndn = mt->mt_pseudorootdn;
|
||||
op2.orb_cred = mt->mt_pseudorootpw;
|
||||
/* FIXME: if sb_method == LDAP_AUTH_SASL things differ a bit */
|
||||
if ( mt->mt_idassert_authmethod == LDAP_AUTH_SASL ) {
|
||||
/* ### */
|
||||
}
|
||||
|
||||
op2.o_req_dn = mt->mt_idassert_authcDN;
|
||||
op2.o_req_ndn = mt->mt_idassert_authcDN;
|
||||
op2.orb_cred = mt->mt_idassert_passwd;
|
||||
op2.orb_method = LDAP_AUTH_SIMPLE;
|
||||
|
||||
massage = 0;
|
||||
@ -233,7 +249,7 @@ retry_lock:;
|
||||
}
|
||||
|
||||
ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
|
||||
if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
|
||||
if ( isroot ) {
|
||||
mc->mc_conn = LDAP_BACK_PCONN_SET( op );
|
||||
}
|
||||
lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
|
||||
@ -310,7 +326,7 @@ retry:;
|
||||
switch ( ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) {
|
||||
case 0:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s meta_back_single_bind[%d]: ldap_result=0 nretries=%d.\n",
|
||||
"%s meta_back_bind_op_result[%d]: ldap_result=0 nretries=%d.\n",
|
||||
op->o_log_prefix, candidate, nretries );
|
||||
|
||||
if ( nretries != META_RETRY_NEVER ) {
|
||||
@ -334,11 +350,12 @@ retry:;
|
||||
"err=%d (%s) nretries=%d",
|
||||
rs->sr_err, ldap_err2string( rs->sr_err ), nretries );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"### %s meta_back_single_bind[%d]: %s.\n",
|
||||
"### %s meta_back_bind_op_result[%d]: %s.\n",
|
||||
op->o_log_prefix, candidate, buf );
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err,
|
||||
NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
@ -416,7 +433,20 @@ meta_back_single_bind(
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &op->o_req_dn );
|
||||
/* If defined, proxyAuthz will be used also when
|
||||
* back-ldap is the authorizing backend; for this
|
||||
* purpose, a successful bind is followed by a
|
||||
* bind with the configured identity assertion */
|
||||
/* NOTE: use with care */
|
||||
if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
|
||||
meta_back_proxy_authz_bind( mc, candidate, op, rs, LDAP_BACK_SENDERR );
|
||||
if ( !LDAP_BACK_CONN_ISBOUND( msc ) ) {
|
||||
goto return_results;
|
||||
}
|
||||
goto cache_refresh;
|
||||
}
|
||||
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &op->o_req_ndn );
|
||||
LDAP_BACK_CONN_ISBOUND_SET( msc );
|
||||
mc->mc_authz_target = candidate;
|
||||
|
||||
@ -468,41 +498,18 @@ meta_back_single_dobind(
|
||||
|
||||
assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
|
||||
|
||||
/*
|
||||
* meta_back_single_dobind() calls meta_back_single_bind()
|
||||
* if required.
|
||||
*/
|
||||
if ( be_isroot( op ) && !BER_BVISNULL( &mt->mt_pseudorootdn ) )
|
||||
/* NOTE: this obsoletes pseudorootdn */
|
||||
if ( op->o_conn != NULL &&
|
||||
!op->o_do_not_cache &&
|
||||
( BER_BVISNULL( &msc->msc_bound_ndn ) ||
|
||||
BER_BVISEMPTY( &msc->msc_bound_ndn ) ||
|
||||
( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
|
||||
{
|
||||
Operation op2 = *op;
|
||||
|
||||
op2.o_tag = LDAP_REQ_BIND;
|
||||
op2.o_req_dn = mt->mt_pseudorootdn;
|
||||
op2.o_req_ndn = mt->mt_pseudorootdn;
|
||||
op2.orb_cred = mt->mt_pseudorootpw;
|
||||
op2.orb_method = LDAP_AUTH_SIMPLE;
|
||||
|
||||
rc = meta_back_single_bind( &op2, rs, *mcp, candidate, 0 );
|
||||
(void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok );
|
||||
rc = rs->sr_err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise an anonymous bind is performed
|
||||
* (note: if the target was already bound, the anonymous
|
||||
* bind clears the previous bind).
|
||||
*/
|
||||
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
|
||||
ber_memfree( msc->msc_bound_ndn.bv_val );
|
||||
BER_BVZERO( &msc->msc_bound_ndn );
|
||||
}
|
||||
|
||||
if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &msc->msc_cred ) ) {
|
||||
/* destroy sensitive data */
|
||||
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
|
||||
ber_memfree( msc->msc_cred.bv_val );
|
||||
BER_BVZERO( &msc->msc_cred );
|
||||
}
|
||||
|
||||
/* FIXME: should we check if at least some of the op->o_ctrls
|
||||
* can/should be passed? */
|
||||
rs->sr_err = ldap_sasl_bind( msc->msc_ld, "", LDAP_SASL_SIMPLE, &cred,
|
||||
@ -576,7 +583,7 @@ meta_back_dobind(
|
||||
for ( i = 0; i < mi->mi_ntargets; i++ ) {
|
||||
metatarget_t *mt = mi->mi_targets[ i ];
|
||||
metasingleconn_t *msc = &mc->mc_conns[ i ];
|
||||
int rc, do_retry = 1;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Not a candidate
|
||||
@ -593,7 +600,10 @@ meta_back_dobind(
|
||||
|
||||
retry_binding:;
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
if ( LDAP_BACK_CONN_ISBOUND( msc ) || LDAP_BACK_CONN_ISANON( msc ) ) {
|
||||
if ( LDAP_BACK_CONN_ISBOUND( msc )
|
||||
|| ( LDAP_BACK_CONN_ISANON( msc )
|
||||
&& mt->mt_idassert_authmethod == LDAP_AUTH_NONE ) )
|
||||
{
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
++bound;
|
||||
continue;
|
||||
@ -608,7 +618,6 @@ retry_binding:;
|
||||
LDAP_BACK_CONN_BINDING_SET( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
retry:;
|
||||
rc = meta_back_single_dobind( op, rs, &mc, i,
|
||||
LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
|
||||
/*
|
||||
@ -625,10 +634,11 @@ retry:;
|
||||
}
|
||||
|
||||
|
||||
if ( rc == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( rc == LDAP_UNAVAILABLE ) {
|
||||
/* FIXME: meta_back_retry() already calls
|
||||
* meta_back_single_dobind() */
|
||||
if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
|
||||
goto retry;
|
||||
goto retry_ok;
|
||||
}
|
||||
|
||||
if ( mc != NULL ) {
|
||||
@ -669,6 +679,7 @@ retry:;
|
||||
continue;
|
||||
} /* else */
|
||||
|
||||
retry_ok:;
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"%s meta_back_dobind[%d]: "
|
||||
"(%s)\n",
|
||||
@ -983,3 +994,303 @@ meta_back_op_result(
|
||||
return ( ( rerr == LDAP_SUCCESS ) ? 0 : -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_back_proxy_authz_cred()
|
||||
*
|
||||
* prepares credentials & method for meta_back_proxy_authz_bind();
|
||||
* or, if method is SASL, performs the SASL bind directly.
|
||||
*/
|
||||
int
|
||||
meta_back_proxy_authz_cred(
|
||||
metaconn_t *mc,
|
||||
int candidate,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
ldap_back_send_t sendok,
|
||||
struct berval *binddn,
|
||||
struct berval *bindcred,
|
||||
int *method )
|
||||
{
|
||||
metainfo_t *mi = (metainfo_t *)op->o_bd->be_private;
|
||||
metatarget_t *mt = mi->mi_targets[ candidate ];
|
||||
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
|
||||
struct berval ndn;
|
||||
int dobind = 0;
|
||||
|
||||
/* don't proxyAuthz if protocol is not LDAPv3 */
|
||||
switch ( mt->mt_version ) {
|
||||
case LDAP_VERSION3:
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
|
||||
break;
|
||||
}
|
||||
/* fall thru */
|
||||
|
||||
default:
|
||||
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( op->o_tag == LDAP_REQ_BIND ) {
|
||||
ndn = op->o_req_ndn;
|
||||
|
||||
} else if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
|
||||
ndn = op->o_conn->c_ndn;
|
||||
|
||||
} else {
|
||||
ndn = op->o_ndn;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: we need to let clients use proxyAuthz
|
||||
* 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 authzTo directive of the "proxyauthzdn".
|
||||
*/
|
||||
/*
|
||||
* NOTE: current Proxy Authorization specification
|
||||
* and implementation do not allow proxy authorization
|
||||
* control to be provided with Bind requests
|
||||
*/
|
||||
/*
|
||||
* if no bind took place yet, but the connection is bound
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* bind as proxyauthzdn only if no idassert mode
|
||||
* is requested, or if the client's identity
|
||||
* is authorized */
|
||||
switch ( mt->mt_idassert_mode ) {
|
||||
case LDAP_BACK_IDASSERT_LEGACY:
|
||||
if ( !BER_BVISNULL( &ndn ) && !BER_BVISEMPTY( &ndn ) ) {
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) && !BER_BVISEMPTY( &mt->mt_idassert_authcDN ) )
|
||||
{
|
||||
*binddn = mt->mt_idassert_authcDN;
|
||||
*bindcred = mt->mt_idassert_passwd;
|
||||
dobind = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* NOTE: rootdn can always idassert */
|
||||
if ( BER_BVISNULL( &ndn ) && mt->mt_idassert_authz == NULL ) {
|
||||
if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
|
||||
rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
|
||||
} else {
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
*binddn = slap_empty_bv;
|
||||
*bindcred = slap_empty_bv;
|
||||
break;
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
} else if ( mt->mt_idassert_authz && !be_isroot( op ) ) {
|
||||
struct berval authcDN;
|
||||
|
||||
if ( BER_BVISNULL( &ndn ) ) {
|
||||
authcDN = slap_empty_bv;
|
||||
|
||||
} else {
|
||||
authcDN = ndn;
|
||||
}
|
||||
rs->sr_err = slap_sasl_matches( op, mt->mt_idassert_authz,
|
||||
&authcDN, &authcDN );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
|
||||
} else {
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
*binddn = slap_empty_bv;
|
||||
*bindcred = slap_empty_bv;
|
||||
break;
|
||||
}
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
*binddn = mt->mt_idassert_authcDN;
|
||||
*bindcred = mt->mt_idassert_passwd;
|
||||
dobind = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( dobind && mt->mt_idassert_authmethod == LDAP_AUTH_SASL ) {
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
void *defaults = NULL;
|
||||
struct berval authzID = BER_BVNULL;
|
||||
int freeauthz = 0;
|
||||
|
||||
/* if SASL supports native authz, prepare for it */
|
||||
if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&
|
||||
( mt->mt_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
|
||||
{
|
||||
switch ( mt->mt_idassert_mode ) {
|
||||
case LDAP_BACK_IDASSERT_OTHERID:
|
||||
case LDAP_BACK_IDASSERT_OTHERDN:
|
||||
authzID = mt->mt_idassert_authzID;
|
||||
break;
|
||||
|
||||
case LDAP_BACK_IDASSERT_ANONYMOUS:
|
||||
BER_BVSTR( &authzID, "dn:" );
|
||||
break;
|
||||
|
||||
case LDAP_BACK_IDASSERT_SELF:
|
||||
if ( BER_BVISNULL( &ndn ) ) {
|
||||
/* connection is not authc'd, so don't idassert */
|
||||
BER_BVSTR( &authzID, "dn:" );
|
||||
break;
|
||||
}
|
||||
authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
|
||||
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 + STRLENOF( "dn:" ),
|
||||
ndn.bv_val, ndn.bv_len + 1 );
|
||||
freeauthz = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mt->mt_idassert_secprops != NULL ) {
|
||||
rs->sr_err = ldap_set_option( msc->msc_ld,
|
||||
LDAP_OPT_X_SASL_SECPROPS,
|
||||
(void *)mt->mt_idassert_secprops );
|
||||
|
||||
if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
defaults = lutil_sasl_defaults( msc->msc_ld,
|
||||
mt->mt_idassert_sasl_mech.bv_val,
|
||||
mt->mt_idassert_sasl_realm.bv_val,
|
||||
mt->mt_idassert_authcID.bv_val,
|
||||
mt->mt_idassert_passwd.bv_val,
|
||||
authzID.bv_val );
|
||||
|
||||
rs->sr_err = ldap_sasl_interactive_bind_s( msc->msc_ld, binddn->bv_val,
|
||||
mt->mt_idassert_sasl_mech.bv_val, NULL, NULL,
|
||||
LDAP_SASL_QUIET, lutil_sasl_interact,
|
||||
defaults );
|
||||
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
||||
} else {
|
||||
LDAP_BACK_CONN_ISBOUND_SET( msc );
|
||||
}
|
||||
|
||||
lutil_sasl_freedefs( defaults );
|
||||
if ( freeauthz ) {
|
||||
slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
goto done;
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
}
|
||||
|
||||
*method = mt->mt_idassert_authmethod;
|
||||
switch ( mt->mt_idassert_authmethod ) {
|
||||
case LDAP_AUTH_NONE:
|
||||
BER_BVSTR( binddn, "" );
|
||||
BER_BVSTR( bindcred, "" );
|
||||
/* fallthru */
|
||||
|
||||
case LDAP_AUTH_SIMPLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unsupported! */
|
||||
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
|
||||
rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
done:;
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
|
||||
{
|
||||
metainfo_t *mi = (metainfo_t *)op->o_bd->be_private;
|
||||
metatarget_t *mt = mi->mi_targets[ candidate ];
|
||||
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
|
||||
struct berval binddn = BER_BVC( "" ),
|
||||
cred = BER_BVC( "" );
|
||||
int method = LDAP_AUTH_NONE,
|
||||
rc;
|
||||
|
||||
rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, sendok, &binddn, &cred, &method );
|
||||
if ( rc == LDAP_SUCCESS && !LDAP_BACK_CONN_ISBOUND( msc ) ) {
|
||||
int msgid;
|
||||
|
||||
switch ( method ) {
|
||||
case LDAP_AUTH_NONE:
|
||||
case LDAP_AUTH_SIMPLE:
|
||||
rs->sr_err = ldap_sasl_bind( msc->msc_ld,
|
||||
binddn.bv_val, LDAP_SASL_SIMPLE,
|
||||
&cred, NULL, NULL, &msgid );
|
||||
rc = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
/* set rebind stuff in case of successful proxyAuthz bind,
|
||||
* so that referral chasing is attempted using the right
|
||||
* identity */
|
||||
LDAP_BACK_CONN_ISBOUND_SET( msc );
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &binddn );
|
||||
|
||||
if ( LDAP_BACK_SAVECRED( mi ) ) {
|
||||
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
|
||||
memset( msc->msc_cred.bv_val, 0,
|
||||
msc->msc_cred.bv_len );
|
||||
}
|
||||
ber_bvreplace( &msc->msc_cred, &cred );
|
||||
ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LDAP_BACK_CONN_ISBOUND( msc );
|
||||
}
|
||||
|
@ -214,10 +214,8 @@ meta_clear_candidates( Operation *op, metaconn_t *mc )
|
||||
int c;
|
||||
|
||||
for ( c = 0; c < mi->mi_ntargets; c++ ) {
|
||||
if ( mc->mc_conns[ c ].msc_ld != NULL ) {
|
||||
meta_clear_one_candidate( &mc->mc_conns[ c ] );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,6 +74,8 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
struct berval mdn = BER_BVNULL;
|
||||
struct berval mapped_attr = op->orc_ava->aa_desc->ad_cname;
|
||||
struct berval mapped_value = op->orc_ava->aa_value;
|
||||
metatarget_t *mt = mi->mi_targets[ i ];
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
if ( ! META_IS_CANDIDATE( &candidates[ i ] ) ) {
|
||||
msgid[ i ] = -1;
|
||||
@ -83,7 +85,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the compare dn, if needed
|
||||
*/
|
||||
dc.target = mi->mi_targets[ i ];
|
||||
dc.target = mt;
|
||||
|
||||
switch ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
case LDAP_UNWILLING_TO_PERFORM:
|
||||
@ -98,7 +100,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
* if attr is objectClass, try to remap the value
|
||||
*/
|
||||
if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass ) {
|
||||
ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_oc,
|
||||
ldap_back_map( &mt->mt_rwmap.rwm_oc,
|
||||
&op->orc_ava->aa_value,
|
||||
&mapped_value, BACKLDAP_MAP );
|
||||
|
||||
@ -109,7 +111,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
* else try to remap the attribute
|
||||
*/
|
||||
} else {
|
||||
ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_at,
|
||||
ldap_back_map( &mt->mt_rwmap.rwm_at,
|
||||
&op->orc_ava->aa_desc->ad_cname,
|
||||
&mapped_attr, BACKLDAP_MAP );
|
||||
if ( BER_BVISNULL( &mapped_attr ) || mapped_attr.bv_val[0] == '\0' ) {
|
||||
@ -132,6 +134,13 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
}
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ i ].msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* the compare op is spawned across the targets and the first
|
||||
* that returns determines the result; a constraint on unicity
|
||||
@ -139,7 +148,9 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
*/
|
||||
rc = ldap_compare_ext( mc->mc_conns[ i ].msc_ld, mdn.bv_val,
|
||||
mapped_attr.bv_val, &mapped_value,
|
||||
op->o_ctrls, NULL, &msgid[ i ] );
|
||||
ctrls, NULL, &msgid[ i ] );
|
||||
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
|
||||
free( mdn.bv_val );
|
||||
@ -208,6 +219,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( msc->msc_ld, res,
|
||||
&rs->sr_err,
|
||||
NULL, NULL, NULL, NULL, 1 );
|
||||
|
@ -781,10 +781,12 @@ meta_back_db_config(
|
||||
}
|
||||
|
||||
/* bind-defer? */
|
||||
} else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) {
|
||||
} else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0
|
||||
|| strcasecmp( argv[ 0 ], "root-bind-defer" ) == 0 )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n",
|
||||
"%s: line %d: \"[pseudo]root-bind-defer {FALSE|true}\" takes 1 argument\n",
|
||||
fname, lineno, 0 );
|
||||
return( 1 );
|
||||
}
|
||||
@ -800,7 +802,7 @@ meta_back_db_config(
|
||||
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\": invalid arg \"%s\".\n",
|
||||
"%s: line %d: \"[pseudo]root-bind-defer {FALSE|true}\": invalid arg \"%s\".\n",
|
||||
fname, lineno, argv[ 1 ] );
|
||||
return 1;
|
||||
}
|
||||
@ -956,15 +958,74 @@ meta_back_db_config(
|
||||
return 1;
|
||||
}
|
||||
|
||||
dn.bv_val = argv[ 1 ];
|
||||
dn.bv_len = strlen( argv[ 1 ] );
|
||||
if ( dnNormalize( 0, NULL, NULL, &dn,
|
||||
&mi->mi_targets[ i ]->mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
|
||||
/*
|
||||
* exact replacement:
|
||||
*
|
||||
|
||||
idassert-bind bindmethod=simple
|
||||
binddn=<pseudorootdn>
|
||||
credentials=<pseudorootpw>
|
||||
mode=none
|
||||
flags=non-prescriptive
|
||||
idassert-authzFrom "dn:<rootdn>"
|
||||
|
||||
* so that only when authc'd as <rootdn> the proxying occurs
|
||||
* rebinding as the <pseudorootdn> without proxyAuthz.
|
||||
*/
|
||||
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"pseudorootdn\", \"pseudorootpw\" are no longer supported; "
|
||||
"use \"idassert-bind\" and \"idassert-authzFrom\" instead.\n",
|
||||
fname, lineno, 0 );
|
||||
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
|
||||
"pseudoroot DN '%s' is invalid\n",
|
||||
fname, lineno, argv[ 1 ] );
|
||||
return( 1 );
|
||||
char binddn[ SLAP_TEXT_BUFLEN ];
|
||||
char *cargv[] = {
|
||||
"idassert-bind",
|
||||
"bindmethod=simple",
|
||||
NULL,
|
||||
"mode=none",
|
||||
"flags=non-prescriptive",
|
||||
NULL
|
||||
};
|
||||
int cargc = 5;
|
||||
int rc;
|
||||
|
||||
if ( BER_BVISNULL( &be->be_rootndn ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: line %d: \"pseudorootpw\": \"rootdn\" must be defined first.\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( snprintf( binddn, sizeof( binddn ), "binddn=%s", argv[ 1 ] ) >= sizeof( binddn ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: line %d: \"pseudorootdn\" too long.\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
cargv[ 2 ] = binddn;
|
||||
|
||||
rc = slap_idassert_parse_cf( fname, lineno, cargc, cargv, &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert );
|
||||
if ( rc == 0 ) {
|
||||
struct berval bv;
|
||||
|
||||
if ( mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert_authz != NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: line %d: \"idassert-authzFrom\" already defined (discarded).\n",
|
||||
fname, lineno, 0 );
|
||||
ber_bvarray_free( mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert_authz );
|
||||
mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert_authz = NULL;
|
||||
}
|
||||
|
||||
assert( !BER_BVISNULL( &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert_authcDN ) );
|
||||
|
||||
bv.bv_len = STRLENOF( "dn:" ) + be->be_rootndn.bv_len;
|
||||
bv.bv_val = ber_memalloc( bv.bv_len + 1 );
|
||||
AC_MEMCPY( bv.bv_val, "dn:", STRLENOF( "dn:" ) );
|
||||
AC_MEMCPY( &bv.bv_val[ STRLENOF( "dn:" ) ], be->be_rootndn.bv_val, be->be_rootndn.bv_len + 1 );
|
||||
|
||||
ber_bvarray_add( &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert_authz, &bv );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* password to use as pseudo-root */
|
||||
@ -984,7 +1045,65 @@ meta_back_db_config(
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ]->mt_pseudorootpw );
|
||||
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"pseudorootdn\", \"pseudorootpw\" are no longer supported; "
|
||||
"use \"idassert-bind\" and \"idassert-authzFrom\" instead.\n",
|
||||
fname, lineno, 0 );
|
||||
|
||||
if ( BER_BVISNULL( &mi->mi_targets[ i ]->mt_idassert_authcDN ) ) {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: line %d: \"pseudorootpw\": \"pseudorootdn\" must be defined first.\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( !BER_BVISNULL( &mi->mi_targets[ i ]->mt_idassert_passwd ) ) {
|
||||
memset( mi->mi_targets[ i ]->mt_idassert_passwd.bv_val, 0,
|
||||
mi->mi_targets[ i ]->mt_idassert_passwd.bv_len );
|
||||
ber_memfree( mi->mi_targets[ i ]->mt_idassert_passwd.bv_val );
|
||||
}
|
||||
ber_str2bv( argv[ 1 ], 0, 1, &mi->mi_targets[ i ]->mt_idassert_passwd );
|
||||
|
||||
/* idassert-bind */
|
||||
} else if ( strcasecmp( argv[ 0 ], "idassert-bind" ) == 0 ) {
|
||||
if ( mi->mi_ntargets == 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"idassert-bind\" "
|
||||
"must appear inside a target specification.\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return slap_idassert_parse_cf( fname, lineno, argc, argv, &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert );
|
||||
|
||||
/* idassert-authzFrom */
|
||||
} else if ( strcasecmp( argv[ 0 ], "idassert-authzFrom" ) == 0 ) {
|
||||
if ( mi->mi_ntargets == 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"idassert-bind\" "
|
||||
"must appear inside a target specification.\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch ( argc ) {
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: missing <id> in \"idassert-authzFrom <id>\".\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: extra cruft after <id> in \"idassert-authzFrom <id>\".\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return slap_idassert_authzfrom_parse_cf( fname, lineno, argv[ 1 ], &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_idassert );
|
||||
|
||||
/* quarantine */
|
||||
} else if ( strcasecmp( argv[ 0 ], "quarantine" ) == 0 ) {
|
||||
|
@ -368,6 +368,7 @@ retry:;
|
||||
if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
int err;
|
||||
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rs->sr_err = ldap_parse_result( msc->msc_ld, res,
|
||||
&err, NULL, NULL, NULL, NULL, 1 );
|
||||
res = NULL;
|
||||
@ -443,21 +444,28 @@ retry:;
|
||||
*/
|
||||
|
||||
if ( ispriv ) {
|
||||
if ( !BER_BVISNULL( &mt->mt_pseudorootdn ) ) {
|
||||
ber_dupbv( &msc->msc_bound_ndn, &mt->mt_pseudorootdn );
|
||||
if ( !BER_BVISNULL( &mt->mt_pseudorootpw ) ) {
|
||||
ber_dupbv( &msc->msc_cred, &mt->mt_pseudorootpw );
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) ) {
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &mt->mt_idassert_authcDN );
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_passwd ) ) {
|
||||
ber_bvreplace( &msc->msc_cred, &mt->mt_idassert_passwd );
|
||||
}
|
||||
|
||||
} else {
|
||||
ber_str2bv( "", 0, 1, &msc->msc_bound_ndn );
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &slap_empty_bv );
|
||||
}
|
||||
|
||||
LDAP_BACK_CONN_ISPRIV_SET( msc );
|
||||
|
||||
} else {
|
||||
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
|
||||
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
|
||||
ber_memfree_x( msc->msc_cred.bv_val, NULL );
|
||||
BER_BVZERO( &msc->msc_cred );
|
||||
}
|
||||
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
|
||||
ber_memfree_x( msc->msc_bound_ndn.bv_val, NULL );
|
||||
BER_BVZERO( &msc->msc_bound_ndn );
|
||||
}
|
||||
if ( !BER_BVISEMPTY( &op->o_ndn )
|
||||
&& SLAP_IS_AUTHZ_BACKEND( op )
|
||||
&& isauthz )
|
||||
@ -484,7 +492,7 @@ retry:;
|
||||
}
|
||||
|
||||
} else {
|
||||
ber_str2bv( "", 0, 1, &msc->msc_bound_ndn );
|
||||
ber_dupbv( &msc->msc_bound_ndn, &slap_empty_bv );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ int
|
||||
meta_back_delete( Operation *op, SlapReply *rs )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt;
|
||||
metaconn_t *mc = NULL;
|
||||
int candidate = -1;
|
||||
struct berval mdn = BER_BVNULL;
|
||||
@ -42,6 +43,7 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
int maperr = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
@ -53,7 +55,8 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the compare dn, if needed
|
||||
*/
|
||||
dc.target = mi->mi_targets[ candidate ];
|
||||
mt = mi->mi_targets[ candidate ];
|
||||
dc.target = mt;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "deleteDN";
|
||||
@ -63,9 +66,17 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
||||
goto done;
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
|
||||
{
|
||||
maperr = 0;
|
||||
goto sendres;
|
||||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_delete_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
mdn.bv_val, op->o_ctrls, NULL, &msgid );
|
||||
mdn.bv_val, ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
@ -78,8 +89,8 @@ retry:;
|
||||
LDAPMessage *res = NULL;
|
||||
int rc;
|
||||
|
||||
if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_DELETE ];
|
||||
if ( mt->mt_timeout[ LDAP_BACK_OP_DELETE ] != 0 ) {
|
||||
tv.tv_sec = mt->mt_timeout[ LDAP_BACK_OP_DELETE ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
@ -100,6 +111,7 @@ retry:;
|
||||
break;
|
||||
|
||||
case LDAP_RES_DELETE:
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
res, &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
@ -114,13 +126,16 @@ retry:;
|
||||
}
|
||||
}
|
||||
|
||||
sendres:;
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( maperr ) {
|
||||
rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
|
||||
if ( META_BACK_TGT_QUARANTINE( mt ) ) {
|
||||
meta_back_quarantine( op, rs, candidate );
|
||||
}
|
||||
}
|
||||
|
@ -230,11 +230,26 @@ target_free(
|
||||
if ( !BER_BVISNULL( &mt->mt_bindpw ) ) {
|
||||
free( mt->mt_bindpw.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_pseudorootdn ) ) {
|
||||
free( mt->mt_pseudorootdn.bv_val );
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_authcID ) ) {
|
||||
ch_free( mt->mt_idassert_authcID.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_pseudorootpw ) ) {
|
||||
free( mt->mt_pseudorootpw.bv_val );
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) ) {
|
||||
ch_free( mt->mt_idassert_authcDN.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_passwd ) ) {
|
||||
ch_free( mt->mt_idassert_passwd.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_authzID ) ) {
|
||||
ch_free( mt->mt_idassert_authzID.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_sasl_mech ) ) {
|
||||
ch_free( mt->mt_idassert_sasl_mech.bv_val );
|
||||
}
|
||||
if ( !BER_BVISNULL( &mt->mt_idassert_sasl_realm ) ) {
|
||||
ch_free( mt->mt_idassert_sasl_realm.bv_val );
|
||||
}
|
||||
if ( mt->mt_idassert_authz != NULL ) {
|
||||
ber_bvarray_free( mt->mt_idassert_authz );
|
||||
}
|
||||
if ( mt->mt_rwmap.rwm_rw ) {
|
||||
rewrite_info_delete( &mt->mt_rwmap.rwm_rw );
|
||||
|
@ -35,6 +35,7 @@ int
|
||||
meta_back_modify( Operation *op, SlapReply *rs )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt;
|
||||
metaconn_t *mc;
|
||||
int rc = 0;
|
||||
int maperr = 1;
|
||||
@ -48,6 +49,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
@ -59,7 +61,8 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the modify dn, if needed
|
||||
*/
|
||||
dc.target = mi->mi_targets[ candidate ];
|
||||
mt = mi->mi_targets[ candidate ];
|
||||
dc.target = mt;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
dc.ctx = "modifyDN";
|
||||
@ -102,7 +105,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
mapped = ml->sml_desc->ad_cname;
|
||||
|
||||
} else {
|
||||
ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
|
||||
ldap_back_map( &mt->mt_rwmap.rwm_at,
|
||||
&ml->sml_desc->ad_cname, &mapped,
|
||||
BACKLDAP_MAP );
|
||||
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
|
||||
@ -129,11 +132,11 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
|
||||
struct ldapmapping *mapping;
|
||||
|
||||
ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
|
||||
ldap_back_mapping( &mt->mt_rwmap.rwm_oc,
|
||||
&ml->sml_values[ j ], &mapping, BACKLDAP_MAP );
|
||||
|
||||
if ( mapping == NULL ) {
|
||||
if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
|
||||
if ( mt->mt_rwmap.rwm_oc.drop_missing ) {
|
||||
continue;
|
||||
}
|
||||
mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
|
||||
@ -174,9 +177,17 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
}
|
||||
modv[ i ] = 0;
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
rc = ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
maperr = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
modv, op->o_ctrls, NULL, &msgid );
|
||||
modv, ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
@ -188,8 +199,8 @@ retry:;
|
||||
struct timeval tv, *tvp = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
|
||||
if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODIFY ];
|
||||
if ( mt->mt_timeout[ LDAP_BACK_OP_MODIFY ] != 0 ) {
|
||||
tv.tv_sec = mt->mt_timeout[ LDAP_BACK_OP_MODIFY ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
@ -210,6 +221,7 @@ retry:;
|
||||
break;
|
||||
|
||||
case LDAP_RES_MODIFY:
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
res, &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
@ -226,13 +238,15 @@ retry:;
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( maperr ) {
|
||||
rc = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
|
||||
if ( META_BACK_TGT_QUARANTINE( mt ) ) {
|
||||
meta_back_quarantine( op, rs, candidate );
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ int
|
||||
meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt;
|
||||
metaconn_t *mc;
|
||||
int candidate = -1;
|
||||
struct berval mdn = BER_BVNULL,
|
||||
@ -43,6 +44,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
int maperr = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
@ -51,6 +53,8 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
|
||||
assert( mc->mc_conns[ candidate ].msc_ld != NULL );
|
||||
|
||||
mt = mi->mi_targets[ candidate ];
|
||||
dc.target = mt;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
|
||||
@ -76,7 +80,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
*/
|
||||
|
||||
/* needs LDAPv3 */
|
||||
switch ( mi->mi_targets[ candidate ]->mt_version ) {
|
||||
switch ( mt->mt_version ) {
|
||||
case LDAP_VERSION3:
|
||||
break;
|
||||
|
||||
@ -97,7 +101,6 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the new superior, if defined and required
|
||||
*/
|
||||
dc.target = mi->mi_targets[ candidate ];
|
||||
dc.ctx = "newSuperiorDN";
|
||||
if ( ldap_back_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
@ -109,7 +112,6 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
/*
|
||||
* Rewrite the modrdn dn, if required
|
||||
*/
|
||||
dc.target = mi->mi_targets[ candidate ];
|
||||
dc.ctx = "modrDN";
|
||||
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
@ -117,11 +119,19 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
|
||||
{
|
||||
maperr = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_rename( mc->mc_conns[ candidate ].msc_ld,
|
||||
mdn.bv_val, op->orr_newrdn.bv_val,
|
||||
mnewSuperior.bv_val, op->orr_deleteoldrdn,
|
||||
op->o_ctrls, NULL, &msgid );
|
||||
ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
@ -134,8 +144,8 @@ retry:;
|
||||
LDAPMessage *res = NULL;
|
||||
int rc;
|
||||
|
||||
if ( mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ]->mt_timeout[ LDAP_BACK_OP_MODRDN ];
|
||||
if ( mt->mt_timeout[ LDAP_BACK_OP_MODRDN ] != 0 ) {
|
||||
tv.tv_sec = mt->mt_timeout[ LDAP_BACK_OP_MODRDN ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
@ -155,6 +165,7 @@ retry:;
|
||||
break;
|
||||
|
||||
case LDAP_RES_RENAME:
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
res, &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
@ -170,13 +181,15 @@ retry:;
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( maperr ) {
|
||||
meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
|
||||
if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
|
||||
if ( META_BACK_TGT_QUARANTINE( mt ) ) {
|
||||
meta_back_quarantine( op, rs, candidate );
|
||||
}
|
||||
}
|
||||
|
@ -76,11 +76,11 @@ meta_search_dobind_init(
|
||||
metatarget_t *mt = mi->mi_targets[ candidate ];
|
||||
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
|
||||
|
||||
char *binddn = "";
|
||||
struct berval cred = BER_BVC( "" );
|
||||
struct berval binddn = BER_BVC( "" ),
|
||||
cred = BER_BVC( "" );
|
||||
int method;
|
||||
|
||||
int rc;
|
||||
int nretries = 1;
|
||||
|
||||
meta_search_candidate_t retcode;
|
||||
|
||||
@ -108,42 +108,61 @@ meta_search_dobind_init(
|
||||
LDAP_BACK_CONN_BINDING_SET( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
if ( be_isroot( op ) && !BER_BVISNULL( &mt->mt_pseudorootdn ) ) {
|
||||
binddn = mt->mt_pseudorootdn.bv_val;
|
||||
cred = mt->mt_pseudorootpw;
|
||||
/* NOTE: this obsoletes pseudorootdn */
|
||||
if ( op->o_conn != NULL &&
|
||||
!op->o_do_not_cache &&
|
||||
( BER_BVISNULL( &msc->msc_bound_ndn ) ||
|
||||
BER_BVISEMPTY( &msc->msc_bound_ndn ) ||
|
||||
( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
|
||||
{
|
||||
rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, LDAP_BACK_DONTSEND, &binddn, &cred, &method );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto down;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise an anonymous bind is performed
|
||||
* (note: if the target was already bound, the anonymous
|
||||
* bind clears the previous bind).
|
||||
*/
|
||||
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
|
||||
ber_memfree( msc->msc_bound_ndn.bv_val );
|
||||
BER_BVZERO( &msc->msc_bound_ndn );
|
||||
/* NOTE: we copy things here, even if bind didn't succeed yet,
|
||||
* because the connection is not shared until bind is over */
|
||||
if ( !BER_BVISNULL( &binddn ) ) {
|
||||
ber_bvreplace( &msc->msc_bound_ndn, &binddn );
|
||||
if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &cred ) ) {
|
||||
ber_dupbv( &msc->msc_cred, &cred );
|
||||
}
|
||||
}
|
||||
|
||||
if ( LDAP_BACK_SAVECRED( mi ) && !BER_BVISNULL( &msc->msc_cred ) ) {
|
||||
/* destroy sensitive data */
|
||||
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
|
||||
ber_memfree( msc->msc_cred.bv_val );
|
||||
BER_BVZERO( &msc->msc_cred );
|
||||
if ( LDAP_BACK_CONN_ISBOUND( msc ) ) {
|
||||
/* idassert ws configured with SASL bind */
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
return META_SEARCH_CANDIDATE;
|
||||
}
|
||||
|
||||
/* paranoid */
|
||||
switch ( method ) {
|
||||
case LDAP_AUTH_NONE:
|
||||
case LDAP_AUTH_SIMPLE:
|
||||
/* do a simple bind with binddn, cred */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
retry:;
|
||||
assert( msc->msc_ld != NULL );
|
||||
|
||||
rc = ldap_sasl_bind( msc->msc_ld, binddn, LDAP_SASL_SIMPLE, &cred,
|
||||
rc = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred,
|
||||
NULL, NULL, &candidates[ candidate ].sr_msgid );
|
||||
switch ( rc ) {
|
||||
case LDAP_SUCCESS:
|
||||
META_BINDING_SET( &candidates[ candidate ] );
|
||||
return META_SEARCH_BINDING;
|
||||
|
||||
down:;
|
||||
case LDAP_SERVER_DOWN:
|
||||
if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
|
||||
nretries = 0;
|
||||
goto retry;
|
||||
if ( meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
|
||||
return META_SEARCH_CANDIDATE;
|
||||
}
|
||||
|
||||
if ( *mcp == NULL ) {
|
||||
@ -195,12 +214,14 @@ meta_search_dobind_result(
|
||||
|
||||
assert( msc->msc_ld != NULL );
|
||||
|
||||
/* FIXME: matched? referrals? response controls? */
|
||||
rc = ldap_parse_result( msc->msc_ld, res,
|
||||
&candidates[ candidate ].sr_err,
|
||||
NULL, NULL, NULL, NULL, 1 );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
rc = slap_map_api2result( &candidates[ candidate ] );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
candidates[ candidate ].sr_err = rc;
|
||||
}
|
||||
rc = slap_map_api2result( &candidates[ candidate ] );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
@ -248,6 +269,7 @@ meta_back_search_start(
|
||||
meta_search_candidate_t retcode;
|
||||
struct timeval tv, *tvp = NULL;
|
||||
int nretries = 1;
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
/* this should not happen; just in case... */
|
||||
if ( msc->msc_ld == NULL ) {
|
||||
@ -402,6 +424,15 @@ meta_back_search_start(
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
if ( ldap_back_proxy_authz_ctrl( &msc->msc_bound_ndn,
|
||||
mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
|
||||
{
|
||||
candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
|
||||
retcode = META_SEARCH_NOT_CANDIDATE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts the search
|
||||
*/
|
||||
@ -410,7 +441,7 @@ retry:;
|
||||
rc = ldap_search_ext( msc->msc_ld,
|
||||
mbase.bv_val, realscope, mfilter.bv_val,
|
||||
mapped_attrs, op->ors_attrsonly,
|
||||
op->o_ctrls, NULL, tvp, op->ors_slimit,
|
||||
ctrls, NULL, tvp, op->ors_slimit,
|
||||
&candidates[ candidate ].sr_msgid );
|
||||
switch ( rc ) {
|
||||
case LDAP_SUCCESS:
|
||||
@ -435,6 +466,8 @@ retry:;
|
||||
}
|
||||
|
||||
done:;
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( mapped_attrs ) {
|
||||
free( mapped_attrs );
|
||||
}
|
||||
@ -892,6 +925,7 @@ really_bad:;
|
||||
* back-meta would need to merge them
|
||||
* consistently (think of pagedResults...)
|
||||
*/
|
||||
/* FIXME: response controls? */
|
||||
rs->sr_err = ldap_parse_result( msc->msc_ld,
|
||||
res,
|
||||
&candidates[ i ].sr_err,
|
||||
|
Loading…
Reference in New Issue
Block a user