Пример #1
0
Entry *
monitor_entry_stub(
	struct berval *pdn,
	struct berval *pndn,
	struct berval *rdn,
	ObjectClass *oc,
	struct berval *create,
	struct berval *modify
)
{
	monitor_info_t *mi;
	AttributeDescription *nad = NULL;
	Entry *e;
	struct berval nat;
	char *ptr;
	const char *text;
	int rc;

	mi = ( monitor_info_t * )be_monitor->be_private;

	nat = *rdn;
	ptr = strchr( nat.bv_val, '=' );
	nat.bv_len = ptr - nat.bv_val;
	rc = slap_bv2ad( &nat, &nad, &text );
	if ( rc )
		return NULL;

	e = entry_alloc();
	if ( e ) {
		struct berval nrdn;

		rdnNormalize( 0, NULL, NULL, rdn, &nrdn, NULL );
		build_new_dn( &e->e_name, pdn, rdn, NULL );
		build_new_dn( &e->e_nname, pndn, &nrdn, NULL );
		ber_memfree( nrdn.bv_val );
		nat.bv_val = ptr + 1;
		nat.bv_len = rdn->bv_len - ( nat.bv_val - rdn->bv_val );
		attr_merge_normalize_one( e, slap_schema.si_ad_objectClass,
			&oc->soc_cname, NULL );
		attr_merge_normalize_one( e, slap_schema.si_ad_structuralObjectClass,
			&oc->soc_cname, NULL );
		attr_merge_normalize_one( e, nad, &nat, NULL );
		attr_merge_one( e, slap_schema.si_ad_creatorsName, &mi->mi_creatorsName,
			&mi->mi_ncreatorsName );
		attr_merge_one( e, slap_schema.si_ad_modifiersName, &mi->mi_creatorsName,
			&mi->mi_ncreatorsName );
		attr_merge_normalize_one( e, slap_schema.si_ad_createTimestamp,
			create ? create : &mi->mi_startTime, NULL );
		attr_merge_normalize_one( e, slap_schema.si_ad_modifyTimestamp,
			modify ? modify : &mi->mi_startTime, NULL );
	}
	return e;
}
Пример #2
0
void glue_parent(Operation *op) {
	Operation nop = *op;
	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
	struct berval ndn = BER_BVNULL;
	Attribute *a;
	Entry *e;
	struct berval	pdn;

	dnParent( &op->o_req_ndn, &pdn );
	ber_dupbv_x( &ndn, &pdn, op->o_tmpmemctx );

	Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", ndn.bv_val, 0, 0);

	e = entry_alloc();
	e->e_id = NOID;
	ber_dupbv(&e->e_name, &ndn);
	ber_dupbv(&e->e_nname, &ndn);

	a = attr_alloc( slap_schema.si_ad_objectClass );
	a->a_numvals = 2;
	a->a_vals = ch_malloc(sizeof(struct berval) * 3);
	ber_dupbv(&a->a_vals[0], &glue[0]);
	ber_dupbv(&a->a_vals[1], &glue[1]);
	ber_dupbv(&a->a_vals[2], &glue[2]);
	a->a_nvals = a->a_vals;
	a->a_next = e->e_attrs;
	e->e_attrs = a;

	a = attr_alloc( slap_schema.si_ad_structuralObjectClass );
	a->a_numvals = 1;
	a->a_vals = ch_malloc(sizeof(struct berval) * 2);
	ber_dupbv(&a->a_vals[0], &glue[1]);
	ber_dupbv(&a->a_vals[1], &glue[2]);
	a->a_nvals = a->a_vals;
	a->a_next = e->e_attrs;
	e->e_attrs = a;

	nop.o_req_dn = ndn;
	nop.o_req_ndn = ndn;
	nop.ora_e = e;

	nop.o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
	syncrepl_add_glue(&nop, e);
	nop.o_bd->bd_info = (BackendInfo *) on;

	op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );

	return;
}
Пример #3
0
int hash_map_add(struct hash_map_t *self_p,
                 long key,
                 void *value_p)
{
    ASSERTN(self_p != NULL, EINVAL);
    ASSERTN(value_p != NULL, EINVAL);

    int hash;
    struct hash_map_bucket_t *bucket_p;
    struct hash_map_entry_t *entry_p;

    /* Hash key. */
    hash = self_p->hash(key);
    hash %= self_p->buckets_max;
    bucket_p = &self_p->buckets_p[hash];

    /* Is the key already in map? */
    if (bucket_p->list_p != NULL) {
        entry_p = bucket_p->list_p;

        while (entry_p != NULL) {
            if (entry_p->key == key) {
                entry_p->value_p = value_p;

                return (0);
            }

            entry_p = entry_p->next_p;
        }
    }

    /* Allocate new entry. */
    entry_p = entry_alloc(self_p);

    if (entry_p == NULL) {
        return (-ENOMEM);
    }

    /* Initiate entry.*/
    entry_p->key = key;
    entry_p->value_p = value_p;

    /* Insert in list. */
    entry_p->next_p = bucket_p->list_p;
    bucket_p->list_p = entry_p;

    return (0);
}
Пример #4
0
Entry* ndb_tool_entry_get( BackendDB *be, ID id )
{
	NdbArgs NA;
	int rc;
	char text[1024];
	Operation op = {0};
	Opheader ohdr = {0};

	assert( be != NULL );
	assert( slapMode & SLAP_TOOL_MODE );

	NA.txn = myNdb->startTransaction();
	if ( !NA.txn ) {
		snprintf( text, sizeof(text),
			"start_transaction failed: %s (%d)",
			myNdb->getNdbError().message, myNdb->getNdbError().code );
		Debug( LDAP_DEBUG_ANY,
			"=> " LDAP_XSTRING(ndb_tool_entry_get) ": %s\n",
			 text, 0, 0 );
		return NULL;
	}

	NA.e = entry_alloc();
	NA.e->e_id = id;
	ber_dupbv( &NA.e->e_name, &myDn );
	dnNormalize( 0, NULL, NULL, &NA.e->e_name, &NA.e->e_nname, NULL );

	op.o_hdr = &ohdr;
	op.o_bd = be;
	op.o_tmpmemctx = NULL;
	op.o_tmpmfuncs = &ch_mfuncs;

	NA.ndb = myNdb;
	NA.ocs = myOcList;
	rc = ndb_entry_get_data( &op, &NA, 0 );

	if ( rc ) {
		entry_free( NA.e );
		NA.e = NULL;
	}
	NA.txn->close();

	return NA.e;
}
Пример #5
0
/*********************************************************************************
 * The contents of this file are subject to the Common Public Attribution
 * License Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.openemm.org/cpal1.html. The License is based on the Mozilla
 * Public License Version 1.1 but Sections 14 and 15 have been added to cover
 * use of software over a computer network and provide for limited attribution
 * for the Original Developer. In addition, Exhibit A has been modified to be
 * consistent with Exhibit B.
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * The Original Code is OpenEMM.
 * The Original Developer is the Initial Developer.
 * The Initial Developer of the Original Code is AGNITAS AG. All portions of
 * the code written by AGNITAS AG are Copyright (c) 2007 AGNITAS AG. All Rights
 * Reserved.
 * 
 * Contributor(s): AGNITAS AG. 
 ********************************************************************************/
# include	<stdlib.h>
# include	<unistd.h>
# include	<fcntl.h>
# include	<string.h>
# include	<dirent.h>
# include	<errno.h>
# include	<sys/types.h>
# include	<sys/stat.h>
# include	"qctrl.h"

entry_t *
entry_alloc (const char *fname, int match) /*{{{*/
{
	entry_t	*e;
	
	if (e = (entry_t *) malloc (sizeof (entry_t))) {
		e -> fname = NULL;
		e -> match = match;
		e -> next = NULL;
		if (fname && (! (e -> fname = strdup (fname))))
			e = entry_free (e);
	}
	return e;
}/*}}}*/
entry_t *
entry_free (entry_t *e) /*{{{*/
{
	if (e) {
		if (e -> fname)
			free (e -> fname);
		free (e);
	}
	return NULL;
}/*}}}*/
entry_t *
entry_free_all (entry_t *e) /*{{{*/
{
	entry_t	*tmp;
	
	while (tmp = e) {
		e = e -> next;
		entry_free (tmp);
	}
	return NULL;
}/*}}}*/

static bool_t
iswhitespace (const char ch) /*{{{*/
{
	return ((ch == ' ') || (ch == '\t')) ? true : false;
}/*}}}*/
qf_t *
qf_alloc (const buffer_t *src) /*{{{*/
{
	qf_t	*q;
	char	*temp;
	int	size;
	char	*ptr;
	
	q = NULL;
	if (temp = malloc (src -> length + 1)) {
		memcpy (temp, src -> buffer, src -> length);
		temp[src -> length] = '\0';
		size = 0;
		if (q = (qf_t *) malloc (sizeof (qf_t))) {
			q -> content = NULL;
			q -> count = 0;
			q -> idx = 0;
			for (ptr = temp; ptr; ) {
				if (q -> count >= size) {
					size += (size ? size : 32);
					if (! (q -> content = (char **) realloc (q -> content, (size + 1) * sizeof (char *))))
						break;
				}
				if (*ptr) {
					q -> content[q -> count++] = ptr;
					while (ptr = strchr (ptr, '\n'))
						if ((! *(ptr + 1)) || (! iswhitespace (*(ptr + 1))))
							break;
						else
							++ptr;
				}
				if (ptr)
					if (*ptr)
						*ptr++ = '\0';
					else
						ptr = NULL;
			}
			if (ptr) {
				if (q -> content)
					free (q -> content);
				free (q);
				q = NULL;
			} else {
				q -> content[q -> count] = NULL;
				if (q -> count)
					temp = NULL;
			}
		}
		if (temp)
			free (temp);
	}
	return q;
}/*}}}*/
qf_t *
qf_free (qf_t *q) /*{{{*/
{
	if (q) {
		if (q -> content) {
			if (q -> content[0])
				free (q -> content[0]);
			free (q -> content);
		}
		free (q);
	}
	return NULL;
}/*}}}*/
const char *
qf_first (qf_t *q, char ch) /*{{{*/
{
	q -> idx = 0;
	return qf_next (q, ch);
}/*}}}*/
const char *
qf_next (qf_t *q, char ch) /*{{{*/
{
	while (q -> idx < q -> count)
		if (q -> content[q -> idx][0] == ch)
			return q -> content[q -> idx++];
		else if (q -> content[q -> idx][0] == '.')
			q -> idx = q -> count;
		else
			q -> idx++;
	return NULL;
}/*}}}*/
int
qf_count (qf_t *q, char ch) /*{{{*/
{
	int	n;
	int	cnt;

	for (n = 0, cnt = 0; n < q -> count; ++n)
		if ((! ch) || (q -> content[n][0] == ch))
			++cnt;
	return cnt;
}/*}}}*/
queue_t *
queue_scan (const char *path, int (*filter) (void *, queue_t *, const char *), void *data) /*{{{*/
{
	queue_t	*q;
	DIR	*dp;
	
	q = NULL;
	if (dp = opendir (path)) {
		if (q = (queue_t *) malloc (sizeof (queue_t))) {
			bool_t		st;
			entry_t		*prv, *tmp;
			struct dirent	*ent;
			int		n;

			strcpy (q -> path, path);
			strcpy (q -> fbuf, q -> path);
			for (q -> fptr = q -> fbuf; *(q -> fptr); q -> fptr++)
				;
			*(q -> fptr++) = '/';
			q -> qf = NULL;
			q -> ent = NULL;
			st = true;
			prv = NULL;
			while (st && (ent = readdir (dp))) {
				n = 0;
				if ((! filter) || (n = (*filter) (data, q, ent -> d_name)))
					if (tmp = entry_alloc (ent -> d_name, n)) {
						if (prv)
							prv -> next = tmp;
						else
							q -> ent = tmp;
						prv = tmp;
					} else
						st = false;
			}
			if (! st)
				q = queue_free (q);
		}
		closedir (dp);
	}
	return q;
}/*}}}*/
Пример #6
0
/*..........................................................................*/
static QHsm *Entry_ctor(raid5_entry_t *rentry)
{
	Entry *me;
	Entry *entry;

	/* allocate the memory */
	me = entry = entry_alloc();
	Q_ASSERT(me != NULL);

	QS_OBJ_DICTIONARY(entry);
	/* QS_OBJ_DICTIONARY(entry->x); */
	
	QS_SIG_DICTIONARY(DIR_REQUEST_SIG, me);
	QS_SIG_DICTIONARY(DIR_UPDATE_SIG,  me);
	QS_SIG_DICTIONARY(DIR_INSERT_SIG,  me);
	
	/* adding free list */
	list_add_tail(&me->entry, &rentry->free);
	
	/* call QHsm */
	QHsm_ctor(&me->super, (QStateHandler)&Entry_initial);

	return &me->super;
}
Пример #7
0
static int
bdb_db_open( BackendDB *be, ConfigReply *cr )
{
	int rc, i;
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	struct stat stat1, stat2;
	u_int32_t flags;
	char path[MAXPATHLEN];
	char *dbhome;
	Entry *e = NULL;
	int do_recover = 0, do_alock_recover = 0;
	int alockt, quick = 0;
	int do_retry = 1;

	if ( be->be_suffix == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": need suffix.\n",
			1, 0, 0 );
		return -1;
	}

	Debug( LDAP_DEBUG_ARGS,
		LDAP_XSTRING(bdb_db_open) ": \"%s\"\n",
		be->be_suffix[0].bv_val, 0, 0 );

	/* Check existence of dbenv_home. Any error means trouble */
	rc = stat( bdb->bi_dbenv_home, &stat1 );
	if( rc != 0 ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"cannot access database directory \"%s\" (%d).\n",
			be->be_suffix[0].bv_val, bdb->bi_dbenv_home, errno );
		return -1;
	}

	/* Perform database use arbitration/recovery logic */
	alockt = (slapMode & SLAP_TOOL_READONLY) ? ALOCK_LOCKED : ALOCK_UNIQUE;
	if ( slapMode & SLAP_TOOL_QUICK ) {
		alockt |= ALOCK_NOSAVE;
		quick = 1;
	}

	rc = alock_open( &bdb->bi_alock_info, 
				"slapd", 
				bdb->bi_dbenv_home, alockt );

	/* alockt is TRUE if the existing environment was created in Quick mode */
	alockt = (rc & ALOCK_NOSAVE) ? 1 : 0;
	rc &= ~ALOCK_NOSAVE;

	if( rc == ALOCK_RECOVER ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"unclean shutdown detected; attempting recovery.\n", 
			be->be_suffix[0].bv_val, 0, 0 );
		do_alock_recover = 1;
		do_recover = DB_RECOVER;
	} else if( rc == ALOCK_BUSY ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"database already in use.\n", 
			be->be_suffix[0].bv_val, 0, 0 );
		return -1;
	} else if( rc != ALOCK_CLEAN ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"alock package is unstable.\n", 
			be->be_suffix[0].bv_val, 0, 0 );
		return -1;
	}
	if ( rc == ALOCK_CLEAN )
		be->be_flags |= SLAP_DBFLAG_CLEAN;

	/*
	 * The DB_CONFIG file may have changed. If so, recover the
	 * database so that new settings are put into effect. Also
	 * note the possible absence of DB_CONFIG in the log.
	 */
	if( stat( bdb->bi_db_config_path, &stat1 ) == 0 ) {
		if ( !do_recover ) {
			char *ptr = lutil_strcopy(path, bdb->bi_dbenv_home);
			*ptr++ = LDAP_DIRSEP[0];
			strcpy( ptr, "__db.001" );
			if( stat( path, &stat2 ) == 0 ) {
				if( stat2.st_mtime < stat1.st_mtime ) {
					Debug( LDAP_DEBUG_ANY,
						LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix \"%s\" has changed.\n",
							be->be_suffix[0].bv_val, 0, 0 );
					if ( quick ) {
						Debug( LDAP_DEBUG_ANY,
							"Cannot use Quick mode; perform manual recovery first.\n",
							0, 0, 0 );
						slapMode ^= SLAP_TOOL_QUICK;
						rc = -1;
						goto fail;
					} else {
						Debug( LDAP_DEBUG_ANY,
							"Performing database recovery to activate new settings.\n",
							0, 0, 0 );
					}
					do_recover = DB_RECOVER;
				}
			}
		}
	}
	else {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": warning - no DB_CONFIG file found "
			"in directory %s: (%d).\n"
			"Expect poor performance for suffix \"%s\".\n",
			bdb->bi_dbenv_home, errno, be->be_suffix[0].bv_val );
	}

	/* Always let slapcat run, regardless of environment state.
	 * This can be used to cause a cache flush after an unclean
	 * shutdown.
	 */
	if ( do_recover && ( slapMode & SLAP_TOOL_READONLY )) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"recovery skipped in read-only mode. "
			"Run manual recovery if errors are encountered.\n",
			be->be_suffix[0].bv_val, 0, 0 );
		do_recover = 0;
		do_alock_recover = 0;
		quick = alockt;
	}

	/* An existing environment in Quick mode has nothing to recover. */
	if ( alockt && do_recover ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"cannot recover, database must be reinitialized.\n", 
			be->be_suffix[0].bv_val, 0, 0 );
		rc = -1;
		goto fail;
	}

	rc = db_env_create( &bdb->bi_dbenv, 0 );
	if( rc != 0 ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
			"db_env_create failed: %s (%d).\n",
			be->be_suffix[0].bv_val, db_strerror(rc), rc );
		goto fail;
	}

#ifdef HAVE_EBCDIC
	strcpy( path, bdb->bi_dbenv_home );
	__atoe( path );
	dbhome = path;
#else
	dbhome = bdb->bi_dbenv_home;
#endif

	/* If existing environment is clean but doesn't support
	 * currently requested modes, remove it.
	 */
	if ( !do_recover && ( alockt ^ quick )) {
shm_retry:
		rc = bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, DB_FORCE );
		if ( rc ) {
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
				"dbenv remove failed: %s (%d).\n",
				be->be_suffix[0].bv_val, db_strerror(rc), rc );
			bdb->bi_dbenv = NULL;
			goto fail;
		}
		rc = db_env_create( &bdb->bi_dbenv, 0 );
		if( rc != 0 ) {
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
				"db_env_create failed: %s (%d).\n",
				be->be_suffix[0].bv_val, db_strerror(rc), rc );
			goto fail;
		}
	}

	bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
	bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );

	bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );

	if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
		rc = bdb->bi_dbenv->set_encrypt( bdb->bi_dbenv, bdb->bi_db_crypt_key.bv_val,
			DB_ENCRYPT_AES );
		if ( rc ) {
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
				"dbenv set_encrypt failed: %s (%d).\n",
				be->be_suffix[0].bv_val, db_strerror(rc), rc );
			goto fail;
		}
	}

	/* One long-lived TXN per thread, two TXNs per write op */
	bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 );

	if( bdb->bi_dbenv_xflags != 0 ) {
		rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv,
			bdb->bi_dbenv_xflags, 1);
		if( rc != 0 ) {
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
				"dbenv_set_flags failed: %s (%d).\n",
				be->be_suffix[0].bv_val, db_strerror(rc), rc );
			goto fail;
		}
	}

#define	BDB_TXN_FLAGS	(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN)

	Debug( LDAP_DEBUG_TRACE,
		LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
		"dbenv_open(%s).\n",
		be->be_suffix[0].bv_val, bdb->bi_dbenv_home, 0);

	flags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD;

	if ( !quick )
		flags |= BDB_TXN_FLAGS;

	/* If a key was set, use shared memory for the BDB environment */
	if ( bdb->bi_shm_key ) {
		bdb->bi_dbenv->set_shm_key( bdb->bi_dbenv, bdb->bi_shm_key );
		flags |= DB_SYSTEM_MEM;
	}
	rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome,
			flags | do_recover, bdb->bi_dbenv_mode );

	if ( rc ) {
		/* Regular open failed, probably a missing shm environment.
		 * Start over, do a recovery.
		 */
		if ( !do_recover && bdb->bi_shm_key && do_retry ) {
			bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
			rc = db_env_create( &bdb->bi_dbenv, 0 );
			if( rc == 0 ) {
				Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_db_open)
					": database \"%s\": "
					"shared memory env open failed, assuming stale env.\n",
					be->be_suffix[0].bv_val, 0, 0 );
				do_retry = 0;
				goto shm_retry;
			}
		}
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\" cannot be %s, err %d. "
			"Restore from backup!\n",
			be->be_suffix[0].bv_val, do_recover ? "recovered" : "opened", rc );
		goto fail;
	}

	if ( do_alock_recover && alock_recover (&bdb->bi_alock_info) != 0 ) {
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": database \"%s\": alock_recover failed\n",
			be->be_suffix[0].bv_val, 0, 0 );
		rc = -1;
		goto fail;
	}

#ifdef SLAP_ZONE_ALLOC
	if ( bdb->bi_cache.c_maxsize ) {
		bdb->bi_cache.c_zctx = slap_zn_mem_create(
			SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE,
			SLAP_ZONE_DELTA, SLAP_ZONE_SIZE);
	}
#endif

	/* dncache defaults to 0 == unlimited
	 * must be >= entrycache
	 */
	if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) {
		bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize;
	}

	if ( bdb->bi_idl_cache_max_size ) {
		bdb->bi_idl_tree = NULL;
		bdb->bi_idl_cache_size = 0;
	}

	flags = DB_THREAD | bdb->bi_db_opflags;

#ifdef DB_AUTO_COMMIT
	if ( !quick )
		flags |= DB_AUTO_COMMIT;
#endif

	bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
		BDB_INDICES * sizeof(struct bdb_db_info *) );

	/* open (and create) main database */
	for( i = 0; bdbi_databases[i].name.bv_val; i++ ) {
		struct bdb_db_info *db;

		db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info));

		rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 );
		if( rc != 0 ) {
			snprintf(cr->msg, sizeof(cr->msg),
				"database \"%s\": db_create(%s) failed: %s (%d).",
				be->be_suffix[0].bv_val, 
				bdb->bi_dbenv_home, db_strerror(rc), rc );
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": %s\n",
				cr->msg, 0, 0 );
			goto fail;
		}

		if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
			rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT );
			if ( rc ) {
				snprintf(cr->msg, sizeof(cr->msg),
					"database \"%s\": db set_flags(DB_ENCRYPT)(%s) failed: %s (%d).",
					be->be_suffix[0].bv_val, 
					bdb->bi_dbenv_home, db_strerror(rc), rc );
				Debug( LDAP_DEBUG_ANY,
					LDAP_XSTRING(bdb_db_open) ": %s\n",
					cr->msg, 0, 0 );
				goto fail;
			}
		}

		if( bdb->bi_flags & BDB_CHKSUM ) {
			rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM );
			if ( rc ) {
				snprintf(cr->msg, sizeof(cr->msg),
					"database \"%s\": db set_flags(DB_CHKSUM)(%s) failed: %s (%d).",
					be->be_suffix[0].bv_val, 
					bdb->bi_dbenv_home, db_strerror(rc), rc );
				Debug( LDAP_DEBUG_ANY,
					LDAP_XSTRING(bdb_db_open) ": %s\n",
					cr->msg, 0, 0 );
				goto fail;
			}
		}

		rc = bdb_db_findsize( bdb, (struct berval *)&bdbi_databases[i].name );

		if( i == BDB_ID2ENTRY ) {
			if ( !rc ) rc = BDB_ID2ENTRY_PAGESIZE;
			rc = db->bdi_db->set_pagesize( db->bdi_db, rc );

			if ( slapMode & SLAP_TOOL_MODE )
				db->bdi_db->mpf->set_priority( db->bdi_db->mpf,
					DB_PRIORITY_VERY_LOW );

			if ( slapMode & SLAP_TOOL_READMAIN ) {
				flags |= DB_RDONLY;
			} else {
				flags |= DB_CREATE;
			}
		} else {
			/* Use FS default size if not configured */
			if ( rc )
				rc = db->bdi_db->set_pagesize( db->bdi_db, rc );

			rc = db->bdi_db->set_flags( db->bdi_db, 
				DB_DUP | DB_DUPSORT );
#ifndef BDB_HIER
			if ( slapMode & SLAP_TOOL_READONLY ) {
				flags |= DB_RDONLY;
			} else {
				flags |= DB_CREATE;
			}
#else
			rc = db->bdi_db->set_dup_compare( db->bdi_db,
				bdb_dup_compare );
			if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) {
				flags |= DB_RDONLY;
			} else {
				flags |= DB_CREATE;
			}
#endif
		}

#ifdef HAVE_EBCDIC
		strcpy( path, bdbi_databases[i].file );
		__atoe( path );
		rc = DB_OPEN( db->bdi_db,
			path,
		/*	bdbi_databases[i].name, */ NULL,
			bdbi_databases[i].type,
			bdbi_databases[i].flags | flags,
			bdb->bi_dbenv_mode );
#else
		rc = DB_OPEN( db->bdi_db,
			bdbi_databases[i].file,
		/*	bdbi_databases[i].name, */ NULL,
			bdbi_databases[i].type,
			bdbi_databases[i].flags | flags,
			bdb->bi_dbenv_mode );
#endif

		if ( rc != 0 ) {
			snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
				"db_open(%s/%s) failed: %s (%d).", 
				be->be_suffix[0].bv_val, 
				bdb->bi_dbenv_home, bdbi_databases[i].file,
				db_strerror(rc), rc );
			Debug( LDAP_DEBUG_ANY,
				LDAP_XSTRING(bdb_db_open) ": %s\n",
				cr->msg, 0, 0 );
			db->bdi_db->close( db->bdi_db, 0 );
			goto fail;
		}

		flags &= ~(DB_CREATE | DB_RDONLY);
		db->bdi_name = bdbi_databases[i].name;
		bdb->bi_databases[i] = db;
	}

	bdb->bi_databases[i] = NULL;
	bdb->bi_ndatabases = i;

	/* get nextid */
	rc = bdb_last_id( be, NULL );
	if( rc != 0 ) {
		snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": "
			"last_id(%s) failed: %s (%d).",
			be->be_suffix[0].bv_val, bdb->bi_dbenv_home,
			db_strerror(rc), rc );
		Debug( LDAP_DEBUG_ANY,
			LDAP_XSTRING(bdb_db_open) ": %s\n",
			cr->msg, 0, 0 );
		goto fail;
	}

	if ( !quick ) {
		TXN_BEGIN(bdb->bi_dbenv, NULL, &bdb->bi_cache.c_txn, DB_READ_COMMITTED | DB_TXN_NOWAIT);
	}

	entry_prealloc( bdb->bi_cache.c_maxsize );
	attr_prealloc( bdb->bi_cache.c_maxsize * 20 );

	/* setup for empty-DN contexts */
	if ( BER_BVISEMPTY( &be->be_nsuffix[0] )) {
		rc = bdb_id2entry( be, NULL, 0, &e );
	}
	if ( !e ) {
		struct berval gluebv = BER_BVC("glue");
		Operation op = {0};
		Opheader ohdr = {0};
		e = entry_alloc();
		e->e_id = 0;
		ber_dupbv( &e->e_name, (struct berval *)&slap_empty_bv );
		ber_dupbv( &e->e_nname, (struct berval *)&slap_empty_bv );
		attr_merge_one( e, slap_schema.si_ad_objectClass,
			&gluebv, NULL );
		attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
			&gluebv, NULL );
		op.o_hdr = &ohdr;
		op.o_bd = be;
		op.ora_e = e;
		op.o_dn = be->be_rootdn;
		op.o_ndn = be->be_rootndn;
		slap_add_opattrs( &op, NULL, NULL, 0, 0 );
	}
	e->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END;
	e->e_private = &bdb->bi_cache.c_dntree;
	bdb->bi_cache.c_dntree.bei_e = e;

	/* monitor setup */
	rc = bdb_monitor_db_open( be );
	if ( rc != 0 ) {
		goto fail;
	}

	bdb->bi_flags |= BDB_IS_OPEN;

	return 0;

fail:
	bdb_db_close( be, NULL );
	return rc;
}
Пример #8
0
/* Duplicates an entry using a single malloc. Saves CPU time, increases
 * heap usage because a single large malloc is harder to satisfy than
 * lots of small ones, and the freed space isn't as easily reusable.
 *
 * Probably not worth using this function.
 */
Entry *entry_dup_bv( Entry *e )
{
	ber_len_t len;
	int nattrs, nvals;
	Entry *ret;
	struct berval *bvl;
	char *ptr;
	Attribute *src, *dst;

	ret = entry_alloc();

	entry_partsize(e, &len, &nattrs, &nvals, 1);
	ret->e_id = e->e_id;
	ret->e_attrs = attrs_alloc( nattrs );
	ret->e_ocflags = e->e_ocflags;
	ret->e_bv.bv_len = len + nvals * sizeof(struct berval);
	ret->e_bv.bv_val = ch_malloc( ret->e_bv.bv_len );

	bvl = (struct berval *)ret->e_bv.bv_val;
	ptr = (char *)(bvl + nvals);

	ret->e_name.bv_len = e->e_name.bv_len;
	ret->e_name.bv_val = ptr;
	AC_MEMCPY( ptr, e->e_name.bv_val, e->e_name.bv_len );
	ptr += e->e_name.bv_len;
	*ptr++ = '\0';

	ret->e_nname.bv_len = e->e_nname.bv_len;
	ret->e_nname.bv_val = ptr;
	AC_MEMCPY( ptr, e->e_nname.bv_val, e->e_nname.bv_len );
	ptr += e->e_name.bv_len;
	*ptr++ = '\0';

	dst = ret->e_attrs;
	for (src = e->e_attrs; src; src=src->a_next,dst=dst->a_next ) {
		int i;
		dst->a_desc = src->a_desc;
		dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
		dst->a_vals = bvl;
		dst->a_numvals = src->a_numvals;
		for ( i=0; src->a_vals[i].bv_val; i++ ) {
			bvl->bv_len = src->a_vals[i].bv_len;
			bvl->bv_val = ptr;
			AC_MEMCPY( ptr, src->a_vals[i].bv_val, bvl->bv_len );
			ptr += bvl->bv_len;
			*ptr++ = '\0';
			bvl++;
		}
		BER_BVZERO(bvl);
		bvl++;
		if ( src->a_vals != src->a_nvals ) {
			dst->a_nvals = bvl;
			for ( i=0; src->a_nvals[i].bv_val; i++ ) {
				bvl->bv_len = src->a_nvals[i].bv_len;
				bvl->bv_val = ptr;
				AC_MEMCPY( ptr, src->a_nvals[i].bv_val, bvl->bv_len );
				ptr += bvl->bv_len;
				*ptr++ = '\0';
				bvl++;
			}
			BER_BVZERO(bvl);
			bvl++;
		}
	}
	return ret;
}
Пример #9
0
/*
 * Store some statistics for a statement.
 */
static void
pgss_store(const char *query, double total_time, uint64 rows,
		   const BufferUsage *bufusage)
{
	pgssHashKey key;
	double		usage;
	pgssEntry  *entry;

	Assert(query != NULL);

	/* Safety check... */
	if (!pgss || !pgss_hash)
		return;

	/* Set up key for hashtable search */
	key.userid = GetUserId();
	key.dbid = MyDatabaseId;
	key.encoding = GetDatabaseEncoding();
	key.query_len = strlen(query);
	if (key.query_len >= pgss->query_size)
		key.query_len = pg_encoding_mbcliplen(key.encoding,
											  query,
											  key.query_len,
											  pgss->query_size - 1);
	key.query_ptr = query;

	usage = USAGE_EXEC(duration);

	/* Lookup the hash table entry with shared lock. */
	LWLockAcquire(pgss->lock, LW_SHARED);

	entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
	if (!entry)
	{
		/* Must acquire exclusive lock to add a new entry. */
		LWLockRelease(pgss->lock);
		LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
		entry = entry_alloc(&key);
	}

	/* Grab the spinlock while updating the counters. */
	{
		volatile pgssEntry *e = (volatile pgssEntry *) entry;

		SpinLockAcquire(&e->mutex);
		e->counters.calls += 1;
		e->counters.total_time += total_time;
		e->counters.rows += rows;
		e->counters.shared_blks_hit += bufusage->shared_blks_hit;
		e->counters.shared_blks_read += bufusage->shared_blks_read;
		e->counters.shared_blks_written += bufusage->shared_blks_written;
		e->counters.local_blks_hit += bufusage->local_blks_hit;
		e->counters.local_blks_read += bufusage->local_blks_read;
		e->counters.local_blks_written += bufusage->local_blks_written;
		e->counters.temp_blks_read += bufusage->temp_blks_read;
		e->counters.temp_blks_written += bufusage->temp_blks_written;
		e->counters.usage += usage;
		SpinLockRelease(&e->mutex);
	}

	LWLockRelease(pgss->lock);
}
Пример #10
0
Entry *
str2entry2( char *s, int checkvals )
{
	int rc;
	Entry		*e;
	struct berval	*type, *vals, *nvals;
	char 	*freeval;
	AttributeDescription *ad, *ad_prev;
	const char *text;
	char	*next;
	int		attr_cnt;
	int		i, lines;
	Attribute	ahead, *atail;

	/*
	 * LDIF is used as the string format.
	 * An entry looks like this:
	 *
	 *	dn: <dn>\n
	 *	[<attr>:[:] <value>\n]
	 *	[<tab><continuedvalue>\n]*
	 *	...
	 *
	 * If a double colon is used after a type, it means the
	 * following value is encoded as a base 64 string.  This
	 * happens if the value contains a non-printing character
	 * or newline.
	 */

	Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n",
		s ? s : "NULL" );

	e = entry_alloc();

	if( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"<= str2entry NULL (entry allocation failed)\n" );
		return( NULL );
	}

	/* initialize entry */
	e->e_id = NOID;

	/* dn + attributes */
	atail = &ahead;
	ahead.a_next = NULL;
	ad = NULL;
	ad_prev = NULL;
	attr_cnt = 0;
	next = s;

	lines = ldif_countlines( s );
	type = ch_calloc( 1, (lines+1)*3*sizeof(struct berval)+lines );
	vals = type+lines+1;
	nvals = vals+lines+1;
	freeval = (char *)(nvals+lines+1);
	i = -1;

	/* parse into individual values, record DN */
	while ( (s = ldif_getline( &next )) != NULL ) {
		int freev;
		if ( *s == '\n' || *s == '\0' ) {
			break;
		}
		i++;
		if (i >= lines) {
			Debug( LDAP_DEBUG_TRACE,
				"<= str2entry ran past end of entry\n" );
			goto fail;
		}

		rc = ldif_parse_line2( s, type+i, vals+i, &freev );
		freeval[i] = freev;
		if ( rc ) {
			Debug( LDAP_DEBUG_TRACE,
				"<= str2entry NULL (parse_line)\n" );
			continue;
		}

		if ( bvcasematch( &type[i], &dn_bv ) ) {
			if ( e->e_dn != NULL ) {
				Debug( LDAP_DEBUG_ANY, "str2entry: "
					"entry %ld has multiple DNs \"%s\" and \"%s\"\n",
					(long) e->e_id, e->e_dn, vals[i].bv_val );
				goto fail;
			}

			rc = dnPrettyNormal( NULL, &vals[i], &e->e_name, &e->e_nname, NULL );
			if( rc != LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_ANY, "str2entry: "
					"entry %ld has invalid DN \"%s\"\n",
					(long) e->e_id, vals[i].bv_val );
				goto fail;
			}
			if ( freeval[i] ) free( vals[i].bv_val );
			vals[i].bv_val = NULL;
			i--;
			continue;
		}
	}
	lines = i+1;

	/* check to make sure there was a dn: line */
	if ( BER_BVISNULL( &e->e_name )) {
		Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n",
			(long) e->e_id );
		goto fail;
	}

	/* Make sure all attributes with multiple values are contiguous */
	if ( checkvals ) {
		int j, k;
		struct berval bv;
		int fv;

		for (i=0; i<lines; i++) {
			for ( j=i+1; j<lines; j++ ) {
				if ( bvcasematch( type+i, type+j )) {
					/* out of order, move intervening attributes down */
					if ( j != i+1 ) {
						bv = vals[j];
						fv = freeval[j];
						for ( k=j; k>i; k-- ) {
							type[k] = type[k-1];
							vals[k] = vals[k-1];
							freeval[k] = freeval[k-1];
						}
						k++;
						type[k] = type[i];
						vals[k] = bv;
						freeval[k] = fv;
					}
					i++;
				}
			}
		}
	}

	if ( lines > 0 ) {
		for ( i=0; i<=lines; i++ ) {
			ad_prev = ad;
			if ( !ad || ( i<lines && !bvcasematch( type+i, &ad->ad_cname ))) {
				ad = NULL;
				rc = slap_bv2ad( type+i, &ad, &text );

				if( rc != LDAP_SUCCESS ) {
					int wtool = ( slapMode & (SLAP_TOOL_MODE|SLAP_TOOL_READONLY) ) == SLAP_TOOL_MODE;
					Debug( wtool ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
						"<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text );
					if( wtool ) {
						goto fail;
					}

					rc = slap_bv2undef_ad( type+i, &ad, &text, 0 );
					if( rc != LDAP_SUCCESS ) {
						Debug( LDAP_DEBUG_ANY,
							"<= str2entry: slap_str2undef_ad(%s): %s\n",
								type[i].bv_val, text );
						goto fail;
					}
				}

				/* require ';binary' when appropriate (ITS#5071) */
				if ( slap_syntax_is_binary( ad->ad_type->sat_syntax ) && !slap_ad_is_binary( ad ) ) {
					Debug( LDAP_DEBUG_ANY,
						"str2entry: attributeType %s #%d: "
						"needs ';binary' transfer as per syntax %s\n",
						ad->ad_cname.bv_val, 0,
						ad->ad_type->sat_syntax->ssyn_oid );
					goto fail;
				}
			}

			if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
				int j, k;
				atail->a_next = attr_alloc( NULL );
				atail = atail->a_next;
				atail->a_flags = 0;
				atail->a_numvals = attr_cnt;
				atail->a_desc = ad_prev;
				atail->a_vals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
				if( ad_prev->ad_type->sat_equality &&
					ad_prev->ad_type->sat_equality->smr_normalize )
					atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
				else
					atail->a_nvals = NULL;
				k = i - attr_cnt;
				for ( j=0; j<attr_cnt; j++ ) {
					if ( freeval[k] )
						atail->a_vals[j] = vals[k];
					else
						ber_dupbv( atail->a_vals+j, &vals[k] );
					vals[k].bv_val = NULL;
					if ( atail->a_nvals ) {
						atail->a_nvals[j] = nvals[k];
						nvals[k].bv_val = NULL;
					}
					k++;
				}
				BER_BVZERO( &atail->a_vals[j] );
				if ( atail->a_nvals ) {
					BER_BVZERO( &atail->a_nvals[j] );
				} else {
					atail->a_nvals = atail->a_vals;
				}
				attr_cnt = 0;
				/* FIXME: we only need this when migrating from an unsorted DB */
				if ( atail->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
					rc = slap_sort_vals( (Modifications *)atail, &text, &j, NULL );
					if ( rc == LDAP_SUCCESS ) {
						atail->a_flags |= SLAP_ATTR_SORTED_VALS;
					} else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
						Debug( LDAP_DEBUG_ANY,
							"str2entry: attributeType %s value #%d provided more than once\n",
							atail->a_desc->ad_cname.bv_val, j );
						goto fail;
					}
				}
				if ( i == lines ) break;
			}

			if ( BER_BVISNULL( &vals[i] ) ) {
				Debug( LDAP_DEBUG_ANY,
					"str2entry: attributeType %s #%d: "
					"no value\n",
					ad->ad_cname.bv_val, attr_cnt );
				goto fail;
			}

			if ( ad->ad_type->sat_equality &&
				ad->ad_type->sat_equality->smr_normalize )
			{
				rc = ordered_value_normalize(
					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
					ad,
					ad->ad_type->sat_equality,
					&vals[i], &nvals[i], NULL );

				if ( rc ) {
					Debug( LDAP_DEBUG_ANY,
				   		"<= str2entry NULL (smr_normalize %s %d)\n", ad->ad_cname.bv_val, rc );
					goto fail;
				}
			}

			attr_cnt++;
		}
	}

	free( type );
	atail->a_next = NULL;
	e->e_attrs = ahead.a_next;

	Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> 0x%lx\n",
		e->e_dn, (unsigned long) e );
	return( e );

fail:
	for ( i=0; i<lines; i++ ) {
		if ( freeval[i] ) free( vals[i].bv_val );
		free( nvals[i].bv_val );
	}
	free( type );
	entry_free( e );
	return NULL;
}
Пример #11
0
static int translucent_pwmod(Operation *op, SlapReply *rs) {
	SlapReply nrs = { REP_RESULT };
	Operation nop;

	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
	translucent_info *ov = on->on_bi.bi_private;
	Entry *e = NULL, *re = NULL;
	BackendDB *db;
	int rc = 0;
	slap_callback cb = { 0 };

	if (!ov->pwmod_local) {
		rs->sr_err = LDAP_CONSTRAINT_VIOLATION,
		rs->sr_text = "attempt to modify password in local database";
		return rs->sr_err;
	}

/*
** fetch entry from the captive backend;
** if it did not exist, fail;
** release it, if captive backend supports this;
**
*/
	db = op->o_bd;
	op->o_bd = &ov->db;
	ov->db.be_acl = op->o_bd->be_acl;
	rc = ov->db.bd_info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re);
	if(rc != LDAP_SUCCESS || re == NULL ) {
		send_ldap_error((op), rs, LDAP_NO_SUCH_OBJECT,
			"attempt to modify nonexistent local record");
		return(rs->sr_err);
	}
	op->o_bd = db;
/*
** fetch entry from local backend;
** if it exists:
**	return CONTINUE;
*/

	op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
	rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &e);
	op->o_bd->bd_info = (BackendInfo *) on;

	if(e && rc == LDAP_SUCCESS) {
		if(re) {
			if(ov->db.bd_info->bi_entry_release_rw) {
				op->o_bd = &ov->db;
				ov->db.bd_info->bi_entry_release_rw(op, re, 0);
				op->o_bd = db;
			} else {
				entry_free(re);
			}
		}
		op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
		be_entry_release_r(op, e);
		op->o_bd->bd_info = (BackendInfo *) on;
		return SLAP_CB_CONTINUE;
	}

	/* don't leak remote entry copy */
	if(re) {
		if(ov->db.bd_info->bi_entry_release_rw) {
			op->o_bd = &ov->db;
			ov->db.bd_info->bi_entry_release_rw(op, re, 0);
			op->o_bd = db;
		} else {
			entry_free(re);
		}
	}
/*
** glue_parent() for this Entry;
** call bi_op_add() in local backend;
**
*/
	e = entry_alloc();
	ber_dupbv( &e->e_name, &op->o_req_dn );
	ber_dupbv( &e->e_nname, &op->o_req_ndn );
	e->e_attrs = NULL;

	nop = *op;
	nop.o_tag = LDAP_REQ_ADD;
	cb.sc_response = slap_null_cb;
	nop.oq_add.rs_e	= e;

	glue_parent(&nop);

	nop.o_callback = &cb;
	rc = on->on_info->oi_orig->bi_op_add(&nop, &nrs);
	if ( nop.ora_e == e ) {
		entry_free( e );
	}

	if ( rc == LDAP_SUCCESS ) {
		return SLAP_CB_CONTINUE;
	}

	return rc;
}
Пример #12
0
static int translucent_modify(Operation *op, SlapReply *rs) {
	SlapReply nrs = { REP_RESULT };

	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
	translucent_info *ov = on->on_bi.bi_private;
	Entry *e = NULL, *re = NULL;
	Attribute *a, *ax;
	Modifications *m, **mm;
	BackendDB *db;
	int del, rc, erc = 0;
	slap_callback cb = { 0 };

	Debug(LDAP_DEBUG_TRACE, "==> translucent_modify: %s\n",
		op->o_req_dn.bv_val, 0, 0);

	if(ov->defer_db_open) {
		send_ldap_error(op, rs, LDAP_UNAVAILABLE,
			"remote DB not available");
		return(rs->sr_err);
	}
/*
** fetch entry from the captive backend;
** if it did not exist, fail;
** release it, if captive backend supports this;
**
*/

	db = op->o_bd;
	op->o_bd = &ov->db;
	ov->db.be_acl = op->o_bd->be_acl;
	rc = ov->db.bd_info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re);
	op->o_bd = db;
	if(rc != LDAP_SUCCESS || re == NULL ) {
		send_ldap_error((op), rs, LDAP_NO_SUCH_OBJECT,
			"attempt to modify nonexistent local record");
		return(rs->sr_err);
	}
/*
** fetch entry from local backend;
** if it exists:
**	foreach Modification:
**	    if attr not present in local:
**		if Mod == LDAP_MOD_DELETE:
**		    if remote attr not present, return NO_SUCH;
**		    if remote attr present, drop this Mod;
**		else force this Mod to LDAP_MOD_ADD;
**	return CONTINUE;
**
*/

	op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
	rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &e);
	op->o_bd->bd_info = (BackendInfo *) on;

	if(e && rc == LDAP_SUCCESS) {
		Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: found local entry\n", 0, 0, 0);
		for(mm = &op->orm_modlist; *mm; ) {
			m = *mm;
			for(a = e->e_attrs; a; a = a->a_next)
				if(a->a_desc == m->sml_desc) break;
			if(a) {
				mm = &m->sml_next;
				continue;		/* found local attr */
			}
			if(m->sml_op == LDAP_MOD_DELETE) {
				for(a = re->e_attrs; a; a = a->a_next)
					if(a->a_desc == m->sml_desc) break;
				/* not found remote attr */
				if(!a) {
					erc = LDAP_NO_SUCH_ATTRIBUTE;
					goto release;
				}
				if(ov->strict) {
					erc = LDAP_CONSTRAINT_VIOLATION;
					goto release;
				}
				Debug(LDAP_DEBUG_TRACE,
					"=> translucent_modify: silently dropping delete: %s\n",
					m->sml_desc->ad_cname.bv_val, 0, 0);
				*mm = m->sml_next;
				m->sml_next = NULL;
				slap_mods_free(m, 1);
				continue;
			}
			m->sml_op = LDAP_MOD_ADD;
			mm = &m->sml_next;
		}
		erc = SLAP_CB_CONTINUE;
release:
		if(re) {
			if(ov->db.bd_info->bi_entry_release_rw) {
				op->o_bd = &ov->db;
				ov->db.bd_info->bi_entry_release_rw(op, re, 0);
				op->o_bd = db;
			} else
				entry_free(re);
		}
		op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
		be_entry_release_r(op, e);
		op->o_bd->bd_info = (BackendInfo *) on;
		if(erc == SLAP_CB_CONTINUE) {
			return(erc);
		} else if(erc) {
			send_ldap_error(op, rs, erc,
				"attempt to delete nonexistent attribute");
			return(erc);
		}
	}

	/* don't leak remote entry copy */
	if(re) {
		if(ov->db.bd_info->bi_entry_release_rw) {
			op->o_bd = &ov->db;
			ov->db.bd_info->bi_entry_release_rw(op, re, 0);
			op->o_bd = db;
		} else
			entry_free(re);
	}
/*
** foreach Modification:
**	if MOD_ADD or MOD_REPLACE, add Attribute;
** if no Modifications were suitable:
**	if strict, throw CONSTRAINT_VIOLATION;
**	else, return early SUCCESS;
** fabricate Entry with new Attribute chain;
** glue_parent() for this Entry;
** call bi_op_add() in local backend;
**
*/

	Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: fabricating local add\n", 0, 0, 0);
	a = NULL;
	for(del = 0, ax = NULL, m = op->orm_modlist; m; m = m->sml_next) {
		Attribute atmp;
		if(((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_ADD) &&
		   ((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_REPLACE)) {
			Debug(LDAP_DEBUG_ANY,
				"=> translucent_modify: silently dropped modification(%d): %s\n",
				m->sml_op, m->sml_desc->ad_cname.bv_val, 0);
			if((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) del++;
			continue;
		}
		atmp.a_desc = m->sml_desc;
		atmp.a_vals = m->sml_values;
		atmp.a_nvals = m->sml_nvalues ? m->sml_nvalues : atmp.a_vals;
		atmp.a_numvals = m->sml_numvals;
		atmp.a_flags = 0;
		a = attr_dup( &atmp );
		a->a_next  = ax;
		ax = a;
	}

	if(del && ov->strict) {
		attrs_free( a );
		send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,
			"attempt to delete attributes from local database");
		return(rs->sr_err);
	}

	if(!ax) {
		if(ov->strict) {
			send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,
				"modification contained other than ADD or REPLACE");
			return(rs->sr_err);
		}
		/* rs->sr_text = "no valid modification found"; */
		rs->sr_err = LDAP_SUCCESS;
		send_ldap_result(op, rs);
		return(rs->sr_err);
	}

	e = entry_alloc();
	ber_dupbv( &e->e_name, &op->o_req_dn );
	ber_dupbv( &e->e_nname, &op->o_req_ndn );
	e->e_attrs = a;

	op->o_tag	= LDAP_REQ_ADD;
	cb.sc_response = translucent_tag_cb;
	cb.sc_private = op->orm_modlist;
	op->oq_add.rs_e	= e;

	glue_parent(op);

	cb.sc_next = op->o_callback;
	op->o_callback = &cb;
	rc = on->on_info->oi_orig->bi_op_add(op, &nrs);
	if ( op->ora_e == e )
		entry_free( e );
	op->o_callback = cb.sc_next;

	return(rc);
}
Пример #13
0
/* return 0 IFF we can retrieve the entry with ndn
 */
int
ldap_back_entry_get(
		Operation		*op,
		struct berval		*ndn,
		ObjectClass		*oc,
		AttributeDescription	*at,
		int			rw,
		Entry			**ent )
{
	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;

	ldapconn_t	*lc = NULL;
	int		rc,
			do_not_cache;
	ber_tag_t	tag;
	struct berval	bdn;
	LDAPMessage	*result = NULL,
			*e = NULL;
	char		*attr[3], **attrp = NULL;
	char		*filter = NULL;
	SlapReply	rs;
	int		do_retry = 1;
	LDAPControl	**ctrls = NULL;

	*ent = NULL;

	/* Tell getconn this is a privileged op */
	do_not_cache = op->o_do_not_cache;
	tag = op->o_tag;
	/* do not cache */
	op->o_do_not_cache = 1;
	/* ldap_back_entry_get() is an entry lookup, so it does not need
	 * to know what the entry is being looked up for */
	op->o_tag = LDAP_REQ_SEARCH;
	rc = ldap_back_dobind( &lc, op, &rs, LDAP_BACK_DONTSEND );
	op->o_do_not_cache = do_not_cache;
	op->o_tag = tag;
	if ( !rc ) {
		return rs.sr_err;
	}

	if ( at ) {
		attrp = attr;
		if ( oc && at != slap_schema.si_ad_objectClass ) {
			attr[0] = slap_schema.si_ad_objectClass->ad_cname.bv_val;
			attr[1] = at->ad_cname.bv_val;
			attr[2] = NULL;

		} else {
			attr[0] = at->ad_cname.bv_val;
			attr[1] = NULL;
		}
	}

	if ( oc ) {
		char	*ptr;

		filter = op->o_tmpalloc( STRLENOF( "(objectClass=" ")" ) 
				+ oc->soc_cname.bv_len + 1, op->o_tmpmemctx );
		ptr = lutil_strcopy( filter, "(objectClass=" );
		ptr = lutil_strcopy( ptr, oc->soc_cname.bv_val );
		*ptr++ = ')';
		*ptr++ = '\0';
	}

retry:
	ctrls = op->o_ctrls;
	rc = ldap_back_controls_add( op, &rs, lc, &ctrls );
	if ( rc != LDAP_SUCCESS ) {
		goto cleanup;
	}

	/* TODO: timeout? */
	rc = ldap_pvt_search_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
				attrp, LDAP_DEREF_NEVER, ctrls, NULL,
				NULL, LDAP_NO_LIMIT, 0, &result );
	if ( rc != LDAP_SUCCESS ) {
		if ( rc == LDAP_SERVER_DOWN && do_retry ) {
			do_retry = 0;
			if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
				/* if the identity changed, there might be need to re-authz */
				(void)ldap_back_controls_free( op, &rs, &ctrls );
				goto retry;
			}
		}
		goto cleanup;
	}

	e = ldap_first_entry( lc->lc_ld, result );
	if ( e == NULL ) {
		/* the entry exists, but it doesn't match the filter? */
		goto cleanup;
	}

	*ent = entry_alloc();
	if ( *ent == NULL ) {
		rc = LDAP_NO_MEMORY;
		goto cleanup;
	}

	rc = ldap_build_entry( op, e, *ent, &bdn );

	if ( rc != LDAP_SUCCESS ) {
		entry_free( *ent );
		*ent = NULL;
	}

cleanup:
	(void)ldap_back_controls_free( op, &rs, &ctrls );

	if ( result ) {
		ldap_msgfree( result );
	}

	if ( filter ) {
		op->o_tmpfree( filter, op->o_tmpmemctx );
	}

	if ( lc != NULL ) {
		ldap_back_release_conn( li, lc );
	}

	return rc;
}
Пример #14
0
static int parse_dir (inode_build_t * grand_parent_inode,
	inode_build_t * parent_inode, char * parent_path)
	{
	int err;

	DIR * parent_dir = NULL;

	while (1)
		{
		parent_dir = opendir (parent_path);
		if (!parent_dir)
			{
			err = errno;
			break;
			}

		while (1)
			{
			struct dirent * ent = readdir (parent_dir);
			if (!ent)
				{
				err = errno;
				break;
				}

			char * name = ent->d_name;
			entry_build_t * child_ent = entry_alloc (parent_inode, name);
			if (!child_ent)
				{
				err = -1;
				break;
				}

			char * child_path = malloc (strlen (parent_path) + 1 + strlen (name) + 1);
			strcpy (child_path, parent_path);
			strcat (child_path, "/");
			strcat (child_path, name);

			if (!strcmp (name, "."))
				{
				printf ("Pseudo: %s\n", child_path);
				child_ent->inode = parent_inode;
				}

			else if (!strcmp (name, ".."))
				{
				printf ("Pseudo: %s\n", child_path);
				if (grand_parent_inode)
					child_ent->inode = grand_parent_inode;
					else
					child_ent->inode = parent_inode;  /* self for root */

				}

			else
				{
				inode_build_t * child_inode = inode_alloc (parent_inode, child_path);
				if (!child_inode)
					{
					err = -1;
					break;
					}

				child_ent->inode = child_inode;

				struct stat child_stat;
				err = lstat (child_path, &child_stat);
				if (err)
					{
					err = errno;
					break;
					}

				if (S_ISREG (child_stat.st_mode))
					{
					printf ("File:   %s\n", child_path);
					child_inode->flags = INODE_FILE;
					child_inode->size = child_stat.st_size;
					}

				else if (S_ISDIR (child_stat.st_mode))
					{
					printf ("Dir:    %s\n", child_path);
					child_inode->flags = INODE_DIR;
					err = parse_dir (parent_inode, child_inode, child_path);
					if (err) break;
					}

				else
					{
					assert (0);
					}
				}

			if (child_path) free (child_path);
			}

		if (err != 0)
			{
			perror ("Read directory");
			}

		break;
		}

	if (parent_dir) closedir (parent_dir);

	return err;
	}
Пример #15
0
int
schema_info( Entry **entry, const char **text )
{
	AttributeDescription *ad_structuralObjectClass
		= slap_schema.si_ad_structuralObjectClass;
	AttributeDescription *ad_objectClass
		= slap_schema.si_ad_objectClass;
	AttributeDescription *ad_createTimestamp
		= slap_schema.si_ad_createTimestamp;
	AttributeDescription *ad_modifyTimestamp
		= slap_schema.si_ad_modifyTimestamp;

	Entry		*e;
	struct berval	vals[5];
	struct berval	nvals[5];

	e = entry_alloc();
	if( e == NULL ) {
		/* Out of memory, do something about it */
		Debug( LDAP_DEBUG_ANY, 
			"schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	e->e_attrs = NULL;
	/* backend-specific schema info should be created by the
	 * backend itself
	 */
	ber_dupbv( &e->e_name, &frontendDB->be_schemadn );
	ber_dupbv( &e->e_nname, &frontendDB->be_schemandn );
	e->e_private = NULL;

	BER_BVSTR( &vals[0], "subentry" );
	if( attr_merge_one( e, ad_structuralObjectClass, vals, NULL ) ) {
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	BER_BVSTR( &vals[0], "top" );
	BER_BVSTR( &vals[1], "subentry" );
	BER_BVSTR( &vals[2], "subschema" );
	BER_BVSTR( &vals[3], "extensibleObject" );
	BER_BVZERO( &vals[4] );
	if ( attr_merge( e, ad_objectClass, vals, NULL ) ) {
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	{
		int rc;
		AttributeDescription *desc = NULL;
		struct berval rdn = frontendDB->be_schemadn;
		vals[0].bv_val = ber_bvchr( &rdn, '=' );

		if( vals[0].bv_val == NULL ) {
			*text = "improperly configured subschema subentry";
			return LDAP_OTHER;
		}

		vals[0].bv_val++;
		vals[0].bv_len = rdn.bv_len - (vals[0].bv_val - rdn.bv_val);
		rdn.bv_len -= vals[0].bv_len + 1;

		rc = slap_bv2ad( &rdn, &desc, text );

		if( rc != LDAP_SUCCESS ) {
			entry_free( e );
			*text = "improperly configured subschema subentry";
			return LDAP_OTHER;
		}

		nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' );
		assert( nvals[0].bv_val != NULL );
		nvals[0].bv_val++;
		nvals[0].bv_len = frontendDB->be_schemandn.bv_len -
			(nvals[0].bv_val - frontendDB->be_schemandn.bv_val);

		if ( attr_merge_one( e, desc, vals, nvals ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
	}

	{
		char		timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];

		/*
		 * According to RFC 4512:

   Servers SHOULD maintain the 'creatorsName', 'createTimestamp',       
   'modifiersName', and 'modifyTimestamp' attributes for all entries of 
   the DIT. 

		 * to be conservative, we declare schema created 
		 * AND modified at server startup time ...
		 */

		vals[0].bv_val = timebuf;
		vals[0].bv_len = sizeof( timebuf );

		slap_timestamp( &starttime, vals );

		if( attr_merge_one( e, ad_createTimestamp, vals, NULL ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
		if( attr_merge_one( e, ad_modifyTimestamp, vals, NULL ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
	}

	if ( syn_schema_info( e ) 
		|| mr_schema_info( e )
		|| mru_schema_info( e )
		|| at_schema_info( e )
		|| oc_schema_info( e )
		|| cr_schema_info( e ) )
	{
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}
	
	*entry = e;
	return LDAP_SUCCESS;
}
Пример #16
0
/*
 * shmem_startup hook: allocate or attach to shared memory,
 * then load any pre-existing statistics from file.
 */
static void
pgss_shmem_startup(void)
{
	bool		found;
	HASHCTL		info;
	FILE	   *file;
	uint32		header;
	int32		num;
	int32		i;
	int			query_size;
	int			buffer_size;
	char	   *buffer = NULL;

	if (prev_shmem_startup_hook)
		prev_shmem_startup_hook();

	/* reset in case this is a restart within the postmaster */
	pgss = NULL;
	pgss_hash = NULL;

	/*
	 * Create or attach to the shared memory state, including hash table
	 */
	LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);

	pgss = ShmemInitStruct("pg_stat_statements",
						   sizeof(pgssSharedState),
						   &found);

	if (!found)
	{
		/* First time through ... */
		pgss->lock = LWLockAssign();
		pgss->query_size = pgstat_track_activity_query_size;
	}

	/* Be sure everyone agrees on the hash table entry size */
	query_size = pgss->query_size;

	memset(&info, 0, sizeof(info));
	info.keysize = sizeof(pgssHashKey);
	info.entrysize = offsetof(pgssEntry, query) +query_size;
	info.hash = pgss_hash_fn;
	info.match = pgss_match_fn;
	pgss_hash = ShmemInitHash("pg_stat_statements hash",
							  pgss_max, pgss_max,
							  &info,
							  HASH_ELEM | HASH_FUNCTION | HASH_COMPARE);

	LWLockRelease(AddinShmemInitLock);

	/*
	 * If we're in the postmaster (or a standalone backend...), set up a shmem
	 * exit hook to dump the statistics to disk.
	 */
	if (!IsUnderPostmaster)
		on_shmem_exit(pgss_shmem_shutdown, (Datum) 0);

	/*
	 * Attempt to load old statistics from the dump file, if this is the first
	 * time through and we weren't told not to.
	 */
	if (found || !pgss_save)
		return;

	/*
	 * Note: we don't bother with locks here, because there should be no other
	 * processes running when this code is reached.
	 */
	file = AllocateFile(PGSS_DUMP_FILE, PG_BINARY_R);
	if (file == NULL)
	{
		if (errno == ENOENT)
			return;				/* ignore not-found error */
		goto error;
	}

	buffer_size = query_size;
	buffer = (char *) palloc(buffer_size);

	if (fread(&header, sizeof(uint32), 1, file) != 1 ||
		header != PGSS_FILE_HEADER ||
		fread(&num, sizeof(int32), 1, file) != 1)
		goto error;

	for (i = 0; i < num; i++)
	{
		pgssEntry	temp;
		pgssEntry  *entry;

		if (fread(&temp, offsetof(pgssEntry, mutex), 1, file) != 1)
			goto error;

		/* Encoding is the only field we can easily sanity-check */
		if (!PG_VALID_BE_ENCODING(temp.key.encoding))
			goto error;

		/* Previous incarnation might have had a larger query_size */
		if (temp.key.query_len >= buffer_size)
		{
			buffer = (char *) repalloc(buffer, temp.key.query_len + 1);
			buffer_size = temp.key.query_len + 1;
		}

		if (fread(buffer, 1, temp.key.query_len, file) != temp.key.query_len)
			goto error;
		buffer[temp.key.query_len] = '\0';

		/* Clip to available length if needed */
		if (temp.key.query_len >= query_size)
			temp.key.query_len = pg_encoding_mbcliplen(temp.key.encoding,
													   buffer,
													   temp.key.query_len,
													   query_size - 1);
		temp.key.query_ptr = buffer;

		/* make the hashtable entry (discards old entries if too many) */
		entry = entry_alloc(&temp.key);

		/* copy in the actual stats */
		entry->counters = temp.counters;
	}

	pfree(buffer);
	FreeFile(file);
	return;

error:
	ereport(LOG,
			(errcode_for_file_access(),
			 errmsg("could not read pg_stat_statement file \"%s\": %m",
					PGSS_DUMP_FILE)));
	if (buffer)
		pfree(buffer);
	if (file)
		FreeFile(file);
	/* If possible, throw away the bogus file; ignore any error */
	unlink(PGSS_DUMP_FILE);
}
Пример #17
0
int entry_decode(EntryHeader *eh, Entry **e)
#endif
{
	int i, j, nattrs, nvals ALLOW_UNUSED;
	int rc;
	Attribute *a;
	Entry *x;
	const char *text;
	AttributeDescription *ad;
	unsigned char *ptr = (unsigned char *)eh->bv.bv_val;
	BerVarray bptr;

	nattrs = eh->nattrs;
	nvals = eh->nvals;
	x = entry_alloc();
	x->e_attrs = attrs_alloc( nattrs );
	ptr = (unsigned char *)eh->data;
	i = entry_getlen(&ptr);
	x->e_name.bv_val = (char *) ptr;
	x->e_name.bv_len = i;
	ptr += i+1;
	i = entry_getlen(&ptr);
	x->e_nname.bv_val = (char *) ptr;
	x->e_nname.bv_len = i;
	ptr += i+1;
	Debug( LDAP_DEBUG_TRACE,
		"entry_decode: \"%s\"\n",
		x->e_dn );
	x->e_bv = eh->bv;

	a = x->e_attrs;
	bptr = (BerVarray)eh->bv.bv_val;

	while ((i = entry_getlen(&ptr))) {
		struct berval bv;
		bv.bv_len = i;
		bv.bv_val = (char *) ptr;
		ad = NULL;
		rc = slap_bv2ad( &bv, &ad, &text );

		if( rc != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_TRACE,
				"<= entry_decode: str2ad(%s): %s\n", ptr, text );
			rc = slap_bv2undef_ad( &bv, &ad, &text, 0 );

			if( rc != LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_ANY,
					"<= entry_decode: slap_str2undef_ad(%s): %s\n",
						ptr, text );
				return rc;
			}
		}
		ptr += i + 1;
		a->a_desc = ad;
		a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
		j = entry_getlen(&ptr);
		a->a_numvals = j;
		a->a_vals = bptr;

		while (j) {
			i = entry_getlen(&ptr);
			bptr->bv_len = i;
			bptr->bv_val = (char *)ptr;
			ptr += i+1;
			bptr++;
			j--;
		}
		bptr->bv_val = NULL;
		bptr->bv_len = 0;
		bptr++;

		j = entry_getlen(&ptr);
		if (j) {
			a->a_nvals = bptr;
			while (j) {
				i = entry_getlen(&ptr);
				bptr->bv_len = i;
				bptr->bv_val = (char *)ptr;
				ptr += i+1;
				bptr++;
				j--;
			}
			bptr->bv_val = NULL;
			bptr->bv_len = 0;
			bptr++;
		} else {
			a->a_nvals = a->a_vals;
		}
		/* FIXME: This is redundant once a sorted entry is saved into the DB */
		if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
			rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL );
			if ( rc == LDAP_SUCCESS ) {
				a->a_flags |= SLAP_ATTR_SORTED_VALS;
			} else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
				/* should never happen */
				Debug( LDAP_DEBUG_ANY,
					"entry_decode: attributeType %s value #%d provided more than once\n",
					a->a_desc->ad_cname.bv_val, j );
				return rc;
			}
		}
		a = a->a_next;
		nattrs--;
		if ( !nattrs )
			break;
	}

	Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n",
		x->e_dn );
	*e = x;
	return 0;
}
Пример #18
0
/*
 * Read the entries specified in fname and merge the attributes
 * to the user defined baseObject entry. Note that if we find any errors
 * what so ever, we will discard the entire entries, print an
 * error message and return.
 */
static int
read_baseObject( 
	BackendDB	*be,
	const char	*fname )
{
	backsql_info 	*bi = (backsql_info *)be->be_private;
	LDIFFP		*fp;
	int		rc = 0, lmax = 0, ldifrc;
	unsigned long	lineno = 0;
	char		*buf = NULL;

	assert( fname != NULL );

	fp = ldif_open( fname, "r" );
	if ( fp == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"could not open back-sql baseObject "
			"attr file \"%s\" - absolute path?\n",
			fname, 0, 0 );
		perror( fname );
		return LDAP_OTHER;
	}

	bi->sql_baseObject = entry_alloc();
	if ( bi->sql_baseObject == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"read_baseObject_file: entry_alloc failed", 0, 0, 0 );
		ldif_close( fp );
		return LDAP_NO_MEMORY;
	}
	bi->sql_baseObject->e_name = be->be_suffix[0];
	bi->sql_baseObject->e_nname = be->be_nsuffix[0];
	bi->sql_baseObject->e_attrs = NULL;

	while (( ldifrc = ldif_read_record( fp, &lineno, &buf, &lmax )) > 0 ) {
		Entry		*e = str2entry( buf );
		Attribute	*a;

		if( e == NULL ) {
			fprintf( stderr, "back-sql baseObject: "
					"could not parse entry (line=%lu)\n",
					lineno );
			rc = LDAP_OTHER;
			break;
		}

		/* make sure the DN is the database's suffix */
		if ( !be_issuffix( be, &e->e_nname ) ) {
			fprintf( stderr,
				"back-sql: invalid baseObject - "
				"dn=\"%s\" (line=%lu)\n",
				e->e_name.bv_val, lineno );
			entry_free( e );
			rc = LDAP_OTHER;
			break;
		}

		/*
		 * we found a valid entry, so walk thru all the attributes in the
		 * entry, and add each attribute type and description to baseObject
		 */
		for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
			if ( attr_merge( bi->sql_baseObject, a->a_desc,
						a->a_vals,
						( a->a_nvals == a->a_vals ) ?
						NULL : a->a_nvals ) )
			{
				rc = LDAP_OTHER;
				break;
			}
		}

		entry_free( e );
		if ( rc ) {
			break;
		}
	}

	if ( ldifrc < 0 )
		rc = LDAP_OTHER;

	if ( rc ) {
		entry_free( bi->sql_baseObject );
		bi->sql_baseObject = NULL;
	}

	ch_free( buf );

	ldif_close( fp );

	Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n",
			fname, 0, 0 );

	return rc;
}
Пример #19
0
Entry *
entry_dup( Entry *e )
{
	return entry_dup2( entry_alloc(), e );
}