From a83b327f1bec10f18ebe59c2fde7fe74228149f2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2008 08:35:35 +0100 Subject: s3:dbwrap: add get_flags() hook to db_context metze --- source3/include/dbwrap.h | 1 + source3/lib/dbwrap_ctdb.c | 8 ++++++++ source3/lib/dbwrap_tdb.c | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index 46833fabdce..3312f9c1217 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); diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 38daa61b330..03667ff3552 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 4860c61ab04..b5eb1881d42 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; -- cgit v1.2.1 From 535311d1875a4302a1c42d92046d2cdc8d3ef4ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2008 08:53:31 +0100 Subject: s3:dbwrap: add dbwrap_delete(), dbwrap_store() and dbwrap_fetch() The _bystring function are now just tiny wrappers. metze --- source3/include/dbwrap.h | 5 +++++ source3/lib/dbwrap.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index 3312f9c1217..aad4ccd721e 100644 --- a/source3/include/dbwrap.h +++ b/source3/include/dbwrap.h @@ -83,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 73c2761a1b3..a57b7c97a5d 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)); +} + -- cgit v1.2.1 From 4feafd7c7be947bb38856dee79f057b2671151f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 16 Dec 2008 21:14:36 +0100 Subject: s3:idmap_tdb: convert to the dbwrap api metze --- source3/winbindd/idmap_tdb.c | 467 +++++++++++++++++++++---------------------- 1 file changed, 223 insertions(+), 244 deletions(-) diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 4c8cceb691d..99821ae5010 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; - } - - return tdb_close(idmap_tdb_common_ctx); -} - /********************************************************************** IDMAP ALLOC TDB BACKEND **********************************************************************/ -static TDB_CONTEXT *idmap_alloc_tdb; +static struct db_context *idmap_alloc_db; /********************************** Initialise idmap alloc database. @@ -311,74 +319,70 @@ static TDB_CONTEXT *idmap_alloc_tdb; static NTSTATUS idmap_tdb_alloc_init( const char *params ) { - NTSTATUS ret; - TALLOC_CTX *ctx; - uid_t low_uid = 0; - uid_t high_uid = 0; - gid_t low_gid = 0; - gid_t high_gid = 0; - uint32_t low_id; + int ret; + NTSTATUS status; + uint32_t low_uid; + uint32_t low_gid; + bool update_uid = false; + bool update_gid = false; - /* use our own context here */ - ctx = talloc_new(NULL); - if (!ctx) { - DEBUG(0, ("Out of memory!\n")); - return NT_STATUS_NO_MEMORY; + 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; } - ret = idmap_tdb_open_db(ctx, &idmap_alloc_tdb); - if ( ! NT_STATUS_IS_OK(ret)) { - talloc_free(ctx); - return ret; + low_uid = dbwrap_fetch_int32(idmap_alloc_db, HWM_USER); + if (low_uid == -1 || low_uid < idmap_tdb_state.low_uid) { + update_uid = true; } - talloc_free(ctx); - - /* 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")); - return NT_STATUS_UNSUCCESSFUL; + low_gid = dbwrap_fetch_int32(idmap_alloc_db, HWM_GROUP); + if (low_gid == -1 || low_gid < idmap_tdb_state.low_gid) { + update_gid = true; } - 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")); - DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); - return NT_STATUS_UNSUCCESSFUL; + if (!update_uid && !update_gid) { + return NT_STATUS_OK; } - if (idmap_tdb_state.high_gid <= idmap_tdb_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 (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 (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_USER)) == -1) || - (low_id < idmap_tdb_state.low_uid)) { - if (tdb_store_int32(idmap_alloc_tdb, HWM_USER, - idmap_tdb_state.low_uid) == -1) { + 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 (((low_id = tdb_fetch_int32(idmap_alloc_tdb, HWM_GROUP)) == -1) || - (low_id < idmap_tdb_state.low_gid)) { - if (tdb_store_int32(idmap_alloc_tdb, HWM_GROUP, - idmap_tdb_state.low_gid) == -1) { + 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; } @@ -414,7 +418,7 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) return NT_STATUS_INVALID_PARAMETER; } - if ((hwm = tdb_fetch_int32(idmap_alloc_tdb, hwmkey)) == -1) { + if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) { return NT_STATUS_INTERNAL_DB_ERROR; } @@ -426,9 +430,9 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) } /* fetch a new id and increment it */ - ret = tdb_change_uint32_atomic(idmap_alloc_tdb, hwmkey, &hwm, 1); - if (!ret) { - DEBUG(1, ("Fatal error while fetching a new %s value\n!", hwmtype)); + ret = dbwrap_change_uint32_atomic(idmap_alloc_db, hwmkey, &hwm, 1); + if (ret != 0) { + DEBUG(0, ("Fatal error while fetching a new %s value\n!", hwmtype)); return NT_STATUS_UNSUCCESSFUL; } @@ -475,7 +479,7 @@ static NTSTATUS idmap_tdb_get_hwm(struct unixid *xid) return NT_STATUS_INVALID_PARAMETER; } - if ((hwm = tdb_fetch_int32(idmap_alloc_tdb, hwmkey)) == -1) { + if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) { return NT_STATUS_INTERNAL_DB_ERROR; } @@ -522,7 +526,7 @@ static NTSTATUS idmap_tdb_set_hwm(struct unixid *xid) hwm = xid->id; - if ((hwm = tdb_store_int32(idmap_alloc_tdb, hwmkey, hwm)) == -1) { + if ((hwm = dbwrap_store_uint32(idmap_alloc_db, hwmkey, hwm)) == -1) { return NT_STATUS_INTERNAL_DB_ERROR; } @@ -541,13 +545,7 @@ static NTSTATUS idmap_tdb_set_hwm(struct unixid *xid) static NTSTATUS idmap_tdb_alloc_close(void) { - if (idmap_alloc_tdb) { - if (idmap_tdb_tdb_close(idmap_alloc_tdb) == 0) { - return NT_STATUS_OK; - } else { - return NT_STATUS_UNSUCCESSFUL; - } - } + TALLOC_FREE(idmap_alloc_db); return NT_STATUS_OK; } @@ -556,7 +554,7 @@ static NTSTATUS idmap_tdb_alloc_close(void) **********************************************************************/ struct idmap_tdb_context { - TDB_CONTEXT *tdb; + struct db_context *db; uint32_t filter_low_id; uint32_t filter_high_id; }; @@ -585,7 +583,7 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params) goto failed; } - ret = idmap_tdb_open_db(ctx, &ctx->tdb); + ret = idmap_tdb_open_db(ctx, false, &ctx->db); if ( ! NT_STATUS_IS_OK(ret)) { goto failed; } @@ -657,7 +655,7 @@ static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map DEBUG(10,("Fetching record %s\n", keystr)); /* Check if the mapping exists */ - data = tdb_fetch_bystring(ctx->tdb, keystr); + data = dbwrap_fetch_bystring(ctx->db, NULL, keystr); if (!data.dptr) { DEBUG(10,("Record %s not found\n", keystr)); @@ -676,7 +674,7 @@ static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map ret = NT_STATUS_OK; done: - SAFE_FREE(data.dptr); + talloc_free(data.dptr); talloc_free(keystr); return ret; } @@ -703,7 +701,7 @@ static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map DEBUG(10,("Fetching record %s\n", keystr)); /* Check if sid is present in database */ - data = tdb_fetch_bystring(ctx->tdb, keystr); + data = dbwrap_fetch_bystring(ctx->db, NULL, keystr); if (!data.dptr) { DEBUG(10,("Record %s not found\n", keystr)); ret = NT_STATUS_NONE_MAPPED; @@ -728,7 +726,7 @@ static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map ret = NT_STATUS_INTERNAL_DB_ERROR; } - SAFE_FREE(data.dptr); + TALLOC_FREE(data.dptr); /* apply filters before returning result */ if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) || @@ -828,7 +826,7 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, { struct idmap_tdb_context *ctx; NTSTATUS ret; - TDB_DATA ksid, kid, data; + TDB_DATA ksid, kid; char *ksidstr, *kidstr; fstring tmp; @@ -837,7 +835,6 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, } ksidstr = kidstr = NULL; - data.dptr = NULL; /* TODO: should we filter a set_mapping using low/high filters ? */ @@ -877,64 +874,41 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, kid = string_term_tdb_data(kidstr); ksid = string_term_tdb_data(ksidstr); - /* *DELETE* previous mappings if any. - * This is done for both the SID and [U|G]ID passed in */ - - /* NOTE: We should lock both the ksid and kid records here, before - * making modifications. However, because tdb_chainlock() is a - * blocking call we could create an unrecoverable deadlock, so for now - * we only lock the ksid record. */ - - /* Lock the record for this SID. */ - if (tdb_chainlock(ctx->tdb, ksid) != 0) { - DEBUG(10,("Failed to lock record %s. Error %s\n", - ksidstr, tdb_errorstr(ctx->tdb) )); - return NT_STATUS_UNSUCCESSFUL; - } - - data = tdb_fetch(ctx->tdb, ksid); - if (data.dptr) { - DEBUG(10, ("Deleting existing mapping %s <-> %s\n", - (const char *)data.dptr, ksidstr )); - tdb_delete(ctx->tdb, data); - tdb_delete(ctx->tdb, ksid); - SAFE_FREE(data.dptr); + if (ctx->db->transaction_start(ctx->db) != 0) { + DEBUG(0, ("Failed to start transaction for %s\n", + ksidstr)); + ret = NT_STATUS_INTERNAL_DB_ERROR; + goto done; } - data = tdb_fetch(ctx->tdb, kid); - if (data.dptr) { - DEBUG(10,("Deleting existing mapping %s <-> %s\n", - (const char *)data.dptr, kidstr )); - tdb_delete(ctx->tdb, data); - tdb_delete(ctx->tdb, kid); - SAFE_FREE(data.dptr); + ret = dbwrap_store(ctx->db, ksid, kid, TDB_REPLACE); + if (!NT_STATUS_IS_OK(ret)) { + ctx->db->transaction_cancel(ctx->db); + DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n", + ksidstr, kidstr, nt_errstr(ret))); + goto done; } - - if (tdb_store(ctx->tdb, ksid, kid, TDB_INSERT) == -1) { - DEBUG(0, ("Error storing SID -> ID: %s\n", - tdb_errorstr(ctx->tdb))); - tdb_chainunlock(ctx->tdb, ksid); - ret = NT_STATUS_UNSUCCESSFUL; + ret = dbwrap_store(ctx->db, kid, ksid, TDB_REPLACE); + if (!NT_STATUS_IS_OK(ret)) { + ctx->db->transaction_cancel(ctx->db); + DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n", + kidstr, ksidstr, nt_errstr(ret))); goto done; } - if (tdb_store(ctx->tdb, kid, ksid, TDB_INSERT) == -1) { - DEBUG(0, ("Error storing ID -> SID: %s\n", - tdb_errorstr(ctx->tdb))); - /* try to remove the previous stored SID -> ID map */ - tdb_delete(ctx->tdb, ksid); - tdb_chainunlock(ctx->tdb, ksid); - ret = NT_STATUS_UNSUCCESSFUL; + + if (ctx->db->transaction_commit(ctx->db) != 0) { + DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n", + ksidstr, kidstr)); + ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } - tdb_chainunlock(ctx->tdb, ksid); DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr)); ret = NT_STATUS_OK; done: talloc_free(ksidstr); talloc_free(kidstr); - SAFE_FREE(data.dptr); return ret; } @@ -996,23 +970,17 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, ksid = string_term_tdb_data(ksidstr); kid = string_term_tdb_data(kidstr); - /* NOTE: We should lock both the ksid and kid records here, before - * making modifications. However, because tdb_chainlock() is a - * blocking call we could create an unrecoverable deadlock, so for now - * we only lock the ksid record. */ - - /* Lock the record for this SID. */ - if (tdb_chainlock(ctx->tdb, ksid) != 0) { - DEBUG(10,("Failed to lock record %s. Error %s\n", - ksidstr, tdb_errorstr(ctx->tdb) )); - return NT_STATUS_UNSUCCESSFUL; + if (ctx->db->transaction_start(ctx->db) != 0) { + DEBUG(0, ("Failed to start transaction for %s\n", + ksidstr)); + return NT_STATUS_INTERNAL_DB_ERROR; } /* Check if sid is present in database */ - data = tdb_fetch(ctx->tdb, ksid); + data = dbwrap_fetch(ctx->db, NULL, ksid); if (!data.dptr) { + ctx->db->transaction_cancel(ctx->db); DEBUG(10,("Record %s not found\n", ksidstr)); - tdb_chainunlock(ctx->tdb, ksid); ret = NT_STATUS_NONE_MAPPED; goto done; } @@ -1020,10 +988,10 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, /* Check if sid is mapped to the specified ID */ if ((data.dsize != kid.dsize) || (memcmp(data.dptr, kid.dptr, data.dsize) != 0)) { + ctx->db->transaction_cancel(ctx->db); DEBUG(10,("Specified SID does not map to specified ID\n")); DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, (const char *)data.dptr)); - tdb_chainunlock(ctx->tdb, ksid); ret = NT_STATUS_NONE_MAPPED; goto done; } @@ -1033,18 +1001,32 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, /* Delete previous mappings. */ DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr )); - tdb_delete(ctx->tdb, ksid); + ret = dbwrap_delete(ctx->db, ksid); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Warning: Failed to delete %s: %s\n", + ksidstr, nt_errstr(ret))); + } DEBUG(10,("Deleting existing mapping %s -> %s\n", kidstr, ksidstr )); - tdb_delete(ctx->tdb, kid); + ret = dbwrap_delete(ctx->db, kid); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Warning: Failed to delete %s: %s\n", + kidstr, nt_errstr(ret))); + } + + if (ctx->db->transaction_commit(ctx->db) != 0) { + DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n", + ksidstr, kidstr)); + ret = NT_STATUS_INTERNAL_DB_ERROR; + goto done; + } - tdb_chainunlock(ctx->tdb, ksid); ret = NT_STATUS_OK; done: talloc_free(ksidstr); talloc_free(kidstr); - SAFE_FREE(data.dptr); + talloc_free(data.dptr); return ret; } @@ -1059,11 +1041,7 @@ static NTSTATUS idmap_tdb_close(struct idmap_domain *dom) if (dom->private_data) { ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); - if (idmap_tdb_tdb_close(ctx->tdb) == 0) { - return NT_STATUS_OK; - } else { - return NT_STATUS_UNSUCCESSFUL; - } + TALLOC_FREE(ctx->db); } return NT_STATUS_OK; } @@ -1075,14 +1053,14 @@ struct dump_data { NTSTATUS ret; }; -static int idmap_tdb_dump_one_entry(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA value, void *pdata) +static int idmap_tdb_dump_one_entry(struct db_record *rec, void *pdata) { struct dump_data *data = talloc_get_type(pdata, struct dump_data); struct id_map *maps; int num_maps = *data->num_maps; /* ignore any record but the ones with a SID as key */ - if (strncmp((const char *)key.dptr, "S-", 2) == 0) { + if (strncmp((const char *)rec->key.dptr, "S-", 2) == 0) { maps = talloc_realloc(NULL, *data->maps, struct id_map, num_maps+1); if ( ! maps) { @@ -1098,21 +1076,21 @@ static int idmap_tdb_dump_one_entry(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA val return -1; } - if (!string_to_sid(maps[num_maps].sid, (const char *)key.dptr)) { - DEBUG(10,("INVALID record %s\n", (const char *)key.dptr)); + if (!string_to_sid(maps[num_maps].sid, (const char *)rec->key.dptr)) { + DEBUG(10,("INVALID record %s\n", (const char *)rec->key.dptr)); /* continue even with errors */ return 0; } /* Try a UID record. */ - if (sscanf((const char *)value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) { + if (sscanf((const char *)rec->value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) { maps[num_maps].xid.type = ID_TYPE_UID; maps[num_maps].status = ID_MAPPED; *data->num_maps = num_maps + 1; /* Try a GID record. */ } else - if (sscanf((const char *)value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) { + if (sscanf((const char *)rec->value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) { maps[num_maps].xid.type = ID_TYPE_GID; maps[num_maps].status = ID_MAPPED; *data->num_maps = num_maps + 1; @@ -1121,7 +1099,8 @@ static int idmap_tdb_dump_one_entry(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA val } else { maps[num_maps].status = ID_UNKNOWN; DEBUG(2, ("Found INVALID record %s -> %s\n", - (const char *)key.dptr, (const char *)value.dptr)); + (const char *)rec->key.dptr, + (const char *)rec->value.dptr)); /* do not increment num_maps */ } } @@ -1150,7 +1129,7 @@ static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **ma data->num_maps = num_maps; data->ret = NT_STATUS_OK; - tdb_traverse(ctx->tdb, idmap_tdb_dump_one_entry, data); + ctx->db->traverse_read(ctx->db, idmap_tdb_dump_one_entry, data); if ( ! NT_STATUS_IS_OK(data->ret)) { ret = data->ret; -- cgit v1.2.1 From 288ce60748576a64efd5d3a3897fae1110379565 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 Jan 2009 19:24:54 +0100 Subject: Add some more entries to WHATSNEW, by no means complete. --- WHATSNEW4.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index ee083785fcb..5ac0b0b39fb 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -132,6 +132,16 @@ continued to evolve, but you may particularly notice these areas Auxiliary classes in LDAP schema conversion are now collapsed. + Several tests have been added to the SMB testsuite. + + Object GUIDs in DCE/RPC connections are now dealt with properly. + + The correctness of the LSA and NETLOGON implementations has been + improved. + + Multi Master Replication configuration can now be generated + for OpenLDAP. + These are just some of the highlights of the work done in the past few months. More details can be found in our GIT history. -- cgit v1.2.1