Exemple #1
0
static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
{
    if (level <= TDB_DEBUG_ERROR) {
        va_list ap;
        this_log_level = level;
        char newfmt[strlen(tdb_name(tdb)) + 1 + strlen(fmt) + 1];
        sprintf(newfmt, "%s:%s", tdb_name(tdb), fmt);
        va_start(ap, fmt);
        do_debug_v(newfmt, ap);
        va_end(ap);
    }
}
Exemple #2
0
/*
 * internal validation function, executed by the child.
 */
static int tdb_validate_child(struct tdb_context *tdb,
			      tdb_validate_data_func validate_fn)
{
	int ret = 1;
	int num_entries = 0;
	struct tdb_validation_status v_status;

	v_status.tdb_error = False;
	v_status.bad_freelist = False;
	v_status.bad_entry = False;
	v_status.unknown_key = False;
	v_status.success = True;

	if (!tdb) {
		v_status.tdb_error = True;
		v_status.success = False;
		goto out;
	}

	/* Check if the tdb's freelist is good. */
	if (tdb_validate_freelist(tdb, &num_entries) == -1) {
		v_status.bad_freelist = True;
		v_status.success = False;
		goto out;
	}

	DEBUG(10,("tdb_validate_child: tdb %s freelist has %d entries\n",
		  tdb_name(tdb), num_entries));

	/* Now traverse the tdb to validate it. */
	num_entries = tdb_traverse(tdb, validate_fn, (void *)&v_status);
	if (!v_status.success) {
		goto out;
	} else if (num_entries == -1) {
		v_status.tdb_error = True;
		v_status.success = False;
		goto out;
	}

	DEBUG(10,("tdb_validate_child: tdb %s is good with %d entries\n",
		  tdb_name(tdb), num_entries));
	ret = 0; /* Cache is good. */

out:
	DEBUG(10,   ("tdb_validate_child: summary of validation status:\n"));
	DEBUGADD(10,(" * tdb error: %s\n", v_status.tdb_error ? "yes" : "no"));
	DEBUGADD(10,(" * bad freelist: %s\n",v_status.bad_freelist?"yes":"no"));
	DEBUGADD(10,(" * bad entry: %s\n", v_status.bad_entry ? "yes" : "no"));
	DEBUGADD(10,(" * unknown key: %s\n", v_status.unknown_key?"yes":"no"));
	DEBUGADD(10,(" => overall success: %s\n", v_status.success?"yes":"no"));

	return ret;
}
Exemple #3
0
static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level,
		       const char *fmt, ...)
{
	va_list ap;
	const char *name = tdb_name(tdb);
	const char *prefix = "";

	if (!name)
		name = "unnamed";

	switch (level) {
	case TDB_DEBUG_ERROR:
		prefix = "ERROR: ";
		break;
	case TDB_DEBUG_WARNING:
		prefix = "WARNING: ";
		break;
	case TDB_DEBUG_TRACE:
		return;

	default:
	case TDB_DEBUG_FATAL:
		prefix = "FATAL: ";
		break;
	}

	va_start(ap, fmt);
	fprintf(stderr, "tdb(%s): %s", name, prefix);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
}
Exemple #4
0
static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
{
    va_list ap;
    const char *name = tdb_name(tdb);
    struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context);
    enum ldb_debug_level ldb_level;
    char *message;

    if (ldb == NULL)
        return;

    va_start(ap, fmt);
    message = talloc_vasprintf(ldb, fmt, ap);
    va_end(ap);

    switch (level) {
    case TDB_DEBUG_FATAL:
        ldb_level = LDB_DEBUG_FATAL;
        break;
    case TDB_DEBUG_ERROR:
        ldb_level = LDB_DEBUG_ERROR;
        break;
    case TDB_DEBUG_WARNING:
        ldb_level = LDB_DEBUG_WARNING;
        break;
    case TDB_DEBUG_TRACE:
        ldb_level = LDB_DEBUG_TRACE;
        break;
    default:
        ldb_level = LDB_DEBUG_FATAL;
    }

    ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message);
    talloc_free(message);
}
Exemple #5
0
static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
			 const char *format, ...)
{
	va_list ap;
	char *ptr = NULL;
	int debuglevel = 0;
	int ret;

	switch (level) {
	case TDB_DEBUG_FATAL:
		debuglevel = 0;
		break;
	case TDB_DEBUG_ERROR:
		debuglevel = 1;
		break;
	case TDB_DEBUG_WARNING:
		debuglevel = 2;
		break;
	case TDB_DEBUG_TRACE:
		debuglevel = 5;
		break;
	default:
		debuglevel = 0;
	}

	va_start(ap, format);
	ret = vasprintf(&ptr, format, ap);
	va_end(ap);

	if (ret != -1) {
		const char *name = tdb_name(tdb);
		DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr));
		free(ptr);
	}
}
Exemple #6
0
static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type)
{
	/* Allow tdb_chainlock to be interrupted by an alarm. */
	int ret;
	gotalarm = 0;

	if (timeout) {
		CatchSignal(SIGALRM, gotalarm_sig);
		tdb_setalarm_sigptr(tdb, &gotalarm);
		alarm(timeout);
	}

	if (rw_type == F_RDLCK)
		ret = tdb_chainlock_read(tdb, key);
	else
		ret = tdb_chainlock(tdb, key);

	if (timeout) {
		alarm(0);
		tdb_setalarm_sigptr(tdb, NULL);
		CatchSignal(SIGALRM, SIG_IGN);
		if (gotalarm && (ret != 0)) {
			DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
				timeout, key.dptr, tdb_name(tdb)));
			/* TODO: If we time out waiting for a lock, it might
			 * be nice to use F_GETLK to get the pid of the
			 * process currently holding the lock and print that
			 * as part of the debugging message. -- mbp */
			return -1;
		}
	}

	return ret == 0 ? 0 : -1;
}
Exemple #7
0
static uint32_t _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
					       int keyval,
					       char **retbuf,
					       uint32_t buffer_size)
{
	TDB_DATA kbuf, dbuf;
	char temp[PERFCOUNT_MAX_LEN] = {0};
	char *buf1 = *retbuf;
	uint32_t working_size = 0;
	DATA_BLOB name_index, name;
	bool ok;

	snprintf(temp, sizeof(temp), "%d", keyval);
	kbuf = string_tdb_data(temp);
	dbuf = tdb_fetch(tdb, kbuf);
	if(dbuf.dptr == NULL)
	{
		/* If a key isn't there, just bypass it -- this really shouldn't 
		   happen unless someone's mucking around with the tdb */
		DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n",
			  temp, tdb_name(tdb)));
		return buffer_size;
	}
	/* First encode the name_index */
	working_size = (kbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	ok = push_reg_sz(talloc_tos(), &name_index, (const char *)kbuf.dptr);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name_index.data, working_size);
	buffer_size += working_size;
	/* Now encode the actual name */
	working_size = (dbuf.dsize + 1)*sizeof(uint16_t);
	buf1 = (char *)SMB_REALLOC(buf1, buffer_size + working_size);
	if(!buf1) {
		buffer_size = 0;
		return buffer_size;
	}
	memset(temp, 0, sizeof(temp));
	memcpy(temp, dbuf.dptr, dbuf.dsize);
	SAFE_FREE(dbuf.dptr);
	ok = push_reg_sz(talloc_tos(), &name, temp);
	if (!ok) {
		buffer_size = 0;
		return buffer_size;
	}
	memcpy(buf1+buffer_size, (char *)name.data, working_size);
	buffer_size += working_size;

	*retbuf = buf1;

	return buffer_size;
}
int main(int argc, char *argv[])
{
    struct tdb_context *tdb;
    TDB_DATA key, data;

    plan_tests(13);
    agent = prepare_external_agent();
    if (!agent)
        err(1, "preparing agent");

    tdb = tdb_open_ex("run-traverse-in-transaction.tdb",
                      1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
                      0600, &taplogctx, NULL);
    ok1(tdb);

    key.dsize = strlen("hi");
    key.dptr = (void *)"hi";
    data.dptr = (void *)"world";
    data.dsize = strlen("world");

    ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);

    ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS);

    ok1(tdb_transaction_start(tdb) == 0);
    ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
        == WOULD_HAVE_BLOCKED);
    tdb_traverse(tdb, traverse, NULL);

    /* That should *not* release the transaction lock! */
    ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
        == WOULD_HAVE_BLOCKED);
    tdb_traverse_read(tdb, traverse, NULL);

    /* That should *not* release the transaction lock! */
    ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
        == WOULD_HAVE_BLOCKED);
    ok1(tdb_transaction_commit(tdb) == 0);
    /* Now we should be fine. */
    ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb))
        == SUCCESS);

    tdb_close(tdb);

    return exit_status();
}
/*
 * Write a key with uin64 value
 */
static int partition_metadata_set_uint64(struct ldb_module *module,
					 const char *key, uint64_t value,
					 bool insert)
{
	struct partition_private_data *data;
	struct tdb_context *tdb;
	TDB_DATA tdb_key, tdb_data;
	int tdb_flag;
	char *value_str;
	TALLOC_CTX *tmp_ctx;

	data = talloc_get_type_abort(ldb_module_get_private(module),
				     struct partition_private_data);

	if (!data || !data->metadata || !data->metadata->db) {
		return ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
					"partition_metadata: metadata tdb not initialized");
	}

	tmp_ctx = talloc_new(NULL);
	if (tmp_ctx == NULL) {
		return ldb_module_oom(module);
	}

	tdb = data->metadata->db->tdb;

	value_str = talloc_asprintf(tmp_ctx, "%llu", (unsigned long long)value);
	if (value_str == NULL) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	tdb_key.dptr = (uint8_t *)discard_const_p(char, key);
	tdb_key.dsize = strlen(key);

	tdb_data.dptr = (uint8_t *)value_str;
	tdb_data.dsize = strlen(value_str);

	if (insert) {
		tdb_flag = TDB_INSERT;
	} else {
		tdb_flag = TDB_MODIFY;
	}

	if (tdb_store(tdb, tdb_key, tdb_data, tdb_flag) != 0) {
		int ret;
		char *error_string = talloc_asprintf(tmp_ctx, "%s: tdb_store of key %s failed: %s",
						     tdb_name(tdb), key, tdb_errorstr(tdb));
		ret = ldb_module_error(module, LDB_ERR_OPERATIONS_ERROR,
				       error_string);
		talloc_free(tmp_ctx);
		return ret;
	}

	talloc_free(tmp_ctx);

	return LDB_SUCCESS;
}
Exemple #10
0
static PyObject *tdb_object_repr(PyTdbObject *self)
{
	PyErr_TDB_RAISE_IF_CLOSED(self);
	if (tdb_get_flags(self->ctx) & TDB_INTERNAL) {
		return PyString_FromString("Tdb(<internal>)");
	} else {
		return PyString_FromFormat("Tdb('%s')", tdb_name(self->ctx));
	}
}
Exemple #11
0
static void tdb_log(struct tdb_context *tdb,
		    enum tdb_log_level level,
		    enum TDB_ERROR ecode,
		    const char *message,
		    void *data)
{
	fprintf(stderr, "tdb:%s:%s:%s\n",
		tdb_name(tdb), tdb_errorstr(ecode), message);
}
Exemple #12
0
static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
    TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;

    if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
        fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new));
        failed = 1;
        return 1;
    }
    return 0;
}
Exemple #13
0
static int traverse_copy_fn(struct tdb_context *tdb, TDB_DATA key,
			    TDB_DATA dbuf, void *private_data)
{
	struct tdb_copy_data *data = (struct tdb_copy_data *)private_data;

	if (tdb_store(data->dst, key, dbuf, TDB_INSERT) != 0) {
		DEBUG(4, ("Failed to insert into %s: %s\n", tdb_name(data->dst),
			  strerror(errno)));
		data->success = False;
		return 1;
	}
	return 0;
}
Exemple #14
0
static void tdb_log(struct tdb_context *tdb,
		    enum tdb_log_level level,
		    enum TDB_ERROR ecode,
		    const char *message,
		    void *data)
{
	printf("tdb:%s:%s:%s\n",
	       tdb_name(tdb), tdb_errorstr(ecode), message);
	fflush(stdout);
#if 0
	{
		char str[200];
		signal(SIGUSR1, SIG_IGN);
		sprintf(str,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
		system(str);
	}
#endif	
}
Exemple #15
0
static void ltdb_log_fn(struct tdb_context *tdb,
                        enum tdb_log_level level,
                        const char *message,
                        struct ldb_context *ldb)
{
    enum ldb_debug_level ldb_level;
    const char *name = tdb_name(tdb);

    switch (level) {
    case TDB_LOG_WARNING:
        ldb_level = LDB_DEBUG_WARNING;
    case TDB_LOG_USE_ERROR:
    case TDB_LOG_ERROR:
        ldb_level = LDB_DEBUG_FATAL;
        break;
    default:
        ldb_level = LDB_DEBUG_FATAL;
    }

    ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message);
}
Exemple #16
0
/*
  we've made a modification to a dn - possibly reindex and
  update sequence number
*/
static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
{
	int ret = LDB_SUCCESS;
	struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private);

	/* only allow modifies inside a transaction, otherwise the
	 * ldb is unsafe */
	if (ltdb->in_transaction == 0) {
		ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction");
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (ldb_dn_is_special(dn) &&
	    (ldb_dn_check_special(dn, LTDB_INDEXLIST) ||
	     ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) )
	{
		if (ltdb->warn_reindex) {
			ldb_debug(ldb_module_get_ctx(module),
				LDB_DEBUG_ERROR, "Reindexing %s due to modification on %s",
				tdb_name(ltdb->tdb), ldb_dn_get_linearized(dn));
		}
		ret = ltdb_reindex(module);
	}

	/* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
	if (ret == LDB_SUCCESS &&
	    !(ldb_dn_is_special(dn) &&
	      ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
		ret = ltdb_increase_sequence_number(module);
	}

	/* If the modify was to @OPTIONS, reload the cache */
	if (ret == LDB_SUCCESS &&
	    ldb_dn_is_special(dn) &&
	    (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
		ret = ltdb_cache_reload(module);
	}

	return ret;
}
Exemple #17
0
static void tdb_wrap_log(struct tdb_context *tdb,
			 enum tdb_log_level level,
			 const char *message,
			 void *unused)
{
	int dl;
	const char *name = tdb_name(tdb);

	switch (level) {
	case TDB_LOG_USE_ERROR:
	case TDB_LOG_ERROR:
		dl = 0;
		break;
	case TDB_LOG_WARNING:
		dl = 2;
		break;
	default:
		dl = 0;
	}

	DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", message));
}
Exemple #18
0
static enum agent_return do_operation(enum operation op, const char *name)
{
	TDB_DATA k;
	enum agent_return ret;
	TDB_DATA data;
	enum TDB_ERROR ecode;
	union tdb_attribute cif;

	if (op != OPEN && op != OPEN_WITH_HOOK && !tdb) {
		diag("external: No tdb open!");
		return OTHER_FAILURE;
	}

	diag("external: %s", operation_name(op));

	k = tdb_mkdata(name, strlen(name));

	locking_would_block = 0;
	switch (op) {
	case OPEN:
		if (tdb) {
			diag("Already have tdb %s open", tdb_name(tdb));
			return OTHER_FAILURE;
		}
		tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &tap_log_attr);
		if (!tdb) {
			if (!locking_would_block)
				diag("Opening tdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case OPEN_WITH_HOOK:
		if (tdb) {
			diag("Already have tdb %s open", tdb_name(tdb));
			return OTHER_FAILURE;
		}
		cif.openhook.base.attr = TDB_ATTRIBUTE_OPENHOOK;
		cif.openhook.base.next = &tap_log_attr;
		cif.openhook.fn = clear_if_first;
		tdb = tdb_open(name, TDB_DEFAULT, O_RDWR, 0, &cif);
		if (!tdb) {
			if (!locking_would_block)
				diag("Opening tdb gave %s", strerror(errno));
			forget_locking();
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case FETCH:
		ecode = tdb_fetch(tdb, k, &data);
		if (ecode == TDB_ERR_NOEXIST) {
			ret = FAILED;
		} else if (ecode < 0) {
			ret = OTHER_FAILURE;
		} else if (!tdb_deq(data, k)) {
			ret = OTHER_FAILURE;
			external_agent_free(data.dptr);
		} else {
			ret = SUCCESS;
			external_agent_free(data.dptr);
		}
		break;
	case STORE:
		ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_START:
		ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_COMMIT:
		ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE;
		break;
	case NEEDS_RECOVERY:
		ret = external_agent_needs_rec(tdb);
		break;
	case CHECK:
		ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case CLOSE:
		ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		tdb = NULL;
		break;
	case SEND_SIGNAL:
		/* We do this async */
		ret = SUCCESS;
		break;
	default:
		ret = OTHER_FAILURE;
	}

	if (locking_would_block)
		ret = WOULD_HAVE_BLOCKED;

	return ret;
}
Exemple #19
0
struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
			       struct loadparm_context *lp_ctx,
			       const char *name,
			       int hash_size, int tdb_flags,
			       int open_flags, mode_t mode,
			       enum dbwrap_lock_order lock_order,
			       uint64_t dbrwap_flags)
{
	struct db_context *result = NULL;
	struct db_tdb_ctx *db_tdb;
	struct stat st;

	result = talloc_zero(mem_ctx, struct db_context);
	if (result == NULL) {
		DEBUG(0, ("talloc failed\n"));
		goto fail;
	}

	result->private_data = db_tdb = talloc(result, struct db_tdb_ctx);
	if (db_tdb == NULL) {
		DEBUG(0, ("talloc failed\n"));
		goto fail;
	}
	result->lock_order = lock_order;

	if (hash_size == 0) {
		hash_size = lpcfg_tdb_hash_size(lp_ctx, name);
	}

	db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size,
				     lpcfg_tdb_flags(lp_ctx, tdb_flags),
				     open_flags, mode);
	if (db_tdb->wtdb == NULL) {
		DEBUG(3, ("Could not open tdb: %s\n", strerror(errno)));
		goto fail;
	}

	ZERO_STRUCT(db_tdb->id);

	if (fstat(tdb_fd(db_tdb->wtdb->tdb), &st) == -1) {
		DEBUG(3, ("fstat failed: %s\n", strerror(errno)));
		goto fail;
	}
	db_tdb->id.dev = st.st_dev;
	db_tdb->id.ino = st.st_ino;

	result->fetch_locked = db_tdb_fetch_locked;
	result->try_fetch_locked = db_tdb_try_fetch_locked;
	result->traverse = db_tdb_traverse;
	result->traverse_read = db_tdb_traverse_read;
	result->parse_record = db_tdb_parse;
	result->get_seqnum = db_tdb_get_seqnum;
	result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
	result->transaction_start = db_tdb_transaction_start;
	result->transaction_start_nonblock = db_tdb_transaction_start_nonblock;
	result->transaction_commit = db_tdb_transaction_commit;
	result->transaction_cancel = db_tdb_transaction_cancel;
	result->exists = db_tdb_exists;
	result->wipe = db_tdb_wipe;
	result->id = db_tdb_id;
	result->check = db_tdb_check;
	result->name = tdb_name(db_tdb->wtdb->tdb);
	result->hash_size = hash_size;
	return result;

 fail:
	TALLOC_FREE(result);
	return NULL;
}
Exemple #20
0
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state)
{
	int ret, i, j;
	struct ldb_dn *dn = state;
	struct ldb_message *msg = talloc_zero(NULL, struct ldb_message);
	struct ldb_val dbuf = {
		.data = _dbuf.dptr,
		.length = _dbuf.dsize,
	};
	struct ldb_ldif ldif = {
		.msg = msg,
		.changetype = LDB_CHANGETYPE_NONE
	};
	if (!msg) {
		return -1;
	}

	ret = ldb_unpack_data(ldb, &dbuf, msg);
	if (ret != 0) {
		fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr);
		TALLOC_FREE(msg);
		return 0;
	}

	if (dn && ldb_dn_compare(msg->dn, dn) != 0) {
		TALLOC_FREE(msg);
		return 0;
	}

	if (!show_index && ldb_dn_is_special(msg->dn)) {
		const char *dn_lin = ldb_dn_get_linearized(msg->dn);
		if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) {
			/*
			  the user has asked not to show index
			  records. Also exclude BASEINFO as it
			  contains meta-data which will be re-created
			  if this database is restored
			 */
			TALLOC_FREE(msg);
			return 0;
		}
	}

	if (!validate_contents || ldb_dn_is_special(msg->dn)) {
		ldb_ldif_write_file(ldb, stdout, &ldif);
		TALLOC_FREE(msg);
		return 0;
	}

	for (i=0;i<msg->num_elements;i++) {
		const struct ldb_schema_attribute *a;

		a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name);
		for (j=0;j<msg->elements[i].num_values;j++) {
			struct ldb_val v;
			ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v);
			if (ret != 0) {
				v = msg->elements[i].values[j];
				if (ldb_should_b64_encode(ldb, &v)) {
					v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length);
					v.length = strlen((char *)v.data);
				}
				fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n",
					ldb_dn_get_linearized(msg->dn),
					msg->elements[i].name,
					j, (int)v.length, (int)v.length,
					v.data);
				TALLOC_FREE(msg);
				return 0;
			}
		}
	}
	ldb_ldif_write_file(ldb, stdout, &ldif);
	TALLOC_FREE(msg);

	return 0;
}

static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level,
		       const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);

static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level,
		       const char *fmt, ...)
{
	va_list ap;
	const char *name = tdb_name(tdb);
	const char *prefix = "";

	if (!name)
		name = "unnamed";

	switch (level) {
	case TDB_DEBUG_ERROR:
		prefix = "ERROR: ";
		break;
	case TDB_DEBUG_WARNING:
		prefix = "WARNING: ";
		break;
	case TDB_DEBUG_TRACE:
		return;

	default:
	case TDB_DEBUG_FATAL:
		prefix = "FATAL: ";
		break;
	}

	va_start(ap, fmt);
	fprintf(stderr, "tdb(%s): %s", name, prefix);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
}
Exemple #21
0
static PyObject *obj_get_filename(PyTdbObject *self, void *closure)
{
	PyErr_TDB_RAISE_IF_CLOSED(self);
	return PyString_FromString(tdb_name(self->ctx));
}
Exemple #22
0
/*
 * tdb validation function.
 * returns 0 if tdb is ok, != 0 if it isn't.
 * this function expects an opened tdb.
 */
int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
{
	pid_t child_pid = -1;
	int child_status = 0;
	int wait_pid = 0;
	int ret = 1;

	if (tdb == NULL) {
		DEBUG(1, ("Error: tdb_validate called with tdb == NULL\n"));
		return ret;
	}

	DEBUG(5, ("tdb_validate called for tdb '%s'\n", tdb_name(tdb)));

	/* fork and let the child do the validation.
	 * benefit: no need to twist signal handlers and panic functions.
	 * just let the child panic. we catch the signal. */

	DEBUG(10, ("tdb_validate: forking to let child do validation.\n"));
	child_pid = sys_fork();
	if (child_pid == 0) {
		/* child code */
		DEBUG(10, ("tdb_validate (validation child): created\n"));
		DEBUG(10, ("tdb_validate (validation child): "
			   "calling tdb_validate_child\n"));
		exit(tdb_validate_child(tdb, validate_fn));
	}
	else if (child_pid < 0) {
		DEBUG(1, ("tdb_validate: fork for validation failed.\n"));
		goto done;
	}

	/* parent */

	DEBUG(10, ("tdb_validate: fork succeeded, child PID = %u\n",
		(unsigned int)child_pid));

	DEBUG(10, ("tdb_validate: waiting for child to finish...\n"));
	while  ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
		if (errno == EINTR) {
			DEBUG(10, ("tdb_validate: got signal during waitpid, "
				   "retrying\n"));
			errno = 0;
			continue;
		}
		DEBUG(1, ("tdb_validate: waitpid failed with error '%s'.\n",
			  strerror(errno)));
		goto done;
	}
	if (wait_pid != child_pid) {
		DEBUG(1, ("tdb_validate: waitpid returned pid %d, "
			  "but %u was expected\n", wait_pid, (unsigned int)child_pid));
		goto done;
	}

	DEBUG(10, ("tdb_validate: validating child returned.\n"));
	if (WIFEXITED(child_status)) {
		DEBUG(10, ("tdb_validate: child exited, code %d.\n",
			   WEXITSTATUS(child_status)));
		ret = WEXITSTATUS(child_status);
	}
	if (WIFSIGNALED(child_status)) {
		DEBUG(10, ("tdb_validate: child terminated by signal %d\n",
			   WTERMSIG(child_status)));
#ifdef WCOREDUMP
		if (WCOREDUMP(child_status)) {
			DEBUGADD(10, ("core dumped\n"));
		}
#endif
		ret = WTERMSIG(child_status);
	}
	if (WIFSTOPPED(child_status)) {
		DEBUG(10, ("tdb_validate: child was stopped by signal %d\n",
			   WSTOPSIG(child_status)));
		ret = WSTOPSIG(child_status);
	}

done:
	DEBUG(5, ("tdb_validate returning code '%d' for tdb '%s'\n", ret,
		  tdb_name(tdb)));

	return ret;
}
Exemple #23
0
static enum agent_return do_operation(enum operation op, const char *name)
{
	TDB_DATA k;
	enum agent_return ret;
	TDB_DATA data;

	if (op != OPEN && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) {
		diag("external: No tdb open!");
		return OTHER_FAILURE;
	}

	k.dptr = (void *)name;
	k.dsize = strlen(name);

	locking_would_block = 0;
	switch (op) {
	case OPEN:
		if (tdb) {
			diag("Already have tdb %s open", tdb_name(tdb));
			return OTHER_FAILURE;
		}
		tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0,
				  &taplogctx, NULL);
		if (!tdb) {
			if (!locking_would_block)
				diag("Opening tdb gave %s", strerror(errno));
			ret = OTHER_FAILURE;
		} else
			ret = SUCCESS;
		break;
	case OPEN_WITH_CLEAR_IF_FIRST:
		if (tdb)
			return OTHER_FAILURE;
		tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0,
				  &taplogctx, NULL);
		ret = tdb ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_START:
		ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case FETCH:
		data = tdb_fetch(tdb, k);
		if (data.dptr == NULL) {
			if (tdb_error(tdb) == TDB_ERR_NOEXIST)
				ret = FAILED;
			else
				ret = OTHER_FAILURE;
		} else if (data.dsize != k.dsize
			   || memcmp(data.dptr, k.dptr, k.dsize) != 0) {
			ret = OTHER_FAILURE;
		} else {
			ret = SUCCESS;
		}
		free(data.dptr);
		break;
	case STORE:
		ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case TRANSACTION_COMMIT:
		ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE;
		break;
	case CHECK:
		ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE;
		break;
	case NEEDS_RECOVERY:
		ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED;
		break;
	case CLOSE:
		ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE;
		tdb = NULL;
		break;
	default:
		ret = OTHER_FAILURE;
	}

	if (locking_would_block)
		ret = WOULD_HAVE_BLOCKED;

	return ret;
}