struct berval mdn = { 0, NULL };
int rc = 0;
ber_int_t msgid;
+ dncookie dc;
lc = ldap_back_getconn(op, rs);
if ( !lc ) {
/*
* Rewrite the bind dn if needed
*/
+ dc.rwmap = &li->rwmap;
#ifdef ENABLE_REWRITE
- switch ( rewrite_session( li->rwinfo, "bindDn",
- op->o_req_dn.bv_val,
- op->o_conn, &mdn.bv_val ) ) {
- case REWRITE_REGEXEC_OK:
- if ( mdn.bv_val == NULL ) {
- mdn = op->o_req_dn;
- } else {
- mdn.bv_len = strlen( mdn.bv_val );
- }
-
-#ifdef NEW_LOGGING
- LDAP_LOG( BACK_LDAP, DETAIL1,
- "[rw] bindDn: \"%s\" -> \"%s\"\n",
- op->o_req_dn.bv_val, mdn.bv_val, 0 );
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ARGS, "rw> bindDn: \"%s\" -> \"%s\"\n",
- op->o_req_dn.bv_val, mdn.bv_val, 0 );
-#endif /* !NEW_LOGGING */
- break;
-
- case REWRITE_REGEXEC_UNWILLING:
- send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
- "Operation not allowed" );
- return( -1 );
-
- case REWRITE_REGEXEC_ERR:
- send_ldap_error( op, rs, LDAP_OTHER,
- "Rewrite error" );
- return( -1 );
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "bindDn";
+#else
+ dc.tofrom = 1;
+ dc.normalized = 0;
+#endif
+ if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
+ send_ldap_result( op, rs );
+ return -1;
}
-#else /* !ENABLE_REWRITE */
- ldap_back_dn_massage( li, &op->o_req_dn, &mdn, 0, 1 );
-#endif /* !ENABLE_REWRITE */
if ( lc->bound_dn.bv_val ) {
ch_free( lc->bound_dn.bv_val );
}
lc->bound = 0;
/* method is always LDAP_AUTH_SIMPLE if we got here */
- rc = ldap_sasl_bind(lc->ld, mdn.bv_val, LDAP_SASL_SIMPLE,
+ rs->sr_err = ldap_sasl_bind(lc->ld, mdn.bv_val, LDAP_SASL_SIMPLE,
&op->oq_bind.rb_cred, op->o_ctrls, NULL, &msgid);
- rc = ldap_back_op_result( li, lc, op, rs, msgid, rc, 1 );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
if (rc == LDAP_SUCCESS) {
lc->bound = 1;
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
} else {
ber_dupbv( &lc->bound_dn, &op->o_req_dn );
}
+ mdn.bv_val = NULL;
+
if ( li->savecred ) {
if ( lc->cred.bv_val )
ch_free( lc->cred.bv_val );
}
}
+ if ( mdn.bv_val && mdn.bv_val != op->o_req_dn.bv_val ) {
+ free( mdn.bv_val );
+ }
+
return( rc );
}
LDAP *ld;
int is_priv = 0;
- /*
- * The local DN is the op->o_req_ndn if binding, otherwise
- * it's the op->o_conn->c_ndn
- */
- struct berval *cdn = &op->o_conn->c_ndn;
-
/* Searches for a ldapconn in the avl tree */
/* Explicit binds must not be shared */
- if ( op->o_tag == LDAP_REQ_BIND ) {
+ if ( op->o_tag == LDAP_REQ_BIND
+ || (op->o_conn
+ && (op->o_bd == op->o_conn->c_authz_backend ))) {
lc_curr.conn = op->o_conn;
- cdn = &op->o_req_ndn;
-
- } else if ( op->o_conn->c_ndn.bv_len ) {
- lc_curr.conn = op->o_conn;
-
} else {
lc_curr.conn = NULL;
}
- /* Internal searches are privileged. So is root. */
+ /* Internal searches are privileged and shared. So is root. */
if ( op->o_do_not_cache || be_isroot( li->be, &op->o_ndn ) ) {
lc_curr.local_dn = li->be->be_rootndn;
+ lc_curr.conn = NULL;
is_priv = 1;
} else {
- lc_curr.local_dn = *cdn;
+ lc_curr.local_dn = op->o_ndn;
}
+
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
lc = (struct ldapconn *)avl_find( li->conntree,
(caddr_t)&lc_curr, ldap_back_conn_cmp );
/* Looks like we didn't get a bind. Open a new session... */
if (!lc) {
- int vers = op->o_conn->c_protocol;
+ int vers = op->o_protocol;
rs->sr_err = ldap_initialize(&ld, li->url);
if (rs->sr_err != LDAP_SUCCESS) {
- rs->sr_err = ldap_back_map_result(rs->sr_err);
- rs->sr_text = "ldap_initialize() failed";
- send_ldap_result( op, rs );
+ rs->sr_err = ldap_back_map_result(rs);
+ if (rs->sr_text == NULL) {
+ rs->sr_text = "ldap_initialize() failed";
+ }
+ if (op->o_conn) send_ldap_result( op, rs );
+ rs->sr_text = NULL;
return( NULL );
}
/* Set LDAP version. This will always succeed: If the client
lc->ld = ld;
ber_dupbv( &lc->local_dn, &lc_curr.local_dn );
- if ( is_priv ) {
- ber_dupbv( &lc->cred, &li->bindpw );
- } else {
- lc->cred.bv_len = 0;
- lc->cred.bv_val = NULL;
- }
-
- ldap_pvt_thread_mutex_init( &lc->lc_mutex );
-
#ifdef ENABLE_REWRITE
/*
* Sets a cookie for the rewrite session
* since we may have different entries
* for the same connection
*/
- ( void )rewrite_session_init( li->rwinfo, op->o_conn );
+ ( void )rewrite_session_init( li->rwmap.rwm_rw, op->o_conn );
#endif /* ENABLE_REWRITE */
- if ( !is_priv && op->o_conn->c_dn.bv_len != 0 ) {
-
- /*
- * Rewrite the bind dn if needed
- */
-#ifdef ENABLE_REWRITE
+ ldap_pvt_thread_mutex_init( &lc->lc_mutex );
+
+ if ( is_priv ) {
+ ber_dupbv( &lc->cred, &li->bindpw );
+ ber_dupbv( &lc->bound_dn, &li->binddn );
+ } else {
+ lc->cred.bv_len = 0;
+ lc->cred.bv_val = NULL;
lc->bound_dn.bv_val = NULL;
lc->bound_dn.bv_len = 0;
- switch ( rewrite_session( li->rwinfo, "bindDn",
- op->o_conn->c_dn.bv_val,
- op->o_conn,
- &lc->bound_dn.bv_val ) ) {
- case REWRITE_REGEXEC_OK:
- if ( lc->bound_dn.bv_val == NULL ) {
- ber_dupbv( &lc->bound_dn,
- &op->o_conn->c_dn );
- } else {
- lc->bound_dn.bv_len = strlen( lc->bound_dn.bv_val );
- }
-#ifdef NEW_LOGGING
- LDAP_LOG( BACK_LDAP, DETAIL1,
- "[rw] bindDn: \"%s\" ->"
- " \"%s\"\n",
- op->o_conn->c_dn.bv_val,
- lc->bound_dn.bv_val, 0 );
-#else /* !NEW_LOGGING */
- Debug( LDAP_DEBUG_ARGS,
- "rw> bindDn: \"%s\" ->"
- " \"%s\"\n",
- op->o_conn->c_dn.bv_val,
- lc->bound_dn.bv_val, 0 );
-#endif /* !NEW_LOGGING */
- break;
-
- case REWRITE_REGEXEC_UNWILLING:
- send_ldap_error( op, rs,
- LDAP_UNWILLING_TO_PERFORM,
- "Operation not allowed" );
- return( NULL );
+ if ( op->o_conn->c_dn.bv_len != 0
+ && ( op->o_bd == op->o_conn->c_authz_backend ) ) {
- case REWRITE_REGEXEC_ERR:
- send_ldap_error( op, rs,
- LDAP_OTHER,
- "Rewrite error" );
- return( NULL );
- }
+ dncookie dc;
+ struct berval bv;
-#else /* !ENABLE_REWRITE */
- struct berval bv;
- ldap_back_dn_massage( li, &op->o_conn->c_dn, &bv, 0, 1 );
- if ( bv.bv_val == op->o_conn->c_dn.bv_val ) {
- ber_dupbv( &lc->bound_dn, &bv );
- } else {
- lc->bound_dn = bv;
- }
-#endif /* !ENABLE_REWRITE */
+ /*
+ * Rewrite the bind dn if needed
+ */
+ dc.rwmap = &li->rwmap;
+#ifdef ENABLE_REWRITE
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "bindDn";
+#else
+ dc.tofrom = 1;
+ dc.normalized = 0;
+#endif
- } else {
- lc->bound_dn.bv_val = NULL;
- lc->bound_dn.bv_len = 0;
+ if ( ldap_back_dn_massage( &dc, &op->o_conn->c_dn, &bv ) ) {
+ if (op->o_conn) send_ldap_result( op, rs );
+ return NULL;
+ }
+
+ if ( bv.bv_val == op->o_conn->c_dn.bv_val ) {
+ ber_dupbv( &lc->bound_dn, &bv );
+ } else {
+ lc->bound_dn = bv;
+ }
+ }
}
+
lc->bound = 0;
/* Inserts the newly created ldapconn in the avl tree */
/* Err could be -1 in case a duplicate ldapconn is inserted */
if ( rs->sr_err != 0 ) {
ldap_back_conn_free( lc );
- send_ldap_error( op, rs, LDAP_OTHER,
- "internal server error" );
+ if (op->o_conn) {
+ send_ldap_error( op, rs, LDAP_OTHER,
+ "internal server error" );
+ }
return( NULL );
}
} else {
int
ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
{
- struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
int rc;
ber_int_t msgid;
ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
if ( !lc->bound ) {
- rc = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val,
+ rs->sr_err = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val,
LDAP_SASL_SIMPLE, &lc->cred, NULL, NULL, &msgid);
- rc = ldap_back_op_result( li, lc, op, rs, msgid, rc, 0 );
+ rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
if (rc == LDAP_SUCCESS) {
lc->bound = 1;
}
/* Map API errors to protocol errors... */
int
-ldap_back_map_result(int err)
+ldap_back_map_result(SlapReply *rs)
{
- switch(err)
+ switch(rs->sr_err)
{
case LDAP_SERVER_DOWN:
return LDAP_UNAVAILABLE;
case LDAP_AUTH_UNKNOWN:
return LDAP_AUTH_METHOD_NOT_SUPPORTED;
case LDAP_FILTER_ERROR:
+ rs->sr_text = "Filter error";
return LDAP_OTHER;
case LDAP_USER_CANCELLED:
+ rs->sr_text = "User cancelled";
return LDAP_OTHER;
case LDAP_PARAM_ERROR:
return LDAP_PROTOCOL_ERROR;
case LDAP_NO_RESULTS_RETURNED:
return LDAP_NO_SUCH_OBJECT;
case LDAP_MORE_RESULTS_TO_RETURN:
+ rs->sr_text = "More results to return";
return LDAP_OTHER;
case LDAP_CLIENT_LOOP:
case LDAP_REFERRAL_LIMIT_EXCEEDED:
return LDAP_LOOP_DETECT;
default:
- if LDAP_API_ERROR(err)
+ if LDAP_API_ERROR(rs->sr_err)
return LDAP_OTHER;
else
- return err;
+ return rs->sr_err;
}
}
int
-ldap_back_op_result(struct ldapinfo *li, struct ldapconn *lc,
- Operation *op, SlapReply *rs, ber_int_t msgid, int err, int sendok)
+ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
+ ber_int_t msgid, int sendok)
{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
char *match = NULL;
LDAPMessage *res;
- int rc;
+ char *text = NULL;
rs->sr_text = NULL;
rs->sr_matched = NULL;
- if (err == LDAP_SUCCESS) {
+ if (rs->sr_err == LDAP_SUCCESS) {
if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
- ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &err);
+ ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
+ &rs->sr_err);
} else {
- rc = ldap_parse_result(lc->ld, res, &err, &match,
- (char **)&rs->sr_text, NULL, NULL, 1);
- if (rc != LDAP_SUCCESS) err = rc;
+ int rc = ldap_parse_result(lc->ld, res, &rs->sr_err,
+ &match, &text, NULL, NULL, 1);
+ rs->sr_text = text;
+ if (rc != LDAP_SUCCESS) rs->sr_err = rc;
}
}
- if (err != LDAP_SUCCESS) {
- err = ldap_back_map_result(err);
+
+ if (rs->sr_err != LDAP_SUCCESS) {
+ rs->sr_err = ldap_back_map_result(rs);
/* internal ops must not reply to client */
- if ( op->o_conn && !op->o_do_not_cache ) {
+ if ( op->o_conn && !op->o_do_not_cache && match ) {
+ struct berval dn, mdn;
+ dncookie dc;
+
+ dc.rwmap = &li->rwmap;
#ifdef ENABLE_REWRITE
- if (match) {
-
- switch(rewrite_session(li->rwinfo, "matchedDn", match, op->o_conn,
- (char **)&rs->sr_matched)) {
- case REWRITE_REGEXEC_OK:
- if (!rs->sr_matched) rs->sr_matched = match; break;
- case REWRITE_REGEXEC_UNWILLING:
- case REWRITE_REGEXEC_ERR:
- break;
- }
- }
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "matchedDn";
#else
- struct berval dn, mdn;
- if (match) {
- ber_str2bv(match, 0, 0, &dn);
- ldap_back_dn_massage(li, &dn, &mdn, 0, 0);
- rs->sr_matched = mdn.bv_val;
- }
+ dc.tofrom = 0;
+ dc.normalized = 0;
#endif
+ ber_str2bv(match, 0, 0, &dn);
+ ldap_back_dn_massage(&dc, &dn, &mdn);
+ rs->sr_matched = mdn.bv_val;
+
}
}
- if (sendok || err != LDAP_SUCCESS) {
- rs->sr_err = err;
+ if (op->o_conn && (sendok || rs->sr_err != LDAP_SUCCESS)) {
send_ldap_result( op, rs );
}
- if (rs->sr_matched != match) free((char *)rs->sr_matched);
- rs->sr_matched = NULL;
- if ( match ) ldap_memfree( match );
- if ( rs->sr_text ) {
- ldap_memfree( (char *)rs->sr_text );
- rs->sr_text = NULL;
+ if ( match ) {
+ if ( rs->sr_matched != match ) {
+ free( (char *)rs->sr_matched );
+ }
+ rs->sr_matched = NULL;
+ ldap_memfree( match );
}
- return( (err==LDAP_SUCCESS) ? 0 : -1 );
+ if ( text ) {
+ ldap_memfree( text );
+ }
+ rs->sr_text = NULL;
+ return( (rs->sr_err == LDAP_SUCCESS) ? 0 : -1 );
}