[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Mon Apr 4 10:22:02 MDT 2011


The branch, master has been updated
       via  a217ec6 s3-net: add command "net idmap check"
       via  8fc8c88 s3: add function srprs_quoted to parse strings written with cbuf_print_quoted
       via  9272614 s3: add function cbuf_print_quoted
       via  340f20d s3: add function dbwrap_traverse
       via  84019ea s3: add function dbwrap_trans_traverse
       via  10cec2f s3: fix cbuf_swapptr
       via  b7e330a s3:idmap_tdb2: fix build of tdb2
      from  a3ef974 s3-rpc_server Remove comment, yes the key is correct.

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


- Log -----------------------------------------------------------------
commit a217ec64ec5b189f697c58456dad6a6151f763ab
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Jan 28 10:55:58 2011 +0100

    s3-net: add command "net idmap check"
    
    This is a tool to check the consistency of an idmap tdb database.
    
    The default mode is to scan the database and list invalid entries,
    e.g. records with an invalid format, or records which are valid
    but for which the reverse mapping entry is missing.
    
    With the "--repair" switch, one can enter an interactive
    repair mode which will prompt for each invalid entry found
    with the option to delete, skip or edit the record.
    
    There is also a non-interactive repair mode triggered by "--auto"
    which will remove all records with invalid content and fill up
    mappings which are missing the reverse entry.
    
    The "--test" parameter lets "net idmap check" only list the
    changes that would be written and not actually commit them to
    the database.
    
    The "--lock" option allows to lock the database already in the
    first reading traverse, in order to remove the race when the
    database has to be closed and reopened again before writing
    the changes.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User: Michael Adam <obnox at samba.org>
    Autobuild-Date: Mon Apr  4 18:21:09 CEST 2011 on sn-devel-104

commit 8fc8c880074d01af5a2d92fbd9b2fb042bdd59f3
Author: Gregor Beck <gbeck at sernet.de>
Date:   Thu Mar 17 10:22:25 2011 +0100

    s3: add function srprs_quoted to parse strings written with cbuf_print_quoted

commit 9272614d9dad501ad95ac76b40f53e433a4878bc
Author: Gregor Beck <gbeck at sernet.de>
Date:   Thu Mar 17 10:20:30 2011 +0100

    s3: add function cbuf_print_quoted

commit 340f20ddb01da08b6a6ad11143768ffd69b7944e
Author: Gregor Beck <gbeck at sernet.de>
Date:   Fri Mar 18 14:39:15 2011 +0100

    s3: add function dbwrap_traverse

commit 84019ea5288ec3ec83739aa8142ec50cef0f1b82
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 16 09:13:40 2011 +0100

    s3: add function dbwrap_trans_traverse

commit 10cec2f0ec752cbec2055b0aa878b4814f3c1309
Author: Gregor Beck <gbeck at sernet.de>
Date:   Wed Mar 16 09:12:28 2011 +0100

    s3: fix cbuf_swapptr

commit b7e330a2b325463e49abceb8f3e8d792248179ed
Author: Michael Adam <obnox at samba.org>
Date:   Mon Apr 4 11:46:31 2011 +0200

    s3:idmap_tdb2: fix build of tdb2
    
    The include of system/filesys.h was removed from includes.h. ...

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

Summary of changes:
 source3/Makefile.in                                |    2 +-
 source3/include/dbwrap.h                           |    7 +
 source3/lib/cbuf.c                                 |   35 +
 source3/lib/cbuf.h                                 |   17 +-
 source3/lib/dbwrap_util.c                          |   38 +
 source3/lib/srprs.c                                |   40 +
 source3/lib/srprs.h                                |   13 +-
 source3/utils/net.c                                |    3 +
 source3/utils/net.h                                |    3 +
 source3/utils/net_idmap.c                          |   47 +-
 source3/utils/net_idmap_check.c                    | 1006 ++++++++++++++++++++
 .../srv_epmapper.h => utils/net_idmap_check.h}     |   38 +-
 source3/winbindd/idmap_tdb2.c                      |    1 +
 source3/wscript_build                              |    3 +-
 14 files changed, 1236 insertions(+), 17 deletions(-)
 create mode 100644 source3/utils/net_idmap_check.c
 copy source3/{rpc_server/epmapper/srv_epmapper.h => utils/net_idmap_check.h} (56%)


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index a0f28f1..108bfef 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1147,7 +1147,7 @@ LIBNET_SAMSYNC_OBJ = libnet/libnet_samsync.o \
 NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \
 	   utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
 	   utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
-	   utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
+	   utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o utils/net_idmap_check.o\
 	   utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \
 	   utils/net_rpc_service.o utils/net_rpc_registry.o utils/net_usershare.o \
 	   utils/netlookup.o utils/net_sam.o utils/net_rpc_shell.o \
diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h
index 8dba624..ef35b00 100644
--- a/source3/include/dbwrap.h
+++ b/source3/include/dbwrap.h
@@ -127,6 +127,13 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key);
 NTSTATUS dbwrap_trans_do(struct db_context *db,
 			 NTSTATUS (*action)(struct db_context *, void *),
 			 void *private_data);
+NTSTATUS dbwrap_trans_traverse(struct db_context *db,
+			       int (*f)(struct db_record*, void*),
+			       void *private_data);
+NTSTATUS dbwrap_traverse(struct db_context *db,
+			 int (*f)(struct db_record*, void*),
+			 void *private_data);
+
 NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key);
 NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
 				     TDB_DATA data, int flags);
diff --git a/source3/lib/cbuf.c b/source3/lib/cbuf.c
index e9763ae..42353f8 100644
--- a/source3/lib/cbuf.c
+++ b/source3/lib/cbuf.c
@@ -116,8 +116,10 @@ cbuf* cbuf_takeover(cbuf* b1, cbuf* b2)
 
 cbuf* cbuf_swapptr(cbuf* b, char** ptr, size_t len)
 {
+	void* p = talloc_parent(*ptr);
 	SWAP(b->buf, *ptr, char*);
 	talloc_steal(b, b->buf);
+	talloc_steal(p, *ptr);
 	b->size = talloc_get_size(b->buf);
 	b->pos  = (len == -1) ? strlen(b->buf) : len;
 
@@ -284,3 +286,36 @@ int cbuf_print_quoted_string(cbuf* ost, const char* s)
 		s++;
 	}
 }
+
+
+int cbuf_print_quoted(cbuf* ost, const char* s, size_t len)
+{
+	int n = 1;
+	int ret;
+	cbuf_reserve(ost, len+2);
+
+	cbuf_putc(ost,'"');
+
+	while(len--) {
+		switch (*s) {
+		case '"':
+		case '\\':
+			ret = cbuf_printf(ost, "\\%c", *s);
+			break;
+		default:
+			if (isprint(*s) && ((*s == ' ') || !isspace(*s))) {
+				ret = cbuf_putc(ost, *s);
+			} else {
+				ret = cbuf_printf(ost, "\\%02x", *s);
+			}
+		}
+		s++;
+		if (ret == -1) {
+			return -1;
+		}
+		n += ret;
+	}
+	ret = cbuf_putc(ost,'"');
+
+	return (ret == -1) ? -1 : (n + ret);
+}
diff --git a/source3/lib/cbuf.h b/source3/lib/cbuf.h
index ffb52d7..90318ec 100644
--- a/source3/lib/cbuf.h
+++ b/source3/lib/cbuf.h
@@ -225,11 +225,26 @@ char* cbuf_gets(cbuf* b, size_t idx);
  * @see srprs_quoted_string
  *
  * @param[out] ost outstream
- * @param[in]  s string
+ * @param[in]  s '\0' terminated string of printable characters.
  *
  * @return numner of bytes written, -1 on error
  */
 int cbuf_print_quoted_string(cbuf* ost, const char* s);
 
+/**
+ * Print quoted string to stream.
+ * Escapes nonprintable characters.
+ *
+ * @todo check for ssputc failure
+ * @see srprs_quoted
+ *
+ * @param[out] ost outstream
+ * @param[in]  s string of bytes
+ * @param[in]  len number of bytes
+ *
+ * @return numner of bytes written, -1 on error
+ */
+int cbuf_print_quoted(cbuf* ost, const char* s, size_t len);
+
 
 #endif /*__CBUF_H*/
diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c
index 0020fc6..35f8a14 100644
--- a/source3/lib/dbwrap_util.c
+++ b/source3/lib/dbwrap_util.c
@@ -416,6 +416,44 @@ NTSTATUS dbwrap_trans_do(struct db_context *db,
 	return NT_STATUS_INTERNAL_DB_CORRUPTION;
 }
 
+struct dbwrap_trans_traverse_action_ctx {
+	int (*f)(struct db_record* rec, void* private_data);
+	void* private_data;
+};
+
+
+static NTSTATUS dbwrap_trans_traverse_action(struct db_context* db, void* private_data)
+{
+	struct dbwrap_trans_traverse_action_ctx* ctx =
+		(struct dbwrap_trans_traverse_action_ctx*)private_data;
+
+	int ret = db->traverse(db, ctx->f, ctx->private_data);
+
+	return (ret == -1) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
+}
+
+NTSTATUS dbwrap_trans_traverse(struct db_context *db,
+			       int (*f)(struct db_record*, void*),
+			       void *private_data)
+{
+	struct dbwrap_trans_traverse_action_ctx ctx = {
+		.f = f,
+		.private_data = private_data,
+	};
+	return dbwrap_trans_do(db, dbwrap_trans_traverse_action, &ctx);
+}
+
+NTSTATUS dbwrap_traverse(struct db_context *db,
+			 int (*f)(struct db_record*, void*),
+			 void *private_data)
+{
+	int ret = db->traverse(db, f, private_data);
+	return (ret == -1) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
+}
+
+
+
+
 NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key)
 {
 	char *key_upper;
diff --git a/source3/lib/srprs.c b/source3/lib/srprs.c
index 77464f5..5a032d2 100644
--- a/source3/lib/srprs.c
+++ b/source3/lib/srprs.c
@@ -183,3 +183,43 @@ bool srprs_line(const char** ptr, cbuf* str)
 		;
 	return true;
 }
+
+bool srprs_quoted(const char** ptr, cbuf* str)
+{
+	const char* pos = *ptr;
+	const size_t spos = cbuf_getpos(str);
+
+	if (!srprs_char(&pos, '"')) {
+		goto fail;
+	}
+
+	while (true) {
+		while (srprs_charsetinv(&pos, "\\\"", str))
+			;
+
+		switch (*pos) {
+		case '\0':
+			goto fail;
+		case '"':
+			*ptr  = pos+1;
+			return true;
+
+		case '\\':
+			pos++;
+			if (!srprs_charset(&pos, "\\\"", str)) {
+				unsigned u;
+				if (!srprs_hex(&pos, 2, &u)) {
+					goto fail;
+				}
+				cbuf_putc(str, u);
+			}
+			break;
+		default:
+			assert(false);
+		}
+	}
+
+fail:
+	cbuf_setpos(str, spos);
+	return false;
+}
diff --git a/source3/lib/srprs.h b/source3/lib/srprs.h
index bbbcdc7..350e08c 100644
--- a/source3/lib/srprs.h
+++ b/source3/lib/srprs.h
@@ -113,9 +113,10 @@ bool srprs_charsetinv(const char** ptr, const char* set, struct cbuf* oss);
  * assert(*cont == false);
  * assert(strcmp(cbuf_gets(out, 0), "start...continued...end")==0);
  * @endcode
+ * @see cbuf_print_quoted_string
  *
  * @param[in,out] ptr parse position
- * @param[out] str output buffer where to put the match, may be NULL
+ * @param[out] str output buffer where to put the match
  * @param[in,out] cont
  *
  * @return true if matched
@@ -177,5 +178,15 @@ bool srprs_eol(const char** ptr, struct cbuf* nl);
  */
 bool srprs_line(const char** ptr, struct cbuf* str);
 
+/**
+ * Match a quoted string with escaped characters.
+ * @see cbuf_print_quoted
+ *
+ * @param[in,out] ptr parse position
+ * @param[out] str output buffer where to put the match
+ *
+ * @return true if matched
+ */
+bool srprs_quoted(const char** ptr, struct cbuf* str);
 
 #endif /* __SRPRS_H */
diff --git a/source3/utils/net.c b/source3/utils/net.c
index ec202bb..7ade307 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -817,6 +817,9 @@ static struct functable net_func[] = {
 		{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
 		/* Options for 'net idmap'*/
 		{"db", 0, POPT_ARG_STRING, &c->opt_db},
+		{"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
+		{"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
+		{"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
 		POPT_COMMON_SAMBA
 		{ 0, 0, 0, 0}
 	};
diff --git a/source3/utils/net.h b/source3/utils/net.h
index 9618e7a..7ac3b5c 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -76,6 +76,9 @@ struct net_context {
 	int opt_single_obj_repl;
 	int opt_clean_old_entries;
 	const char *opt_db;
+	int opt_lock;
+	int opt_auto;
+	int opt_repair;
 
 	int opt_have_ip;
 	struct sockaddr_storage opt_dest_ip;
diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 79f69f2..c8241e2 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -17,7 +17,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define FOO(x) (x)
 #include "includes.h"
 #include "system/filesys.h"
 #include "utils/net.h"
@@ -25,6 +24,7 @@
 #include "idmap.h"
 #include "dbwrap.h"
 #include "../libcli/security/security.h"
+#include "net_idmap_check.h"
 
 #define ALLOC_CHECK(mem) do { \
 	if (!mem) { \
@@ -535,6 +535,43 @@ static int net_idmap_secret(struct net_context *c, int argc, const char **argv)
 	return 0;
 }
 
+static int net_idmap_check(struct net_context *c, int argc, const char **argv)
+{
+	const char* dbfile;
+	struct check_options opts;
+
+	if ( argc > 1 || c->display_usage) {
+		d_printf("%s\n%s",
+			 _("Usage:"),
+			 _("net idmap check [-f] [-a] [-T] [-v] [--auto] [[--db=]<TDB>]\n"
+			   "  Check an idmap database.\n"
+			   "    --repair,-r\trepair\n"
+			   "    --fore,-f\tforce\n"
+			   "    --auto,-a\tnoninteractive mode\n"
+			   "    --test,-T\tdry run\n"
+			   "    --lock\tlock db while doing the check\n"
+			   "    TDB\tidmap database\n"));
+		return c->display_usage ? 0 : -1;
+	}
+
+	dbfile = (argc > 0) ? argv[0] : net_idmap_dbfile(c);
+	if (dbfile == NULL) {
+		return -1;
+	}
+	d_fprintf(stderr, _("check database: %s\n"), dbfile);
+
+	opts = (struct check_options) {
+		.lock = c->opt_lock,
+		.test = c->opt_testmode,
+		.automatic = c->opt_auto,
+		.verbose = c->opt_verbose,
+		.force = c->opt_force,
+		.repair = c->opt_repair || c->opt_reboot,
+	};
+
+	return net_idmap_check_db(dbfile, &opts);
+}
+
 static int net_idmap_aclmapset(struct net_context *c, int argc, const char **argv)
 {
 	TALLOC_CTX *mem_ctx;
@@ -653,6 +690,14 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			N_("net idmap aclmapset\n"
 			   "  Set acl map")
 		},
+		{
+			"check",
+			net_idmap_check,
+			NET_TRANSPORT_LOCAL,
+			N_("Check id mappings"),
+			N_("net idmap check\n"
+			   "  Check id mappings")
+		},
 		{NULL, NULL, 0, NULL, NULL}
 	};
 
diff --git a/source3/utils/net_idmap_check.c b/source3/utils/net_idmap_check.c
new file mode 100644
index 0000000..5231461
--- /dev/null
+++ b/source3/utils/net_idmap_check.c
@@ -0,0 +1,1006 @@
+/*
+ * Samba Unix/Linux SMB client library
+ *
+ * Copyright (C) Gregor Beck 2011
+ *
+ * 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/>.
+ */
+
+/**
+ * @brief  Check the idmap database.
+ * @author Gregor Beck <gb at sernet.de>
+ * @date   Mar 2011
+ */
+
+#include "net_idmap_check.h"
+#include "includes.h"
+#include "system/filesys.h"
+#include "dbwrap.h"
+#include "net.h"
+#include "../libcli/security/dom_sid.h"
+#include "cbuf.h"
+#include "srprs.h"
+#include <termios.h>
+
+static int traverse_commit(struct db_record *diff_rec, void* data);
+static int traverse_check(struct db_record *rec, void* data);
+
+static char* interact_edit(TALLOC_CTX* mem_ctx, const char* str);
+static int interact_prompt(const char* msg, const char* accept, char def);
+
+/* TDB_DATA *******************************************************************/
+static char*    print_data(TALLOC_CTX* mem_ctx, TDB_DATA d);
+static TDB_DATA parse_data(TALLOC_CTX* mem_ctx, const char** ptr);
+static TDB_DATA talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data);
+static bool is_empty(TDB_DATA data) {
+	return (data.dsize == 0) || (data.dptr == NULL);
+}
+
+/* record *********************************************************************/
+
+enum DT {
+	DT_INV = 0,
+	DT_SID,	DT_UID,	DT_GID,
+	DT_HWM,	DT_VER
+};
+
+struct record {
+	enum DT key_type, val_type;
+	TDB_DATA key, val;
+	struct dom_sid sid;
+	long unsigned  id;
+};
+
+static struct record* parse_record(TALLOC_CTX* ctx, TDB_DATA key, TDB_DATA val);
+static struct record* reverse_record(struct record* rec);
+
+static bool is_invalid(const struct record* r) {
+	return (r->key_type == DT_INV) || (r->val_type == DT_INV);
+}
+
+static bool is_map(const struct record* r) {
+	return (r->key_type == DT_SID)
+		|| (r->key_type == DT_UID) || (r->key_type == DT_GID);
+}
+
+/* action *********************************************************************/
+
+typedef struct check_action {
+	const char* fmt;
+	const char* name;
+	const char* prompt;
+	const char* answers;
+	char auto_action;
+	char default_action;
+	bool verbose;
+} check_action;
+
+struct check_actions {
+	check_action invalid_record;
+	check_action missing_reverse;
+	check_action invalid_mapping;
+	check_action invalid_edit;
+	check_action record_exists;
+	check_action no_version;
+	check_action wrong_version;
+	check_action invalid_hwm;
+	check_action commit;
+	check_action valid_mapping;
+	check_action valid_other;
+	check_action invalid_diff;
+};
+
+static struct check_actions
+check_actions_init(const struct check_options* opts) {
+	struct check_actions ret = {
+		.invalid_record = (check_action) {
+			.name = "Invalid record",
+			.prompt = "[e]dit/[d]elete/[D]elete all"
+			"/[s]kip/[S]kip all",
+			.answers = "eds",
+			.default_action = 'e',
+			.verbose = true,
+		},
+		.missing_reverse = (check_action) {
+			.name = "Missing reverse mapping for",
+			.prompt = "[f]ix/[F]ix all/[e]dit/[d]elete/[D]elete all"
+			"/[s]kip/[S]kip all",
+			.answers = "feds",
+			.default_action = 'f',
+			.verbose = true,
+		},
+		.invalid_mapping = (check_action) {
+			.fmt = "%1$s: %2$s -> %3$s\n(%4$s <- %3$s)\n",
+			.name = "Invalid mapping",
+			.prompt = "[e]dit/[d]elete/[D]elete all"
+			"/[s]kip/[S]kip all",
+			.answers = "eds",
+			.default_action = 'd',
+			.verbose = true,
+		},
+		.invalid_edit = (check_action) {
+			.name = "Invalid record",
+			.prompt = "[e]dit/[d]elete/[D]elete all"
+			"/[s]kip/[S]kip all",
+			.answers = "eds",
+			.default_action = 'e',
+			.verbose = true,
+		},
+		.record_exists = (check_action) {
+			.fmt = "%1$s: %2$s\n-%4$s\n+%3$s\n",
+			.name = "Record exists",
+			.prompt = "[o]verwrite/[O]verwrite all/[e]dit"


-- 
Samba Shared Repository


More information about the samba-cvs mailing list