op->o_req_dn.bv_val, 0, 0);
/* allow noauth binds */
- if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
- ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
- /* front end will send result */
- return LDAP_SUCCESS;
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ /* in case of success, frontend will send result;
+ * otherwise, be_rootdn_bind() did */
+ return rs->sr_err;
}
rs->sr_err = LOCK_ID(bdb->bi_dbenv, &locker);
int
dnssrv_back_bind(
- Operation *op,
- SlapReply *rs )
+ Operation *op,
+ SlapReply *rs )
{
- Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind %s (%d)\n",
- op->o_req_dn.bv_val == NULL ? "" : op->o_req_dn.bv_val,
- op->oq_bind.rb_method, NULL );
-
- if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE &&
- !BER_BVISNULL( &op->oq_bind.rb_cred ) &&
- !BER_BVISEMPTY( &op->oq_bind.rb_cred ) )
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind dn=\"%s\" (%d)\n",
+ BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val,
+ op->orb_method, 0 );
+
+ /* allow rootdn as a means to auth without the need to actually
+ * contact the proxied DSA */
+ switch ( be_rootdn_bind( op, NULL ) ) {
+ case LDAP_SUCCESS:
+ /* frontend will send result */
+ return rs->sr_err;
+
+ default:
+ /* treat failure and like any other bind, otherwise
+ * it could reveal the DN of the rootdn */
+ break;
+ }
+
+ if ( !BER_BVISNULL( &op->orb_cred ) &&
+ !BER_BVISEMPTY( &op->orb_cred ) )
{
+ /* simple bind */
Statslog( LDAP_DEBUG_STATS,
- "%s DNSSRV BIND dn=\"%s\" provided passwd\n",
+ "%s DNSSRV BIND dn=\"%s\" provided cleartext passwd\n",
op->o_log_prefix,
BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val , 0, 0, 0 );
- Debug( LDAP_DEBUG_TRACE,
- "DNSSRV: BIND dn=\"%s\" provided cleartext password\n",
- BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
-
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
"you shouldn't send strangers your password" );
} else {
+ /* unauthenticated bind */
+ /* NOTE: we're not going to get here anyway:
+ * unauthenticated bind is dealt with by the frontend */
Debug( LDAP_DEBUG_TRACE, "DNSSRV: BIND dn=\"%s\"\n",
BER_BVISNULL( &op->o_req_dn ) ? "" : op->o_req_dn.bv_val, 0, 0 );
ber_int_t msgid;
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
+ /* allow rootdn as a means to auth without the need to actually
+ * contact the proxied DSA */
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ return rs->sr_err;
+ }
+
lc = ldap_back_getconn( op, rs, LDAP_BACK_BIND_SERR, NULL, NULL );
if ( !lc ) {
return rs->sr_err;
int return_val = 0;
Entry * entry = NULL;
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ /* in case of success, front end will send result;
+ * otherwise, be_rootdn_bind() did */
+ return rs->sr_err;
+ }
+
li = (struct ldif_info *) op->o_bd->be_private;
ldap_pvt_thread_rdwr_rlock(&li->li_rdwr);
entry = get_entry(op, &li->li_base_path);
/* no object is found for them */
if(entry == NULL) {
- if(be_isroot_pw(op)) {
- rs->sr_err = return_val = LDAP_SUCCESS;
- } else {
- rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
- }
+ rs->sr_err = return_val = LDAP_INVALID_CREDENTIALS;
goto return_result;
}
op->o_log_prefix, op->o_req_dn.bv_val, 0 );
/* the test on the bind method should be superfluous */
- if ( op->orb_method == LDAP_AUTH_SIMPLE
- && be_isroot_dn( op->o_bd, &op->o_req_ndn ) )
- {
- if ( !be_isroot_pw( op ) ) {
- rs->sr_err = LDAP_INVALID_CREDENTIALS;
- rs->sr_text = NULL;
- send_ldap_result( op, rs );
- return rs->sr_err;
- }
-
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case LDAP_SUCCESS:
if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
- rs->sr_err = LDAP_SUCCESS;
- rs->sr_text = NULL;
/* frontend will return success */
return rs->sr_err;
}
isroot = 1;
+ /* fallthru */
+
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ /* be_rootdn_bind() sent result */
+ return rs->sr_err;
}
/* we need meta_back_getconn() not send result even on error,
{
Debug(LDAP_DEBUG_ARGS, "==> monitor_back_bind: dn: %s\n",
op->o_req_dn.bv_val, 0, 0 );
-
- if ( op->oq_bind.rb_method == LDAP_AUTH_SIMPLE
- && be_isroot_pw( op ) )
- {
- ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
+
+ if ( be_isroot_pw( op ) ) {
return LDAP_SUCCESS;
}
PerlBackend *perl_back = (PerlBackend *) op->o_bd->be_private;
+ /* allow rootdn as a means to auth without the need to actually
+ * contact the proxied DSA */
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ return rs->sr_err;
+ }
+
#if defined(HAVE_WIN32_ASPERL) || defined(USE_ITHREADS)
PERL_SET_CONTEXT( PERL_INTERPRETER );
#endif
BackendDB *bd;
int rc = 1;
+ /* allow rootdn as a means to auth without the need to actually
+ * contact the proxied DSA */
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ return rs->sr_err;
+ }
+
bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS, 1 );
if ( bd == NULL ) {
return rc;
FILE *rfp, *wfp;
int rc;
+ /* allow rootdn as a means to auth without the need to actually
+ * contact the proxied DSA */
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ return rs->sr_err;
+ }
+
if ( si->si_bind == NULL ) {
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
"bind not implemented" );
Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
- if ( be_isroot_pw( op ) ) {
- ber_dupbv( &op->oq_bind.rb_edn, be_root_dn( op->o_bd ) );
- Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n",
- 0, 0, 0 );
- return LDAP_SUCCESS;
- }
-
- ber_dupbv( &op->oq_bind.rb_edn, &op->o_req_ndn );
-
- if ( op->oq_bind.rb_method != LDAP_AUTH_SIMPLE ) {
- rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED;
- rs->sr_text = "authentication method not supported";
- send_ldap_result( op, rs );
+ switch ( be_rootdn_bind( op, rs ) ) {
+ case SLAP_CB_CONTINUE:
+ break;
+
+ default:
+ /* in case of success, front end will send result;
+ * otherwise, be_rootdn_bind() did */
+ Debug( LDAP_DEBUG_TRACE, "<==backsql_bind(%d)\n",
+ rs->sr_err, 0, 0 );
return rs->sr_err;
}
- /*
- * method = LDAP_AUTH_SIMPLE
- */
rs->sr_err = backsql_get_db_conn( op, &dbh );
if ( !dbh ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
int
be_isroot_pw( Operation *op )
{
- int result;
+ return be_rootdn_bind( op, NULL ) == LDAP_SUCCESS;
+}
- if ( ! be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
- return 0;
+/*
+ * checks if binding as rootdn
+ *
+ * return value:
+ * SLAP_CB_CONTINUE if not the rootdn
+ * LDAP_SUCCESS if rootdn & rootpw
+ * LDAP_INVALID_CREDENTIALS if rootdn & !rootpw
+ *
+ * if rs != NULL
+ * if LDAP_SUCCESS, op->orb_edn is set
+ * if LDAP_INVALID_CREDENTIALS, response is sent to client
+ */
+int
+be_rootdn_bind( Operation *op, SlapReply *rs )
+{
+ int rc;
+
+ assert( op->o_tag == LDAP_REQ_BIND );
+ assert( op->orb_method == LDAP_AUTH_SIMPLE );
+
+ if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
+ return SLAP_CB_CONTINUE;
}
if ( BER_BVISEMPTY( &op->o_bd->be_rootpw ) ) {
- return 0;
+ rc = LDAP_INVALID_CREDENTIALS;
+ if ( rs ) {
+ goto send_result;
+ }
+
+ return rc;
}
#ifdef SLAPD_SPASSWD
op->o_conn->c_sasl_authctx, NULL );
#endif
- result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
+ rc = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
#ifdef SLAPD_SPASSWD
ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, NULL, NULL );
#endif
- return result == 0;
+ rc = ( rc == 0 ? LDAP_SUCCESS : LDAP_INVALID_CREDENTIALS );
+ if ( rs ) {
+send_result:;
+ rs->sr_err = rc;
+
+ Debug( LDAP_DEBUG_TRACE, "%s: rootdn=\"%s\" bind%s\n",
+ op->o_log_prefix, op->o_bd->be_rootdn.bv_val,
+ rc == LDAP_SUCCESS ? " succeeded" : " failed" );
+
+ if ( rc == LDAP_SUCCESS ) {
+ /* Set to the pretty rootdn */
+ ber_dupbv( &op->orb_edn, &op->o_bd->be_rootdn );
+
+ } else {
+ send_ldap_result( op, rs );
+ }
+ }
+
+ return rc;
}
int
static int
config_back_bind( Operation *op, SlapReply *rs )
{
- if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+ if ( be_isroot_pw( op ) ) {
ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
/* frontend sends result */
return LDAP_SUCCESS;
case LDAP_REQ_BIND:
/* skip if rootdn */
+ /* FIXME: better give the db a chance? */
if ( be_isroot_pw( op ) ) {
return LDAP_SUCCESS;
}
LDAP_SLAPD_F (int) be_isroot LDAP_P(( Operation *op ));
LDAP_SLAPD_F (int) be_isroot_dn LDAP_P(( Backend *be, struct berval *ndn ));
LDAP_SLAPD_F (int) be_isroot_pw LDAP_P(( Operation *op ));
+LDAP_SLAPD_F (int) be_rootdn_bind LDAP_P(( Operation *op, SlapReply *rs ));
LDAP_SLAPD_F (int) be_slurp_update LDAP_P(( Operation *op ));
#define be_isupdate( op ) be_slurp_update( (op) )
LDAP_SLAPD_F (int) be_shadow_update LDAP_P(( Operation *op ));