[PATCHSET] adding idmap-autorid functionality to net

Michael Adam obnox at samba.org
Tue Sep 24 07:57:43 CEST 2013


Hi,

attached find a bigger patchset that refactors db handling
code out of the autorid idmap backend (s3) and creates
a couple of new subcommands to "net idmap" to operate on
the idmap autorid database.

This work was started by Atul Kulkarni <atul.kulkarni at in.ibm.com>
and continued by me, partly pair-programming with him.

I was thinking about a proper CLI for net idmap.
First I considered a "net idmap autorid" command, but I have
abandoned this again and came up with this:

=========================
old cli:
=========================

net idmap dump
net idmap restore
net idmap check
net idmap setmap [id-mapping - not implemented]
net idmap delete [id-mapping]
net idmap secret

=========================
new cli:
=========================

net idmap dump  [tdb,tdb2,autorid]
net idmap restore
net idmap check
net idmap secret (==> now also "net idmap set secret")

net idmap get
[net idmap get mapping (not implemented yet)]
net idmap get range
net idmap get ranges
net idmap get config

net idmap set
net idmap set mapping (not implemented yet)
net idmap set range
net idmap set config
net idmap set secret (was "net idmap secret")

net idmap delete
net idmap delete mapping
net idmap delete range
net idmap delete ranges
[net idmap delete config (optional, not implemented yet)]

================

I think this is pretty natural to use.
The "range|ranges|config" subcommands are for the autorid
backend, the "mapping" subcommand is for tdb/tdb2.

The manpage update still needs to be finished.
But the code is complete and the patchset clean (imho).

The code can also be grabbed from my repository:

http://gitweb.samba.org/?p=obnox/samba/samba-obnox.git;a=shortlog;h=refs/heads/master-idmap-autorido

Please let me know what you think/review/comment...

Thanks - Michael

-------------- next part --------------
From f1fbe39509563354ec431d9b0510be5762f3b587 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 13:53:22 +0200
Subject: [PATCH 01/57] idmap_autorid: add a db_context argument to
 idmap_autorid_get_domainrange()

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 16f609d..2b81202 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -194,7 +194,8 @@ error:
 
 }
 
-static NTSTATUS idmap_autorid_get_domainrange(struct autorid_range_config *range,
+static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
+					      struct autorid_range_config *range,
 					      bool read_only)
 {
 	NTSTATUS ret;
@@ -211,14 +212,14 @@ static NTSTATUS idmap_autorid_get_domainrange(struct autorid_range_config *range
 		fstrcpy(range->keystr, range->domsid);
 	}
 
-	ret = dbwrap_fetch_uint32_bystring(autorid_db, range->keystr,
+	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
 					   &(range->rangenum));
 
 	if (!NT_STATUS_IS_OK(ret)) {
 		if (read_only) {
 			return NT_STATUS_NOT_FOUND;
 		}
-		ret = dbwrap_trans_do(autorid_db,
+		ret = dbwrap_trans_do(db,
 			      idmap_autorid_get_domainrange_action, range);
 	}
 
@@ -261,7 +262,7 @@ static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 	range.globalcfg = globalcfg;
 	fstrcpy(range.domsid, ALLOC_RANGE);
 
-	ret = idmap_autorid_get_domainrange(&range, dom->read_only);
+	ret = idmap_autorid_get_domainrange(autorid_db, &range, dom->read_only);
 
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(3, ("Could not determine range for allocation pool, "
@@ -644,7 +645,8 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 		/* Calculate domain_range_index for multi-range support */
 		range.domain_range_index = rid / (global->rangesize);
 
-		ret = idmap_autorid_get_domainrange(&range, dom->read_only);
+		ret = idmap_autorid_get_domainrange(autorid_db, &range,
+						    dom->read_only);
 
 		/* read-only mode and a new domain range would be required? */
 		if (NT_STATUS_EQUAL(ret, NT_STATUS_NOT_FOUND) &&
-- 
1.7.9.5


From 04ef168c8bee71a5216375b88e19cd1301ffe8b4 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 14:00:24 +0200
Subject: [PATCH 02/57] idmap_autorid: add a db_context argument to
 idmap_autorid_loadconfig()

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 2b81202..6b9a472 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -751,7 +751,8 @@ static NTSTATUS idmap_autorid_db_init(void)
 	return status;
 }
 
-static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx)
+static struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
+							      TALLOC_CTX *ctx)
 {
 
 	TDB_DATA data;
@@ -759,7 +760,7 @@ static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx)
 	unsigned long minvalue, rangesize, maxranges;
 	NTSTATUS status;
 
-	status = dbwrap_fetch_bystring(autorid_db, ctx, CONFIGKEY, &data);
+	status = dbwrap_fetch_bystring(db, ctx, CONFIGKEY, &data);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("No saved config found\n"));
@@ -937,7 +938,7 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 		   config->minvalue, config->rangesize, config->maxranges));
 
 	/* read previously stored config and current HWM */
-	storedconfig = idmap_autorid_loadconfig(talloc_tos());
+	storedconfig = idmap_autorid_loadconfig(autorid_db, talloc_tos());
 
 	status = dbwrap_fetch_uint32_bystring(autorid_db, HWM, &hwm);
 	if (!NT_STATUS_IS_OK(status)) {
-- 
1.7.9.5


From 893e1a16e5a41b3b493540e9b4e59690943b299a Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 14:03:33 +0200
Subject: [PATCH 03/57] idmap_autorid: add a db_context argument to
 idmap_autorid_saveconfig()

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 6b9a472..df2cba1 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -793,7 +793,8 @@ static struct autorid_global_config *idmap_autorid_loadconfig(struct db_context
 
 }
 
-static NTSTATUS idmap_autorid_saveconfig(struct autorid_global_config *cfg)
+static NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
+					 struct autorid_global_config *cfg)
 {
 
 	NTSTATUS status;
@@ -811,8 +812,7 @@ static NTSTATUS idmap_autorid_saveconfig(struct autorid_global_config *cfg)
 
 	data = string_tdb_data(cfgstr);
 
-	status = dbwrap_trans_store_bystring(autorid_db, CONFIGKEY,
-					     data, TDB_REPLACE);
+	status = dbwrap_trans_store_bystring(db, CONFIGKEY, data, TDB_REPLACE);
 
 	talloc_free(cfgstr);
 
@@ -970,7 +970,7 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 		goto error;
 	}
 
-	status = idmap_autorid_saveconfig(config);
+	status = idmap_autorid_saveconfig(autorid_db, config);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Failed to store configuration data!\n"));
-- 
1.7.9.5


From a051fc42395e8cbee54dbc35dc5d2830221298d1 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 30 Aug 2013 13:20:15 +0200
Subject: [PATCH 04/57] idmap_autorid: add a db_context argument to
 idmap_autorid_init_hwm()

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index df2cba1..62beb1d 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -692,14 +692,14 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 }
 
 /* initialize the given HWM to 0 if it does not exist yet */
-static NTSTATUS idmap_autorid_init_hwm(const char *hwm) {
-
+static NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
+{
 	NTSTATUS status;
 	uint32_t hwmval;
 
-	status = dbwrap_fetch_uint32_bystring(autorid_db, hwm, &hwmval);
+	status = dbwrap_fetch_uint32_bystring(db, hwm, &hwmval);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))  {
-		status = dbwrap_trans_store_int32_bystring(autorid_db, hwm, 0);
+		status = dbwrap_trans_store_int32_bystring(db, hwm, 0);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(0,
 			      ("Unable to initialise HWM (%s) in autorid "
@@ -740,13 +740,13 @@ static NTSTATUS idmap_autorid_db_init(void)
 
 	/* Initialize high water mark for the currently used range to 0 */
 
-	status = idmap_autorid_init_hwm(HWM);
+	status = idmap_autorid_init_hwm(autorid_db, HWM);
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	status = idmap_autorid_init_hwm(ALLOC_HWM_UID);
+	status = idmap_autorid_init_hwm(autorid_db, ALLOC_HWM_UID);
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	status = idmap_autorid_init_hwm(ALLOC_HWM_GID);
+	status = idmap_autorid_init_hwm(autorid_db, ALLOC_HWM_GID);
 
 	return status;
 }
-- 
1.7.9.5


From 1dfade8d2f017f542151463da8d1c6de65ef42f9 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Fri, 30 Aug 2013 13:29:01 +0200
Subject: [PATCH 05/57] idmap_autorid: add path, and db parameters to
 idmap_autorid_db_init()

I preparation of calling this from net for different dbs.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid.c |   26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 62beb1d..b3cd8f3 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -718,35 +718,35 @@ static NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
 /*
  * open and initialize the database which stores the ranges for the domains
  */
-static NTSTATUS idmap_autorid_db_init(void)
+static NTSTATUS idmap_autorid_db_init(const char *path,
+				      TALLOC_CTX *mem_ctx,
+				      struct db_context **db)
 {
 	NTSTATUS status;
 
-	if (autorid_db) {
+	if (*db != NULL) {
 		/* its already open */
 		return NT_STATUS_OK;
 	}
 
 	/* Open idmap repository */
-	autorid_db = db_open(NULL, state_path("autorid.tdb"), 0,
-			     TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
-			     DBWRAP_LOCK_ORDER_1);
+	*db = db_open(mem_ctx, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
+		      DBWRAP_LOCK_ORDER_1);
 
-	if (!autorid_db) {
-		DEBUG(0, ("Unable to open idmap_autorid database '%s'\n",
-			  state_path("autorid.tdb")));
+	if (*db == NULL) {
+		DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", path));
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
 	/* Initialize high water mark for the currently used range to 0 */
 
-	status = idmap_autorid_init_hwm(autorid_db, HWM);
+	status = idmap_autorid_init_hwm(*db, HWM);
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	status = idmap_autorid_init_hwm(autorid_db, ALLOC_HWM_UID);
+	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_UID);
 	NT_STATUS_NOT_OK_RETURN(status);
 
-	status = idmap_autorid_init_hwm(autorid_db, ALLOC_HWM_GID);
+	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_GID);
 
 	return status;
 }
@@ -899,7 +899,9 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = idmap_autorid_db_init();
+	status = idmap_autorid_db_init(state_path("autorid.tdb"),
+				       NULL, /* TALLOC_CTX */
+				       &autorid_db);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto error;
 	}
-- 
1.7.9.5


From 840507c20e0b7dc3eb0ca15881fa45f573d9c917 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 15:07:44 +0200
Subject: [PATCH 06/57] idmap_autorid: remove the ignore_builtin bool from the
 global_config struct

The ignore_builtin flag is used only to change the bahaviour of the
daemon code, not in the database.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index b3cd8f3..72bd384 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -97,7 +97,6 @@ struct autorid_global_config {
 	uint32_t minvalue;
 	uint32_t rangesize;
 	uint32_t maxranges;
-	bool ignore_builtin;
 };
 
 struct autorid_range_config {
@@ -112,6 +111,8 @@ struct autorid_range_config {
 /* handle to the tdb storing domain <-> range assignments */
 static struct db_context *autorid_db;
 
+static bool ignore_builtin = false;
+
 static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 					      void *private_data)
 {
@@ -622,7 +623,7 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 
 		/* BUILTIN is passdb's job */
 		if (dom_sid_equal(&domainsid, &global_sid_Builtin) &&
-		    global->ignore_builtin) {
+		    ignore_builtin) {
 			DEBUG(10, ("Ignoring request for BUILTIN domain\n"));
 			continue;
 		}
@@ -982,8 +983,8 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 	DEBUG(5, ("%d domain ranges with a size of %d are available\n",
 		  config->maxranges, config->rangesize));
 
-	config->ignore_builtin = lp_parm_bool(-1, "idmap config *",
-					      "ignore builtin", false);
+	ignore_builtin = lp_parm_bool(-1, "idmap config *",
+				      "ignore builtin", false);
 
 	/* fill the TDB common configuration */
 	commonconfig->private_data = config;
-- 
1.7.9.5


From d3f724a648f2352a8248f63d810ff64274b9e9f6 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Wed, 28 Aug 2013 13:19:27 +0530
Subject: [PATCH 07/57] idmap_autorid: extract common code to separate file

This is in preparation of adding "net idmap autorid" functionality.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |   72 +++++++++
 source3/winbindd/idmap_autorid.c     |  278 +---------------------------------
 source3/winbindd/idmap_autorid_tdb.c |  276 +++++++++++++++++++++++++++++++++
 source3/winbindd/wscript_build       |    6 +-
 4 files changed, 354 insertions(+), 278 deletions(-)
 create mode 100644 source3/include/idmap_autorid.h
 create mode 100644 source3/winbindd/idmap_autorid_tdb.c

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
new file mode 100644
index 0000000..1215128
--- /dev/null
+++ b/source3/include/idmap_autorid.h
@@ -0,0 +1,72 @@
+/*
+ *  idmap_autorid: static map between Active Directory/NT RIDs
+ *  and RFC 2307 accounts. This file contains common functions
+ *  and structures used by idmap_autorid and net idmap autorid utilities
+ *
+ *  Copyright (C) Christian Ambach, 2010-2012
+ *  Copyright (C) Atul Kulkarni, 2013
+ *  Copyright (C) Michael Adam, 2012-2013
+ *
+ *  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/>.
+ *
+ */
+
+#ifndef _IDMAP_AUTORID_H_
+#define _IDMAP_AUTORID_H_
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_open.h"
+#include "../lib/util/util_tdb.h"
+#include "winbindd/idmap_tdb_common.h"
+
+#define HWM "NEXT RANGE"
+#define ALLOC_HWM_UID "NEXT ALLOC UID"
+#define ALLOC_HWM_GID "NEXT ALLOC GID"
+#define ALLOC_RANGE "ALLOC"
+#define CONFIGKEY "CONFIG"
+
+struct autorid_global_config {
+	uint32_t minvalue;
+	uint32_t rangesize;
+	uint32_t maxranges;
+};
+
+struct autorid_range_config {
+	fstring domsid;
+	fstring keystr;
+	uint32_t rangenum;
+	uint32_t domain_range_index;
+	uint32_t low_id;
+	struct autorid_global_config *globalcfg;
+};
+
+NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
+				       struct autorid_range_config *range,
+				       bool read_only);
+
+NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm);
+
+NTSTATUS idmap_autorid_db_init(const char *path,
+			       TALLOC_CTX *mem_ctx,
+			       struct db_context **db);
+
+struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
+						       TALLOC_CTX *ctx);
+
+NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
+				  struct autorid_global_config *cfg);
+
+#endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 72bd384..f303b0c 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -73,168 +73,20 @@
  *   rid = reduced_rid + domain_range_index * range_size
  */
 
-#include "includes.h"
-#include "system/filesys.h"
+#include "idmap_autorid.h"
 #include "winbindd.h"
-#include "dbwrap/dbwrap.h"
-#include "dbwrap/dbwrap_open.h"
 #include "idmap.h"
 #include "idmap_rw.h"
 #include "../libcli/security/dom_sid.h"
-#include "util_tdb.h"
-#include "winbindd/idmap_tdb_common.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
 
-#define HWM "NEXT RANGE"
-#define ALLOC_HWM_UID "NEXT ALLOC UID"
-#define ALLOC_HWM_GID "NEXT ALLOC GID"
-#define ALLOC_RANGE "ALLOC"
-#define CONFIGKEY "CONFIG"
-
-struct autorid_global_config {
-	uint32_t minvalue;
-	uint32_t rangesize;
-	uint32_t maxranges;
-};
-
-struct autorid_range_config {
-	fstring domsid;
-	fstring keystr;
-	uint32_t rangenum;
-	uint32_t domain_range_index;
-	uint32_t low_id;
-	struct autorid_global_config *globalcfg;
-};
-
 /* handle to the tdb storing domain <-> range assignments */
 static struct db_context *autorid_db;
 
 static bool ignore_builtin = false;
 
-static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
-					      void *private_data)
-{
-	NTSTATUS ret;
-	uint32_t rangenum, hwm;
-	char *numstr;
-	struct autorid_range_config *range;
-
-	range = (struct autorid_range_config *)private_data;
-
-	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
-					   &(range->rangenum));
-
-	if (NT_STATUS_IS_OK(ret)) {
-		/* entry is already present*/
-		return ret;
-	}
-
-	DEBUG(10, ("Acquiring new range for domain %s "
-		   "(domain_range_index=%"PRIu32")\n",
-		   range->domsid, range->domain_range_index));
-
-	/* fetch the current HWM */
-	ret = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while fetching current "
-			  "HWM value: %s\n", nt_errstr(ret)));
-		ret = NT_STATUS_INTERNAL_ERROR;
-		goto error;
-	}
-
-	/* do we have a range left? */
-	if (hwm >= range->globalcfg->maxranges) {
-		DEBUG(1, ("No more domain ranges available!\n"));
-		ret = NT_STATUS_NO_MEMORY;
-		goto error;
-	}
-
-	/* increase the HWM */
-	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &rangenum, 1);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while fetching a new "
-			  "domain range value!\n"));
-		goto error;
-	}
-
-	/* store away the new mapping in both directions */
-	ret = dbwrap_store_uint32_bystring(db, range->keystr, rangenum);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while storing new "
-			  "domain->range assignment!\n"));
-		goto error;
-	}
-
-	numstr = talloc_asprintf(db, "%u", rangenum);
-	if (!numstr) {
-		ret = NT_STATUS_NO_MEMORY;
-		goto error;
-	}
-
-	ret = dbwrap_store_bystring(db, numstr,
-			string_term_tdb_data(range->keystr), TDB_INSERT);
-
-	talloc_free(numstr);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while storing "
-			  "new domain->range assignment!\n"));
-		goto error;
-	}
-	DEBUG(5, ("Acquired new range #%d for domain %s "
-		  "(domain_range_index=%"PRIu32")\n", rangenum, range->keystr,
-		  range->domain_range_index));
-
-	range->rangenum = rangenum;
-
-	return NT_STATUS_OK;
-
-error:
-	return ret;
-
-}
-
-static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
-					      struct autorid_range_config *range,
-					      bool read_only)
-{
-	NTSTATUS ret;
-
-	/*
-	 * try to find mapping without locking the database,
-	 * if it is not found create a mapping in a transaction unless
-	 * read-only mode has been set
-	 */
-	if (range->domain_range_index > 0) {
-		snprintf(range->keystr, FSTRING_LEN, "%s#%"PRIu32,
-			 range->domsid, range->domain_range_index);
-	} else {
-		fstrcpy(range->keystr, range->domsid);
-	}
-
-	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
-					   &(range->rangenum));
-
-	if (!NT_STATUS_IS_OK(ret)) {
-		if (read_only) {
-			return NT_STATUS_NOT_FOUND;
-		}
-		ret = dbwrap_trans_do(db,
-			      idmap_autorid_get_domainrange_action, range);
-	}
-
-	range->low_id = range->globalcfg->minvalue
-		      + range->rangenum * range->globalcfg->rangesize;
-
-	DEBUG(10, ("Using range #%d for domain %s "
-		   "(domain_range_index=%"PRIu32", low_id=%"PRIu32")\n",
-		   range->rangenum, range->domsid, range->domain_range_index,
-		   range->low_id));
-
-	return ret;
-}
-
 static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 					  struct unixid *xid) {
 
@@ -692,134 +544,6 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 
 }
 
-/* initialize the given HWM to 0 if it does not exist yet */
-static NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
-{
-	NTSTATUS status;
-	uint32_t hwmval;
-
-	status = dbwrap_fetch_uint32_bystring(db, hwm, &hwmval);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))  {
-		status = dbwrap_trans_store_int32_bystring(db, hwm, 0);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0,
-			      ("Unable to initialise HWM (%s) in autorid "
-			       "database: %s\n", hwm, nt_errstr(status)));
-			return NT_STATUS_INTERNAL_DB_ERROR;
-		}
-	} else if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("unable to fetch HWM (%s) from autorid "
-			  "database: %s\n", hwm,  nt_errstr(status)));
-		return status;
-	}
-
-	return NT_STATUS_OK;
-}
-
-/*
- * open and initialize the database which stores the ranges for the domains
- */
-static NTSTATUS idmap_autorid_db_init(const char *path,
-				      TALLOC_CTX *mem_ctx,
-				      struct db_context **db)
-{
-	NTSTATUS status;
-
-	if (*db != NULL) {
-		/* its already open */
-		return NT_STATUS_OK;
-	}
-
-	/* Open idmap repository */
-	*db = db_open(mem_ctx, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
-		      DBWRAP_LOCK_ORDER_1);
-
-	if (*db == NULL) {
-		DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", path));
-		return NT_STATUS_UNSUCCESSFUL;
-	}
-
-	/* Initialize high water mark for the currently used range to 0 */
-
-	status = idmap_autorid_init_hwm(*db, HWM);
-	NT_STATUS_NOT_OK_RETURN(status);
-
-	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_UID);
-	NT_STATUS_NOT_OK_RETURN(status);
-
-	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_GID);
-
-	return status;
-}
-
-static struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
-							      TALLOC_CTX *ctx)
-{
-
-	TDB_DATA data;
-	struct autorid_global_config *cfg;
-	unsigned long minvalue, rangesize, maxranges;
-	NTSTATUS status;
-
-	status = dbwrap_fetch_bystring(db, ctx, CONFIGKEY, &data);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("No saved config found\n"));
-		return NULL;
-	}
-
-	cfg = talloc_zero(ctx, struct autorid_global_config);
-	if (!cfg) {
-		return NULL;
-	}
-
-	if (sscanf((char *)data.dptr,
-		   "minvalue:%lu rangesize:%lu maxranges:%lu",
-		   &minvalue, &rangesize, &maxranges) != 3) {
-		DEBUG(1,
-		      ("Found invalid configuration data"
-		       "creating new config\n"));
-		return NULL;
-	}
-
-	cfg->minvalue = minvalue;
-	cfg->rangesize = rangesize;
-	cfg->maxranges = maxranges;
-
-	DEBUG(10, ("Loaded previously stored configuration "
-		   "minvalue:%d rangesize:%d\n",
-		   cfg->minvalue, cfg->rangesize));
-
-	return cfg;
-
-}
-
-static NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
-					 struct autorid_global_config *cfg)
-{
-
-	NTSTATUS status;
-	TDB_DATA data;
-	char *cfgstr;
-
-	cfgstr =
-	    talloc_asprintf(talloc_tos(),
-			    "minvalue:%u rangesize:%u maxranges:%u",
-			    cfg->minvalue, cfg->rangesize, cfg->maxranges);
-
-	if (!cfgstr) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	data = string_tdb_data(cfgstr);
-
-	status = dbwrap_trans_store_bystring(db, CONFIGKEY, data, TDB_REPLACE);
-
-	talloc_free(cfgstr);
-
-	return status;
-}
-
 static NTSTATUS idmap_autorid_preallocate_wellknown(struct idmap_domain *dom)
 {
 	const char *groups[] = { "S-1-1-0", "S-1-2-0", "S-1-2-1",
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
new file mode 100644
index 0000000..e835dc0
--- /dev/null
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -0,0 +1,276 @@
+/*
+ *  idmap_autorid_tdb: This file contains common code used by
+ *  idmap_autorid and net idmap autorid utilities. The common
+ *  code provides functions for performing various operations
+ *  on autorid.tdb
+ *
+ *  Copyright (C) Christian Ambach, 2010-2012
+ *  Copyright (C) Atul Kulkarni, 2013
+ *  Copyright (C) Michael Adam, 2012-2013
+ *
+ *  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 "idmap_autorid.h"
+
+static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
+					      void *private_data)
+{
+	NTSTATUS ret;
+	uint32_t rangenum, hwm;
+	char *numstr;
+	struct autorid_range_config *range;
+
+	range = (struct autorid_range_config *)private_data;
+
+	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
+					   &(range->rangenum));
+
+	if (NT_STATUS_IS_OK(ret)) {
+		/* entry is already present*/
+		return ret;
+	}
+
+	DEBUG(10, ("Acquiring new range for domain %s "
+		   "(domain_range_index=%"PRIu32")\n",
+		   range->domsid, range->domain_range_index));
+
+	/* fetch the current HWM */
+	ret = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(1, ("Fatal error while fetching current "
+			  "HWM value: %s\n", nt_errstr(ret)));
+		ret = NT_STATUS_INTERNAL_ERROR;
+		goto error;
+	}
+
+	/* do we have a range left? */
+	if (hwm >= range->globalcfg->maxranges) {
+		DEBUG(1, ("No more domain ranges available!\n"));
+		ret = NT_STATUS_NO_MEMORY;
+		goto error;
+	}
+
+	/* increase the HWM */
+	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &rangenum, 1);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(1, ("Fatal error while fetching a new "
+			  "domain range value!\n"));
+		goto error;
+	}
+
+	/* store away the new mapping in both directions */
+	ret = dbwrap_store_uint32_bystring(db, range->keystr, rangenum);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(1, ("Fatal error while storing new "
+			  "domain->range assignment!\n"));
+		goto error;
+	}
+
+	numstr = talloc_asprintf(db, "%u", rangenum);
+	if (!numstr) {
+		ret = NT_STATUS_NO_MEMORY;
+		goto error;
+	}
+
+	ret = dbwrap_store_bystring(db, numstr,
+			string_term_tdb_data(range->keystr), TDB_INSERT);
+
+	talloc_free(numstr);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(1, ("Fatal error while storing "
+			  "new domain->range assignment!\n"));
+		goto error;
+	}
+	DEBUG(5, ("Acquired new range #%d for domain %s "
+		  "(domain_range_index=%"PRIu32")\n", rangenum, range->keystr,
+		  range->domain_range_index));
+
+	range->rangenum = rangenum;
+
+	return NT_STATUS_OK;
+
+error:
+	return ret;
+
+}
+
+NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
+				       struct autorid_range_config *range,
+				       bool read_only)
+{
+	NTSTATUS ret;
+
+	/*
+	 * try to find mapping without locking the database,
+	 * if it is not found create a mapping in a transaction unless
+	 * read-only mode has been set
+	 */
+	if (range->domain_range_index > 0) {
+		snprintf(range->keystr, FSTRING_LEN, "%s#%"PRIu32,
+			 range->domsid, range->domain_range_index);
+	} else {
+		fstrcpy(range->keystr, range->domsid);
+	}
+
+	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
+					   &(range->rangenum));
+
+	if (!NT_STATUS_IS_OK(ret)) {
+		if (read_only) {
+			return NT_STATUS_NOT_FOUND;
+		}
+		ret = dbwrap_trans_do(db,
+			      idmap_autorid_get_domainrange_action, range);
+	}
+
+	range->low_id = range->globalcfg->minvalue
+		      + range->rangenum * range->globalcfg->rangesize;
+
+	DEBUG(10, ("Using range #%d for domain %s "
+		   "(domain_range_index=%"PRIu32", low_id=%"PRIu32")\n",
+		   range->rangenum, range->domsid, range->domain_range_index,
+		   range->low_id));
+
+	return ret;
+}
+
+/* initialize the given HWM to 0 if it does not exist yet */
+NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
+{
+	NTSTATUS status;
+	uint32_t hwmval;
+
+	status = dbwrap_fetch_uint32_bystring(db, hwm, &hwmval);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))  {
+		status = dbwrap_trans_store_int32_bystring(db, hwm, 0);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0,
+			      ("Unable to initialise HWM (%s) in autorid "
+			       "database: %s\n", hwm, nt_errstr(status)));
+			return NT_STATUS_INTERNAL_DB_ERROR;
+		}
+	} else if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("unable to fetch HWM (%s) from autorid "
+			  "database: %s\n", hwm,  nt_errstr(status)));
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/*
+ * open and initialize the database which stores the ranges for the domains
+ */
+NTSTATUS idmap_autorid_db_init(const char *path,
+			       TALLOC_CTX *mem_ctx,
+			       struct db_context **db)
+{
+	NTSTATUS status;
+
+	if (*db != NULL) {
+		/* its already open */
+		return NT_STATUS_OK;
+	}
+
+	/* Open idmap repository */
+	*db = db_open(mem_ctx, path, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644,
+		      DBWRAP_LOCK_ORDER_1);
+
+	if (*db == NULL) {
+		DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", path));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	/* Initialize high water mark for the currently used range to 0 */
+
+	status = idmap_autorid_init_hwm(*db, HWM);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_UID);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = idmap_autorid_init_hwm(*db, ALLOC_HWM_GID);
+
+	return status;
+}
+
+struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
+						       TALLOC_CTX *ctx)
+{
+
+	TDB_DATA data;
+	struct autorid_global_config *cfg;
+	unsigned long minvalue, rangesize, maxranges;
+	NTSTATUS status;
+
+	status = dbwrap_fetch_bystring(db, ctx, CONFIGKEY, &data);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("No saved config found\n"));
+		return NULL;
+	}
+
+	cfg = talloc_zero(ctx, struct autorid_global_config);
+	if (!cfg) {
+		return NULL;
+	}
+
+	if (sscanf((char *)data.dptr,
+		   "minvalue:%lu rangesize:%lu maxranges:%lu",
+		   &minvalue, &rangesize, &maxranges) != 3) {
+		DEBUG(1,
+		      ("Found invalid configuration data"
+		       "creating new config\n"));
+		return NULL;
+	}
+
+	cfg->minvalue = minvalue;
+	cfg->rangesize = rangesize;
+	cfg->maxranges = maxranges;
+
+	DEBUG(10, ("Loaded previously stored configuration "
+		   "minvalue:%d rangesize:%d\n",
+		   cfg->minvalue, cfg->rangesize));
+
+	return cfg;
+
+}
+
+NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
+				  struct autorid_global_config *cfg)
+{
+
+	NTSTATUS status;
+	TDB_DATA data;
+	char *cfgstr;
+
+	cfgstr =
+	    talloc_asprintf(talloc_tos(),
+			    "minvalue:%u rangesize:%u maxranges:%u",
+			    cfg->minvalue, cfg->rangesize, cfg->maxranges);
+
+	if (!cfgstr) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	data = string_tdb_data(cfgstr);
+
+	status = dbwrap_trans_store_bystring(db, CONFIGKEY, data, TDB_REPLACE);
+
+	talloc_free(cfgstr);
+
+	return status;
+}
diff --git a/source3/winbindd/wscript_build b/source3/winbindd/wscript_build
index b318bec..ea1131c 100644
--- a/source3/winbindd/wscript_build
+++ b/source3/winbindd/wscript_build
@@ -99,10 +99,14 @@ bld.SAMBA3_MODULE('idmap_hash',
                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_hash'),
                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_hash'))
 
+bld.SAMBA3_SUBSYSTEM('IDMAP_AUTORID_TDB',
+                     source='idmap_autorid_tdb.c',
+                     deps='tdb')
+
 bld.SAMBA3_MODULE('idmap_autorid',
                  subsystem='idmap',
                  source='idmap_autorid.c',
-                 deps='samba-util tdb IDMAP_TDB_COMMON',
+                 deps='samba-util tdb IDMAP_TDB_COMMON IDMAP_AUTORID_TDB',
                  init_function='',
                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_autorid'),
                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_autorid'),
-- 
1.7.9.5


From 8c271e62f363b241a13caf294bc9cb6b1c055d04 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 14:20:13 +0200
Subject: [PATCH 08/57] idmap_autorid_tdb: add idmap_autorid_getconfigstr()

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/include/idmap_autorid.h      |    6 ++++
 source3/winbindd/idmap_autorid_tdb.c |   65 ++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 1215128..21e4ddb 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -69,4 +69,10 @@ struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 				  struct autorid_global_config *cfg);
 
+/**
+ * get the range config string stored in the database
+ */
+NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
+				    char **result);
+
 #endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index e835dc0..3f5a2e0 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -207,6 +207,71 @@ NTSTATUS idmap_autorid_db_init(const char *path,
 	return status;
 }
 
+struct idmap_autorid_fetch_config_state {
+	TALLOC_CTX *mem_ctx;
+	char *configstr;
+	NTSTATUS status;
+};
+
+static void idmap_autorid_config_parser(TDB_DATA key, TDB_DATA value,
+					void *private_data)
+{
+	struct idmap_autorid_fetch_config_state *state;
+
+	state = (struct idmap_autorid_fetch_config_state *)private_data;
+
+	state->configstr = talloc_zero_array(state->mem_ctx, char, value.dsize+1);
+	if (state->configstr == NULL) {
+		state->status = NT_STATUS_NO_MEMORY;
+		return;
+	}
+
+	memcpy(state->configstr, value.dptr, value.dsize);
+	state->status = NT_STATUS_OK;
+}
+
+NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
+				    char **result)
+{
+	TDB_DATA key;
+	NTSTATUS status;
+	struct idmap_autorid_fetch_config_state state;
+
+	if (result == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	key = string_term_tdb_data(CONFIGKEY);
+
+	if (!dbwrap_exists(db, key)) {
+		DEBUG(1, ("Error: CONFIG entry does not exist\n"));
+		return NT_STATUS_NOT_FOUND;
+	}
+
+	state.mem_ctx = mem_ctx;
+	state.configstr = NULL;
+	state.status = NT_STATUS_OK;
+
+	status = dbwrap_parse_record(db, key, idmap_autorid_config_parser,
+				     &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Error while retrieving config: %s\n",
+			  nt_errstr(status)));
+		return status;
+	}
+
+	if (!NT_STATUS_IS_OK(state.status)) {
+		DEBUG(1, ("Error while retrieving config: %s\n",
+			  nt_errstr(state.status)));
+		return state.status;
+	}
+
+	DEBUG(5, ("found CONFIG: %s\n", state.configstr));
+
+	*result = state.configstr;
+	return status;
+}
+
 struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 						       TALLOC_CTX *ctx)
 {
-- 
1.7.9.5


From 26e8536a2fb0cd4b7502045f2f9b6de72c16cfbe Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 14:32:19 +0200
Subject: [PATCH 09/57] idmap_autorid: refactor idmap_autorid_loadconfig to
 use idmap_config_getconfigstr

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid_tdb.c |    9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 3f5a2e0..dbb0265 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -275,16 +275,13 @@ NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 						       TALLOC_CTX *ctx)
 {
-
-	TDB_DATA data;
 	struct autorid_global_config *cfg;
 	unsigned long minvalue, rangesize, maxranges;
 	NTSTATUS status;
+	char *configstr = NULL;
 
-	status = dbwrap_fetch_bystring(db, ctx, CONFIGKEY, &data);
-
+	status = idmap_autorid_getconfigstr(db, ctx, &configstr);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(10, ("No saved config found\n"));
 		return NULL;
 	}
 
@@ -293,7 +290,7 @@ struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 		return NULL;
 	}
 
-	if (sscanf((char *)data.dptr,
+	if (sscanf(configstr,
 		   "minvalue:%lu rangesize:%lu maxranges:%lu",
 		   &minvalue, &rangesize, &maxranges) != 3) {
 		DEBUG(1,
-- 
1.7.9.5


From ba4a5dded2198b7e3573b97bd40303c9903693f2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 13:43:15 +0200
Subject: [PATCH 10/57] idmap_autorid: rename TALLOC_CTX argument of
 idmap_autorid_loadconfig() to mem_ctx

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index dbb0265..d78bcd1 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -273,19 +273,19 @@ NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 }
 
 struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
-						       TALLOC_CTX *ctx)
+						       TALLOC_CTX *mem_ctx)
 {
 	struct autorid_global_config *cfg;
 	unsigned long minvalue, rangesize, maxranges;
 	NTSTATUS status;
 	char *configstr = NULL;
 
-	status = idmap_autorid_getconfigstr(db, ctx, &configstr);
+	status = idmap_autorid_getconfigstr(db, mem_ctx, &configstr);
 	if (!NT_STATUS_IS_OK(status)) {
 		return NULL;
 	}
 
-	cfg = talloc_zero(ctx, struct autorid_global_config);
+	cfg = talloc_zero(mem_ctx, struct autorid_global_config);
 	if (!cfg) {
 		return NULL;
 	}
-- 
1.7.9.5


From c5281ecd00a93d3b0a2f57e97c72c9be22ab2b10 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 28 Aug 2013 15:29:37 +0200
Subject: [PATCH 11/57] idmap_autorid: refactor
 idmap_autorid_parse_configstr() out of
 idmap_autorid_loadconfig()

This will be used for other purposes as well.

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/include/idmap_autorid.h      |    7 +++++++
 source3/winbindd/idmap_autorid_tdb.c |   36 +++++++++++++++++++++++-----------
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 21e4ddb..2702f4c 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -75,4 +75,11 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 				    char **result);
 
+/**
+ * parse the handed in config string and fill the provided config structure.
+ * return false if the string could not be parsed.
+ */
+bool idmap_autorid_parse_configstr(const char *configstr,
+				   struct autorid_global_config *cfg);
+
 #endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index d78bcd1..e579349 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -272,12 +272,33 @@ NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+bool idmap_autorid_parse_configstr(const char *configstr,
+				   struct autorid_global_config *cfg)
+{
+	unsigned long minvalue, rangesize, maxranges;
+
+	if (sscanf(configstr,
+		   "minvalue:%lu rangesize:%lu maxranges:%lu",
+		   &minvalue, &rangesize, &maxranges) != 3) {
+		DEBUG(1,
+		      ("Found invalid configuration data"
+		       "creating new config\n"));
+		return false;
+	}
+
+	cfg->minvalue = minvalue;
+	cfg->rangesize = rangesize;
+	cfg->maxranges = maxranges;
+
+	return true;
+}
+
 struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 						       TALLOC_CTX *mem_ctx)
 {
 	struct autorid_global_config *cfg;
-	unsigned long minvalue, rangesize, maxranges;
 	NTSTATUS status;
+	bool ok;
 	char *configstr = NULL;
 
 	status = idmap_autorid_getconfigstr(db, mem_ctx, &configstr);
@@ -290,19 +311,12 @@ struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
 		return NULL;
 	}
 
-	if (sscanf(configstr,
-		   "minvalue:%lu rangesize:%lu maxranges:%lu",
-		   &minvalue, &rangesize, &maxranges) != 3) {
-		DEBUG(1,
-		      ("Found invalid configuration data"
-		       "creating new config\n"));
+	ok = idmap_autorid_parse_configstr(configstr, cfg);
+	if (!ok) {
+		talloc_free(cfg);
 		return NULL;
 	}
 
-	cfg->minvalue = minvalue;
-	cfg->rangesize = rangesize;
-	cfg->maxranges = maxranges;
-
 	DEBUG(10, ("Loaded previously stored configuration "
 		   "minvalue:%d rangesize:%d\n",
 		   cfg->minvalue, cfg->rangesize));
-- 
1.7.9.5


From 48a7a96e259a399f1a2f0b46fa7763cb7df1b5a1 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 18:07:15 +0200
Subject: [PATCH 12/57] idmap_autorid: change idmap_autorid_loadconfig() to
 return NTSTATUS

for better error propagation.

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/include/idmap_autorid.h      |    5 +++--
 source3/winbindd/idmap_autorid.c     |    9 ++++++++-
 source3/winbindd/idmap_autorid_tdb.c |   20 +++++++++++++-------
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 2702f4c..e385f49 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -63,8 +63,9 @@ NTSTATUS idmap_autorid_db_init(const char *path,
 			       TALLOC_CTX *mem_ctx,
 			       struct db_context **db);
 
-struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
-						       TALLOC_CTX *ctx);
+NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
+				  TALLOC_CTX *ctx,
+				  struct autorid_global_config **result);
 
 NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 				  struct autorid_global_config *cfg);
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index f303b0c..928d8c8 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -665,7 +665,14 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 		   config->minvalue, config->rangesize, config->maxranges));
 
 	/* read previously stored config and current HWM */
-	storedconfig = idmap_autorid_loadconfig(autorid_db, talloc_tos());
+	status = idmap_autorid_loadconfig(autorid_db, talloc_tos(),
+					  &storedconfig);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+		DEBUG(5, ("No configuration found. Storing initial "
+			  "configuration.\n"));
+	} else if (!NT_STATUS_IS_OK(status)) {
+		goto error;
+	}
 
 	status = dbwrap_fetch_uint32_bystring(autorid_db, HWM, &hwm);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index e579349..1f2d33e 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -293,36 +293,42 @@ bool idmap_autorid_parse_configstr(const char *configstr,
 	return true;
 }
 
-struct autorid_global_config *idmap_autorid_loadconfig(struct db_context *db,
-						       TALLOC_CTX *mem_ctx)
+NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
+				  TALLOC_CTX *mem_ctx,
+				  struct autorid_global_config **result)
 {
 	struct autorid_global_config *cfg;
 	NTSTATUS status;
 	bool ok;
 	char *configstr = NULL;
 
+	if (result == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
 	status = idmap_autorid_getconfigstr(db, mem_ctx, &configstr);
 	if (!NT_STATUS_IS_OK(status)) {
-		return NULL;
+		return status;
 	}
 
 	cfg = talloc_zero(mem_ctx, struct autorid_global_config);
-	if (!cfg) {
-		return NULL;
+	if (cfg == NULL) {
+		return NT_STATUS_NO_MEMORY;
 	}
 
 	ok = idmap_autorid_parse_configstr(configstr, cfg);
 	if (!ok) {
 		talloc_free(cfg);
-		return NULL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	DEBUG(10, ("Loaded previously stored configuration "
 		   "minvalue:%d rangesize:%d\n",
 		   cfg->minvalue, cfg->rangesize));
 
-	return cfg;
+	*result = cfg;
 
+	return NT_STATUS_OK;
 }
 
 NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
-- 
1.7.9.5


From 7b8f3717a21bd1a7c273d8797bb921c1b005244e Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Wed, 28 Aug 2013 16:12:58 +0200
Subject: [PATCH 13/57] idmap_autorid: improve implementation of
 idmap_autorid_parse_configstr()

This new implementation is more generous. It can cope with multiple spaces.
It can also print more precise error messages, when the input string is not
valid.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |  105 +++++++++++++++++++++++++++++-----
 1 file changed, 92 insertions(+), 13 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 1f2d33e..62b6d32 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -275,22 +275,101 @@ NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 bool idmap_autorid_parse_configstr(const char *configstr,
 				   struct autorid_global_config *cfg)
 {
-	unsigned long minvalue, rangesize, maxranges;
-
-	if (sscanf(configstr,
-		   "minvalue:%lu rangesize:%lu maxranges:%lu",
-		   &minvalue, &rangesize, &maxranges) != 3) {
-		DEBUG(1,
-		      ("Found invalid configuration data"
-		       "creating new config\n"));
-		return false;
+	const char *confnames[] = { [0] = "minvalue",
+				    [1] = "rangesize",
+				    [2] = "maxranges" };
+	char *str1, *saveptr1;
+	const char *delim = " ";
+	const char *subdelim = ":";
+	int j;
+	bool ret = false;
+
+	if (cfg == NULL || configstr == NULL) {
+		goto done;
 	}
 
-	cfg->minvalue = minvalue;
-	cfg->rangesize = rangesize;
-	cfg->maxranges = maxranges;
+	if (strlen(configstr) < 34) {
+		DEBUG(0, ("less than expected length for config: '%s'\n",
+			   configstr));
+		goto done;
+	}
+
+	DEBUG(5, ("config for parsing: %s\n", configstr));
+
+	for (j = 0, str1 = discard_const_p(char, configstr); ; j++, str1 = NULL)
+	{
+		int k;
+		char *token, *str2, *saveptr2;
+
+		token = strtok_r(str1, delim, &saveptr1);
+		if (token == NULL) {
+			break;
+		}
+
+		if (strncmp(token, confnames[j], strlen(confnames[j]))) {
+			DEBUG(0, ("expected %s but received '%s'\n",
+				  confnames[j], token));
+			goto done;
+		}
 
-	return true;
+		for (k=0, str2 = token; ; k++, str2 = NULL) {
+			char *e = NULL;
+			char *pp, *vp;
+
+			pp = strtok_r(str2, subdelim, &saveptr2);
+			if (pp == NULL) {
+				break;
+			}
+
+			if (k > 0 ) {
+				DEBUG(0, ("more than expected tokens in %s\n",
+					  confnames[j]));
+				goto done;
+			}
+
+			vp = strtok_r(NULL, subdelim, &saveptr2);
+			if (vp == NULL) {
+				DEBUG(0, ("error while looking"
+					  " for a value of %s\n", pp));
+				goto done;
+			}
+
+			if (*vp == '-') {
+				DEBUG(0, ("value specified for '%s' "
+					  "can't be negative\n", confnames[j]));
+				goto done;
+			}
+
+			switch(j) {
+				case 0:
+					cfg->minvalue = strtoul(vp, &e, 10);
+					break;
+				case 1:
+					cfg->rangesize = strtoul(vp, &e, 10);
+					break;
+				case 2:
+					cfg->maxranges = strtoul(vp, &e, 10);
+					break;
+			}
+
+			if (errno == ERANGE || vp == e || (e && *e != '\0')) {
+				DEBUG(0, ("invalid value specified for '%s'\n",
+					  confnames[j]));
+				goto done;
+			}
+		}
+	}
+
+	if (cfg->rangesize == 0 || cfg->maxranges == 0) {
+		DEBUG(0, ("%s and %s both must be greater than 0\n",
+			  confnames[1], confnames[2]));
+		goto done;
+	}
+
+	ret = true;
+
+done:
+	return ret;
 }
 
 NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
-- 
1.7.9.5


From a2bf7ed6cc43cdf761aa78e62e02838fc3a0acfa Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Wed, 28 Aug 2013 17:00:56 +0200
Subject: [PATCH 14/57] idmap_autorid: add parameter checks to
 idmap_autorid_saveconfig()

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Reviewed-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 62b6d32..825e8fc 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -414,10 +414,14 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 				  struct autorid_global_config *cfg)
 {
 
-	NTSTATUS status;
+	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
 	TDB_DATA data;
 	char *cfgstr;
 
+	if (db == NULL || cfg == NULL) {
+		goto done;
+	}
+
 	cfgstr =
 	    talloc_asprintf(talloc_tos(),
 			    "minvalue:%u rangesize:%u maxranges:%u",
@@ -433,5 +437,6 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 
 	talloc_free(cfgstr);
 
+done:
 	return status;
 }
-- 
1.7.9.5


From 85d436fe5f49428be7081d73598029a4ba0c5f70 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Wed, 28 Aug 2013 17:19:30 +0200
Subject: [PATCH 15/57] idmap_autorid: move the checks from
 idmap_autorid_initialize to
 idmap_autorid_saveconfig()

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid.c     |   61 ----------------------------------
 source3/winbindd/idmap_autorid_tdb.c |   59 ++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 928d8c8..b258c0b 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -595,9 +595,7 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 {
 	struct idmap_tdb_common_context *commonconfig;
 	struct autorid_global_config *config;
-	struct autorid_global_config *storedconfig = NULL;
 	NTSTATUS status;
-	uint32_t hwm;
 
 	if (!strequal(dom->name, "*")) {
 		DEBUG(0, ("idmap_autorid_initialize: Error: autorid configured "
@@ -635,22 +633,9 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 	config->rangesize = lp_parm_int(-1, "idmap config *",
 					"rangesize", 100000);
 
-	if (config->rangesize < 2000) {
-		DEBUG(1, ("autorid rangesize must be at least 2000\n"));
-		status = NT_STATUS_INVALID_PARAMETER;
-		goto error;
-	}
-
 	config->maxranges = (dom->high_id - dom->low_id + 1) /
 	    config->rangesize;
 
-	if (config->maxranges == 0) {
-		DEBUG(1, ("allowed uid range is smaller then rangesize, "
-			  "increase uid range or decrease rangesize\n"));
-		status = NT_STATUS_INVALID_PARAMETER;
-		goto error;
-	}
-
 	/* check if the high-low limit is a multiple of the rangesize */
 	if ((dom->high_id - dom->low_id + 1) % config->rangesize != 0) {
 		DEBUG(5, ("High uid-low uid difference of %d "
@@ -660,50 +645,6 @@ static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom)
 			  config->maxranges));
 	}
 
-	DEBUG(10, ("Current configuration in config is "
-		   "minvalue:%d rangesize:%d maxranges:%d\n",
-		   config->minvalue, config->rangesize, config->maxranges));
-
-	/* read previously stored config and current HWM */
-	status = idmap_autorid_loadconfig(autorid_db, talloc_tos(),
-					  &storedconfig);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-		DEBUG(5, ("No configuration found. Storing initial "
-			  "configuration.\n"));
-	} else if (!NT_STATUS_IS_OK(status)) {
-		goto error;
-	}
-
-	status = dbwrap_fetch_uint32_bystring(autorid_db, HWM, &hwm);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("Fatal error while fetching current "
-			  "HWM value: %s\n", nt_errstr(status)));
-		status = NT_STATUS_INTERNAL_ERROR;
-		goto error;
-	}
-
-	/* did the minimum value or rangesize change? */
-	if (storedconfig &&
-	    ((storedconfig->minvalue != config->minvalue) ||
-	     (storedconfig->rangesize != config->rangesize))) {
-		DEBUG(1, ("New configuration values for rangesize or "
-			  "minimum uid value conflict with previously "
-			  "used values! Aborting initialization\n"));
-		status = NT_STATUS_INVALID_PARAMETER;
-		goto error;
-	}
-
-	/*
-	 * has the highest uid value been reduced to setting that is not
-	 * sufficient any more for already existing ranges?
-	 */
-	if (hwm > config->maxranges) {
-		DEBUG(1, ("New upper uid limit is too low to cover "
-			  "existing mappings! Aborting initialization\n"));
-		status = NT_STATUS_INVALID_PARAMETER;
-		goto error;
-	}
-
 	status = idmap_autorid_saveconfig(autorid_db, config);
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -738,8 +679,6 @@ error:
 	talloc_free(config);
 
 done:
-	talloc_free(storedconfig);
-
 	return status;
 }
 
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 825e8fc..1ae4248 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -414,14 +414,73 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 				  struct autorid_global_config *cfg)
 {
 
+	struct autorid_global_config *storedconfig = NULL;
 	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
 	TDB_DATA data;
 	char *cfgstr;
+	uint32_t hwm;
 
 	if (db == NULL || cfg == NULL) {
 		goto done;
 	}
 
+	DEBUG(10, ("New configuration provided for storing is "
+		   "minvalue:%d rangesize:%d maxranges:%d\n",
+		   cfg->minvalue, cfg->rangesize, cfg->maxranges));
+
+	if (cfg->rangesize < 2000) {
+		DEBUG(1, ("autorid rangesize must be at least 2000\n"));
+		goto done;
+	}
+
+	if (cfg->maxranges == 0) {
+		DEBUG(1, ("allowed uid range is smaller then rangesize, "
+			  "increase uid range or decrease rangesize\n"));
+		goto done;
+	}
+
+	status = idmap_autorid_loadconfig(db, talloc_tos(), &storedconfig);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+		DEBUG(5, ("No configuration found. Storing initial "
+			  "configuration.\n"));
+	} else if (!NT_STATUS_IS_OK(status)) {
+		goto done;
+	}
+
+	/* did the minimum value or rangesize change? */
+	if (storedconfig &&
+	    ((storedconfig->minvalue != cfg->minvalue) ||
+	     (storedconfig->rangesize != cfg->rangesize)))
+	{
+		DEBUG(1, ("New configuration values for rangesize or "
+			  "minimum uid value conflict with previously "
+			  "used values! Not storing new config.\n"));
+		talloc_free(storedconfig);
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto done;
+	}
+
+	talloc_free(storedconfig);
+
+	status = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Fatal error while fetching current "
+			  "HWM value: %s\n", nt_errstr(status)));
+		status = NT_STATUS_INTERNAL_ERROR;
+		goto done;
+	}
+
+	/*
+	 * has the highest uid value been reduced to setting that is not
+	 * sufficient any more for already existing ranges?
+	 */
+	if (hwm > cfg->maxranges) {
+		DEBUG(1, ("New upper uid limit is too low to cover "
+			  "existing mappings! Not storing new config."));
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto done;
+	}
+
 	cfgstr =
 	    talloc_asprintf(talloc_tos(),
 			    "minvalue:%u rangesize:%u maxranges:%u",
-- 
1.7.9.5


From ea37f8e3c6d4bd9a6ce523b16e9a0b53a161a4d2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 18:27:46 +0200
Subject: [PATCH 16/57] idmap_autorid: improve idmap_autorid_saveconfig() by
 adding a talloc stackframe

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid_tdb.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 1ae4248..763287a 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -419,6 +419,7 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 	TDB_DATA data;
 	char *cfgstr;
 	uint32_t hwm;
+	TALLOC_CTX *frame = talloc_stackframe();
 
 	if (db == NULL || cfg == NULL) {
 		goto done;
@@ -439,7 +440,7 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 		goto done;
 	}
 
-	status = idmap_autorid_loadconfig(db, talloc_tos(), &storedconfig);
+	status = idmap_autorid_loadconfig(db, frame, &storedconfig);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 		DEBUG(5, ("No configuration found. Storing initial "
 			  "configuration.\n"));
@@ -455,13 +456,10 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 		DEBUG(1, ("New configuration values for rangesize or "
 			  "minimum uid value conflict with previously "
 			  "used values! Not storing new config.\n"));
-		talloc_free(storedconfig);
 		status = NT_STATUS_INVALID_PARAMETER;
 		goto done;
 	}
 
-	talloc_free(storedconfig);
-
 	status = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Fatal error while fetching current "
@@ -482,20 +480,20 @@ NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 	}
 
 	cfgstr =
-	    talloc_asprintf(talloc_tos(),
+	    talloc_asprintf(frame,
 			    "minvalue:%u rangesize:%u maxranges:%u",
 			    cfg->minvalue, cfg->rangesize, cfg->maxranges);
 
-	if (!cfgstr) {
-		return NT_STATUS_NO_MEMORY;
+	if (cfgstr == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
 	}
 
 	data = string_tdb_data(cfgstr);
 
 	status = dbwrap_trans_store_bystring(db, CONFIGKEY, data, TDB_REPLACE);
 
-	talloc_free(cfgstr);
-
 done:
+	talloc_free(frame);
 	return status;
 }
-- 
1.7.9.5


From 00a13fc9333a19452b2eb6d5ab0422c6411a0409 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Fri, 30 Aug 2013 13:35:49 +0530
Subject: [PATCH 17/57] idmap_autorid: remove autorid_global_config member
 from autorid_range_config

global config is not part of range config.
By removing this, autorid_range_config becomes more suitable
for using it elsewhere.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |    1 -
 source3/winbindd/idmap_autorid.c     |   11 -----------
 source3/winbindd/idmap_autorid_tdb.c |   20 +++++++++++++++++---
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index e385f49..f4286f0 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -50,7 +50,6 @@ struct autorid_range_config {
 	uint32_t rangenum;
 	uint32_t domain_range_index;
 	uint32_t low_id;
-	struct autorid_global_config *globalcfg;
 };
 
 NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index b258c0b..787bf05 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -91,17 +91,8 @@ static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 					  struct unixid *xid) {
 
 	NTSTATUS ret;
-	struct idmap_tdb_common_context *commoncfg;
-	struct autorid_global_config *globalcfg;
 	struct autorid_range_config range;
 
-	commoncfg =
-	    talloc_get_type_abort(dom->private_data,
-				  struct idmap_tdb_common_context);
-
-	globalcfg = talloc_get_type(commoncfg->private_data,
-				    struct autorid_global_config);
-
 	if (dom->read_only) {
 		DEBUG(3, ("Backend is read-only, refusing "
 			  "new allocation request\n"));
@@ -112,7 +103,6 @@ static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 
 	ZERO_STRUCT(range);
 
-	range.globalcfg = globalcfg;
 	fstrcpy(range.domsid, ALLOC_RANGE);
 
 	ret = idmap_autorid_get_domainrange(autorid_db, &range, dom->read_only);
@@ -492,7 +482,6 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 		}
 		TALLOC_FREE(domain);
 
-		range.globalcfg = global;
 		sid_to_fstring(range.domsid, &domainsid);
 
 		/* Calculate domain_range_index for multi-range support */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 763287a..738f337 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -32,6 +32,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 	uint32_t rangenum, hwm;
 	char *numstr;
 	struct autorid_range_config *range;
+	struct autorid_global_config *globalcfg;
 
 	range = (struct autorid_range_config *)private_data;
 
@@ -56,12 +57,19 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 		goto error;
 	}
 
+	ret = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
+	if (!NT_STATUS_IS_OK(ret)) {
+		return ret;
+	}
+
 	/* do we have a range left? */
-	if (hwm >= range->globalcfg->maxranges) {
+	if (hwm >= globalcfg->maxranges) {
 		DEBUG(1, ("No more domain ranges available!\n"));
+		talloc_free(globalcfg);
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
 	}
+	TALLOC_FREE(globalcfg);
 
 	/* increase the HWM */
 	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &rangenum, 1);
@@ -112,6 +120,7 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 				       bool read_only)
 {
 	NTSTATUS ret;
+	struct autorid_global_config *globalcfg;
 
 	/*
 	 * try to find mapping without locking the database,
@@ -136,14 +145,19 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 			      idmap_autorid_get_domainrange_action, range);
 	}
 
-	range->low_id = range->globalcfg->minvalue
-		      + range->rangenum * range->globalcfg->rangesize;
+	ret = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
+	if (!NT_STATUS_IS_OK(ret)) {
+		return ret;
+	}
+	range->low_id = globalcfg->minvalue
+		      + range->rangenum * globalcfg->rangesize;
 
 	DEBUG(10, ("Using range #%d for domain %s "
 		   "(domain_range_index=%"PRIu32", low_id=%"PRIu32")\n",
 		   range->rangenum, range->domsid, range->domain_range_index,
 		   range->low_id));
 
+	talloc_free(globalcfg);
 	return ret;
 }
 
-- 
1.7.9.5


From 9674c38459c2ac37e0fe9aee75d7baa2338f2dc7 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Fri, 30 Aug 2013 13:49:10 +0530
Subject: [PATCH 18/57] idmap_autorid: remove fstring keystr from
 autorid_range_config

This is just used to change the behavior of the function.
Making it more suitable to be used at other places.
---
 source3/include/idmap_autorid.h      |    1 -
 source3/winbindd/idmap_autorid_tdb.c |   23 ++++++++++++++++-------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index f4286f0..f39062f 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -46,7 +46,6 @@ struct autorid_global_config {
 
 struct autorid_range_config {
 	fstring domsid;
-	fstring keystr;
 	uint32_t rangenum;
 	uint32_t domain_range_index;
 	uint32_t low_id;
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 738f337..7b95bbe 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -33,10 +33,18 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 	char *numstr;
 	struct autorid_range_config *range;
 	struct autorid_global_config *globalcfg;
+	fstring keystr;
 
 	range = (struct autorid_range_config *)private_data;
 
-	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
+	if (range->domain_range_index > 0) {
+		snprintf(keystr, FSTRING_LEN, "%s#%"PRIu32,
+			 range->domsid, range->domain_range_index);
+	} else {
+		fstrcpy(keystr, range->domsid);
+	}
+
+	ret = dbwrap_fetch_uint32_bystring(db, keystr,
 					   &(range->rangenum));
 
 	if (NT_STATUS_IS_OK(ret)) {
@@ -80,7 +88,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 	}
 
 	/* store away the new mapping in both directions */
-	ret = dbwrap_store_uint32_bystring(db, range->keystr, rangenum);
+	ret = dbwrap_store_uint32_bystring(db, keystr, rangenum);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while storing new "
 			  "domain->range assignment!\n"));
@@ -94,7 +102,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 	}
 
 	ret = dbwrap_store_bystring(db, numstr,
-			string_term_tdb_data(range->keystr), TDB_INSERT);
+			string_term_tdb_data(keystr), TDB_INSERT);
 
 	talloc_free(numstr);
 	if (!NT_STATUS_IS_OK(ret)) {
@@ -103,7 +111,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 		goto error;
 	}
 	DEBUG(5, ("Acquired new range #%d for domain %s "
-		  "(domain_range_index=%"PRIu32")\n", rangenum, range->keystr,
+		  "(domain_range_index=%"PRIu32")\n", rangenum, keystr,
 		  range->domain_range_index));
 
 	range->rangenum = rangenum;
@@ -121,6 +129,7 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 {
 	NTSTATUS ret;
 	struct autorid_global_config *globalcfg;
+	fstring keystr;
 
 	/*
 	 * try to find mapping without locking the database,
@@ -128,13 +137,13 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 	 * read-only mode has been set
 	 */
 	if (range->domain_range_index > 0) {
-		snprintf(range->keystr, FSTRING_LEN, "%s#%"PRIu32,
+		snprintf(keystr, FSTRING_LEN, "%s#%"PRIu32,
 			 range->domsid, range->domain_range_index);
 	} else {
-		fstrcpy(range->keystr, range->domsid);
+		fstrcpy(keystr, range->domsid);
 	}
 
-	ret = dbwrap_fetch_uint32_bystring(db, range->keystr,
+	ret = dbwrap_fetch_uint32_bystring(db, keystr,
 					   &(range->rangenum));
 
 	if (!NT_STATUS_IS_OK(ret)) {
-- 
1.7.9.5


From 90d81a408389ac1e3fd548cb095f97e478d372d8 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 30 Aug 2013 17:31:16 +0200
Subject: [PATCH 19/57] idmap_autorid: factor building of the keystr into a
 function

to avoid code duplication.

Pair-Programmed-with: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid_tdb.c |   32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 7b95bbe..1778410 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -25,6 +25,22 @@
 
 #include "idmap_autorid.h"
 
+/**
+ * Build the database keystring for getting a range
+ * belonging to a domain sid and a range index.
+ */
+static void idmap_autorid_build_keystr(const char *domsid,
+				       uint32_t domain_range_index,
+				       fstring keystr)
+{
+	if (domain_range_index > 0) {
+		snprintf(keystr, FSTRING_LEN, "%s#%"PRIu32,
+			 domsid, domain_range_index);
+	} else {
+		fstrcpy(keystr, domsid);
+	}
+}
+
 static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 					      void *private_data)
 {
@@ -37,12 +53,8 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 
 	range = (struct autorid_range_config *)private_data;
 
-	if (range->domain_range_index > 0) {
-		snprintf(keystr, FSTRING_LEN, "%s#%"PRIu32,
-			 range->domsid, range->domain_range_index);
-	} else {
-		fstrcpy(keystr, range->domsid);
-	}
+	idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
+				   keystr);
 
 	ret = dbwrap_fetch_uint32_bystring(db, keystr,
 					   &(range->rangenum));
@@ -136,12 +148,8 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 	 * if it is not found create a mapping in a transaction unless
 	 * read-only mode has been set
 	 */
-	if (range->domain_range_index > 0) {
-		snprintf(keystr, FSTRING_LEN, "%s#%"PRIu32,
-			 range->domsid, range->domain_range_index);
-	} else {
-		fstrcpy(keystr, range->domsid);
-	}
+	idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
+				   keystr);
 
 	ret = dbwrap_fetch_uint32_bystring(db, keystr,
 					   &(range->rangenum));
-- 
1.7.9.5


From 7d539af6d93bdfc421136c23bc3327c3b6e91a30 Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Fri, 30 Aug 2013 16:18:39 +0530
Subject: [PATCH 20/57] idamp_autorid: factor out domain range fetching part
 from idmap_autorid_get_domainrange()

Fatored out read-only function idmap_autorid_getrange() will be used elsewhere.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |   58 ++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 20 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 1778410..b7f58a5 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -128,6 +128,9 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 
 	range->rangenum = rangenum;
 
+	range->low_id = globalcfg->minvalue
+		      + range->rangenum * globalcfg->rangesize;
+
 	return NT_STATUS_OK;
 
 error:
@@ -135,25 +138,48 @@ error:
 
 }
 
-NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
-				       struct autorid_range_config *range,
-				       bool read_only)
+static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
+					   struct autorid_range_config *range)
 {
-	NTSTATUS ret;
-	struct autorid_global_config *globalcfg;
+	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
+	struct autorid_global_config *globalcfg = NULL;
 	fstring keystr;
 
-	/*
-	 * try to find mapping without locking the database,
-	 * if it is not found create a mapping in a transaction unless
-	 * read-only mode has been set
-	 */
+	if (db == NULL || range == NULL) {
+		DEBUG(3, ("Invalid arguments received\n"));
+		goto done;
+	}
+
 	idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
 				   keystr);
 
-	ret = dbwrap_fetch_uint32_bystring(db, keystr,
-					   &(range->rangenum));
+	DEBUG(10, ("reading domain range for key %s\n", keystr));
+	status = dbwrap_fetch_uint32_bystring(db, keystr, &(range->rangenum));
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Failed to read database for key %s\n", keystr));
+		goto done;
+	}
+
+	status = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Failed to read global configuration"));
+		goto done;
+	}
+	range->low_id = globalcfg->minvalue
+		      + range->rangenum * globalcfg->rangesize;
+
+	talloc_free(globalcfg);
+done:
+	return status;
+}
+
+NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
+				       struct autorid_range_config *range,
+				       bool read_only)
+{
+	NTSTATUS ret;
 
+	ret = idmap_autorid_getrange_int(db, range);
 	if (!NT_STATUS_IS_OK(ret)) {
 		if (read_only) {
 			return NT_STATUS_NOT_FOUND;
@@ -162,19 +188,11 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 			      idmap_autorid_get_domainrange_action, range);
 	}
 
-	ret = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
-	if (!NT_STATUS_IS_OK(ret)) {
-		return ret;
-	}
-	range->low_id = globalcfg->minvalue
-		      + range->rangenum * globalcfg->rangesize;
-
 	DEBUG(10, ("Using range #%d for domain %s "
 		   "(domain_range_index=%"PRIu32", low_id=%"PRIu32")\n",
 		   range->rangenum, range->domsid, range->domain_range_index,
 		   range->low_id));
 
-	talloc_free(globalcfg);
 	return ret;
 }
 
-- 
1.7.9.5


From 877a0d748b9cc028b0f37c2e1c1a455caee4d8b1 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Sun, 15 Sep 2013 13:07:21 +0200
Subject: [PATCH 21/57] idmap_autorid: improve a debug message in
 idmap_autorid_getrange_int()

Add output of status code.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index b7f58a5..af9d317 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -156,7 +156,8 @@ static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
 	DEBUG(10, ("reading domain range for key %s\n", keystr));
 	status = dbwrap_fetch_uint32_bystring(db, keystr, &(range->rangenum));
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("Failed to read database for key %s\n", keystr));
+		DEBUG(1, ("Failed to read database for key '%s': %s\n",
+			  keystr, nt_errstr(status)));
 		goto done;
 	}
 
-- 
1.7.9.5


From 194e01af6dddbdf5497ea5913872b9fd1ab5b25b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 11 Sep 2013 01:04:13 +0200
Subject: [PATCH 22/57] idmap_autorid: add idmap_autorid_getrange()

Wrapper to idmap_autorid_getrange_int().

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |   10 ++++++++++
 source3/winbindd/idmap_autorid_tdb.c |   31 +++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index f39062f..6ac56b3 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -55,6 +55,16 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 				       struct autorid_range_config *range,
 				       bool read_only);
 
+/**
+ * get the domain range and low_id for the domain
+ * identified by domsid and domain_range_index
+ */
+NTSTATUS idmap_autorid_getrange(struct db_context *db,
+				const char *domsid,
+				uint32_t domain_range_index,
+				uint32_t *rangenum,
+				uint32_t *low_id);
+
 NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm);
 
 NTSTATUS idmap_autorid_db_init(const char *path,
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index af9d317..433ea55 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -174,6 +174,37 @@ done:
 	return status;
 }
 
+NTSTATUS idmap_autorid_getrange(struct db_context *db,
+				const char *domsid,
+				uint32_t domain_range_index,
+				uint32_t *rangenum,
+				uint32_t *low_id)
+{
+	NTSTATUS status;
+	struct autorid_range_config range;
+
+	if (rangenum == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	ZERO_STRUCT(range);
+	fstrcpy(range.domsid, domsid);
+	range.domain_range_index = domain_range_index;
+
+	status = idmap_autorid_getrange_int(db, &range);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	*rangenum = range.rangenum;
+
+	if (low_id != NULL) {
+		*low_id = range.low_id;
+	}
+
+	return NT_STATUS_OK;
+}
+
 NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 				       struct autorid_range_config *range,
 				       bool read_only)
-- 
1.7.9.5


From 617fe8f72172a130c9f23f7c72585da16e73c95d Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 30 Aug 2013 18:49:28 +0530
Subject: [PATCH 23/57] idmap_autorid: factor out domain range adding code
 into a separate function

This also adds a new mode to the new idmap_autorid_addrange() function
that allows to set a provided range if the range is available, instead
of the original only mode of automatically allocating a new range
by incrementing the HWM counter.

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid_tdb.c |  140 ++++++++++++++++++++++++++++------
 1 file changed, 117 insertions(+), 23 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 433ea55..b65cf90 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -24,6 +24,7 @@
  */
 
 #include "idmap_autorid.h"
+#include "../libcli/security/dom_sid.h"
 
 /**
  * Build the database keystring for getting a range
@@ -41,32 +42,87 @@ static void idmap_autorid_build_keystr(const char *domsid,
 	}
 }
 
-static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
+static bool idmap_autorid_validate_sid(const char *sid)
+{
+	struct dom_sid ignore;
+	if (sid == NULL) {
+		return false;
+	}
+
+	if (strcmp(sid, ALLOC_RANGE) == 0) {
+		return true;
+	}
+
+	return dom_sid_parse(sid, &ignore);
+}
+
+struct idmap_autorid_addrange_ctx {
+	struct autorid_range_config *range;
+	bool acquire;
+};
+
+static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 					      void *private_data)
 {
+	struct idmap_autorid_addrange_ctx *ctx;
+	uint32_t requested_rangenum, stored_rangenum;
+	struct autorid_range_config *range;
+	bool acquire;
 	NTSTATUS ret;
-	uint32_t rangenum, hwm;
+	uint32_t hwm;
 	char *numstr;
-	struct autorid_range_config *range;
 	struct autorid_global_config *globalcfg;
 	fstring keystr;
+	uint32_t increment;
+
+	ctx = (struct idmap_autorid_addrange_ctx *)private_data;
+	range = ctx->range;
+	acquire = ctx->acquire;
+	requested_rangenum = range->rangenum;
+
+	if (db == NULL) {
+		DEBUG(3, ("Invalid database argument: NULL"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (range == NULL) {
+		DEBUG(3, ("Invalid range argument: NULL"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
 
-	range = (struct autorid_range_config *)private_data;
+	DEBUG(10, ("Adding new range for domain %s "
+		   "(domain_range_index=%"PRIu32")\n",
+		   range->domsid, range->domain_range_index));
+
+	if (!idmap_autorid_validate_sid(range->domsid)) {
+		DEBUG(3, ("Invalid SID: %s\n", range->domsid));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
 
 	idmap_autorid_build_keystr(range->domsid, range->domain_range_index,
 				   keystr);
 
-	ret = dbwrap_fetch_uint32_bystring(db, keystr,
-					   &(range->rangenum));
+	ret = dbwrap_fetch_uint32_bystring(db, keystr, &stored_rangenum);
 
 	if (NT_STATUS_IS_OK(ret)) {
 		/* entry is already present*/
-		return ret;
-	}
+		if (acquire) {
+			DEBUG(10, ("domain range already allocated - "
+				   "Not adding!\n"));
+			return NT_STATUS_OK;
+		}
 
-	DEBUG(10, ("Acquiring new range for domain %s "
-		   "(domain_range_index=%"PRIu32")\n",
-		   range->domsid, range->domain_range_index));
+		if (stored_rangenum != requested_rangenum) {
+			DEBUG(1, ("Error: requested rangenumber (%u) differs "
+				  "from stored one (%u).\n",
+				  requested_rangenum, stored_rangenum));
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+
+		DEBUG(10, ("Note: stored range agrees with requested "
+			   "one - ok\n"));
+		return NT_STATUS_OK;
+	}
 
 	/* fetch the current HWM */
 	ret = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
@@ -79,20 +135,45 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 
 	ret = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
 	if (!NT_STATUS_IS_OK(ret)) {
-		return ret;
+		DEBUG(1, ("Fatal error while fetching configuration: %s\n",
+			  nt_errstr(ret)));
+		goto error;
 	}
 
-	/* do we have a range left? */
-	if (hwm >= globalcfg->maxranges) {
-		DEBUG(1, ("No more domain ranges available!\n"));
-		talloc_free(globalcfg);
+	if (acquire) {
+		/*
+		 * automatically acquire the next range
+		 */
+		requested_rangenum = hwm;
+	} else {
+		/*
+		 * set a specified range
+		 */
+
+		if (requested_rangenum < hwm) {
+			DEBUG(3, ("Invalid range %u requested: Range may not "
+				  "be smaller than %u (current HWM)\n",
+				  requested_rangenum, hwm));
+			ret = NT_STATUS_INVALID_PARAMETER;
+			goto error;
+		}
+	}
+
+	if (requested_rangenum >= globalcfg->maxranges) {
+		DEBUG(1, ("Not enough ranges available: New range %u must be "
+			  "smaller than configured maximum number of ranges "
+			  "(%u).\n",
+			  requested_rangenum, globalcfg->maxranges));
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
 	}
 	TALLOC_FREE(globalcfg);
 
+	/* HWM always contains current max range + 1 */
+	increment = requested_rangenum + 1 - hwm;
+
 	/* increase the HWM */
-	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &rangenum, 1);
+	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &hwm, increment);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while fetching a new "
 			  "domain range value!\n"));
@@ -100,14 +181,14 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 	}
 
 	/* store away the new mapping in both directions */
-	ret = dbwrap_store_uint32_bystring(db, keystr, rangenum);
+	ret = dbwrap_store_uint32_bystring(db, keystr, requested_rangenum);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while storing new "
 			  "domain->range assignment!\n"));
 		goto error;
 	}
 
-	numstr = talloc_asprintf(db, "%u", rangenum);
+	numstr = talloc_asprintf(db, "%u", requested_rangenum);
 	if (!numstr) {
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
@@ -123,10 +204,10 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 		goto error;
 	}
 	DEBUG(5, ("Acquired new range #%d for domain %s "
-		  "(domain_range_index=%"PRIu32")\n", rangenum, keystr,
+		  "(domain_range_index=%"PRIu32")\n", requested_rangenum, keystr,
 		  range->domain_range_index));
 
-	range->rangenum = rangenum;
+	range->rangenum = requested_rangenum;
 
 	range->low_id = globalcfg->minvalue
 		      + range->rangenum * globalcfg->rangesize;
@@ -135,7 +216,20 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
 
 error:
 	return ret;
+}
 
+static NTSTATUS idmap_autorid_addrange(struct db_context *db,
+				       struct autorid_range_config *range,
+				       bool acquire)
+{
+	NTSTATUS status;
+	struct idmap_autorid_addrange_ctx ctx;
+
+	ctx.acquire = acquire;
+	ctx.range = range;
+
+	status = dbwrap_trans_do(db, idmap_autorid_addrange_action, &ctx);
+	return status;
 }
 
 static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
@@ -216,8 +310,8 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 		if (read_only) {
 			return NT_STATUS_NOT_FOUND;
 		}
-		ret = dbwrap_trans_do(db,
-			      idmap_autorid_get_domainrange_action, range);
+
+		ret = idmap_autorid_addrange(db, range, true);
 	}
 
 	DEBUG(10, ("Using range #%d for domain %s "
-- 
1.7.9.5


From 1186a99847adeee81e374fce81a4cbf811b70af4 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 4 Sep 2013 17:43:28 +0200
Subject: [PATCH 24/57] idmap_autorid: add new function
 idmap_autorid_setrange()

This allows to directly set a range for a domsid#index pair.
It fails if a stored range is found which is different from
the requested one.

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/include/idmap_autorid.h      |    9 +++++++++
 source3/winbindd/idmap_autorid_tdb.c |   17 +++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 6ac56b3..6f74196 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -65,6 +65,15 @@ NTSTATUS idmap_autorid_getrange(struct db_context *db,
 				uint32_t *rangenum,
 				uint32_t *low_id);
 
+/**
+ * Set a range for a domain#index pair to a given
+ * number. Fail if a different range was already stored.
+ */
+NTSTATUS idmap_autorid_setrange(struct db_context *db,
+				const char *domsid,
+				uint32_t domain_range_index,
+				uint32_t rangenum);
+
 NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm);
 
 NTSTATUS idmap_autorid_db_init(const char *path,
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index b65cf90..ec5d932 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -232,6 +232,23 @@ static NTSTATUS idmap_autorid_addrange(struct db_context *db,
 	return status;
 }
 
+NTSTATUS idmap_autorid_setrange(struct db_context *db,
+				const char *domsid,
+				uint32_t domain_range_index,
+				uint32_t rangenum)
+{
+	NTSTATUS status;
+	struct autorid_range_config range;
+
+	ZERO_STRUCT(range);
+	fstrcpy(range.domsid, domsid);
+	range.domain_range_index = domain_range_index;
+	range.rangenum = rangenum;
+
+	status = idmap_autorid_addrange(db, &range, false);
+	return status;
+}
+
 static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
 					   struct autorid_range_config *range)
 {
-- 
1.7.9.5


From 259a163e8476bf78ee77b910983033078746e6a2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 4 Sep 2013 17:49:36 +0200
Subject: [PATCH 25/57] idmap_autorid: for clarity, add a wrapper
 idmap_autorid_acquire_range() to
 idmap_autorid_addrange()

This one calls into the HWM bumping acquire code path.

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/winbindd/idmap_autorid_tdb.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index ec5d932..849cc07 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -249,6 +249,12 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
 	return status;
 }
 
+static NTSTATUS idmap_autorid_acquire_range(struct db_context *db,
+					    struct autorid_range_config *range)
+{
+	return idmap_autorid_addrange(db, range, true);
+}
+
 static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
 					   struct autorid_range_config *range)
 {
@@ -328,7 +334,7 @@ NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 			return NT_STATUS_NOT_FOUND;
 		}
 
-		ret = idmap_autorid_addrange(db, range, true);
+		ret = idmap_autorid_acquire_range(db, range);
 	}
 
 	DEBUG(10, ("Using range #%d for domain %s "
-- 
1.7.9.5


From b47d78cba8d5193aa8b49e2e1cdaf4676fc1432b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 4 Sep 2013 13:11:28 +0200
Subject: [PATCH 26/57] idmap_autorid: fix a debug message in
 idmap_autorid_addrange()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 849cc07..2c21f4c 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -175,8 +175,8 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	/* increase the HWM */
 	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &hwm, increment);
 	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while fetching a new "
-			  "domain range value!\n"));
+		DEBUG(1, ("Fatal error while incrementing the HWM value "
+			  "in the database: %s\n", nt_errstr(ret)));
 		goto error;
 	}
 
-- 
1.7.9.5


From b5895410c9acac5355b681bcbd637b8775199c77 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 4 Sep 2013 13:13:15 +0200
Subject: [PATCH 27/57] idmap_autorid: improve two debug messages by printing
 NT error codes

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 2c21f4c..4aed766 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -184,7 +184,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	ret = dbwrap_store_uint32_bystring(db, keystr, requested_rangenum);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while storing new "
-			  "domain->range assignment!\n"));
+			  "domain->range assignment: %s\n", nt_errstr(ret)));
 		goto error;
 	}
 
@@ -199,8 +199,8 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 
 	talloc_free(numstr);
 	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while storing "
-			  "new domain->range assignment!\n"));
+		DEBUG(1, ("Fatal error while storing new "
+			  "domain->range assignment: %s\n", nt_errstr(ret)));
 		goto error;
 	}
 	DEBUG(5, ("Acquired new range #%d for domain %s "
-- 
1.7.9.5


From 3b5088107b9682cd685047d24f8a46b92cb21646 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 4 Sep 2013 13:29:56 +0200
Subject: [PATCH 28/57] idmap_autorid: Don't use db as a temporary talloc
 context.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 4aed766..cea973c 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -188,7 +188,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		goto error;
 	}
 
-	numstr = talloc_asprintf(db, "%u", requested_rangenum);
+	numstr = talloc_asprintf(talloc_tos(), "%u", requested_rangenum);
 	if (!numstr) {
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
-- 
1.7.9.5


From 903483930726e4f936230046a389a3a505686093 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 5 Sep 2013 14:43:26 +0200
Subject: [PATCH 29/57] idmap_autorid: add a comment explaining
 idmap_autorid_get_domainrange()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 6f74196..5bcb517 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -51,6 +51,13 @@ struct autorid_range_config {
 	uint32_t low_id;
 };
 
+/**
+ * Get the range for a pair consisting of the domain sid
+ * and a domain range. If there is no stored range for
+ * this pair and read_only == false, a new range is
+ * acquired by incrementing that range HWM counter in the
+ * database.
+ */
 NTSTATUS idmap_autorid_get_domainrange(struct db_context *db,
 				       struct autorid_range_config *range,
 				       bool read_only);
-- 
1.7.9.5


From aab740374674a609cfd7e9b1c9d2f8cc31b4a80b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 5 Sep 2013 14:45:29 +0200
Subject: [PATCH 30/57] idmap_autorid: add a comment explaining
 idmap_autorid_init_hwm()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 5bcb517..bf96d76 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -81,6 +81,10 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
 				uint32_t domain_range_index,
 				uint32_t rangenum);
 
+/**
+ * Initialize a specified HWM value to 0 if it is not
+ * yet present in the database.
+ */
 NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm);
 
 NTSTATUS idmap_autorid_db_init(const char *path,
-- 
1.7.9.5


From 1ad08da61f9378f348f5b9d17d887d96f43d7303 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 5 Sep 2013 14:47:43 +0200
Subject: [PATCH 31/57] idmap_autorid: add a comment explaining
 idmap_autorid_db_init()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index bf96d76..1609657 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -87,6 +87,12 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
  */
 NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm);
 
+/**
+ * Initialize an idmap_autorid database.
+ * After this function has successfully completed, the following are true:
+ * - the database exists
+ * - the requred HWM keys exist (range, alloc-uid, alloc-gid)
+ */
 NTSTATUS idmap_autorid_db_init(const char *path,
 			       TALLOC_CTX *mem_ctx,
 			       struct db_context **db);
-- 
1.7.9.5


From 424959f97bdd27f58a3b47edcb57dab10a6014bc Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 5 Sep 2013 14:48:28 +0200
Subject: [PATCH 32/57] idmap_autorid: add a comment explaining
 idmap_autorid_loadconfig()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 1609657..9c319c0 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -97,6 +97,9 @@ NTSTATUS idmap_autorid_db_init(const char *path,
 			       TALLOC_CTX *mem_ctx,
 			       struct db_context **db);
 
+/**
+ * Load the configuration stored in the autorid database.
+ */
 NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
 				  TALLOC_CTX *ctx,
 				  struct autorid_global_config **result);
-- 
1.7.9.5


From 8943924497bcc4e4e17e3bed61d05cb4c80be014 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 5 Sep 2013 14:53:11 +0200
Subject: [PATCH 33/57] idmap_autorid: add a comment explaining
 idmap_autorid_saveconfig()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 9c319c0..d0e1cef 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -104,6 +104,13 @@ NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
 				  TALLOC_CTX *ctx,
 				  struct autorid_global_config **result);
 
+/**
+ * Save the global autorid configuration into the autorid database.
+ * The stored configuration consists of:
+ * - the low value of the idmap range
+ * - the rangesize
+ * - the maximum number of ranges
+ */
 NTSTATUS idmap_autorid_saveconfig(struct db_context *db,
 				  struct autorid_global_config *cfg);
 
-- 
1.7.9.5


From 5c35865f8da6096cc4e8c3ccff1d72344d43844d Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 9 Sep 2013 16:58:05 +0200
Subject: [PATCH 34/57] net: improve help text for "net idmap dump"

With idmap autorid "dump ID mappings" is not precise enough any more.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index fbeca3e..0953583 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -720,7 +720,7 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			"dump",
 			net_idmap_dump,
 			NET_TRANSPORT_LOCAL,
-			N_("Dump the current ID mappings"),
+			N_("Dump the current ID mapping database"),
 			N_("net idmap dump\n"
 			   "  Dump the current ID mappings")
 		},
-- 
1.7.9.5


From c0d0bf53ee97f58a088ea1a53c9588c042574ca8 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 9 Sep 2013 16:58:42 +0200
Subject: [PATCH 35/57] net: improve help text for "net idmap restore"

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 0953583..22fc13c 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -728,7 +728,7 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			"restore",
 			net_idmap_restore,
 			NET_TRANSPORT_LOCAL,
-			N_("Restore entries from stdin"),
+			N_("Restore entries from a file or stdin"),
 			N_("net idmap restore\n"
 			   "  Restore entries from stdin")
 		},
-- 
1.7.9.5


From 350b34adf3b61636e4b11ae74905caf90d5be26c Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 6 Sep 2013 17:48:40 +0200
Subject: [PATCH 36/57] net: rename "net idmap setmap" to "net idmap set"

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 22fc13c..6f2efec 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -575,6 +575,7 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 	d_printf("%s\n", _("Not implemented yet"));
 	return -1;
 }
+
 static bool idmap_store_secret(const char *backend,
 			       const char *domain,
 			       const char *identity,
@@ -733,11 +734,11 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			   "  Restore entries from stdin")
 		},
 		{
-			"setmap",
+			"set",
 			net_idmap_set,
 			NET_TRANSPORT_LOCAL,
 			N_("Not implemented yet"),
-			N_("net idmap setmap\n"
+			N_("net idmap set\n"
 			   "  Not implemented yet")
 		},
 		{
-- 
1.7.9.5


From da607a3bccf6d0e9496a4dc04b1edfe13f22d7a2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 6 Sep 2013 18:01:20 +0200
Subject: [PATCH 37/57] net: move the "net idmap set" functionality to
 subcommand "net idmap set mapping"

This is in preparation of adding more "net idmap set" subcommands for the autorid backend.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 6f2efec..93a68d2 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -570,7 +570,8 @@ done:
 	return ret;
 }
 
-static int net_idmap_set(struct net_context *c, int argc, const char **argv)
+static int net_idmap_set_mapping(struct net_context *c,
+				 int argc, const char **argv)
 {
 	d_printf("%s\n", _("Not implemented yet"));
 	return -1;
@@ -665,6 +666,23 @@ static int net_idmap_secret(struct net_context *c, int argc, const char **argv)
 	return 0;
 }
 
+static int net_idmap_set(struct net_context *c, int argc, const char **argv)
+{
+	struct functable func[] = {
+		{
+			"mapping",
+			net_idmap_set_mapping,
+			NET_TRANSPORT_LOCAL,
+			N_("Not implemented yet"),
+			N_("net idmap set mapping\n"
+			   "  Not implemented yet")
+		},
+		{NULL, NULL, 0, NULL, NULL}
+	};
+
+	return net_run_function(c, argc, argv, "net idmap set", func);
+}
+
 static int net_idmap_check(struct net_context *c, int argc, const char **argv)
 {
 	const char* dbfile;
@@ -737,9 +755,9 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			"set",
 			net_idmap_set,
 			NET_TRANSPORT_LOCAL,
-			N_("Not implemented yet"),
+			N_("Write data to the ID mapping database"),
 			N_("net idmap set\n"
-			   "  Not implemented yet")
+			   "  Write data to the ID mapping database")
 		},
 		{
 			"delete",
-- 
1.7.9.5


From 590d9acd4a0bd2a328fee6868a98c31e9ff8e47e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 9 Sep 2013 17:13:47 +0200
Subject: [PATCH 38/57] net: add the "net idmap set secret" subcommand as
 alias for "net idmap secret"

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 93a68d2..db7587a 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -615,7 +615,7 @@ static int net_idmap_secret(struct net_context *c, int argc, const char **argv)
 	if (argc != 2 || c->display_usage) {
 		d_printf("%s\n%s",
 			 _("Usage:\n"),
-			 _("net idmap secret <DOMAIN> <secret>\n"
+			 _("net idmap set secret <DOMAIN> <secret>\n"
 			   "  Set the secret for the specified domain\n"
 			   "    DOMAIN\tDomain to set secret for.\n"
 			   "    secret\tNew secret to set.\n"));
@@ -677,6 +677,14 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 			N_("net idmap set mapping\n"
 			   "  Not implemented yet")
 		},
+		{
+			"secret",
+			net_idmap_secret,
+			NET_TRANSPORT_LOCAL,
+			N_("Set secret for specified domain"),
+			N_("net idmap set secret <DOMAIN> <secret>\n"
+			   "  Set secret for specified domain")
+		},
 		{NULL, NULL, 0, NULL, NULL}
 	};
 
-- 
1.7.9.5


From 68673fbf1c4315a0104717442271365450e9fa9d Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 9 Sep 2013 17:30:32 +0200
Subject: [PATCH 39/57] net: move the "net idmap delete" functionality to
 subcommand "net idmap delete mapping"

This is in preparation of adding more types of entries to delete...

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index db7587a..306b130 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -516,7 +516,8 @@ static bool delete_args_ok(int argc, const char **argv)
 	return false;
 }
 
-static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
+static int net_idmap_delete_mapping(struct net_context *c, int argc,
+				    const char **argv)
 {
 	int ret = -1;
 	struct db_context *db;
@@ -529,7 +530,7 @@ static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
 	if ( !delete_args_ok(argc,argv) || c->display_usage) {
 		d_printf("%s\n%s",
 			 _("Usage:"),
-			 _("net idmap delete [-f] [--db=<TDB>] <ID>\n"
+			 _("net idmap delete mapping [-f] [--db=<TDB>] <ID>\n"
 			   "  Delete mapping of ID from TDB.\n"
 			   "    -f\tforce\n"
 			   "    TDB\tidmap database\n"
@@ -570,6 +571,24 @@ done:
 	return ret;
 }
 
+static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
+{
+	struct functable func[] = {
+		{
+			"mapping",
+			net_idmap_delete_mapping,
+			NET_TRANSPORT_LOCAL,
+			N_("Delete ID mapping"),
+			N_("net idmap delete mapping <ID>\n"
+			   "  Delete ID mapping")
+		},
+		{NULL, NULL, 0, NULL, NULL}
+	};
+
+	return net_run_function(c, argc, argv, "net idmap delete", func);
+}
+
+
 static int net_idmap_set_mapping(struct net_context *c,
 				 int argc, const char **argv)
 {
@@ -771,9 +790,9 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			"delete",
 			net_idmap_delete,
 			NET_TRANSPORT_LOCAL,
-			N_("Delete ID mapping"),
-			N_("net idmap delete <ID>\n"
-			   "  Delete ID mapping")
+			N_("Delete entries from the ID mapping database"),
+			N_("net idmap delete\n"
+			   "  Delete entries from the ID mapping database")
 		},
 		{
 			"secret",
-- 
1.7.9.5


From 734db805866b11b66c32a47c14cc3e215ecc176d Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 01:19:05 +0200
Subject: [PATCH 40/57] net: rename "idmap_dump_ctx" to "net_idmap_ctx".

This started specific, but is now generic.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 306b130..b12039bd 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -40,7 +40,7 @@ enum idmap_dump_backend {
 	AUTORID
 };
 
-struct idmap_dump_ctx {
+struct net_idmap_ctx {
 	enum idmap_dump_backend backend;
 };
 
@@ -129,7 +129,7 @@ static int net_idmap_dump_one_tdb_entry(struct db_record *rec,
 }
 
 static const char* net_idmap_dbfile(struct net_context *c,
-				    struct idmap_dump_ctx *ctx)
+				    struct net_idmap_ctx *ctx)
 {
 	const char* dbfile = NULL;
 	const char *backend = NULL;
@@ -190,7 +190,7 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv)
 	const char* dbfile;
 	NTSTATUS status;
 	int ret = -1;
-	struct idmap_dump_ctx ctx = { .backend = TDB };
+	struct net_idmap_ctx ctx = { .backend = TDB };
 
 	if ( argc > 1  || c->display_usage) {
 		d_printf("%s\n%s",
@@ -292,7 +292,7 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
 	struct db_context *db;
 	const char *dbfile = NULL;
 	int ret = 0;
-	struct idmap_dump_ctx ctx = { .backend = TDB };
+	struct net_idmap_ctx ctx = { .backend = TDB };
 
 	if (c->display_usage) {
 		d_printf("%s\n%s",
@@ -525,7 +525,7 @@ static int net_idmap_delete_mapping(struct net_context *c, int argc,
 	TDB_DATA key;
 	NTSTATUS status;
 	const char* dbfile;
-	struct idmap_dump_ctx ctx = { .backend = TDB };
+	struct net_idmap_ctx ctx = { .backend = TDB };
 
 	if ( !delete_args_ok(argc,argv) || c->display_usage) {
 		d_printf("%s\n%s",
@@ -714,7 +714,7 @@ static int net_idmap_check(struct net_context *c, int argc, const char **argv)
 {
 	const char* dbfile;
 	struct check_options opts;
-	struct idmap_dump_ctx ctx = { .backend = TDB };
+	struct net_idmap_ctx ctx = { .backend = TDB };
 
 	if ( argc > 1 || c->display_usage) {
 		d_printf("%s\n%s",
-- 
1.7.9.5


From 0038561f1e887c725c15b7717099c610ab9b371f Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Tue, 10 Sep 2013 01:19:52 +0200
Subject: [PATCH 41/57] net: add new function net_idmap_opendb_autorid()

This checks the backend is autorid, and opens the db if so.
If readonly == true, the DB is simply opened for reading.
If readonly == false, the DB is created if necessary and
initialized with HWMs.

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   51 +++++++++++++++++++++++++++++++++++++++++++++
 source3/wscript_build     |    3 ++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index b12039bd..3fbc482 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -27,6 +27,7 @@
 #include "../libcli/security/security.h"
 #include "net_idmap_check.h"
 #include "util_tdb.h"
+#include "idmap_autorid.h"
 
 #define ALLOC_CHECK(mem) do { \
 	if (!mem) { \
@@ -180,6 +181,56 @@ static const char* net_idmap_dbfile(struct net_context *c,
 	return dbfile;
 }
 
+static bool net_idmap_opendb_autorid(TALLOC_CTX *mem_ctx,
+				     struct net_context *c,
+				     bool readonly,
+				     struct db_context **db)
+{
+	bool ret = false;
+	const char *dbfile;
+	struct net_idmap_ctx ctx = { .backend = AUTORID };
+
+	if (c == NULL) {
+		goto done;
+	}
+
+	dbfile = net_idmap_dbfile(c, &ctx);
+	if (dbfile == NULL) {
+		goto done;
+	}
+
+	if (ctx.backend != AUTORID) {
+		d_fprintf(stderr, _("Unsupported backend\n"));
+		goto done;
+	}
+
+	if (readonly) {
+		*db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0,
+			     DBWRAP_LOCK_ORDER_1);
+		if (*db == NULL) {
+			d_fprintf(stderr,
+				  _("Could not open autorid db (%s): %s\n"),
+				 dbfile, strerror(errno));
+			goto done;
+		}
+	} else {
+		NTSTATUS status;
+		status = idmap_autorid_db_init(dbfile, mem_ctx, db);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr,
+				_("Error calling idmap_autorid_db_init: %s\n"),
+				nt_errstr(status));
+			goto done;
+		}
+	}
+
+	ret = true;
+
+done:
+	return ret;
+}
+
+
 /***********************************************************
  Dump the current idmap
  **********************************************************/
diff --git a/source3/wscript_build b/source3/wscript_build
index 02d9a1a..d3b2a7d 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -1111,7 +1111,8 @@ bld.SAMBA3_BINARY('net',
                  RPC_NDR_DSSETUP
                  RPC_NDR_INITSHUTDOWN
                  printing_migrate
-                 trusts_util''')
+                 trusts_util
+                 IDMAP_AUTORID_TDB''')
 
 bld.SAMBA3_BINARY('profiles',
                  source='utils/profiles.c',
-- 
1.7.9.5


From 190d5dee2b38c8aa24ef15dc72e01f2c43e66308 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 01:45:52 +0200
Subject: [PATCH 42/57] idmap_autorid: add idmap_autorid_saveconfigstr()

Store a configuration as provided by a config string
after parsing and validating the string.

Based on similar patch by Atul Kulkarni <atul.kulkarni at in.ibm.com>.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |    9 +++++++++
 source3/winbindd/idmap_autorid_tdb.c |   16 ++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index d0e1cef..b629f0f 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -127,4 +127,13 @@ NTSTATUS idmap_autorid_getconfigstr(struct db_context *db, TALLOC_CTX *mem_ctx,
 bool idmap_autorid_parse_configstr(const char *configstr,
 				   struct autorid_global_config *cfg);
 
+
+/**
+ * Save the global autorid configuration into the autorid database
+ * as provided in the config string.
+ * First parse the configstr and validate it.
+ */
+NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
+				     const char *configstr);
+
 #endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index cea973c..aee2296 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -695,3 +695,19 @@ done:
 	talloc_free(frame);
 	return status;
 }
+
+NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
+				     const char *configstr)
+{
+	bool ok;
+	NTSTATUS status;
+	struct autorid_global_config cfg;
+
+	ok = idmap_autorid_parse_configstr(configstr, &cfg);
+	if (!ok) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	status = idmap_autorid_saveconfig(db, &cfg);
+	return status;
+}
-- 
1.7.9.5


From b1f12fd8bcfce5332e85e0e3f568dd725e62e59f Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Tue, 10 Sep 2013 01:47:46 +0200
Subject: [PATCH 43/57] net: add "net idmap set config" command to store the
 autorid global config

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   46 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 3fbc482..b17e819 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -736,6 +736,44 @@ static int net_idmap_secret(struct net_context *c, int argc, const char **argv)
 	return 0;
 }
 
+static int net_idmap_autorid_set_config(struct net_context *c,
+					int argc, const char **argv)
+{
+	int ret = -1;
+	NTSTATUS status;
+	TALLOC_CTX *mem_ctx;
+	struct db_context *db = NULL;
+
+	if (argc != 1 || c->display_usage) {
+		d_printf("%s\n%s",
+			 _("Usage:"),
+			 _("net idmap set config <config>"
+			   " [--db=<inputfile>]\n"
+			   " Update CONFIG entry in autorid.\n"
+			   "	config\tConfig string to be stored\n"
+			   "	inputfile\tTDB file to update config.\n"));
+		return c->display_usage ? 0 : -1;
+	}
+
+	mem_ctx = talloc_stackframe();
+
+	if (!net_idmap_opendb_autorid(mem_ctx, c, false, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_saveconfigstr(db, argv[0]);
+	if ( !NT_STATUS_IS_OK(status) ) {
+		printf( "Error updating config to the database \n" );
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
 static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 {
 	struct functable func[] = {
@@ -748,6 +786,14 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 			   "  Not implemented yet")
 		},
 		{
+			"config",
+			net_idmap_autorid_set_config,
+			NET_TRANSPORT_LOCAL,
+			N_("Save the global configuration in the autorid database"),
+			N_("net idmap set config \n"
+			   "  Save the global configuration in the autorid database ")
+		},
+		{
 			"secret",
 			net_idmap_secret,
 			NET_TRANSPORT_LOCAL,
-- 
1.7.9.5


From e5b3d4a08aadad5c516b1cc674168bf02d900232 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 01:53:14 +0200
Subject: [PATCH 44/57] net: add "net idmap get" command

This has no subcommands yet and is added in preparation of adding some.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index b17e819..e297925 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -807,6 +807,15 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 	return net_run_function(c, argc, argv, "net idmap set", func);
 }
 
+static int net_idmap_get(struct net_context *c, int argc, const char **argv)
+{
+	struct functable func[] = {
+		{NULL, NULL, 0, NULL, NULL}
+	};
+
+	return net_run_function(c, argc, argv, "net idmap get", func);
+}
+
 static int net_idmap_check(struct net_context *c, int argc, const char **argv)
 {
 	const char* dbfile;
@@ -876,6 +885,14 @@ int net_idmap(struct net_context *c, int argc, const char **argv)
 			   "  Restore entries from stdin")
 		},
 		{
+			"get",
+			net_idmap_get,
+			NET_TRANSPORT_LOCAL,
+			N_("Read data from the ID mapping database"),
+			N_("net idmap get\n"
+			   "  Read data from the ID mapping database")
+		},
+		{
 			"set",
 			net_idmap_set,
 			NET_TRANSPORT_LOCAL,
-- 
1.7.9.5


From 9f220a21d8c4453674afde42df6d6b532a5aa94b Mon Sep 17 00:00:00 2001
From: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Date: Mon, 12 Aug 2013 13:09:31 +0530
Subject: [PATCH 45/57] net: add "net idmap get config" to read the autorid
 config from the database

Pair-Programmed-With: Michael Adam <obnox at samba.org>

Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index e297925..016ce85 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -807,9 +807,59 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 	return net_run_function(c, argc, argv, "net idmap set", func);
 }
 
+static int net_idmap_autorid_get_config(struct net_context *c, int argc,
+					const char **argv)
+{
+	int ret = -1;
+	char *config;
+	TALLOC_CTX *mem_ctx;
+	NTSTATUS status;
+	struct db_context *db = NULL;
+
+	if (argc > 0 || c->display_usage) {
+		d_printf("%s\n%s",
+			 _("Usage:"),
+			 _("net idmap get config"
+			   " [--db=<inputfile>]\n"
+			   " Get CONFIG entry from autorid database\n"
+			   "	inputfile\tTDB file to read config from.\n"));
+		return c->display_usage ? 0 : -1;
+	}
+
+	mem_ctx = talloc_stackframe();
+
+	if (!net_idmap_opendb_autorid(mem_ctx, c, true, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_getconfigstr(db, mem_ctx, &config);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s: %s\n",
+			  _("Error: unable to read config entry"),
+			  nt_errstr(status));
+		goto done;
+	}
+
+	printf("CONFIG: %s\n", config);
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
+
 static int net_idmap_get(struct net_context *c, int argc, const char **argv)
 {
 	struct functable func[] = {
+		{
+			"config",
+			net_idmap_autorid_get_config,
+			NET_TRANSPORT_LOCAL,
+			N_("Get the global configuration from the autorid database"),
+			N_("net idmap get config \n"
+			   "  Get the global configuration from the autorid database ")
+		},
 		{NULL, NULL, 0, NULL, NULL}
 	};
 
-- 
1.7.9.5


From 4c455a68274a9b9ba8a39f24ef42bc9e265dc973 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 9 Sep 2013 16:09:52 +0200
Subject: [PATCH 46/57] net: add "net idmap set range" (for autorid backend)

This lets the admin store a range for a domain/index pair.
Call syntax is:

net idmap set range <RANGE> <DOMSID> [<INDEX>]

INDEX defaults to 0.

Pair-Programmed-With: Atul Kulkarni <atul.kulkarni at in.ibm.com>

Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni at in.ibm.com>
---
 source3/utils/net_idmap.c |   78 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 016ce85..d5971d3 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -647,6 +647,76 @@ static int net_idmap_set_mapping(struct net_context *c,
 	return -1;
 }
 
+static void net_idmap_autorid_set_range_usage(void)
+{
+	d_printf("%s\n%s",
+		 _("Usage:"),
+		 _("net idmap set range"
+		   " <range> <SID> [<index>] [--db=<inputfile>]\n"
+		   "  Store a domain-range mapping for a given domain.\n"
+		   "    range\tRange number to be set for the domain\n"
+		   "    SID\t\tSID of the domain\n"
+		   "    index\trange-index number to be set for the domain\n"
+		   "    inputfile\tTDB file to add mapping to.\n"));
+}
+
+static int net_idmap_autorid_set_range(struct net_context *c,
+				       int argc, const char **argv)
+{
+	int ret = -1;
+	TALLOC_CTX *mem_ctx;
+	struct db_context *db = NULL;
+	fstring domsid;
+	uint32_t rangenum;
+	uint32_t range_index = 0;
+	NTSTATUS status;
+
+	if (c->display_usage) {
+		net_idmap_autorid_set_range_usage();
+		return 0;
+	}
+
+	if (argc < 2  || argc > 3) {
+		net_idmap_autorid_set_range_usage();
+		return -1;
+	}
+
+	if (sscanf(argv[0], "%"SCNu32, &rangenum) != 1) {
+		d_printf("%s: %s\n", _("Invalid range specification"), argv[0]);
+		net_idmap_autorid_set_range_usage();
+		return -1;
+	}
+
+	fstrcpy(domsid, argv[1]);
+
+	if (argc == 3) {
+		if (sscanf(argv[2], "%"SCNu32, &range_index) != 1) {
+			d_printf("%s: %s\n",
+				 _("Invalid index specification"), argv[2]);
+			net_idmap_autorid_set_range_usage();
+			return -1;
+		}
+	}
+
+	mem_ctx = talloc_stackframe();
+	if (!net_idmap_opendb_autorid(mem_ctx, c, false, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_setrange(db, domsid, range_index, rangenum);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s: %s\n",
+			  _("Failed to save domain mapping"), nt_errstr(status));
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	talloc_free( mem_ctx );
+	return ret;
+}
+
 static bool idmap_store_secret(const char *backend,
 			       const char *domain,
 			       const char *identity,
@@ -786,6 +856,14 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 			   "  Not implemented yet")
 		},
 		{
+			"range",
+			net_idmap_autorid_set_range,
+			NET_TRANSPORT_LOCAL,
+			N_("Store a domain-range mapping"),
+			N_("net idmap set range\n"
+			   "  Store a domain-range mapping")
+		},
+		{
 			"config",
 			net_idmap_autorid_set_config,
 			NET_TRANSPORT_LOCAL,
-- 
1.7.9.5


From 692c8d19117ee4b11d4317c49977a4d8b371f32a Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 10 Sep 2013 13:35:56 +0200
Subject: [PATCH 47/57] idmap_autorid: improve clarity of
 idmap_autorid_addrange_action() by adding mem_ctx.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index aee2296..567e28d6 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -74,6 +74,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	struct autorid_global_config *globalcfg;
 	fstring keystr;
 	uint32_t increment;
+	TALLOC_CTX *mem_ctx = NULL;
 
 	ctx = (struct idmap_autorid_addrange_ctx *)private_data;
 	range = ctx->range;
@@ -129,11 +130,12 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while fetching current "
 			  "HWM value: %s\n", nt_errstr(ret)));
-		ret = NT_STATUS_INTERNAL_ERROR;
-		goto error;
+		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	ret = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
+	mem_ctx = talloc_stackframe();
+
+	ret = idmap_autorid_loadconfig(db, mem_ctx, &globalcfg);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while fetching configuration: %s\n",
 			  nt_errstr(ret)));
@@ -167,7 +169,6 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
 	}
-	TALLOC_FREE(globalcfg);
 
 	/* HWM always contains current max range + 1 */
 	increment = requested_rangenum + 1 - hwm;
@@ -188,7 +189,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		goto error;
 	}
 
-	numstr = talloc_asprintf(talloc_tos(), "%u", requested_rangenum);
+	numstr = talloc_asprintf(mem_ctx, "%u", requested_rangenum);
 	if (!numstr) {
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
@@ -197,7 +198,6 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	ret = dbwrap_store_bystring(db, numstr,
 			string_term_tdb_data(keystr), TDB_INSERT);
 
-	talloc_free(numstr);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while storing new "
 			  "domain->range assignment: %s\n", nt_errstr(ret)));
@@ -212,9 +212,10 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	range->low_id = globalcfg->minvalue
 		      + range->rangenum * globalcfg->rangesize;
 
-	return NT_STATUS_OK;
+	ret = NT_STATUS_OK;
 
 error:
+	talloc_free(mem_ctx);
 	return ret;
 }
 
-- 
1.7.9.5


From c086be43cb8f7d42ed3b837a6274c6d978b9c91f Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 11 Sep 2013 01:05:02 +0200
Subject: [PATCH 48/57] net: implement "net idmap get range"

get the range for a domain sid and range index.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   82 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index d5971d3..bd6cf0d 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -885,6 +885,80 @@ static int net_idmap_set(struct net_context *c, int argc, const char **argv)
 	return net_run_function(c, argc, argv, "net idmap set", func);
 }
 
+static void net_idmap_autorid_get_range_usage(void)
+{
+	d_printf("%s\n%s",
+		 _("Usage:"),
+		 _("net idmap get range <SID> [<index>] [--db=<inputfile>]\n"
+		   "  Get the range for a given domain and index.\n"
+		   "    SID\t\tSID of the domain\n"
+		   "    index\trange-index number to be retrieved\n"
+		   "    inputfile\tTDB file to add mapping to.\n"));
+}
+
+
+static int net_idmap_autorid_get_range(struct net_context *c, int argc,
+				       const char **argv)
+{
+	int ret = -1;
+	TALLOC_CTX *mem_ctx;
+	struct db_context *db = NULL;
+	fstring domsid;
+	uint32_t rangenum;
+	uint32_t range_index = 0;
+	uint32_t low_id;
+	NTSTATUS status;
+	char *keystr;
+
+	if (c->display_usage) {
+		net_idmap_autorid_get_range_usage();
+		return 0;
+	}
+
+	if (argc < 1  || argc > 2) {
+		net_idmap_autorid_get_range_usage();
+		return -1;
+	}
+
+	fstrcpy(domsid, argv[0]);
+
+	if (argc == 2) {
+		if (sscanf(argv[1], "%"SCNu32, &range_index) != 1) {
+			d_printf("%s: %s\n",
+				 _("Invalid index specification"), argv[2]);
+			net_idmap_autorid_get_range_usage();
+			return -1;
+		}
+	}
+
+	mem_ctx = talloc_stackframe();
+	if (!net_idmap_opendb_autorid(mem_ctx, c, true, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_getrange(db, domsid, range_index, &rangenum, &low_id);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s: %s\n",
+			  _("Failed to load domain range"), nt_errstr(status));
+		goto done;
+	}
+
+	if (range_index == 0) {
+		keystr = talloc_strdup(mem_ctx, domsid);
+	} else {
+		keystr = talloc_asprintf(mem_ctx, "%s#%"PRIu32, domsid, range_index);
+	}
+
+	printf("RANGE %"PRIu32": %s (low id: %"PRIu32")\n",
+	       rangenum, keystr, low_id);
+
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
 static int net_idmap_autorid_get_config(struct net_context *c, int argc,
 					const char **argv)
 {
@@ -931,6 +1005,14 @@ static int net_idmap_get(struct net_context *c, int argc, const char **argv)
 {
 	struct functable func[] = {
 		{
+			"range",
+			net_idmap_autorid_get_range,
+			NET_TRANSPORT_LOCAL,
+			N_("Get the range for a domain and range-index"),
+			N_("net idmap get range\n"
+			   "  Get the range for a domain and range-index")
+		},
+		{
 			"config",
 			net_idmap_autorid_get_config,
 			NET_TRANSPORT_LOCAL,
-- 
1.7.9.5


From 6e19a6d71b1a05563205daa6fe6cde0e8882b7ce Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 12 Sep 2013 07:37:17 +0200
Subject: [PATCH 49/57] idmap_autorid: extend idmap_autorid_addrange to allow
 to set mappings below the HWM

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |   59 ++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 21 deletions(-)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 567e28d6..f12a7e0 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -147,18 +147,6 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		 * automatically acquire the next range
 		 */
 		requested_rangenum = hwm;
-	} else {
-		/*
-		 * set a specified range
-		 */
-
-		if (requested_rangenum < hwm) {
-			DEBUG(3, ("Invalid range %u requested: Range may not "
-				  "be smaller than %u (current HWM)\n",
-				  requested_rangenum, hwm));
-			ret = NT_STATUS_INVALID_PARAMETER;
-			goto error;
-		}
 	}
 
 	if (requested_rangenum >= globalcfg->maxranges) {
@@ -170,18 +158,47 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		goto error;
 	}
 
-	/* HWM always contains current max range + 1 */
-	increment = requested_rangenum + 1 - hwm;
+	if (requested_rangenum < hwm) {
+		/*
+		 * Set a specified range below the HWM:
+		 * We need to check that it is not yet taken.
+		 */
 
-	/* increase the HWM */
-	ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &hwm, increment);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(1, ("Fatal error while incrementing the HWM value "
-			  "in the database: %s\n", nt_errstr(ret)));
-		goto error;
+		numstr = talloc_asprintf(mem_ctx, "%u", requested_rangenum);
+		if (!numstr) {
+			ret = NT_STATUS_NO_MEMORY;
+			goto error;
+		}
+
+		if (dbwrap_exists(db, string_term_tdb_data(keystr))) {
+			DEBUG(1, ("Requested range already in use.\n"));
+			ret = NT_STATUS_INVALID_PARAMETER;
+			goto error;
+		}
+
+		TALLOC_FREE(numstr);
+	} else {
+		/*
+		 * requested or automatic range >= HWM:
+		 * increment the HWM.
+		 */
+
+		/* HWM always contains current max range + 1 */
+		increment = requested_rangenum + 1 - hwm;
+
+		/* increase the HWM */
+		ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &hwm, increment);
+		if (!NT_STATUS_IS_OK(ret)) {
+			DEBUG(1, ("Fatal error while incrementing the HWM value "
+				  "in the database: %s\n", nt_errstr(ret)));
+			goto error;
+		}
 	}
 
-	/* store away the new mapping in both directions */
+	/*
+	 * store away the new mapping in both directions
+	 */
+
 	ret = dbwrap_store_uint32_bystring(db, keystr, requested_rangenum);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while storing new "
-- 
1.7.9.5


From fd6436a53c832b2887917823c08cecfd3c709f58 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Sun, 15 Sep 2013 11:58:02 +0200
Subject: [PATCH 50/57] idmap_autorid: add idmap_autorid_build_keystr_talloc()

talloc version of idmap_autorid_build_keystr()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/idmap_autorid_tdb.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index f12a7e0..adb171f 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -42,6 +42,23 @@ static void idmap_autorid_build_keystr(const char *domsid,
 	}
 }
 
+static char *idmap_autorid_build_keystr_talloc(TALLOC_CTX *mem_ctx,
+					      const char *domsid,
+					      uint32_t domain_range_index)
+{
+	char *keystr;
+
+	if (domain_range_index > 0) {
+		keystr = talloc_asprintf(mem_ctx, "%s#%"PRIu32, domsid,
+					 domain_range_index);
+	} else {
+		keystr = talloc_strdup(mem_ctx, domsid);
+	}
+
+	return keystr;
+}
+
+
 static bool idmap_autorid_validate_sid(const char *sid)
 {
 	struct dom_sid ignore;
-- 
1.7.9.5


From 0562a8b2e7fdc040f29a8d394e03070f8e54d41a Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 12 Sep 2013 13:44:53 +0200
Subject: [PATCH 51/57] idmap_autorid: add idmap_autorid_delete_range_by_sid()

Delete a range mapping as specified by domain SID and range index.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |   11 ++++
 source3/winbindd/idmap_autorid_tdb.c |  116 ++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index b629f0f..27192ff 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -82,6 +82,17 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
 				uint32_t rangenum);
 
 /**
+ * Delete a domain#index <-> range maping from the database.
+ * The mapping is specified by the sid and index.
+ * If force == true, invalid mapping records are deleted as far
+ * as possible, otherwise they are left untouched.
+ */
+NTSTATUS idmap_autorid_delete_range_by_sid(struct db_context *db,
+					   const char *domsid,
+					   uint32_t domain_range_index,
+					   bool force);
+
+/**
  * Initialize a specified HWM value to 0 if it is not
  * yet present in the database.
  */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index adb171f..518b4d6 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -405,6 +405,122 @@ NTSTATUS idmap_autorid_init_hwm(struct db_context *db, const char *hwm)
 }
 
 /*
+ * Delete a domain#index <-> range mapping from the database.
+ * The mapping is specified by the sid and index.
+ * If force == true, invalid mapping records are deleted as far
+ * as possible, otherwise they are left untouched.
+ */
+
+struct idmap_autorid_delete_range_by_sid_ctx {
+	const char *domsid;
+	uint32_t domain_range_index;
+	bool force;
+};
+
+static NTSTATUS idmap_autorid_delete_range_by_sid_action(struct db_context *db,
+							 void *private_data)
+{
+	struct idmap_autorid_delete_range_by_sid_ctx *ctx;
+	ctx = (struct idmap_autorid_delete_range_by_sid_ctx *)private_data;
+	const char *domsid;
+	uint32_t domain_range_index;
+	uint32_t rangenum;
+	char *keystr;
+	char *range_keystr;
+	TDB_DATA data;
+	NTSTATUS status;
+	TALLOC_CTX *frame = talloc_stackframe();
+	bool is_valid_range_mapping = true;
+	bool force;
+
+	domsid = ctx->domsid;
+	domain_range_index = ctx->domain_range_index;
+	force = ctx->force;
+
+	keystr = idmap_autorid_build_keystr_talloc(frame, domsid, domain_range_index);
+	if (keystr == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
+	}
+
+	status = dbwrap_fetch_uint32_bystring(db, keystr, &rangenum);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto done;
+	}
+
+	range_keystr = talloc_asprintf(frame, "%"PRIu32, rangenum);
+	if (range_keystr == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
+	}
+
+	status = dbwrap_fetch_bystring(db, frame, range_keystr, &data);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+		DEBUG(1, ("Incomplete mapping %s -> %s: no backward mapping\n",
+			  keystr, range_keystr));
+		is_valid_range_mapping = false;
+	} else if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Error fetching reverse mapping for %s -> %s:  %s\n",
+			  keystr, range_keystr, nt_errstr(status)));
+		goto done;
+	} else if (strncmp((const char *)data.dptr, keystr, strlen(keystr))
+		   != 0)
+	{
+		DEBUG(1, ("Invalid mapping: %s -> %s -> %s\n",
+			  keystr, range_keystr, (const char *)data.dptr));
+		is_valid_range_mapping = false;
+	}
+
+	if (!is_valid_range_mapping && !force) {
+		DEBUG(10, ("Not deleting invalid mapping, since not in force "
+			   "mode.\n"));
+		status = NT_STATUS_FILE_INVALID;
+		goto done;
+	}
+
+	status = dbwrap_delete_bystring(db, keystr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Deletion of '%s' failed: %s\n",
+			  keystr, nt_errstr(status)));
+		goto done;
+	}
+
+	if (!is_valid_range_mapping) {
+		goto done;
+	}
+
+	status = dbwrap_delete_bystring(db, range_keystr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Deletion of '%s' failed: %s\n",
+			  range_keystr, nt_errstr(status)));
+		goto done;
+	}
+
+	DEBUG(10, ("Deleted range mapping %s <--> %s\n", keystr, range_keystr));
+
+done:
+	talloc_free(frame);
+	return status;
+}
+
+NTSTATUS idmap_autorid_delete_range_by_sid(struct db_context *db,
+					   const char *domsid,
+					   uint32_t domain_range_index,
+					   bool force)
+{
+	NTSTATUS status;
+	struct idmap_autorid_delete_range_by_sid_ctx ctx;
+
+	ctx.domain_range_index = domain_range_index;
+	ctx.domsid = domsid;
+	ctx.force = force;
+
+	status = dbwrap_trans_do(db, idmap_autorid_delete_range_by_sid_action, &ctx);
+	return status;
+}
+
+
+/*
  * open and initialize the database which stores the ranges for the domains
  */
 NTSTATUS idmap_autorid_db_init(const char *path,
-- 
1.7.9.5


From 0aec669d569cd428342ad4f8c4711f7a564f06d0 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 12 Sep 2013 23:59:15 +0200
Subject: [PATCH 52/57] idmap_autorid: add 
 idmap_autorid_delete_range_by_num()

query and delete a mapping specified by the range number.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |   10 +++
 source3/winbindd/idmap_autorid_tdb.c |  115 ++++++++++++++++++++++++++++++++++
 2 files changed, 125 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 27192ff..61cf238 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -93,6 +93,16 @@ NTSTATUS idmap_autorid_delete_range_by_sid(struct db_context *db,
 					   bool force);
 
 /**
+ * Delete a domain#index <-> range maping from the database.
+ * The mapping is specified by the range number.
+ * If force == true, invalid mapping records are deleted as far
+ * as possible, otherwise they are left untouched.
+ */
+NTSTATUS idmap_autorid_delete_range_by_num(struct db_context *db,
+					   uint32_t rangenum,
+					   bool force);
+
+/**
  * Initialize a specified HWM value to 0 if it is not
  * yet present in the database.
  */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 518b4d6..7f73eb3 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -519,6 +519,121 @@ NTSTATUS idmap_autorid_delete_range_by_sid(struct db_context *db,
 	return status;
 }
 
+/*
+ * Delete a domain#index <-> range mapping from the database.
+ * The mapping is specified by the range number.
+ * If force == true, invalid mapping records are deleted as far
+ * as possible, otherwise they are left untouched.
+ */
+struct idmap_autorid_delete_range_by_num_ctx {
+	uint32_t rangenum;
+	bool force;
+};
+
+static NTSTATUS idmap_autorid_delete_range_by_num_action(struct db_context *db,
+							   void *private_data)
+{
+	struct idmap_autorid_delete_range_by_num_ctx *ctx;
+	ctx = (struct idmap_autorid_delete_range_by_num_ctx *)private_data;
+	uint32_t rangenum;
+	char *keystr;
+	char *range_keystr;
+	TDB_DATA val;
+	NTSTATUS status;
+	TALLOC_CTX *frame = talloc_stackframe();
+	bool is_valid_range_mapping = true;
+	bool force;
+
+	rangenum = ctx->rangenum;
+	force = ctx->force;
+
+	range_keystr = talloc_asprintf(frame, "%"PRIu32, rangenum);
+	if (range_keystr == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
+	}
+
+	ZERO_STRUCT(val);
+
+	status = dbwrap_fetch_bystring(db, frame, range_keystr, &val);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+		DEBUG(10, ("Did not find range '%s' in database.\n", range_keystr));
+		goto done;
+	} else if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5, ("Error fetching rang key: %s\n", nt_errstr(status)));
+		goto done;
+	}
+
+	if (val.dptr == NULL) {
+		DEBUG(1, ("Invalid mapping: %s -> empty value\n", range_keystr));
+		is_valid_range_mapping = false;
+	} else {
+		uint32_t reverse_rangenum = 0;
+
+		keystr = (char *)val.dptr;
+
+		status = dbwrap_fetch_uint32_bystring(db, keystr,
+						      &reverse_rangenum);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+			DEBUG(1, ("Incomplete mapping %s -> %s: "
+				  "no backward mapping\n",
+				  range_keystr, keystr));
+			is_valid_range_mapping = false;
+		} else if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(1, ("Error fetching reverse mapping for "
+				  "%s -> %s: %s\n",
+				  range_keystr, keystr, nt_errstr(status)));
+			goto done;
+		} else if (rangenum != reverse_rangenum) {
+			is_valid_range_mapping = false;
+		}
+	}
+
+	if (!is_valid_range_mapping && !force) {
+		DEBUG(10, ("Not deleting invalid mapping, since not in force "
+			   "mode.\n"));
+		status = NT_STATUS_FILE_INVALID;
+		goto done;
+	}
+
+	status = dbwrap_delete_bystring(db, range_keystr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Deletion of '%s' failed: %s\n",
+			  range_keystr, nt_errstr(status)));
+		goto done;
+	}
+
+	if (!is_valid_range_mapping) {
+		goto done;
+	}
+
+	status = dbwrap_delete_bystring(db, keystr);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Deletion of '%s' failed: %s\n",
+			  keystr, nt_errstr(status)));
+		goto done;
+	}
+
+	DEBUG(10, ("Deleted range mapping %s <--> %s\n", range_keystr, keystr));
+
+done:
+	talloc_free(frame);
+	return status;
+}
+
+NTSTATUS idmap_autorid_delete_range_by_num(struct db_context *db,
+					   uint32_t rangenum,
+					   bool force)
+{
+	NTSTATUS status;
+	struct idmap_autorid_delete_range_by_num_ctx ctx;
+
+	ctx.rangenum = rangenum;
+	ctx.force = force;
+
+	status = dbwrap_trans_do(db, idmap_autorid_delete_range_by_num_action, &ctx);
+	return status;
+}
 
 /*
  * open and initialize the database which stores the ranges for the domains
-- 
1.7.9.5


From 9b9d76b93297601afb547fd6df5018f75b78526b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Thu, 12 Sep 2013 13:45:22 +0200
Subject: [PATCH 53/57] net: implement "net idmap delete range"

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   99 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index bd6cf0d..0281ec3 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -622,6 +622,97 @@ done:
 	return ret;
 }
 
+static void net_idmap_autorid_delete_range_usage(void)
+{
+	d_printf("%s\n%s",
+		 _("Usage:"),
+		 _("net idmap delete range [-f] [--db=<TDB>] <RANGE>|(<SID>[ <INDEX>])\n"
+		   "  Delete a domain range mapping from the database.\n"
+		   "    -f\tforce\n"
+		   "    TDB\tidmap database\n"
+		   "    RANGE\tthe range number to delete\n"
+		   "    SID\t\tSID of the domain\n"
+		   "    INDEX\trange index number do delete for the domain\n"));
+}
+
+static int net_idmap_autorid_delete_range(struct net_context *c, int argc,
+					  const char **argv)
+{
+	int ret = -1;
+	struct db_context *db = NULL;
+	NTSTATUS status;
+	uint32_t rangenum;
+	uint32_t range_index;
+	fstring domsid;
+	TALLOC_CTX *mem_ctx = NULL;
+	bool force = (c->opt_force != 0);
+
+	if (c->display_usage) {
+		net_idmap_autorid_delete_range_usage();
+		return 0;
+	}
+
+	if (argc < 1 || argc > 2) {
+		net_idmap_autorid_delete_range_usage();
+		return -1;
+	}
+
+	mem_ctx = talloc_stackframe();
+	if (!net_idmap_opendb_autorid(mem_ctx, c, false, &db)) {
+		goto done;
+	}
+
+	if (sscanf(argv[0], "%"SCNu32, &rangenum) == 1) {
+		fstring teststr;
+
+		/* found a number. check whether that was all of argv[0] */
+		snprintf(teststr, FSTRING_LEN, "%"PRIu32, rangenum);
+		if (strcmp(teststr, argv[0]) != 0) {
+			d_printf("%s: %s\n", _("Invalid range specification "
+				 "(trailing characters)"), argv[0]);
+			net_idmap_autorid_delete_range_usage();
+			goto done;
+		}
+
+		d_printf("%s: %"PRIu32"\n", _("Deleting range number "),
+			 rangenum);
+
+		status = idmap_autorid_delete_range_by_num(db, rangenum, force);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr, "%s: %s\n",
+				  _("Failed to delete domain range mapping"),
+				  nt_errstr(status));
+			goto done;
+		}
+	}
+
+	fstrcpy(domsid, argv[0]);
+
+	if (argc == 2) {
+		if (sscanf(argv[1], "%"SCNu32, &range_index) != 1) {
+			d_printf("%s: %s\n",
+				 _("Invalid index specification"), argv[1]);
+			net_idmap_autorid_delete_range_usage();
+			goto done;
+		}
+	}
+
+	status = idmap_autorid_delete_range_by_sid(db, domsid, range_index,
+						   force);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s: %s\n",
+			  _("Failed to delete domain range mapping"),
+			  nt_errstr(status));
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
 static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
 {
 	struct functable func[] = {
@@ -633,6 +724,14 @@ static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
 			N_("net idmap delete mapping <ID>\n"
 			   "  Delete ID mapping")
 		},
+		{
+			"range",
+			net_idmap_autorid_delete_range,
+			NET_TRANSPORT_LOCAL,
+			N_("Delete a domain range mapping"),
+			N_("net idmap delete range <RANGE>|(<SID>[ <INDEX>])\n"
+			   "  Delete a domain range mapping")
+		},
 		{NULL, NULL, 0, NULL, NULL}
 	};
 
-- 
1.7.9.5


From 9835f0e95c34f07124c797414713dda500688a04 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 18 Sep 2013 01:54:58 +0200
Subject: [PATCH 54/57] idmap_autorid: add
 idmap_autorid_iterate_domain_ranges[_read]()

Functions to perform an action on all domain range mappings for
a given domain, specified by the domain sid.

Inspired by a previous patch by Atul Kulkarni <atul.kulkarni at in.ibm.com>.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |   31 ++++++
 source3/winbindd/idmap_autorid_tdb.c |  191 ++++++++++++++++++++++++++++++++++
 2 files changed, 222 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 61cf238..512453c 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -157,4 +157,35 @@ bool idmap_autorid_parse_configstr(const char *configstr,
 NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
 				     const char *configstr);
 
+
+/**
+ * idmap_autorid_iterate_domain_ranges:
+ * perform an action on all domain range mappings for a given domain
+ * specified by domain sid.
+ */
+NTSTATUS idmap_autorid_iterate_domain_ranges(struct db_context *db,
+					const char *domsid,
+					NTSTATUS (*fn)(struct db_context *db,
+						       const char *domsid,
+						       uint32_t index,
+						       uint32_t rangenum,
+						       void *private_data),
+					void *private_data,
+					int *count);
+
+/**
+ * idmap_autorid_iterate_domain_ranges_read:
+ * perform a read only action on all domain range mappings for a given domain
+ * specified by domain sid.
+ */
+NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
+					const char *domsid,
+					NTSTATUS (*fn)(struct db_context *db,
+						       const char *domsid,
+						       uint32_t index,
+						       uint32_t rangenum,
+						       void *private_data),
+					void *private_data,
+					int *count);
+
 #endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 7f73eb3..575d77d 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -977,3 +977,194 @@ NTSTATUS idmap_autorid_saveconfigstr(struct db_context *db,
 	status = idmap_autorid_saveconfig(db, &cfg);
 	return status;
 }
+
+
+/*
+ * iteration: Work on all range mappings for a given domain
+ */
+
+struct domain_range_visitor_ctx {
+	const char *domsid;
+	NTSTATUS (*fn)(struct db_context *db,
+		       const char *domsid,
+		       uint32_t index,
+		       uint32_t rangenum,
+		       void *private_data);
+	void *private_data;
+	int count; /* number of records worked on */
+};
+
+static int idmap_autorid_visit_domain_range(struct db_record *rec,
+					    void *private_data)
+{
+	struct domain_range_visitor_ctx *vi;
+	char *domsid;
+	char *sep;
+	uint32_t range_index = 0;
+	uint32_t rangenum = 0;
+	TDB_DATA key, value;
+	NTSTATUS status;
+	int ret = 0;
+	struct db_context *db;
+
+	vi = talloc_get_type_abort(private_data,
+				   struct domain_range_visitor_ctx);
+
+	if (vi->domsid == NULL) {
+		DEBUG(1, ("Error: no domain sid provided\n"));
+		return -1;
+	}
+
+	if (vi->fn == NULL) {
+		DEBUG(1, ("Error: missing visitor callback\n"));
+		return -1;
+	}
+
+	key = dbwrap_record_get_key(rec);
+
+	/*
+	 * split string "<sid>[#<index>]" into sid string and index number
+	 */
+
+	domsid = (char *)key.dptr;
+
+	DEBUG(10, ("idmap_autorid_visit_domain_range: visiting key '%s'\n", domsid));
+
+	sep = strrchr(domsid, '#');
+	if (sep != NULL) {
+		char *index_str;
+		*sep = '\0';
+		index_str = sep+1;
+		if (sscanf(index_str, "%"SCNu32, &range_index) != 1) {
+			DEBUG(3, ("Error parsing domain range index part of "
+				  "record\n"));
+			goto done;
+		}
+	}
+
+	if (!idmap_autorid_validate_sid(domsid)) {
+		DEBUG(3, ("Invalid sid string found in record\n"));
+		goto done;
+	}
+
+	if (strcmp(domsid, vi->domsid) != 0) {
+		DEBUG(10, ("key sid '%s' does not match requested sid '%s'\n",
+			   domsid, vi->domsid));
+		goto done;
+	}
+
+	value = dbwrap_record_get_value(rec);
+	rangenum = IVAL(value.dptr, 0);
+
+	db = dbwrap_record_get_db(rec);
+
+	status = vi->fn(db, domsid, range_index, rangenum, vi->private_data);
+	if (!NT_STATUS_IS_OK(status)) {
+		ret = -1;
+		goto done;
+	}
+
+	vi->count++;
+	ret = 0;
+
+done:
+	return ret;
+}
+
+static NTSTATUS idmap_autorid_iterate_domain_ranges_int(struct db_context *db,
+				const char *domsid,
+				NTSTATUS (*fn)(struct db_context *db,
+					       const char *domsid,
+					       uint32_t index,
+					       uint32_t rangnum,
+					       void *private_data),
+				void *private_data,
+				int *count,
+				NTSTATUS (*traverse)(struct db_context *db,
+					  int (*f)(struct db_record *, void *),
+					  void *private_data,
+					  int *count))
+{
+	NTSTATUS status;
+	struct domain_range_visitor_ctx *vi;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	vi = talloc_zero(frame, struct domain_range_visitor_ctx);
+	if (vi == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
+	}
+
+	if (domsid == NULL) {
+		DEBUG(1, ("Error: no domain sid provided\n"));
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto done;
+	}
+
+	vi->domsid = talloc_strdup(vi, domsid);
+	if (vi->domsid == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto done;
+	}
+
+	vi->fn = fn;
+	vi->private_data = private_data;
+
+	status = traverse(db, idmap_autorid_visit_domain_range, vi, NULL);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto done;
+	}
+
+	if (count != NULL) {
+		*count = vi->count;
+	}
+
+done:
+	talloc_free(frame);
+	return status;
+}
+
+NTSTATUS idmap_autorid_iterate_domain_ranges(struct db_context *db,
+					const char *domsid,
+					NTSTATUS (*fn)(struct db_context *db,
+						       const char *domsid,
+						       uint32_t index,
+						       uint32_t rangenum,
+						       void *private_data),
+					void *private_data,
+					int *count)
+{
+	NTSTATUS status;
+
+	status = idmap_autorid_iterate_domain_ranges_int(db,
+							 domsid,
+							 fn,
+							 private_data,
+							 count,
+							 dbwrap_traverse);
+
+	return status;
+}
+
+
+NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
+					const char *domsid,
+					NTSTATUS (*fn)(struct db_context *db,
+						       const char *domsid,
+						       uint32_t index,
+						       uint32_t rangenum,
+						       void *count),
+					void *private_data,
+					int *count)
+{
+	NTSTATUS status;
+
+	status = idmap_autorid_iterate_domain_ranges_int(db,
+							 domsid,
+							 fn,
+							 private_data,
+							 count,
+							 dbwrap_traverse_read);
+
+	return status;
+}
-- 
1.7.9.5


From c2b202a9a90c3815d19a61650e6dcb08988fadb2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 18 Sep 2013 02:39:51 +0200
Subject: [PATCH 55/57] net: add "net idmap get ranges" operation for autorid

Implemented usint the idmap_autorid_iterate_domain_ranges_read() function.
Based on earlier patch by Atul Kulkarni <atul.kulkarni at in.ibm.com>.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   74 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index 0281ec3..c436c6a 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -1058,6 +1058,72 @@ done:
 	return ret;
 }
 
+static NTSTATUS net_idmap_autorid_print_range(struct db_context *db,
+					      const char *domsid,
+					      uint32_t range_index,
+					      uint32_t rangenum,
+					      void *private_data)
+{
+	printf("RANGE %"PRIu32": %s#%"PRIu32"\n", rangenum, domsid,
+	       range_index);
+
+	return NT_STATUS_OK;
+}
+
+static void net_idmap_autorid_get_ranges_usage(void)
+{
+	d_printf("%s\n%s",
+		 _("Usage:"),
+		 _("net idmap get ranges <SID> [--db=<inputfile>]\n"
+		   "  Get all ranges for a given domain.\n"
+		   "    SID\t\tSID of the domain\n"
+		   "    inputfile\tTDB file to add mapping to.\n"));
+}
+
+static int net_idmap_autorid_get_ranges(struct net_context *c, int argc,
+					const char **argv)
+{
+	int ret = -1;
+	TALLOC_CTX *mem_ctx;
+	struct db_context *db = NULL;
+	fstring domsid;
+	NTSTATUS status;
+
+	if (c->display_usage) {
+		net_idmap_autorid_get_ranges_usage();
+		return 0;
+	}
+
+	if (argc != 1) {
+		net_idmap_autorid_get_ranges_usage();
+		return -1;
+	}
+
+	fstrcpy(domsid, argv[0]);
+
+	mem_ctx = talloc_stackframe();
+	if (!net_idmap_opendb_autorid(mem_ctx, c, true, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_iterate_domain_ranges_read(db,
+						domsid,
+						net_idmap_autorid_print_range,
+						NULL, /* private_data */
+						NULL  /* count */);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s: %s\n",
+			  _("Error getting domain ranges"), nt_errstr(status));
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
 static int net_idmap_autorid_get_config(struct net_context *c, int argc,
 					const char **argv)
 {
@@ -1112,6 +1178,14 @@ static int net_idmap_get(struct net_context *c, int argc, const char **argv)
 			   "  Get the range for a domain and range-index")
 		},
 		{
+			"ranges",
+			net_idmap_autorid_get_ranges,
+			NET_TRANSPORT_LOCAL,
+			N_("Get all ranges for a domain"),
+			N_("net idmap get ranges <SID>\n"
+			   "  Get all ranges for a domain")
+		},
+		{
 			"config",
 			net_idmap_autorid_get_config,
 			NET_TRANSPORT_LOCAL,
-- 
1.7.9.5


From 5a8044f61bdba61788bec03ba29ff6d64057311e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 18 Sep 2013 03:04:52 +0200
Subject: [PATCH 56/57] idmap_autorid: add
 idmap_autorid_delete_domain_ranges()

This uses the new idmap_autorid_iterate_domain_ranges() function.
Based on earlier patch by Atul Kulkarni <atul.kulkarni at in.ibm.com>.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/include/idmap_autorid.h      |    8 ++++
 source3/winbindd/idmap_autorid_tdb.c |   81 ++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/source3/include/idmap_autorid.h b/source3/include/idmap_autorid.h
index 512453c..4c5c184 100644
--- a/source3/include/idmap_autorid.h
+++ b/source3/include/idmap_autorid.h
@@ -188,4 +188,12 @@ NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
 					void *private_data,
 					int *count);
 
+/**
+ * delete all range mappings for a given domain
+ */
+NTSTATUS idmap_autorid_delete_domain_ranges(struct db_context *db,
+					    const char *domsid,
+					    bool force,
+					    int *count);
+
 #endif /* _IDMAP_AUTORID_H_ */
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 575d77d..6bd007e 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -1168,3 +1168,84 @@ NTSTATUS idmap_autorid_iterate_domain_ranges_read(struct db_context *db,
 
 	return status;
 }
+
+
+/*
+ * Delete all ranges configured for a given domain
+ */
+
+struct delete_domain_ranges_visitor_ctx {
+	bool force;
+};
+
+static NTSTATUS idmap_autorid_delete_domain_ranges_visitor(
+						struct db_context *db,
+						const char *domsid,
+						uint32_t domain_range_index,
+						uint32_t rangenum,
+						void *private_data)
+{
+	struct delete_domain_ranges_visitor_ctx *ctx;
+	NTSTATUS status;
+
+	ctx = (struct delete_domain_ranges_visitor_ctx *)private_data;
+
+	status = idmap_autorid_delete_range_by_sid(db, domsid, domain_range_index, ctx->force);
+	return status;
+}
+
+struct idmap_autorid_delete_domain_ranges_ctx {
+	const char *domsid;
+	bool force;
+	int count; /* output: count records operated on */
+};
+
+static NTSTATUS idmap_autorid_delete_domain_ranges_action(struct db_context *db,
+							  void *private_data)
+{
+	struct idmap_autorid_delete_domain_ranges_ctx *ctx;
+	struct delete_domain_ranges_visitor_ctx visitor_ctx;
+	int count;
+	NTSTATUS status;
+
+	ctx = (struct idmap_autorid_delete_domain_ranges_ctx *)private_data;
+
+	ZERO_STRUCT(visitor_ctx);
+	visitor_ctx.force = ctx->force;
+
+	status = idmap_autorid_iterate_domain_ranges(db,
+				ctx->domsid,
+				idmap_autorid_delete_domain_ranges_visitor,
+				&visitor_ctx,
+				&count);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	ctx->count = count;
+
+	return NT_STATUS_OK;
+}
+
+NTSTATUS idmap_autorid_delete_domain_ranges(struct db_context *db,
+					    const char *domsid,
+					    bool force,
+					    int *count)
+{
+	NTSTATUS status;
+	struct idmap_autorid_delete_domain_ranges_ctx ctx;
+
+	ZERO_STRUCT(ctx);
+	ctx.domsid = domsid;
+	ctx.force = force;
+
+	status = dbwrap_trans_do(db, idmap_autorid_delete_domain_ranges_action,
+				 &ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	*count = ctx.count;
+
+	return NT_STATUS_OK;
+}
-- 
1.7.9.5


From b131b5338173929add7d608f6b450a871c5edcf2 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 18 Sep 2013 03:19:58 +0200
Subject: [PATCH 57/57] net: implement "net idmap delete ranges"

Inspired by a patch by Atul Kulkarni <atul.kulkarni at in.ibm.com>.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/utils/net_idmap.c |   65 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c
index c436c6a..c480b1b 100644
--- a/source3/utils/net_idmap.c
+++ b/source3/utils/net_idmap.c
@@ -713,6 +713,63 @@ done:
 	return ret;
 }
 
+static void net_idmap_autorid_delete_ranges_usage(void)
+{
+	d_printf("%s\n%s",
+		 _("Usage:"),
+		 _("net idmap delete ranges [-f] [--db=<TDB>] <SID>)\n"
+		   "  Delete all domain range mappings for a given domain.\n"
+		   "    -f\tforce\n"
+		   "    TDB\tidmap database\n"
+		   "    SID\t\tSID of the domain\n"));
+}
+
+static int net_idmap_autorid_delete_ranges(struct net_context *c, int argc,
+					   const char **argv)
+{
+	int ret = -1;
+	struct db_context *db = NULL;
+	NTSTATUS status;
+	fstring domsid;
+	TALLOC_CTX *mem_ctx = NULL;
+	bool force = (c->opt_force != 0);
+	int count = 0;
+
+	if (c->display_usage) {
+		net_idmap_autorid_delete_ranges_usage();
+		return 0;
+	}
+
+	if (argc != 1) {
+		net_idmap_autorid_delete_ranges_usage();
+		return -1;
+	}
+
+	fstrcpy(domsid, argv[0]);
+
+	mem_ctx = talloc_stackframe();
+	if (!net_idmap_opendb_autorid(mem_ctx, c, false, &db)) {
+		goto done;
+	}
+
+	status = idmap_autorid_delete_domain_ranges(db, domsid, force, &count);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "%s %s: %s\n",
+			  _("Failed to delete domain range mappings for domain"),
+			  domsid,
+			  nt_errstr(status));
+		goto done;
+	}
+
+	d_printf(_("deleted %d domain mappings\n"), count);
+
+	ret = 0;
+
+done:
+	talloc_free(mem_ctx);
+	return ret;
+}
+
 static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
 {
 	struct functable func[] = {
@@ -732,6 +789,14 @@ static int net_idmap_delete(struct net_context *c, int argc, const char **argv)
 			N_("net idmap delete range <RANGE>|(<SID>[ <INDEX>])\n"
 			   "  Delete a domain range mapping")
 		},
+		{
+			"ranges",
+			net_idmap_autorid_delete_ranges,
+			NET_TRANSPORT_LOCAL,
+			N_("Delete all domain range mapping for a given domain"),
+			N_("net idmap delete ranges <SID>\n"
+			   "  Delete a domain range mapping")
+		},
 		{NULL, NULL, 0, NULL, NULL}
 	};
 
-- 
1.7.9.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 215 bytes
Desc: Digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20130924/8fb1431a/attachment-0001.pgp>


More information about the samba-technical mailing list