Beispiel #1
0
static int
sock_over_response( Operation *op, SlapReply *rs )
{
	slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
	struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private;
	FILE *fp;

	if ( rs->sr_type == REP_RESULT ) {
		if ( !( si->si_resps & SOCK_REP_RESULT ))
			return SLAP_CB_CONTINUE;
	} else if ( rs->sr_type == REP_SEARCH ) {
		if ( !( si->si_resps & SOCK_REP_SEARCH ))
			return SLAP_CB_CONTINUE;
	} else
		return SLAP_CB_CONTINUE;

	if (( fp = opensock( si->si_sockpath )) == NULL )
		return SLAP_CB_CONTINUE;

	if ( rs->sr_type == REP_RESULT ) {
		/* write out the result */
		fprintf( fp, "RESULT\n" );
		fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
		sock_print_conn( fp, op->o_conn, si );
		fprintf( fp, "code: %d\n", rs->sr_err );
		if ( rs->sr_matched )
			fprintf( fp, "matched: %s\n", rs->sr_matched );
		if (rs->sr_text )
			fprintf( fp, "info: %s\n", rs->sr_text );
	} else {
		/* write out the search entry */
		int len;
		fprintf( fp, "ENTRY\n" );
		fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
		sock_print_conn( fp, op->o_conn, si );
		ldap_pvt_thread_mutex_lock( &entry2str_mutex );
		fprintf( fp, "%s", entry2str( rs->sr_entry, &len ) );
		ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
	}
	fprintf( fp, "\n" );
	fclose( fp );

	return SLAP_CB_CONTINUE;
}
Beispiel #2
0
int
shell_back_add(
    Operation	*op,
    SlapReply	*rs )
{
	struct shellinfo	*si = (struct shellinfo *) op->o_bd->be_private;
	AttributeDescription *entry = slap_schema.si_ad_entry;
	FILE			*rfp, *wfp;
	int			len;

	if ( si->si_add == NULL ) {
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
		    "add not implemented" );
		return( -1 );
	}

	if ( ! access_allowed( op, op->oq_add.rs_e,
		entry, NULL, ACL_WADD, NULL ) )
	{
		send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
		return -1;
	}

	if ( forkandexec( si->si_add, &rfp, &wfp ) == (pid_t)-1 ) {
		send_ldap_error( op, rs, LDAP_OTHER,
		    "could not fork/exec" );
		return( -1 );
	}

	/* write out the request to the add process */
	fprintf( wfp, "ADD\n" );
	fprintf( wfp, "msgid: %ld\n", (long) op->o_msgid );
	print_suffixes( wfp, op->o_bd );
	ldap_pvt_thread_mutex_lock( &entry2str_mutex );
	fprintf( wfp, "%s", entry2str( op->oq_add.rs_e, &len ) );
	ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
	fclose( wfp );

	/* read in the result and send it along */
	read_and_send_results( op, rs, rfp );

	fclose( rfp );
	return( 0 );
}
Beispiel #3
0
void
bdb_cache_release_all( Cache *cache )
{
	Entry *e;
	int rc;

	/* set cache write lock */
	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );
	/* set lru mutex */
	ldap_pvt_thread_mutex_lock( &cache->lru_mutex );

#ifdef NEW_LOGGING
	LDAP_LOG( CACHE, ENTRY, "bdb_cache_release_all: enter\n", 0, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 );
#endif

	while ( (e = cache->c_lrutail) != NULL && BEI(e)->bei_refcnt == 0 ) {
#ifdef LDAP_RDWR_DEBUG
		assert(!ldap_pvt_thread_rdwr_active(&BEI(e)->bei_rdwr));
#endif

		/* delete from cache and lru q */
		/* XXX do we need rc ? */
		rc = bdb_cache_delete_entry_internal( cache, e );
		bdb_cache_entry_private_destroy( e );
		bdb_entry_return( e );
	}

	if ( cache->c_cursize ) {
#ifdef NEW_LOGGING
		LDAP_LOG( CACHE, INFO,
		   "bdb_cache_release_all: Entry cache could not be emptied.\n", 0, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE, "Entry-cache could not be emptied\n", 0, 0, 0 );
#endif

	}

	/* free lru mutex */
	ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );
	/* free cache write lock */
	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
}
Beispiel #4
0
int
ldap_back_conn_destroy(
		Backend		*be,
		Connection	*conn
)
{
	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",
		conn->c_connid, 0, 0 );

	lc_curr.lc_conn = conn;
	
	ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
#if LDAP_BACK_PRINT_CONNTREE > 0
	ldap_back_print_conntree( li, ">>> ldap_back_conn_destroy" );
#endif /* LDAP_BACK_PRINT_CONNTREE */
	while ( ( lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ) ) != NULL )
	{
		assert( !LDAP_BACK_PCONN_ISPRIV( lc ) );
		Debug( LDAP_DEBUG_TRACE,
			"=>ldap_back_conn_destroy: destroying conn %lu "
			"refcnt=%d flags=0x%08x\n",
			lc->lc_conn->c_connid, lc->lc_refcnt, lc->lc_lcflags );

		if ( lc->lc_refcnt > 0 ) {
			/* someone else might be accessing the connection;
			 * mark for deletion */
			LDAP_BACK_CONN_CACHED_CLEAR( lc );
			LDAP_BACK_CONN_TAINTED_SET( lc );

		} else {
			ldap_back_conn_free( lc );
		}
	}
#if LDAP_BACK_PRINT_CONNTREE > 0
	ldap_back_print_conntree( li, "<<< ldap_back_conn_destroy" );
#endif /* LDAP_BACK_PRINT_CONNTREE */
	ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );

	return 0;
}
Beispiel #5
0
static void *
dds_expire_fn( void *ctx, void *arg )
{
	struct re_s     *rtask = arg;
	dds_info_t	*di = rtask->arg;

	assert( di->di_expire_task == rtask );

	(void)dds_expire( ctx, di );

	ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
	if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
		ldap_pvt_runqueue_stoptask( &slapd_rq, rtask );
	}
	ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
	ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );

	return NULL;
}
Beispiel #6
0
Attribute *
attr_alloc( AttributeDescription *ad )
{
	Attribute *a;

	ldap_pvt_thread_mutex_lock( &attr_mutex );
	if ( !attr_list )
		attr_prealloc( CHUNK_SIZE );
	a = attr_list;
	attr_list = a->a_next;
	a->a_next = NULL;
	ldap_pvt_thread_mutex_unlock( &attr_mutex );
	
	a->a_desc = ad;
	if ( ad && ( ad->ad_type->sat_flags & SLAP_AT_SORTED_VAL ))
		a->a_flags |= SLAP_ATTR_SORTED_VALS;

	return a;
}
Beispiel #7
0
int
ldap_pvt_discard(
	LDAP *ld,
	ber_int_t msgid )
{
	int	rc;

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif

	rc = do_abandon( ld, msgid, msgid, NULL, 0 );

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif

	return rc;
}
Beispiel #8
0
static LDAPConn *
find_connection( LDAP *ld, LDAPURLDesc *srv, int any )
/*
 * return an existing connection (if any) to the server srv
 * if "any" is non-zero, check for any server in the "srv" chain
 */
{
	LDAPConn	*lc;
	LDAPURLDesc	*lcu, *lsu;
	int lcu_port, lsu_port;
	int found = 0;

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
#endif
	for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
		lcu = lc->lconn_server;
		lcu_port = ldap_pvt_url_scheme_port( lcu->lud_scheme,
			lcu->lud_port );

		for ( lsu = srv; lsu != NULL; lsu = lsu->lud_next ) {
			lsu_port = ldap_pvt_url_scheme_port( lsu->lud_scheme,
				lsu->lud_port );

			if ( lsu_port == lcu_port
				&& strcmp( lcu->lud_scheme, lsu->lud_scheme ) == 0
				&& lcu->lud_host != NULL && lsu->lud_host != NULL
				&& strcasecmp( lsu->lud_host, lcu->lud_host ) == 0 )
			{
				found = 1;
				break;
			}

			if ( !any ) break;
		}
		if ( found )
			break;
	}
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
#endif
	return lc;
}
Beispiel #9
0
int
perl_back_db_open(
    BackendDB	*be,
    ConfigReply	*cr
)
{
    int count;
    int return_code;

    PerlBackend *perl_back = (PerlBackend *) be->be_private;

    ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );

    {
        dSP;
        ENTER;
        SAVETMPS;

        PUSHMARK(sp);
        XPUSHs( perl_back->pb_obj_ref );

        PUTBACK;

        count = call_method("init", G_SCALAR);

        SPAGAIN;

        if (count != 1) {
            croak("Big trouble in perl_back_db_open\n");
        }

        return_code = POPi;

        PUTBACK;
        FREETMPS;
        LEAVE;
    }

    ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );

    return return_code;
}
Beispiel #10
0
static int
usn_func( Operation *op, SlapReply *rs )
{
	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;
	usn_info_t		*ui = on->on_bi.bi_private;
	int my_usn;
	char intbuf[64];
	struct berval bv[2];

	ldap_pvt_thread_mutex_lock( &ui->ui_mutex );
	ui->ui_current++;
	my_usn = ui->ui_current;
	ldap_pvt_thread_mutex_unlock( &ui->ui_mutex );

	BER_BVZERO(&bv[1]);
	bv[0].bv_val = intbuf;
	bv[0].bv_len = snprintf( intbuf, sizeof(intbuf), "%d", my_usn );
	switch(op->o_tag) {
	case LDAP_REQ_ADD:
		attr_merge( op->ora_e, ad_usnCreated, bv, NULL );
		attr_merge( op->ora_e, ad_usnChanged, bv, NULL );
		break;
	case LDAP_REQ_DELETE:
		/* Probably need to update root usnLastObjRem */
		break;
	default: {
		/* Modify, ModDN */
		Modifications *ml, *mod = ch_calloc( sizeof( Modifications ), 1 );
		for ( ml = op->orm_modlist; ml && ml->sml_next; ml = ml->sml_next );
		ml->sml_next = mod;
		mod->sml_desc = ad_usnChanged;
		mod->sml_numvals = 1;
		value_add_one( &mod->sml_values, &bv[0] );
		mod->sml_nvalues = NULL;
		mod->sml_op = LDAP_MOD_REPLACE;
		mod->sml_flags = 0;
		mod->sml_next = NULL;
		break;
		}
	}
	return SLAP_CB_CONTINUE;
}
Beispiel #11
0
int
fe_op_bind_success( Operation *op, SlapReply *rs )
{
	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );

	if( op->o_conn->c_authz_backend == NULL ) {
		op->o_conn->c_authz_backend = op->o_bd;
	}

	/* be_bind returns regular/global edn */
	if( !BER_BVISEMPTY( &op->orb_edn ) ) {
		op->o_conn->c_dn = op->orb_edn;
	} else {
		ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn);
	}

	ber_dupbv( &op->o_conn->c_ndn, &op->o_req_ndn );

	/* op->o_conn->c_sb may be 0 for internal operations */
	if( !BER_BVISEMPTY( &op->o_conn->c_dn ) && op->o_conn->c_sb != 0 ) {
		ber_len_t max = sockbuf_max_incoming_auth;
		ber_sockbuf_ctrl( op->o_conn->c_sb,
			LBER_SB_OPT_SET_MAX_INCOMING, &max );
	}

	/* log authorization identity */
	Statslog( LDAP_DEBUG_STATS,
		"%s BIND dn=\"%s\" mech=%s ssf=0\n",
		op->o_log_prefix,
		op->o_conn->c_dn.bv_val, op->orb_mech.bv_val );

	Debug( LDAP_DEBUG_TRACE,
		"do_bind: v%d bind: \"%s\" to \"%s\"\n",
		op->o_protocol, op->o_req_dn.bv_val, op->o_conn->c_dn.bv_val );

	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );

	/* send this here to avoid a race condition */
	send_ldap_result( op, rs );

	return LDAP_SUCCESS;
}
Beispiel #12
0
static int
bdb_db_destroy( BackendDB *be, ConfigReply *cr )
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;

	/* stop and remove checkpoint task */
	if ( bdb->bi_txn_cp_task ) {
		struct re_s *re = bdb->bi_txn_cp_task;
		bdb->bi_txn_cp_task = NULL;
		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
		if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
			ldap_pvt_runqueue_stoptask( &slapd_rq, re );
		ldap_pvt_runqueue_remove( &slapd_rq, re );
		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
	}

	/* monitor handling */
	(void)bdb_monitor_db_destroy( be );

	if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home );
	if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path );

	bdb_attr_index_destroy( bdb );

	ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_lru_mutex );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_count_mutex );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_eifree_mutex );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
#ifdef BDB_HIER
	ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex );
#endif
	ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
	ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
	ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );

	ch_free( bdb );
	be->be_private = NULL;

	return 0;
}
Beispiel #13
0
static int
undef_promote(
	AttributeType	*at,
	char		*name,
	AttributeType	*nat )
{
	AttributeDescription	**u_ad, **n_ad;

	/* Get to last ad on the new type */
	for ( n_ad = &nat->sat_ad; *n_ad; n_ad = &(*n_ad)->ad_next ) ;

	for ( u_ad = &at->sat_ad; *u_ad; ) {
		struct berval	bv;

		ber_str2bv( name, 0, 0, &bv );

		/* remove iff undef == name or undef == name;tag */
		if ( (*u_ad)->ad_cname.bv_len >= bv.bv_len
			&& strncasecmp( (*u_ad)->ad_cname.bv_val, bv.bv_val, bv.bv_len ) == 0
			&& ( (*u_ad)->ad_cname.bv_val[ bv.bv_len ] == '\0'
				|| (*u_ad)->ad_cname.bv_val[ bv.bv_len ] == ';' ) )
		{
			AttributeDescription	*tmp = *u_ad;

			*u_ad = (*u_ad)->ad_next;

			tmp->ad_type = nat;
			tmp->ad_next = NULL;
			/* ad_cname was contiguous, no leak here */
			tmp->ad_cname = nat->sat_cname;
			ldap_pvt_thread_mutex_lock( &ad_index_mutex );
			tmp->ad_index = ++ad_count;
			ldap_pvt_thread_mutex_unlock( &ad_index_mutex );
			*n_ad = tmp;
			n_ad = &tmp->ad_next;
		} else {
			u_ad = &(*u_ad)->ad_next;
		}
	}

	return 0;
}
Beispiel #14
0
int ldap_pvt_thread_rmutex_lock( ldap_pvt_thread_rmutex_t *rmutex,
	ldap_pvt_thread_t owner )
{
	struct ldap_int_thread_rmutex_s *rm;

	assert( rmutex != NULL );
	rm = *rmutex;

	assert( rm != NULL );
	assert( rm->ltrm_valid == LDAP_PVT_THREAD_RMUTEX_VALID );

	if( rm->ltrm_valid != LDAP_PVT_THREAD_RMUTEX_VALID )
		return LDAP_PVT_THREAD_EINVAL;

	ldap_pvt_thread_mutex_lock( &rm->ltrm_mutex );

	assert( rm->ltrm_depth >= 0 );
	assert( rm->ltrm_waits >= 0 );

	if( rm->ltrm_depth > 0 ) {
		/* already locked */
		if ( !ldap_pvt_thread_equal( rm->ltrm_owner, owner )) {
			rm->ltrm_waits++;
			do {
				ldap_pvt_thread_cond_wait( &rm->ltrm_cond,
					&rm->ltrm_mutex );
			} while( rm->ltrm_depth > 0 );

			rm->ltrm_waits--;
			assert( rm->ltrm_waits >= 0 );
			rm->ltrm_owner = owner;
		}
	} else {
		rm->ltrm_owner = owner;
	}

	rm->ltrm_depth++;

	ldap_pvt_thread_mutex_unlock( &rm->ltrm_mutex );

	return 0;
}
Beispiel #15
0
int ldap_pvt_thread_rdwr_wlock( ldap_pvt_thread_rdwr_t *rwlock )
{
	struct ldap_int_thread_rdwr_s *rw;

	assert( rwlock != NULL );
	rw = *rwlock;

	assert( rw != NULL );
	assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );

	if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID )
		return LDAP_PVT_THREAD_EINVAL;

	ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );

	assert( rw->ltrw_w_active >= 0 ); 
	assert( rw->ltrw_w_wait >= 0 ); 
	assert( rw->ltrw_r_active >= 0 ); 
	assert( rw->ltrw_r_wait >= 0 ); 

	if ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 ) {
		rw->ltrw_w_wait++;

		do {
			ldap_pvt_thread_cond_wait(
				&rw->ltrw_write, &rw->ltrw_mutex );
		} while ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 );

		rw->ltrw_w_wait--;
		assert( rw->ltrw_w_wait >= 0 ); 
	}

#ifdef LDAP_RDWR_DEBUG
	rw->ltrw_writer = ldap_pvt_thread_self();
#endif
	rw->ltrw_w_active++;

	ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );

	return 0;
}
Beispiel #16
0
static void
bdb_cache_entryinfo_free( Cache *cache, EntryInfo *ei )
{
	free( ei->bei_nrdn.bv_val );
	ei->bei_nrdn.bv_val = NULL;
#ifdef BDB_HIER
	free( ei->bei_rdn.bv_val );
	ei->bei_rdn.bv_val = NULL;
	ei->bei_modrdns = 0;
	ei->bei_ckids = 0;
	ei->bei_dkids = 0;
#endif
	ei->bei_parent = NULL;
	ei->bei_kids = NULL;
	ei->bei_lruprev = NULL;

	ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
	ei->bei_lrunext = cache->c_eifree;
	cache->c_eifree = ei;
	ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
}
Beispiel #17
0
int
perl_back_delete(
	Operation	*op,
	SlapReply	*rs )
{
	PerlBackend *perl_back = (PerlBackend *) op->o_bd->be_private;
	int count;

	PERL_SET_CONTEXT( PERL_INTERPRETER );
	ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );

	{
		dSP; ENTER; SAVETMPS;

		PUSHMARK(sp);
		XPUSHs( perl_back->pb_obj_ref );
		XPUSHs(sv_2mortal(newSVpv( op->o_req_dn.bv_val , op->o_req_dn.bv_len )));

		PUTBACK;

		count = call_method("delete", G_SCALAR);

		SPAGAIN;

		if (count != 1) {
			croak("Big trouble in perl-back_delete\n");
		}

		rs->sr_err = POPi;

		PUTBACK; FREETMPS; LEAVE;
	}

	ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );

	send_ldap_result( op, rs );

	Debug( LDAP_DEBUG_ANY, "Perl DELETE\n" );
	return( 0 );
}
Beispiel #18
0
/*
 * ldap_result - wait for an ldap result response to a message from the
 * ldap server.  If msgid is LDAP_RES_ANY (-1), any message will be
 * accepted.  If msgid is LDAP_RES_UNSOLICITED (0), any unsolicited
 * message is accepted.  Otherwise ldap_result will wait for a response
 * with msgid.  If all is LDAP_MSG_ONE (0) the first message with id
 * msgid will be accepted, otherwise, ldap_result will wait for all
 * responses with id msgid and then return a pointer to the entire list
 * of messages.  In general, this is only useful for search responses,
 * which can be of three message types (zero or more entries, zero or
 * search references, followed by an ldap result).  An extension to
 * LDAPv3 allows partial extended responses to be returned in response
 * to any request.  The type of the first message received is returned.
 * When waiting, any messages that have been abandoned/discarded are 
 * discarded.
 *
 * Example:
 *	ldap_result( s, msgid, all, timeout, result )
 */
int
ldap_result(
	LDAP *ld,
	int msgid,
	int all,
	struct timeval *timeout,
	LDAPMessage **result )
{
	LDAPMessage	*lm = NULL;
	int		rc;

	assert( ld != NULL );
	assert( result != NULL );

	Debug( LDAP_DEBUG_TRACE, "ldap_result ld %p msgid %d\n", (void *)ld, msgid, 0 );

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif

#if 0
	/* this is already done inside wait4msg(), right?... */
	lm = chkResponseList( ld, msgid, all );
#endif

	if ( lm == NULL ) {
		rc = wait4msg( ld, msgid, all, timeout, result );

	} else {
		*result = lm;
		ld->ld_errno = LDAP_SUCCESS;
		rc = lm->lm_msgtype;
	}

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
#endif

	return rc;
}
Beispiel #19
0
static int
dds_db_close(
	BackendDB	*be,
	ConfigReply	*cr )
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	dds_info_t	*di = on->on_bi.bi_private;

	/* stop expire task */
	if ( di && di->di_expire_task ) {
		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
		if ( ldap_pvt_runqueue_isrunning( &slapd_rq, di->di_expire_task ) ) {
			ldap_pvt_runqueue_stoptask( &slapd_rq, di->di_expire_task );
		}
		ldap_pvt_runqueue_remove( &slapd_rq, di->di_expire_task );
		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
	}

	(void)entry_info_unregister( dds_entry_info, (void *)di );

	return 0;
}
Beispiel #20
0
static void *
bdb_tool_trickle_task( void *ctx, void *ptr )
{
	DB_ENV *env = ptr;
	int wrote;

	ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex );
	bdb_tool_trickle_active = 1;
	ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end );
	while ( 1 ) {
		ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond,
			&bdb_tool_trickle_mutex );
		if ( slapd_shutdown )
			break;
		env->memp_trickle( env, 30, &wrote );
	}
	bdb_tool_trickle_active = 0;
	ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end );
	ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex );

	return NULL;
}
Beispiel #21
0
int
sock_back_add(
    Operation	*op,
    SlapReply	*rs )
{
	struct sockinfo	*si = (struct sockinfo *) op->o_bd->be_private;
	AttributeDescription *entry = slap_schema.si_ad_entry;
	FILE			*fp;
	int			len;

	if ( ! access_allowed( op, op->oq_add.rs_e,
		entry, NULL, ACL_WADD, NULL ) )
	{
		send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
		return -1;
	}

	if ( (fp = opensock( si->si_sockpath )) == NULL ) {
		send_ldap_error( op, rs, LDAP_OTHER,
		    "could not open socket" );
		return( -1 );
	}

	/* write out the request to the add process */
	fprintf( fp, "ADD\n" );
	fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
	sock_print_conn( fp, op->o_conn, si );
	sock_print_suffixes( fp, op->o_bd );
	ldap_pvt_thread_mutex_lock( &entry2str_mutex );
	fprintf( fp, "%s", entry2str( op->oq_add.rs_e, &len ) );
	ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
	fprintf (fp, "\n" );

	/* read in the result and send it along */
	sock_read_and_send_results( op, rs, fp );

	fclose( fp );
	return( 0 );
}
Beispiel #22
0
LDAPRequest *
ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
{
	LDAPRequest	*lr;

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
		if ( lr->lr_status == LDAP_REQST_COMPLETED ) {
			continue;	/* Skip completed requests */
		}
		if ( msgid == lr->lr_msgid ) {
			lr->lr_refcnt++;
			break;
		}
	}
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif

	return( lr );
}
Beispiel #23
0
static int
ldap_distproc_connection_destroy(
	BackendDB *be,
	Connection *conn
)
{
	slap_overinst		*on = (slap_overinst *) be->bd_info;
	ldap_distproc_t		*lc = (ldap_distproc_t *)on->on_bi.bi_private;
	void			*private = be->be_private;
	ldap_distproc_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_distproc_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;
}
Beispiel #24
0
static void *
bdb_tool_index_task( void *ctx, void *ptr )
{
	int base = *(int *)ptr;

	free( ptr );
	while ( 1 ) {
		ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex );
		bdb_tool_index_tcount--;
		if ( !bdb_tool_index_tcount )
			ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main );
		ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work,
			&bdb_tool_index_mutex );
		ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex );
		if ( slapd_shutdown )
			break;

		bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op,
			bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base );
	}

	return NULL;
}
Beispiel #25
0
struct tm *
ldap_pvt_localtime( const time_t *timep, struct tm *result )
{
	struct tm *tm_ptr;

# ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ldap_int_gmtime_mutex );
# endif /* LDAP_R_COMPILE */

	tm_ptr = localtime( timep );
	if ( tm_ptr == NULL ) {
		result = NULL;

	} else {
		*result = *tm_ptr;
	}

# ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ldap_int_gmtime_mutex );
# endif /* LDAP_R_COMPILE */

	return result;
}
Beispiel #26
0
static EntryInfo *
bdb_cache_entryinfo_new( Cache *cache )
{
	EntryInfo *ei = NULL;

	if ( cache->c_eifree ) {
		ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex );
		if ( cache->c_eifree ) {
			ei = cache->c_eifree;
			cache->c_eifree = ei->bei_lrunext;
			ei->bei_finders = 0;
		}
		ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex );
	}
	if ( !ei ) {
		ei = ch_calloc(1, sizeof(EntryInfo));
		ldap_pvt_thread_mutex_init( &ei->bei_kids_mutex );
	}

	ei->bei_state = CACHE_ENTRY_REFERENCED;

	return ei;
}
Beispiel #27
0
meta_search_candidate_t
asyncmeta_return_bind_errors(a_metaconn_t *mc, int candidate, SlapReply *bind_result, void *ctx, int dolock)
{
	a_metainfo_t	*mi = mc->mc_info;
	bm_context_t *bc, *onext;

	if ( dolock )
		ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );

	for (bc = LDAP_STAILQ_FIRST(&mc->mc_om_list); bc; bc = onext) {
		onext = LDAP_STAILQ_NEXT(bc, bc_next);
		if (bc->candidates[candidate].sr_msgid != META_MSGID_NEED_BIND
		    || bc->bc_active > 0 || bc->op->o_abandon > 0) {
			continue;
		}
		bc->candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		bc->candidates[ candidate ].sr_type = REP_RESULT;
		bc->candidates[ candidate ].sr_err = bind_result->sr_err;
		if (bc->op->o_tag != LDAP_REQ_SEARCH || (META_BACK_ONERR_STOP( mi )) ||
		    (asyncmeta_is_last_result(mc, bc, candidate) == 0)) {
			LDAP_STAILQ_REMOVE(&mc->mc_om_list, bc, bm_context_t, bc_next);
			bc->op->o_threadctx = ctx;
			bc->op->o_tid = ldap_pvt_thread_pool_tid( ctx );
			slap_sl_mem_setctx(ctx, bc->op->o_tmpmemctx);
			bc->rs.sr_err = bind_result->sr_err;
			bc->rs.sr_text = bind_result->sr_text;
			mc->pending_ops--;
			asyncmeta_send_ldap_result(bc, bc->op, &bc->rs);
			asyncmeta_clear_bm_context(bc);
		}
	}

	if ( dolock )
		ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	return META_SEARCH_CANDIDATE;
}
Beispiel #28
0
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rwlock )
{
	struct ldap_int_thread_rdwr_s *rw;

	assert( rwlock != NULL );
	rw = *rwlock;

	assert( rw != NULL );
	assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );

	if( rw->ltrw_valid != LDAP_PVT_THREAD_RDWR_VALID )
		return LDAP_PVT_THREAD_EINVAL;

	ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );

	rw->ltrw_w_active--;

	assert( rw->ltrw_w_active >= 0 ); 
	assert( rw->ltrw_w_wait >= 0 ); 
	assert( rw->ltrw_r_active >= 0 ); 
	assert( rw->ltrw_r_wait >= 0 ); 

	if (rw->ltrw_r_wait > 0) {
		ldap_pvt_thread_cond_broadcast( &rw->ltrw_read );

	} else if (rw->ltrw_w_wait > 0) {
		ldap_pvt_thread_cond_signal( &rw->ltrw_write );
	}

#ifdef LDAP_RDWR_DEBUG
	assert( rw->ltrw_writer == ldap_pvt_thread_self() );
	rw->ltrw_writer = 0;
#endif
	ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );

	return 0;
}
Beispiel #29
0
/*
 * meta_dncache_get_target
 *
 * returns the target a dn belongs to, or -1 in case the dn is not
 * in the cache
 */
int
meta_dncache_get_target(
	metadncache_t	*cache,
	struct berval	*ndn )
{
	metadncacheentry_t	tmp_entry,
				*entry;
	int			target = META_TARGET_NONE;

	assert( cache != NULL );
	assert( ndn != NULL );

	tmp_entry.dn = *ndn;
	ldap_pvt_thread_mutex_lock( &cache->mutex );
	entry = ( metadncacheentry_t * )avl_find( cache->tree,
			( caddr_t )&tmp_entry, meta_dncache_cmp );

	if ( entry != NULL ) {
		
		/*
		 * if cache->ttl < 0, cache never expires;
		 * if cache->ttl = 0 no cache is used; shouldn't get here
		 * else, cache is used with ttl
		 */
		if ( cache->ttl < 0 ) { 
			target = entry->target;

		} else {
			if ( entry->lastupdated+cache->ttl > slap_get_time() ) {
				target = entry->target;
			}
		}
	}
	ldap_pvt_thread_mutex_unlock( &cache->mutex );

	return target;
}
Beispiel #30
0
void
attrs_free( Attribute *a )
{
	if ( a ) {
		Attribute *b = (Attribute *)0xBAD, *tail, *next;

		/* save tail */
		tail = a;
		do {
			next = a->a_next;
			attr_clean( a );
			a->a_next = b;
			b = a;
			a = next;
		} while ( next );

		ldap_pvt_thread_mutex_lock( &attr_mutex );
		/* replace NULL with current attr list and let attr list
		 * start from last attribute returned to list */
		tail->a_next = attr_list;
		attr_list = b;
		ldap_pvt_thread_mutex_unlock( &attr_mutex );
	}
}