Beispiel #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;
}
Beispiel #2
0
static NTSTATUS regdb_trans_do_action(struct db_context *db, void *private_data)
{
	NTSTATUS status;
	int32_t version_id;
	struct regdb_trans_ctx *ctx = (struct regdb_trans_ctx *)private_data;

	status = dbwrap_fetch_int32(db, REGDB_VERSION_KEYNAME, &version_id);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("ERROR: could not fetch registry db version: %s. "
			  "Denying access.\n", nt_errstr(status)));
		return NT_STATUS_ACCESS_DENIED;
	}

	if (version_id != REGDB_CODE_VERSION) {
		DEBUG(0, ("ERROR: changed registry version %d found while "
			  "trying to write to the registry. Version %d "
			  "expected.  Denying access.\n",
			  version_id, REGDB_CODE_VERSION));
		return NT_STATUS_ACCESS_DENIED;
	}

	status = ctx->action(db,  ctx->private_data);
	return status;
}
Beispiel #3
0
/*
  load the idmap allocation ranges and high/low water marks
*/
static NTSTATUS idmap_tdb2_alloc_load(void)
{
	NTSTATUS status;
	uint32 low_id;

	/* see if a idmap script is configured */
	idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap",
							     "script", NULL);

	if (idmap_tdb2_state.idmap_script) {
		DEBUG(1, ("using idmap script '%s'\n",
			  idmap_tdb2_state.idmap_script));
	}

	/* load ranges */

	status = idmap_tdb2_load_ranges();
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Create high water marks for group and user id */

	low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_USER);
	if ((low_id == -1) || (low_id < idmap_tdb2_state.low_uid)) {
		if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
					     idmap_tdb2, HWM_USER,
					     idmap_tdb2_state.low_uid))) {
			DEBUG(0, ("Unable to initialise user hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_GROUP);
	if ((low_id == -1) || (low_id < idmap_tdb2_state.low_gid)) {
		if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
					     idmap_tdb2, HWM_GROUP,
					     idmap_tdb2_state.low_gid))) {
			DEBUG(0, ("Unable to initialise group hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	return NT_STATUS_OK;
}
Beispiel #4
0
static int dbwrap_tool_fetch_int32(struct db_context *db,
				   const char *keyname,
				   void *data)
{
	int32_t value;

	value = dbwrap_fetch_int32(db, keyname);
	d_printf("%d\n", value);

	return 0;
}
Beispiel #5
0
static int dbwrap_tool_fetch_int32(struct db_context *db,
				   const char *keyname,
				   const char *data)
{
	int32_t value;
	NTSTATUS status;

	status = dbwrap_fetch_int32(db, keyname, &value);
	if (!NT_STATUS_IS_OK(status)) {
		d_printf("Error fetching int32 from key '%s': %s\n",
			 keyname, nt_errstr(status));
		return -1;
	}
	d_printf("%d\n", value);

	return 0;
}
Beispiel #6
0
static NTSTATUS idmap_tdb_allocate_id_action(struct db_context *db,
					     void *private_data)
{
	NTSTATUS ret;
	struct idmap_tdb_allocate_id_context *state;
	uint32_t hwm;

	state = (struct idmap_tdb_allocate_id_context *)private_data;

	hwm = dbwrap_fetch_int32(db, state->hwmkey);
	if (hwm == -1) {
		ret = NT_STATUS_INTERNAL_DB_ERROR;
		goto done;
	}

	/* check it is in the range */
	if (hwm > state->high_hwm) {
		DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
			  state->hwmtype, (unsigned long)state->high_hwm));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	/* fetch a new id and increment it */
	ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1);
	if (!NT_STATUS_IS_OK(ret)) {
		DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!",
			  state->hwmtype, nt_errstr(ret)));
		goto done;
	}

	/* recheck it is in the range */
	if (hwm > state->high_hwm) {
		DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
			  state->hwmtype, (unsigned long)state->high_hwm));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	ret = NT_STATUS_OK;
	state->hwm = hwm;

done:
	return ret;
}
Beispiel #7
0
/*
  Get current highest id. 
*/
static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
{
	const char *hwmkey;
	const char *hwmtype;
	uint32_t hwm;
	uint32_t high_hwm;
	NTSTATUS status;

	status = idmap_tdb2_open_db();
	NT_STATUS_NOT_OK_RETURN(status);

	/* Get current high water mark */
	switch (xid->type) {

	case ID_TYPE_UID:
		hwmkey = HWM_USER;
		hwmtype = "UID";
		high_hwm = idmap_tdb2_state.high_uid;
		break;

	case ID_TYPE_GID:
		hwmkey = HWM_GROUP;
		hwmtype = "GID";
		high_hwm = idmap_tdb2_state.high_gid;
		break;

	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) {
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	xid->id = hwm;

	/* Warn if it is out of range */
	if (hwm >= high_hwm) {
		DEBUG(0, ("Warning: %s range full!! (max: %lu)\n", 
			  hwmtype, (unsigned long)high_hwm));
	}

	return NT_STATUS_OK;
}
Beispiel #8
0
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;
}
Beispiel #9
0
/*
  load the idmap allocation ranges and high/low water marks
*/
static NTSTATUS idmap_tdb2_alloc_load(void)
{
	uid_t low_uid = 0;
	uid_t high_uid = 0;
	gid_t low_gid = 0;
	gid_t high_gid = 0;
	uint32 low_id;

	/* see if a idmap script is configured */
	idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap",
							     "script", NULL);

	if (idmap_tdb2_state.idmap_script) {
		DEBUG(1, ("using idmap script '%s'\n",
			  idmap_tdb2_state.idmap_script));
	}

	/* load ranges */

	/* Create high water marks for group and user id */
	if (!lp_idmap_uid(&low_uid, &high_uid)
	    || !lp_idmap_gid(&low_gid, &high_gid)) {
		DEBUG(1, ("idmap uid or idmap gid missing\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	idmap_tdb2_state.low_uid = low_uid;
	idmap_tdb2_state.high_uid = high_uid;
	idmap_tdb2_state.low_gid = low_gid;
	idmap_tdb2_state.high_gid = high_gid;

	if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) {
		DEBUG(1, ("idmap uid range missing or invalid\n"));
		DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (((low_id = dbwrap_fetch_int32(idmap_tdb2,
					  HWM_USER)) == -1) ||
	    (low_id < idmap_tdb2_state.low_uid)) {
		if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
					     idmap_tdb2, HWM_USER,
					     idmap_tdb2_state.low_uid))) {
			DEBUG(0, ("Unable to initialise user hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) {
		DEBUG(1, ("idmap gid range missing or invalid\n"));
		DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (((low_id = dbwrap_fetch_int32(idmap_tdb2,
					  HWM_GROUP)) == -1) ||
	    (low_id < idmap_tdb2_state.low_gid)) {
		if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
					     idmap_tdb2, HWM_GROUP,
					     idmap_tdb2_state.low_gid))) {
			DEBUG(0, ("Unable to initialise group hwm in idmap "
				  "database\n"));
			return NT_STATUS_INTERNAL_DB_ERROR;
		}
	}

	return NT_STATUS_OK;
}
Beispiel #10
0
/*
  Allocate a new id. 
*/
static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
{
	bool ret;
	const char *hwmkey;
	const char *hwmtype;
	uint32_t high_hwm;
	uint32_t hwm;
	int res;
	NTSTATUS status;

	status = idmap_tdb2_open_db();
	NT_STATUS_NOT_OK_RETURN(status);

	/* Get current high water mark */
	switch (xid->type) {

	case ID_TYPE_UID:
		hwmkey = HWM_USER;
		hwmtype = "UID";
		high_hwm = idmap_tdb2_state.high_uid;
		break;

	case ID_TYPE_GID:
		hwmkey = HWM_GROUP;
		hwmtype = "GID";
		high_hwm = idmap_tdb2_state.high_gid;
		break;

	default:
		DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
		return NT_STATUS_INVALID_PARAMETER;
	}

	res = idmap_tdb2->transaction_start(idmap_tdb2);
	if (res != 0) {
		DEBUG(1,(__location__ " Failed to start transaction\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) {
		idmap_tdb2->transaction_cancel(idmap_tdb2);
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	/* check it is in the range */
	if (hwm > high_hwm) {
		DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 
			  hwmtype, (unsigned long)high_hwm));
		idmap_tdb2->transaction_cancel(idmap_tdb2);
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* fetch a new id and increment it */
	ret = dbwrap_change_uint32_atomic(idmap_tdb2, hwmkey, &hwm, 1);
	if (ret == -1) {
		DEBUG(1, ("Fatal error while fetching a new %s value\n!", hwmtype));
		idmap_tdb2->transaction_cancel(idmap_tdb2);
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* recheck it is in the range */
	if (hwm > high_hwm) {
		DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 
			  hwmtype, (unsigned long)high_hwm));
		idmap_tdb2->transaction_cancel(idmap_tdb2);
		return NT_STATUS_UNSUCCESSFUL;
	}

	res = idmap_tdb2->transaction_commit(idmap_tdb2);
	if (res != 0) {
		DEBUG(1,(__location__ " Failed to commit transaction\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	xid->id = hwm;
	DEBUG(10,("New %s = %d\n", hwmtype, hwm));

	return NT_STATUS_OK;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
0
NTSTATUS dbwrap_fetch_int32_bystring(struct db_context *db, const char *keystr,
				     int32_t *result)
{
	return dbwrap_fetch_int32(db, string_term_tdb_data(keystr), result);
}
Beispiel #14
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;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
static bool tdbsam_open( const char *name )
{
	int32	version;
	int32	minor_version;

	/* check if we are already open */

	if ( db_sam ) {
		return true;
	}

	/* Try to open tdb passwd.  Create a new one if necessary */

	db_sam = db_open(NULL, name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600);
	if (db_sam == NULL) {
		DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd "
			  "[%s]\n", name));
		return false;
	}

	/* Check the version */
	version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
	if (version == -1) {
		version = 0;	/* Version not found, assume version 0 */
	}

	/* Get the minor version */
	minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
	if (minor_version == -1) {
		minor_version = 0; /* Minor version not found, assume 0 */
	}

	/* Compare the version */
	if (version > TDBSAM_VERSION) {
		/* Version more recent than the latest known */
		DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
		TALLOC_FREE(db_sam);
		return false;
	}

	if ( version < TDBSAM_VERSION ||
			(version == TDBSAM_VERSION &&
			 minor_version < TDBSAM_MINOR_VERSION) ) {
		/*
		 * Ok - we think we're going to have to convert.
		 * Due to the backup process we now must do to
		 * upgrade we have to get a mutex and re-check
		 * the version. Someone else may have upgraded
		 * whilst we were checking.
		 */

		struct named_mutex *mtx = grab_named_mutex(NULL,
						"tdbsam_upgrade_mutex",
						600);

		if (!mtx) {
			DEBUG(0, ("tdbsam_open: failed to grab mutex.\n"));
			TALLOC_FREE(db_sam);
			return false;
		}

		/* Re-check the version */
		version = dbwrap_fetch_int32(db_sam, TDBSAM_VERSION_STRING);
		if (version == -1) {
			version = 0;	/* Version not found, assume version 0 */
		}

		/* Re-check the minor version */
		minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING);
		if (minor_version == -1) {
			minor_version = 0; /* Minor version not found, assume 0 */
		}

		/* Compare the version */
		if (version > TDBSAM_VERSION) {
			/* Version more recent than the latest known */
			DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
			TALLOC_FREE(db_sam);
			TALLOC_FREE(mtx);
			return false;
		}

		if ( version < TDBSAM_VERSION ||
				(version == TDBSAM_VERSION &&
				 minor_version < TDBSAM_MINOR_VERSION) ) {
			/*
			 * Note that minor versions we read that are greater
			 * than the current minor version we have hard coded
			 * are assumed to be compatible if they have the same
			 * major version. That allows previous versions of the
			 * passdb code that don't know about minor versions to
			 * still use this database. JRA.
			 */

			DEBUG(1, ("tdbsam_open: Converting version %d.%d database to "
				  "version %d.%d.\n",
					version,
					minor_version,
					TDBSAM_VERSION,
					TDBSAM_MINOR_VERSION));

			if ( !tdbsam_convert(&db_sam, name, version) ) {
				DEBUG(0, ("tdbsam_open: Error when trying to convert "
					  "tdbsam [%s]\n",name));
				TALLOC_FREE(db_sam);
				TALLOC_FREE(mtx);
				return false;
			}

			DEBUG(3, ("TDBSAM converted successfully.\n"));
		}
		TALLOC_FREE(mtx);
	}

	DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));

	return true;
}
Beispiel #18
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;
}
Beispiel #19
0
WERROR regdb_init(void)
{
	const char *vstring = "INFO/version";
	uint32 vers_id, expected_version;
	WERROR werr;

	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);
	if (!regdb) {
		regdb = db_open(NULL, state_path("registry.tdb"), 0,
				      REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600);
		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;
		}

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

	expected_version = REGVER_V2;

	vers_id = dbwrap_fetch_int32(regdb, vstring);
	if (vers_id == -1) {
		DEBUG(10, ("regdb_init: registry version uninitialized "
			   "(got %d), initializing to version %d\n",
			   vers_id, expected_version));

		werr = regdb_store_regdb_version(expected_version);
		return werr;
	}

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

	if (vers_id == REGVER_V1) {
		DEBUG(10, ("regdb_init: got registry db version %d, upgrading "
			   "to version %d\n", REGVER_V1, REGVER_V2));

		if (regdb->transaction_start(regdb) != 0) {
			return WERR_REG_IO_FAILURE;
		}

		werr = regdb_upgrade_v1_to_v2();
		if (!W_ERROR_IS_OK(werr)) {
			regdb->transaction_cancel(regdb);
			return werr;
		}

		if (regdb->transaction_commit(regdb) != 0) {
			return WERR_REG_IO_FAILURE;
		}

		vers_id = REGVER_V2;
	}

	/* future upgrade code should go here */

	return WERR_OK;
}