1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

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@in.ibm.com>

Signed-off-by: Michael Adam <obnox@samba.org>
Signed-off-by: Atul Kulkarni <atul.kulkarni@in.ibm.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
Michael Adam 2013-08-30 18:49:28 +05:30
parent 69dbc1577b
commit 6e08f5a792

View File

@ -24,6 +24,7 @@
*/
#include "idmap_autorid_tdb.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)
{
NTSTATUS ret;
uint32_t rangenum, hwm;
char *numstr;
struct idmap_autorid_addrange_ctx *ctx;
uint32_t requested_rangenum, stored_rangenum;
struct autorid_range_config *range;
bool acquire;
NTSTATUS ret;
uint32_t hwm;
char *numstr;
struct autorid_global_config *globalcfg;
fstring keystr;
uint32_t increment;
range = (struct autorid_range_config *)private_data;
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;
}
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 "