[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue Dec 16 13:23:12 MST 2014


The branch, master has been updated
       via  173a647 notify: Move path construction to notify_trigger
       via  db2f5b4 lib: Add ctdbd_messaging_send to ctdb_dummy.c
       via  cf2c12b messaging3: Add messaging_handler_send/recv
       via  28f7506 messaging3: Add messaging_send_iov_from
       via  d9a8453 messaging3: Add messaging_names_db
       via  bbc5c64 dbwrap: Add code to marshall a db_context's db
       via  972efb0 lib: Add server_id_db
       via  5d7a183 lib: Add "strv" string handling routines
       via  b306f16 lib: Add tdb_fetch_talloc
       via  7be1dfa lib: Add map_unix_error_from_tdb
      from  10fdf4f smbstatus: Tell the user that smbstatus can only be run as root.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 173a647698da0e67047aa1073552cc06ed90c87d
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 2 17:54:53 2014 +0100

    notify: Move path construction to notify_trigger
    
    notify_msg won't need to construct the path anymore, it will be able to
    put the parts into iovecs
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Dec 16 21:22:26 CET 2014 on sn-devel-104

commit db2f5b4c21acddffce9960ebdc906be16c9e34af
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 12 10:08:36 2014 +0000

    lib: Add ctdbd_messaging_send to ctdb_dummy.c
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cf2c12baa8a5031fbe419399e1a00e89c465cf52
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 13 11:25:40 2014 +0000

    messaging3: Add messaging_handler_send/recv
    
    This repeatedly listens on msg_type. It's similar to messaging_register
    with talloc based autocleanup. The handler is free to talloc_move a way
    the record for later use.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 28f750643bac2049eeeaab23d7d2d9a5a6256bcd
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 12 16:42:59 2014 +0100

    messaging3: Add messaging_send_iov_from
    
    In the notifyd code it will be very helpful to fake source server_ids
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d9a8453bbf69567236038e62f1c5cc4df25d899b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Oct 17 12:09:03 2014 +0000

    messaging3: Add messaging_names_db
    
    This will enable messaging3 users to more easily register themselves
    under a name
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit bbc5c64191d304aabf6ebebb2111396ee8bc2bc1
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 5 13:02:38 2014 +0000

    dbwrap: Add code to marshall a db_context's db
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 972efb05e0ee467c1049207a803090a056aa17f6
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 15 16:14:42 2014 +0000

    lib: Add server_id_db
    
    This is a mapping from names to server_ids. In the future, this will
    replace the namedb in source4/messaging.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5d7a183b9eb444f12bb501f5314afb01e5944966
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 15 13:26:51 2014 +0000

    lib: Add "strv" string handling routines
    
    This is a little set of routines designed after the glibc argz
    routines. It is supposed to eventually replace our inefficient string_list
    routines. A talloc blob is an array of strings separated by the \0
    character. See argz(3) on a Linux system for the ideas where this came
    from. Based on talloc strv is simpler because talloc knows about the
    size of the blob, so we don't have to explicitly maintain it.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b306f165648b54c8b302974e1938d694c571b23a
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Oct 21 10:39:53 2014 +0000

    lib: Add tdb_fetch_talloc
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7be1dfa05c6b3c9077f09fd29f6ffdd8ea4011ec
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Sep 14 13:10:58 2014 +0200

    lib: Add map_unix_error_from_tdb
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/dbwrap/dbwrap.h                               |   9 +
 lib/dbwrap/dbwrap_util.c                          | 166 ++++++++++++
 lib/util/server_id_db.c                           | 308 ++++++++++++++++++++++
 lib/util/server_id_db.h                           |  47 ++++
 lib/util/strv.c                                   | 141 ++++++++++
 source3/utils/status_profile.h => lib/util/strv.h |  20 +-
 lib/util/util_tdb.c                               |  90 +++++++
 lib/util/util_tdb.h                               |  10 +-
 lib/util/wscript_build                            |  10 +
 source3/include/messages.h                        |  14 +
 source3/lib/ctdb_dummy.c                          |   7 +
 source3/lib/messages.c                            | 130 ++++++++-
 source3/smbd/notify.c                             |  13 +-
 source3/smbd/notify_internal.c                    |  19 +-
 source3/smbd/proto.h                              |   3 +-
 source3/wscript_build                             |   1 +
 16 files changed, 954 insertions(+), 34 deletions(-)
 create mode 100644 lib/util/server_id_db.c
 create mode 100644 lib/util/server_id_db.h
 create mode 100644 lib/util/strv.c
 copy source3/utils/status_profile.h => lib/util/strv.h (58%)


Changeset truncated at 500 lines:

diff --git a/lib/dbwrap/dbwrap.h b/lib/dbwrap/dbwrap.h
index e56e036..00c7672 100644
--- a/lib/dbwrap/dbwrap.h
+++ b/lib/dbwrap/dbwrap.h
@@ -155,6 +155,15 @@ NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
 NTSTATUS dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
 				     const char *key, TDB_DATA *value);
 
+size_t dbwrap_marshall(struct db_context *db, uint8_t *buf, size_t bufsize);
+NTSTATUS dbwrap_parse_marshall_buf(const uint8_t *buf, size_t buflen,
+				   bool (*fn)(TDB_DATA key, TDB_DATA value,
+					      void *private_data),
+				   void *private_data);
+NTSTATUS dbwrap_unmarshall(struct db_context *db, const uint8_t *buf,
+			   size_t buflen);
+
+
 /**
  * This opens an ntdb or tdb file: you can hand it a .ntdb or .tdb extension
  * and it will decide (based on parameter settings, or else what exists) which
diff --git a/lib/dbwrap/dbwrap_util.c b/lib/dbwrap/dbwrap_util.c
index 4185fff..901ef56 100644
--- a/lib/dbwrap/dbwrap_util.c
+++ b/lib/dbwrap/dbwrap_util.c
@@ -595,3 +595,169 @@ NTSTATUS dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
 	talloc_free(key_upper);
 	return status;
 }
+
+struct dbwrap_marshall_state {
+	uint8_t *buf;
+	size_t bufsize;
+	size_t dbsize;
+};
+
+static int dbwrap_marshall_fn(struct db_record *rec, void *private_data)
+{
+	struct dbwrap_marshall_state *state = private_data;
+	TDB_DATA key, value;
+	size_t new_dbsize;
+
+	key = dbwrap_record_get_key(rec);
+	value = dbwrap_record_get_value(rec);
+
+	new_dbsize = state->dbsize;
+	new_dbsize += 8 + key.dsize;
+	new_dbsize += 8 + value.dsize;
+
+	if (new_dbsize <= state->bufsize) {
+		uint8_t *p = state->buf + state->dbsize;
+
+		SBVAL(p, 0, key.dsize);
+		p += 8;
+		memcpy(p, key.dptr, key.dsize);
+		p += key.dsize;
+
+		SBVAL(p, 0, value.dsize);
+		p += 8;
+		memcpy(p, value.dptr, value.dsize);
+	}
+	state->dbsize = new_dbsize;
+	return 0;
+}
+
+size_t dbwrap_marshall(struct db_context *db, uint8_t *buf, size_t bufsize)
+{
+	struct dbwrap_marshall_state state;
+
+	state.bufsize = bufsize;
+	state.buf = buf;
+	state.dbsize = 0;
+
+	dbwrap_traverse_read(db, dbwrap_marshall_fn, &state, NULL);
+
+	return state.dbsize;
+}
+
+static ssize_t dbwrap_unmarshall_get_data(const uint8_t *buf, size_t buflen,
+					  size_t ofs, TDB_DATA *pdata)
+{
+	uint64_t space, len;
+	const uint8_t *p;
+
+	if (ofs == buflen) {
+		return 0;
+	}
+	if (ofs > buflen) {
+		return -1;
+	}
+
+	space = buflen - ofs;
+	if (space < 8) {
+		return -1;
+	}
+
+	p = buf + ofs;
+	len = BVAL(p, 0);
+
+	p += 8;
+	space -= 8;
+
+	if (len > space) {
+		return -1;
+	}
+
+	*pdata = (TDB_DATA) { .dptr = discard_const_p(uint8_t, p),
+			      .dsize = len };
+	return len + 8;
+}
+
+NTSTATUS dbwrap_parse_marshall_buf(const uint8_t *buf, size_t buflen,
+				   bool (*fn)(TDB_DATA key, TDB_DATA value,
+					      void *private_data),
+				   void *private_data)
+{
+	size_t ofs = 0;
+
+	while (true) {
+		ssize_t len;
+		TDB_DATA key, value;
+		bool ok;
+
+		len = dbwrap_unmarshall_get_data(buf, buflen, ofs, &key);
+		if (len == 0) {
+			break;
+		}
+		if (len == -1) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		ofs += len;
+
+		len = dbwrap_unmarshall_get_data(buf, buflen, ofs, &value);
+		if (len == 0) {
+			break;
+		}
+		if (len == -1) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		ofs += len;
+
+		ok = fn(key, value, private_data);
+		if (!ok) {
+			break;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+struct dbwrap_unmarshall_state {
+	struct db_context *db;
+	NTSTATUS ret;
+};
+
+static bool dbwrap_unmarshall_fn(TDB_DATA key, TDB_DATA value,
+				 void *private_data)
+{
+	struct dbwrap_unmarshall_state *state = private_data;
+	struct db_record *rec;
+	NTSTATUS status;
+
+	rec = dbwrap_fetch_locked(state->db, state->db, key);
+	if (rec == NULL) {
+		DEBUG(10, ("%s: dbwrap_fetch_locked failed\n",
+			   __func__));
+		state->ret = NT_STATUS_NO_MEMORY;
+		return false;
+	}
+
+	status = dbwrap_record_store(rec, value, 0);
+	TALLOC_FREE(rec);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("%s: dbwrap_record_store failed: %s\n",
+			   __func__, nt_errstr(status)));
+		state->ret = status;
+		return false;
+	}
+
+	return true;
+}
+
+NTSTATUS dbwrap_unmarshall(struct db_context *db, const uint8_t *buf,
+			   size_t buflen)
+{
+	struct dbwrap_unmarshall_state state = { .db = db };
+	NTSTATUS status;
+
+	status = dbwrap_parse_marshall_buf(buf, buflen,
+					   dbwrap_unmarshall_fn, &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+	return state.ret;
+}
diff --git a/lib/util/server_id_db.c b/lib/util/server_id_db.c
new file mode 100644
index 0000000..7f5b055
--- /dev/null
+++ b/lib/util/server_id_db.c
@@ -0,0 +1,308 @@
+/*
+ * Map names to server_ids
+ *
+ * Copyright Volker Lendecke <vl at samba.org> 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/server_id_db.h"
+#include "lib/tdb_wrap/tdb_wrap.h"
+#include "lib/util/strv.h"
+#include "lib/util/util_tdb.h"
+#include "lib/util/samba_util.h"
+
+static TDB_DATA talloc_tdb_data(void *ptr)
+{
+	return (TDB_DATA) { .dptr = ptr, .dsize = talloc_get_size(ptr) };
+}
+
+struct server_id_db {
+	struct server_id pid;
+	struct tdb_wrap *tdb;
+	char *names;
+};
+
+static int server_id_db_destructor(struct server_id_db *db);
+
+struct server_id_db *server_id_db_init(TALLOC_CTX *mem_ctx,
+				       struct server_id pid,
+				       const char *base_path,
+				       int hash_size, int tdb_flags)
+{
+	struct server_id_db *db;
+	size_t pathlen = strlen(base_path) + 11;
+	char path[pathlen];
+
+	db = talloc(mem_ctx, struct server_id_db);
+	if (db == NULL) {
+		return NULL;
+	}
+	db->pid = pid;
+	db->names = NULL;
+
+	snprintf(path, pathlen, "%s/names.tdb", base_path);
+
+	db->tdb = tdb_wrap_open(db, path, hash_size, tdb_flags,
+				O_RDWR|O_CREAT, 0660);
+	if (db->tdb == NULL) {
+		TALLOC_FREE(db);
+		return NULL;
+	}
+
+	talloc_set_destructor(db, server_id_db_destructor);
+
+	return db;
+}
+
+void server_id_db_reinit(struct server_id_db *db, struct server_id pid)
+{
+	db->pid = pid;
+	TALLOC_FREE(db->names);
+}
+
+static int server_id_db_destructor(struct server_id_db *db)
+{
+	char *name = NULL;
+
+	while ((name = strv_next(db->names, name)) != NULL) {
+		server_id_db_remove(db, name);
+	}
+
+	return 0;
+}
+
+int server_id_db_add(struct server_id_db *db, const char *name)
+{
+	struct tdb_context *tdb = db->tdb->tdb;
+	struct server_id_buf buf;
+	TDB_DATA key, data;
+	char *n;
+	int ret;
+
+	n = strv_find(db->names, name);
+	if (n != NULL) {
+		return EEXIST;
+	}
+
+	ret = strv_add(db, &db->names, name);
+	if (ret != 0) {
+		return ret;
+	}
+
+	key = string_term_tdb_data(name);
+
+	server_id_str_buf(db->pid, &buf);
+	data = string_term_tdb_data(buf.buf);
+
+	ret = tdb_append(tdb, key, data);
+	if (ret != 0) {
+		enum TDB_ERROR err = tdb_error(tdb);
+		strv_delete(&db->names, strv_find(db->names, name));
+		return map_unix_error_from_tdb(err);
+	}
+
+	return 0;
+}
+
+int server_id_db_remove(struct server_id_db *db, const char *name)
+{
+	struct tdb_context *tdb = db->tdb->tdb;
+	struct server_id_buf buf;
+	TDB_DATA key;
+	uint8_t *data;
+	char *ids, *n, *id;
+	int ret;
+
+	n = strv_find(db->names, name);
+	if (n == NULL) {
+		return ENOENT;
+	}
+
+	key = string_term_tdb_data(name);
+	server_id_str_buf(db->pid, &buf);
+
+	ret = tdb_chainlock(tdb, key);
+	if (ret == -1) {
+		enum TDB_ERROR err = tdb_error(tdb);
+		return map_unix_error_from_tdb(err);
+	}
+
+	ret = tdb_fetch_talloc(tdb, key, db, &data);
+	if (ret != 0) {
+		tdb_chainunlock(tdb, key);
+		return ret;
+	}
+
+	ids = (char *)data;
+
+	id = strv_find(ids, buf.buf);
+	if (id == NULL) {
+		tdb_chainunlock(tdb, key);
+		TALLOC_FREE(data);
+		return ENOENT;
+	}
+
+	strv_delete(&ids, id);
+	ret = tdb_store(tdb, key, talloc_tdb_data(ids), TDB_MODIFY);
+	TALLOC_FREE(data);
+
+	tdb_chainunlock(tdb, key);
+
+	if (ret == -1) {
+		enum TDB_ERROR err = tdb_error(tdb);
+		return map_unix_error_from_tdb(err);
+	}
+
+	strv_delete(&db->names, n);
+	return 0;
+}
+
+int server_id_db_lookup(struct server_id_db *db, const char *name,
+			TALLOC_CTX *mem_ctx, unsigned *pnum_servers,
+			struct server_id **pservers)
+{
+	struct tdb_context *tdb = db->tdb->tdb;
+	TDB_DATA key;
+	uint8_t *data;
+	char *ids, *id;
+	unsigned num_servers;
+	struct server_id *servers;
+	int i, ret;
+
+	key = string_term_tdb_data(name);
+
+	ret = tdb_fetch_talloc(tdb, key, mem_ctx, &data);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ids = (char *)data;
+	num_servers = strv_count(ids);
+
+	servers = talloc_array(mem_ctx, struct server_id, num_servers);
+	if (servers == NULL) {
+		TALLOC_FREE(data);
+		return ENOMEM;
+	}
+
+	i = 0;
+
+	for (id = ids; id != NULL; id = strv_next(ids, id)) {
+		servers[i++] = server_id_from_string(NONCLUSTER_VNN, id);
+	}
+
+	TALLOC_FREE(data);
+
+	*pnum_servers = num_servers;
+	*pservers = servers;
+
+	return 0;
+}
+
+bool server_id_db_lookup_one(struct server_id_db *db, const char *name,
+			     struct server_id *server)
+{
+	int ret;
+	unsigned num_servers;
+	struct server_id *servers;
+
+	ret = server_id_db_lookup(db, name, db, &num_servers, &servers);
+	if (ret != 0) {
+		return false;
+	}
+	if (num_servers == 0) {
+		TALLOC_FREE(servers);
+		return false;
+	}
+	*server = servers[0];
+	TALLOC_FREE(servers);
+	return true;
+}
+
+struct server_id_db_traverse_state {
+	TALLOC_CTX *mem_ctx;
+	int (*fn)(const char *name,
+		  unsigned num_servers,
+		  const struct server_id *servers,
+		  void *private_data);
+	void *private_data;
+};
+
+static int server_id_db_traverse_fn(struct tdb_context *tdb,
+				    TDB_DATA key, TDB_DATA data,
+				    void *private_data)
+{
+	struct server_id_db_traverse_state *state = private_data;
+	const char *name;
+	char *ids, *id;
+	unsigned num_servers;
+	struct server_id *servers;
+	int i, ret;
+
+	if (key.dsize == 0) {
+		return 0;
+	}
+	if (key.dptr[key.dsize-1] != '\0') {
+		return 0;
+	}
+	name = (const char *)key.dptr;
+
+	ids = (char *)talloc_memdup(state->mem_ctx, data.dptr, data.dsize);
+	if (ids == NULL) {
+		return 0;
+	}
+
+	num_servers = strv_count(ids);
+	servers = talloc_array(ids, struct server_id, num_servers);
+
+	i = 0;
+
+	for (id = ids; id != NULL; id = strv_next(ids, id)) {
+		servers[i++] = server_id_from_string(NONCLUSTER_VNN, id);
+	}
+
+	ret = state->fn(name, num_servers, servers, state->private_data);
+
+	TALLOC_FREE(ids);
+
+	return ret;
+}
+
+int server_id_db_traverse_read(struct server_id_db *db,
+			       int (*fn)(const char *name,
+					 unsigned num_servers,
+					 const struct server_id *servers,
+					 void *private_data),
+			       void *private_data)
+{
+	struct server_id_db_traverse_state state;
+	int ret;
+
+	state = (struct server_id_db_traverse_state) {
+		.fn = fn, .private_data = private_data,
+		.mem_ctx = talloc_new(db)
+	};
+
+	if (state.mem_ctx == NULL) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list