Back to index

openldap  2.4.31
Defines | Functions | Variables
proto-ldap.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define ldap_back_release_conn(li, lc)   ldap_back_release_conn_lock((li), &(lc), 1)

Functions

void ldap_back_release_conn_lock (ldapinfo_t *li, ldapconn_t **lcp, int dolock)
int ldap_back_dobind (ldapconn_t **lcp, 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_cancel (ldapconn_t *lc, Operation *op, SlapReply *rs, ber_int_t msgid, ldap_back_send_t sendok)
int ldap_back_init_cf (BackendInfo *bi)
int ldap_pbind_init_cf (BackendInfo *bi)
int ldap_back_conndn_cmp (const void *c1, const void *c2)
int ldap_back_conn_cmp (const void *c1, const void *c2)
int ldap_back_conndn_dup (void *c1, void *c2)
void ldap_back_conn_free (void *c)
ldapconn_tldap_back_conn_delete (ldapinfo_t *li, ldapconn_t *lc)
int ldap_back_conn2str (const ldapconn_base_t *lc, char *buf, ber_len_t buflen)
int ldap_back_connid2str (const ldapconn_base_t *lc, char *buf, ber_len_t buflen)
int ldap_back_proxy_authz_ctrl (Operation *op, SlapReply *rs, struct berval *bound_ndn, int version, slap_idassert_t *si, LDAPControl *ctrl)
int ldap_back_controls_add (Operation *op, SlapReply *rs, ldapconn_t *lc, LDAPControl ***pctrls)
int ldap_back_controls_free (Operation *op, SlapReply *rs, LDAPControl ***pctrls)
void ldap_back_quarantine (Operation *op, SlapReply *rs)
void slap_retry_info_destroy (slap_retry_info_t *ri)
int slap_retry_info_parse (char *in, slap_retry_info_t *ri, char *buf, ber_len_t buflen)
int slap_retry_info_unparse (slap_retry_info_t *ri, struct berval *bvout)
int slap_idassert_authzfrom_parse_cf (const char *fname, int lineno, const char *arg, slap_idassert_t *si)
int slap_idassert_passthru_parse_cf (const char *fname, int lineno, const char *arg, slap_idassert_t *si)
int slap_idassert_parse_cf (const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si)
int chain_initialize (void)
int pbind_initialize (void)
int ldap_back_monitor_db_init (BackendDB *be)
int ldap_back_monitor_db_open (BackendDB *be)
int ldap_back_monitor_db_close (BackendDB *be)
int ldap_back_monitor_db_destroy (BackendDB *be)

Variables

LDAP_BEGIN_DECL BI_init ldap_back_initialize
BI_open ldap_back_open
BI_db_init ldap_back_db_init
BI_db_open ldap_back_db_open
BI_db_close ldap_back_db_close
BI_db_destroy ldap_back_db_destroy
BI_op_bind ldap_back_bind
BI_op_search ldap_back_search
BI_op_compare ldap_back_compare
BI_op_modify ldap_back_modify
BI_op_modrdn ldap_back_modrdn
BI_op_add ldap_back_add
BI_op_delete ldap_back_delete
BI_op_abandon ldap_back_abandon
BI_op_extended ldap_back_extended
BI_connection_destroy ldap_back_conn_destroy
BI_entry_get_rw ldap_back_entry_get
LDAP_REBIND_PROC ldap_back_default_rebind
LDAP_URLLIST_PROC ldap_back_default_urllist

Define Documentation

#define ldap_back_release_conn (   li,
  lc 
)    ldap_back_release_conn_lock((li), &(lc), 1)

Definition at line 49 of file proto-ldap.h.


Function Documentation

Definition at line 2276 of file chain.c.

{
       int rc;

       /* Make sure we don't exceed the bits reserved for userland */
       config_check_userland( CH_LAST );

#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
       rc = register_supported_control( LDAP_CONTROL_X_CHAINING_BEHAVIOR,
                     /* SLAP_CTRL_GLOBAL| */ SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
                     ldap_chain_parse_ctrl, &sc_chainingBehavior );
       if ( rc != LDAP_SUCCESS ) {
              Debug( LDAP_DEBUG_ANY, "slapd-chain: "
                     "unable to register chaining behavior control: %d.\n",
                     rc, 0, 0 );
              return rc;
       }
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */

       ldapchain.on_bi.bi_type = "chain";
       ldapchain.on_bi.bi_db_init = ldap_chain_db_init;
       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;

       ldapchain.on_bi.bi_connection_destroy = ldap_chain_connection_destroy;

       ldapchain.on_response = ldap_chain_response;

       ldapchain.on_bi.bi_cf_ocs = chainocs;

       rc = config_register_schema( chaincfg, chainocs );
       if ( rc ) {
              return rc;
       }

       return overlay_register( &ldapchain );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_back_cancel ( ldapconn_t lc,
Operation op,
SlapReply rs,
ber_int_t  msgid,
ldap_back_send_t  sendok 
)

Definition at line 1675 of file bind.c.

{
       ldapinfo_t    *li = (ldapinfo_t *)op->o_bd->be_private;

       /* default behavior */
       if ( LDAP_BACK_ABANDON( li ) ) {
              return ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
       }

       if ( LDAP_BACK_IGNORE( li ) ) {
              return ldap_pvt_discard( lc->lc_ld, msgid );
       }

       if ( LDAP_BACK_CANCEL( li ) ) {
              /* FIXME: asynchronous? */
              return ldap_cancel_s( lc->lc_ld, msgid, NULL, NULL );
       }

       assert( 0 );

       return LDAP_OTHER;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_back_conn2str ( const ldapconn_base_t lc,
char *  buf,
ber_len_t  buflen 
)

Definition at line 2944 of file bind.c.

{
       char tbuf[ SLAP_TEXT_BUFLEN ];
       char *ptr = buf, *end = buf + buflen;
       int len;

       if ( ptr + sizeof("conn=") > end ) return -1;
       ptr = lutil_strcopy( ptr, "conn=" );

       len = ldap_back_connid2str( lc, ptr, (ber_len_t)(end - ptr) );
       ptr += len;
       if ( ptr >= end ) return -1;

       if ( !BER_BVISNULL( &lc->lcb_local_ndn ) ) {
              if ( ptr + sizeof(" DN=\"\"") + lc->lcb_local_ndn.bv_len > end ) return -1;
              ptr = lutil_strcopy( ptr, " DN=\"" );
              ptr = lutil_strncopy( ptr, lc->lcb_local_ndn.bv_val, lc->lcb_local_ndn.bv_len );
              *ptr++ = '"';
       }

       if ( lc->lcb_create_time != 0 ) {
              len = snprintf( tbuf, sizeof(tbuf), "%ld", lc->lcb_create_time );
              if ( ptr + sizeof(" created=") + len >= end ) return -1;
              ptr = lutil_strcopy( ptr, " created=" );
              ptr = lutil_strcopy( ptr, tbuf );
       }

       if ( lc->lcb_time != 0 ) {
              len = snprintf( tbuf, sizeof(tbuf), "%ld", lc->lcb_time );
              if ( ptr + sizeof(" modified=") + len >= end ) return -1;
              ptr = lutil_strcopy( ptr, " modified=" );
              ptr = lutil_strcopy( ptr, tbuf );
       }

       len = snprintf( tbuf, sizeof(tbuf), "%u", lc->lcb_refcnt );
       if ( ptr + sizeof(" refcnt=") + len >= end ) return -1;
       ptr = lutil_strcopy( ptr, " refcnt=" );
       ptr = lutil_strcopy( ptr, tbuf );

       return ptr - buf;
}

Here is the call graph for this function:

int ldap_back_conn_cmp ( const void c1,
const void c2 
)

Definition at line 460 of file bind.c.

{
       const ldapconn_t     *lc1 = (const ldapconn_t *)c1;
       const ldapconn_t     *lc2 = (const ldapconn_t *)c2;

       /* For shared sessions, conn is NULL. Only explicitly
        * bound sessions will have non-NULL conn.
        */
       return SLAP_PTRCMP( lc1->lc_conn, lc2->lc_conn );
}

Definition at line 171 of file bind.c.

{
       if ( LDAP_BACK_PCONN_ISPRIV( lc ) ) {
              if ( LDAP_BACK_CONN_CACHED( lc ) ) {
                     assert( lc->lc_q.tqe_prev != NULL );
                     assert( li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num > 0 );
                     li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_num--;
                     LDAP_TAILQ_REMOVE( &li->li_conn_priv[ LDAP_BACK_CONN2PRIV( lc ) ].lic_priv, lc, lc_q );
                     LDAP_TAILQ_ENTRY_INIT( lc, lc_q );
                     LDAP_BACK_CONN_CACHED_CLEAR( lc );

              } else {
                     assert( LDAP_BACK_CONN_TAINTED( lc ) );
                     assert( lc->lc_q.tqe_prev == NULL );
              }

       } else {
              ldapconn_t    *tmplc = NULL;

              if ( LDAP_BACK_CONN_CACHED( lc ) ) {
                     assert( !LDAP_BACK_CONN_TAINTED( lc ) );
                     tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
                            ldap_back_conndnlc_cmp );
                     assert( tmplc == lc );
                     LDAP_BACK_CONN_CACHED_CLEAR( lc );
              }

              assert( LDAP_BACK_CONN_TAINTED( lc ) || tmplc == lc );
       }

       return lc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 258 of file init.c.

{
       ldapconn_t    *lc = v_lc;

       if ( lc->lc_ld != NULL ) {  
              ldap_unbind_ext( lc->lc_ld, NULL, NULL );
       }
       if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
              ch_free( lc->lc_bound_ndn.bv_val );
       }
       if ( !BER_BVISNULL( &lc->lc_cred ) ) {
              memset( lc->lc_cred.bv_val, 0, lc->lc_cred.bv_len );
              ch_free( lc->lc_cred.bv_val );
       }
       if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
              ch_free( lc->lc_local_ndn.bv_val );
       }
       lc->lc_q.tqe_prev = NULL;
       lc->lc_q.tqe_next = NULL;
       ch_free( lc );
}
int ldap_back_conndn_cmp ( const void c1,
const void c2 
)

Definition at line 406 of file bind.c.

{
       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 */
       /* For shared sessions, conn is NULL. Only explicitly
        * bound sessions will have non-NULL conn.
        */
       rc = SLAP_PTRCMP( lc1->lc_conn, lc2->lc_conn );
       if ( rc == 0 ) {
              rc = ber_bvcmp( &lc1->lc_local_ndn, &lc2->lc_local_ndn );
       }

       return rc;
}

Here is the caller graph for this function:

int ldap_back_conndn_dup ( void c1,
void c2 
)

Definition at line 478 of file bind.c.

{
       ldapconn_t    *lc1 = (ldapconn_t *)c1;
       ldapconn_t    *lc2 = (ldapconn_t *)c2;

       /* Cannot have more than one shared session with same DN */
       if ( lc1->lc_conn == lc2->lc_conn &&
              dn_match( &lc1->lc_local_ndn, &lc2->lc_local_ndn ) )
       {
              return -1;
       }
              
       return 0;
}

Here is the caller graph for this function:

int ldap_back_connid2str ( const ldapconn_base_t lc,
char *  buf,
ber_len_t  buflen 
)

Definition at line 2987 of file bind.c.

{
       static struct berval conns[] = {
              BER_BVC("ROOTDN"),
              BER_BVC("ROOTDN-TLS"),
              BER_BVC("ANON"),
              BER_BVC("ANON-TLS"),
              BER_BVC("BIND"),
              BER_BVC("BIND-TLS"),
              BER_BVNULL
       };

       int len = 0;

       if ( LDAP_BACK_PCONN_ISPRIV( (const ldapconn_t *)lc ) ) {
              long cid;
              struct berval *bv;

              cid = (long)lc->lcb_conn;
              assert( cid >= LDAP_BACK_PCONN_FIRST && cid < LDAP_BACK_PCONN_LAST );

              bv = &conns[ cid ];

              if ( bv->bv_len >= buflen ) {
                     return bv->bv_len + 1;
              }

              len = bv->bv_len;
              lutil_strncopy( buf, bv->bv_val, bv->bv_len + 1 );

       } else {
              len = snprintf( buf, buflen, "%lu", lc->lcb_conn->c_connid );
       }

       return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_back_controls_add ( Operation op,
SlapReply rs,
ldapconn_t lc,
LDAPControl ***  pctrls 
)

Definition at line 2771 of file bind.c.

{
       ldapinfo_t    *li = (ldapinfo_t *)op->o_bd->be_private;

       LDAPControl   **ctrls = NULL;
       /* set to the maximum number of controls this backend can add */
       LDAPControl   c[ 2 ] = { { 0 } };
       int           n = 0, i, j1 = 0, j2 = 0;

       *pctrls = NULL;

       rs->sr_err = LDAP_SUCCESS;

       /* don't add controls if protocol is not LDAPv3 */
       switch ( li->li_version ) {
       case LDAP_VERSION3:
              break;

       case 0:
              if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
                     break;
              }
              /* fall thru */

       default:
              goto done;
       }

       /* put controls that go __before__ existing ones here */

       /* proxyAuthz for identity assertion */
       switch ( ldap_back_proxy_authz_ctrl( op, rs, &lc->lc_bound_ndn,
              li->li_version, &li->li_idassert, &c[ j1 ] ) )
       {
       case SLAP_CB_CONTINUE:
              break;

       case LDAP_SUCCESS:
              j1++;
              break;

       default:
              goto done;
       }

       /* put controls that go __after__ existing ones here */

#ifdef SLAP_CONTROL_X_SESSION_TRACKING
       /* FIXME: according to <draft-wahl-ldap-session>, 
        * the server should check if the control can be added
        * based on the identity of the client and so */

       /* session tracking */
       if ( LDAP_BACK_ST_REQUEST( li ) ) {
              switch ( slap_ctrl_session_tracking_request_add( op, rs, &c[ j1 + j2 ] ) ) {
              case SLAP_CB_CONTINUE:
                     break;

              case LDAP_SUCCESS:
                     j2++;
                     break;

              default:
                     goto done;
              }
       }
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */

       if ( rs->sr_err == SLAP_CB_CONTINUE ) {
              rs->sr_err = LDAP_SUCCESS;
       }

       /* if nothing to do, just bail out */
       if ( j1 == 0 && j2 == 0 ) {
              goto done;
       }

       assert( j1 + j2 <= (int) (sizeof( c )/sizeof( c[0] )) );

       if ( op->o_ctrls ) {
              for ( n = 0; op->o_ctrls[ n ]; n++ )
                     /* just count ctrls */ ;
       }

       ctrls = op->o_tmpalloc( (n + j1 + j2 + 1) * sizeof( LDAPControl * ) + ( j1 + j2 ) * sizeof( LDAPControl ),
                     op->o_tmpmemctx );
       if ( j1 ) {
              ctrls[ 0 ] = (LDAPControl *)&ctrls[ n + j1 + j2 + 1 ];
              *ctrls[ 0 ] = c[ 0 ];
              for ( i = 1; i < j1; i++ ) {
                     ctrls[ i ] = &ctrls[ 0 ][ i ];
                     *ctrls[ i ] = c[ i ];
              }
       }

       i = 0;
       if ( op->o_ctrls ) {
              for ( i = 0; op->o_ctrls[ i ]; i++ ) {
                     ctrls[ i + j1 ] = op->o_ctrls[ i ];
              }
       }

       n += j1;
       if ( j2 ) {
              ctrls[ n ] = (LDAPControl *)&ctrls[ n + j2 + 1 ] + j1;
              *ctrls[ n ] = c[ j1 ];
              for ( i = 1; i < j2; i++ ) {
                     ctrls[ n + i ] = &ctrls[ n ][ i ];
                     *ctrls[ n + i ] = c[ i ];
              }
       }

       ctrls[ n + j2 ] = NULL;

done:;
       if ( ctrls == NULL ) {
              ctrls = op->o_ctrls;
       }

       *pctrls = ctrls;
       
       return rs->sr_err;
}

Here is the caller graph for this function:

int ldap_back_controls_free ( Operation op,
SlapReply rs,
LDAPControl ***  pctrls 
)

Definition at line 2900 of file bind.c.

{
       LDAPControl   **ctrls = *pctrls;

       /* we assume that the controls added by the proxy come first,
        * so as soon as we find op->o_ctrls[ 0 ] we can stop */
       if ( ctrls && ctrls != op->o_ctrls ) {
              int           i = 0, n = 0, n_added;
              LDAPControl   *lower, *upper;

              assert( ctrls[ 0 ] != NULL );

              for ( n = 0; ctrls[ n ] != NULL; n++ )
                     /* count 'em */ ;

              if ( op->o_ctrls ) {
                     for ( i = 0; op->o_ctrls[ i ] != NULL; i++ )
                            /* count 'em */ ;
              }

              n_added = n - i;
              lower = (LDAPControl *)&ctrls[ n ];
              upper = &lower[ n_added ];

              for ( i = 0; ctrls[ i ] != NULL; i++ ) {
                     if ( ctrls[ i ] < lower || ctrls[ i ] >= upper ) {
                            /* original; don't touch */
                            continue;
                     }

                     if ( !BER_BVISNULL( &ctrls[ i ]->ldctl_value ) ) {
                            op->o_tmpfree( ctrls[ i ]->ldctl_value.bv_val, op->o_tmpmemctx );
                     }
              }

              op->o_tmpfree( ctrls, op->o_tmpmemctx );
       } 

       *pctrls = NULL;

       return 0;
}

Here is the caller graph for this function:

int ldap_back_dobind ( ldapconn_t **  lcp,
Operation op,
SlapReply rs,
ldap_back_send_t  sendok 
)

Definition at line 1589 of file bind.c.

{
       ldapinfo_t    *li = (ldapinfo_t *)op->o_bd->be_private;

       return ldap_back_dobind_int( lcp, op, rs,
              ( sendok | LDAP_BACK_GETCONN ), li->li_nretries, 1 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2220 of file config.c.

{
       int                  rc;
       AttributeDescription *ad = NULL;
       const char           *text;

       /* Make sure we don't exceed the bits reserved for userland */
       config_check_userland( LDAP_BACK_CFG_LAST );

       bi->bi_cf_ocs = ldapocs;

       rc = config_register_schema( ldapcfg, ldapocs );
       if ( rc ) {
              return rc;
       }

       /* setup olcDbAclPasswd and olcDbIDAssertPasswd 
        * to be base64-encoded when written in LDIF form;
        * basically, we don't care if it fails */
       rc = slap_str2ad( "olcDbACLPasswd", &ad, &text );
       if ( rc ) {
              Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
                     "warning, unable to get \"olcDbACLPasswd\" "
                     "attribute description: %d: %s\n",
                     rc, text, 0 );
       } else {
              (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
                     ad->ad_type->sat_oid );
       }

       ad = NULL;
       rc = slap_str2ad( "olcDbIDAssertPasswd", &ad, &text );
       if ( rc ) {
              Debug( LDAP_DEBUG_ANY, "config_back_initialize: "
                     "warning, unable to get \"olcDbIDAssertPasswd\" "
                     "attribute description: %d: %s\n",
                     rc, text, 0 );
       } else {
              (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val,
                     ad->ad_type->sat_oid );
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 610 of file monitor.c.

{
       ldapinfo_t           *li = (ldapinfo_t *) be->be_private;

       if ( li && !BER_BVISNULL( &li->li_monitor_info.lmi_filter ) ) {
              BackendInfo          *mi;
              monitor_extra_t             *mbe;

              /* check if monitor is configured and usable */
              mi = backend_info( "monitor" );
              if ( mi && mi->bi_extra ) {
                     mbe = mi->bi_extra;

                     mbe->unregister_entry_parent(
                            &li->li_monitor_info.lmi_nrdn,
                            (monitor_callback_t *)li->li_monitor_info.lmi_cb,
                            &li->li_monitor_info.lmi_base,
                            li->li_monitor_info.lmi_scope,
                            &li->li_monitor_info.lmi_filter );
              }
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 639 of file monitor.c.

{
       ldapinfo_t           *li = (ldapinfo_t *) be->be_private;

       if ( li ) {
              (void)ldap_back_monitor_info_destroy( li );
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 381 of file monitor.c.

{
       int    rc;

       rc = ldap_back_monitor_initialize();
       if ( rc != LDAP_SUCCESS ) {
              return rc;
       }

#if 0  /* uncomment to turn monitoring on by default */
       SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
#endif

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 401 of file monitor.c.

{
       ldapinfo_t           *li = (ldapinfo_t *) be->be_private;
       char                 buf[ BACKMONITOR_BUFSIZE ];
       Entry                *e = NULL;
       monitor_callback_t   *cb = NULL;
       struct berval        suffix, *filter, *base;
       char                 *ptr;
       time_t               now;
       char                 timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
       struct berval               timestamp;
       int                  rc = 0;
       BackendInfo          *mi;
       monitor_extra_t             *mbe;

       if ( !SLAP_DBMONITORING( be ) ) {
              return 0;
       }

       /* check if monitor is configured and usable */
       mi = backend_info( "monitor" );
       if ( !mi || !mi->bi_extra ) {
              SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
              return 0;
       }
       mbe = mi->bi_extra;

       /* don't bother if monitor is not configured */
       if ( !mbe->is_configured() ) {
              static int warning = 0;

              if ( warning++ == 0 ) {
                     Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
                            "monitoring disabled; "
                            "configure monitor database to enable\n",
                            0, 0, 0 );
              }

              return 0;
       }

       /* set up the fake subsystem that is used to create
        * the volatile connection entries */
       li->li_monitor_info.lmi_mss.mss_name = "back-ldap";
       li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH;
       li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create;

       li->li_monitor_info.lmi_li = li;
       li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE;
       base = &li->li_monitor_info.lmi_base;
       BER_BVSTR( base, "cn=databases,cn=monitor" );
       filter = &li->li_monitor_info.lmi_filter;
       BER_BVZERO( filter );

       suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] );
       if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) {
              suffix = be->be_nsuffix[ 0 ];

       } else {
              ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix );
       }
       
       filter->bv_len = STRLENOF( "(&" )
              + li->li_monitor_info.lmi_more_filter.bv_len
              + STRLENOF( "(monitoredInfo=" )
              + strlen( be->bd_info->bi_type )
              + STRLENOF( ")(!(monitorOverlay=" )
              + strlen( be->bd_info->bi_type )
              + STRLENOF( "))(namingContexts:distinguishedNameMatch:=" )
              + suffix.bv_len + STRLENOF( "))" );
       ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 );
       ptr = lutil_strcopy( ptr, "(&" );
       ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val,
              li->li_monitor_info.lmi_more_filter.bv_len );
       ptr = lutil_strcopy( ptr, "(monitoredInfo=" );
       ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
       ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" );
       ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
       ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" );
       ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len );
       ptr = lutil_strcopy( ptr, "))" );
       ptr[ 0 ] = '\0';
       assert( ptr == &filter->bv_val[ filter->bv_len ] );

       if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) {
              ch_free( suffix.bv_val );
       }

       now = slap_get_time();
       timestamp.bv_val = timebuf;
       timestamp.bv_len = sizeof( timebuf );
       slap_timestamp( &now, &timestamp );

       /* caller (e.g. an overlay based on back-ldap) may want to use
        * a different RDN... */
       if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) {
              ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn );
       }

       ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' );
       assert( ptr != NULL );
       ptr[ 0 ] = '\0';
       ptr++;

       snprintf( buf, sizeof( buf ),
              "dn: %s=%s\n"
              "objectClass: monitorContainer\n"
              "%s: %s\n"
              "creatorsName: %s\n"
              "createTimestamp: %s\n"
              "modifiersName: %s\n"
              "modifyTimestamp: %s\n",
              li->li_monitor_info.lmi_rdn.bv_val,
                     ptr,
              li->li_monitor_info.lmi_rdn.bv_val,
                     ptr,
              BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
              timestamp.bv_val,
              BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
              timestamp.bv_val );
       e = str2entry( buf );
       if ( e == NULL ) {
              rc = -1;
              goto cleanup;
       }

       ptr[ -1 ] = '=';

       /* add labeledURI and special, modifiable URI value */
       if ( li->li_uri != NULL ) {
              struct berval bv;
              LDAPURLDesc   *ludlist = NULL;
              int           rc;

              rc = ldap_url_parselist_ext( &ludlist,
                     li->li_uri, NULL,
                     LDAP_PVT_URL_PARSE_NOEMPTY_HOST
                            | LDAP_PVT_URL_PARSE_DEF_PORT );
              if ( rc != LDAP_URL_SUCCESS ) {
                     Debug( LDAP_DEBUG_ANY,
                            "ldap_back_monitor_db_open: "
                            "unable to parse URI list (ignored)\n",
                            0, 0, 0 );
              } else {
                     for ( ; ludlist != NULL; ) {
                            LDAPURLDesc   *next = ludlist->lud_next;

                            bv.bv_val = ldap_url_desc2str( ludlist );
                            assert( bv.bv_val != NULL );
                            ldap_free_urldesc( ludlist );
                            bv.bv_len = strlen( bv.bv_val );
                            attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
                                   &bv, NULL );
                            ch_free( bv.bv_val );

                            ludlist = next;
                     }
              }
              
              ber_str2bv( li->li_uri, 0, 0, &bv );
              attr_merge_normalize_one( e, ad_olmDbURIList,
                     &bv, NULL );
       }

       ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname );

       cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
       cb->mc_update = ldap_back_monitor_update;
       cb->mc_modify = ldap_back_monitor_modify;
       cb->mc_free = ldap_back_monitor_free;
       cb->mc_private = (void *)li;

       rc = mbe->register_entry_parent( e, cb,
              (monitor_subsys_t *)&li->li_monitor_info,
              MONITOR_F_VOLATILE_CH,
              base, LDAP_SCOPE_SUBORDINATE, filter );

cleanup:;
       if ( rc != 0 ) {
              if ( cb != NULL ) {
                     ch_free( cb );
                     cb = NULL;
              }

              if ( e != NULL ) {
                     entry_free( e );
                     e = NULL;
              }

              if ( !BER_BVISNULL( filter ) ) {
                     ch_free( filter->bv_val );
                     BER_BVZERO( filter );
              }
       }

       /* store for cleanup */
       li->li_monitor_info.lmi_cb = (void *)cb;

       if ( e != NULL ) {
              entry_free( e );
       }

       return rc;
}

Here is the call graph for this function:

int ldap_back_op_result ( ldapconn_t lc,
Operation op,
SlapReply rs,
ber_int_t  msgid,
time_t  timeout,
ldap_back_send_t  sendok 
)

Definition at line 1704 of file bind.c.

{
       ldapinfo_t    *li = (ldapinfo_t *)op->o_bd->be_private;

       char          *match = NULL;
       char          *text = NULL;
       char          **refs = NULL;
       LDAPControl   **ctrls = NULL;

       rs->sr_text = NULL;
       rs->sr_matched = NULL;
       rs->sr_ref = NULL;
       rs->sr_ctrls = NULL;

       /* if the error recorded in the reply corresponds
        * to a successful state, get the error from the
        * remote server response */
       if ( LDAP_ERR_OK( rs->sr_err ) ) {
              int           rc;
              struct timeval       tv;
              LDAPMessage   *res = NULL;
              time_t        stoptime = (time_t)(-1);
              int           timeout_err = op->o_protocol >= LDAP_VERSION3 ?
                                   LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
              const char    *timeout_text = "Operation timed out";

              /* if timeout is not specified, compute and use
               * the one specific to the ongoing operation */
              if ( timeout == (time_t)(-1) ) {
                     slap_op_t     opidx = slap_req2op( op->o_tag );

                     if ( opidx == SLAP_OP_SEARCH ) {
                            if ( op->ors_tlimit <= 0 ) {
                                   timeout = 0;

                            } else {
                                   timeout = op->ors_tlimit;
                                   timeout_err = LDAP_TIMELIMIT_EXCEEDED;
                                   timeout_text = NULL;
                            }

                     } else {
                            timeout = li->li_timeout[ opidx ];
                     }
              }

              /* better than nothing :) */
              if ( timeout == 0 ) {
                     if ( li->li_idle_timeout ) {
                            timeout = li->li_idle_timeout;

                     } else if ( li->li_conn_ttl ) {
                            timeout = li->li_conn_ttl;
                     }
              }

              if ( timeout ) {
                     stoptime = op->o_time + timeout;
              }

              LDAP_BACK_TV_SET( &tv );

retry:;
              /* if result parsing fails, note the failure reason */
              rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
              switch ( rc ) {
              case 0:
                     if ( timeout && slap_get_time() > stoptime ) {
                            if ( sendok & LDAP_BACK_BINDING ) {
                                   ldap_unbind_ext( lc->lc_ld, NULL, NULL );
                                   lc->lc_ld = NULL;

                                   /* let it be used, but taint/delete it so that 
                                    * no-one else can look it up any further */
                                   ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );

#if LDAP_BACK_PRINT_CONNTREE > 0
                                   ldap_back_print_conntree( li, ">>> ldap_back_getconn(timeout)" );
#endif /* LDAP_BACK_PRINT_CONNTREE */

                                   (void)ldap_back_conn_delete( li, lc );
                                   LDAP_BACK_CONN_TAINTED_SET( lc );

#if LDAP_BACK_PRINT_CONNTREE > 0
                                   ldap_back_print_conntree( li, "<<< ldap_back_getconn(timeout)" );
#endif /* LDAP_BACK_PRINT_CONNTREE */
                                   ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );

                            } else {
                                   (void)ldap_back_cancel( lc, op, rs, msgid, sendok );
                            }
                            rs->sr_err = timeout_err;
                            rs->sr_text = timeout_text;
                            break;
                     }

                     /* timeout == 0 */
                     LDAP_BACK_TV_SET( &tv );
                     ldap_pvt_thread_yield();
                     goto retry;

              case -1:
                     ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER,
                                   &rs->sr_err );
                     break;


              /* otherwise get the result; if it is not
               * LDAP_SUCCESS, record it in the reply
               * structure (this includes 
               * LDAP_COMPARE_{TRUE|FALSE}) */
              default:
                     /* only touch when activity actually took place... */
                     if ( li->li_idle_timeout && lc ) {
                            lc->lc_time = op->o_time;
                     }

                     rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
                                   &match, &text, &refs, &ctrls, 1 );
                     if ( rc == LDAP_SUCCESS ) {
                            rs->sr_text = text;
                     } else {
                            rs->sr_err = rc;
                     }
                     rs->sr_err = slap_map_api2result( rs );

                     /* RFC 4511: referrals can only appear
                      * if result code is LDAP_REFERRAL */
                     if ( refs != NULL
                            && refs[ 0 ] != NULL
                            && refs[ 0 ][ 0 ] != '\0' )
                     {
                            if ( rs->sr_err != LDAP_REFERRAL ) {
                                   Debug( LDAP_DEBUG_ANY,
                                          "%s ldap_back_op_result: "
                                          "got referrals with err=%d\n",
                                          op->o_log_prefix,
                                          rs->sr_err, 0 );

                            } else {
                                   int    i;

                                   for ( i = 0; refs[ i ] != NULL; i++ )
                                          /* count */ ;
                                   rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ),
                                          op->o_tmpmemctx );
                                   for ( i = 0; refs[ i ] != NULL; i++ ) {
                                          ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] );
                                   }
                                   BER_BVZERO( &rs->sr_ref[ i ] );
                            }

                     } else if ( rs->sr_err == LDAP_REFERRAL ) {
                            Debug( LDAP_DEBUG_ANY,
                                   "%s ldap_back_op_result: "
                                   "got err=%d with null "
                                   "or empty referrals\n",
                                   op->o_log_prefix,
                                   rs->sr_err, 0 );

                            rs->sr_err = LDAP_NO_SUCH_OBJECT;
                     }

                     if ( ctrls != NULL ) {
                            rs->sr_ctrls = ctrls;
                     }
              }
       }

       /* if the error in the reply structure is not
        * LDAP_SUCCESS, try to map it from client 
        * to server error */
       if ( !LDAP_ERR_OK( rs->sr_err ) ) {
              rs->sr_err = slap_map_api2result( rs );

              /* internal ops ( op->o_conn == NULL ) 
               * must not reply to client */
              if ( op->o_conn && !op->o_do_not_cache && match ) {

                     /* record the (massaged) matched
                      * DN into the reply structure */
                     rs->sr_matched = match;
              }
       }

       if ( rs->sr_err == LDAP_UNAVAILABLE ) {
              if ( !( sendok & LDAP_BACK_RETRYING ) ) {
                     if ( LDAP_BACK_QUARANTINE( li ) ) {
                            ldap_back_quarantine( op, rs );
                     }
                     if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {
                            if ( rs->sr_text == NULL ) rs->sr_text = "Proxy operation retry failed";
                            send_ldap_result( op, rs );
                     }
              }

       } else if ( op->o_conn &&
              ( ( ( sendok & LDAP_BACK_SENDOK ) && LDAP_ERR_OK( rs->sr_err ) )
                     || ( ( sendok & LDAP_BACK_SENDERR ) && !LDAP_ERR_OK( rs->sr_err ) ) ) )
       {
              send_ldap_result( op, rs );
       }

       if ( text ) {
              ldap_memfree( text );
       }
       rs->sr_text = NULL;

       /* there can't be refs with a (successful) bind */
       if ( rs->sr_ref ) {
              op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
              rs->sr_ref = NULL;
       }

       if ( refs ) {
              ber_memvfree( (void **)refs );
       }

       /* match should not be possible with a successful bind */
       if ( match ) {
              if ( rs->sr_matched != match ) {
                     free( (char *)rs->sr_matched );
              }
              rs->sr_matched = NULL;
              ldap_memfree( match );
       }

       if ( ctrls != NULL ) {
              if ( op->o_tag == LDAP_REQ_BIND && rs->sr_err == LDAP_SUCCESS ) {
                     int i;

                     for ( i = 0; ctrls[i] != NULL; i++ );

                     rs->sr_ctrls = op->o_tmpalloc( sizeof( LDAPControl * )*( i + 1 ),
                            op->o_tmpmemctx );
                     for ( i = 0; ctrls[ i ] != NULL; i++ ) {
                            char *ptr;
                            ber_len_t oidlen = strlen( ctrls[i]->ldctl_oid );
                            ber_len_t size = sizeof( LDAPControl )
                                   + oidlen + 1
                                   + ctrls[i]->ldctl_value.bv_len + 1;
       
                            rs->sr_ctrls[ i ] = op->o_tmpalloc( size, op->o_tmpmemctx );
                            rs->sr_ctrls[ i ]->ldctl_oid = (char *)&rs->sr_ctrls[ i ][ 1 ];
                            lutil_strcopy( rs->sr_ctrls[ i ]->ldctl_oid, ctrls[i]->ldctl_oid );
                            rs->sr_ctrls[ i ]->ldctl_value.bv_val
                                          = (char *)&rs->sr_ctrls[ i ]->ldctl_oid[oidlen + 1];
                            rs->sr_ctrls[ i ]->ldctl_value.bv_len
                                   = ctrls[i]->ldctl_value.bv_len;
                            ptr = lutil_memcopy( rs->sr_ctrls[ i ]->ldctl_value.bv_val,
                                   ctrls[i]->ldctl_value.bv_val, ctrls[i]->ldctl_value.bv_len );
                            *ptr = '\0';
                     }
                     rs->sr_ctrls[ i ] = NULL;
                     rs->sr_flags |= REP_CTRLS_MUSTBEFREED;

              } else {
                     assert( rs->sr_ctrls != NULL );
                     rs->sr_ctrls = NULL;
              }

              ldap_controls_free( ctrls );
       }

       return( LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_back_proxy_authz_ctrl ( Operation op,
SlapReply rs,
struct berval bound_ndn,
int  version,
slap_idassert_t si,
LDAPControl ctrl 
)

Definition at line 2492 of file bind.c.

{
       slap_idassert_mode_t mode;
       struct berval        assertedID,
                            ndn;
       int                  isroot = 0;

       rs->sr_err = SLAP_CB_CONTINUE;

       /* 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( &si->si_bc.sb_authcId ) || BER_BVISEMPTY( &si->si_bc.sb_authcId ) )
              && ( BER_BVISNULL( &si->si_bc.sb_binddn ) || BER_BVISEMPTY( &si->si_bc.sb_binddn ) )
              && BER_BVISNULL( &si->si_bc.sb_saslmech ) )
       {
              goto done;
       }

       if ( !op->o_conn || op->o_do_not_cache || ( isroot = be_isroot( op ) ) ) {
              goto done;
       }

       if ( op->o_tag == LDAP_REQ_BIND ) {
              ndn = op->o_req_ndn;

       } else if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
              ndn = op->o_conn->c_ndn;

       } else {
              ndn = op->o_ndn;
       }

       if ( si->si_mode == LDAP_BACK_IDASSERT_LEGACY ) {
              if ( op->o_proxy_authz ) {
                     /*
                      * FIXME: we do not want to perform proxyAuthz
                      * on behalf of the client, because this would
                      * be performed with "proxyauthzdn" privileges.
                      *
                      * This might actually be too strict, since
                      * the "proxyauthzdn" authzTo, and each entry's
                      * authzFrom attributes may be crafted
                      * to avoid unwanted proxyAuthz to take place.
                      */
#if 0
                     rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                     rs->sr_text = "proxyAuthz not allowed within namingContext";
#endif
                     goto done;
              }

              if ( !BER_BVISNULL( bound_ndn ) ) {
                     goto done;
              }

              if ( BER_BVISNULL( &ndn ) ) {
                     goto done;
              }

              if ( BER_BVISNULL( &si->si_bc.sb_binddn ) ) {
                     goto done;
              }

       } else if ( si->si_bc.sb_method == LDAP_AUTH_SASL ) {
              if ( ( si->si_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
              {
                     /* already asserted in SASL via native authz */
                     goto done;
              }

       } else if ( si->si_authz && !isroot ) {
              int           rc;
              struct berval authcDN;

              if ( BER_BVISNULL( &ndn ) ) {
                     authcDN = slap_empty_bv;
              } else {
                     authcDN = ndn;
              }
              rc = slap_sasl_matches( op, si->si_authz,
                            &authcDN, &authcDN );
              if ( rc != LDAP_SUCCESS ) {
                     if ( si->si_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
                            /* ndn is not authorized
                             * to use idassert */
                            rs->sr_err = rc;
                     }
                     goto done;
              }
       }

       if ( op->o_proxy_authz ) {
              /*
               * FIXME: we can:
               * 1) ignore the already set proxyAuthz control
               * 2) leave it in place, and don't set ours
               * 3) add both
               * 4) reject the operation
               *
               * option (4) is very drastic
               * option (3) will make the remote server reject
               * the operation, thus being equivalent to (4)
               * option (2) will likely break the idassert
               * assumptions, so we cannot accept it;
               * option (1) means that we are contradicting
               * the client's reques.
               *
               * I think (4) is the only correct choice.
               */
              rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
              rs->sr_text = "proxyAuthz not allowed within namingContext";
       }

       if ( op->o_is_auth_check ) {
              mode = LDAP_BACK_IDASSERT_NOASSERT;

       } else {
              mode = si->si_mode;
       }

       switch ( mode ) {
       case LDAP_BACK_IDASSERT_LEGACY:
              /* original behavior:
               * assert the client's identity */
       case LDAP_BACK_IDASSERT_SELF:
              assertedID = ndn;
              break;

       case LDAP_BACK_IDASSERT_ANONYMOUS:
              /* assert "anonymous" */
              assertedID = slap_empty_bv;
              break;

       case LDAP_BACK_IDASSERT_NOASSERT:
              /* don't assert; bind as proxyauthzdn */
              goto done;

       case LDAP_BACK_IDASSERT_OTHERID:
       case LDAP_BACK_IDASSERT_OTHERDN:
              /* assert idassert DN */
              assertedID = si->si_bc.sb_authzId;
              break;

       default:
              assert( 0 );
       }

       /* if we got here, "" is allowed to proxyAuthz */
       if ( BER_BVISNULL( &assertedID ) ) {
              assertedID = slap_empty_bv;
       }

       /* don't idassert the bound DN (ITS#4497) */
       if ( dn_match( &assertedID, bound_ndn ) ) {
              goto done;
       }

       ctrl->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
       ctrl->ldctl_iscritical = ( ( si->si_flags & LDAP_BACK_AUTH_PROXYAUTHZ_CRITICAL ) == LDAP_BACK_AUTH_PROXYAUTHZ_CRITICAL );

       switch ( si->si_mode ) {
       /* already in u:ID or dn:DN form */
       case LDAP_BACK_IDASSERT_OTHERID:
       case LDAP_BACK_IDASSERT_OTHERDN:
              ber_dupbv_x( &ctrl->ldctl_value, &assertedID, op->o_tmpmemctx );
              rs->sr_err = LDAP_SUCCESS;
              break;

       /* needs the dn: prefix */
       default:
              ctrl->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
              ctrl->ldctl_value.bv_val = op->o_tmpalloc( ctrl->ldctl_value.bv_len + 1,
                            op->o_tmpmemctx );
              AC_MEMCPY( ctrl->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
              AC_MEMCPY( &ctrl->ldctl_value.bv_val[ STRLENOF( "dn:" ) ],
                            assertedID.bv_val, assertedID.bv_len + 1 );
              rs->sr_err = LDAP_SUCCESS;
              break;
       }

       /* Older versions of <draft-weltman-ldapv3-proxy> required
        * to encode the value of the authzID (and called it proxyDN);
        * this hack provides compatibility with those DSAs that
        * implement it this way */
       if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
              struct berval        authzID = ctrl->ldctl_value;
              BerElementBuffer     berbuf;
              BerElement           *ber = (BerElement *)&berbuf;
              ber_tag_t            tag;

              ber_init2( ber, 0, LBER_USE_DER );
              ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );

              tag = ber_printf( ber, "O", &authzID );
              if ( tag == LBER_ERROR ) {
                     rs->sr_err = LDAP_OTHER;
                     goto free_ber;
              }

              if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
                     rs->sr_err = LDAP_OTHER;
                     goto free_ber;
              }

              rs->sr_err = LDAP_SUCCESS;

free_ber:;
              op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
              ber_free_buf( ber );

              if ( rs->sr_err != LDAP_SUCCESS ) {
                     goto done;
              }

       } else if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
              struct berval        authzID = ctrl->ldctl_value,
                                   tmp;
              BerElementBuffer     berbuf;
              BerElement           *ber = (BerElement *)&berbuf;
              ber_tag_t            tag;

              if ( strncasecmp( authzID.bv_val, "dn:", STRLENOF( "dn:" ) ) != 0 ) {
                     rs->sr_err = LDAP_PROTOCOL_ERROR;
                     goto done;
              }

              tmp = authzID;
              tmp.bv_val += STRLENOF( "dn:" );
              tmp.bv_len -= STRLENOF( "dn:" );

              ber_init2( ber, 0, LBER_USE_DER );
              ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );

              /* apparently, Mozilla API encodes this
               * as "SEQUENCE { LDAPDN }" */
              tag = ber_printf( ber, "{O}", &tmp );
              if ( tag == LBER_ERROR ) {
                     rs->sr_err = LDAP_OTHER;
                     goto free_ber2;
              }

              if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
                     rs->sr_err = LDAP_OTHER;
                     goto free_ber2;
              }

              ctrl->ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
              rs->sr_err = LDAP_SUCCESS;

free_ber2:;
              op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
              ber_free_buf( ber );

              if ( rs->sr_err != LDAP_SUCCESS ) {
                     goto done;
              }
       }

done:;

       return rs->sr_err;
}

Here is the call graph for this function:

Definition at line 1208 of file bind.c.

{
       ldapinfo_t           *li = (ldapinfo_t *)op->o_bd->be_private;

       slap_retry_info_t    *ri = &li->li_quarantine;

       ldap_pvt_thread_mutex_lock( &li->li_quarantine_mutex );

       if ( rs->sr_err == LDAP_UNAVAILABLE ) {
              time_t        new_last = slap_get_time();

              switch ( li->li_isquarantined ) {
              case LDAP_BACK_FQ_NO:
                     if ( ri->ri_last == new_last ) {
                            goto done;
                     }

                     Debug( LDAP_DEBUG_ANY,
                            "%s: ldap_back_quarantine enter.\n",
                            op->o_log_prefix, 0, 0 );

                     ri->ri_idx = 0;
                     ri->ri_count = 0;
                     break;

              case LDAP_BACK_FQ_RETRYING:
                     Debug( LDAP_DEBUG_ANY,
                            "%s: ldap_back_quarantine block #%d try #%d failed.\n",
                            op->o_log_prefix, ri->ri_idx, ri->ri_count );

                     ++ri->ri_count;
                     if ( ri->ri_num[ ri->ri_idx ] != SLAP_RETRYNUM_FOREVER
                            && ri->ri_count == ri->ri_num[ ri->ri_idx ] )
                     {
                            ri->ri_count = 0;
                            ++ri->ri_idx;
                     }
                     break;

              default:
                     break;
              }

              li->li_isquarantined = LDAP_BACK_FQ_YES;
              ri->ri_last = new_last;

       } else if ( li->li_isquarantined != LDAP_BACK_FQ_NO ) {
              if ( ri->ri_last == slap_get_time() ) {
                     goto done;
              }

              Debug( LDAP_DEBUG_ANY,
                     "%s: ldap_back_quarantine exit (%d) err=%d.\n",
                     op->o_log_prefix, li->li_isquarantined, rs->sr_err );

              if ( li->li_quarantine_f ) {
                     (void)li->li_quarantine_f( li, li->li_quarantine_p );
              }

              ri->ri_count = 0;
              ri->ri_idx = 0;
              li->li_isquarantined = LDAP_BACK_FQ_NO;
       }

done:;
       ldap_pvt_thread_mutex_unlock( &li->li_quarantine_mutex );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ldap_back_release_conn_lock ( ldapinfo_t li,
ldapconn_t **  lcp,
int  dolock 
)

Definition at line 1184 of file bind.c.

{

       ldapconn_t    *lc = *lcp;

       if ( dolock ) {
              ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
       }
       assert( lc->lc_refcnt > 0 );
       LDAP_BACK_CONN_BINDING_CLEAR( lc );
       lc->lc_refcnt--;
       if ( LDAP_BACK_CONN_TAINTED( lc ) ) {
              ldap_back_freeconn( li, lc, 0 );
              *lcp = NULL;
       }
       if ( dolock ) {
              ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldap_back_retry ( ldapconn_t **  lcp,
Operation op,
SlapReply rs,
ldap_back_send_t  sendok 
)

Definition at line 1979 of file bind.c.

{
       ldapinfo_t    *li = (ldapinfo_t *)op->o_bd->be_private;
       int           rc = 0;

       assert( lcp != NULL );
       assert( *lcp != NULL );

       ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );

       if ( (*lcp)->lc_refcnt == 1 ) {
              int binding = LDAP_BACK_CONN_BINDING( *lcp );

              ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
              Debug( LDAP_DEBUG_ANY,
                     "%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
                     op->o_log_prefix, li->li_uri,
                     BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ?
                            "" : (*lcp)->lc_bound_ndn.bv_val );
              ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );

              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( *lcp, op, rs, sendok );
              if ( rc != LDAP_SUCCESS ) {
                     /* freeit, because lc_refcnt == 1 */
                     (*lcp)->lc_refcnt = 0;
                     (void)ldap_back_freeconn( li, *lcp, 0 );
                     *lcp = NULL;
                     rc = 0;

              } else if ( ( sendok & LDAP_BACK_BINDING ) ) {
                     if ( binding ) {
                            LDAP_BACK_CONN_BINDING_SET( *lcp );
                     }
                     rc = 1;

              } else {
                     rc = ldap_back_dobind_int( lcp, op, rs, sendok, 0, 0 );
                     if ( rc == 0 && *lcp != NULL ) {
                            /* freeit, because lc_refcnt == 1 */
                            (*lcp)->lc_refcnt = 0;
                            LDAP_BACK_CONN_TAINTED_SET( *lcp );
                            (void)ldap_back_freeconn( li, *lcp, 0 );
                            *lcp = NULL;
                     }
              }

       } else {
              Debug( LDAP_DEBUG_TRACE,
                     "ldap_back_retry: conn %p refcnt=%u unable to retry.\n",
                     (void *)(*lcp), (*lcp)->lc_refcnt, 0 );

              LDAP_BACK_CONN_TAINTED_SET( *lcp );
              ldap_back_release_conn_lock( li, lcp, 0 );
              assert( *lcp == NULL );

              if ( sendok & LDAP_BACK_SENDERR ) {
                     rs->sr_err = LDAP_UNAVAILABLE;
                     rs->sr_text = "Unable to retry";
                     send_ldap_result( op, rs );
              }
       }

       ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2279 of file config.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int slap_idassert_authzfrom_parse_cf ( const char *  fname,
int  lineno,
const char *  arg,
slap_idassert_t si 
)

Definition at line 914 of file config.c.

{
       ConfigArgs    c = { 0 };
       char          *argv[ 3 ];

       snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
       c.argc = 2;
       c.argv = argv;
       argv[ 0 ] = "idassert-authzFrom";
       argv[ 1 ] = (char *)arg;
       argv[ 2 ] = NULL;

       return slap_idassert_authzfrom_parse( &c, si );
}

Here is the call graph for this function:

int slap_idassert_parse_cf ( const char *  fname,
int  lineno,
int  argc,
char *  argv[],
slap_idassert_t si 
)

Definition at line 946 of file config.c.

{
       ConfigArgs    c = { 0 };

       snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
       c.argc = argc;
       c.argv = argv;

       return slap_idassert_parse( &c, si );
}

Here is the call graph for this function:

int slap_idassert_passthru_parse_cf ( const char *  fname,
int  lineno,
const char *  arg,
slap_idassert_t si 
)

Definition at line 930 of file config.c.

{
       ConfigArgs    c = { 0 };
       char          *argv[ 3 ];

       snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno );
       c.argc = 2;
       c.argv = argv;
       argv[ 0 ] = "idassert-passThru";
       argv[ 1 ] = (char *)arg;
       argv[ 2 ] = NULL;

       return slap_idassert_passthru_parse( &c, si );
}

Here is the call graph for this function:

Definition at line 629 of file config.c.

{
       assert( ri != NULL );

       assert( ri->ri_interval != NULL );
       ch_free( ri->ri_interval );
       ri->ri_interval = NULL;

       assert( ri->ri_num != NULL );
       ch_free( ri->ri_num );
       ri->ri_num = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slap_retry_info_parse ( char *  in,
slap_retry_info_t ri,
char *  buf,
ber_len_t  buflen 
)

Definition at line 493 of file config.c.

{
       char                 **retrylist = NULL;
       int                  rc = 0;
       int                  i;

       slap_str2clist( &retrylist, in, " ;" );
       if ( retrylist == NULL ) {
              return 1;
       }

       for ( i = 0; retrylist[ i ] != NULL; i++ )
              /* count */ ;

       ri->ri_interval = ch_calloc( sizeof( time_t ), i + 1 );
       ri->ri_num = ch_calloc( sizeof( int ), i + 1 );

       for ( i = 0; retrylist[ i ] != NULL; i++ ) {
              unsigned long t;
              char          *sep = strchr( retrylist[ i ], ',' );

              if ( sep == NULL ) {
                     snprintf( buf, buflen,
                            "missing comma in retry pattern #%d \"%s\"",
                            i, retrylist[ i ] );
                     rc = 1;
                     goto done;
              }

              *sep++ = '\0';

              if ( lutil_parse_time( retrylist[ i ], &t ) ) {
                     snprintf( buf, buflen,
                            "unable to parse interval #%d \"%s\"",
                            i, retrylist[ i ] );
                     rc = 1;
                     goto done;
              }
              ri->ri_interval[ i ] = (time_t)t;

              if ( strcmp( sep, "+" ) == 0 ) {
                     if ( retrylist[ i + 1 ] != NULL ) {
                            snprintf( buf, buflen,
                                   "extra cruft after retry pattern "
                                   "#%d \"%s,+\" with \"forever\" mark",
                                   i, retrylist[ i ] );
                            rc = 1;
                            goto done;
                     }
                     ri->ri_num[ i ] = SLAP_RETRYNUM_FOREVER;
                     
              } else if ( lutil_atoi( &ri->ri_num[ i ], sep ) ) {
                     snprintf( buf, buflen,
                            "unable to parse retry num #%d \"%s\"",
                            i, sep );
                     rc = 1;
                     goto done;
              }
       }

       ri->ri_num[ i ] = SLAP_RETRYNUM_TAIL;

       ri->ri_idx = 0;
       ri->ri_count = 0;
       ri->ri_last = (time_t)(-1);

done:;
       ldap_charray_free( retrylist );

       if ( rc ) {
              slap_retry_info_destroy( ri );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int slap_retry_info_unparse ( slap_retry_info_t ri,
struct berval bvout 
)

Definition at line 574 of file config.c.

{
       char          buf[ BUFSIZ * 2 ],
                     *ptr = buf;
       int           i, len, restlen = (int) sizeof( buf );
       struct berval bv;

       assert( ri != NULL );
       assert( bvout != NULL );

       BER_BVZERO( bvout );

       for ( i = 0; ri->ri_num[ i ] != SLAP_RETRYNUM_TAIL; i++ ) {
              if ( i > 0 ) {
                     if ( --restlen <= 0 ) {
                            return 1;
                     }
                     *ptr++ = ';';
              }

              if ( lutil_unparse_time( ptr, restlen, ri->ri_interval[i] ) < 0 ) {
                     return 1;
              }
              len = (int) strlen( ptr );
              if ( (restlen -= len + 1) <= 0 ) {
                     return 1;
              }
              ptr += len;
              *ptr++ = ',';

              if ( ri->ri_num[i] == SLAP_RETRYNUM_FOREVER ) {
                     if ( --restlen <= 0 ) {
                            return 1;
                     }
                     *ptr++ = '+';

              } else {
                     len = snprintf( ptr, restlen, "%d", ri->ri_num[i] );
                     if ( (restlen -= len) <= 0 || len < 0 ) {
                            return 1;
                     }
                     ptr += len;
              }
       }

       bv.bv_val = buf;
       bv.bv_len = ptr - buf;
       ber_dupbv( bvout, &bv );

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

LDAP_REBIND_PROC ldap_back_default_rebind
LDAP_URLLIST_PROC ldap_back_default_urllist
BI_entry_get_rw ldap_back_entry_get