Ejemplo n.º 1
0
int
bdb_dn2id_matched(
	BackendDB	*be,
	DB_TXN *txn,
	struct berval	*in,
	ID *id,
	ID *id2,
	int flags )
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	struct berval	rdn;
	char		*p1, *p2;
	idNode *n, *p;
	int		rc = 0;

	if (!bdb->bi_troot)
		return DB_NOTFOUND;

	p = bdb->bi_troot;
	if (be_issuffix(be, in)) {
		*id = p->i_id;
		return 0;
	}

	p1 = in->bv_val + in->bv_len - be->be_nsuffix[0].bv_len - 1;

	n = p;
	ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
	for (;;) {
		for (p2 = p1-1; (p2 >= in->bv_val) && !DN_SEPARATOR(*p2); p2--);
		rdn.bv_val = p2+1;
		rdn.bv_len = p1-rdn.bv_val;
		p1 = p2;

		ldap_pvt_thread_rdwr_rlock(&p->i_kids_rdwr);
		n = bdb_find_rdn_node(&rdn, p->i_kids);
		ldap_pvt_thread_rdwr_runlock(&p->i_kids_rdwr);
		if (!n || p2 < in->bv_val) break;
		p = n;
	}
	ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);

	if (n) {
		*id = n->i_id;
	} else if (id2) {
		*id2 = p->i_id;
	} else {
		rc = DB_NOTFOUND;
	}

	return rc;
}
Ejemplo n.º 2
0
int
bdb_dn2id_children(
	BackendDB	*be,
	DB_TXN *txn,
	struct berval	*dn,
	int flags )
{
	int		rc;
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	ID		id;
	idNode *n;

	rc = bdb_dn2id(be, txn, dn, &id, flags);
	if (rc != 0)
		return rc;

	ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
	n = bdb_find_id_node(id, bdb->bi_tree);
	ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);

	if (!n->i_kids)
		return DB_NOTFOUND;
	else
		return 0;
}
Ejemplo n.º 3
0
Archivo: idl.c Proyecto: 1ack/Impala
/* Find a db/key pair in the IDL cache. If ids is non-NULL,
 * copy the cached IDL into it, otherwise just return the status.
 */
int
bdb_idl_cache_get(
	struct bdb_info	*bdb,
	DB			*db,
	DBT			*key,
	ID			*ids )
{
	bdb_idl_cache_entry_t idl_tmp;
	bdb_idl_cache_entry_t *matched_idl_entry;
	int rc = LDAP_NO_SUCH_OBJECT;

	DBT2bv( key, &idl_tmp.kstr );
	idl_tmp.db = db;
	ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock );
	matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
				      bdb_idl_entry_cmp );
	if ( matched_idl_entry != NULL ) {
		if ( matched_idl_entry->idl && ids )
			BDB_IDL_CPY( ids, matched_idl_entry->idl );
		matched_idl_entry->idl_flags |= CACHE_ENTRY_REFERENCED;
		if ( matched_idl_entry->idl )
			rc = LDAP_SUCCESS;
		else
			rc = DB_NOTFOUND;
	}
	ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );

	return rc;
}
Ejemplo n.º 4
0
/*
 * Fetches a session
 */
struct rewrite_session *
rewrite_session_find(
		struct rewrite_info *info,
		const void *cookie
)
{
	struct rewrite_session *session, tmp;

	assert( info != NULL );
	assert( cookie != NULL );
	
	tmp.ls_cookie = ( void * )cookie;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
	ldap_pvt_thread_rdwr_rlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
	session = ( struct rewrite_session * )avl_find( info->li_cookies,
			( caddr_t )&tmp, rewrite_cookie_cmp );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
	if ( session ) {
		ldap_pvt_thread_mutex_lock( &session->ls_mutex );
	}
	ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

	return session;
}
Ejemplo n.º 5
0
static int
ndb_oc_check( BackendDB *be, Ndb *ndb,
	struct berval *ocsin, NdbOcs *out )
{
	struct ndb_info *ni = (struct ndb_info *) be->be_private;
	const NdbDictionary::Dictionary *myDict = ndb->getDictionary();

	int i, rc = 0;

	out->no_ninfo = 0;
	out->no_ntext = 0;
	out->no_nitext = 0;

	/* Find all objectclasses and their superiors. List
	 * the superiors first.
	 */

	ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock );
	for ( i=0; !BER_BVISNULL( &ocsin[i] ); i++ ) {
		rc = ndb_oc_list( ni, myDict, &ocsin[i], 0, out );
		if ( rc ) break;
	}
	ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock );
	return rc;
}
Ejemplo n.º 6
0
/*
 * Gets a var with global scope
 */
int
rewrite_param_get(
		struct rewrite_info *info,
		const char *name,
		struct berval *value
)
{
	struct rewrite_var *var;

	assert( info != NULL );
	assert( name != NULL );
	assert( value != NULL );

	value->bv_val = NULL;
	value->bv_len = 0;
	
#ifdef USE_REWRITE_LDAP_PVT_THREADS
	ldap_pvt_thread_rdwr_rlock( &info->li_params_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
	
	var = rewrite_var_find( info->li_params, name );
	if ( var == NULL ) {
		
#ifdef USE_REWRITE_LDAP_PVT_THREADS
		ldap_pvt_thread_rdwr_runlock( &info->li_params_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
		
		return REWRITE_ERR;
	} else {
		value->bv_val = strdup( var->lv_value.bv_val );
		value->bv_len = var->lv_value.bv_len;
	}
	
#ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_runlock( &info->li_params_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
	
	return REWRITE_SUCCESS;
}
Ejemplo n.º 7
0
/*
 * Gets a var with session scope
 */
int
rewrite_session_var_get(
		struct rewrite_info *info,
		const void *cookie,
		const char *name,
		struct berval *value
)
{
	struct rewrite_session *session;
	struct rewrite_var *var;
	int rc = REWRITE_SUCCESS;

	assert( info != NULL );
	assert( cookie != NULL );
	assert( name != NULL );
	assert( value != NULL );

	value->bv_val = NULL;
	value->bv_len = 0;
	
	if ( cookie == NULL ) {
		return REWRITE_ERR;
	}

	session = rewrite_session_find( info, cookie );
	if ( session == NULL ) {
		return REWRITE_ERR;
	}

#ifdef USE_REWRITE_LDAP_PVT_THREADS
	ldap_pvt_thread_rdwr_rlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
	
	var = rewrite_var_find( session->ls_vars, name );
	if ( var != NULL ) {
		value->bv_val = strdup( var->lv_value.bv_val );
		value->bv_len = var->lv_value.bv_len;
	}

	if ( var == NULL || value->bv_val == NULL ) {
		rc = REWRITE_ERR;
	}

#ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

	rewrite_session_return( info, session );

	return rc;
}
Ejemplo n.º 8
0
int
bdb_dn2idl(
	BackendDB	*be,
	struct berval	*dn,
	int prefix,
	ID *ids )
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	int		rc;
	ID		id;
	idNode		*n;

	if (prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn)) {
		BDB_IDL_ALL(bdb, ids);
		return 0;
	}

	rc = bdb_dn2id(be, NULL, dn, &id, 0);
	if (rc) return rc;

	ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
	n = bdb_find_id_node(id, bdb->bi_tree);
	ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);

	ids[0] = 0;
	ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
	if (prefix == DN_ONE_PREFIX) {
		rc = avl_apply(n->i_kids, insert_one, ids, -1, AVL_INORDER);
	} else {
		ids[0] = 1;
		ids[1] = id;
		if (n->i_kids)
			rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
	}
	ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
	return rc;
}
Ejemplo n.º 9
0
EntryInfo *
bdb_cache_find_info(
	struct bdb_info *bdb,
	ID id )
{
	EntryInfo	ei = { 0 },
			*ei2;

	ei.bei_id = id;

	ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
	ei2 = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree,
					(caddr_t) &ei, bdb_id_cmp );
	ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
	return ei2;
}
Ejemplo n.º 10
0
static int
bdb_cache_entry_rdwr_unlock(Entry *e, int rw)
{
#ifdef NEW_LOGGING
	LDAP_LOG( CACHE, ENTRY, 
		"bdb_cache_entry_rdwr_unlock: remove %s lock on ID %ld.\n",
		rw ? "w" : "r", e->e_id, 0 );
#else
	Debug( LDAP_DEBUG_ARGS, "entry_rdwr_%sunlock: ID: %ld\n",
		rw ? "w" : "r", e->e_id, 0);
#endif

	if (rw)
		return ldap_pvt_thread_rdwr_wunlock(&BEI(e)->bei_rdwr);
	else
		return ldap_pvt_thread_rdwr_runlock(&BEI(e)->bei_rdwr);
}
Ejemplo n.º 11
0
static int
insert_sub(
	void *v_n,
	void *v_ids
)
{
	idNode *n = v_n;
	ID *ids = v_ids;
	int rc;

	rc = bdb_idl_insert(ids, n->i_id);
	if (rc == 0) {
		ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
		rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
		ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
	}
	return rc;
}
Ejemplo n.º 12
0
/* This function constructs a full DN for a given id. We really should
 * be passing idNodes directly, to save some effort...
 */
int bdb_fix_dn(
	BackendDB *be,
	ID id,
	Entry *e
)
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	idNode *n, *o;
	int rlen, nrlen;
	char *ptr, *nptr;
	
	ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
	o = bdb_find_id_node(id, bdb->bi_tree);
	rlen = be->be_suffix[0].bv_len + 1;
	nrlen = be->be_nsuffix[0].bv_len + 1;
	for (n = o; n && n->i_parent; n=n->i_parent) {
		rlen += n->i_rdn->rdn.bv_len + 1;
		nrlen += n->i_rdn->nrdn.bv_len + 1;
	}
	e->e_name.bv_len = rlen - 1;
	e->e_nname.bv_len = nrlen - 1;
	e->e_name.bv_val = ch_malloc(rlen + nrlen);
	e->e_nname.bv_val = e->e_name.bv_val + rlen;
	ptr = e->e_name.bv_val;
	nptr = e->e_nname.bv_val;
	for (n = o; n && n->i_parent; n=n->i_parent) {
		ptr = lutil_strcopy(ptr, n->i_rdn->rdn.bv_val);
		*ptr++ = ',';
		nptr = lutil_strcopy(nptr, n->i_rdn->nrdn.bv_val);
		*nptr++ = ',';
	}
	ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);

	strcpy(ptr, be->be_suffix[0].bv_val);
	strcpy(nptr, be->be_nsuffix[0].bv_val);

	return 0;
}
Ejemplo n.º 13
0
static int
ndb_oc_list( struct ndb_info *ni, const NdbDictionary::Dictionary *myDict,
	struct berval *oname, int implied, NdbOcs *out )
{
	const NdbDictionary::Table *myTable;
	NdbOcInfo *oci, octmp;
	ObjectClass *oc;
	int i, rc;

	/* shortcut top */
	if ( ber_bvstrcasecmp( oname, &slap_schema.si_oc_top->soc_cname )) {
		octmp.no_name = *oname;
		oci = (NdbOcInfo *)avl_find( ni->ni_oc_tree, &octmp, ndb_name_cmp );
		if ( oci ) {
			oc = oci->no_oc;
		} else {
			oc = oc_bvfind( oname );
			if ( !oc ) {
				/* undefined - shouldn't happen */
				return LDAP_INVALID_SYNTAX;
			}
		}
		if ( oc->soc_sups ) {
			int i;

			for ( i=0; oc->soc_sups[i]; i++ ) {
				rc = ndb_oc_list( ni, myDict, &oc->soc_sups[i]->soc_cname, 1, out );
				if ( rc ) return rc;
			}
		}
	} else {
		oc = slap_schema.si_oc_top;
	}
	/* Only insert once */
	for ( i=0; i<out->no_ntext; i++ )
		if ( out->no_text[i].bv_val == oc->soc_cname.bv_val )
			break;
	if ( i == out->no_ntext ) {
		for ( i=0; i<out->no_nitext; i++ )
			if ( out->no_itext[i].bv_val == oc->soc_cname.bv_val )
				break;
		if ( i == out->no_nitext ) {
			if ( implied )
				out->no_itext[out->no_nitext++] = oc->soc_cname;
			else
				out->no_text[out->no_ntext++] = oc->soc_cname;
		}
	}

	/* ignore top, etc... */
	if ( oc->soc_kind == LDAP_SCHEMA_ABSTRACT )
		return 0;

	if ( !oci ) {
		ldap_pvt_thread_rdwr_runlock( &ni->ni_oc_rwlock );
		oci = (NdbOcInfo *)ch_malloc( sizeof( NdbOcInfo )+oc->soc_cname.bv_len+1 );
		oci->no_table.bv_val = (char *)(oci+1);
		strcpy( oci->no_table.bv_val, oc->soc_cname.bv_val );
		oci->no_table.bv_len = oc->soc_cname.bv_len;
		oci->no_name = oci->no_table;
		oci->no_oc = oc;
		oci->no_flag = 0;
		oci->no_nsets = 0;
		oci->no_nattrs = 0;
		ldap_pvt_thread_rdwr_wlock( &ni->ni_oc_rwlock );
		if ( avl_insert( &ni->ni_oc_tree, oci, ndb_name_cmp, ndb_oc_dup_err )) {
			octmp.no_oc = oci->no_oc;
			ch_free( oci );
			oci = (NdbOcInfo *)octmp.no_oc;
		}
		/* see if the oc table already exists in the DB */
		myTable = myDict->getTable( oci->no_table.bv_val );
		rc = ndb_oc_create( ni, oci, myTable == NULL );
		ldap_pvt_thread_rdwr_wunlock( &ni->ni_oc_rwlock );
		ldap_pvt_thread_rdwr_rlock( &ni->ni_oc_rwlock );
		if ( rc ) return rc;
	}
	/* Only insert once */
	for ( i=0; i<out->no_ninfo; i++ )
		if ( out->no_info[i] == oci )
			break;
	if ( i == out->no_ninfo )
		out->no_info[out->no_ninfo++] = oci;
	return 0;
}
Ejemplo n.º 14
0
int
bdb_cache_find_id(
	Operation *op,
	DB_TXN	*tid,
	ID				id,
	EntryInfo	**eip,
	int		flag,
	DB_LOCK		*lock )
{
	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
	Entry	*ep = NULL;
	int	rc = 0, load = 0;
	EntryInfo ei = { 0 };

	ei.bei_id = id;

#ifdef SLAP_ZONE_ALLOC
	slap_zh_rlock(bdb->bi_cache.c_zctx);
#endif
	/* If we weren't given any info, see if we have it already cached */
	if ( !*eip ) {
again:	ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock );
		*eip = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree,
			(caddr_t) &ei, bdb_id_cmp );
		if ( *eip ) {
			/* If the lock attempt fails, the info is in use */
			if ( bdb_cache_entryinfo_trylock( *eip )) {
				int del = (*eip)->bei_state & CACHE_ENTRY_DELETED;
				ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
				/* If this node is being deleted, treat
				 * as if the delete has already finished
				 */
				if ( del ) {
					return DB_NOTFOUND;
				}
				/* otherwise, wait for the info to free up */
				ldap_pvt_thread_yield();
				goto again;
			}
			/* If this info isn't hooked up to its parent yet,
			 * unlock and wait for it to be fully initialized
			 */
			if ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) {
				bdb_cache_entryinfo_unlock( *eip );
				ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
				ldap_pvt_thread_yield();
				goto again;
			}
			flag |= ID_LOCKED;
		}
		ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock );
	}

	/* See if the ID exists in the database; add it to the cache if so */
	if ( !*eip ) {
#ifndef BDB_HIER
		rc = bdb_id2entry( op->o_bd, tid, id, &ep );
		if ( rc == 0 ) {
			rc = bdb_cache_find_ndn( op, tid,
				&ep->e_nname, eip );
			if ( *eip ) flag |= ID_LOCKED;
			if ( rc ) {
				ep->e_private = NULL;
#ifdef SLAP_ZONE_ALLOC
				bdb_entry_return( bdb, ep, (*eip)->bei_zseq );
#else
				bdb_entry_return( ep );
#endif
				ep = NULL;
			}
		}
#else
		rc = hdb_cache_find_parent(op, tid, id, eip );
		if ( rc == 0 ) flag |= ID_LOCKED;
#endif
	}

	/* Ok, we found the info, do we have the entry? */
	if ( rc == 0 ) {
		if ( !( flag & ID_LOCKED )) {
			bdb_cache_entryinfo_lock( *eip );
			flag |= ID_LOCKED;
		}

		if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
			rc = DB_NOTFOUND;
		} else {
			(*eip)->bei_finders++;
			(*eip)->bei_state |= CACHE_ENTRY_REFERENCED;
			if ( flag & ID_NOENTRY ) {
				bdb_cache_entryinfo_unlock( *eip );
				return 0;
			}
			/* Make sure only one thread tries to load the entry */
load1:
#ifdef SLAP_ZONE_ALLOC
			if ((*eip)->bei_e && !slap_zn_validate(
					bdb->bi_cache.c_zctx, (*eip)->bei_e, (*eip)->bei_zseq)) {
				(*eip)->bei_e = NULL;
				(*eip)->bei_zseq = 0;
			}
#endif
			if ( !(*eip)->bei_e && !((*eip)->bei_state & CACHE_ENTRY_LOADING)) {
				load = 1;
				(*eip)->bei_state |= CACHE_ENTRY_LOADING;
				flag |= ID_CHKPURGE;
			}

			if ( !load ) {
				/* Clear the uncached state if we are not
				 * loading it, i.e it is already cached or
				 * another thread is currently loading it.
				 */
				if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) {
					(*eip)->bei_state ^= CACHE_ENTRY_NOT_CACHED;
					flag |= ID_CHKPURGE;
				}
			}

			if ( flag & ID_LOCKED ) {
				bdb_cache_entryinfo_unlock( *eip );
				flag ^= ID_LOCKED;
			}
			rc = bdb_cache_entry_db_lock( bdb, tid, *eip, load, 0, lock );
			if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) {
				rc = DB_NOTFOUND;
				bdb_cache_entry_db_unlock( bdb, lock );
				bdb_cache_entryinfo_lock( *eip );
				(*eip)->bei_finders--;
				bdb_cache_entryinfo_unlock( *eip );
			} else if ( rc == 0 ) {
				if ( load ) {
					if ( !ep) {
						rc = bdb_id2entry( op->o_bd, tid, id, &ep );
					}
					if ( rc == 0 ) {
						ep->e_private = *eip;
#ifdef BDB_HIER
						while ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED )
							ldap_pvt_thread_yield();
						bdb_fix_dn( ep, 0 );
#endif
						bdb_cache_entryinfo_lock( *eip );

						(*eip)->bei_e = ep;
#ifdef SLAP_ZONE_ALLOC
						(*eip)->bei_zseq = *((ber_len_t *)ep - 2);
#endif
						ep = NULL;
						if ( flag & ID_NOCACHE ) {
							/* Set the cached state only if no other thread
							 * found the info while we were loading the entry.
							 */
							if ( (*eip)->bei_finders == 1 ) {
								(*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED;
								flag ^= ID_CHKPURGE;
							}
						}
						bdb_cache_entryinfo_unlock( *eip );
						bdb_cache_lru_link( bdb, *eip );
					}
					if ( rc == 0 ) {
						/* If we succeeded, downgrade back to a readlock. */
						rc = bdb_cache_entry_db_relock( bdb, tid,
							*eip, 0, 0, lock );
					} else {
						/* Otherwise, release the lock. */
						bdb_cache_entry_db_unlock( bdb, lock );
					}
				} else if ( !(*eip)->bei_e ) {
					/* Some other thread is trying to load the entry,
					 * wait for it to finish.
					 */
					bdb_cache_entry_db_unlock( bdb, lock );
					bdb_cache_entryinfo_lock( *eip );
					flag |= ID_LOCKED;
					goto load1;
#ifdef BDB_HIER
				} else {
					/* Check for subtree renames
					 */
					rc = bdb_fix_dn( (*eip)->bei_e, 1 );
					if ( rc ) {
						bdb_cache_entry_db_relock( bdb,
							tid, *eip, 1, 0, lock );
						/* check again in case other modifier did it already */
						if ( bdb_fix_dn( (*eip)->bei_e, 1 ) )
							rc = bdb_fix_dn( (*eip)->bei_e, 2 );
						bdb_cache_entry_db_relock( bdb,
							tid, *eip, 0, 0, lock );
					}
#endif
				}
				bdb_cache_entryinfo_lock( *eip );
				(*eip)->bei_finders--;
				if ( load )
					(*eip)->bei_state ^= CACHE_ENTRY_LOADING;
				bdb_cache_entryinfo_unlock( *eip );
			}
		}
	}
	if ( flag & ID_LOCKED ) {
		bdb_cache_entryinfo_unlock( *eip );
	}
	if ( ep ) {
		ep->e_private = NULL;
#ifdef SLAP_ZONE_ALLOC
		bdb_entry_return( bdb, ep, (*eip)->bei_zseq );
#else
		bdb_entry_return( ep );
#endif
	}
	if ( rc == 0 ) {
		int purge = 0;

		if (( flag & ID_CHKPURGE ) || bdb->bi_cache.c_eimax ) {
			ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
			if ( flag & ID_CHKPURGE ) {
				bdb->bi_cache.c_cursize++;
				if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
					purge = 1;
					bdb->bi_cache.c_purging = 1;
				}
			} else if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) {
				purge = 1;
				bdb->bi_cache.c_purging = 1;
			}
			ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
		}
		if ( purge )
			bdb_cache_lru_purge( bdb );
	}

#ifdef SLAP_ZONE_ALLOC
	if (rc == 0 && (*eip)->bei_e) {
		slap_zn_rlock(bdb->bi_cache.c_zctx, (*eip)->bei_e);
	}
	slap_zh_runlock(bdb->bi_cache.c_zctx);
#endif
	return rc;
}
Ejemplo n.º 15
0
int
ldbm_back_bind(
    Backend		*be,
    Connection		*conn,
    Operation		*op,
    struct berval	*dn,
    struct berval	*ndn,
    int			method,
    struct berval	*cred,
    struct berval	*edn
)
{
	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
	Entry		*e;
	Attribute	*a;
	int		rc;
	Entry		*matched;
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
	char		krbname[MAX_K_NAME_SZ + 1];
	AttributeDescription *krbattr = slap_schema.si_ad_krbName;
	AUTH_DAT	ad;
#endif

	AttributeDescription *password = slap_schema.si_ad_userPassword;

#ifdef NEW_LOGGING
	LDAP_LOG( BACK_LDBM, ENTRY, 
		"ldbm_back_bind: dn: %s.\n", dn->bv_val, 0, 0 );
#else
	Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn->bv_val, 0, 0);
#endif

	dn = ndn;

	/* grab giant lock for reading */
	ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);

	/* get entry with reader lock */
	if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
		char *matched_dn = NULL;
		BerVarray refs = NULL;

		if( matched != NULL ) {
			matched_dn = ch_strdup( matched->e_dn );

			refs = is_entry_referral( matched )
				? get_entry_referrals( be, conn, op, matched )
				: NULL;

			cache_return_entry_r( &li->li_cache, matched );

		} else {
			refs = referral_rewrite( default_referral,
				NULL, dn, LDAP_SCOPE_DEFAULT );
		}

		ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

		/* allow noauth binds */
		rc = 1;
		if ( method == LDAP_AUTH_SIMPLE ) {
			if ( be_isroot_pw( be, conn, dn, cred ) ) {
				ber_dupbv( edn, be_root_dn( be ) );
				rc = 0; /* front end will send result */

			} else if ( refs != NULL ) {
				send_ldap_result( conn, op, LDAP_REFERRAL,
					matched_dn, NULL, refs, NULL );

			} else {
				send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
					NULL, NULL, NULL, NULL );
			}

		} else if ( refs != NULL ) {
			send_ldap_result( conn, op, LDAP_REFERRAL,
				matched_dn, NULL, refs, NULL );

		} else {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
		}

		if ( refs ) ber_bvarray_free( refs );
		if ( matched_dn ) free( matched_dn );
		return( rc );
	}

	ber_dupbv( edn, &e->e_name );

	/* check for deleted */

	if ( is_entry_alias( e ) ) {
		/* entry is an alias, don't allow bind */
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDBM, INFO, 
			"ldbm_back_bind: entry (%s) is an alias.\n", e->e_dn, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
		    0, 0 );
#endif


		send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
		    NULL, "entry is alias", NULL, NULL );

		rc = 1;
		goto return_results;
	}

	if ( is_entry_referral( e ) ) {
		/* entry is a referral, don't allow bind */
		BerVarray refs = get_entry_referrals( be,
			conn, op, e );

#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDBM, INFO, 
			   "ldbm_back_bind: entry(%s) is a referral.\n", e->e_dn, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
		    0, 0 );
#endif


		if( refs != NULL ) {
			send_ldap_result( conn, op, LDAP_REFERRAL,
				e->e_dn, NULL, refs, NULL );

		} else {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
		}

		ber_bvarray_free( refs );

		rc = 1;
		goto return_results;
	}

	switch ( method ) {
	case LDAP_AUTH_SIMPLE:
		/* check for root dn/passwd */
		if ( be_isroot_pw( be, conn, dn, cred ) ) {
			/* front end will send result */
			if(edn->bv_val != NULL) free( edn->bv_val );
			ber_dupbv( edn, be_root_dn( be ) );
			rc = 0;
			goto return_results;
		}

		if ( ! access_allowed( be, conn, op, e,
			password, NULL, ACL_AUTH, NULL ) )
		{
			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
				NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
			send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
			    NULL, NULL, NULL, NULL );

			/* stop front end from sending result */
			rc = 1;
			goto return_results;
		}

		if ( slap_passwd_check( conn, a, cred ) != 0 ) {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
			/* stop front end from sending result */
			rc = 1;
			goto return_results;
		}

		rc = 0;
		break;

#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
	case LDAP_AUTH_KRBV41:
		if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
			    NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		if ( ! access_allowed( be, conn, op, e,
			krbattr, NULL, ACL_AUTH, NULL ) )
		{
			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
				NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
		    : "", ad.pinst, ad.prealm );

		if ( (a = attr_find( e->e_attrs, krbattr )) == NULL ) {
			/*
			 * no krbname values present:  check against DN
			 */
			if ( strcasecmp( dn->bv_val, krbname ) == 0 ) {
				rc = 0;
				break;
			}
			send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
			    NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;

		} else {	/* look for krbname match */
			struct berval	krbval;

			krbval.bv_val = krbname;
			krbval.bv_len = strlen( krbname );

			if ( value_find( a->a_desc, a->a_vals, &krbval ) != 0 ) {
				send_ldap_result( conn, op,
				    LDAP_INVALID_CREDENTIALS,
					NULL, NULL, NULL, NULL );
				rc = 1;
				goto return_results;
			}
		}
		rc = 0;
		break;

	case LDAP_AUTH_KRBV42:
		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
			NULL, "Kerberos bind step 2 not supported",
			NULL, NULL );
		/* stop front end from sending result */
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto return_results;
#endif

	default:
		send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
		    NULL, "authentication method not supported", NULL, NULL );
		rc = 1;
		goto return_results;
	}

return_results:;
	/* free entry and reader lock */
	cache_return_entry_r( &li->li_cache, e );
	ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

	/* front end will send result on success (rc==0) */
	return( rc );
}
Ejemplo n.º 16
0
int
bdb_dn2id_add(
	BackendDB	*be,
	DB_TXN *txn,
	struct berval	*pdn,
	Entry		*e )
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	int		rc, rlen, nrlen;
	DBT		key, data;
	DB *db = bdb->bi_id2parent->bdi_db;
	diskNode *d;
	idNode *n;

	nrlen = dn_rdnlen( be, &e->e_nname );
	if (nrlen) {
		rlen = dn_rdnlen( be, &e->e_name );
	} else {
		rlen = 0;
	}

	d = ch_malloc(sizeof(diskNode) + rlen + nrlen + 2);
	d->rdn.bv_len = rlen;
	d->nrdn.bv_len = nrlen;
	d->rdn.bv_val = (char *)(d+1);
	d->nrdn.bv_val = d->rdn.bv_val + rlen + 1;
	strncpy(d->rdn.bv_val, e->e_dn, rlen);
	d->rdn.bv_val[rlen] = '\0';
	strncpy(d->nrdn.bv_val, e->e_ndn, nrlen);
	d->nrdn.bv_val[nrlen] = '\0';
	d->rdn.bv_val -= (long)d;
	d->nrdn.bv_val -= (long)d;

	if (pdn->bv_len) {
		bdb_dn2id(be, txn, pdn, &d->parent, 0);
	} else {
		d->parent = 0;
	}

	DBTzero(&key);
	DBTzero(&data);
	key.data = &e->e_id;
	key.size = sizeof(ID);
	key.flags = DB_DBT_USERMEM;

	data.data = d;
	data.size = sizeof(diskNode) + rlen + nrlen + 2;
	data.flags = DB_DBT_USERMEM;

	rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );

	if (rc == 0) {
		ldap_pvt_thread_rdwr_wlock(&bdb->bi_tree_rdwr);
		n = bdb_add_node( e->e_id, data.data, bdb);
		ldap_pvt_thread_rdwr_wunlock(&bdb->bi_tree_rdwr);

		if (d->parent) {
			ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
			bdb_insert_kid(n, bdb->bi_tree);
			ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
		}
	} else {
		free(d);
	}
	return rc;
}
Ejemplo n.º 17
0
Entry *
bdb_cache_find_entry_id(
	DB_ENV	*env,
	Cache	*cache,
	ID				id,
	int				rw,
	u_int32_t	locker,
	DB_LOCK		*lock
)
{
	Entry	e;
	Entry	*ep;
	int	count = 0;
	int	rc;

	e.e_id = id;

try_again:
	/* set cache read lock */
	ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );

	if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
	                               entry_id_cmp )) != NULL )
	{
		int state;
		ID	ep_id;

		count++;

		assert( ep->e_private );

		ep_id = ep->e_id; 
		state = BEI(ep)->bei_state;

		/*
		 * entry is deleted or not fully created yet
		 */
		if ( state != CACHE_ENTRY_READY && state != CACHE_ENTRY_COMMITTED ) {

			assert(state != CACHE_ENTRY_UNDEFINED);

			/* free cache read lock */
			ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

#ifdef NEW_LOGGING
			LDAP_LOG( CACHE, INFO, 
				"bdb_cache_find_entry_id: (%ld)->%ld not ready (%d).\n",
				id, ep_id, state );
				   
#else
			Debug(LDAP_DEBUG_TRACE,
				"====> bdb_cache_find_entry_id( %ld ): %ld (not ready) %d\n",
				id, ep_id, state);
#endif

			ldap_pvt_thread_yield();
			goto try_again;
		}

		/* acquire reader lock */
		rc = bdb_cache_entry_db_lock ( env, locker, ep, rw, 0, lock );

#if 0
		if ( bdb_cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) {
#endif

		if ( rc ) { /* will be changed to retry beyond threshold */
			/* could not acquire entry lock...
			 * owner cannot free as we have the cache locked.
			 * so, unlock the cache, yield, and try again.
			 */

			/* free cache read lock */
			ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

#ifdef NEW_LOGGING
			LDAP_LOG( CACHE, INFO, 
				"bdb_cache_find_entry_id: %ld -> %ld (busy) %d.\n",
				id, ep_id, state );
#else
			Debug(LDAP_DEBUG_TRACE,
				"====> bdb_cache_find_entry_id( %ld ): %ld (busy) %d\n",
				id, ep_id, state);
			Debug(LDAP_DEBUG_TRACE,
				"locker = %d\n",
				locker, 0, 0);
#endif

			ldap_pvt_thread_yield();
			goto try_again;
		}

		/* Mark entry in-use */
		BEI(ep)->bei_refcnt++;

		/* free cache read lock */
		ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );
		/* set lru mutex */
		ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
		/* lru */
		LRU_DELETE( cache, ep );
		LRU_ADD( cache, ep );

		/* free lru mutex */
		ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );

#ifdef NEW_LOGGING
		LDAP_LOG( CACHE, DETAIL1, 
			"bdb_cache_find_entry_id: %ld -> %s  found %d tries.\n",
			ep_id, ep->e_dn, count );
#else
		Debug(LDAP_DEBUG_TRACE,
			"====> bdb_cache_find_entry_id( %ld ) \"%s\" (found) (%d tries)\n",
			ep_id, ep->e_dn, count);
#endif


		return( ep );
	}

	/* free cache read lock */
	ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

	return( NULL );
}

/*
 * cache_delete_entry - delete the entry e from the cache.  the caller
 * should have obtained e (increasing its ref count) via a call to one
 * of the cache_find_* routines.  the caller should *not* call the
 * cache_return_entry() routine prior to calling cache_delete_entry().
 * it performs this function.
 *
 * returns:	0	e was deleted ok
 *		1	e was not in the cache
 *		-1	something bad happened
 */
int
bdb_cache_delete_entry(
    Cache	*cache,
    Entry		*e
)
{
	int	rc;

	/* set cache write lock */
	ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock );

	assert( e->e_private );

#ifdef NEW_LOGGING
	LDAP_LOG( CACHE, ENTRY, 
		"bdb_cache_delete_entry: delete %ld.\n", e->e_id, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_delete_entry( %ld )\n",
		e->e_id, 0, 0 );
#endif

	/* set lru mutex */
	ldap_pvt_thread_mutex_lock( &cache->lru_mutex );
	rc = bdb_cache_delete_entry_internal( cache, e );
	/* free lru mutex */
	ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );

	/* free cache write lock */
	ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
	return( rc );
}
Ejemplo n.º 18
0
int ndb_modify_internal(
	Operation *op,
	NdbArgs *NA,
	const char **text,
	char *textbuf,
	size_t textlen )
{
	struct ndb_info *ni = (struct ndb_info *) op->o_bd->be_private;
	Modification	*mod;
	Modifications	*ml;
	Modifications	*modlist = op->orm_modlist;
	NdbAttrInfo **modai, *atmp;
	const NdbDictionary::Dictionary *myDict;
	const NdbDictionary::Table *myTable;
	int got_oc = 0, nmods = 0, nai = 0, i, j;
	int rc, indexed = 0;
	Attribute *old = NULL;

	Debug( LDAP_DEBUG_TRACE, "ndb_modify_internal: 0x%08lx: %s\n",
		NA->e->e_id, NA->e->e_dn, 0);

	if ( !acl_check_modlist( op, NA->e, modlist )) {
		return LDAP_INSUFFICIENT_ACCESS;
	}

	old = attrs_dup( NA->e->e_attrs );

	for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
		mod = &ml->sml_mod;
		nmods++;

		switch ( mod->sm_op ) {
		case LDAP_MOD_ADD:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: add %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
			rc = modify_add_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );
			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
			break;

		case LDAP_MOD_DELETE:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: delete %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
			rc = ndb_modify_delete( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen, NULL );
			assert( rc != LDAP_TYPE_OR_VALUE_EXISTS );
			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
			break;

		case LDAP_MOD_REPLACE:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: replace %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
			rc = modify_replace_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );
			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
			break;

		case LDAP_MOD_INCREMENT:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: increment %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
			rc = modify_increment_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );
			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS,
					"ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
			break;

		case SLAP_MOD_SOFTADD:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: softadd %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
 			mod->sm_op = LDAP_MOD_ADD;

			rc = modify_add_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );

 			mod->sm_op = SLAP_MOD_SOFTADD;

 			if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
 				rc = LDAP_SUCCESS;
 			}

			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
 			break;

		case SLAP_MOD_SOFTDEL:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: softdel %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
 			mod->sm_op = LDAP_MOD_DELETE;

			rc = modify_delete_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );

 			mod->sm_op = SLAP_MOD_SOFTDEL;

 			if ( rc == LDAP_NO_SUCH_ATTRIBUTE) {
 				rc = LDAP_SUCCESS;
 			}

			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
 			break;

		case SLAP_MOD_ADD_IF_NOT_PRESENT:
			Debug(LDAP_DEBUG_ARGS,
				"ndb_modify_internal: add_if_not_present %s\n",
				mod->sm_desc->ad_cname.bv_val, 0, 0);
			if ( attr_find( NA->e->e_attrs, mod->sm_desc ) ) {
				rc = LDAP_SUCCESS;
				break;
			}

 			mod->sm_op = LDAP_MOD_ADD;

			rc = modify_add_values( NA->e, mod, get_permissiveModify(op),
				text, textbuf, textlen );

 			mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;

			if( rc != LDAP_SUCCESS ) {
				Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
					rc, *text, 0);
			}
 			break;

		default:
			Debug(LDAP_DEBUG_ANY, "ndb_modify_internal: invalid op %d\n",
				mod->sm_op, 0, 0);
			*text = "Invalid modify operation";
			rc = LDAP_OTHER;
			Debug(LDAP_DEBUG_ARGS, "ndb_modify_internal: %d %s\n",
				rc, *text, 0);
		}

		if ( rc != LDAP_SUCCESS ) {
			attrs_free( old );
			return rc; 
		}

		/* If objectClass was modified, reset the flags */
		if ( mod->sm_desc == slap_schema.si_ad_objectClass ) {
			NA->e->e_ocflags = 0;
			got_oc = 1;
		}
	}

	/* check that the entry still obeys the schema */
	rc = entry_schema_check( op, NA->e, NULL, get_relax(op), 0, NULL,
		text, textbuf, textlen );
	if ( rc != LDAP_SUCCESS || op->o_noop ) {
		if ( rc != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY,
				"entry failed schema check: %s\n",
				*text, 0, 0 );
		}
		attrs_free( old );
		return rc;
	}

	if ( got_oc ) {
		rc = ndb_entry_put_info( op->o_bd, NA, 1 );
		if ( rc ) {
			attrs_free( old );
			return rc;
		}
	}

	/* apply modifications to DB */
	modai = (NdbAttrInfo **)op->o_tmpalloc( nmods * sizeof(NdbAttrInfo*), op->o_tmpmemctx );

	/* Get the unique list of modified attributes */
	ldap_pvt_thread_rdwr_rlock( &ni->ni_ai_rwlock );
	for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
		/* Already took care of objectclass */
		if ( ml->sml_desc == slap_schema.si_ad_objectClass )
			continue;
		for ( i=0; i<nai; i++ ) {
			if ( ml->sml_desc->ad_type == modai[i]->na_attr )
				break;
		}
		/* This attr was already updated */
		if ( i < nai )
			continue;
		modai[nai] = ndb_ai_find( ni, ml->sml_desc->ad_type );
		if ( modai[nai]->na_flag & NDB_INFO_INDEX )
			indexed++;
		nai++;
	}
	ldap_pvt_thread_rdwr_runlock( &ni->ni_ai_rwlock );

	/* If got_oc, this was already done above */
	if ( indexed && !got_oc) {
		rc = ndb_entry_put_info( op->o_bd, NA, 1 );
		if ( rc ) {
			attrs_free( old );
			return rc;
		}
	}

	myDict = NA->ndb->getDictionary();

	/* sort modai so that OcInfo's are contiguous */
	{
		int j, k;
		for ( i=0; i<nai; i++ ) {
			for ( j=i+1; j<nai; j++ ) {
				if ( modai[i]->na_oi == modai[j]->na_oi )
					continue;
				for ( k=j+1; k<nai; k++ ) {
					if ( modai[i]->na_oi == modai[k]->na_oi ) {
						atmp = modai[j];
						modai[j] = modai[k];
						modai[k] = atmp;
						break;
					}
				}
				/* there are no more na_oi's that match modai[i] */
				if ( k == nai ) {
					i = j;
				}
			}
		}
	}

	/* One call per table... */
	for ( i=0; i<nai; i += j ) {
		atmp = modai[i];
		for ( j=i+1; j<nai; j++ )
			if ( atmp->na_oi != modai[j]->na_oi )
				break;
		j -= i;
		myTable = myDict->getTable( atmp->na_oi->no_table.bv_val );
		if ( !myTable )
			continue;
		rc = ndb_oc_attrs( NA->txn, myTable, NA->e, atmp->na_oi, &modai[i], j, old );
		if ( rc ) break;
	}
	attrs_free( old );
	return rc;
}
Ejemplo n.º 19
0
int
ldbm_back_compare(
    Backend	*be,
    Connection	*conn,
    Operation	*op,
    struct berval	*dn,
    struct berval	*ndn,
    AttributeAssertion *ava
)
{
    struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
    Entry		*matched;
    Entry		*e;
    Attribute	*a;
    int		rc;
    int		manageDSAit = get_manageDSAit( op );

    /* grab giant lock for reading */
    ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);

    /* get entry with reader lock */
    if ( (e = dn2entry_r( be, ndn, &matched )) == NULL ) {
        char *matched_dn = NULL;
        BerVarray refs = NULL;

        if ( matched != NULL ) {
            matched_dn = ch_strdup( matched->e_dn );
            refs = is_entry_referral( matched )
                   ? get_entry_referrals( be, conn, op, matched )
                   : NULL;
            cache_return_entry_r( &li->li_cache, matched );
        } else {
            refs = referral_rewrite( default_referral,
                                     NULL, dn, LDAP_SCOPE_DEFAULT );
        }

        ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

        send_ldap_result( conn, op, LDAP_REFERRAL,
                          matched_dn, NULL, refs, NULL );

        if ( refs ) ber_bvarray_free( refs );
        free( matched_dn );

        return( 1 );
    }

    if (!manageDSAit && is_entry_referral( e ) ) {
        /* entry is a referral, don't allow add */
        BerVarray refs = get_entry_referrals( be,
                                              conn, op, e );

#ifdef NEW_LOGGING
        LDAP_LOG( BACK_LDBM, INFO,
                  "ldbm_back_compare: entry (%s) is a referral.\n", e->e_dn, 0, 0 );
#else
        Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
               0, 0 );
#endif


        send_ldap_result( conn, op, LDAP_REFERRAL,
                          e->e_dn, NULL, refs, NULL );

        if (refs ) ber_bvarray_free( refs );

        rc = 1;
        goto return_results;
    }

    if ( ! access_allowed( be, conn, op, e,
                           ava->aa_desc, &ava->aa_value, ACL_COMPARE, NULL ) )
    {
        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
                          NULL, NULL, NULL, NULL );
        rc = 1;
        goto return_results;
    }

    rc = LDAP_NO_SUCH_ATTRIBUTE;

    for(a = attrs_find( e->e_attrs, ava->aa_desc );
            a != NULL;
            a = attrs_find( a->a_next, ava->aa_desc ))
    {
        rc = LDAP_COMPARE_FALSE;

        if ( value_find( ava->aa_desc, a->a_vals, &ava->aa_value ) == 0 ) {
            rc = LDAP_COMPARE_TRUE;
            break;
        }
    }

    send_ldap_result( conn, op, rc,
                      NULL, NULL, NULL, NULL );

    if( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
        rc = 0;
    }


return_results:
    ;
    cache_return_entry_r( &li->li_cache, e );
    ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
    return( rc );
}
Ejemplo n.º 20
0
int
ldbm_back_referrals(
    Backend	*be,
    Connection	*conn,
    Operation	*op,
    struct berval *dn,
    struct berval *ndn,
	const char **text )
{
	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
	int rc = LDAP_SUCCESS;
	Entry *e, *matched;

	if( op->o_tag == LDAP_REQ_SEARCH ) {
		/* let search take care of itself */
		return rc;
	}

	if( get_manageDSAit( op ) ) {
		/* let op take care of DSA management */
		return rc;
	} 

	/* grab giant lock for reading */
	ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);

	/* get entry with reader lock */
	e = dn2entry_r( be, ndn, &matched );
	if ( e == NULL ) {
		char *matched_dn = NULL;
		BerVarray refs = NULL;

		if ( matched != NULL ) {
			matched_dn = ch_strdup( matched->e_dn );

#ifdef NEW_LOGGING
			LDAP_LOG( BACK_LDBM, DETAIL1,
				"ldbm_back_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
				op->o_tag, dn->bv_val, matched_dn );
#else
			Debug( LDAP_DEBUG_TRACE,
				"ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
				op->o_tag, dn->bv_val, matched_dn );
#endif

			if( is_entry_referral( matched ) ) {
				rc = LDAP_OTHER;
				refs = get_entry_referrals( be, conn, op, matched );
			}

			cache_return_entry_r( &li->li_cache, matched );

		} else if ( default_referral != NULL ) {
			rc = LDAP_OTHER;
			refs = referral_rewrite( default_referral,
				NULL, dn, LDAP_SCOPE_DEFAULT );
		}

		ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

		if( refs != NULL ) {
			/* send referrals */
			send_ldap_result( conn, op, rc = LDAP_REFERRAL,
				matched_dn, NULL, refs, NULL );
			ber_bvarray_free( refs );

		} else if ( rc != LDAP_SUCCESS ) {
			send_ldap_result( conn, op, rc, matched_dn,
				matched_dn ? "bad referral object" : "bad default referral",
				NULL, NULL );
		}

		if ( matched_dn ) free( matched_dn );
		return rc;
	}

	if ( is_entry_referral( e ) ) {
		/* entry is a referral */
		BerVarray refs = get_entry_referrals( be, conn, op, e );
		BerVarray rrefs = referral_rewrite(
			refs, &e->e_name, dn, LDAP_SCOPE_DEFAULT );

#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDBM, DETAIL1,
			"ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
			op->o_tag, dn->bv_val, e->e_dn );
#else
		Debug( LDAP_DEBUG_TRACE,
			"ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
			op->o_tag, dn->bv_val, e->e_dn );
#endif

		if( rrefs != NULL ) {
			send_ldap_result( conn, op, rc = LDAP_REFERRAL,
				e->e_dn, NULL, rrefs, NULL );

			ber_bvarray_free( rrefs );

		} else {
			send_ldap_result( conn, op, rc = LDAP_OTHER, e->e_dn,
				"bad referral object", NULL, NULL );
		}

		if( refs != NULL ) ber_bvarray_free( refs );
	}

	cache_return_entry_r( &li->li_cache, e );
	ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

	return rc;
}
Ejemplo n.º 21
0
ID
bdb_cache_find_entry_ndn2id(
	Backend		*be,
    Cache	*cache,
    struct berval	*ndn
)
{
	Entry		e, *ep;
	ID			id;
	int count = 0;

	/* this function is always called with normalized DN */
	e.e_nname = *ndn;

try_again:
	/* set cache read lock */
	ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );

	if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
	                               entry_dn_cmp )) != NULL )
	{
		int state;
		count++;

		/*
		 * ep now points to an unlocked entry
		 * we do not need to lock the entry if we only
		 * check the state, refcnt, LRU, and id.
		 */

		assert( ep->e_private );

		/* save id */
		id = ep->e_id;
		state = BEI(ep)->bei_state;

		/*
		 * entry is deleted or not fully created yet
		 */
		if ( state != CACHE_ENTRY_READY && state != CACHE_ENTRY_COMMITTED ) {
			assert(state != CACHE_ENTRY_UNDEFINED);

			/* free cache read lock */
			ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

#ifdef NEW_LOGGING
			LDAP_LOG( CACHE, INFO, 
				"bdb_cache_find_entry_dn2id: (%s) %ld not ready: %d\n",
				ndn->bv_val, id, state );
#else
			Debug(LDAP_DEBUG_TRACE,
				"====> bdb_cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n",
				ndn->bv_val, id, state);
#endif


			ldap_pvt_thread_yield();
			goto try_again;
		}

		/* free cache read lock */
		ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

		/* set lru mutex */
		ldap_pvt_thread_mutex_lock( &cache->lru_mutex );

		/* lru */
		LRU_DELETE( cache, ep );
		LRU_ADD( cache, ep );
		
		/* free lru mutex */
		ldap_pvt_thread_mutex_unlock( &cache->lru_mutex );

#ifdef NEW_LOGGING
		LDAP_LOG( CACHE, DETAIL1, 
			"bdb_cache_find_entry_dn2id: (%s): %ld %d tries\n",
			ndn->bv_val, id, count );
#else
		Debug(LDAP_DEBUG_TRACE,
			"====> bdb_cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n",
			ndn->bv_val, id, count);
#endif

	} else {
		/* free cache read lock */
		ldap_pvt_thread_rdwr_runlock( &cache->c_rwlock );

		id = NOID;
	}

	return( id );
}