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