Example #1
0
static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom)
{
	int ret;
	uint32_t low_uid;
	uint32_t low_gid;
	bool update_uid = false;
	bool update_gid = false;
	struct idmap_tdb_context *ctx;

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

	low_uid = dbwrap_fetch_int32(ctx->db, HWM_USER);
	if (low_uid == -1 || low_uid < dom->low_id) {
		update_uid = true;
	}

	low_gid = dbwrap_fetch_int32(ctx->db, HWM_GROUP);
	if (low_gid == -1 || low_gid < dom->low_id) {
		update_gid = true;
	}

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

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

	if (update_uid) {
		ret = dbwrap_store_int32(ctx->db, HWM_USER, dom->low_id);
		if (ret == -1) {
			ctx->db->transaction_cancel(ctx->db);
			DEBUG(0, ("Unable to initialise user hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (update_gid) {
		ret = dbwrap_store_int32(ctx->db, HWM_GROUP, dom->low_id);
		if (ret == -1) {
			ctx->db->transaction_cancel(ctx->db);
			DEBUG(0, ("Unable to initialise group hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

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

	return NT_STATUS_OK;
}
Example #2
0
bool run_dbwrap_watch1(int dummy)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg = NULL;
	struct db_context *db = NULL;
	const char *keystr = "key";
	TDB_DATA key = string_term_tdb_data(keystr);
	struct db_record *rec = NULL;
	struct tevent_req *req = NULL;
	NTSTATUS status;
	bool ret = false;

	ev = tevent_context_init(talloc_tos());
	if (ev == NULL) {
		fprintf(stderr, "tevent_context_init failed\n");
		goto fail;
	}
	msg = messaging_init(ev, ev);
	if (msg == NULL) {
		fprintf(stderr, "messaging_init failed\n");
		goto fail;
	}
	db = db_open(msg, "test_watch.tdb", 0, TDB_DEFAULT,
		     O_CREAT|O_RDWR, 0644, DBWRAP_LOCK_ORDER_1);
	if (db == NULL) {
		fprintf(stderr, "db_open failed: %s\n", strerror(errno));
		goto fail;
	}
	dbwrap_watch_db(db, msg);
	rec = dbwrap_fetch_locked(db, db, key);
	if (rec == NULL) {
		fprintf(stderr, "dbwrap_fetch_locked failed\n");
		goto fail;
	}
	req = dbwrap_record_watch_send(talloc_tos(), ev, rec, msg);
	if (req == NULL) {
		fprintf(stderr, "dbwrap_record_watch_send failed\n");
		goto fail;
	}
	TALLOC_FREE(rec);

	status = dbwrap_store_int32(db, keystr, 1);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "dbwrap_store_int32 failed: %s\n",
			nt_errstr(status));
		goto fail;
	}

	if (!tevent_req_poll(req, ev)) {
		fprintf(stderr, "tevent_req_poll failed\n");
		goto fail;
	}

	status = dbwrap_record_watch_recv(req, talloc_tos(), &rec);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "dbwrap_record_watch_recv failed: %s\n",
			nt_errstr(status));
		goto fail;
	}

	ret = true;
fail:
	TALLOC_FREE(req);
	TALLOC_FREE(rec);
	TALLOC_FREE(db);
	TALLOC_FREE(msg);
	TALLOC_FREE(ev);
	return ret;
}
Example #3
0
static bool idmap_tdb_upgrade(struct idmap_domain *dom, struct db_context *db)
{
	int32 vers;
	bool bigendianheader;
	struct convert_fn_state s;
	NTSTATUS status;

#if BUILD_TDB2
	/* If we are bigendian, tdb is bigendian if NOT converted. */
	union {
		uint16 large;
		unsigned char small[2];
	} u;
	u.large = 0x0102;
	if (u.small[0] == 0x01)
		bigendianheader = !(dbwrap_get_flags(db) & TDB_CONVERT);
	else {
		assert(u.small[0] == 0x02);
		bigendianheader = (dbwrap_get_flags(db) & TDB_CONVERT);
	}
#else
	bigendianheader = (dbwrap_get_flags(db) & TDB_BIGENDIAN) ? True : False;
#endif
	DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));

	status = dbwrap_fetch_int32(db, "IDMAP_VERSION", &vers);
	if (!NT_STATUS_IS_OK(status)) {
		vers = -1;
	}

	if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
		/* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
		/*
		 * high and low records were created on a
		 * big endian machine and will need byte-reversing.
		 */

		int32 wm;

		status = dbwrap_fetch_int32(db, HWM_USER, &wm);
		if (!NT_STATUS_IS_OK(status)) {
			wm = -1;
		}

		if (wm != -1) {
			wm = IREV(wm);
		}  else {
			wm = dom->low_id;
		}

		status = dbwrap_store_int32(db, HWM_USER, wm);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Unable to byteswap user hwm in idmap "
				  "database: %s\n", nt_errstr(status)));
			return False;
		}

		status = dbwrap_fetch_int32(db, HWM_GROUP, &wm);
		if (!NT_STATUS_IS_OK(status)) {
			wm = -1;
		}

		if (wm != -1) {
			wm = IREV(wm);
		} else {
			wm = dom->low_id;
		}

		status = dbwrap_store_int32(db, HWM_GROUP, wm);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Unable to byteswap group hwm in idmap "
				  "database: %s\n", nt_errstr(status)));
			return False;
		}
	}

	s.db = db;
	s.failed = false;

	/* the old format stored as DOMAIN/rid - now we store the SID direct */
	status = dbwrap_traverse(db, convert_fn, &s, NULL);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Database traverse failed during conversion\n"));
		return false;
	}

	if (s.failed) {
		DEBUG(0, ("Problem during conversion\n"));
		return False;
	}

	status = dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Unable to store idmap version in database: %s\n",
			  nt_errstr(status)));
		return False;
	}

	return True;
}
Example #4
0
static NTSTATUS idmap_tdb_alloc_init( const char *params )
{
	int ret;
	NTSTATUS status;
	uint32_t low_uid;
	uint32_t low_gid;
	bool update_uid = false;
	bool update_gid = false;

	status = idmap_tdb_open_db(NULL, true, &idmap_alloc_db);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("idmap will be unable to map foreign SIDs: %s\n",
			  nt_errstr(status)));
		return status;
	}

	low_uid = dbwrap_fetch_int32(idmap_alloc_db, HWM_USER);
	if (low_uid == -1 || low_uid < idmap_tdb_state.low_uid) {
		update_uid = true;
	}

	low_gid = dbwrap_fetch_int32(idmap_alloc_db, HWM_GROUP);
	if (low_gid == -1 || low_gid < idmap_tdb_state.low_gid) {
		update_gid = true;
	}

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

	if (idmap_alloc_db->transaction_start(idmap_alloc_db) != 0) {
		TALLOC_FREE(idmap_alloc_db);
		DEBUG(0, ("Unable to start upgrade transaction!\n"));
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	if (update_uid) {
		ret = dbwrap_store_int32(idmap_alloc_db, HWM_USER,
					 idmap_tdb_state.low_uid);
		if (ret == -1) {
			idmap_alloc_db->transaction_cancel(idmap_alloc_db);
			TALLOC_FREE(idmap_alloc_db);
			DEBUG(0, ("Unable to initialise user hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (update_gid) {
		ret = dbwrap_store_int32(idmap_alloc_db, HWM_GROUP,
					 idmap_tdb_state.low_gid);
		if (ret == -1) {
			idmap_alloc_db->transaction_cancel(idmap_alloc_db);
			TALLOC_FREE(idmap_alloc_db);
			DEBUG(0, ("Unable to initialise group hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (idmap_alloc_db->transaction_commit(idmap_alloc_db) != 0) {
		TALLOC_FREE(idmap_alloc_db);
		DEBUG(0, ("Unable to commit upgrade transaction!\n"));
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	return NT_STATUS_OK;
}
Example #5
0
static bool idmap_tdb_upgrade(struct db_context *db)
{
	int32 vers;
	bool bigendianheader;
	struct convert_fn_state s;

	DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));

	bigendianheader = (db->get_flags(db) & TDB_BIGENDIAN) ? True : False;

	vers = dbwrap_fetch_int32(db, "IDMAP_VERSION");

	if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
		/* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
		/*
		 * high and low records were created on a
		 * big endian machine and will need byte-reversing.
		 */

		int32 wm;

		wm = dbwrap_fetch_int32(db, HWM_USER);

		if (wm != -1) {
			wm = IREV(wm);
		}  else {
			wm = idmap_tdb_state.low_uid;
		}

		if (dbwrap_store_int32(db, HWM_USER, wm) == -1) {
			DEBUG(0, ("Unable to byteswap user hwm in idmap database\n"));
			return False;
		}

		wm = dbwrap_fetch_int32(db, HWM_GROUP);
		if (wm != -1) {
			wm = IREV(wm);
		} else {
			wm = idmap_tdb_state.low_gid;
		}

		if (dbwrap_store_int32(db, HWM_GROUP, wm) == -1) {
			DEBUG(0, ("Unable to byteswap group hwm in idmap database\n"));
			return False;
		}
	}

	s.db = db;
	s.failed = false;

	/* the old format stored as DOMAIN/rid - now we store the SID direct */
	db->traverse(db, convert_fn, &s);

	if (s.failed) {
		DEBUG(0, ("Problem during conversion\n"));
		return False;
	}

	if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
		DEBUG(0, ("Unable to store idmap version in databse\n"));
		return False;
	}

	return True;
}
Example #6
0
bool share_info_db_init(void)
{
	const char *vstring = "INFO/version";
	int32 vers_id;

	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;
	}

	vers_id = dbwrap_fetch_int32(share_db, vstring);
	if (vers_id == SHARE_DATABASE_VERSION_V2) {
		return true;
	}

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

	vers_id = dbwrap_fetch_int32(share_db, vstring);
	if (vers_id == SHARE_DATABASE_VERSION_V2) {
		/*
		 * Race condition
		 */
		if (share_db->transaction_cancel(share_db)) {
			smb_panic("transaction_cancel failed");
		}
		return true;
	}

	/* 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. */

		if (dbwrap_store_int32(share_db, vstring,
				       SHARE_DATABASE_VERSION_V2) != 0) {
			DEBUG(0, ("dbwrap_store_int32 failed\n"));
			goto cancel;
		}
		vers_id = SHARE_DATABASE_VERSION_V2;
	}

	if (vers_id != SHARE_DATABASE_VERSION_V2) {
		int ret;
		ret = share_db->traverse(share_db, delete_fn, NULL);
		if (ret < 0) {
			DEBUG(0, ("traverse failed\n"));
			goto cancel;
		}
		if (dbwrap_store_int32(share_db, vstring,
				       SHARE_DATABASE_VERSION_V2) != 0) {
			DEBUG(0, ("dbwrap_store_int32 failed\n"));
			goto cancel;
		}
	}

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

	return true;

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

	return false;
}
Example #7
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;
}
Example #8
0
static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 from)
{
	struct tdbsam_convert_state state;
	struct db_context *db = NULL;
	int ret;

	/* 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 (db->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;
	}

	ret = db->traverse(db, tdbsam_convert_one, &state);
	if (ret < 0) {
		DEBUG(0, ("tdbsam_convert: traverse failed\n"));
		goto cancel;
	}

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

	if (dbwrap_store_int32(db, TDBSAM_VERSION_STRING,
			       TDBSAM_VERSION) != 0) {
		DEBUG(0, ("tdbsam_convert: Could not store tdbsam version\n"));
		goto cancel;
	}

	if (dbwrap_store_int32(db, TDBSAM_MINOR_VERSION_STRING,
			       TDBSAM_MINOR_VERSION) != 0) {
		DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor version\n"));
		goto cancel;
	}

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

	return true;

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

	return false;
}