The branch, master has been updated via 4feafd7c7be947bb38856dee79f057b2671151f3 (commit) via 535311d1875a4302a1c42d92046d2cdc8d3ef4ef (commit) via a83b327f1bec10f18ebe59c2fde7fe74228149f2 (commit) from aa79f76b0cfcf402bdf955cdf8356d619ace0b68 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4feafd7c7be947bb38856dee79f057b2671151f3 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Dec 16 21:14:36 2008 +0100 s3:idmap_tdb: convert to the dbwrap api metze commit 535311d1875a4302a1c42d92046d2cdc8d3ef4ef Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 17 08:53:31 2008 +0100 s3:dbwrap: add dbwrap_delete(), dbwrap_store() and dbwrap_fetch() The _bystring function are now just tiny wrappers. metze commit a83b327f1bec10f18ebe59c2fde7fe74228149f2 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 17 08:35:35 2008 +0100 s3:dbwrap: add get_flags() hook to db_context metze ----------------------------------------------------------------------- Summary of changes: source3/include/dbwrap.h | 6 + source3/lib/dbwrap.c | 34 +++- source3/lib/dbwrap_ctdb.c | 8 + source3/lib/dbwrap_tdb.c | 9 + source3/winbindd/idmap_tdb.c | 467 ++++++++++++++++++++---------------------- 5 files changed, 272 insertions(+), 252 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index 46833fa..aad4ccd 100644 --- a/source3/include/dbwrap.h +++ b/source3/include/dbwrap.h @@ -42,6 +42,7 @@ struct db_context { void *private_data), void *private_data); int (*get_seqnum)(struct db_context *db); + int (*get_flags)(struct db_context *db); int (*transaction_start)(struct db_context *db); int (*transaction_commit)(struct db_context *db); int (*transaction_cancel)(struct db_context *db); @@ -82,6 +83,11 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx, int open_flags, mode_t mode); +NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key); +NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key, + TDB_DATA data, int flags); +TDB_DATA dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key); NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key); NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key, TDB_DATA data, int flags); diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c index 73c2761..a57b7c9 100644 --- a/source3/lib/dbwrap.c +++ b/source3/lib/dbwrap.c @@ -105,12 +105,12 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, return result; } -NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key) +NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key) { struct db_record *rec; NTSTATUS status; - rec = db->fetch_locked(db, talloc_tos(), string_term_tdb_data(key)); + rec = db->fetch_locked(db, talloc_tos(), key); if (rec == NULL) { return NT_STATUS_NO_MEMORY; } @@ -119,13 +119,13 @@ NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key) return status; } -NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key, - TDB_DATA data, int flags) +NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key, + TDB_DATA data, int flags) { struct db_record *rec; NTSTATUS status; - rec = db->fetch_locked(db, talloc_tos(), string_term_tdb_data(key)); + rec = db->fetch_locked(db, talloc_tos(), key); if (rec == NULL) { return NT_STATUS_NO_MEMORY; } @@ -135,14 +135,32 @@ NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key, return status; } -TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx, - const char *key) +TDB_DATA dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key) { TDB_DATA result; - if (db->fetch(db, mem_ctx, string_term_tdb_data(key), &result) == -1) { + if (db->fetch(db, mem_ctx, key, &result) == -1) { return make_tdb_data(NULL, 0); } return result; } + +NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key) +{ + return dbwrap_delete(db, string_term_tdb_data(key)); +} + +NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key, + TDB_DATA data, int flags) +{ + return dbwrap_store(db, string_term_tdb_data(key), data, flags); +} + +TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx, + const char *key) +{ + return dbwrap_fetch(db, mem_ctx, string_term_tdb_data(key)); +} + diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 38daa61..03667ff 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -1158,6 +1158,13 @@ static int db_ctdb_get_seqnum(struct db_context *db) return tdb_get_seqnum(ctx->wtdb->tdb); } +static int db_ctdb_get_flags(struct db_context *db) +{ + struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, + struct db_ctdb_ctx); + return tdb_get_flags(ctx->wtdb->tdb); +} + struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, const char *name, int hash_size, int tdb_flags, @@ -1219,6 +1226,7 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, result->traverse = db_ctdb_traverse; result->traverse_read = db_ctdb_traverse_read; result->get_seqnum = db_ctdb_get_seqnum; + result->get_flags = db_ctdb_get_flags; result->transaction_start = db_ctdb_transaction_start; result->transaction_commit = db_ctdb_transaction_commit; result->transaction_cancel = db_ctdb_transaction_cancel; diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index 4860c61..b5eb188 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -291,6 +291,14 @@ static int db_tdb_get_seqnum(struct db_context *db) return tdb_get_seqnum(db_ctx->wtdb->tdb); } +static int db_tdb_get_flags(struct db_context *db) + +{ + struct db_tdb_ctx *db_ctx = + talloc_get_type_abort(db->private_data, struct db_tdb_ctx); + return tdb_get_flags(db_ctx->wtdb->tdb); +} + static int db_tdb_transaction_start(struct db_context *db) { struct db_tdb_ctx *db_ctx = @@ -344,6 +352,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; result->get_seqnum = db_tdb_get_seqnum; + result->get_flags = db_tdb_get_flags; result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); result->transaction_start = db_tdb_transaction_start; result->transaction_commit = db_tdb_transaction_commit; diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 4c8cceb..99821ae 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -40,41 +40,50 @@ static struct idmap_tdb_state { } idmap_tdb_state; +struct convert_fn_state { + struct db_context *db; + bool failed; +}; + /***************************************************************************** For idmap conversion: convert one record to new format Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid instead of the SID. *****************************************************************************/ -static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state) +static int convert_fn(struct db_record *rec, void *private_data) { struct winbindd_domain *domain; char *p; + NTSTATUS status; DOM_SID sid; uint32 rid; fstring keystr; fstring dom_name; TDB_DATA key2; - bool *failed = (bool *)state; + struct convert_fn_state *s = (struct convert_fn_state *)private_data; - DEBUG(10,("Converting %s\n", (const char *)key.dptr)); + DEBUG(10,("Converting %s\n", (const char *)rec->key.dptr)); - p = strchr((const char *)key.dptr, '/'); + p = strchr((const char *)rec->key.dptr, '/'); if (!p) return 0; *p = 0; - fstrcpy(dom_name, (const char *)key.dptr); + fstrcpy(dom_name, (const char *)rec->key.dptr); *p++ = '/'; domain = find_domain_from_name(dom_name); if (domain == NULL) { /* We must delete the old record. */ DEBUG(0,("Unable to find domain %s\n", dom_name )); - DEBUG(0,("deleting record %s\n", (const char *)key.dptr )); - - if (tdb_delete(tdb, key) != 0) { - DEBUG(0, ("Unable to delete record %s\n", (const char *)key.dptr)); - *failed = True; + DEBUG(0,("deleting record %s\n", (const char *)rec->key.dptr )); + + status = rec->delete_rec(rec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Unable to delete record %s:%s\n", + (const char *)rec->key.dptr, + nt_errstr(status))); + s->failed = true; return -1; } @@ -89,21 +98,30 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state sid_to_fstring(keystr, &sid); key2 = string_term_tdb_data(keystr); - if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) { - DEBUG(0,("Unable to add record %s\n", (const char *)key2.dptr )); - *failed = True; + status = dbwrap_store(s->db, key2, rec->value, TDB_INSERT); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to add record %s:%s\n", + (const char *)key2.dptr, + nt_errstr(status))); + s->failed = true; return -1; } - if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) { - DEBUG(0,("Unable to update record %s\n", (const char *)data.dptr )); - *failed = True; + status = dbwrap_store(s->db, rec->value, key2, TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update record %s:%s\n", + (const char *)rec->value.dptr, + nt_errstr(status))); + s->failed = true; return -1; } - if (tdb_delete(tdb, key) != 0) { - DEBUG(0,("Unable to delete record %s\n", (const char *)key.dptr )); - *failed = True; + status = rec->delete_rec(rec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to delete record %s:%s\n", + (const char *)rec->key.dptr, + nt_errstr(status))); + s->failed = true; return -1; } @@ -114,25 +132,17 @@ static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state Convert the idmap database from an older version. *****************************************************************************/ -static bool idmap_tdb_upgrade(const char *idmap_name) +static bool idmap_tdb_upgrade(struct db_context *db) { int32 vers; bool bigendianheader; - bool failed = False; - TDB_CONTEXT *idmap_tdb; + struct convert_fn_state s; DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n")); - if (!(idmap_tdb = tdb_open_log(idmap_name, 0, - TDB_DEFAULT, O_RDWR, - 0600))) { - DEBUG(0, ("Unable to open idmap database\n")); - return False; - } - - bigendianheader = (tdb_get_flags(idmap_tdb) & TDB_BIGENDIAN) ? True : False; + bigendianheader = (db->get_flags(db) & TDB_BIGENDIAN) ? True : False; - vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION"); + vers = dbwrap_fetch_int32(db, "IDMAP_VERSION"); if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) { /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */ @@ -143,7 +153,7 @@ static bool idmap_tdb_upgrade(const char *idmap_name) int32 wm; - wm = tdb_fetch_int32(idmap_tdb, HWM_USER); + wm = dbwrap_fetch_int32(db, HWM_USER); if (wm != -1) { wm = IREV(wm); @@ -151,66 +161,87 @@ static bool idmap_tdb_upgrade(const char *idmap_name) wm = idmap_tdb_state.low_uid; } - if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) { + if (dbwrap_store_int32(db, HWM_USER, wm) == -1) { DEBUG(0, ("Unable to byteswap user hwm in idmap database\n")); - tdb_close(idmap_tdb); return False; } - wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP); + wm = dbwrap_fetch_int32(db, HWM_GROUP); if (wm != -1) { wm = IREV(wm); } else { wm = idmap_tdb_state.low_gid; } - if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) { + if (dbwrap_store_int32(db, HWM_GROUP, wm) == -1) { DEBUG(0, ("Unable to byteswap group hwm in idmap database\n")); - tdb_close(idmap_tdb); return False; } } + s.db = db; + s.failed = false; + /* the old format stored as DOMAIN/rid - now we store the SID direct */ - tdb_traverse(idmap_tdb, convert_fn, &failed); + db->traverse(db, convert_fn, &s); - if (failed) { + if (s.failed) { DEBUG(0, ("Problem during conversion\n")); - tdb_close(idmap_tdb); return False; } - if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) { + if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) { DEBUG(0, ("Unable to dtore idmap version in databse\n")); - tdb_close(idmap_tdb); return False; } - tdb_close(idmap_tdb); return True; } -/* WARNING: We can't open a tdb twice inthe same process, for that reason - * I'm going to use a hack with open ref counts to open the winbindd_idmap.tdb - * only once. We will later decide whether to split the db in multiple files - * or come up with a better solution to share them. */ - -static TDB_CONTEXT *idmap_tdb_common_ctx; -static int idmap_tdb_open_ref_count = 0; - -static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx, TDB_CONTEXT **tdbctx) +static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx, + bool check_config, + struct db_context **dbctx) { NTSTATUS ret; TALLOC_CTX *ctx; - SMB_STRUCT_STAT stbuf; char *tdbfile = NULL; - int32 version; - bool tdb_is_new = False; + struct db_context *db = NULL; + int32_t version; + uid_t low_uid = 0; + uid_t high_uid = 0; + gid_t low_gid = 0; + gid_t high_gid = 0; + bool config_error = false; - if (idmap_tdb_open_ref_count) { /* the tdb has already been opened */ - idmap_tdb_open_ref_count++; - *tdbctx = idmap_tdb_common_ctx; - return NT_STATUS_OK; + /* load ranges */ + if (!lp_idmap_uid(&low_uid, &high_uid) + || !lp_idmap_gid(&low_gid, &high_gid)) { + DEBUG(1, ("idmap uid or idmap gid missing\n")); + config_error = true; + if (check_config) { + return NT_STATUS_UNSUCCESSFUL; + } + } + + idmap_tdb_state.low_uid = low_uid; + idmap_tdb_state.high_uid = high_uid; + idmap_tdb_state.low_gid = low_gid; + idmap_tdb_state.high_gid = high_gid; + + if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) { + DEBUG(1, ("idmap uid range missing or invalid\n")); + config_error = true; + if (check_config) { + return NT_STATUS_UNSUCCESSFUL; + } + } + + if (idmap_tdb_state.high_gid <= idmap_tdb_state.low_gid) { + DEBUG(1, ("idmap gid range missing or invalid\n")); + config_error = true; + if (check_config) { + return NT_STATUS_UNSUCCESSFUL; + } } /* use our own context here */ @@ -228,52 +259,47 @@ static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx, TDB_CONTEXT **tdbctx) goto done; } - if (!file_exist_stat(tdbfile, &stbuf)) { - tdb_is_new = True; - } - DEBUG(10,("Opening tdbfile %s\n", tdbfile )); /* Open idmap repository */ - if (!(idmap_tdb_common_ctx = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644))) { + db = db_open(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; } - if (tdb_is_new) { - /* the file didn't existed before opening it, let's - * store idmap version as nobody else yet opened and - * stored it. I do not like this method but didn't - * found a way to understand if an opened tdb have - * been just created or not --- SSS */ - tdb_store_int32(idmap_tdb_common_ctx, "IDMAP_VERSION", IDMAP_VERSION); - } - /* check against earlier versions */ - version = tdb_fetch_int32(idmap_tdb_common_ctx, "IDMAP_VERSION"); + version = dbwrap_fetch_int32(db, "IDMAP_VERSION"); if (version != IDMAP_VERSION) { - - /* backup_tdb expects the tdb not to be open */ - tdb_close(idmap_tdb_common_ctx); + 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 (db->transaction_start(db) != 0) { + DEBUG(0, ("Unable to start upgrade transaction!\n")); + ret = NT_STATUS_INTERNAL_DB_ERROR; + goto done; + } - if ( ! idmap_tdb_upgrade(tdbfile)) { - + if (!idmap_tdb_upgrade(db)) { + db->transaction_cancel(db); DEBUG(0, ("Unable to open idmap database, it's in an old formati, and upgrade failed!\n")); ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } - /* Re-Open idmap repository */ - if (!(idmap_tdb_common_ctx = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644))) { - DEBUG(0, ("Unable to open idmap database\n")); - ret = NT_STATUS_UNSUCCESSFUL; + if (db->transaction_commit(db) != 0) { + DEBUG(0, ("Unable to commit upgrade transaction!\n")); + ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } } - *tdbctx = idmap_tdb_common_ctx; - idmap_tdb_open_ref_count++; + *dbctx = talloc_move(memctx, &db); ret = NT_STATUS_OK; done: @@ -281,29 +307,11 @@ done: return ret; } - /* NEVER use tdb_close() except for the conversion routines that are guaranteed - * to run only when the database is opened the first time, always use this function. */ - -bool idmap_tdb_tdb_close(TDB_CONTEXT *tdbctx) -{ - if (tdbctx != idmap_tdb_common_ctx) { - DEBUG(0, ("ERROR: Invalid tdb context!")); - return False; - } - - idmap_tdb_open_ref_count--; - if (idmap_tdb_open_ref_count) { - return True; - } -- Samba Shared Repository