From: Pierangelo Masarati Date: Sat, 19 Nov 2005 15:00:50 +0000 (+0000) Subject: fix dangling resources issue in slapd-ldap; completely rework slapo-chain to fix... X-Git-Tag: OPENLDAP_REL_ENG_2_4_BP~779 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=7fa4b159bffe1ac0e357994f78d2e419f4d83f18;p=openldap fix dangling resources issue in slapd-ldap; completely rework slapo-chain to fix the resource leak/concurrency issue; add support for multiple well-known URIs to set credentials for, and deal with unknown URIs anonymously; similar reworking and cleanup for slapd-meta --- diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index 0c394c3645..c15fdd0e9f 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -36,9 +36,9 @@ ldap_back_add( Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - struct ldapconn *lc; + ldapconn_t *lc; int i = 0, j = 0; Attribute *a; @@ -103,10 +103,10 @@ retry: rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs, ctrls, NULL, &msgid ); rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, - li->timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT ); + li->li_timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index f0a4330ac4..5eaddcc398 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -26,7 +26,7 @@ LDAP_BEGIN_DECL -struct ldapconn { +typedef struct ldapconn_t { Connection *lc_conn; #define LDAP_BACK_PCONN ((void *)0x0) #define LDAP_BACK_PCONN_TLS ((void *)0x1) @@ -79,7 +79,7 @@ struct ldapconn { unsigned lc_refcnt; unsigned lc_flags; -}; +} ldapconn_t; /* * identity assertion modes @@ -104,50 +104,58 @@ enum { LDAP_BACK_OP_LAST }; -struct ldapinfo { - char *url; - LDAPURLDesc *lud; - - slap_bindconf acl_sb; -#define acl_authcID acl_sb.sb_authcId -#define acl_authcDN acl_sb.sb_binddn -#define acl_passwd acl_sb.sb_cred -#define acl_authzID acl_sb.sb_authzId -#define acl_authmethod acl_sb.sb_method -#define acl_sasl_mech acl_sb.sb_saslmech -#define acl_sasl_realm acl_sb.sb_realm -#define acl_secprops acl_sb.sb_secprops +typedef struct ldap_avl_info_t { + ldap_pvt_thread_mutex_t lai_mutex; + Avlnode *lai_tree; +} ldap_avl_info_t; + +typedef struct ldapinfo_t { + /* li_uri: the string that goes into ldap_initialize() + * TODO: use li_acl.sb_uri instead */ + char *li_uri; + /* li_bvuri: an array of each single URI that is equivalent; + * to be checked for the presence of a certain item */ + BerVarray li_bvuri; + + slap_bindconf li_acl; +#define li_acl_authcID li_acl.sb_authcId +#define li_acl_authcDN li_acl.sb_binddn +#define li_acl_passwd li_acl.sb_cred +#define li_acl_authzID li_acl.sb_authzId +#define li_acl_authmethod li_acl.sb_method +#define li_acl_sasl_mech li_acl.sb_saslmech +#define li_acl_sasl_realm li_acl.sb_realm +#define li_acl_secprops li_acl.sb_secprops /* ID assert stuff */ - int idassert_mode; - - slap_bindconf idassert_sb; -#define idassert_authcID idassert_sb.sb_authcId -#define idassert_authcDN idassert_sb.sb_binddn -#define idassert_passwd idassert_sb.sb_cred -#define idassert_authzID idassert_sb.sb_authzId -#define idassert_authmethod idassert_sb.sb_method -#define idassert_sasl_mech idassert_sb.sb_saslmech -#define idassert_sasl_realm idassert_sb.sb_realm -#define idassert_secprops idassert_sb.sb_secprops - - unsigned idassert_flags; + 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 - BerVarray idassert_authz; + BerVarray li_idassert_authz; /* end of ID assert stuff */ - int nretries; + int li_nretries; #define LDAP_BACK_RETRY_UNDEFINED (-2) #define LDAP_BACK_RETRY_FOREVER (-1) #define LDAP_BACK_RETRY_NEVER (0) #define LDAP_BACK_RETRY_DEFAULT (3) - ldap_pvt_thread_mutex_t conn_mutex; - unsigned flags; + unsigned li_flags; #define LDAP_BACK_F_NONE 0x00U #define LDAP_BACK_F_SAVECRED 0x01U #define LDAP_BACK_F_USE_TLS 0x02U @@ -163,23 +171,18 @@ struct ldapinfo { #define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x40U #define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER) -#define LDAP_BACK_SAVECRED(li) ( (li)->flags & LDAP_BACK_F_SAVECRED ) -#define LDAP_BACK_USE_TLS(li) ( (li)->flags & LDAP_BACK_F_USE_TLS ) -#define LDAP_BACK_PROPAGATE_TLS(li) ( (li)->flags & LDAP_BACK_F_PROPAGATE_TLS ) -#define LDAP_BACK_TLS_CRITICAL(li) ( (li)->flags & LDAP_BACK_F_TLS_CRITICAL ) -#define LDAP_BACK_CHASE_REFERRALS(li) ( (li)->flags & LDAP_BACK_F_CHASE_REFERRALS ) +#define LDAP_BACK_SAVECRED(li) ( (li)->li_flags & LDAP_BACK_F_SAVECRED ) +#define LDAP_BACK_USE_TLS(li) ( (li)->li_flags & LDAP_BACK_F_USE_TLS ) +#define LDAP_BACK_PROPAGATE_TLS(li) ( (li)->li_flags & LDAP_BACK_F_PROPAGATE_TLS ) +#define LDAP_BACK_TLS_CRITICAL(li) ( (li)->li_flags & LDAP_BACK_F_TLS_CRITICAL ) +#define LDAP_BACK_CHASE_REFERRALS(li) ( (li)->li_flags & LDAP_BACK_F_CHASE_REFERRALS ) - int version; + int li_version; - Avlnode *conntree; + ldap_avl_info_t li_conninfo; -#if 0 - /* FIXME: automatic rwm instantiation removed */ - int rwm_started; -#endif - - time_t timeout[ LDAP_BACK_OP_LAST ]; -}; + time_t li_timeout[ LDAP_BACK_OP_LAST ]; +} ldapinfo_t; typedef enum ldap_back_send_t { LDAP_BACK_DONTSEND = 0x00, diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index a77af50c9f..266136dc3f 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -42,16 +42,16 @@ static LDAP_REBIND_PROC ldap_back_default_rebind; LDAP_REBIND_PROC *ldap_back_rebind_f = ldap_back_default_rebind; static int -ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ); +ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ); static int -ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); +ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); int ldap_back_bind( Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; - struct ldapconn *lc; + ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; + ldapconn_t *lc; int rc = 0; ber_int_t msgid; @@ -79,7 +79,7 @@ ldap_back_bind( Operation *op, SlapReply *rs ) * purpose, a successful bind is followed by a * bind with the configured identity assertion */ /* NOTE: use with care */ - if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { ldap_back_proxy_authz_bind( lc, op, rs ); if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) { rc = 1; @@ -109,22 +109,22 @@ done:; /* wait for all other ops to release the connection */ retry_lock:; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); if ( lc->lc_refcnt > 1 ) { - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); ldap_pvt_thread_yield(); goto retry_lock; } assert( lc->lc_refcnt == 1 ); - lc = avl_delete( &li->conntree, (caddr_t)lc, + lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ); assert( lc != NULL ); ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn ); - lerr = avl_insert( &li->conntree, (caddr_t)lc, + lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp, ldap_back_conn_dup ); - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); if ( lerr == -1 ) { /* we can do this because lc_refcnt == 1 */ ldap_back_conn_free( lc ); @@ -142,14 +142,14 @@ retry_lock:; /* * ldap_back_conn_cmp * - * compares two struct ldapconn based on the value of the conn pointer; + * compares two ldapconn_t based on the value of the conn pointer; * used by avl stuff */ int ldap_back_conn_cmp( const void *c1, const void *c2 ) { - const struct ldapconn *lc1 = (const struct ldapconn *)c1; - const struct ldapconn *lc2 = (const struct ldapconn *)c2; + const ldapconn_t *lc1 = (const ldapconn_t *)c1; + const ldapconn_t *lc2 = (const ldapconn_t *)c2; int rc; /* If local DNs don't match, it is definitely not a match */ @@ -167,14 +167,14 @@ ldap_back_conn_cmp( const void *c1, const void *c2 ) /* * ldap_back_conn_dup * - * returns -1 in case a duplicate struct ldapconn has been inserted; + * returns -1 in case a duplicate ldapconn_t has been inserted; * used by avl stuff */ int ldap_back_conn_dup( void *c1, void *c2 ) { - struct ldapconn *lc1 = (struct ldapconn *)c1; - struct ldapconn *lc2 = (struct ldapconn *)c2; + ldapconn_t *lc1 = (ldapconn_t *)c1; + ldapconn_t *lc2 = (ldapconn_t *)c2; /* Cannot have more than one shared session with same DN */ if ( dn_match( &lc1->lc_local_ndn, &lc2->lc_local_ndn ) && @@ -190,8 +190,8 @@ ldap_back_conn_dup( void *c1, void *c2 ) static void ravl_print( Avlnode *root, int depth ) { - int i; - struct ldapconn *lc; + int i; + ldapconn_t *lc; if ( root == 0 ) { return; @@ -227,22 +227,26 @@ myprint( Avlnode *root ) #endif /* PRINT_CONNTREE */ int -ldap_back_freeconn( Operation *op, struct ldapconn *lc ) +ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ) { - struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + } assert( lc->lc_refcnt > 0 ); if ( --lc->lc_refcnt == 0 ) { - lc = avl_delete( &li->conntree, (caddr_t)lc, + lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ); assert( lc != NULL ); ldap_back_conn_free( (void *)lc ); } - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + } return 0; } @@ -259,10 +263,10 @@ ldap_back_start_tls( const char **text ) { int rc = LDAP_SUCCESS; - struct ldapinfo dummy; + ldapinfo_t dummy; /* this is ridiculous... */ - dummy.flags = flags; + dummy.li_flags = flags; /* start TLS ("tls-[try-]{start,propagate}" statements) */ if ( ( LDAP_BACK_USE_TLS( &dummy ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &dummy ) ) ) @@ -392,9 +396,9 @@ retry:; #endif /* HAVE_TLS */ static int -ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) +ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; int vers = op->o_protocol; LDAP *ld = NULL; #ifdef HAVE_TLS @@ -403,7 +407,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda assert( lcp != NULL ); - rs->sr_err = ldap_initialize( &ld, li->url ); + rs->sr_err = ldap_initialize( &ld, li->li_uri ); if ( rs->sr_err != LDAP_SUCCESS ) { goto error_return; } @@ -420,7 +424,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda #ifdef HAVE_TLS rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls, - li->url, li->flags, li->nretries, &rs->sr_text ); + li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { ldap_unbind_ext( ld, NULL, NULL ); goto error_return; @@ -428,8 +432,8 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda #endif /* HAVE_TLS */ if ( *lcp == NULL ) { - *lcp = (struct ldapconn *)ch_calloc( 1, sizeof( struct ldapconn ) ); - (*lcp)->lc_flags= li->flags; + *lcp = (ldapconn_t *)ch_calloc( 1, sizeof( ldapconn_t ) ); + (*lcp)->lc_flags= li->li_flags; } (*lcp)->lc_ld = ld; (*lcp)->lc_refcnt = 1; @@ -456,11 +460,11 @@ error_return:; return rs->sr_err; } -struct ldapconn * +ldapconn_t * ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; - struct ldapconn *lc, + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; + ldapconn_t *lc, lc_curr = { 0 }; int refcnt = 1; @@ -482,14 +486,14 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) } /* Searches for a ldapconn in the avl tree */ - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); - lc = (struct ldapconn *)avl_find( li->conntree, + lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); if ( lc != NULL ) { refcnt = ++lc->lc_refcnt; } - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); /* Looks like we didn't get a bind. Open a new session... */ if ( lc == NULL ) { @@ -501,8 +505,8 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn ); if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) { - ber_dupbv( &lc->lc_cred, &li->acl_passwd ); - ber_dupbv( &lc->lc_bound_ndn, &li->acl_authcDN ); + ber_dupbv( &lc->lc_cred, &li->li_acl_passwd ); + ber_dupbv( &lc->lc_bound_ndn, &li->li_acl_authcDN ); LDAP_BACK_CONN_ISPRIV_SET( lc ); } else { @@ -527,18 +531,18 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) if ( lc->lc_conn == LDAP_BACK_PCONN_TLS && !ldap_tls_inplace( lc->lc_ld ) ) { - struct ldapconn *tmplc; + ldapconn_t *tmplc; lc_curr.lc_conn = LDAP_BACK_PCONN; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); - tmplc = (struct ldapconn *)avl_find( li->conntree, + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + tmplc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); if ( tmplc != NULL ) { refcnt = ++tmplc->lc_refcnt; ldap_back_conn_free( lc ); lc = tmplc; } - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); if ( tmplc != NULL ) { goto done; @@ -549,17 +553,17 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); /* Inserts the newly created ldapconn in the avl tree */ - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); assert( lc->lc_refcnt == 1 ); - rs->sr_err = avl_insert( &li->conntree, (caddr_t)lc, + rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp, ldap_back_conn_dup ); #if PRINT_CONNTREE > 0 - myprint( li->conntree ); + myprint( li->li_conninfo.lai_tree ); #endif /* PRINT_CONNTREE */ - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); Debug( LDAP_DEBUG_TRACE, "=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n", @@ -590,14 +594,14 @@ void ldap_back_release_conn( Operation *op, SlapReply *rs, - struct ldapconn *lc ) + ldapconn_t *lc ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); assert( lc->lc_refcnt > 0 ); lc->lc_refcnt--; - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } /* @@ -607,18 +611,18 @@ ldap_back_release_conn( * it from all the callers, and I made the function return the flag, so * it can be used to simplify the check. * - * Note: dolock indicates whether li->conn_mutex must be locked or not + * Note: dolock indicates whether li->li_conninfo.lai_mutex must be locked or not */ static int ldap_back_dobind_int( - struct ldapconn *lc, + ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok, int retries, int dolock ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; int rc = LDAP_BACK_CONN_ISBOUND( lc ); ber_int_t msgid; @@ -654,7 +658,7 @@ ldap_back_dobind_int( if ( op->o_conn != NULL && !op->o_do_not_cache && ( BER_BVISNULL( &lc->lc_bound_ndn ) || - ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) + ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) { (void)ldap_back_proxy_authz_bind( lc, op, rs ); goto done; @@ -662,32 +666,32 @@ ldap_back_dobind_int( #ifdef HAVE_CYRUS_SASL if ( LDAP_BACK_CONN_ISPRIV( lc ) - && li->acl_authmethod == LDAP_AUTH_SASL ) + && li->li_acl_authmethod == LDAP_AUTH_SASL ) { void *defaults = NULL; - if ( li->acl_secprops != NULL ) { + if ( li->li_acl_secprops != NULL ) { rc = ldap_set_option( lc->lc_ld, - LDAP_OPT_X_SASL_SECPROPS, li->acl_secprops); + LDAP_OPT_X_SASL_SECPROPS, li->li_acl_secprops); if ( rc != LDAP_OPT_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option " "(%s,SECPROPS,\"%s\") failed!\n", - li->url, li->acl_secprops, 0 ); + li->li_uri, li->li_acl_secprops, 0 ); goto done; } } defaults = lutil_sasl_defaults( lc->lc_ld, - li->acl_sasl_mech.bv_val, - li->acl_sasl_realm.bv_val, - li->acl_authcID.bv_val, - li->acl_passwd.bv_val, + li->li_acl_sasl_mech.bv_val, + li->li_acl_sasl_realm.bv_val, + li->li_acl_authcID.bv_val, + li->li_acl_passwd.bv_val, NULL ); rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, - li->acl_authcDN.bv_val, - li->acl_sasl_mech.bv_val, NULL, NULL, + li->li_acl_authcDN.bv_val, + li->li_acl_sasl_mech.bv_val, NULL, NULL, LDAP_SASL_QUIET, lutil_sasl_interact, defaults ); @@ -714,7 +718,7 @@ retry:; if ( rs->sr_err == LDAP_SERVER_DOWN ) { if ( retries != LDAP_BACK_RETRY_NEVER ) { if ( dolock ) { - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); } assert( lc->lc_refcnt > 0 ); @@ -726,7 +730,7 @@ retry:; rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok ); } if ( dolock ) { - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } if ( rs->sr_err == LDAP_SUCCESS ) { if ( retries > 0 ) { @@ -736,7 +740,7 @@ retry:; } } - ldap_back_freeconn( op, lc ); + ldap_back_freeconn( op, lc, dolock ); rs->sr_err = slap_map_api2result( rs ); return 0; @@ -757,11 +761,11 @@ done:; } int -ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) +ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - return ldap_back_dobind_int( lc, op, rs, sendok, li->nretries, 1 ); + return ldap_back_dobind_int( lc, op, rs, sendok, li->li_nretries, 1 ); } /* @@ -774,7 +778,7 @@ static int ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params ) { - struct ldapconn *lc = (struct ldapconn *)params; + ldapconn_t *lc = (ldapconn_t *)params; #ifdef HAVE_TLS /* ... otherwise we couldn't get here */ @@ -801,7 +805,7 @@ ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request, int ldap_back_op_result( - struct ldapconn *lc, + ldapconn_t *lc, Operation *op, SlapReply *rs, ber_int_t msgid, @@ -906,40 +910,43 @@ retry:; /* return true if bound, false if failed */ int -ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) +ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { int rc = 0; - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; - - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - if ( lc->lc_refcnt == 1 ) { + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + + if ( (*lcp)->lc_refcnt == 1 ) { Debug( LDAP_DEBUG_ANY, "%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n", - op->o_log_prefix, li->url, - BER_BVISNULL( &lc->lc_bound_ndn ) ? - "" : lc->lc_bound_ndn.bv_val ); + op->o_log_prefix, li->li_uri, + BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ? + "" : (*lcp)->lc_bound_ndn.bv_val ); - ldap_unbind_ext( lc->lc_ld, NULL, NULL ); - lc->lc_ld = NULL; - LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); + ldap_unbind_ext( (*lcp)->lc_ld, NULL, NULL ); + (*lcp)->lc_ld = NULL; + LDAP_BACK_CONN_ISBOUND_CLEAR( (*lcp) ); /* lc here must be the regular lc, reset and ready for init */ - rc = ldap_back_prepare_conn( &lc, op, rs, sendok ); + rc = ldap_back_prepare_conn( lcp, op, rs, sendok ); if ( rc == LDAP_SUCCESS ) { - rc = ldap_back_dobind_int( lc, op, rs, sendok, 0, 0 ); + rc = ldap_back_dobind_int( *lcp, op, rs, sendok, 0, 0 ); + if ( rc == 0 ) { + *lcp = NULL; + } } } - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); return rc; } static int -ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) +ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; struct berval binddn = slap_empty_bv; struct berval bindcred = slap_empty_bv; int dobind = 0; @@ -969,13 +976,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) /* bind as proxyauthzdn only if no idassert mode * is requested, or if the client's identity * is authorized */ - switch ( li->idassert_mode ) { + switch ( li->li_idassert_mode ) { case LDAP_BACK_IDASSERT_LEGACY: if ( !BER_BVISNULL( &op->o_conn->c_ndn ) && !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) { - if ( !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) ) + if ( !BER_BVISNULL( &li->li_idassert_authcDN ) && !BER_BVISEMPTY( &li->li_idassert_authcDN ) ) { - binddn = li->idassert_authcDN; - bindcred = li->idassert_passwd; + binddn = li->li_idassert_authcDN; + bindcred = li->li_idassert_passwd; dobind = 1; } } @@ -983,7 +990,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) default: /* NOTE: rootdn can always idassert */ - if ( li->idassert_authz && !be_isroot( op ) ) { + if ( li->li_idassert_authz && !be_isroot( op ) ) { struct berval authcDN; if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) { @@ -992,10 +999,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) } else { authcDN = op->o_conn->c_ndn; } - rs->sr_err = slap_sasl_matches( op, li->idassert_authz, + rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz, &authcDN, &authcDN ); if ( rs->sr_err != LDAP_SUCCESS ) { - if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { send_ldap_result( op, rs ); LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); @@ -1010,13 +1017,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) } } - binddn = li->idassert_authcDN; - bindcred = li->idassert_passwd; + binddn = li->li_idassert_authcDN; + bindcred = li->li_idassert_passwd; dobind = 1; break; } - if ( dobind && li->idassert_authmethod == LDAP_AUTH_SASL ) { + if ( dobind && li->li_idassert_authmethod == LDAP_AUTH_SASL ) { #ifdef HAVE_CYRUS_SASL void *defaults = NULL; struct berval authzID = BER_BVNULL; @@ -1024,12 +1031,12 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) /* if SASL supports native authz, prepare for it */ if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) && - ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) ) + ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) ) { - switch ( li->idassert_mode ) { + switch ( li->li_idassert_mode ) { case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERDN: - authzID = li->idassert_authzID; + authzID = li->li_idassert_authzID; break; case LDAP_BACK_IDASSERT_ANONYMOUS: @@ -1055,10 +1062,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) } } - if ( li->idassert_secprops != NULL ) { + if ( li->li_idassert_secprops != NULL ) { rs->sr_err = ldap_set_option( lc->lc_ld, LDAP_OPT_X_SASL_SECPROPS, - (void *)li->idassert_secprops ); + (void *)li->li_idassert_secprops ); if ( rs->sr_err != LDAP_OPT_SUCCESS ) { send_ldap_result( op, rs ); @@ -1068,14 +1075,14 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) } defaults = lutil_sasl_defaults( lc->lc_ld, - li->idassert_sasl_mech.bv_val, - li->idassert_sasl_realm.bv_val, - li->idassert_authcID.bv_val, - li->idassert_passwd.bv_val, + li->li_idassert_sasl_mech.bv_val, + li->li_idassert_sasl_realm.bv_val, + li->li_idassert_authcID.bv_val, + li->li_idassert_passwd.bv_val, authzID.bv_val ); rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn.bv_val, - li->idassert_sasl_mech.bv_val, NULL, NULL, + li->li_idassert_sasl_mech.bv_val, NULL, NULL, LDAP_SASL_QUIET, lutil_sasl_interact, defaults ); @@ -1097,7 +1104,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) #endif /* HAVE_CYRUS_SASL */ } - switch ( li->idassert_authmethod ) { + switch ( li->li_idassert_authmethod ) { case LDAP_AUTH_NONE: LDAP_BACK_CONN_ISBOUND_SET( lc ); goto done; @@ -1152,12 +1159,12 @@ done:; */ int ldap_back_proxy_authz_ctrl( - struct ldapconn *lc, + ldapconn_t *lc, Operation *op, SlapReply *rs, LDAPControl ***pctrls ) { - struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; LDAPControl **ctrls = NULL; int i = 0, mode; @@ -1170,8 +1177,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->idassert_authcID ) || BER_BVISEMPTY( &li->idassert_authcID ) ) - && ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) ) + 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 ) ) ) { goto done; } @@ -1180,7 +1187,7 @@ ldap_back_proxy_authz_ctrl( goto done; } - if ( li->idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) { + if ( li->li_idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) { if ( op->o_proxy_authz ) { /* * FIXME: we do not want to perform proxyAuthz @@ -1207,12 +1214,12 @@ ldap_back_proxy_authz_ctrl( goto done; } - if ( BER_BVISNULL( &li->idassert_authcDN ) ) { + if ( BER_BVISNULL( &li->li_idassert_authcDN ) ) { goto done; } - } else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) { - if ( ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) + } else if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) { + if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) /* && ( !BER_BVISNULL( &op->o_conn->c_ndn ) || LDAP_BACK_CONN_ISBOUND( lc ) ) */ ) { @@ -1223,7 +1230,7 @@ ldap_back_proxy_authz_ctrl( goto done; } - } else if ( li->idassert_authz && !be_isroot( op ) ) { + } else if ( li->li_idassert_authz && !be_isroot( op ) ) { int rc; struct berval authcDN; @@ -1232,10 +1239,10 @@ ldap_back_proxy_authz_ctrl( } else { authcDN = op->o_conn->c_ndn; } - rc = slap_sasl_matches( op, li->idassert_authz, + rc = slap_sasl_matches( op, li->li_idassert_authz, &authcDN, & authcDN ); if ( rc != LDAP_SUCCESS ) { - if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) + if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { /* op->o_conn->c_ndn is not authorized * to use idassert */ @@ -1271,7 +1278,7 @@ ldap_back_proxy_authz_ctrl( mode = LDAP_BACK_IDASSERT_NOASSERT; } else { - mode = li->idassert_mode; + mode = li->li_idassert_mode; } switch ( mode ) { @@ -1298,7 +1305,7 @@ ldap_back_proxy_authz_ctrl( case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERDN: /* assert idassert DN */ - assertedID = li->idassert_authzID; + assertedID = li->li_idassert_authzID; break; default: @@ -1320,7 +1327,7 @@ ldap_back_proxy_authz_ctrl( ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; ctrls[ 0 ]->ldctl_iscritical = 1; - switch ( li->idassert_mode ) { + switch ( li->li_idassert_mode ) { /* already in u:ID or dn:DN form */ case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERDN: diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c index 3a582883c3..b0d8801859 100644 --- a/servers/slapd/back-ldap/chain.c +++ b/servers/slapd/back-ldap/chain.c @@ -17,6 +17,7 @@ /* ACKNOWLEDGEMENTS: * This work was initially developed by the Howard Chu for inclusion * in OpenLDAP Software. + * This work was subsequently modified by Pierangelo Masarati. */ #include "portable.h" @@ -64,12 +65,31 @@ static int sc_chainingBehavior; static BackendInfo *lback; typedef struct ldap_chain_t { - struct ldapinfo *lc_li; - unsigned lc_flags; -#define LDAP_CHAIN_F_NONE 0x00U -#define LDAP_CHAIN_F_CHAINING 0x01U + /* + * TODO: create a template ldapinfo_t that gets all common + * configuration items; then for each configured URI create + * an entry in this tree; all the specific configuration + * items get in the current URI structure. + * + * Then, for each referral, extract the URI and lookup the + * related structure. If configured to do so, allow URIs + * not found in the structure to create a temporary one + * that chains anonymously; maybe it can also be added to + * the tree? Should be all configurable. + */ + /* tree of configured[/generated] "uri" info */ + int lc_lai_count; + ldap_avl_info_t lc_lai; - ldap_pvt_thread_mutex_t lc_mutex; + /* current configuration info */ + ldapinfo_t *lc_cfg_li; + /* "common" configuration info (all occurring before an "uri") */ + ldapinfo_t *lc_common_li; + + unsigned lc_flags; +#define LDAP_CHAIN_F_NONE (0x00U) +#define LDAP_CHAIN_F_CHAINING (0x01U) +#define LDAP_CHAIN_F_CACHE_INFO (0x10U) #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl lc_chaining_ctrl; @@ -77,6 +97,8 @@ typedef struct ldap_chain_t { #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ } ldap_chain_t; +static int ldap_chain_db_init_one( BackendDB *be ); + #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR static int chaining_control_add( @@ -149,6 +171,46 @@ chaining_control_remove( } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +static int +ldap_chain_uri_cmp( const void *c1, const void *c2 ) +{ + const ldapinfo_t *li1 = (const ldapinfo_t *)c1; + const ldapinfo_t *li2 = (const ldapinfo_t *)c2; + + assert( li1->li_bvuri != NULL ); + assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) ); + assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) ); + + assert( li2->li_bvuri != NULL ); + assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) ); + assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) ); + + /* If local DNs don't match, it is definitely not a match */ + return ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] ); +} + +static int +ldap_chain_uri_dup( void *c1, void *c2 ) +{ + ldapinfo_t *li1 = (ldapinfo_t *)c1; + ldapinfo_t *li2 = (ldapinfo_t *)c2; + + assert( li1->li_bvuri != NULL ); + assert( !BER_BVISNULL( &li1->li_bvuri[ 0 ] ) ); + assert( BER_BVISNULL( &li1->li_bvuri[ 1 ] ) ); + + assert( li2->li_bvuri != NULL ); + assert( !BER_BVISNULL( &li2->li_bvuri[ 0 ] ) ); + assert( BER_BVISNULL( &li2->li_bvuri[ 1 ] ) ); + + /* Cannot have more than one shared session with same DN */ + if ( ber_bvcmp( &li1->li_bvuri[ 0 ], &li2->li_bvuri[ 0 ] ) == 0 ) { + return -1; + } + + return 0; +} + static int ldap_chain_operational( Operation *op, SlapReply *rs ) { @@ -211,7 +273,7 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs ) switch ( get_continuationBehavior( op ) ) { case SLAP_CH_RESOLVE_CHAINING_REQUIRED: op->o_callback->sc_private = LDAP_CH_ERR; - return -1; + return rs->sr_err = LDAP_X_CANNOT_CHAIN; default: break; @@ -241,7 +303,36 @@ ldap_chain_cb_response( Operation *op, SlapReply *rs ) } if ( rs->sr_type == REP_RESULT ) { - op->o_callback->sc_private = LDAP_CH_RES; + switch ( rs->sr_err ) { + case LDAP_COMPARE_TRUE: + case LDAP_COMPARE_FALSE: + if ( op->o_tag != LDAP_REQ_COMPARE ) { + return rs->sr_err; + } + /* fallthru */ + + case LDAP_SUCCESS: + op->o_callback->sc_private = LDAP_CH_RES; + break; + + case LDAP_REFERRAL: +#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR + if ( get_chaining( op ) > SLAP_CONTROL_IGNORED ) { + switch ( get_continuationBehavior( op ) ) { + case SLAP_CH_RESOLVE_CHAINING_REQUIRED: + op->o_callback->sc_private = LDAP_CH_ERR; + return rs->sr_err = LDAP_X_CANNOT_CHAIN; + + default: + break; + } + } +#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + break; + + default: + return rs->sr_err; + } } else if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) { @@ -261,10 +352,8 @@ ldap_chain_op( { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - - struct ldapinfo *lip = lc->lc_li; - char *save_url = NULL; - SlapReply rs2 = { 0 }; + ldapinfo_t li = *lc->lc_common_li, *lip = NULL; + struct berval bvuri[ 2 ] = { { 0 } }; /* NOTE: returned if ref is empty... */ int rc = LDAP_OTHER; @@ -275,27 +364,11 @@ ldap_chain_op( (void)chaining_control_add( lc, op, &ctrls ); #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - if ( lip->url != NULL ) { - op->o_bd->be_private = lip; - rc = ( *op_f )( op, &rs2 ); - rs->sr_err = rs2.sr_err; - goto done; - } - - save_url = lip->url; - lip->url = NULL; - op->o_bd->be_private = lip; - - /* if we parse the URI then by no means - * we can cache stuff or reuse connections, - * because in back-ldap there's no caching - * based on the URI value, which is supposed - * to be set once for all (correct?) */ - op->o_do_not_cache = 1; - + li.li_bvuri = bvuri; for ( ; !BER_BVISNULL( ref ); ref++ ) { LDAPURLDesc *srv; char *save_dn; + int temporary = 0; /* We're setting the URI of the first referral; * what if there are more? @@ -328,30 +401,63 @@ Document: draft-ietf-ldapbis-protocol-27.txt save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - lip->url = ldap_url_desc2str( srv ); + li.li_uri = ldap_url_desc2str( srv ); srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( lip->url == NULL ) { + if ( li.li_uri == NULL ) { /* try next */ rc = LDAP_OTHER; continue; } - rc = ( *op_f )( op, &rs2 ); - rs->sr_err = rs2.sr_err; + ber_str2bv( li.li_uri, 0, 0, &li.li_bvuri[ 0 ] ); + + /* Searches for a ldapinfo in the avl tree */ + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); + lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, + (caddr_t)&li, ldap_chain_uri_cmp ); + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + + if ( lip != NULL ) { + op->o_bd->be_private = (void *)lip; + + } else { + rc = ldap_chain_db_init_one( op->o_bd ); + if ( rc != 0 ) { + goto cleanup; + } + lip = (ldapinfo_t *)op->o_bd->be_private; + lip->li_uri = li.li_uri; + lip->li_bvuri = bvuri; + rc = lback->bi_db_open( op->o_bd ); + if ( rc != 0 ) { + (void)lback->bi_db_destroy( op->o_bd ); + goto cleanup; + } + temporary = 1; + } + + rc = ( *op_f )( op, rs ); + +cleanup:; + ldap_memfree( li.li_uri ); + li.li_uri = NULL; - ldap_memfree( lip->url ); - lip->url = NULL; + if ( temporary ) { + lip->li_uri = NULL; + lip->li_bvuri = NULL; +#if 0 /* does not exist yet */ + (void)lback->bi_db_close( op->o_bd ); +#endif + (void)lback->bi_db_destroy( op->o_bd ); + } if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) { break; } } - lip->url = save_url; - -done:; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR (void)chaining_control_remove( op, &ctrls ); #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ @@ -367,14 +473,10 @@ ldap_chain_response( Operation *op, SlapReply *rs ) slap_callback *sc = op->o_callback, sc2 = { 0 }; int rc = 0; - int cache = op->o_do_not_cache; - char *matched; + const char *matched; BerVarray ref; struct berval ndn = op->o_ndn; - ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - struct ldapinfo *lip = lc->lc_li; - #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR int sr_err = rs->sr_err; slap_reply_t sr_type = rs->sr_type; @@ -413,8 +515,6 @@ ldap_chain_response( Operation *op, SlapReply *rs ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - ldap_pvt_thread_mutex_lock( &lc->lc_mutex ); - /* * TODO: add checks on who/when chain operations; e.g.: * a) what identities are authorized @@ -455,28 +555,39 @@ ldap_chain_response( Operation *op, SlapReply *rs ) op->o_conn = conn; } break; + case LDAP_REQ_ADD: rc = ldap_chain_op( op, rs, lback->bi_op_add, ref ); break; + case LDAP_REQ_DELETE: rc = ldap_chain_op( op, rs, lback->bi_op_delete, ref ); break; + case LDAP_REQ_MODRDN: rc = ldap_chain_op( op, rs, lback->bi_op_modrdn, ref ); break; + case LDAP_REQ_MODIFY: rc = ldap_chain_op( op, rs, lback->bi_op_modify, ref ); break; + case LDAP_REQ_COMPARE: rc = ldap_chain_op( op, rs, lback->bi_op_compare, ref ); + if ( rs->sr_err == LDAP_COMPARE_TRUE || rs->sr_err == LDAP_COMPARE_FALSE ) { + rc = LDAP_SUCCESS; + } break; + case LDAP_REQ_SEARCH: if ( rs->sr_type == REP_SEARCHREF ) { + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; + ldapinfo_t li = *lc->lc_common_li, *lip = NULL; + struct berval bvuri[ 2 ] = { { 0 } }; + struct berval *curr = ref, odn = op->o_req_dn, ondn = op->o_req_ndn; - char *save_url = NULL; - SlapReply rs2 = { 0 }; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl **ctrls = NULL; @@ -488,21 +599,16 @@ ldap_chain_response( Operation *op, SlapReply *rs ) sc2.sc_response = ldap_chain_cb_search_response; - save_url = lip->url; - lip->url = NULL; - op->o_bd->be_private = lip; - /* if we parse the URI then by no means * we can cache stuff or reuse connections, * because in back-ldap there's no caching * based on the URI value, which is supposed * to be set once for all (correct?) */ - op->o_do_not_cache = 1; - - /* copy the private info because we need to modify it */ + li.li_bvuri = bvuri; for ( ; !BER_BVISNULL( &curr[0] ); curr++ ) { LDAPURLDesc *srv; char *save_dn; + int temporary = 0; /* parse reference and use * proto://[host][:port]/ only */ @@ -519,8 +625,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - lip->url = ldap_url_desc2str( srv ); - if ( lip->url != NULL ) { + li.li_uri = ldap_url_desc2str( srv ); + if ( li.li_uri != NULL ) { ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn, @@ -530,26 +636,62 @@ ldap_chain_response( Operation *op, SlapReply *rs ) srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( lip->url == NULL ) { + if ( li.li_uri == NULL ) { /* try next */ rs->sr_err = LDAP_OTHER; continue; } + ber_str2bv( li.li_uri, 0, 0, &li.li_bvuri[ 0 ] ); + + /* Searches for a ldapinfo in the avl tree */ + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); + lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, + (caddr_t)&li, ldap_chain_uri_cmp ); + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + + if ( lip != NULL ) { + op->o_bd->be_private = (void *)lip; + + } else { + /* if none is found, create a temporary... */ + rc = ldap_chain_db_init_one( op->o_bd ); + if ( rc != 0 ) { + goto cleanup; + } + lip = (ldapinfo_t *)op->o_bd->be_private; + lip->li_uri = li.li_uri; + lip->li_bvuri = bvuri; + rc = lback->bi_db_open( op->o_bd ); + if ( rc != 0 ) { + (void)lback->bi_db_destroy( op->o_bd ); + goto cleanup; + } + temporary = 1; + } /* FIXME: should we also copy filter and scope? * according to RFC3296, no */ - rc = lback->bi_op_search( op, &rs2 ); - rs->sr_err = rs2.sr_err; + rc = lback->bi_op_search( op, rs ); - ldap_memfree( lip->url ); - lip->url = NULL; +cleanup:; + ldap_memfree( li.li_uri ); + li.li_uri = NULL; op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); + if ( temporary ) { + lip->li_uri = NULL; + lip->li_bvuri = NULL; +#if 0 /* does not exist yet */ + (void)lback->bi_db_close( op->o_bd ); +#endif + (void)lback->bi_db_destroy( op->o_bd ); + } + if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) { break; } @@ -561,8 +703,6 @@ ldap_chain_response( Operation *op, SlapReply *rs ) (void)chaining_control_remove( op, &ctrls ); #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - lip->url = save_url; - op->o_req_dn = odn; op->o_req_ndn = ondn; rs->sr_type = REP_SEARCHREF; @@ -577,24 +717,38 @@ ldap_chain_response( Operation *op, SlapReply *rs ) rc = ldap_chain_op( op, rs, lback->bi_op_search, ref ); } break; + case LDAP_REQ_EXTENDED: rc = ldap_chain_op( op, rs, lback->bi_extended, ref ); /* FIXME: ldap_back_extended() by design * doesn't send result; frontend is expected * to send it... */ + /* FIXME: what aboit chaining? */ if ( rc != SLAPD_ABANDON ) { send_ldap_extended( op, rs ); rc = LDAP_SUCCESS; } + sc2.sc_private = LDAP_CH_RES; break; + default: rc = SLAP_CB_CONTINUE; break; } + switch ( rc ) { + case SLAPD_ABANDON: + goto dont_chain; + + case LDAP_SUCCESS: + case LDAP_REFERRAL: + /* slapd-ldap sent response */ + assert( sc2.sc_private == LDAP_CH_RES ); + break; + + default: #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR - if ( rc != LDAP_SUCCESS || sc2.sc_private == LDAP_CH_ERR ) { - if ( rs->sr_err == LDAP_X_CANNOT_CHAIN ) { + if ( sc2.sc_private == LDAP_CH_ERR && rs->sr_err == LDAP_X_CANNOT_CHAIN ) { goto cannot_chain; } @@ -604,19 +758,22 @@ cannot_chain:; op->o_callback = NULL; send_ldap_error( op, rs, LDAP_X_CANNOT_CHAIN, "operation cannot be completed without chaining" ); - break; + goto dont_chain; default: +#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ rc = SLAP_CB_CONTINUE; rs->sr_err = sr_err; rs->sr_type = sr_type; + rs->sr_matched = matched; + rs->sr_ref = ref; +#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR break; } - goto dont_chain; - } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + } - if ( sc2.sc_private == LDAP_CH_NONE ) { + if ( sc2.sc_private == LDAP_CH_NONE && rc != SLAPD_ABANDON ) { op->o_callback = NULL; rc = rs->sr_err = slap_map_api2result( rs ); send_ldap_result( op, rs ); @@ -625,14 +782,13 @@ cannot_chain:; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR dont_chain:; #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - op->o_do_not_cache = cache; + rs->sr_err = sr_err; + rs->sr_type = sr_type; + rs->sr_matched = matched; + rs->sr_ref = ref; op->o_bd->be_private = private; op->o_callback = sc; op->o_ndn = ndn; - rs->sr_matched = matched; - rs->sr_ref = ref; - - ldap_pvt_thread_mutex_unlock( &lc->lc_mutex ); return rc; } @@ -664,14 +820,18 @@ str2chain( const char *s ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +/* + * configuration... + */ + enum { PC_CHAINING = 1 }; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR static ConfigDriver chain_cf_gen; -static ConfigCfAdd chain_cfadd; #endif +static ConfigCfAdd chain_cfadd; static ConfigLDAPadd chain_ldadd; static ConfigTable chaincfg[] = { @@ -703,14 +863,45 @@ static ConfigOCs chainocs[] = { static int chain_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ) { - if ( p->ce_type != Cft_Overlay || !p->ce_bi || - p->ce_bi->bi_cf_ocs != chainocs ) + if ( p->ce_type != Cft_Overlay + || !p->ce_bi + || p->ce_bi->bi_cf_ocs != chainocs ) + { return LDAP_CONSTRAINT_VIOLATION; + } return LDAP_SUCCESS; } -#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR +typedef struct ldap_chain_cfadd_apply_t { + Operation *op; + SlapReply *rs; + Entry *p; + ConfigArgs *ca; + int count; +} ldap_chain_cfadd_apply_t; + +static int +ldap_chain_cfadd_apply( void *datum, void *arg ) +{ + ldapinfo_t *li = (ldapinfo_t *)datum; + ldap_chain_cfadd_apply_t *lca = (ldap_chain_cfadd_apply_t *)arg; + + struct berval bv; + + /* FIXME: should not hardcode "olcDatabase" here */ + bv.bv_len = snprintf( lca->ca->msg, sizeof( lca->ca->msg ), + "olcDatabase={%d}%s", lca->count, lback->bi_type ); + bv.bv_val = lca->ca->msg; + + lca->ca->be->be_private = (void *)li; + config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca, + &bv, lback->bi_cf_ocs, &chainocs[1] ); + + lca->count++; + + return 0; +} static int chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) @@ -719,22 +910,29 @@ chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) slap_overinst *on = (slap_overinst *)pe->ce_bi; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; void *priv = (void *)ca->be->be_private; - struct berval bv; - /* FIXME: should not hardcode "olcDatabase" here */ - bv.bv_len = sprintf( ca->msg, "olcDatabase=%s", lback->bi_type ); - bv.bv_val = ca->msg; - - /* We can only create this entry if the database is table-driven */ if ( lback->bi_cf_ocs ) { - ca->be->be_private = (void *)lc->lc_li; - config_build_entry( op, rs, pe, ca, &bv, lback->bi_cf_ocs, &chainocs[1] ); + ldap_chain_cfadd_apply_t lca = { 0 }; + + lca.op = op; + lca.rs = rs; + lca.p = p; + lca.ca = ca; + lca.count = -1; + + (void)ldap_chain_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca ); + + (void)avl_apply( lc->lc_lai.lai_tree, ldap_chain_cfadd_apply, + &lca, 1, AVL_INORDER ); + ca->be->be_private = priv; } return 0; } +#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR + static slap_verbmasks chaining_mode[] = { { BER_BVC("referralsRequired"), LDAP_REFERRALS_REQUIRED }, { BER_BVC("referralsPreferred"), LDAP_REFERRALS_PREFERRED }, @@ -930,6 +1128,34 @@ chain_cf_gen( ConfigArgs *c ) #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ +static int +ldap_chain_db_init( + BackendDB *be ) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + ldap_chain_t *lc = NULL; + int rc; + BackendDB bd = *be; + + if ( lback == NULL ) { + lback = backend_info( "ldap" ); + + if ( lback == NULL ) { + return -1; + } + } + + lc = ch_malloc( sizeof( ldap_chain_t ) ); + memset( lc, 0, sizeof( ldap_chain_t ) ); + + bd.be_private = NULL; + rc = lback->bi_db_init( &bd ); + lc->lc_cfg_li = lc->lc_common_li = (ldapinfo_t *)bd.be_private; + on->on_bi.bi_private = (void *)lc; + + return rc; +} + static int ldap_chain_db_config( BackendDB *be, @@ -938,219 +1164,262 @@ ldap_chain_db_config( int argc, char **argv ) { - slap_overinst *on = (slap_overinst *) be->bd_info; + slap_overinst *on = (slap_overinst *)be->bd_info; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - char *argv0 = NULL; - int rc; - BackendDB db = *be; + int rc = SLAP_CONF_UNKNOWN; + + /* Something for the cache database? */ if ( strncasecmp( argv[ 0 ], "chain-", STRLENOF( "chain-" ) ) == 0 ) { - argv0 = argv[ 0 ]; - argv[ 0 ] = &argv[ 0 ][ STRLENOF( "chain-" ) ]; - -#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR - if ( strcasecmp( argv[ 0 ], "chaining" ) == 0 ) { - char **tmpargv = argv; - BerElementBuffer berbuf; - BerElement *ber = (BerElement *)&berbuf; - int resolve = -1, - continuation = -1, - iscritical = 0; - Operation op = { 0 }; - SlapReply rs = { 0 }; - - lc->lc_chaining_ctrlflag = 0; - - for ( argc--, tmpargv++; argc > 0; argc--, tmpargv++ ) { - if ( strncasecmp( tmpargv[ 0 ], "resolve=", STRLENOF( "resolve=" ) ) == 0 ) { - resolve = str2chain( tmpargv[ 0 ] + STRLENOF( "resolve=" ) ); - if ( resolve == -1 ) { - fprintf( stderr, "%s line %d: " - "illegal value %s " - "in \"chain-chaining>\"\n", - fname, lineno, tmpargv[ 0 ] ); - return 1; - } - - } else if ( strncasecmp( tmpargv[ 0 ], "continuation=", STRLENOF( "continuation=" ) ) == 0 ) { - continuation = str2chain( tmpargv[ 0 ] + STRLENOF( "continuation=" ) ); - if ( continuation == -1 ) { - fprintf( stderr, "%s line %d: " - "illegal value %s " - "in \"chain-chaining\"\n", - fname, lineno, tmpargv[ 0 ] ); - return 1; - } - - } else if ( strcasecmp( tmpargv[ 0 ], "critical" ) == 0 ) { - iscritical = 1; - - } else { - fprintf( stderr, "%s line %d: " - "unknown option in \"chain-chaining\"\n", - fname, lineno ); - return 1; - } + char *save_argv0 = argv[ 0 ]; + BackendInfo *bd_info = bd_info; + void *be_private = be->be_private; + ConfigOCs *be_cf_ocs = be->be_cf_ocs; + int is_uri = 0; + + argv[ 0 ] += STRLENOF( "chain-" ); + + /* TODO: create a new structure and, after parsing the URI, + * put it in the lc->lc_lai tree */ + if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) { + rc = ldap_chain_db_init_one( be ); + if ( rc != 0 ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "underlying slapd-ldap initialization failed\n.", + fname, lineno, 0 ); + return 1; } + lc->lc_cfg_li = be->be_private; + is_uri = 1; + } - if ( resolve != -1 || continuation != -1 ) { - int err; + be->bd_info = lback; + be->be_private = (void *)lc->lc_cfg_li; + be->be_cf_ocs = lback->bi_cf_ocs; - if ( resolve == -1 ) { - /* default */ - resolve = SLAP_CHAINING_DEFAULT; - } + rc = config_generic_wrapper( be, fname, lineno, argc, argv ); - ber_init2( ber, NULL, LBER_USE_DER ); + argv[ 0 ] = save_argv0; + be->be_cf_ocs = be_cf_ocs; + be->be_private = be_private; + be->bd_info = bd_info; - err = ber_printf( ber, "{e" /* } */, resolve ); - if ( err == -1 ) { - ber_free( ber, 1 ); - fprintf( stderr, "%s line %d: " - "chaining behavior control encoding error!\n", - fname, lineno ); - return 1; - } + if ( is_uri ) { +private_destroy:; + if ( rc != 0 ) { + BackendDB db = *be; - if ( continuation > -1 ) { - err = ber_printf( ber, "e", continuation ); - if ( err == -1 ) { - ber_free( ber, 1 ); - fprintf( stderr, "%s line %d: " - "chaining behavior control encoding error!\n", - fname, lineno ); - return 1; - } - } + db.bd_info = lback; + db.be_private = (void *)lc->lc_cfg_li; + lback->bi_db_destroy( &db ); + lc->lc_cfg_li = NULL; - err = ber_printf( ber, /* { */ "N}" ); - if ( err == -1 ) { - ber_free( ber, 1 ); - fprintf( stderr, "%s line %d: " - "chaining behavior control encoding error!\n", - fname, lineno ); - return 1; + } else { + if ( lc->lc_cfg_li->li_bvuri == NULL + || BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 0 ] ) + || !BER_BVISNULL( &lc->lc_cfg_li->li_bvuri[ 1 ] ) ) + { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "no URI list allowed in slapo-chain.\n", + fname, lineno, 0 ); + rc = 1; + goto private_destroy; } - if ( ber_flatten2( ber, &lc->lc_chaining_ctrl.ldctl_value, 0 ) == -1 ) { - exit( EXIT_FAILURE ); + if ( avl_insert( &lc->lc_lai.lai_tree, + (caddr_t)lc->lc_cfg_li, + ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) + { + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "duplicate URI in slapo-chain.\n", + fname, lineno, 0 ); + rc = 1; + goto private_destroy; } - - } else { - BER_BVZERO( &lc->lc_chaining_ctrl.ldctl_value ); - } - - lc->lc_chaining_ctrl.ldctl_oid = LDAP_CONTROL_X_CHAINING_BEHAVIOR; - lc->lc_chaining_ctrl.ldctl_iscritical = iscritical; - - if ( ldap_chain_parse_ctrl( &op, &rs, &lc->lc_chaining_ctrl ) != LDAP_SUCCESS ) - { - fprintf( stderr, "%s line %d: " - "unable to parse chaining control%s%s\n", - fname, lineno, - rs.sr_text ? ": " : "", - rs.sr_text ? rs.sr_text : "" ); - return 1; } + } + } + + return rc; +} - lc->lc_chaining_ctrlflag = op.o_chaining; +enum db_which { + db_open = 0, + db_close, + db_destroy, - lc->lc_flags |= LDAP_CHAIN_F_CHAINING; + db_last +}; - rc = 0; - goto done; - } -#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - } +typedef struct ldap_chain_db_apply_t { + BackendDB *be; + BI_db_func *func; +} ldap_chain_db_apply_t; - db.be_cf_ocs = lback->bi_cf_ocs; - db.be_private = lc->lc_li; - rc = lback->bi_db_config( &db, fname, lineno, argc, argv ); +static int +ldap_chain_db_apply( void *datum, void *arg ) +{ + ldapinfo_t *li = (ldapinfo_t *)datum; + ldap_chain_db_apply_t *lca = (ldap_chain_db_apply_t *)arg; -done:; - if ( argv0 ) { - argv[ 0 ] = argv0; - } + lca->be->be_private = (void *)li; - return rc; + return lca->func( lca->be ); } static int -ldap_chain_db_init( - BackendDB *be ) +ldap_chain_db_func( + BackendDB *be, + enum db_which which +) { slap_overinst *on = (slap_overinst *)be->bd_info; - ldap_chain_t *lc = NULL; - int rc; - BackendDB bd = *be; + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - if ( lback == NULL ) { - lback = backend_info( "ldap" ); + int rc = 0; - if ( lback == NULL ) { - return -1; - } - } + if ( lc ) { + BI_db_func *func = (&lback->bi_db_open)[ which ]; - lc = ch_malloc( sizeof( ldap_chain_t ) ); - memset( lc, 0, sizeof( ldap_chain_t ) ); + if ( func != NULL ) { + BackendDB db = *be; - ldap_pvt_thread_mutex_init( &lc->lc_mutex ); + db.bd_info = lback; + db.be_private = lc->lc_common_li; - bd.be_private = NULL; - rc = lback->bi_db_init( &bd ); - lc->lc_li = (struct ldapinfo *)bd.be_private; - on->on_bi.bi_private = (void *)lc; + rc = func( &db ); + + if ( rc != 0 ) { + return rc; + } + + if ( lc->lc_lai.lai_tree != NULL ) { + ldap_chain_db_apply_t lca; + + lca.be = &db; + lca.func = func; + + rc = avl_apply( lc->lc_lai.lai_tree, + ldap_chain_db_apply, (void *)&lca, + 1, AVL_INORDER ) != AVL_NOMORE; + } + } + } return rc; } static int ldap_chain_db_open( - BackendDB *be -) + BackendDB *be ) { +#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR int rc = 0; -#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR rc = overlay_register_control( be, LDAP_CONTROL_X_CHAINING_BEHAVIOR ); + if ( rc != 0 ) { + return rc; + } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ - return rc; + /* FIXME: right now slapd-ldap has no open function; + * in case one is introduced, this needs be fixed */ + + return ldap_chain_db_func( be, db_open ); +} + +static int +ldap_chain_db_close( + BackendDB *be ) +{ + return ldap_chain_db_func( be, db_close ); } static int ldap_chain_db_destroy( - BackendDB *be -) + BackendDB *be ) { slap_overinst *on = (slap_overinst *) be->bd_info; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - void *private = be->be_private; + int rc; - be->be_private = (void *)lc->lc_li; - rc = lback->bi_db_destroy( be ); - ldap_pvt_thread_mutex_destroy( &lc->lc_mutex ); - ch_free( lc ); - on->on_bi.bi_private = NULL; - be->be_private = private; + rc = ldap_chain_db_func( be, db_destroy ); + + if ( lc ) { + ch_free( lc ); + } + return rc; } +static int +ldap_chain_db_init_one( + BackendDB *be ) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; + + BackendDB db = *be; + int t; + ldapinfo_t *li; + + db.bd_info = lback; + db.be_private = NULL; + t = lback->bi_db_init( &db ); + if ( t != 0 ) { + return t; + } + li = (ldapinfo_t *)db.be_private; + + /* copy common data */ + li->li_nretries = lc->lc_common_li->li_nretries; + li->li_flags = lc->lc_common_li->li_flags; + li->li_version = lc->lc_common_li->li_version; + for ( t = 0; t < LDAP_BACK_OP_LAST; t++ ) { + li->li_timeout[ t ] = lc->lc_common_li->li_timeout[ t ]; + } + + be->be_private = li; + + return 0; +} + +typedef struct ldap_chain_conn_apply_t { + BackendDB *be; + Connection *conn; +} ldap_chain_conn_apply_t; + +static int +ldap_chain_conn_apply( void *datum, void *arg ) +{ + ldapinfo_t *li = (ldapinfo_t *)datum; + ldap_chain_conn_apply_t *lca = (ldap_chain_conn_apply_t *)arg; + + lca->be->be_private = (void *)li; + + return lback->bi_connection_destroy( lca->be, lca->conn ); +} + static int ldap_chain_connection_destroy( BackendDB *be, Connection *conn ) { - slap_overinst *on = (slap_overinst *) be->bd_info; - ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - void *private = be->be_private; - int rc; - - be->be_private = (void *)lc->lc_li; - rc = lback->bi_connection_destroy( be, conn ); + slap_overinst *on = (slap_overinst *) be->bd_info; + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; + void *private = be->be_private; + ldap_chain_conn_apply_t lca; + int rc; + + be->be_private = NULL; + lca.be = be; + lca.conn = conn; + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); + rc = avl_apply( lc->lc_lai.lai_tree, ldap_chain_conn_apply, + (void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE; + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); be->be_private = private; return rc; @@ -1303,8 +1572,9 @@ chain_init( void ) ldapchain.on_bi.bi_type = "chain"; ldapchain.on_bi.bi_db_init = ldap_chain_db_init; - ldapchain.on_bi.bi_db_open = ldap_chain_db_open; ldapchain.on_bi.bi_db_config = ldap_chain_db_config; + ldapchain.on_bi.bi_db_open = ldap_chain_db_open; + ldapchain.on_bi.bi_db_close = ldap_chain_db_close; ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy; /* ... otherwise the underlying backend's function would be called, diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index 64caac368a..0d0a90ed49 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -36,7 +36,7 @@ ldap_back_compare( Operation *op, SlapReply *rs ) { - struct ldapconn *lc; + ldapconn_t *lc; ber_int_t msgid; int do_retry = 1; LDAPControl **ctrls = NULL; @@ -63,7 +63,7 @@ retry: rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT ); if ( rc == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 3e5573f7bb..2cc55fec88 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -293,7 +293,7 @@ static slap_cf_aux_table timeout_table[] = { static int ldap_back_cf_gen( ConfigArgs *c ) { - struct ldapinfo *li = ( struct ldapinfo * )c->be->be_private; + ldapinfo_t *li = ( ldapinfo_t * )c->be->be_private; int rc; int i; @@ -303,8 +303,8 @@ ldap_back_cf_gen( ConfigArgs *c ) switch( c->type ) { case LDAP_BACK_CFG_URI: - if ( li->url != NULL ) { - c->value_string = ch_strdup( li->url ); + if ( li->li_uri != NULL ) { + c->value_string = ch_strdup( li->li_uri ); } else { rc = 1; @@ -312,7 +312,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_TLS: - enum_to_verb( tls_mode, ( li->flags & LDAP_BACK_F_TLS_MASK ), &bv ); + enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv ); if ( BER_BVISNULL( &bv ) ) { /* there's something wrong... */ assert( 0 ); @@ -333,7 +333,7 @@ ldap_back_cf_gen( ConfigArgs *c ) case LDAP_BACK_CFG_ACL_BIND: { int i; - bindconf_unparse( &li->acl_sb, &bv ); + bindconf_unparse( &li->li_acl, &bv ); for ( i = 0; isspace( bv.bv_val[ i ] ); i++ ) /* count spaces */ ; @@ -359,14 +359,14 @@ ldap_back_cf_gen( ConfigArgs *c ) case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: { int i; - if ( li->idassert_authz == NULL ) { + if ( li->li_idassert_authz == NULL ) { rc = 1; break; } - for ( i = 0; !BER_BVISNULL( &li->idassert_authz[ i ] ); i++ ) + for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ ) { - value_add_one( &c->rvalue_vals, &li->idassert_authz[ i ] ); + value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] ); } break; } @@ -376,10 +376,10 @@ ldap_back_cf_gen( ConfigArgs *c ) struct berval bc = BER_BVNULL; char *ptr; - if ( li->idassert_authmethod != LDAP_AUTH_NONE ) { + if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) { ber_len_t len; - switch ( li->idassert_mode ) { + switch ( li->li_idassert_mode ) { case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERDN: break; @@ -387,7 +387,7 @@ ldap_back_cf_gen( ConfigArgs *c ) default: { struct berval mode = BER_BVNULL; - enum_to_verb( idassert_mode, li->idassert_mode, &mode ); + enum_to_verb( idassert_mode, li->li_idassert_mode, &mode ); if ( BER_BVISNULL( &mode ) ) { /* there's something wrong... */ assert( 0 ); @@ -404,7 +404,7 @@ ldap_back_cf_gen( ConfigArgs *c ) } } - if ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) { len = bv.bv_len + STRLENOF( "authz=native" ); if ( !BER_BVISEMPTY( &bv ) ) { @@ -438,13 +438,13 @@ ldap_back_cf_gen( ConfigArgs *c ) ptr = lutil_strcopy( ptr, "flags=" ); - if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { ptr = lutil_strcopy( ptr, "prescriptive" ); } else { ptr = lutil_strcopy( ptr, "non-prescriptive" ); } - if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { ptr = lutil_strcopy( ptr, ",override" ); } @@ -452,7 +452,7 @@ ldap_back_cf_gen( ConfigArgs *c ) /* end-of-flags */ } - bindconf_unparse( &li->idassert_sb, &bc ); + bindconf_unparse( &li->li_idassert, &bc ); if ( !BER_BVISNULL( &bv ) ) { ber_len_t len = bv.bv_len + bc.bv_len; @@ -483,7 +483,7 @@ ldap_back_cf_gen( ConfigArgs *c ) } case LDAP_BACK_CFG_REBIND: - enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_SAVECRED ) == LDAP_BACK_F_SAVECRED ), &bv ); + enum_to_verb( yn_mode, ( ( li->li_flags & LDAP_BACK_F_SAVECRED ) == LDAP_BACK_F_SAVECRED ), &bv ); if ( BER_BVISNULL( &bv ) ) { /* there's something wrong... */ assert( 0 ); @@ -495,7 +495,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_CHASE: - enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) == LDAP_BACK_F_CHASE_REFERRALS ), &bv ); + enum_to_verb( yn_mode, ( ( li->li_flags & LDAP_BACK_F_CHASE_REFERRALS ) == LDAP_BACK_F_CHASE_REFERRALS ), &bv ); if ( BER_BVISNULL( &bv ) ) { /* there's something wrong... */ assert( 0 ); @@ -507,7 +507,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_T_F: - enum_to_verb( t_f_mode, ( ( li->flags & LDAP_BACK_F_SUPPORT_T_F_MASK ) == LDAP_BACK_F_SUPPORT_T_F_MASK ), &bv ); + enum_to_verb( t_f_mode, ( ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F_MASK ) == LDAP_BACK_F_SUPPORT_T_F_MASK ), &bv ); if ( BER_BVISNULL( &bv ) ) { /* there's something wrong... */ assert( 0 ); @@ -519,7 +519,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_WHOAMI: - enum_to_verb( yn_mode, ( ( li->flags & LDAP_BACK_F_PROXY_WHOAMI ) == LDAP_BACK_F_PROXY_WHOAMI ), &bv ); + enum_to_verb( yn_mode, ( ( li->li_flags & LDAP_BACK_F_PROXY_WHOAMI ) == LDAP_BACK_F_PROXY_WHOAMI ), &bv ); if ( BER_BVISNULL( &bv ) ) { /* there's something wrong... */ assert( 0 ); @@ -533,7 +533,7 @@ ldap_back_cf_gen( ConfigArgs *c ) case LDAP_BACK_CFG_TIMEOUT: BER_BVZERO( &bv ); - slap_cf_aux_table_unparse( li->timeout, &bv, timeout_table ); + slap_cf_aux_table_unparse( li->li_timeout, &bv, timeout_table ); if ( !BER_BVISNULL( &bv ) ) { for ( i = 0; isspace( bv.bv_val[ i ] ); i++ ) @@ -560,21 +560,22 @@ ldap_back_cf_gen( ConfigArgs *c ) rc = 0; switch( c->type ) { case LDAP_BACK_CFG_URI: - if ( li->url != NULL ) { - ch_free( li->url ); - li->url = NULL; - } + if ( li->li_uri != NULL ) { + ch_free( li->li_uri ); + li->li_uri = NULL; - if ( li->lud != NULL ) { - ldap_free_urllist( li->lud ); - li->lud = NULL; + assert( li->li_bvuri != NULL ); + ber_bvarray_free( li->li_bvuri ); + li->li_bvuri = NULL; } - + /* better cleanup the cached connections... */ /* NOTE: don't worry about locking: if we got here, * other threads are suspended. */ - avl_free( li->conntree, ldap_back_conn_free ); - li->conntree = NULL; + if ( li->li_conninfo.lai_tree != NULL ) { + avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); + li->li_conninfo.lai_tree = NULL; + } break; @@ -590,7 +591,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_ACL_BIND: - bindconf_free( &li->acl_sb ); + bindconf_free( &li->li_acl ); break; case LDAP_BACK_CFG_IDASSERT_MODE: @@ -602,14 +603,14 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: - if ( li->idassert_authz != NULL ) { - ber_bvarray_free( li->idassert_authz ); - li->idassert_authz = NULL; + if ( li->li_idassert_authz != NULL ) { + ber_bvarray_free( li->li_idassert_authz ); + li->li_idassert_authz = NULL; } break; case LDAP_BACK_CFG_IDASSERT_BIND: - bindconf_free( &li->idassert_sb ); + bindconf_free( &li->li_idassert ); break; case LDAP_BACK_CFG_REBIND: @@ -621,7 +622,7 @@ ldap_back_cf_gen( ConfigArgs *c ) case LDAP_BACK_CFG_TIMEOUT: for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) { - li->timeout[ i ] = 0; + li->li_timeout[ i ] = 0; } break; @@ -636,11 +637,9 @@ ldap_back_cf_gen( ConfigArgs *c ) switch( c->type ) { case LDAP_BACK_CFG_URI: { - LDAPURLDesc *tmpludp; -#if 0 - char **urllist; -#endif - int urlrc, i; + LDAPURLDesc *tmpludp, *lud; + char **urllist = NULL; + int urlrc = LDAP_URL_SUCCESS, i; if ( c->argc != 2 ) { fprintf( stderr, "%s: line %d: " @@ -650,20 +649,17 @@ ldap_back_cf_gen( ConfigArgs *c ) return 1; } - if ( li->url != NULL ) { - ch_free( li->url ); - } + if ( li->li_uri != NULL ) { + ch_free( li->li_uri ); + li->li_uri = NULL; - if ( li->lud != NULL ) { - ldap_free_urllist( li->lud ); + assert( li->li_bvuri != NULL ); + ber_bvarray_free( li->li_bvuri ); + li->li_bvuri = NULL; } -#if 0 /* PARANOID: DN and more are not required nor allowed */ - urlrc = ldap_url_parselist_ext( &li->lud, c->value_string, "\t" ); -#else - urlrc = ldap_url_parselist( &li->lud, c->value_string ); -#endif + urlrc = ldap_url_parselist_ext( &lud, c->value_string, ", \t" ); if ( urlrc != LDAP_URL_SUCCESS ) { char *why; @@ -682,6 +678,7 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_URL_ERR_BADURL: why = "URL is bad"; + break; case LDAP_URL_ERR_BADHOST: why = "host/port is bad"; break; @@ -705,10 +702,11 @@ ldap_back_cf_gen( ConfigArgs *c ) "unable to parse uri \"%s\" " "in \"uri \" line: %s\n", c->fname, c->lineno, c->value_string, why ); - return 1; + urlrc = 1; + goto done_url; } - for ( i = 0, tmpludp = li->lud; + for ( i = 0, tmpludp = lud; tmpludp; i++, tmpludp = tmpludp->lud_next ) { @@ -728,15 +726,14 @@ ldap_back_cf_gen( ConfigArgs *c ) } } -#if 0 - for ( i = 0, tmpludp = li->lud; + for ( i = 0, tmpludp = lud; tmpludp; i++, tmpludp = tmpludp->lud_next ) /* just count */ ; urllist = ch_calloc( sizeof( char * ), i + 1 ); - for ( i = 0, tmpludp = li->lud; + for ( i = 0, tmpludp = lud; tmpludp; i++, tmpludp = tmpludp->lud_next ) { @@ -759,17 +756,33 @@ ldap_back_cf_gen( ConfigArgs *c ) "unable to rebuild uri " "in \"uri \" statement " "for \"%s\"\n", - c->fname, c->lineno, argv[ 1 ] ); - return 1; + c->fname, c->lineno, c->argv[ 1 ] ); + urlrc = 1; + goto done_url; } } - li->url = ldap_charray2str( urllist, " " ); - ldap_charray_free( urllist ); -#else - li->url = c->value_string; - c->value_string = NULL; -#endif + li->li_uri = ldap_charray2str( urllist, " " ); + for ( i = 0; urllist[ i ] != NULL; i++ ) { + struct berval bv; + + ber_str2bv( urllist[ i ], 0, 0, &bv ); + ber_bvarray_add( &li->li_bvuri, &bv ); + urllist[ i ] = NULL; + } + ldap_memfree( urllist ); + urllist = NULL; + +done_url:; + if ( urllist ) { + ldap_charray_free( urllist ); + } + if ( lud ) { + ldap_free_urllist( lud ); + } + if ( urlrc != LDAP_URL_SUCCESS ) { + return 1; + } break; } @@ -778,14 +791,14 @@ ldap_back_cf_gen( ConfigArgs *c ) if ( BER_BVISNULL( &tls_mode[i].word ) ) { return 1; } - li->flags &= ~LDAP_BACK_F_TLS_MASK; - li->flags |= tls_mode[i].mask; + li->li_flags &= ~LDAP_BACK_F_TLS_MASK; + li->li_flags |= tls_mode[i].mask; break; case LDAP_BACK_CFG_ACL_AUTHCDN: - switch ( li->acl_authmethod ) { + switch ( li->li_acl_authmethod ) { case LDAP_AUTH_NONE: - li->acl_authmethod = LDAP_AUTH_SIMPLE; + li->li_acl_authmethod = LDAP_AUTH_SIMPLE; break; case LDAP_AUTH_SIMPLE: @@ -795,22 +808,22 @@ ldap_back_cf_gen( ConfigArgs *c ) fprintf( stderr, "%s: line %d: " "\"acl-authcDN \" incompatible " "with auth method %d.", - c->fname, c->lineno, li->acl_authmethod ); + c->fname, c->lineno, li->li_acl_authmethod ); return 1; } - if ( !BER_BVISNULL( &li->acl_authcDN ) ) { - free( li->acl_authcDN.bv_val ); + if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) { + free( li->li_acl_authcDN.bv_val ); } ber_memfree_x( c->value_dn.bv_val, NULL ); - li->acl_authcDN = c->value_ndn; + li->li_acl_authcDN = c->value_ndn; BER_BVZERO( &c->value_dn ); BER_BVZERO( &c->value_ndn ); break; case LDAP_BACK_CFG_ACL_PASSWD: - switch ( li->acl_authmethod ) { + switch ( li->li_acl_authmethod ) { case LDAP_AUTH_NONE: - li->acl_authmethod = LDAP_AUTH_SIMPLE; + li->li_acl_authmethod = LDAP_AUTH_SIMPLE; break; case LDAP_AUTH_SIMPLE: @@ -820,19 +833,19 @@ ldap_back_cf_gen( ConfigArgs *c ) fprintf( stderr, "%s: line %d: " "\"acl-passwd \" incompatible " "with auth method %d.", - c->fname, c->lineno, li->acl_authmethod ); + c->fname, c->lineno, li->li_acl_authmethod ); return 1; } - if ( !BER_BVISNULL( &li->acl_passwd ) ) { - free( li->acl_passwd.bv_val ); + if ( !BER_BVISNULL( &li->li_acl_passwd ) ) { + free( li->li_acl_passwd.bv_val ); } - ber_str2bv( c->argv[ 1 ], 0, 1, &li->acl_passwd ); + ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_acl_passwd ); break; case LDAP_BACK_CFG_ACL_METHOD: case LDAP_BACK_CFG_ACL_BIND: for ( i = 1; i < c->argc; i++ ) { - if ( bindconf_parse( c->argv[ i ], &li->acl_sb ) ) { + if ( bindconf_parse( c->argv[ i ], &li->li_acl ) ) { return 1; } } @@ -842,9 +855,9 @@ ldap_back_cf_gen( ConfigArgs *c ) i = verb_to_mask( c->argv[1], idassert_mode ); if ( BER_BVISNULL( &idassert_mode[i].word ) ) { if ( strncasecmp( c->argv[1], "u:", STRLENOF( "u:" ) ) == 0 ) { - li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID; - ber_str2bv( c->argv[1], 0, 1, &li->idassert_authzID ); - li->idassert_authzID.bv_val[ 0 ] = 'u'; + li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERID; + ber_str2bv( c->argv[1], 0, 1, &li->li_idassert_authzID ); + li->li_idassert_authzID.bv_val[ 0 ] = 'u'; } else { struct berval id, ndn; @@ -864,17 +877,17 @@ ldap_back_cf_gen( ConfigArgs *c ) return 1; } - li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len; - li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 ); - AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); - AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 ); + li->li_idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len; + li->li_idassert_authzID.bv_val = ch_malloc( li->li_idassert_authzID.bv_len + 1 ); + AC_MEMCPY( li->li_idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); + AC_MEMCPY( &li->li_idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 ); ch_free( ndn.bv_val ); - li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN; + li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERDN; } } else { - li->idassert_mode = idassert_mode[i].mask; + li->li_idassert_mode = idassert_mode[i].mask; } if ( c->argc > 2 ) { @@ -882,13 +895,13 @@ ldap_back_cf_gen( ConfigArgs *c ) for ( i = 2; i < c->argc; i++ ) { if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; + li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; } else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; + li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) { - li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); + li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); } else { Debug( LDAP_DEBUG_ANY, @@ -903,9 +916,9 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_IDASSERT_AUTHCDN: - switch ( li->idassert_authmethod ) { + switch ( li->li_idassert_authmethod ) { case LDAP_AUTH_NONE: - li->idassert_authmethod = LDAP_AUTH_SIMPLE; + li->li_idassert_authmethod = LDAP_AUTH_SIMPLE; break; case LDAP_AUTH_SIMPLE: @@ -915,22 +928,22 @@ ldap_back_cf_gen( ConfigArgs *c ) fprintf( stderr, "%s: line %d: " "\"idassert-authcDN \" incompatible " "with auth method %d.", - c->fname, c->lineno, li->idassert_authmethod ); + c->fname, c->lineno, li->li_idassert_authmethod ); return 1; } - if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { - free( li->idassert_authcDN.bv_val ); + if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) { + free( li->li_idassert_authcDN.bv_val ); } ber_memfree_x( c->value_dn.bv_val, NULL ); - li->idassert_authcDN = c->value_ndn; + li->li_idassert_authcDN = c->value_ndn; BER_BVZERO( &c->value_dn ); BER_BVZERO( &c->value_ndn ); break; case LDAP_BACK_CFG_IDASSERT_PASSWD: - switch ( li->idassert_authmethod ) { + switch ( li->li_idassert_authmethod ) { case LDAP_AUTH_NONE: - li->idassert_authmethod = LDAP_AUTH_SIMPLE; + li->li_idassert_authmethod = LDAP_AUTH_SIMPLE; break; case LDAP_AUTH_SIMPLE: @@ -940,13 +953,13 @@ ldap_back_cf_gen( ConfigArgs *c ) fprintf( stderr, "%s: line %d: " "\"idassert-passwd \" incompatible " "with auth method %d.", - c->fname, c->lineno, li->idassert_authmethod ); + c->fname, c->lineno, li->li_idassert_authmethod ); return 1; } - if ( !BER_BVISNULL( &li->idassert_passwd ) ) { - free( li->idassert_passwd.bv_val ); + if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) { + free( li->li_idassert_passwd.bv_val ); } - ber_str2bv( c->argv[ 1 ], 0, 1, &li->idassert_passwd ); + ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd ); break; case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: { @@ -967,7 +980,7 @@ ldap_back_cf_gen( ConfigArgs *c ) #else /* !SLAP_AUTHZ_SYNTAX */ ber_str2bv( c->argv[ 1 ], 0, 1, &bv ); #endif /* !SLAP_AUTHZ_SYNTAX */ - ber_bvarray_add( &li->idassert_authz, &bv ); + ber_bvarray_add( &li->li_idassert_authz, &bv ); } break; case LDAP_BACK_CFG_IDASSERT_METHOD: @@ -993,13 +1006,13 @@ ldap_back_cf_gen( ConfigArgs *c ) return 1; } - li->idassert_mode = idassert_mode[ j ].mask; + 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->idassert_authmethod != LDAP_AUTH_SASL ) { + if ( li->li_idassert_authmethod != LDAP_AUTH_SASL ) { fprintf( stderr, "%s: %d: " "\"idassert-bind \": " "authz=\"native\" incompatible " @@ -1007,10 +1020,10 @@ ldap_back_cf_gen( ConfigArgs *c ) c->fname, c->lineno ); return 1; } - li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ; + li->li_idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ; } else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) { - li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; + li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; } else { fprintf( stderr, "%s: %d: " @@ -1035,13 +1048,13 @@ ldap_back_cf_gen( ConfigArgs *c ) for ( j = 0; flags[ j ] != NULL; j++ ) { if ( strcasecmp( flags[ j ], "override" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; + li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; } else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; + li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) { - li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); + li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); } else { fprintf( stderr, "%s: %d: " @@ -1054,7 +1067,7 @@ ldap_back_cf_gen( ConfigArgs *c ) ldap_charray_free( flags ); - } else if ( bindconf_parse( c->argv[ i ], &li->idassert_sb ) ) { + } else if ( bindconf_parse( c->argv[ i ], &li->li_idassert ) ) { return 1; } } @@ -1078,10 +1091,10 @@ ldap_back_cf_gen( ConfigArgs *c ) } if ( dorebind ) { - li->flags |= LDAP_BACK_F_SAVECRED; + li->li_flags |= LDAP_BACK_F_SAVECRED; } else { - li->flags &= ~LDAP_BACK_F_SAVECRED; + li->li_flags &= ~LDAP_BACK_F_SAVECRED; } } break; @@ -1103,10 +1116,10 @@ ldap_back_cf_gen( ConfigArgs *c ) } if ( dochase ) { - li->flags |= LDAP_BACK_F_CHASE_REFERRALS; + li->li_flags |= LDAP_BACK_F_CHASE_REFERRALS; } else { - li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS; + li->li_flags &= ~LDAP_BACK_F_CHASE_REFERRALS; } } break; @@ -1115,8 +1128,8 @@ ldap_back_cf_gen( ConfigArgs *c ) if ( BER_BVISNULL( &t_f_mode[i].word ) ) { return 1; } - li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK; - li->flags |= t_f_mode[i].mask; + li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK; + li->li_flags |= t_f_mode[i].mask; break; case LDAP_BACK_CFG_WHOAMI: { @@ -1137,13 +1150,13 @@ ldap_back_cf_gen( ConfigArgs *c ) } if ( dowhoami ) { - li->flags |= LDAP_BACK_F_PROXY_WHOAMI; + li->li_flags |= LDAP_BACK_F_PROXY_WHOAMI; load_extop( (struct berval *)&slap_EXOP_WHOAMI, 0, ldap_back_exop_whoami ); } else { - li->flags &= ~LDAP_BACK_F_PROXY_WHOAMI; + li->li_flags &= ~LDAP_BACK_F_PROXY_WHOAMI; } } break; @@ -1164,13 +1177,13 @@ ldap_back_cf_gen( ConfigArgs *c ) } for ( j = 0; j < LDAP_BACK_OP_LAST; j++ ) { - li->timeout[ j ] = u; + li->li_timeout[ j ] = u; } continue; } - if ( slap_cf_aux_table_parse( c->argv[ i ], li->timeout, timeout_table, "slapd-ldap timeout" ) ) { + if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) { return 1; } } @@ -1238,400 +1251,6 @@ ldap_back_init_cf( BackendInfo *bi ) } -static int -parse_idassert( BackendDB *be, const char *fname, int lineno, - int argc, char **argv ); - -static int -parse_acl_auth( BackendDB *be, const char *fname, int lineno, - int argc, char **argv ); - -int -ldap_back_db_config( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv ) -{ - struct ldapinfo *li = (struct ldapinfo *) be->be_private; - - if ( li == NULL ) { - fprintf( stderr, "%s: line %d: ldap backend info is null!\n", - fname, lineno ); - return 1; - } - - /* server address to query (no longer supported, use "uri" directive) */ - if ( strcasecmp( argv[0], "server" ) == 0 ) { - fprintf( stderr, - "%s: line %d: \"server
\" directive is no longer supported.\n", - fname, lineno ); - return 1; - - /* URI of server to query (obsoletes "server" directive) */ - } else if ( strcasecmp( argv[0], "uri" ) == 0 ) { - LDAPURLDesc *tmpludp; -#if 0 - char **urllist; -#endif - int urlrc, i; - - if ( argc != 2 ) { - fprintf( stderr, "%s: line %d: " - "missing uri " - "in \"uri \" line\n", - fname, lineno ); - return 1; - } - if ( li->url != NULL ) { - ch_free( li->url ); - } - if ( li->lud != NULL ) { - ldap_free_urllist( li->lud ); - } - -#if 0 - /* PARANOID: DN and more are not required nor allowed */ - urlrc = ldap_url_parselist_ext( &li->lud, argv[ 1 ], "\t" ); -#else - urlrc = ldap_url_parselist( &li->lud, argv[ 1 ] ); -#endif - if ( urlrc != LDAP_URL_SUCCESS ) { - char *why; - - switch ( urlrc ) { - case LDAP_URL_ERR_MEM: - why = "no memory"; - break; - case LDAP_URL_ERR_PARAM: - why = "parameter is bad"; - break; - case LDAP_URL_ERR_BADSCHEME: - why = "URL doesn't begin with \"[c]ldap[si]://\""; - break; - case LDAP_URL_ERR_BADENCLOSURE: - why = "URL is missing trailing \">\""; - break; - case LDAP_URL_ERR_BADURL: - why = "URL is bad"; - case LDAP_URL_ERR_BADHOST: - why = "host/port is bad"; - break; - case LDAP_URL_ERR_BADATTRS: - why = "bad (or missing) attributes"; - break; - case LDAP_URL_ERR_BADSCOPE: - why = "scope string is invalid (or missing)"; - break; - case LDAP_URL_ERR_BADFILTER: - why = "bad or missing filter"; - break; - case LDAP_URL_ERR_BADEXTS: - why = "bad or missing extensions"; - break; - default: - why = "unknown reason"; - break; - } - fprintf( stderr, "%s: line %d: " - "unable to parse uri \"%s\" " - "in \"uri \" line: %s\n", - fname, lineno, argv[ 1 ], why ); - return 1; - } - - for ( i = 0, tmpludp = li->lud; - tmpludp; - i++, tmpludp = tmpludp->lud_next ) - { - if ( ( tmpludp->lud_dn != NULL - && tmpludp->lud_dn[0] != '\0' ) - || tmpludp->lud_attrs != NULL - /* || tmpludp->lud_scope != LDAP_SCOPE_DEFAULT */ - || tmpludp->lud_filter != NULL - || tmpludp->lud_exts != NULL ) - { - fprintf( stderr, "%s: line %d: " - "warning, only protocol, " - "host and port allowed " - "in \"uri \" statement " - "for uri #%d of \"%s\"\n", - fname, lineno, i, argv[1] ); - } - } - -#if 0 - for ( i = 0, tmpludp = li->lud; - tmpludp; - i++, tmpludp = tmpludp->lud_next ) - /* just count */ - ; - urllist = ch_calloc( sizeof( char * ), i + 1 ); - - for ( i = 0, tmpludp = li->lud; - tmpludp; - i++, tmpludp = tmpludp->lud_next ) - { - LDAPURLDesc tmplud; - ber_len_t oldlen = 0, len; - - tmplud = *tmpludp; - tmplud.lud_dn = ""; - tmplud.lud_attrs = NULL; - tmplud.lud_filter = NULL; - if ( !ldap_is_ldapi_url( tmplud.lud_scheme ) ) { - tmplud.lud_exts = NULL; - tmplud.lud_crit_exts = 0; - } - - urllist[ i ] = ldap_url_desc2str( &tmplud ); - - if ( urllist[ i ] == NULL ) { - fprintf( stderr, "%s: line %d: " - "unable to rebuild uri " - "in \"uri \" statement " - "for \"%s\"\n", - fname, lineno, argv[ 1 ] ); - return 1; - } - } - - li->url = ldap_charray2str( urllist, " " ); - ldap_charray_free( urllist ); -#else - li->url = ch_strdup( argv[ 1 ] ); -#endif - - } else if ( strcasecmp( argv[0], "tls" ) == 0 ) { - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: \"tls \" needs 1 argument.\n", - fname, lineno ); - return( 1 ); - } - - /* none */ - if ( strcasecmp( argv[1], "none" ) == 0 ) { - li->flags &= ~LDAP_BACK_F_TLS_MASK; - - /* try start tls */ - } else if ( strcasecmp( argv[1], "start" ) == 0 ) { - li->flags |= LDAP_BACK_F_TLS_USE_MASK; - - /* try start tls */ - } else if ( strcasecmp( argv[1], "try-start" ) == 0 ) { - li->flags &= ~LDAP_BACK_F_TLS_CRITICAL; - li->flags |= LDAP_BACK_F_USE_TLS; - - /* propagate start tls */ - } else if ( strcasecmp( argv[1], "propagate" ) == 0 ) { - li->flags |= LDAP_BACK_F_TLS_PROPAGATE_MASK; - - /* try start tls */ - } else if ( strcasecmp( argv[1], "try-propagate" ) == 0 ) { - li->flags &= ~LDAP_BACK_F_TLS_CRITICAL; - li->flags |= LDAP_BACK_F_PROPAGATE_TLS; - - } else { - fprintf( stderr, - "%s: line %d: \"tls \": unknown argument \"%s\".\n", - fname, lineno, argv[1] ); - return( 1 ); - } - - /* remote ACL stuff... */ - } else if ( strncasecmp( argv[0], "acl-", STRLENOF( "acl-" ) ) == 0 - || strncasecmp( argv[0], "bind", STRLENOF( "bind" ) ) == 0 ) - { - /* NOTE: "bind{DN,pw}" was initially used; it's now - * deprected and undocumented, it can be dropped at some - * point, since nobody should be really using it */ - return parse_acl_auth( be, fname, lineno, argc, argv ); - - /* identity assertion stuff... */ - } else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0 - || strncasecmp( argv[0], "proxyauthz", STRLENOF( "proxyauthz" ) ) == 0 ) - { - /* NOTE: "proxyauthz{DN,pw}" was initially used; it's now - * deprected and undocumented, it can be dropped at some - * point, since nobody should be really using it */ - return parse_idassert( be, fname, lineno, argc, argv ); - - /* save bind creds for referral rebinds? */ - } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) { - switch ( argc ) { - case 1: - fprintf( stderr, - "%s: line %d: \"rebind-as-user {NO|yes}\": use without args is deprecated.\n", - fname, lineno ); - - li->flags |= LDAP_BACK_F_SAVECRED; - break; - - case 2: - if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - li->flags |= LDAP_BACK_F_SAVECRED; - - } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - li->flags &= ~LDAP_BACK_F_SAVECRED; - - } else { - fprintf( stderr, - "%s: line %d: \"rebind-as-user {NO|yes}\": unknown argument \"%s\".\n", - fname, lineno, argv[ 1 ] ); - return( 1 ); - } - break; - - default: - fprintf( stderr, - "%s: line %d: \"rebind-as-user {NO|yes}\" needs 1 argument.\n", - fname, lineno ); - return( 1 ); - } - - } else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) { - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: \"chase-referrals {YES|no}\" needs 1 argument.\n", - fname, lineno ); - return( 1 ); - } - - /* this is the default; we add it because the default might change... */ - if ( strcasecmp( argv[1], "yes" ) == 0 ) { - li->flags |= LDAP_BACK_F_CHASE_REFERRALS; - - } else if ( strcasecmp( argv[1], "no" ) == 0 ) { - li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS; - - } else { - fprintf( stderr, - "%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n", - fname, lineno, argv[1] ); - return( 1 ); - } - - } else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) { - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n", - fname, lineno ); - return( 1 ); - } - - if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { - li->flags &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER); - - } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - li->flags |= LDAP_BACK_F_SUPPORT_T_F; - - } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) { - li->flags |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER; - - } else { - fprintf( stderr, - "%s: line %d: \"t-f-support {NO|yes|discover}\": unknown argument \"%s\".\n", - fname, lineno, argv[ 1 ] ); - return 1; - } - - /* intercept exop_who_am_i? */ - } else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) { - int doload_extop = 0; - - switch ( argc ) { - case 1: - fprintf( stderr, - "%s: line %d: \"proxy-whoami {NO|yes}\": use without args is deprecated.\n", - fname, lineno ); - - doload_extop = 1; - break; - - case 2: - if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { - doload_extop = 1; - - } else if ( strcasecmp( argv[ 1 ], "no" ) != 0 ) { - fprintf( stderr, - "%s: line %d: \"proxy-whoami {NO|yes}\": unknown argument \"%s\".\n", - fname, lineno, argv[ 1 ] ); - return( 1 ); - } - break; - - default: - fprintf( stderr, - "%s: line %d: \"proxy-whoami {NO|yes}\" needs 1 argument.\n", - fname, lineno ); - return( 1 ); - } - - if ( doload_extop ) { - li->flags |= LDAP_BACK_F_PROXY_WHOAMI; - - load_extop( (struct berval *)&slap_EXOP_WHOAMI, - 0, ldap_back_exop_whoami ); - } - - /* FIXME: legacy: intercept old rewrite/remap directives - * and try to start the rwm overlay */ - } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 - || strcasecmp( argv[0], "map" ) == 0 - || strncasecmp( argv[0], "rewrite", STRLENOF( "rewrite" ) ) == 0 ) - { -#if 0 - fprintf( stderr, "%s: line %d: " - "rewrite/remap capabilities have been moved " - "to the \"rwm\" overlay; see slapo-rwm(5) " - "for details. I'm trying to do my best " - "to preserve backwards compatibility...\n", - fname, lineno ); - - if ( li->rwm_started == 0 ) { - if ( overlay_config( be, "rwm" ) ) { - fprintf( stderr, "%s: line %d: " - "unable to configure the \"rwm\" " - "overlay, required by directive " - "\"%s\".\n", - fname, lineno, argv[0] ); -#if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC - fprintf( stderr, "\thint: try loading the \"rwm.la\" dynamic module.\n" ); -#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */ - return( 1 ); - } - - fprintf( stderr, "%s: line %d: back-ldap: " - "automatically starting \"rwm\" overlay, " - "triggered by \"%s\" directive.\n", - fname, lineno, argv[ 0 ] ); - - /* this is the default; we add it because the default might change... */ - li->rwm_started = 1; - - return ( *be->bd_info->bi_db_config )( be, fname, lineno, argc, argv ); - } -#else - fprintf( stderr, "%s: line %d: " - "rewrite/remap capabilities have been moved " - "to the \"rwm\" overlay; see slapo-rwm(5) " - "for details (hint: add \"overlay rwm\" " - "and prefix all directives with \"rwm-\").\n", - fname, lineno ); -#endif - - return 1; - - /* anything else */ - } else { - return SLAP_CONF_UNKNOWN; - } - - return 0; -} - static int ldap_back_exop_whoami( Operation *op, @@ -1654,7 +1273,7 @@ ldap_back_exop_whoami( /* if auth'd by back-ldap and request is proxied, forward it */ if ( op->o_conn->c_authz_backend && !strcmp(op->o_conn->c_authz_backend->be_type, "ldap" ) && !dn_match(&op->o_ndn, &op->o_conn->c_ndn)) { - struct ldapconn *lc; + ldapconn_t *lc; LDAPControl c, *ctrls[2] = {NULL, NULL}; LDAPMessage *res; @@ -1683,10 +1302,10 @@ retry: &rs->sr_err); if ( rs->sr_err == LDAP_SERVER_DOWN && doretry ) { doretry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) goto retry; } - ldap_back_freeconn( op, lc ); + ldap_back_freeconn( op, lc, 1 ); lc = NULL; } else { @@ -1724,562 +1343,3 @@ retry: } -static int -parse_idassert( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv -) -{ - struct ldapinfo *li = (struct ldapinfo *) be->be_private; - - /* identity assertion mode */ - if ( strcasecmp( argv[0], "idassert-mode" ) == 0 ) { - if ( argc < 2 ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: illegal args number %d in \"idassert-mode [ [...]]\" line.\n", - fname, lineno, argc ); - return 1; - } - - if ( strcasecmp( argv[1], "legacy" ) == 0 ) { - /* will proxyAuthz as client's identity only if bound */ - li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY; - - } else if ( strcasecmp( argv[1], "self" ) == 0 ) { - /* will proxyAuthz as client's identity */ - li->idassert_mode = LDAP_BACK_IDASSERT_SELF; - - } else if ( strcasecmp( argv[1], "anonymous" ) == 0 ) { - /* will proxyAuthz as anonymous */ - li->idassert_mode = LDAP_BACK_IDASSERT_ANONYMOUS; - - } else if ( strcasecmp( argv[1], "none" ) == 0 ) { - /* will not proxyAuthz */ - li->idassert_mode = LDAP_BACK_IDASSERT_NOASSERT; - - } else { - struct berval id; - int rc; - - /* will proxyAuthz as argv[1] */ - ber_str2bv( argv[1], 0, 0, &id ); - - if ( strncasecmp( id.bv_val, "u:", STRLENOF( "u:" ) ) == 0 ) { - /* force lowercase... */ - id.bv_val[0] = 'u'; - li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID; - ber_dupbv( &li->idassert_authzID, &id ); - - } else { - struct berval dn; - - /* default is DN? */ - if ( strncasecmp( id.bv_val, "dn:", STRLENOF( "dn:" ) ) == 0 ) { - id.bv_val += STRLENOF( "dn:" ); - id.bv_len -= STRLENOF( "dn:" ); - } - - rc = dnNormalize( 0, NULL, NULL, &id, &dn, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: idassert ID \"%s\" is not a valid DN\n", - fname, lineno, argv[1] ); - return 1; - } - - li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + dn.bv_len; - li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 ); - AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); - AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], dn.bv_val, dn.bv_len + 1 ); - ch_free( dn.bv_val ); - - li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN; - } - } - - for ( argc -= 2, argv += 2; argc--; argv++ ) { - if ( strcasecmp( argv[0], "override" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; - - } else { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: unknown flag \"%s\" " - "in \"idassert-mode " - "[]\" line.\n", - fname, lineno, argv[0] ); - return 1; - } - } - - /* name to use for proxyAuthz propagation */ - } else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0 - || strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) - { - struct berval dn; - int rc; - - /* FIXME: "proxyauthzdn" is no longer documented, and - * temporarily supported for backwards compatibility */ - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: missing name in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { - fprintf( stderr, "%s: line %d: " - "authcDN already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_authcDN.bv_val ); - } - - ber_str2bv( argv[1], 0, 0, &dn ); - rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: idassert ID \"%s\" is not a valid DN\n", - fname, lineno, argv[1] ); - return 1; - } - - /* password to use for proxyAuthz propagation */ - } else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0 - || strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) - { - /* FIXME: "proxyauthzpw" is no longer documented, and - * temporarily supported for backwards compatibility */ - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: missing password in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - if ( !BER_BVISNULL( &li->idassert_passwd ) ) { - fprintf( stderr, "%s: line %d: " - "passwd already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_passwd.bv_val ); - } - - ber_str2bv( argv[1], 0, 1, &li->idassert_passwd ); - - /* rules to accept identity assertion... */ - } else if ( strcasecmp( argv[0], "idassert-authzFrom" ) == 0 ) { - struct berval rule; - - ber_str2bv( argv[1], 0, 1, &rule ); - - ber_bvarray_add( &li->idassert_authz, &rule ); - - } else if ( strcasecmp( argv[0], "idassert-method" ) == 0 ) { - char *argv1; - - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing method in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - argv1 = argv[1]; - if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) { - argv1 += STRLENOF( "bindmethod=" ); - } - - if ( strcasecmp( argv1, "none" ) == 0 ) { - /* FIXME: is this at all useful? */ - li->idassert_authmethod = LDAP_AUTH_NONE; - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n", - fname, lineno, argv[0], argv[1] ); - } - - } else if ( strcasecmp( argv1, "simple" ) == 0 ) { - int arg; - - for ( arg = 2; arg < argc; arg++ ) { - if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authcdn=" ); - struct berval dn; - int rc; - - if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { - fprintf( stderr, "%s: line %d: " - "SASL authcDN already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_authcDN.bv_val ); - } - if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) { - val += STRLENOF( "dn:" ); - } - - ber_str2bv( val, 0, 0, &dn ); - rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: SASL authcdn \"%s\" is not a valid DN\n", - fname, lineno, val ); - return 1; - } - - } else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "cred=" ); - - if ( !BER_BVISNULL( &li->idassert_passwd ) ) { - fprintf( stderr, "%s: line %d: " - "SASL cred already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_passwd.bv_val ); - } - ber_str2bv( val, 0, 1, &li->idassert_passwd ); - - } else { - fprintf( stderr, "%s: line %d: " - "unknown parameter %s\n", - fname, lineno, argv[arg] ); - return 1; - } - } - - li->idassert_authmethod = LDAP_AUTH_SIMPLE; - - } else if ( strcasecmp( argv1, "sasl" ) == 0 ) { -#ifdef HAVE_CYRUS_SASL - int arg; - - for ( arg = 2; arg < argc; arg++ ) { - if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "mech=" ); - - if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) { - fprintf( stderr, "%s: line %d: " - "SASL mech already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_sasl_mech.bv_val ); - } - ber_str2bv( val, 0, 1, &li->idassert_sasl_mech ); - - } else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "realm=" ); - - if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) { - fprintf( stderr, "%s: line %d: " - "SASL realm already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_sasl_realm.bv_val ); - } - ber_str2bv( val, 0, 1, &li->idassert_sasl_realm ); - - } else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authcdn=" ); - struct berval dn; - int rc; - - if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { - fprintf( stderr, "%s: line %d: " - "SASL authcDN already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_authcDN.bv_val ); - } - if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) { - val += STRLENOF( "dn:" ); - } - - ber_str2bv( val, 0, 0, &dn ); - rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: SASL authcdn \"%s\" is not a valid DN\n", - fname, lineno, val ); - return 1; - } - - } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authcid=" ); - - if ( !BER_BVISNULL( &li->idassert_authcID ) ) { - fprintf( stderr, "%s: line %d: " - "SASL authcID already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_authcID.bv_val ); - } - if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) { - val += STRLENOF( "u:" ); - } - ber_str2bv( val, 0, 1, &li->idassert_authcID ); - - } else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "cred=" ); - - if ( !BER_BVISNULL( &li->idassert_passwd ) ) { - fprintf( stderr, "%s: line %d: " - "SASL cred already defined; replacing...\n", - fname, lineno ); - ch_free( li->idassert_passwd.bv_val ); - } - ber_str2bv( val, 0, 1, &li->idassert_passwd ); - - } else if ( strncasecmp( argv[arg], "authz=", STRLENOF( "authz=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authz=" ); - - if ( strcasecmp( val, "proxyauthz" ) == 0 ) { - li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; - - } else if ( strcasecmp( val, "native" ) == 0 ) { - li->idassert_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ; - - } else { - fprintf( stderr, "%s: line %d: " - "unknown authz mode \"%s\"\n", - fname, lineno, val ); - return 1; - } - - } else { - fprintf( stderr, "%s: line %d: " - "unknown SASL parameter %s\n", - fname, lineno, argv[arg] ); - return 1; - } - } - - li->idassert_authmethod = LDAP_AUTH_SASL; - -#else /* !HAVE_CYRUS_SASL */ - fprintf( stderr, "%s: line %d: " - "compile --with-cyrus-sasl to enable SASL auth\n", - fname, lineno ); - return 1; -#endif /* !HAVE_CYRUS_SASL */ - - } else { - fprintf( stderr, "%s: line %d: " - "unhandled idassert-method method %s\n", - fname, lineno, argv[1] ); - return 1; - } - - } else { - return SLAP_CONF_UNKNOWN; - } - - return 0; -} - -static int -parse_acl_auth( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv -) -{ - struct ldapinfo *li = (struct ldapinfo *) be->be_private; - - /* name to use for remote ACL access */ - if ( strcasecmp( argv[0], "acl-authcdn" ) == 0 - || strcasecmp( argv[0], "binddn" ) == 0 ) - { - struct berval dn; - int rc; - - /* FIXME: "binddn" is no longer documented, and - * temporarily supported for backwards compatibility */ - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: missing name in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - if ( !BER_BVISNULL( &li->acl_authcDN ) ) { - fprintf( stderr, "%s: line %d: " - "authcDN already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_authcDN.bv_val ); - } - - ber_str2bv( argv[1], 0, 0, &dn ); - rc = dnNormalize( 0, NULL, NULL, &dn, &li->acl_authcDN, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: acl ID \"%s\" is not a valid DN\n", - fname, lineno, argv[1] ); - return 1; - } - - /* password to use for remote ACL access */ - } else if ( strcasecmp( argv[0], "acl-passwd" ) == 0 - || strcasecmp( argv[0], "bindpw" ) == 0 ) - { - /* FIXME: "bindpw" is no longer documented, and - * temporarily supported for backwards compatibility */ - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: missing password in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - if ( !BER_BVISNULL( &li->acl_passwd ) ) { - fprintf( stderr, "%s: line %d: " - "passwd already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_passwd.bv_val ); - } - - ber_str2bv( argv[1], 0, 1, &li->acl_passwd ); - - } else if ( strcasecmp( argv[0], "acl-method" ) == 0 ) { - char *argv1; - - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing method in \"%s \" line\n", - fname, lineno, argv[0] ); - return( 1 ); - } - - argv1 = argv[1]; - if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) { - argv1 += STRLENOF( "bindmethod=" ); - } - - if ( strcasecmp( argv1, "none" ) == 0 ) { - /* FIXME: is this at all useful? */ - li->acl_authmethod = LDAP_AUTH_NONE; - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n", - fname, lineno, argv[0], argv[1] ); - } - - } else if ( strcasecmp( argv1, "simple" ) == 0 ) { - li->acl_authmethod = LDAP_AUTH_SIMPLE; - - if ( argc != 2 ) { - fprintf( stderr, - "%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n", - fname, lineno, argv[0], argv[1] ); - } - - } else if ( strcasecmp( argv1, "sasl" ) == 0 ) { -#ifdef HAVE_CYRUS_SASL - int arg; - - for ( arg = 2; arg < argc; arg++ ) { - if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "mech=" ); - - if ( !BER_BVISNULL( &li->acl_sasl_mech ) ) { - fprintf( stderr, "%s: line %d: " - "SASL mech already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_sasl_mech.bv_val ); - } - ber_str2bv( val, 0, 1, &li->acl_sasl_mech ); - - } else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "realm=" ); - - if ( !BER_BVISNULL( &li->acl_sasl_realm ) ) { - fprintf( stderr, "%s: line %d: " - "SASL realm already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_sasl_realm.bv_val ); - } - ber_str2bv( val, 0, 1, &li->acl_sasl_realm ); - - } else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authcdn=" ); - struct berval dn; - int rc; - - if ( !BER_BVISNULL( &li->acl_authcDN ) ) { - fprintf( stderr, "%s: line %d: " - "SASL authcDN already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_authcDN.bv_val ); - } - if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) { - val += STRLENOF( "dn:" ); - } - - ber_str2bv( val, 0, 0, &dn ); - rc = dnNormalize( 0, NULL, NULL, &dn, &li->acl_authcDN, NULL ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_ANY, - "%s: line %d: SASL authcdn \"%s\" is not a valid DN\n", - fname, lineno, val ); - return 1; - } - - } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "authcid=" ); - - if ( !BER_BVISNULL( &li->acl_authcID ) ) { - fprintf( stderr, "%s: line %d: " - "SASL authcID already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_authcID.bv_val ); - } - if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) { - val += STRLENOF( "u:" ); - } - ber_str2bv( val, 0, 1, &li->acl_authcID ); - - } else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) { - char *val = argv[arg] + STRLENOF( "cred=" ); - - if ( !BER_BVISNULL( &li->acl_passwd ) ) { - fprintf( stderr, "%s: line %d: " - "SASL cred already defined; replacing...\n", - fname, lineno ); - ch_free( li->acl_passwd.bv_val ); - } - ber_str2bv( val, 0, 1, &li->acl_passwd ); - - } else { - fprintf( stderr, "%s: line %d: " - "unknown SASL parameter %s\n", - fname, lineno, argv[arg] ); - return 1; - } - } - - li->acl_authmethod = LDAP_AUTH_SASL; - -#else /* !HAVE_CYRUS_SASL */ - fprintf( stderr, "%s: line %d: " - "compile --with-cyrus-sasl to enable SASL auth\n", - fname, lineno ); - return 1; -#endif /* !HAVE_CYRUS_SASL */ - - } else { - fprintf( stderr, "%s: line %d: " - "unhandled acl-method method %s\n", - fname, lineno, argv[1] ); - return 1; - } - - } else { - return SLAP_CONF_UNKNOWN; - } - - return 0; -} - diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c index dcce01ae74..03afa19083 100644 --- a/servers/slapd/back-ldap/delete.c +++ b/servers/slapd/back-ldap/delete.c @@ -36,9 +36,9 @@ ldap_back_delete( Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - struct ldapconn *lc; + ldapconn_t *lc; ber_int_t msgid; LDAPControl **ctrls = NULL; int do_retry = 1; @@ -62,10 +62,10 @@ retry: rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val, ctrls, NULL, &msgid ); rc = ldap_back_op_result( lc, op, rs, msgid, - li->timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT ); + li->li_timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index fde2c489b0..8eef4d317e 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -48,7 +48,7 @@ ldap_back_extended( for ( i = 0; exop_table[i].extended != NULL; i++ ) { if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) ) { - struct ldapconn *lc; + ldapconn_t *lc; LDAPControl **oldctrls = NULL; int rc; @@ -98,7 +98,7 @@ ldap_back_exop_passwd( Operation *op, SlapReply *rs ) { - struct ldapconn *lc; + ldapconn_t *lc; req_pwdexop_s *qpw = &op->oq_pwdexop; LDAPMessage *res; ber_int_t msgid; @@ -124,7 +124,7 @@ retry: if ( rc == LDAP_SUCCESS ) { if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) { ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc ); - ldap_back_freeconn( op, lc ); + ldap_back_freeconn( op, lc, 0 ); lc = NULL; } else { @@ -168,7 +168,7 @@ retry: rs->sr_err = slap_map_api2result( rs ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index f250f6d0d9..013e62306e 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -80,45 +80,45 @@ ldap_back_initialize( BackendInfo *bi ) int ldap_back_db_init( Backend *be ) { - struct ldapinfo *li; + ldapinfo_t *li; - li = (struct ldapinfo *)ch_calloc( 1, sizeof( struct ldapinfo ) ); + li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) ); if ( li == NULL ) { return -1; } - BER_BVZERO( &li->acl_authcID ); - BER_BVZERO( &li->acl_authcDN ); - BER_BVZERO( &li->acl_passwd ); + BER_BVZERO( &li->li_acl_authcID ); + BER_BVZERO( &li->li_acl_authcDN ); + BER_BVZERO( &li->li_acl_passwd ); - li->acl_authmethod = LDAP_AUTH_NONE; - BER_BVZERO( &li->acl_sasl_mech ); - li->acl_sb.sb_tls = SB_TLS_DEFAULT; + li->li_acl_authmethod = LDAP_AUTH_NONE; + BER_BVZERO( &li->li_acl_sasl_mech ); + li->li_acl.sb_tls = SB_TLS_DEFAULT; - li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY; + li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY; - BER_BVZERO( &li->idassert_authcID ); - BER_BVZERO( &li->idassert_authcDN ); - BER_BVZERO( &li->idassert_passwd ); + BER_BVZERO( &li->li_idassert_authcID ); + BER_BVZERO( &li->li_idassert_authcDN ); + BER_BVZERO( &li->li_idassert_passwd ); - BER_BVZERO( &li->idassert_authzID ); + BER_BVZERO( &li->li_idassert_authzID ); - li->idassert_authmethod = LDAP_AUTH_NONE; - BER_BVZERO( &li->idassert_sasl_mech ); - li->idassert_sb.sb_tls = SB_TLS_DEFAULT; + li->li_idassert_authmethod = LDAP_AUTH_NONE; + BER_BVZERO( &li->li_idassert_sasl_mech ); + li->li_idassert.sb_tls = SB_TLS_DEFAULT; /* by default, use proxyAuthz control on each operation */ - li->idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE; + li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE; - li->idassert_authz = NULL; + li->li_idassert_authz = NULL; /* initialize flags */ - li->flags = LDAP_BACK_F_CHASE_REFERRALS; + li->li_flags = LDAP_BACK_F_CHASE_REFERRALS; /* initialize version */ - li->version = LDAP_VERSION3; + li->li_version = LDAP_VERSION3; - ldap_pvt_thread_mutex_init( &li->conn_mutex ); + ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex ); be->be_private = li; SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD; @@ -131,19 +131,19 @@ ldap_back_db_init( Backend *be ) int ldap_back_db_open( BackendDB *be ) { - struct ldapinfo *li = (struct ldapinfo *)be->be_private; + ldapinfo_t *li = (ldapinfo_t *)be->be_private; Debug( LDAP_DEBUG_TRACE, "ldap_back_db_open: URI=%s\n", - li->url != NULL ? li->url : "", 0, 0 ); + li->li_uri != NULL ? li->li_uri : "", 0, 0 ); /* by default, use proxyAuthz control on each operation */ - switch ( li->idassert_mode ) { + switch ( li->li_idassert_mode ) { case LDAP_BACK_IDASSERT_LEGACY: case LDAP_BACK_IDASSERT_SELF: /* however, since admin connections are pooled and shared, * only static authzIDs can be native */ - li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; + li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; break; default: @@ -159,7 +159,6 @@ ldap_back_db_open( BackendDB *be ) * the normalized one. See ITS#3406 */ struct berval filter, base = BER_BVC( "cn=Databases," SLAPD_MONITOR ); - struct berval vals[ 2 ]; Attribute a = { 0 }; filter.bv_len = STRLENOF( "(&(namingContexts:distinguishedNameMatch:=)(monitoredInfo=ldap))" ) @@ -170,10 +169,8 @@ ldap_back_db_open( BackendDB *be ) be->be_nsuffix[ 0 ].bv_val ); a.a_desc = slap_schema.si_ad_labeledURI; - ber_str2bv( li->url, 0, 0, &vals[ 0 ] ); - BER_BVZERO( &vals[ 1 ] ); - a.a_vals = vals; - a.a_nvals = vals; + a.a_vals = li->li_bvuri; + a.a_nvals = li->li_bvuri; if ( monitor_back_register_entry_attrs( NULL, &a, NULL, &base, LDAP_SCOPE_SUBTREE, &filter ) ) { /* error */ } @@ -182,16 +179,16 @@ ldap_back_db_open( BackendDB *be ) } #endif /* SLAPD_MONITOR */ - if ( li->flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) { + if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) { int rc; - li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER; + li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER; - rc = slap_discover_feature( li->url, li->version, + rc = slap_discover_feature( li->li_uri, li->li_version, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, LDAP_FEATURE_ABSOLUTE_FILTERS ); if ( rc == LDAP_COMPARE_TRUE ) { - li->flags |= LDAP_BACK_F_SUPPORT_T_F; + li->li_flags |= LDAP_BACK_F_SUPPORT_T_F; } } @@ -201,7 +198,7 @@ ldap_back_db_open( BackendDB *be ) void ldap_back_conn_free( void *v_lc ) { - struct ldapconn *lc = v_lc; + ldapconn_t *lc = v_lc; if ( lc->lc_ld != NULL ) { ldap_unbind_ext( lc->lc_ld, NULL, NULL ); @@ -224,75 +221,73 @@ ldap_back_db_destroy( Backend *be ) { - struct ldapinfo *li; - if ( be->be_private ) { - li = ( struct ldapinfo * )be->be_private; + ldapinfo_t *li = ( ldapinfo_t * )be->be_private; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); - if ( li->url != NULL ) { - ch_free( li->url ); - li->url = NULL; - } - if ( li->lud ) { - ldap_free_urldesc( li->lud ); - li->lud = NULL; + if ( li->li_uri != NULL ) { + ch_free( li->li_uri ); + li->li_uri = NULL; + + assert( li->li_bvuri != NULL ); + ber_bvarray_free( li->li_bvuri ); + li->li_bvuri = NULL; } - if ( !BER_BVISNULL( &li->acl_authcID ) ) { - ch_free( li->acl_authcID.bv_val ); - BER_BVZERO( &li->acl_authcID ); + if ( !BER_BVISNULL( &li->li_acl_authcID ) ) { + ch_free( li->li_acl_authcID.bv_val ); + BER_BVZERO( &li->li_acl_authcID ); } - if ( !BER_BVISNULL( &li->acl_authcDN ) ) { - ch_free( li->acl_authcDN.bv_val ); - BER_BVZERO( &li->acl_authcDN ); + if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) { + ch_free( li->li_acl_authcDN.bv_val ); + BER_BVZERO( &li->li_acl_authcDN ); } - if ( !BER_BVISNULL( &li->acl_passwd ) ) { - ch_free( li->acl_passwd.bv_val ); - BER_BVZERO( &li->acl_passwd ); + if ( !BER_BVISNULL( &li->li_acl_passwd ) ) { + ch_free( li->li_acl_passwd.bv_val ); + BER_BVZERO( &li->li_acl_passwd ); } - if ( !BER_BVISNULL( &li->acl_sasl_mech ) ) { - ch_free( li->acl_sasl_mech.bv_val ); - BER_BVZERO( &li->acl_sasl_mech ); + if ( !BER_BVISNULL( &li->li_acl_sasl_mech ) ) { + ch_free( li->li_acl_sasl_mech.bv_val ); + BER_BVZERO( &li->li_acl_sasl_mech ); } - if ( !BER_BVISNULL( &li->acl_sasl_realm ) ) { - ch_free( li->acl_sasl_realm.bv_val ); - BER_BVZERO( &li->acl_sasl_realm ); + if ( !BER_BVISNULL( &li->li_acl_sasl_realm ) ) { + ch_free( li->li_acl_sasl_realm.bv_val ); + BER_BVZERO( &li->li_acl_sasl_realm ); } - if ( !BER_BVISNULL( &li->idassert_authcID ) ) { - ch_free( li->idassert_authcID.bv_val ); - BER_BVZERO( &li->idassert_authcID ); + if ( !BER_BVISNULL( &li->li_idassert_authcID ) ) { + ch_free( li->li_idassert_authcID.bv_val ); + BER_BVZERO( &li->li_idassert_authcID ); } - if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { - ch_free( li->idassert_authcDN.bv_val ); - BER_BVZERO( &li->idassert_authcDN ); + if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) { + ch_free( li->li_idassert_authcDN.bv_val ); + BER_BVZERO( &li->li_idassert_authcDN ); } - if ( !BER_BVISNULL( &li->idassert_passwd ) ) { - ch_free( li->idassert_passwd.bv_val ); - BER_BVZERO( &li->idassert_passwd ); + if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) { + ch_free( li->li_idassert_passwd.bv_val ); + BER_BVZERO( &li->li_idassert_passwd ); } - if ( !BER_BVISNULL( &li->idassert_authzID ) ) { - ch_free( li->idassert_authzID.bv_val ); - BER_BVZERO( &li->idassert_authzID ); + if ( !BER_BVISNULL( &li->li_idassert_authzID ) ) { + ch_free( li->li_idassert_authzID.bv_val ); + BER_BVZERO( &li->li_idassert_authzID ); } - if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) { - ch_free( li->idassert_sasl_mech.bv_val ); - BER_BVZERO( &li->idassert_sasl_mech ); + if ( !BER_BVISNULL( &li->li_idassert_sasl_mech ) ) { + ch_free( li->li_idassert_sasl_mech.bv_val ); + BER_BVZERO( &li->li_idassert_sasl_mech ); } - if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) { - ch_free( li->idassert_sasl_realm.bv_val ); - BER_BVZERO( &li->idassert_sasl_realm ); + if ( !BER_BVISNULL( &li->li_idassert_sasl_realm ) ) { + ch_free( li->li_idassert_sasl_realm.bv_val ); + BER_BVZERO( &li->li_idassert_sasl_realm ); } - if ( li->idassert_authz != NULL ) { - ber_bvarray_free( li->idassert_authz ); - li->idassert_authz = NULL; + if ( li->li_idassert_authz != NULL ) { + ber_bvarray_free( li->li_idassert_authz ); + li->li_idassert_authz = NULL; } - if ( li->conntree ) { - avl_free( li->conntree, ldap_back_conn_free ); + if ( li->li_conninfo.lai_tree ) { + avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); } - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); - ldap_pvt_thread_mutex_destroy( &li->conn_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex ); } ch_free( be->be_private ); diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index ae0820ff53..c5889fb4f5 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -36,9 +36,9 @@ ldap_back_modify( Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - struct ldapconn *lc; + ldapconn_t *lc; LDAPMod **modv = NULL, *mods = NULL; Modifications *ml; @@ -110,10 +110,10 @@ retry: rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv, ctrls, NULL, &msgid ); rc = ldap_back_op_result( lc, op, rs, msgid, - li->timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT ); + li->li_timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 254038570e..17836b4aa1 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -36,9 +36,9 @@ ldap_back_modrdn( Operation *op, SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - struct ldapconn *lc; + ldapconn_t *lc; ber_int_t msgid; LDAPControl **ctrls = NULL; int do_retry = 1; @@ -70,10 +70,10 @@ retry: op->orr_newrdn.bv_val, newSup, op->orr_deleteoldrdn, ctrls, NULL, &msgid ); rc = ldap_back_op_result( lc, op, rs, msgid, - li->timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT ); + li->li_timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT ); if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index f705bf521c..4c911da13d 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -32,7 +32,6 @@ extern BI_destroy ldap_back_destroy; extern BI_db_init ldap_back_db_init; extern BI_db_open ldap_back_db_open; extern BI_db_destroy ldap_back_db_destroy; -extern BI_db_config ldap_back_db_config; extern BI_op_bind ldap_back_bind; extern BI_op_search ldap_back_search; @@ -48,15 +47,14 @@ extern BI_connection_destroy ldap_back_conn_destroy; extern BI_entry_get_rw ldap_back_entry_get; -int ldap_back_freeconn( Operation *op, struct ldapconn *lc ); -struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok); -void ldap_back_release_conn( struct slap_op *op, struct slap_rep *rs, struct ldapconn *lc ); -int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok); -int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok); -int ldap_back_map_result(SlapReply *rs); -int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, - ber_int_t msgid, time_t timeout, ldap_back_send_t sendok); -int back_ldap_LTX_init_module(int argc, char *argv[]); +int ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ); +ldapconn_t *ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ); +void ldap_back_release_conn( Operation *op, SlapReply *rs, ldapconn_t *lc ); +int ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); +int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); +int ldap_back_map_result( SlapReply *rs ); +int ldap_back_op_result( ldapconn_t *lc, Operation *op, SlapReply *rs, + ber_int_t msgid, time_t timeout, ldap_back_send_t sendok ); int ldap_back_init_cf( BackendInfo *bi ); @@ -66,7 +64,7 @@ extern void ldap_back_conn_free( void *c ); extern int ldap_back_proxy_authz_ctrl( - struct ldapconn *lc, + ldapconn_t *lc, Operation *op, SlapReply *rs, LDAPControl ***pctrls ); diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 625f3b0550..8ddd2155c4 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -49,7 +49,7 @@ ldap_back_munge_filter( Operation *op, struct berval *filter ) { - struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; + ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; char *ptr; int gotit = 0; @@ -75,7 +75,7 @@ ldap_back_munge_filter( if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) { oldbv = &bv_true; - if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) { newbv = &bv_t; } else { @@ -85,7 +85,7 @@ ldap_back_munge_filter( } else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 ) { oldbv = &bv_false; - if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) { newbv = &bv_f; } else { @@ -141,7 +141,7 @@ ldap_back_search( Operation *op, SlapReply *rs ) { - struct ldapconn *lc; + ldapconn_t *lc; struct timeval tv; time_t stoptime = (time_t)-1; LDAPMessage *res, @@ -221,13 +221,20 @@ fail:; case LDAP_SERVER_DOWN: if ( do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } - rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); - ldap_back_freeconn( op, lc ); - lc = NULL; + if ( lc == NULL ) { + /* reset by ldap_back_retry ... */ + rs->sr_err = slap_map_api2result( rs ); + + } else { + rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); + ldap_back_freeconn( op, lc, 0 ); + lc = NULL; + } + goto finish; case LDAP_FILTER_ERROR: @@ -417,12 +424,13 @@ fail:; if ( rc == -1 ) { if ( do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { goto retry; } } rs->sr_err = LDAP_SERVER_DOWN; - goto fail; + rs->sr_err = slap_map_api2result( rs ); + goto finish; } /* @@ -688,7 +696,7 @@ ldap_back_entry_get( Entry **ent ) { - struct ldapconn *lc; + ldapconn_t *lc; int rc = 1, do_not_cache; struct berval bdn; @@ -746,7 +754,7 @@ retry: if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; - if ( ldap_back_retry( lc, op, &rs, LDAP_BACK_DONTSEND ) ) { + if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } diff --git a/servers/slapd/back-ldap/unbind.c b/servers/slapd/back-ldap/unbind.c index e097d0ae7a..6cc2c797da 100644 --- a/servers/slapd/back-ldap/unbind.c +++ b/servers/slapd/back-ldap/unbind.c @@ -38,8 +38,8 @@ ldap_back_conn_destroy( Connection *conn ) { - struct ldapinfo *li = (struct ldapinfo *) be->be_private; - struct ldapconn *lc = NULL, lc_curr; + ldapinfo_t *li = (ldapinfo_t *) be->be_private; + ldapconn_t *lc = NULL, lc_curr; Debug( LDAP_DEBUG_TRACE, "=>ldap_back_conn_destroy: fetching conn %ld\n", @@ -48,9 +48,9 @@ ldap_back_conn_destroy( lc_curr.lc_conn = conn; lc_curr.lc_local_ndn = conn->c_ndn; - ldap_pvt_thread_mutex_lock( &li->conn_mutex ); - lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); - ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); if ( lc ) { Debug( LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 87ba1badf0..89f21d8b31 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -257,18 +257,18 @@ typedef struct metainfo_t { metadncache_t mi_cache; - ldap_pvt_thread_mutex_t mi_conn_mutex; - Avlnode *mi_conntree; + ldap_avl_info_t mi_conninfo; - unsigned flags; + unsigned mi_flags; +#define li_flags mi_flags /* uses flags as defined in */ #define META_BACK_F_ONERR_STOP 0x00010000U #define META_BACK_F_DEFER_ROOTDN_BIND 0x00020000U -#define META_BACK_ONERR_STOP(mi) ( (mi)->flags & META_BACK_F_ONERR_STOP ) +#define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP ) #define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) ) -#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND ) +#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND ) int mi_version; time_t mi_timeout[ LDAP_BACK_OP_LAST ]; diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 3d68674336..ccd2a6c275 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -206,22 +206,22 @@ meta_back_bind( Operation *op, SlapReply *rs ) /* wait for all other ops to release the connection */ retry_lock:; - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); if ( mc->mc_refcnt > 1 ) { - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); ldap_pvt_thread_yield(); goto retry_lock; } assert( mc->mc_refcnt == 1 ); - mc = avl_delete( &mi->mi_conntree, (caddr_t)mc, + mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ); assert( mc != NULL ); ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn ); - lerr = avl_insert( &mi->mi_conntree, (caddr_t)mc, + lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp, meta_back_conn_dup ); - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); if ( lerr == -1 ) { for ( i = 0; i < mi->mi_ntargets; ++i ) { if ( mc->mc_conns[ i ].msc_ld != NULL ) { @@ -548,7 +548,7 @@ retry:; * to avoid circular loops; mc_mutex is set * by the caller */ if ( dolock ) { - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); } if ( mc->mc_refcnt == 1 ) { @@ -571,7 +571,7 @@ retry:; } if ( dolock ) { - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } if ( rc == LDAP_SUCCESS ) { diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 58cba85096..035b5a21ec 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -160,7 +160,7 @@ meta_back_db_config( } mi->mi_targets[ i ].mt_nretries = mi->mi_nretries; - mi->mi_targets[ i ].mt_flags = mi->flags; + mi->mi_targets[ i ].mt_flags = mi->mi_flags; mi->mi_targets[ i ].mt_version = mi->mi_version; for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) { @@ -430,16 +430,16 @@ meta_back_db_config( fprintf( stderr, "%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n", fname, lineno ); - mi->flags |= LDAP_BACK_F_SAVECRED; + mi->mi_flags |= LDAP_BACK_F_SAVECRED; } else { switch ( check_true_false( argv[ 1 ] ) ) { case 0: - mi->flags &= ~LDAP_BACK_F_SAVECRED; + mi->mi_flags &= ~LDAP_BACK_F_SAVECRED; break; case 1: - mi->flags |= LDAP_BACK_F_SAVECRED; + mi->mi_flags |= LDAP_BACK_F_SAVECRED; break; default: @@ -453,7 +453,7 @@ meta_back_db_config( } else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) { unsigned *flagsp = mi->mi_ntargets ? &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags - : &mi->flags; + : &mi->mi_flags; if ( argc != 2 ) { fprintf( stderr, @@ -482,7 +482,7 @@ meta_back_db_config( } else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) { unsigned *flagsp = mi->mi_ntargets ? &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags - : &mi->flags; + : &mi->mi_flags; if ( argc != 2 ) { fprintf( stderr, @@ -519,7 +519,7 @@ meta_back_db_config( } else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) { unsigned *flagsp = mi->mi_ntargets ? &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags - : &mi->flags; + : &mi->mi_flags; if ( argc != 2 ) { fprintf( stderr, @@ -560,10 +560,10 @@ meta_back_db_config( } if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) { - mi->flags &= ~META_BACK_F_ONERR_STOP; + mi->mi_flags &= ~META_BACK_F_ONERR_STOP; } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) { - mi->flags |= META_BACK_F_ONERR_STOP; + mi->mi_flags |= META_BACK_F_ONERR_STOP; } else { fprintf( stderr, @@ -583,11 +583,11 @@ meta_back_db_config( switch ( check_true_false( argv[ 1 ] ) ) { case 0: - mi->flags &= ~META_BACK_F_DEFER_ROOTDN_BIND; + mi->mi_flags &= ~META_BACK_F_DEFER_ROOTDN_BIND; break; case 1: - mi->flags |= META_BACK_F_DEFER_ROOTDN_BIND; + mi->mi_flags |= META_BACK_F_DEFER_ROOTDN_BIND; break; default: diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index caaff03b5a..772771abf9 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -186,13 +186,13 @@ meta_back_freeconn( assert( mc != NULL ); - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); if ( --mc->mc_refcnt == 0 ) { meta_back_conn_free( mc ); } - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } /* @@ -444,13 +444,13 @@ meta_back_retry( metasingleconn_t *msc = &mc->mc_conns[ candidate ]; retry_lock:; - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); assert( mc->mc_refcnt > 0 ); if ( mc->mc_refcnt == 1 ) { while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) { - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); ldap_pvt_thread_yield(); goto retry_lock; } @@ -483,7 +483,7 @@ retry_lock:; mc->mc_tainted = 1; } - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); return rc == LDAP_SUCCESS ? 1 : 0; } @@ -734,20 +734,20 @@ meta_back_getconn( } /* Searches for a metaconn in the avl tree */ - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); - mc = (metaconn_t *)avl_find( mi->mi_conntree, + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, (caddr_t)&mc_curr, meta_back_conn_cmp ); if ( mc ) { if ( mc->mc_tainted ) { rs->sr_err = LDAP_UNAVAILABLE; rs->sr_text = "remote server unavailable"; - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); return NULL; } mc->mc_refcnt++; } - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); switch ( op->o_tag ) { case LDAP_REQ_ADD: @@ -927,13 +927,13 @@ meta_back_getconn( /* Retries searching for a metaconn in the avl tree * the reason is that the connection might have been * created by meta_back_get_candidate() */ - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); - mc = (metaconn_t *)avl_find( mi->mi_conntree, + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, (caddr_t)&mc_curr, meta_back_conn_cmp ); if ( mc != NULL ) { mc->mc_refcnt++; } - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); /* Looks like we didn't get a bind. Open a new session... */ if ( mc == NULL ) { @@ -1088,15 +1088,15 @@ done:; /* * Inserts the newly created metaconn in the avl tree */ - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); - err = avl_insert( &mi->mi_conntree, ( caddr_t )mc, + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, meta_back_conn_cmp, meta_back_conn_dup ); #if PRINT_CONNTREE > 0 - myprint( mi->mi_conntree ); + myprint( mi->mi_conninfo.lai_tree ); #endif /* PRINT_CONNTREE */ - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); /* * Err could be -1 in case a duplicate metaconn is inserted @@ -1144,13 +1144,13 @@ meta_back_release_conn( assert( mc != NULL ); - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); assert( mc->mc_refcnt > 0 ); mc->mc_refcnt--; if ( mc->mc_refcnt == 0 && mc->mc_tainted ) { - (void)avl_delete( &mi->mi_conntree, ( caddr_t )mc, + (void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, meta_back_conn_cmp ); meta_back_conn_free( mc ); } - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); } diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index a978646f1f..627a26c27b 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -77,11 +77,10 @@ meta_back_db_init( { metainfo_t *mi; - mi = ch_malloc( sizeof( metainfo_t ) ); + mi = ch_calloc( 1, sizeof( metainfo_t ) ); if ( mi == NULL ) { return -1; } - memset( mi, 0, sizeof( metainfo_t ) ); /* * At present the default is no default target; @@ -89,7 +88,7 @@ meta_back_db_init( */ mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE; - ldap_pvt_thread_mutex_init( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex ); ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex ); /* safe default */ @@ -222,10 +221,10 @@ meta_back_db_destroy( /* * Destroy the connection tree */ - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); - if ( mi->mi_conntree ) { - avl_free( mi->mi_conntree, meta_back_conn_free ); + if ( mi->mi_conninfo.lai_tree ) { + avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free ); } /* @@ -248,8 +247,8 @@ meta_back_db_destroy( ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex ); ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex ); - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); - ldap_pvt_thread_mutex_destroy( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); + ldap_pvt_thread_mutex_destroy( &mi->mi_conninfo.lai_mutex ); if ( mi->mi_candidates != NULL ) { ber_memfree_x( mi->mi_candidates, NULL ); diff --git a/servers/slapd/back-meta/unbind.c b/servers/slapd/back-meta/unbind.c index a38bfa2b07..ed98015e57 100644 --- a/servers/slapd/back-meta/unbind.c +++ b/servers/slapd/back-meta/unbind.c @@ -50,10 +50,10 @@ meta_back_conn_destroy( mc_curr.mc_conn = conn; mc_curr.mc_local_ndn = conn->c_ndn; - ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); - mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr, + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, meta_back_conn_cmp ); - ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); + ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); if ( mc ) { Debug( LDAP_DEBUG_TRACE, diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c index ae234a143b..6dde253909 100644 --- a/servers/slapd/back-monitor/database.c +++ b/servers/slapd/back-monitor/database.c @@ -45,6 +45,9 @@ static int monitor_back_add_plugin( monitor_info_t *mi, Backend *be, Entry *e ); #if 0 && defined(SLAPD_LDBM) #include "../back-ldbm/back-ldbm.h" #endif /* defined(SLAPD_LDBM) */ +#if defined(SLAPD_META) +#include "../back-meta/back-meta.h" +#endif /* defined(SLAPD_META) */ /* for PATH_MAX on some systems (e.g. Solaris) */ #ifdef HAVE_LIMITS_H @@ -300,34 +303,19 @@ monitor_subsys_database_init( } } + + if ( 0 ) { + assert( 0 ); + #if defined(SLAPD_BDB) || defined(SLAPD_HDB) - if ( strcmp( bi->bi_type, "bdb" ) == 0 + } else if ( strcmp( bi->bi_type, "bdb" ) == 0 || strcmp( bi->bi_type, "hdb" ) == 0 ) { struct berval bv; ber_len_t pathlen = 0, len = 0; char path[ PATH_MAX ] = { '\0' }; - char *fname = NULL; - - if ( strcmp( bi->bi_type, "bdb" ) == 0 - || strcmp( bi->bi_type, "hdb" ) == 0 ) - { - struct bdb_info *bdb = (struct bdb_info *) be->be_private; - - fname = bdb->bi_dbenv_home; -#if 0 - } else if ( strcmp( bi->bi_type, "ldbm" ) == 0 ) { - struct ldbminfo *ldbm = (struct ldbminfo *) be->be_private; - - /* FIXME: there's a conflict - * between back-bdb.h and back.ldbm.h; - * anyway, this code will be moved - * to the backends as soon as the - * issue with filtering on namingContexts - * is fixed */ - fname = ldbm->li_directory; -#endif - } + struct bdb_info *bdb = (struct bdb_info *) be->be_private; + char *fname = bdb->bi_dbenv_home; len = strlen( fname ); if ( fname[ 0 ] != '/' ) { @@ -363,22 +351,53 @@ monitor_subsys_database_init( &bv, NULL ); ch_free( bv.bv_val ); - } -#endif /* defined(SLAPD_LDAP) || defined(SLAPD_HDB) */ +#endif /* defined(SLAPD_BDB) || defined(SLAPD_HDB) */ #if defined(SLAPD_LDAP) - if ( strcmp( bi->bi_type, "ldap" ) == 0 ) { - struct ldapinfo *li = - (struct ldapinfo *)be->be_private; - struct berval bv; + } else if ( strcmp( bi->bi_type, "ldap" ) == 0 ) { + ldapinfo_t *li = (ldapinfo_t *)be->be_private; +#if 0 + attr_merge_normalize( e, slap_schema.si_ad_labeledURI, + li->li_bvuri, NULL ); +#else + char **urls = ldap_str2charray( li->li_uri, " " ); + int u; - ber_str2bv( li->url, 0, 0, &bv ); + for ( u = 0; urls[ u ] != NULL; u++ ) { + struct berval bv; + + ber_str2bv( urls[ u ], 0, 0, &bv ); + + attr_merge_normalize_one( e, + slap_schema.si_ad_labeledURI, + &bv, NULL ); + } + + ldap_charray_free( urls ); +#endif - attr_merge_normalize_one( e, - slap_schema.si_ad_labeledURI, - &bv, NULL ); - } #endif /* defined(SLAPD_LDAP) */ +#if defined(SLAPD_META) + } else if ( strcmp( bi->bi_type, "meta" ) == 0 ) { + metainfo_t *mi = (metainfo_t *)be->be_private; + int t; + + for ( t = 0; t < mi->mi_ntargets; t++ ) { + char **urls = ldap_str2charray( mi->mi_targets[ t ].mt_uri, " " ); + int u; + + for ( u = 0; urls[ u ] != NULL; u++ ) { + struct berval bv; + + ber_str2bv( urls[ u ], 0, 0, &bv ); + + attr_merge_normalize_one( e, + slap_schema.si_ad_labeledURI, + &bv, NULL ); + } + } +#endif /* defined(SLAPD_META) */ + } j = -1; LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) { diff --git a/tests/data/slapd-chain1.conf b/tests/data/slapd-chain1.conf index 8f3554718b..0ca328c311 100644 --- a/tests/data/slapd-chain1.conf +++ b/tests/data/slapd-chain1.conf @@ -33,9 +33,11 @@ argsfile @TESTDIR@/slapd.1.args # uses the chain overlay as global; # no chain-URI is configured, so the URI is parsed out of the referral overlay chain -chain-acl-bind bindmethod=simple - binddn="cn=Manager,dc=example,dc=com" - credentials=secret +chain-uri @URI2@ +chain-idassert-bind bindmethod=simple + binddn="cn=Manager,dc=example,dc=com" + credentials=secret + mode=self ####################################################################### # database definitions diff --git a/tests/data/slapd-chain2.conf b/tests/data/slapd-chain2.conf index acc434ba55..b7abea1da3 100644 --- a/tests/data/slapd-chain2.conf +++ b/tests/data/slapd-chain2.conf @@ -56,8 +56,9 @@ rootpw secret # the chain-URI is configured, so only that URI is chained overlay chain chain-uri @URI1@ -chain-acl-bind bindmethod=simple - binddn="cn=Manager,dc=example,dc=com" - credentials=secret +chain-idassert-bind bindmethod=simple + binddn="cn=Manager,dc=example,dc=com" + credentials=secret + mode=self #monitor#database monitor