snprintf( buf, sizeof( buf ),
"conn %p fetched refcnt=%u%s",
- (void *)lc, refcnt, expiring ? " expiring" : "" );
+ (void *)lc, refcnt,
+ expiring ? " expiring" : "" );
Debug( LDAP_DEBUG_TRACE,
"=>ldap_back_getconn: %s.\n", buf, 0, 0 );
}
done:;
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;
#define META_BACK_F_ONERR_REPORT (0x00200000U)
#define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT)
#define META_BACK_F_DEFER_ROOTDN_BIND (0x00400000U)
-#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U)
+#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U) /* users always proxyauthz */
+#define META_BACK_F_PROXYAUTHZ_ANON (0x01000000U) /* anonymous always proxyauthz */
+#define META_BACK_F_PROXYAUTHZ_NOANON (0x02000000U) /* anonymous remains anonymous */
-#define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
-#define META_BACK_ONERR_REPORT(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_REPORT )
-#define META_BACK_ONERR_CONTINUE(mi) ( !( (mi)->mi_flags & META_BACK_F_ONERR_MASK ) )
+#define META_BACK_ONERR_STOP(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_STOP )
+#define META_BACK_ONERR_REPORT(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_REPORT )
+#define META_BACK_ONERR_CONTINUE(mi) ( !LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_MASK ) )
-#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
-#define META_BACK_PROXYAUTHZ_ALWAYS(mi) ( (mi)->mi_flags & META_BACK_F_PROXYAUTHZ_ALWAYS )
+#define META_BACK_DEFER_ROOTDN_BIND(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_DEFER_ROOTDN_BIND )
+#define META_BACK_PROXYAUTHZ_ALWAYS(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ALWAYS )
+#define META_BACK_PROXYAUTHZ_ANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ANON )
+#define META_BACK_PROXYAUTHZ_NOANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_NOANON )
int mi_version;
time_t mi_network_timeout;
extern void
meta_back_release_conn_lock(
- Operation *op,
+ metainfo_t *mi,
metaconn_t *mc,
int dolock );
-#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 )
+#define meta_back_release_conn(mi, mc) meta_back_release_conn_lock( (mi), (mc), 1 )
extern int
meta_back_retry(
ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) );
}
- if ( !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) {
+ if ( !LDAP_BACK_PCONN_ISPRIV( mc )
+ && !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) )
+ {
metaconn_t *tmpmc;
int lerr;
}
if ( mc != NULL ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
/*
LDAP_BACK_CONN_BINDING_CLEAR( msc );
if ( META_BACK_ONERR_STOP( mi ) ) {
LDAP_BACK_CONN_TAINTED_SET( mc );
- meta_back_release_conn_lock( op, mc, 0 );
+ meta_back_release_conn_lock( mi, mc, 0 );
*mcp = NULL;
}
if ( dolock ) {
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 );
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return 0;
op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound );
if ( bound == 0 ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
send_err:;
if ( sendok & LDAP_BACK_SENDERR ) {
default:
/* NOTE: rootdn can always idassert */
- if ( BER_BVISNULL( &ndn ) && mt->mt_idassert_authz == NULL ) {
+ if ( BER_BVISNULL( &ndn )
+ && mt->mt_idassert_authz == NULL
+ && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
+ {
if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
if ( sendok & LDAP_BACK_SENDERR ) {
}
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;
* let the caller do what's best before
* releasing */
if ( META_BACK_ONERR_STOP( mi ) ) {
- meta_back_release_conn_lock( op, mc, 0 );
+ meta_back_release_conn_lock( mi, mc, 0 );
*mcp = NULL;
} else {
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
mc, mc_q );
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
- mc->mc_q.tqe_prev = NULL;
- mc->mc_q.tqe_next = NULL;
+ LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
} else {
assert( !LDAP_BACK_CONN_CACHED( mc ) );
SlapReply *candidates = meta_back_candidates_get( op );
/* Internal searches are privileged and shared. So is root. */
- /* FIXME: there seems to be concurrency issues */
- if ( META_BACK_PROXYAUTHZ_ALWAYS( mi ) || op->o_do_not_cache || be_isroot( op ) ) {
- mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
+ if ( ( !BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ALWAYS( mi ) )
+ || ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ANON( mi ) )
+ || op->o_do_not_cache || be_isroot( op ) )
+ {
LDAP_BACK_CONN_ISPRIV_SET( &mc_curr );
+ mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
LDAP_BACK_PCONN_ROOTDN_SET( &mc_curr, op );
+ } else if ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_NOANON( mi ) )
+ {
+ LDAP_BACK_CONN_ISANON_SET( &mc_curr );
+ BER_BVSTR( &mc_curr.mc_local_ndn, "" );
+ LDAP_BACK_PCONN_ANON_SET( &mc_curr, op );
+
} else {
mc_curr.mc_local_ndn = op->o_ndn;
/* Explicit binds must not be shared */
- if ( op->o_tag == LDAP_REQ_BIND || SLAP_IS_AUTHZ_BACKEND( op ) ) {
+ if ( !BER_BVISEMPTY( &op->o_ndn )
+ || op->o_tag == LDAP_REQ_BIND
+ || SLAP_IS_AUTHZ_BACKEND( op ) )
+ {
mc_curr.mc_conn = op->o_conn;
} else {
}
/* Explicit Bind requests always get their own conn */
- if ( !( sendok & LDAP_BACK_BINDING ) ) {
+ if ( sendok & LDAP_BACK_BINDING ) {
+ mc_curr.mc_conn = op->o_conn;
+
+ } else {
/* Searches for a metaconn in the avl tree */
retry_lock:;
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
{
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
mc, mc_q );
- mc->mc_q.tqe_prev = NULL;
- mc->mc_q.tqe_next = NULL;
+ LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
LDAP_TAILQ_INSERT_TAIL( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
mc, mc_q );
}
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
mc, mc_q );
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
- mc->mc_q.tqe_prev = NULL;
- mc->mc_q.tqe_next = NULL;
+ LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
} else {
assert( !LDAP_BACK_CONN_CACHED( mc ) );
meta_back_conn_free( mc );
} else {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
rs->sr_err = LDAP_NO_SUCH_OBJECT;
if ( i < 0 || rs->sr_err != LDAP_SUCCESS ) {
if ( mc != NULL ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
if ( sendok & LDAP_BACK_SENDERR ) {
if ( dn_type == META_DNTYPE_NEWPARENT && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
{
if ( mc != NULL ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
meta_back_conn_free( mc );
} else {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return NULL;
}
meta_back_conn_free( mc );
} else {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return NULL;
meta_back_conn_free( mc );
} else {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
if ( rs->sr_err == LDAP_SUCCESS ) {
void
meta_back_release_conn_lock(
- Operation *op,
+ metainfo_t *mi,
metaconn_t *mc,
int dolock )
{
- metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
-
assert( mc != NULL );
if ( dolock ) {
* the connection space (and eat up resources). Maybe this
* should be configurable... */
if ( LDAP_BACK_CONN_TAINTED( mc ) ) {
- Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld tainted.\n",
- op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
#if META_BACK_PRINT_CONNTREE > 0
meta_back_print_conntree( mi, ">>> meta_back_release_conn" );
#endif /* META_BACK_PRINT_CONNTREE */
if ( mc->mc_q.tqe_prev != NULL ) {
assert( LDAP_BACK_CONN_CACHED( mc ) );
assert( mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num > 0 );
- mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q );
+ mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
+ LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
} else {
assert( !LDAP_BACK_CONN_CACHED( mc ) );
}
- mc->mc_q.tqe_prev = NULL;
- mc->mc_q.tqe_next = NULL;
} else {
metaconn_t *tmpmc;
tmpmc = avl_delete( &mi->mi_conninfo.lai_tree,
( caddr_t )mc, meta_back_conndnmc_cmp );
- if ( tmpmc == NULL ) {
- Debug( LDAP_DEBUG_TRACE, "%s: meta_back_release_conn: unable to find mc=%p\n",
- op->o_log_prefix, (void *)mc, 0 );
- } else {
- assert( tmpmc == mc );
- }
+ assert( tmpmc == NULL && tmpmc == mc );
}
LDAP_BACK_CONN_CACHED_CLEAR( mc );
}
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;
int i,
not_always = 0,
+ not_always_anon_proxyauthz = 0,
+ not_always_anon_non_prescriptive = 0,
rc;
for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( not_always == 0 ) {
if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
- || !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
+ || mt->mt_idassert_authz != NULL )
{
not_always = 1;
}
}
+
+ if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
+ && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
+ {
+ Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
+ "target #%d inconsistent idassert configuration "
+ "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
+ be->be_suffix[ 0 ].bv_val, i, 0 );
+ return 1;
+ }
+
+ if ( not_always_anon_proxyauthz == 0 ) {
+ if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
+ {
+ not_always_anon_proxyauthz = 1;
+ }
+ }
+
+ if ( not_always_anon_non_prescriptive == 0 ) {
+ if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
+ {
+ not_always_anon_non_prescriptive = 1;
+ }
+ }
}
if ( not_always == 0 ) {
mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
}
+ if ( not_always_anon_proxyauthz == 0 ) {
+ mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;
+
+ } else if ( not_always_anon_non_prescriptive == 0 ) {
+ mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
+ }
+
return 0;
}
free( modv );
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;
}
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;
candidates[ candidate ].sr_err = rc;
if ( META_BACK_ONERR_STOP( mi ) ) {
LDAP_BACK_CONN_TAINTED_SET( mc );
- meta_back_release_conn_lock( op, mc, 0 );
+ meta_back_release_conn_lock( mi, mc, 0 );
*mcp = NULL;
rs->sr_err = rc;
candidates[ candidate ].sr_err = rc;
if ( META_BACK_ONERR_STOP( mi ) ) {
LDAP_BACK_CONN_TAINTED_SET( mc );
- meta_back_release_conn_lock( op, mc, 0 );
+ meta_back_release_conn_lock( mi, mc, 0 );
*mcp = NULL;
retcode = META_SEARCH_ERR;
rs->sr_err = rc;
op->o_log_prefix, (void *)mc, 0 );
#endif /* DEBUG_205 */
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
mc = NULL;
needbind = 0;
}
if ( mc ) {
- meta_back_release_conn( op, mc );
+ meta_back_release_conn( mi, mc );
}
return rs->sr_err;