コード例 #1
0
ファイル: dbwrap_util.c プロジェクト: ebrainte/Samba
/**
 * Wrap db action(s) into a transaction.
 */
NTSTATUS dbwrap_trans_do(struct db_context *db,
			 NTSTATUS (*action)(struct db_context *, void *),
			 void *private_data)
{
	int res;
	NTSTATUS status;

	res = dbwrap_transaction_start(db);
	if (res != 0) {
		DEBUG(5, ("transaction_start failed\n"));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	status = action(db, private_data);
	if (!NT_STATUS_IS_OK(status)) {
		if (dbwrap_transaction_cancel(db) != 0) {
			smb_panic("Cancelling transaction failed");
		}
		return status;
	}

	res = dbwrap_transaction_commit(db);
	if (res == 0) {
		return NT_STATUS_OK;
	}

	DEBUG(2, ("transaction_commit failed\n"));
	return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
コード例 #2
0
ファイル: idmap_tdb.c プロジェクト: DanilKorotenko/samba
static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom)
{
	uint32_t low_uid;
	uint32_t low_gid;
	bool update_uid = false;
	bool update_gid = false;
	struct idmap_tdb_common_context *ctx;
	NTSTATUS status;

	ctx = talloc_get_type(dom->private_data,
			      struct idmap_tdb_common_context);

	status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_uid);
	if (!NT_STATUS_IS_OK(status) || low_uid < dom->low_id) {
		update_uid = true;
	}

	status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_gid);
	if (!NT_STATUS_IS_OK(status) || low_gid < dom->low_id) {
		update_gid = true;
	}

	if (!update_uid && !update_gid) {
		return NT_STATUS_OK;
	}

	if (dbwrap_transaction_start(ctx->db) != 0) {
		DEBUG(0, ("Unable to start upgrade transaction!\n"));
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	if (update_uid) {
		status = dbwrap_store_uint32_bystring(ctx->db, HWM_USER,
						      dom->low_id);
		if (!NT_STATUS_IS_OK(status)) {
			dbwrap_transaction_cancel(ctx->db);
			DEBUG(0, ("Unable to initialise user hwm in idmap "
				  "database: %s\n", nt_errstr(status)));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (update_gid) {
		status = dbwrap_store_uint32_bystring(ctx->db, HWM_GROUP,
						      dom->low_id);
		if (!NT_STATUS_IS_OK(status)) {
			dbwrap_transaction_cancel(ctx->db);
			DEBUG(0, ("Unable to initialise group hwm in idmap "
				  "database: %s\n", nt_errstr(status)));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (dbwrap_transaction_commit(ctx->db) != 0) {
		DEBUG(0, ("Unable to commit upgrade transaction!\n"));
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	return NT_STATUS_OK;
}
コード例 #3
0
static bool open_db(struct idmap_tdb_common_context *ctx)
{
	NTSTATUS status;
	char *db_path;

	if(ctx->db) {
		/* already open */
		return true;
	}

	db_path = talloc_asprintf(talloc_tos(), "%s/idmap_test.tdb",
				  lp_private_dir());
	if(!db_path) {
		DEBUG(0, ("Out of memory!\n"));
		return false;
	}

	ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT,
			  O_RDWR | O_CREAT, 0600,
			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);

	if(!ctx->db) {
		DEBUG(0, ("Failed to open database: %s\n", strerror(errno)));
		return false;
	}

	if(dbwrap_transaction_start(ctx->db) != 0) {
		DEBUG(0, ("Failed to start transaction!\n"));
		return false;
	}

	status = dbwrap_store_uint32_bystring(ctx->db, ctx->hwmkey_uid,
					      LOW_ID);
	if(!NT_STATUS_IS_OK(status)) {
		dbwrap_transaction_cancel(ctx->db);
		return false;
	}

	status = dbwrap_store_uint32_bystring(ctx->db, ctx->hwmkey_gid,
					      LOW_ID);
	if(!NT_STATUS_IS_OK(status)) {
		dbwrap_transaction_cancel(ctx->db);
		return false;
	}

	if(dbwrap_transaction_commit(ctx->db) != 0) {
		DEBUG(0, ("Failed to commit transaction!\n"));
		return false;
	}

	return true;
}
コード例 #4
0
ファイル: machine_sid.c プロジェクト: AIdrifter/samba
/* return our global_sam_sid */
struct dom_sid *get_global_sam_sid(void)
{
	struct db_context *db;

	if (global_sam_sid != NULL)
		return global_sam_sid;

	/*
	 * memory for global_sam_sid is allocated in
	 * pdb_generate_sam_sid() as needed
	 *
	 * Note: this is guarded by a transaction
	 *       to prevent races on startup which
	 *       can happen with some dbwrap backends
	 */

	db = secrets_db_ctx();
	if (!db) {
		smb_panic("could not open secrets db");
	}

	if (dbwrap_transaction_start(db) != 0) {
		smb_panic("could not start transaction on secrets db");
	}

	if (!(global_sam_sid = pdb_generate_sam_sid())) {
		dbwrap_transaction_cancel(db);
		smb_panic("could not generate a machine SID");
	}

	if (dbwrap_transaction_commit(db) != 0) {
		smb_panic("could not start commit secrets db");
	}

	return global_sam_sid;
}
コード例 #5
0
ファイル: dbwrap_torture.c プロジェクト: AIdrifter/samba
static void test_store_records(struct db_context *db, struct tevent_context *ev)
{
	TDB_DATA key;
	uint32_t *counters;
	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	struct timeval start;

	key = string_term_tdb_data("testkey");

	start = timeval_current();
	while ((timelimit == 0) || (timeval_elapsed(&start) < timelimit)) {
		struct db_record *rec;
		TDB_DATA data;
		TDB_DATA value;
		int ret;
		NTSTATUS status;

		if (!no_trans) {
			if (verbose) DEBUG(1, ("starting transaction\n"));
			ret = dbwrap_transaction_start(db);
			if (ret != 0) {
				DEBUG(0, ("Failed to start transaction on node "
					  "%d\n", pnn));
				goto fail;
			}
			if (verbose) DEBUG(1, ("transaction started\n"));
			do_sleep(torture_delay);
		}

		if (verbose) DEBUG(1, ("calling fetch_lock\n"));
		rec = dbwrap_fetch_locked(db, tmp_ctx, key);
		if (rec == NULL) {
			DEBUG(0, ("Failed to fetch record\n"));
			goto fail;
		}
		if (verbose) DEBUG(1, ("fetched record ok\n"));
		do_sleep(torture_delay);
		value = dbwrap_record_get_value(rec);

		data.dsize = MAX(value.dsize, sizeof(uint32_t) * (pnn+1));
		data.dptr = (unsigned char *)talloc_zero_size(tmp_ctx,
							      data.dsize);
		if (data.dptr == NULL) {
			DEBUG(0, ("Failed to allocate data\n"));
			goto fail;
		}
		memcpy(data.dptr, value.dptr, value.dsize);

		counters = (uint32_t *)data.dptr;

		/* bump our counter */
		counters[pnn]++;

		if (verbose) DEBUG(1, ("storing data\n"));
		status = dbwrap_record_store(rec, data, TDB_REPLACE);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to store record\n"));
			if (!no_trans) {
				ret = dbwrap_transaction_cancel(db);
				if (ret != 0) {
					DEBUG(0, ("Error cancelling transaction.\n"));
				}
			}
			goto fail;
		}
		talloc_free(rec);
		if (verbose) DEBUG(1, ("stored data ok\n"));
		do_sleep(torture_delay);

		if (!no_trans) {
			if (verbose) DEBUG(1, ("calling transaction_commit\n"));
			ret = dbwrap_transaction_commit(db);
			if (ret != 0) {
				DEBUG(0, ("Failed to commit transaction\n"));
				goto fail;
			}
			if (verbose) DEBUG(1, ("transaction committed\n"));
		}

		/* store the counters and verify that they are sane */
		if (verbose || (pnn == 0)) {
			if (!check_counters(db, data)) {
				goto fail;
			}
		}
		talloc_free(data.dptr);

		do_sleep(torture_delay);
	}

	goto done;

fail:
	success = false;

done:
	talloc_free(tmp_ctx);
	return;
}
コード例 #6
0
ファイル: dbwrap_cache.c プロジェクト: Gazzonyx/samba
static int dbwrap_cache_transaction_commit(struct db_context *db)
{
	struct db_cache_ctx *ctx = talloc_get_type_abort(
		db->private_data, struct db_cache_ctx);
	return dbwrap_transaction_commit(ctx->backing);
}
コード例 #7
0
ファイル: pdb_tdb.c プロジェクト: Alexander--/samba
/***************************************************************************
 Renames a struct samu
 - check for the posix user/rename user script
 - Add and lock the new user record
 - rename the posix user
 - rewrite the rid->username record
 - delete the old user
 - unlock the new user record
***************************************************************************/
static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
					  struct samu *old_acct,
					  const char *newname)
{
	struct samu      *new_acct = NULL;
	char *rename_script = NULL;
	int              rename_ret;
	fstring          oldname_lower;
	fstring          newname_lower;

	/* can't do anything without an external script */

	if ( !(new_acct = samu_new( talloc_tos() )) ) {
		return NT_STATUS_NO_MEMORY;
	}

	rename_script = lp_rename_user_script(new_acct);
	if (!rename_script) {
		TALLOC_FREE(new_acct);
		return NT_STATUS_NO_MEMORY;
	}
	if (!*rename_script) {
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;
	}

	if ( !pdb_copy_sam_account(new_acct, old_acct)
		|| !pdb_set_username(new_acct, newname, PDB_CHANGED))
	{
		TALLOC_FREE(new_acct);
		return NT_STATUS_NO_MEMORY;
	}

	/* open the database */
	if ( !tdbsam_open( tdbsam_filename ) ) {
		DEBUG(0, ("tdbsam_getsampwnam: failed to open %s!\n",
			  tdbsam_filename));
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;
	}

	if (dbwrap_transaction_start(db_sam) != 0) {
		DEBUG(0, ("Could not start transaction\n"));
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;

	}

	/* add the new account and lock it */
	if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
		goto cancel;
	}

	/* Rename the posix user.  Follow the semantics of _samr_create_user()
	   so that we lower case the posix name but preserve the case in passdb */

	fstrcpy( oldname_lower, pdb_get_username(old_acct) );
	if (!strlower_m( oldname_lower )) {
		goto cancel;
	}

	fstrcpy( newname_lower, newname );
	if (!strlower_m( newname_lower )) {
		goto cancel;
	}

	rename_script = talloc_string_sub2(new_acct,
				rename_script,
				"%unew",
				newname_lower,
				true,
				false,
				true);
	if (!rename_script) {
		goto cancel;
	}
	rename_script = talloc_string_sub2(new_acct,
				rename_script,
				"%uold",
				oldname_lower,
				true,
				false,
				true);
	if (!rename_script) {
		goto cancel;
	}
	rename_ret = smbrun(rename_script, NULL, NULL);

	DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n",
				rename_script, rename_ret));

	if (rename_ret != 0) {
		goto cancel;
	}

	smb_nscd_flush_user_cache();

	/* rewrite the rid->username record */

	if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
		goto cancel;
	}

	tdb_delete_samacct_only( old_acct );

	if (dbwrap_transaction_commit(db_sam) != 0) {
		/*
		 * Ok, we're screwed. We've changed the posix account, but
		 * could not adapt passdb.tdb. Shall we change the posix
		 * account back?
		 */
		DEBUG(0, ("transaction_commit failed\n"));
		TALLOC_FREE(new_acct);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;	
	}

	TALLOC_FREE(new_acct );
	return NT_STATUS_OK;

 cancel:
	if (dbwrap_transaction_cancel(db_sam) != 0) {
		smb_panic("transaction_cancel failed");
	}

	TALLOC_FREE(new_acct);

	return NT_STATUS_ACCESS_DENIED;	
}
コード例 #8
0
ファイル: pdb_tdb.c プロジェクト: Alexander--/samba
static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
			   int flag)
{
	uint32_t oldrid;
	uint32_t newrid;

	if (!(newrid = pdb_get_user_rid(newpwd))) {
		DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n",
			 pdb_get_username(newpwd)));
		return False;
	}

	oldrid = newrid;

	/* open the database */

	if ( !tdbsam_open( tdbsam_filename ) ) {
		DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
		return False;
	}

	if (dbwrap_transaction_start(db_sam) != 0) {
		DEBUG(0, ("Could not start transaction\n"));
		return false;
	}

	/* If we are updating, we may be changing this users RID. Retrieve the old RID
	   so we can check. */

	if (flag == TDB_MODIFY) {
		struct samu *account = samu_new(talloc_tos());
		if (account == NULL) {
			DEBUG(0,("tdb_update_sam: samu_new() failed\n"));
			goto cancel;
		}
		if (!NT_STATUS_IS_OK(tdbsam_getsampwnam(my_methods, account, pdb_get_username(newpwd)))) {
			DEBUG(0,("tdb_update_sam: tdbsam_getsampwnam() for %s failed\n",
				pdb_get_username(newpwd)));
			TALLOC_FREE(account);
			goto cancel;
		}
		if (!(oldrid = pdb_get_user_rid(account))) {
			DEBUG(0,("tdb_update_sam: pdb_get_user_rid() failed\n"));
			TALLOC_FREE(account);
			goto cancel;
		}
		TALLOC_FREE(account);
	}

	/* Update the new samu entry. */
	if (!tdb_update_samacct_only(newpwd, flag)) {
		goto cancel;
	}

	/* Now take care of the case where the RID changed. We need
	 * to delete the old RID key and add the new. */

	if (flag == TDB_MODIFY && newrid != oldrid) { 
		fstring keystr;

		/* Delete old RID key */
		DEBUG(10, ("tdb_update_sam: Deleting key for RID %u\n", oldrid));
		fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, oldrid);
		if (!NT_STATUS_IS_OK(dbwrap_delete_bystring(db_sam, keystr))) {
			DEBUG(0, ("tdb_update_sam: Can't delete %s\n", keystr));
			goto cancel;
		}
		/* Insert new RID key */
		DEBUG(10, ("tdb_update_sam: Inserting key for RID %u\n", newrid));
		if (!tdb_update_ridrec_only(newpwd, TDB_INSERT)) {
			goto cancel;
		}
	} else {
		DEBUG(10, ("tdb_update_sam: %s key for RID %u\n",
			flag == TDB_MODIFY ? "Updating" : "Inserting", newrid));
		if (!tdb_update_ridrec_only(newpwd, flag)) {
			goto cancel;
		}
	}

	if (dbwrap_transaction_commit(db_sam) != 0) {
		DEBUG(0, ("Could not commit transaction\n"));
		return false;
	}

	return true;

 cancel:
	if (dbwrap_transaction_cancel(db_sam) != 0) {
		smb_panic("transaction_cancel failed");
	}
	return false;
}
コード例 #9
0
ファイル: pdb_tdb.c プロジェクト: Alexander--/samba
static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods,
					  struct samu *sam_pass)
{
	NTSTATUS        nt_status = NT_STATUS_UNSUCCESSFUL;
	fstring 	keystr;
	uint32_t	rid;
	fstring		name;

	/* open the database */

	if ( !tdbsam_open( tdbsam_filename ) ) {
		DEBUG(0,("tdbsam_delete_sam_account: failed to open %s!\n",
			 tdbsam_filename));
		return NT_STATUS_ACCESS_DENIED;
	}

	fstrcpy(name, pdb_get_username(sam_pass));
	if (!strlower_m(name)) {
		return NT_STATUS_INVALID_PARAMETER;
	}

  	/* set the search key */

	fstr_sprintf(keystr, "%s%s", USERPREFIX, name);

	rid = pdb_get_user_rid(sam_pass);

	/* it's outaa here!  8^) */

	if (dbwrap_transaction_start(db_sam) != 0) {
		DEBUG(0, ("Could not start transaction\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	nt_status = dbwrap_delete_bystring(db_sam, keystr);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(5, ("Error deleting entry from tdb passwd "
			  "database: %s!\n", nt_errstr(nt_status)));
		goto cancel;
	}

  	/* set the search key */

	fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, rid);

	/* it's outaa here!  8^) */

	nt_status = dbwrap_delete_bystring(db_sam, keystr);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(5, ("Error deleting entry from tdb rid "
			  "database: %s!\n", nt_errstr(nt_status)));
		goto cancel;
	}

	if (dbwrap_transaction_commit(db_sam) != 0) {
		DEBUG(0, ("Could not commit transaction\n"));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	return NT_STATUS_OK;

 cancel:
	if (dbwrap_transaction_cancel(db_sam) != 0) {
		smb_panic("transaction_cancel failed");
	}

	return nt_status;
}
コード例 #10
0
ファイル: pdb_tdb.c プロジェクト: Alexander--/samba
static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32_t from)
{
	struct tdbsam_convert_state state;
	struct db_context *db = NULL;
	NTSTATUS status;

	/* We only need the update backup for local db's. */
	if (db_is_local(name) && !tdbsam_convert_backup(name, pp_db)) {
		DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name));
		return false;
	}

	db = *pp_db;
	state.from = from;
	state.success = true;

	if (dbwrap_transaction_start(db) != 0) {
		DEBUG(0, ("tdbsam_convert: Could not start transaction\n"));
		return false;
	}

	if (!tdbsam_upgrade_next_rid(db)) {
		DEBUG(0, ("tdbsam_convert: tdbsam_upgrade_next_rid failed\n"));
		goto cancel;
	}

	status = dbwrap_traverse(db, tdbsam_convert_one, &state, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("tdbsam_convert: traverse failed\n"));
		goto cancel;
	}

	if (!state.success) {
		DEBUG(0, ("tdbsam_convert: Converting records failed\n"));
		goto cancel;
	}

	status = dbwrap_store_int32_bystring(db, TDBSAM_VERSION_STRING,
					     TDBSAM_VERSION);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("tdbsam_convert: Could not store tdbsam version: "
			  "%s\n", nt_errstr(status)));
		goto cancel;
	}

	status = dbwrap_store_int32_bystring(db, TDBSAM_MINOR_VERSION_STRING,
					     TDBSAM_MINOR_VERSION);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor "
			  "version: %s\n", nt_errstr(status)));
		goto cancel;
	}

	if (dbwrap_transaction_commit(db) != 0) {
		DEBUG(0, ("tdbsam_convert: Could not commit transaction\n"));
		return false;
	}

	return true;

 cancel:
	if (dbwrap_transaction_cancel(db) != 0) {
		smb_panic("tdbsam_convert: transaction_cancel failed");
	}

	return false;
}
コード例 #11
0
ファイル: pdb_tdb.c プロジェクト: Alexander--/samba
static bool tdbsam_convert_backup(const char *dbname, struct db_context **pp_db)
{
	TALLOC_CTX *frame = talloc_stackframe();
	const char *tmp_fname = NULL;
	struct db_context *tmp_db = NULL;
	struct db_context *orig_db = *pp_db;
	struct tdbsam_backup_state bs;
	NTSTATUS status;

	tmp_fname = talloc_asprintf(frame, "%s.tmp", dbname);
	if (!tmp_fname) {
		TALLOC_FREE(frame);
		return false;
	}

	unlink(tmp_fname);

	/* Remember to open this on the NULL context. We need
	 * it to stay around after we return from here. */

	tmp_db = db_open(NULL, tmp_fname, 0,
			 TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
			 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
	if (tmp_db == NULL) {
		DEBUG(0, ("tdbsam_convert_backup: Failed to create backup TDB passwd "
			  "[%s]\n", tmp_fname));
		TALLOC_FREE(frame);
		return false;
	}

	if (dbwrap_transaction_start(orig_db) != 0) {
		DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (1)\n"));
		unlink(tmp_fname);
		TALLOC_FREE(tmp_db);
		TALLOC_FREE(frame);
		return false;
	}
	if (dbwrap_transaction_start(tmp_db) != 0) {
		DEBUG(0, ("tdbsam_convert_backup: Could not start transaction (2)\n"));
		dbwrap_transaction_cancel(orig_db);
		unlink(tmp_fname);
		TALLOC_FREE(tmp_db);
		TALLOC_FREE(frame);
		return false;
	}

	bs.new_db = tmp_db;
	bs.success = true;

        status = dbwrap_traverse(orig_db, backup_copy_fn, (void *)&bs, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("tdbsam_convert_backup: traverse failed\n"));
                goto cancel;
        }

	if (!bs.success) {
		DEBUG(0, ("tdbsam_convert_backup: Rewriting records failed\n"));
		goto cancel;
	}

	if (dbwrap_transaction_commit(orig_db) != 0) {
		smb_panic("tdbsam_convert_backup: orig commit failed\n");
	}
	if (dbwrap_transaction_commit(tmp_db) != 0) {
		smb_panic("tdbsam_convert_backup: orig commit failed\n");
	}

	/* be sure to close the DBs _before_ renaming the file */

	TALLOC_FREE(orig_db);
	TALLOC_FREE(tmp_db);

	/* This is safe from other users as we know we're
 	 * under a mutex here. */

	if (rename(tmp_fname, dbname) == -1) {
		DEBUG(0, ("tdbsam_convert_backup: rename of %s to %s failed %s\n",
			tmp_fname,
			dbname,
			strerror(errno)));
		smb_panic("tdbsam_convert_backup: replace passdb failed\n");
	}

	TALLOC_FREE(frame);

	/* re-open the converted TDB */

	orig_db = db_open(NULL, dbname, 0,
			  TDB_DEFAULT, O_CREAT|O_RDWR, 0600,
			  DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
	if (orig_db == NULL) {
		DEBUG(0, ("tdbsam_convert_backup: Failed to re-open "
			  "converted passdb TDB [%s]\n", dbname));
		return false;
	}

	DEBUG(1, ("tdbsam_convert_backup: updated %s file.\n",
		dbname ));

	/* Replace the global db pointer. */
	*pp_db = orig_db;
	return true;

  cancel:

	if (dbwrap_transaction_cancel(orig_db) != 0) {
		smb_panic("tdbsam_convert: transaction_cancel failed");
	}

	if (dbwrap_transaction_cancel(tmp_db) != 0) {
		smb_panic("tdbsam_convert: transaction_cancel failed");
	}

	unlink(tmp_fname);
	TALLOC_FREE(tmp_db);
	TALLOC_FREE(frame);
	return false;
}
コード例 #12
0
static NTSTATUS idmap_tdb_open_db(struct idmap_domain *dom)
{
	NTSTATUS ret;
	TALLOC_CTX *mem_ctx;
	char *tdbfile = NULL;
	struct db_context *db = NULL;
	int32_t version;
	bool config_error = false;
	struct idmap_tdb_context *ctx;

	ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);

	if (ctx->db) {
		/* it is already open */
		return NT_STATUS_OK;
	}

	/* use our own context here */
	mem_ctx = talloc_stackframe();

	/* use the old database if present */
	tdbfile = state_path("winbindd_idmap.tdb");
	if (!tdbfile) {
		DEBUG(0, ("Out of memory!\n"));
		ret = NT_STATUS_NO_MEMORY;
		goto done;
	}

	DEBUG(10,("Opening tdbfile %s\n", tdbfile ));

	/* Open idmap repository */
	db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
	if (!db) {
		DEBUG(0, ("Unable to open idmap database\n"));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	/* check against earlier versions */
	ret = dbwrap_fetch_int32(db, "IDMAP_VERSION", &version);
	if (!NT_STATUS_IS_OK(ret)) {
		version = -1;
	}

	if (version != IDMAP_VERSION) {
		if (config_error) {
			DEBUG(0,("Upgrade of IDMAP_VERSION from %d to %d is not "
				 "possible with incomplete configuration\n",
				 version, IDMAP_VERSION));
			ret = NT_STATUS_UNSUCCESSFUL;
			goto done;
		}
		if (dbwrap_transaction_start(db) != 0) {
			DEBUG(0, ("Unable to start upgrade transaction!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}

		if (!idmap_tdb_upgrade(dom, db)) {
			dbwrap_transaction_cancel(db);
			DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}

		if (dbwrap_transaction_commit(db) != 0) {
			DEBUG(0, ("Unable to commit upgrade transaction!\n"));
			ret = NT_STATUS_INTERNAL_DB_ERROR;
			goto done;
		}
	}

	ctx->db = talloc_move(ctx, &db);

	ret = idmap_tdb_init_hwm(dom);

done:
	talloc_free(mem_ctx);
	return ret;
}
コード例 #13
0
ファイル: reg_backend_db.c プロジェクト: ekohl/samba
WERROR regdb_transaction_commit(void)
{
	return (dbwrap_transaction_commit(regdb) == 0) ?
		WERR_OK : WERR_REG_IO_FAILURE;
}
コード例 #14
0
ファイル: reg_backend_db.c プロジェクト: ekohl/samba
WERROR regdb_init(void)
{
	int32_t vers_id;
	WERROR werr;
	NTSTATUS status;

	if (regdb) {
		DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
			   regdb_refcount, regdb_refcount+1));
		regdb_refcount++;
		return WERR_OK;
	}

	regdb = db_open(NULL, state_path("registry.tdb"), 0,
			REG_TDB_FLAGS, O_RDWR, 0600,
			DBWRAP_LOCK_ORDER_1);
	if (!regdb) {
		regdb = db_open(NULL, state_path("registry.tdb"), 0,
				REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600,
				DBWRAP_LOCK_ORDER_1);
		if (!regdb) {
			werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
			DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
				state_path("registry.tdb"), strerror(errno) ));
			return werr;
		}

		werr = regdb_store_regdb_version(regdb, REGDB_CODE_VERSION);
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(1, ("regdb_init: Failed to store version: %s\n",
				  win_errstr(werr)));
			return werr;
		}

		DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
	}

	regdb_refcount = 1;
	DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
		   regdb_refcount));

	status = dbwrap_fetch_int32(regdb, REGDB_VERSION_KEYNAME, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("regdb_init: registry version uninitialized "
			   "(got %d), initializing to version %d\n",
			   vers_id, REGDB_VERSION_V1));

		/*
		 * There was a regdb format version prior to version 1
		 * which did not store a INFO/version key. The format
		 * of this version was identical to version 1 except for
		 * the lack of the sorted subkey cache records.
		 * Since these are disposable, we can safely assume version
		 * 1 if no INFO/version key is found and run the db through
		 * the whole chain of upgrade. If the database was not
		 * initialized, this does not harm. If it was the unversioned
		 * version ("0"), then it do the right thing with the records.
		 */
		werr = regdb_store_regdb_version(regdb, REGDB_VERSION_V1);
		if (!W_ERROR_IS_OK(werr)) {
			return werr;
		}
		vers_id = REGDB_VERSION_V1;
	}

	if (vers_id == REGDB_CODE_VERSION) {
		return WERR_OK;
	}

	if (vers_id > REGDB_CODE_VERSION || vers_id == 0) {
		DEBUG(0, ("regdb_init: unknown registry version %d "
			  "(code version = %d), refusing initialization\n",
			  vers_id, REGDB_CODE_VERSION));
		return WERR_CAN_NOT_COMPLETE;
	}

	if (dbwrap_transaction_start(regdb) != 0) {
		return WERR_REG_IO_FAILURE;
	}

	if (vers_id == REGDB_VERSION_V1) {
		DEBUG(10, ("regdb_init: upgrading registry from version %d "
			   "to %d\n", REGDB_VERSION_V1, REGDB_VERSION_V2));

		werr = regdb_upgrade_v1_to_v2(regdb);
		if (!W_ERROR_IS_OK(werr)) {
			dbwrap_transaction_cancel(regdb);
			return werr;
		}

		vers_id = REGDB_VERSION_V2;
	}

	if (vers_id == REGDB_VERSION_V2) {
		DEBUG(10, ("regdb_init: upgrading registry from version %d "
			   "to %d\n", REGDB_VERSION_V2, REGDB_VERSION_V3));

		werr = regdb_upgrade_v2_to_v3(regdb);
		if (!W_ERROR_IS_OK(werr)) {
			dbwrap_transaction_cancel(regdb);
			return werr;
		}

		vers_id = REGDB_VERSION_V3;
	}

	/* future upgrade code should go here */

	if (dbwrap_transaction_commit(regdb) != 0) {
		return WERR_REG_IO_FAILURE;
	}

	return WERR_OK;
}
コード例 #15
0
bool share_info_db_init(void)
{
	const char *vstring = "INFO/version";
	int32 vers_id = 0;
	bool upgrade_ok = true;
	NTSTATUS status;

	if (share_db != NULL) {
		return True;
	}

	share_db = db_open(NULL, state_path("share_info.tdb"), 0,
				 TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
	if (share_db == NULL) {
		DEBUG(0,("Failed to open share info database %s (%s)\n",
			state_path("share_info.tdb"), strerror(errno) ));
		return False;
	}

	status = dbwrap_fetch_int32(share_db, vstring, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		vers_id = 0;
	}

	if (vers_id == SHARE_DATABASE_VERSION_V3) {
		return true;
	}

	if (dbwrap_transaction_start(share_db) != 0) {
		DEBUG(0, ("transaction_start failed\n"));
		TALLOC_FREE(share_db);
		return false;
	}

	status = dbwrap_fetch_int32(share_db, vstring, &vers_id);
	if (!NT_STATUS_IS_OK(status)) {
		vers_id = 0;
	}

	if (vers_id == SHARE_DATABASE_VERSION_V3) {
		/*
		 * Race condition
		 */
		if (dbwrap_transaction_cancel(share_db)) {
			smb_panic("transaction_cancel failed");
		}
		return true;
	}

	/* Move to at least V2. */

	/* Cope with byte-reversed older versions of the db. */
	if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
		/* Written on a bigendian machine with old fetch_int code. Save as le. */

		status = dbwrap_store_int32(share_db, vstring,
					    SHARE_DATABASE_VERSION_V2);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
				  nt_errstr(status)));
			goto cancel;
		}
		vers_id = SHARE_DATABASE_VERSION_V2;
	}

	if (vers_id != SHARE_DATABASE_VERSION_V2) {
		status = dbwrap_traverse(share_db, delete_fn, NULL, NULL);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("traverse failed\n"));
			goto cancel;
		}
		status = dbwrap_store_int32(share_db, vstring,
					    SHARE_DATABASE_VERSION_V2);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
				  nt_errstr(status)));
			goto cancel;
		}
	}

	/* Finally upgrade to version 3, with canonicalized sharenames. */

	status = dbwrap_traverse(share_db, upgrade_v2_to_v3, &upgrade_ok, NULL);
	if (!NT_STATUS_IS_OK(status) || upgrade_ok == false) {
		DEBUG(0, ("traverse failed\n"));
		goto cancel;
	}
	status = dbwrap_store_int32(share_db, vstring,
				    SHARE_DATABASE_VERSION_V3);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dbwrap_store_int32 failed: %s\n",
			  nt_errstr(status)));
		goto cancel;
	}

	if (dbwrap_transaction_commit(share_db) != 0) {
		DEBUG(0, ("transaction_commit failed\n"));
		return false;
	}

	return true;

 cancel:
	if (dbwrap_transaction_cancel(share_db)) {
		smb_panic("transaction_cancel failed");
	}

	return false;
}
コード例 #16
0
ファイル: srv_fss_state.c プロジェクト: 285858315/samba
/*
 * write out the current fsrvp server state to a TDB. This clears any content
 * currently written to the TDB.
 */
_PRIVATE_ NTSTATUS fss_state_store(TALLOC_CTX *mem_ctx,
			 struct fss_sc_set *sc_sets,
			 uint32_t sc_sets_count,
			 const char *db_path)
{
	TALLOC_CTX *tmp_ctx;
	struct db_context *db;
	NTSTATUS status;
	int ret;
	struct fss_sc_set *sc_set;

	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	db = db_open(tmp_ctx, db_path, 0, TDB_DEFAULT,  O_RDWR | O_CREAT,
		     0600, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
	if (db == NULL) {
		DEBUG(0, ("Failed to open fss state database %s\n", db_path));
		status = NT_STATUS_ACCESS_DENIED;
		goto err_ctx_free;
	}

	ret = dbwrap_wipe(db);
	if (ret != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
		goto err_db_free;
	}

	status = dbwrap_store_int32_bystring(db, FSS_DB_KEY_VERSION,
					     FSRVP_STATE_DB_VERSION);
	if (!NT_STATUS_IS_OK(status)) {
		goto err_db_free;
	}

	ret = dbwrap_transaction_start(db);
	if (ret != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
		goto err_db_free;
	}

	status = dbwrap_store_int32_bystring(db, FSS_DB_KEY_SC_SET_COUNT,
					     sc_sets_count);
	if (!NT_STATUS_IS_OK(status)) {
		status = NT_STATUS_UNSUCCESSFUL;
		goto err_trans_cancel;
	}

	for (sc_set = sc_sets; sc_set; sc_set = sc_set->next) {
		status = fss_state_sc_set_store(tmp_ctx, db, sc_set);
		if (!NT_STATUS_IS_OK(status)) {
			goto err_trans_cancel;
		}
	}

	ret = dbwrap_transaction_commit(db);
	if (ret != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
		goto err_trans_cancel;
	}

	talloc_free(db);
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;

err_trans_cancel:
	dbwrap_transaction_cancel(db);
err_db_free:
	talloc_free(db);
err_ctx_free:
	talloc_free(tmp_ctx);
	return status;
}