예제 #1
0
static int
distproc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
{
	CfEntryInfo	*pe = p->e_private;
	slap_overinst	*on = (slap_overinst *)pe->ce_bi;
	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;
	void		*priv = (void *)ca->be->be_private;

	if ( lback->bi_cf_ocs ) {
		ldap_distproc_cfadd_apply_t	lca = { 0 };

		lca.op = op;
		lca.rs = rs;
		lca.p = p;
		lca.ca = ca;
		lca.count = 0;

		(void)ldap_distproc_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca );

		(void)avl_apply( lc->lc_lai.lai_tree, ldap_distproc_cfadd_apply,
			&lca, 1, AVL_INORDER );

		ca->be->be_private = priv;
	}

	return 0;
}
예제 #2
0
파일: ch_malloc.c 프로젝트: leto/389-ds
void
slapi_ch_stop_recording()
{
#if defined(_WIN32) && defined(DEBUG)
    PR_Lock( mr_tree_lock );
	recording= 0;
    avl_apply( mr_tree, memory_record_dump, NULL, STOP_TRAVERSAL, AVL_INORDER );
    avl_free( mr_tree, memory_record_delete );
	mr_tree= NULL;
    PR_Unlock( mr_tree_lock );
#endif
}
예제 #3
0
파일: tools.c 프로젝트: rouzier/openldap
static int
bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic )
{
	Avlnode *root = db->app_private;
	int rc;

	db->app_private = ic;
	rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER );
	avl_free( root, NULL );
	db->app_private = NULL;
	if ( rc != -1 )
		rc = 0;
	return rc;
}
예제 #4
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;
}
예제 #5
0
파일: avl.c 프로젝트: cptaffe/openldap
void*
avl_getfirst( Avlnode *root )
{
	if ( avl_list ) {
		ber_memfree( (char *) avl_list);
		avl_list = (void* *) 0;
	}
	avl_maxlist = 0;
	avl_nextlist = 0;

	if ( root == 0 )
		return( 0 );

	(void) avl_apply( root, avl_buildlist, (void*) 0, -1, AVL_INORDER );

	return( avl_list[ avl_nextlist++ ] );
}
예제 #6
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;
}
예제 #7
0
파일: avl.c 프로젝트: Firstyear/ds
caddr_t
avl_getfirst( Avlnode *root )
{
	if ( avl_list ) {
		free( (char *) avl_list);
		avl_list = (caddr_t *) 0;
	}
	avl_maxlist = 0;
	avl_nextlist = 0;

	if ( root == 0 )
		return( 0 );

	(void) avl_apply( root, avl_buildlist, (caddr_t) 0, -1, AVL_INORDER );
	if(avl_list && avl_list[avl_nextlist++]){
		return avl_list[avl_nextlist];
	} else {
		return( NULL );
	}
}
예제 #8
0
static int
ldap_distproc_db_func(
	BackendDB *be,
	enum db_which which
)
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	ldap_distproc_t	*lc = (ldap_distproc_t *)on->on_bi.bi_private;

	int		rc = 0;

	if ( lc ) {
		BI_db_func	*func = (&lback->bi_db_open)[ which ];

		if ( func != NULL && lc->lc_common_li != NULL ) {
			BackendDB		db = *be;

			db.bd_info = lback;
			db.be_private = lc->lc_common_li;

			rc = func( &db, NULL );

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

			if ( lc->lc_lai.lai_tree != NULL ) {
				ldap_distproc_db_apply_t	lca;

				lca.be = &db;
				lca.func = func;

				rc = avl_apply( lc->lc_lai.lai_tree,
					ldap_distproc_db_apply, (void *)&lca,
					1, AVL_INORDER ) != AVL_NOMORE;
			}
		}
	}

	return rc;
}
예제 #9
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;
}
예제 #10
0
파일: delete.c 프로젝트: cptaffe/openldap
static int
backsql_delete_all_attrs(
	Operation 		*op,
	SlapReply		*rs,
	SQLHDBC			dbh, 
	backsql_entryID		*eid )
{
	backsql_delete_attr_t	bda;
	int			rc;

	bda.op = op;
	bda.rs = rs;
	bda.dbh = dbh;
	bda.e_id = eid;
	
	rc = avl_apply( eid->eid_oc->bom_attrs, backsql_delete_attr_f, &bda,
			BACKSQL_AVL_STOP, AVL_INORDER );
	if ( rc == BACKSQL_AVL_STOP ) {
		return rs->sr_err;
	}

	return LDAP_SUCCESS;
}
예제 #11
0
/* This function initializes the trees at startup time. */
int bdb_build_tree(
	Backend *be
)
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	int rc;
	DBC *cursor;
	DBT key, data;
	ID id;
	idNode *node;

	bdb->bi_tree = NULL;

	rc = bdb->bi_id2parent->bdi_db->cursor(
		bdb->bi_id2parent->bdi_db, NULL, &cursor,
		bdb->bi_db_opflags );
	if( rc != 0 ) {
		return NOID;
	}

	DBTzero( &key );
	DBTzero( &data );
	key.data = (char *)&id;
	key.ulen = sizeof( id );
	key.flags = DB_DBT_USERMEM;
	data.flags = DB_DBT_MALLOC;

	while (cursor->c_get( cursor, &key, &data, DB_NEXT ) == 0) {
		bdb_add_node( id, data.data, bdb );
	}
	cursor->c_close( cursor );

	rc = avl_apply(bdb->bi_tree, bdb_insert_kid, bdb->bi_tree,
		-1, AVL_INORDER );

	return rc;
}
예제 #12
0
파일: dn2id.c 프로젝트: cptaffe/openldap
static int
hdb_dn2idl_internal(
	struct dn2id_cookie *cx
)
{
	BDB_IDL_ZERO( cx->tmp );

	if ( cx->bdb->bi_idl_cache_size ) {
		char *ptr = ((char *)&cx->id)-1;

		cx->key.data = ptr;
		cx->key.size = sizeof(ID)+1;
		if ( cx->prefix == DN_SUBTREE_PREFIX ) {
			ID *ids = cx->depth ? cx->tmp : cx->ids;
			*ptr = cx->prefix;
			cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, ids);
			if ( cx->rc == LDAP_SUCCESS ) {
				if ( cx->depth ) {
					bdb_idl_delete( cx->tmp, cx->id );	/* ITS#6983, drop our own ID */
					bdb_idl_append( cx->ids, cx->tmp );
					cx->need_sort = 1;
				}
				return cx->rc;
			}
		}
		*ptr = DN_ONE_PREFIX;
		cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp);
		if ( cx->rc == LDAP_SUCCESS ) {
			goto gotit;
		}
		if ( cx->rc == DB_NOTFOUND ) {
			return cx->rc;
		}
	}

	bdb_cache_entryinfo_lock( cx->ei );

	/* If number of kids in the cache differs from on-disk, load
	 * up all the kids from the database
	 */
	if ( cx->ei->bei_ckids+1 != cx->ei->bei_dkids ) {
		EntryInfo ei;
		db_recno_t dkids = cx->ei->bei_dkids;
		ei.bei_parent = cx->ei;

		/* Only one thread should load the cache */
		while ( cx->ei->bei_state & CACHE_ENTRY_ONELEVEL ) {
			bdb_cache_entryinfo_unlock( cx->ei );
			ldap_pvt_thread_yield();
			bdb_cache_entryinfo_lock( cx->ei );
			if ( cx->ei->bei_ckids+1 == cx->ei->bei_dkids ) {
				goto synced;
			}
		}

		cx->ei->bei_state |= CACHE_ENTRY_ONELEVEL;

		bdb_cache_entryinfo_unlock( cx->ei );

		cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc,
			cx->bdb->bi_db_opflags );
		if ( cx->rc )
			goto done_one;

		cx->data.data = &cx->dbuf;
		cx->data.ulen = sizeof(ID);
		cx->data.dlen = sizeof(ID);
		cx->data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;

		/* The first item holds the parent ID. Ignore it. */
		cx->key.data = &cx->nid;
		cx->key.size = sizeof(ID);
		cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET );
		if ( cx->rc ) {
			cx->dbc->c_close( cx->dbc );
			goto done_one;
		}

		/* If the on-disk count is zero we've never checked it.
		 * Count it now.
		 */
		if ( !dkids ) {
			cx->dbc->c_count( cx->dbc, &dkids, 0 );
			cx->ei->bei_dkids = dkids;
		}

		cx->data.data = cx->buf;
		cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID);
		cx->data.flags = DB_DBT_USERMEM;

		if ( dkids > 1 ) {
			/* Fetch the rest of the IDs in a loop... */
			while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data,
				DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) {
				u_int8_t *j;
				size_t len;
				void *ptr;
				DB_MULTIPLE_INIT( ptr, &cx->data );
				while (ptr) {
					DB_MULTIPLE_NEXT( ptr, &cx->data, j, len );
					if (j) {
						EntryInfo *ei2;
						diskNode *d = (diskNode *)j;
						short nrlen;

						BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id );
						nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1];
						ei.bei_nrdn.bv_len = nrlen;
						/* nrdn/rdn are set in-place.
						 * hdb_cache_load will copy them as needed
						 */
						ei.bei_nrdn.bv_val = d->nrdn;
						ei.bei_rdn.bv_len = len - sizeof(diskNode)
							- ei.bei_nrdn.bv_len;
						ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1;
						bdb_idl_append_one( cx->tmp, ei.bei_id );
						hdb_cache_load( cx->bdb, &ei, &ei2 );
					}
				}
			}
		}

		cx->rc = cx->dbc->c_close( cx->dbc );
done_one:
		bdb_cache_entryinfo_lock( cx->ei );
		cx->ei->bei_state &= ~CACHE_ENTRY_ONELEVEL;
		bdb_cache_entryinfo_unlock( cx->ei );
		if ( cx->rc )
			return cx->rc;

	} else {
		/* The in-memory cache is in sync with the on-disk data.
		 * do we have any kids?
		 */
synced:
		cx->rc = 0;
		if ( cx->ei->bei_ckids > 0 ) {
			/* Walk the kids tree; order is irrelevant since bdb_idl_sort
			 * will sort it later.
			 */
			avl_apply( cx->ei->bei_kids, apply_func,
				cx->tmp, -1, AVL_POSTORDER );
		}
		bdb_cache_entryinfo_unlock( cx->ei );
	}

	if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 )
		bdb_idl_sort( cx->tmp, cx->buf );
	if ( cx->bdb->bi_idl_cache_max_size && !BDB_IDL_IS_ZERO( cx->tmp )) {
		char *ptr = ((char *)&cx->id)-1;
		cx->key.data = ptr;
		cx->key.size = sizeof(ID)+1;
		*ptr = DN_ONE_PREFIX;
		bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc );
	}

gotit:
	if ( !BDB_IDL_IS_ZERO( cx->tmp )) {
		if ( cx->prefix == DN_SUBTREE_PREFIX ) {
			bdb_idl_append( cx->ids, cx->tmp );
			cx->need_sort = 1;
			if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) {
				ID *save, idcurs;
				EntryInfo *ei = cx->ei;
				int nokids = 1;
				save = cx->op->o_tmpalloc( BDB_IDL_SIZEOF( cx->tmp ),
					cx->op->o_tmpmemctx );
				BDB_IDL_CPY( save, cx->tmp );

				idcurs = 0;
				cx->depth++;
				for ( cx->id = bdb_idl_first( save, &idcurs );
					cx->id != NOID;
					cx->id = bdb_idl_next( save, &idcurs )) {
					EntryInfo *ei2;
					cx->ei = NULL;
					if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei,
						ID_NOENTRY, NULL ))
						continue;
					if ( cx->ei ) {
						ei2 = cx->ei;
						if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) {
							BDB_ID2DISK( cx->id, &cx->nid );
							hdb_dn2idl_internal( cx );
							if ( !BDB_IDL_IS_ZERO( cx->tmp ))
								nokids = 0;
						}
						bdb_cache_entryinfo_lock( ei2 );
						ei2->bei_finders--;
						bdb_cache_entryinfo_unlock( ei2 );
					}
				}
				cx->depth--;
				cx->op->o_tmpfree( save, cx->op->o_tmpmemctx );
				if ( nokids ) {
					bdb_cache_entryinfo_lock( ei );
					ei->bei_state |= CACHE_ENTRY_NO_GRANDKIDS;
					bdb_cache_entryinfo_unlock( ei );
				}
			}
			/* Make sure caller knows it had kids! */
			cx->tmp[0]=1;

			cx->rc = 0;
		} else {
			BDB_IDL_CPY( cx->ids, cx->tmp );
		}
	}
	return cx->rc;
}
예제 #13
0
int
backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
{
	Operation		*op = bsi->bsi_op;
	backsql_info		*bi = (backsql_info *)op->o_bd->be_private;
	int			i;
	int			rc;

	Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );

	assert( bsi->bsi_e != NULL );

	memset( bsi->bsi_e, 0, sizeof( Entry ) );

	if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
		Entry	*e;

		e = entry_dup( bi->sql_baseObject );
		if ( e == NULL ) {
			return LDAP_NO_MEMORY;
		}
			
		*bsi->bsi_e = *e;
		free( e );
		goto done;
	}

	ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx );
	ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx );

	bsi->bsi_e->e_attrs = NULL;
	bsi->bsi_e->e_private = NULL;

	if ( eid->eid_oc == NULL ) {
		eid->eid_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private,
			eid->eid_oc_id );
	}
	bsi->bsi_oc = eid->eid_oc;
	bsi->bsi_c_eid = eid;

#ifndef BACKSQL_ARBITRARY_KEY	
	/* FIXME: unused */
	bsi->bsi_e->e_id = eid->eid_id;
#endif /* ! BACKSQL_ARBITRARY_KEY */
 
	rc = attr_merge_normalize_one( bsi->bsi_e,
			slap_schema.si_ad_objectClass,
			&bsi->bsi_oc->bom_oc->soc_cname,
			bsi->bsi_op->o_tmpmemctx );
	if ( rc != LDAP_SUCCESS ) {
		backsql_entry_clean( op, bsi->bsi_e );
		return rc;
	}

	if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) )
	{
		Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
			"retrieving all attributes\n", 0, 0, 0 );
		avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals,
				bsi, 0, AVL_INORDER );

	} else {
		Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
			"custom attribute list\n", 0, 0, 0 );
		for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) {
			backsql_at_map_rec	**vat;
			AttributeName		*an = &bsi->bsi_attrs[ i ];
			int			j;

			/* if one of the attributes listed here is
			 * a subtype of another, it must be ignored,
			 * because subtypes are already dealt with
			 * by backsql_supad2at()
			 */
			for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) {
				/* skip self */
				if ( j == i ) {
					continue;
				}

				/* skip subtypes */
				if ( is_at_subtype( an->an_desc->ad_type,
							bsi->bsi_attrs[ j ].an_desc->ad_type ) )
				{
					goto next;
				}
			}

			rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat );
			if ( rc != 0 || vat == NULL ) {
				Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
						"attribute \"%s\" is not defined "
						"for objectlass \"%s\"\n",
						an->an_name.bv_val, 
						BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
				continue;
			}

			for ( j = 0; vat[j]; j++ ) {
    				backsql_get_attr_vals( vat[j], bsi );
			}

			ch_free( vat );

next:;
		}
	}

	if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) {
		Attribute	*a_entryUUID,
				**ap;

		a_entryUUID = backsql_operational_entryUUID( bi, eid );
		if ( a_entryUUID != NULL ) {
			for ( ap = &bsi->bsi_e->e_attrs; 
					*ap; 
					ap = &(*ap)->a_next );

			*ap = a_entryUUID;
		}
	}

	if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER )
			|| an_find( bsi->bsi_attrs, slap_bv_all_operational_attrs )
			|| an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) )
	{
		ObjectClass	*soc = NULL;

		if ( BACKSQL_CHECK_SCHEMA( bi ) ) {
			Attribute	*a;
			const char	*text = NULL;
			char		textbuf[ 1024 ];
			size_t		textlen = sizeof( textbuf );
			struct berval	bv[ 2 ],
					*nvals;
			int		rc = LDAP_SUCCESS;

			a = attr_find( bsi->bsi_e->e_attrs,
					slap_schema.si_ad_objectClass );
			if ( a != NULL ) {
				nvals = a->a_nvals;

			} else {
				bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname;
				BER_BVZERO( &bv[ 1 ] );
				nvals = bv;
			}

			rc = structural_class( nvals, &soc, NULL, 
					&text, textbuf, textlen, op->o_tmpmemctx );
			if ( rc != LDAP_SUCCESS ) {
      				Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
					"structural_class() failed %d (%s)\n",
					bsi->bsi_e->e_name.bv_val,
					rc, text ? text : "" );
				backsql_entry_clean( op, bsi->bsi_e );
				return rc;
			}

			if ( !bvmatch( &soc->soc_cname, &bsi->bsi_oc->bom_oc->soc_cname ) ) {
				if ( !is_object_subclass( bsi->bsi_oc->bom_oc, soc ) ) {
					Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
						"computed structuralObjectClass %s "
						"does not match objectClass %s associated "
						"to entry\n",
						bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val,
						bsi->bsi_oc->bom_oc->soc_cname.bv_val );
					backsql_entry_clean( op, bsi->bsi_e );
					return rc;
				}

      				Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): "
					"computed structuralObjectClass %s "
					"is subclass of objectClass %s associated "
					"to entry\n",
					bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val,
					bsi->bsi_oc->bom_oc->soc_cname.bv_val );
			}

		} else {
			soc = bsi->bsi_oc->bom_oc;
		}

		rc = attr_merge_normalize_one( bsi->bsi_e,
				slap_schema.si_ad_structuralObjectClass,
				&soc->soc_cname,
				bsi->bsi_op->o_tmpmemctx );
		if ( rc != LDAP_SUCCESS ) {
			backsql_entry_clean( op, bsi->bsi_e );
			return rc;
		}
	}

done:;
	Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );

	return LDAP_SUCCESS;
}