From f80f43c772e8c5504111dd4274eb928e61fa56ed Mon Sep 17 00:00:00 2001 From: Atul Kulkarni Date: Wed, 28 Aug 2013 13:19:27 +0530 Subject: idmap_autorid: extract common code to separate file This is in preparation of adding "net idmap autorid" functionality. Pair-Programmed-With: Michael Adam Signed-off-by: Atul Kulkarni Signed-off-by: Michael Adam Reviewed-by: Volker Lendecke --- source3/winbindd/idmap_autorid.c | 278 +---------------------------------- source3/winbindd/idmap_autorid_tdb.c | 276 ++++++++++++++++++++++++++++++++++ source3/winbindd/wscript_build | 6 +- 3 files changed, 282 insertions(+), 278 deletions(-) create mode 100644 source3/winbindd/idmap_autorid_tdb.c (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index 72bd384662..d6fd0b9c56 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_tdb.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 0000000000..fbb8a7cff6 --- /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 . + * + */ + +#include "idmap_autorid_tdb.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 b318bec608..ea1131c8be 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'), -- cgit