From 68694369fc96354452979b07425f3f48c4f73bbe Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:09:48 +0300 Subject: Merge CTDB-related fixes from samba-ctdb 3.0 branch (http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 0c8e23afbbb2d081fc23908bafcad04650bfacea) --- source3/lib/dbwrap_util.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 source3/lib/dbwrap_util.c (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c new file mode 100644 index 0000000000..002d572019 --- /dev/null +++ b/source3/lib/dbwrap_util.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + Utility functions for the dbwrap API + Copyright (C) Volker Lendecke 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr) +{ + TDB_DATA dbuf; + int32 ret; + + if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) { + return -1; + } + + if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(int32_t))) { + TALLOC_FREE(dbuf.dptr); + return -1; + } + + ret = IVAL(dbuf.dptr, 0); + TALLOC_FREE(dbuf.dptr); + return ret; +} + +int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v) +{ + struct db_record *rec; + int32 v_store; + NTSTATUS status; + + rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr)); + if (rec == NULL) { + return -1; + } + + SIVAL(&v_store, 0, v); + + status = rec->store(rec, make_tdb_data((const uint8 *)&v_store, + sizeof(v_store)), + TDB_REPLACE); + TALLOC_FREE(rec); + return NT_STATUS_IS_OK(status) ? 0 : -1; +} + +uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, + uint32_t *oldval, uint32_t change_val) +{ + struct db_record *rec; + uint32 val = -1; + TDB_DATA data; + + if (!(rec = db->fetch_locked(db, NULL, + string_term_tdb_data(keystr)))) { + return -1; + } + + if ((rec->value.dptr != NULL) + && (rec->value.dsize == sizeof(val))) { + val = IVAL(rec->value.dptr, 0); + } + + val += change_val; + + data.dsize = sizeof(val); + data.dptr = (uint8 *)&val; + + rec->store(rec, data, TDB_REPLACE); + + TALLOC_FREE(rec); + + return 0; +} + -- cgit From 69d67122b2935ce4e7691a9480444edecac1ab8c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Mar 2008 11:15:10 +0100 Subject: add dbwrap_change_int32_atomic (This used to be commit 4ee21a98bc3d1c41a6d8868e98118c58372b2d1a) --- source3/lib/dbwrap_util.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 002d572019..ba1f6ae96e 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -88,3 +88,31 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, return 0; } +int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, + int32 *oldval, int32 change_val) +{ + struct db_record *rec; + int32 val = -1; + TDB_DATA data; + + if (!(rec = db->fetch_locked(db, NULL, + string_term_tdb_data(keystr)))) { + return -1; + } + + if ((rec->value.dptr != NULL) + && (rec->value.dsize == sizeof(val))) { + val = IVAL(rec->value.dptr, 0); + } + + val += change_val; + + data.dsize = sizeof(val); + data.dptr = (uint8 *)&val; + + rec->store(rec, data, TDB_REPLACE); + + TALLOC_FREE(rec); + + return 0; +} -- cgit From fe0e5d292df820d3c34cdcdfe0880941df9c1621 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2008 13:27:27 +0100 Subject: Add dbwrap_trans_store and dbwrap_trans_delete (This used to be commit e66e502bee65fe44944d325ebeeaa3bf56169eb8) --- source3/lib/dbwrap_util.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index ba1f6ae96e..0bafbe6858 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -116,3 +116,82 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, return 0; } + +int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, + int flag) +{ + int res; + struct db_record *rec; + NTSTATUS status; + + res = db->transaction_start(db); + if (res != 0) { + DEBUG(5, ("transaction_start failed\n")); + } + + rec = db->fetch_locked(db, talloc_tos(), key); + if (rec == NULL) { + DEBUG(5, ("fetch_locked failed\n")); + goto cancel; + } + + status = rec->store(rec, dbuf, flag); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("store returned %s\n", nt_errstr(status))); + goto cancel; + } + + TALLOC_FREE(rec); + + res = db->transaction_commit(db); + if (res != 0) { + DEBUG(5, ("tdb_transaction_commit failed\n")); + } + + return res; + + cancel: + if (db->transaction_cancel(db) != 0) { + smb_panic("Cancelling transaction failed"); + } + return -1; +} + +int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +{ + int res; + struct db_record *rec; + NTSTATUS status; + + res = db->transaction_start(db); + if (res != 0) { + DEBUG(5, ("transaction_start failed\n")); + } + + rec = db->fetch_locked(db, talloc_tos(), key); + if (rec == NULL) { + DEBUG(5, ("fetch_locked failed\n")); + goto cancel; + } + + status = rec->delete_rec(rec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status))); + goto cancel; + } + + TALLOC_FREE(rec); + + res = db->transaction_commit(db); + if (res != 0) { + DEBUG(5, ("tdb_transaction_commit failed\n")); + } + + return res; + + cancel: + if (db->transaction_cancel(db) != 0) { + smb_panic("Cancelling transaction failed"); + } + return -1; +} -- cgit From 32e7cc5193a2c6eaf06a977e16915c74db19d76c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Mar 2008 15:59:58 +0100 Subject: dbwrap: add dbwrap_trans_store_int32() metze Signed-off-by: Stefan Metzmacher (This used to be commit f05e889bc05a816aef5b9ce4f22267e977dade01) --- source3/lib/dbwrap_util.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 0bafbe6858..550e5c482b 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -195,3 +195,18 @@ int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) } return -1; } + +int dbwrap_trans_store_int32(struct db_context *db, const char *keystr, int32_t v) +{ + int ret; + int32 v_store; + + SIVAL(&v_store, 0, v); + + ret = dbwrap_trans_store(db, string_term_tdb_data(keystr), + make_tdb_data((const uint8 *)&v_store, + sizeof(v_store)), + TDB_REPLACE); + + return ret; +} -- cgit From 04ae7b85ea24310cbef34ac20a0b82bcdb714192 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 27 Mar 2008 18:00:25 +0100 Subject: dbwrap: fix dbwrap_trans_[delete|store]() to stop when transaction_start() failed. Michael (This used to be commit ab0aaed907fef233998ff0841d30eabef3263ee8) --- source3/lib/dbwrap_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 550e5c482b..1572f01723 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -127,6 +127,7 @@ int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, res = db->transaction_start(db); if (res != 0) { DEBUG(5, ("transaction_start failed\n")); + return res; } rec = db->fetch_locked(db, talloc_tos(), key); @@ -166,6 +167,7 @@ int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) res = db->transaction_start(db); if (res != 0) { DEBUG(5, ("transaction_start failed\n")); + return res; } rec = db->fetch_locked(db, talloc_tos(), key); -- cgit From d20f88c60302b9af21b3a04e1ebc536a0e0c0e36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Mar 2008 09:42:37 +0100 Subject: Add dbwrap_[fetch|store]_uint32 Signed-off-by: Stefan Metzmacher (This used to be commit f1dd915ce802645166e0c8fc79d18d5ad41cfe7a) --- source3/lib/dbwrap_util.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 1572f01723..01d70556d8 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -59,6 +59,45 @@ int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v) return NT_STATUS_IS_OK(status) ? 0 : -1; } +bool dbwrap_fetch_uint32(struct db_context *db, const char *keystr, + uint32_t *val) +{ + TDB_DATA dbuf; + + if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) { + return false; + } + + if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(uint32_t))) { + TALLOC_FREE(dbuf.dptr); + return false; + } + + *val = IVAL(dbuf.dptr, 0); + TALLOC_FREE(dbuf.dptr); + return true; +} + +bool dbwrap_store_uint32(struct db_context *db, const char *keystr, uint32_t v) +{ + struct db_record *rec; + uint32 v_store; + NTSTATUS status; + + rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr)); + if (rec == NULL) { + return false; + } + + SIVAL(&v_store, 0, v); + + status = rec->store(rec, make_tdb_data((const uint8 *)&v_store, + sizeof(v_store)), + TDB_REPLACE); + TALLOC_FREE(rec); + return NT_STATUS_IS_OK(status) ? 0 : -1; +} + uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, uint32_t *oldval, uint32_t change_val) { -- cgit From fcdfff1cc8c1214cbce1fdd863b1ede970234121 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Mar 2008 11:53:00 +0100 Subject: Convert dbwrap_trans_store to NTSTATUS Signed-off-by: Stefan Metzmacher (This used to be commit 5f4de856af1abe63b13059bbe1615cb5877770d0) --- source3/lib/dbwrap_util.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 01d70556d8..1a636cc8a6 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -156,8 +156,8 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, return 0; } -int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, - int flag) +NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, + int flag) { int res; struct db_record *rec; @@ -166,12 +166,13 @@ int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, res = db->transaction_start(db); if (res != 0) { DEBUG(5, ("transaction_start failed\n")); - return res; + return NT_STATUS_INTERNAL_DB_CORRUPTION; } rec = db->fetch_locked(db, talloc_tos(), key); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); + status = NT_STATUS_NO_MEMORY; goto cancel; } @@ -186,15 +187,17 @@ int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, res = db->transaction_commit(db); if (res != 0) { DEBUG(5, ("tdb_transaction_commit failed\n")); + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto cancel; } - return res; + return NT_STATUS_OK; cancel: if (db->transaction_cancel(db) != 0) { smb_panic("Cancelling transaction failed"); } - return -1; + return status; } int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) @@ -237,17 +240,15 @@ int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) return -1; } -int dbwrap_trans_store_int32(struct db_context *db, const char *keystr, int32_t v) +NTSTATUS dbwrap_trans_store_int32(struct db_context *db, const char *keystr, + int32_t v) { - int ret; int32 v_store; SIVAL(&v_store, 0, v); - ret = dbwrap_trans_store(db, string_term_tdb_data(keystr), - make_tdb_data((const uint8 *)&v_store, + return dbwrap_trans_store(db, string_term_tdb_data(keystr), + make_tdb_data((const uint8 *)&v_store, sizeof(v_store)), - TDB_REPLACE); - - return ret; + TDB_REPLACE); } -- cgit From 16198dc51e8f03d22de73883c0bb6823c464b8c6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Mar 2008 11:57:54 +0100 Subject: Convert dbwrap_trans_delete to NTSTATUS Signed-off-by: Stefan Metzmacher (This used to be commit dead193f46c2b19955ab3e5ac5ba343694f4858a) --- source3/lib/dbwrap_util.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 1a636cc8a6..1005f36b60 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -200,7 +200,7 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, return status; } -int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) +NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) { int res; struct db_record *rec; @@ -209,12 +209,13 @@ int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) res = db->transaction_start(db); if (res != 0) { DEBUG(5, ("transaction_start failed\n")); - return res; + return NT_STATUS_INTERNAL_DB_CORRUPTION; } rec = db->fetch_locked(db, talloc_tos(), key); if (rec == NULL) { DEBUG(5, ("fetch_locked failed\n")); + status = NT_STATUS_NO_MEMORY; goto cancel; } @@ -229,15 +230,17 @@ int dbwrap_trans_delete(struct db_context *db, TDB_DATA key) res = db->transaction_commit(db); if (res != 0) { DEBUG(5, ("tdb_transaction_commit failed\n")); + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto cancel; } - return res; + return NT_STATUS_OK; cancel: if (db->transaction_cancel(db) != 0) { smb_panic("Cancelling transaction failed"); } - return -1; + return status; } NTSTATUS dbwrap_trans_store_int32(struct db_context *db, const char *keystr, -- cgit From 92e6d07ad9743a9e4c10765095b1bdadab2f0541 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Mar 2008 12:02:28 +0100 Subject: Add dbwrap_trans_*_bystring Signed-off-by: Stefan Metzmacher (This used to be commit 2cf2684a11027431e6a93992413a5a5a697a4ba0) --- source3/lib/dbwrap_util.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 1005f36b60..cecb8d6dd6 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -255,3 +255,14 @@ NTSTATUS dbwrap_trans_store_int32(struct db_context *db, const char *keystr, sizeof(v_store)), TDB_REPLACE); } + +NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key, + TDB_DATA data, int flags) +{ + return dbwrap_trans_store(db, string_term_tdb_data(key), data, flags); +} + +NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key) +{ + return dbwrap_trans_delete(db, string_term_tdb_data(key)); +} -- cgit From 3f076ab77384500d6d08ee8b977338ee88911dfe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 28 Mar 2008 20:03:30 +0100 Subject: dbwrap: add dbwrap_trans_store_uint32() metze (This used to be commit 9e739b4c99a9aba5c5bb58f3b6a9fb949e24c581) --- source3/lib/dbwrap_util.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index cecb8d6dd6..1105b083e0 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -256,6 +256,19 @@ NTSTATUS dbwrap_trans_store_int32(struct db_context *db, const char *keystr, TDB_REPLACE); } +NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr, + uint32_t v) +{ + uint32 v_store; + + SIVAL(&v_store, 0, v); + + return dbwrap_trans_store(db, string_term_tdb_data(keystr), + make_tdb_data((const uint8 *)&v_store, + sizeof(v_store)), + TDB_REPLACE); +} + NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key, TDB_DATA data, int flags) { -- cgit From 20dc21f4740588eb9ff95c223cc82bea7b3aa9f7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 30 Mar 2008 13:11:22 +0200 Subject: dbwrap: fix a confusing "tdb_chainunlock failed" message Unlock before we cancel the transaction... metze (This used to be commit d70a8e9c413a7d3993e0d11db5ae9cbc7fdb12c7) --- source3/lib/dbwrap_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 1105b083e0..eea7ca79d7 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -160,7 +160,7 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, int flag) { int res; - struct db_record *rec; + struct db_record *rec = NULL; NTSTATUS status; res = db->transaction_start(db); @@ -194,6 +194,8 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, return NT_STATUS_OK; cancel: + TALLOC_FREE(rec); + if (db->transaction_cancel(db) != 0) { smb_panic("Cancelling transaction failed"); } -- cgit From 2c2379b3216580bfc3f450221cdd325b2dccc80e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Apr 2008 23:36:29 +0200 Subject: dbwrap: fix more "tdb_chainunlock failed" messages TALLOC_FREE(rec) before transaction_cancel also in dbwrap_trans_delete(). Michael (This used to be commit 04cd914a1f12691d27ddc67887a757cd813848a7) --- source3/lib/dbwrap_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index eea7ca79d7..07e50827d4 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -205,7 +205,7 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) { int res; - struct db_record *rec; + struct db_record *rec = NULL; NTSTATUS status; res = db->transaction_start(db); @@ -239,6 +239,8 @@ NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) return NT_STATUS_OK; cancel: + TALLOC_FREE(rec); + if (db->transaction_cancel(db) != 0) { smb_panic("Cancelling transaction failed"); } -- cgit From b59ed9c05f5d5831e6abf5db6f58a75ec98902f8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 5 Aug 2008 22:38:44 +0200 Subject: idmap_tdb2: fix a race condition in idmap_tdb2_allocate_id(). The race is a regression introduced by the change to dbwrap. It might have led to two concurrent processes returning the same id. This fix is achieved by changing dbwrap_change_uint32_atomic() to match the original behaviour of tdb_change_uint32_atomic(), which is the following: *oldval is used as initial value when the value does not yet exist and that the old value should be returned in *oldval. dbwrap_change_uint32_atomic() is used (only) in idmap_tdb2.c, to get new ids. Michael (This used to be commit 72bd83fea7572a6202027b200d192c05023aa633) --- source3/lib/dbwrap_util.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 07e50827d4..14baec11a3 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -110,9 +110,13 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, return -1; } - if ((rec->value.dptr != NULL) - && (rec->value.dsize == sizeof(val))) { + if (rec->value.dptr == NULL) { + val = *oldval; + } else if (rec->value.dsize == sizeof(val)) { val = IVAL(rec->value.dptr, 0); + *oldval = val; + } else { + return -1; } val += change_val; -- cgit From 149e1ae25ab78754532f3005ab7885e826d53104 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 5 Aug 2008 23:13:06 +0200 Subject: dbwrap: add comment describing behaviour of dbwrap_change_uint32_atomic(). Michael (This used to be commit 7edfb54c865ddcfd5cdcc8c2184b96aaac2d2ec0) --- source3/lib/dbwrap_util.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 14baec11a3..3bf312d0d0 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -98,6 +98,13 @@ bool dbwrap_store_uint32(struct db_context *db, const char *keystr, uint32_t v) return NT_STATUS_IS_OK(status) ? 0 : -1; } +/** + * Atomic unsigned integer change (addition): + * + * if value does not exist yet in the db, use *oldval as initial old value. + * return old value in *oldval. + * store *oldval + change_val to db. + */ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, uint32_t *oldval, uint32_t change_val) { -- cgit From 4c5752d40f3854276a4643d834c0cdab8779d43c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 5 Aug 2008 23:14:05 +0200 Subject: secrets: fix replacemend random seed generator (security issue). This is a regression introduced by the change to dbwrap. The replacement dbwrap_change_int32_atomic() does not correctly mimic the behaviour of tdb_change_int32_atomic(): The intended behaviour is to use *oldval as an initial value when the entry does not yet exist in the db and to return the old value in *oldval. The effect was that: 1. get_rand_seed() always returns sys_getpid() in *new_seed instead of the incremented seed from the secrets.tdb. 2. the seed stored in the tdb is always starting at 0 instead of sys_getpid() + 1 and incremented in subsequent calls. In principle this is a security issue, but i think the danger is low, since this is only used as a fallback when there is no useable /dev/urandom, and this is at most called on startup or via reinit_after_fork. Michael (This used to be commit bfc5d34a196f667276ce1e173821db478d01258b) --- source3/lib/dbwrap_util.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 3bf312d0d0..7789f69223 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -150,9 +150,13 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, return -1; } - if ((rec->value.dptr != NULL) - && (rec->value.dsize == sizeof(val))) { + if (rec->value.dptr == NULL) { + val = *oldval; + } else if (rec->value.dsize == sizeof(val)) { val = IVAL(rec->value.dptr, 0); + *oldval = val; + } else { + return -1; } val += change_val; -- cgit From 7b35eec609ac8e120939cd129c8ad9580deaaf5f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 5 Aug 2008 23:38:56 +0200 Subject: dbwrap: add comment describing behaviour of dbwrap_change_int32_atomic(). Michael (This used to be commit f8f21c8e3922806230e240cb54205fc2db7a3619) --- source3/lib/dbwrap_util.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 7789f69223..09e9071d8c 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -138,6 +138,13 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, return 0; } +/** + * Atomic integer change (addition): + * + * if value does not exist yet in the db, use *oldval as initial old value. + * return old value in *oldval. + * store *oldval + change_val to db. + */ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr, int32 *oldval, int32 change_val) { -- cgit From 312a04528c2f3439f0451414fee224dfa4fcb6f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Aug 2008 11:41:21 +1000 Subject: don't leave a dangling transaction on retry error (This used to be commit ddf3022595fe8ca378c5f52107f42e296f852685) --- source3/lib/dbwrap_util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/lib/dbwrap_util.c') diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c index 09e9071d8c..ddc613150b 100644 --- a/source3/lib/dbwrap_util.c +++ b/source3/lib/dbwrap_util.c @@ -210,7 +210,8 @@ NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf, if (res != 0) { DEBUG(5, ("tdb_transaction_commit failed\n")); status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto cancel; + TALLOC_FREE(rec); + return status; } return NT_STATUS_OK; @@ -255,7 +256,8 @@ NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key) if (res != 0) { DEBUG(5, ("tdb_transaction_commit failed\n")); status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto cancel; + TALLOC_FREE(rec); + return status; } return NT_STATUS_OK; -- cgit