1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-08 04:58:40 +03:00

idmap: Initialize all idmap domains at startup

So far we have initialized idmap domains on demand indexed by name.
For sid2xid this works okay, because we could do lookupsids before
and thus get the name. For xid2sid this is more problematic. We
have to rely on enumtrustdoms to work completely, and we have to
look at the list of winbind domains in the parent to get the domain
name. Relying on domain->have_idmap_config is not particularly nice.

This patch re-works initialization of idmap domains by scanning all
parametric parameters, scanning for :backend configuration settings.
This way we get a complete list of :range definitions. This means
we can rely on the idmap domain array to be complete. This in turn
means we can live without the domain name to find a domain, we can
do a range search by uid or gid.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Bug: https://bugzilla.samba.org/show_bug.cgi?id=11464
(cherry picked from commit ef0c91195533d95ba4fb7947ff5f69c20aa677b8)
This commit is contained in:
Volker Lendecke 2015-08-19 17:00:46 +02:00 committed by Stefan Metzmacher
parent 56ac018db8
commit 4fed476226

@ -64,12 +64,22 @@ static struct idmap_domain *passdb_idmap_domain;
static struct idmap_domain **idmap_domains = NULL;
static int num_domains = 0;
static void idmap_init(void)
static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx,
const char *domname);
static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
const char *domainname,
const char *modulename,
bool check_range);
static bool idmap_found_domain_backend(
const char *string, regmatch_t matches[], void *private_data);
static bool idmap_init(void)
{
static bool initialized;
int ret;
if (initialized) {
return;
return true;
}
DEBUG(10, ("idmap_init(): calling static_init_idmap\n"));
@ -77,6 +87,80 @@ static void idmap_init(void)
static_init_idmap;
initialized = true;
if (!pdb_is_responsible_for_everything_else()) {
default_idmap_domain = idmap_init_named_domain(NULL, "*");
if (default_idmap_domain == NULL) {
return false;
}
}
passdb_idmap_domain = idmap_init_domain(
NULL, get_global_sam_name(), "passdb", false);
if (passdb_idmap_domain == NULL) {
TALLOC_FREE(default_idmap_domain);
return false;
}
idmap_domains = talloc_array(NULL, struct idmap_domain *, 0);
if (idmap_domains == NULL) {
TALLOC_FREE(passdb_idmap_domain);
TALLOC_FREE(default_idmap_domain);
return false;
}
ret = lp_wi_scan_global_parametrics(
"idmapconfig\\(.*\\):backend", 2,
idmap_found_domain_backend, NULL);
if (ret != 0) {
DBG_WARNING("wi_scan_global_parametrics returned %d\n", ret);
return false;
}
return true;
}
static bool idmap_found_domain_backend(
const char *string, regmatch_t matches[], void *private_data)
{
if (matches[1].rm_so == -1) {
DBG_WARNING("Found match, but no name??\n");
return false;
}
{
struct idmap_domain *dom, **tmp;
regoff_t len = matches[1].rm_eo - matches[1].rm_so;
char domname[len+1];
memcpy(domname, string + matches[1].rm_so, len);
domname[len] = '\0';
DBG_DEBUG("Found idmap domain \"%s\"\n", domname);
if (strcmp(domname, "*") == 0) {
return false;
}
dom = idmap_init_named_domain(idmap_domains, domname);
if (dom == NULL) {
DBG_NOTICE("Could not init idmap domain %s\n",
domname);
}
tmp = talloc_realloc(idmap_domains, idmap_domains,
struct idmap_domain *, num_domains + 1);
if (tmp == NULL) {
DBG_WARNING("talloc_realloc failed\n");
TALLOC_FREE(dom);
return false;
}
idmap_domains = tmp;
idmap_domains[num_domains] = dom;
num_domains += 1;
}
return false;
}
static struct idmap_methods *get_methods(const char *name)
@ -280,8 +364,12 @@ static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx,
struct idmap_domain *result = NULL;
char *config_option;
const char *backend;
bool ok;
idmap_init();
ok = idmap_init();
if (!ok) {
return NULL;
}
config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
domname);
@ -311,57 +399,6 @@ fail:
return NULL;
}
/**
* Initialize the default domain structure
* @param[in] mem_ctx memory context for the result
* @result The default domain structure
*
* This routine takes the module name from the "idmap backend" parameter,
* passing a possible parameter like ldap:ldap://ldap-url/ to the module.
*/
static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
{
return idmap_init_named_domain(mem_ctx, "*");
}
/**
* Initialize the passdb domain structure
* @param[in] mem_ctx memory context for the result
* @result The default domain structure
*
* No config, passdb has its own configuration.
*/
static struct idmap_domain *idmap_passdb_domain(TALLOC_CTX *mem_ctx)
{
idmap_init();
if (!pdb_is_responsible_for_everything_else()) {
/*
* Always init the default domain, we can't go without one
*/
if (default_idmap_domain == NULL) {
default_idmap_domain = idmap_init_default_domain(NULL);
}
if (default_idmap_domain == NULL) {
return NULL;
}
}
if (passdb_idmap_domain != NULL) {
return passdb_idmap_domain;
}
passdb_idmap_domain = idmap_init_domain(mem_ctx, get_global_sam_name(),
"passdb", false);
if (passdb_idmap_domain == NULL) {
DEBUG(1, ("Could not init passdb idmap domain\n"));
}
return passdb_idmap_domain;
}
/**
* Find a domain struct according to a domain name
* @param[in] domname Domain name to get the config for
@ -379,21 +416,14 @@ static struct idmap_domain *idmap_passdb_domain(TALLOC_CTX *mem_ctx)
static struct idmap_domain *idmap_find_domain(const char *domname)
{
struct idmap_domain *result;
bool ok;
int i;
DEBUG(10, ("idmap_find_domain called for domain '%s'\n",
domname?domname:"NULL"));
idmap_init();
/*
* Always init the default domain, we can't go without one
*/
if (default_idmap_domain == NULL) {
default_idmap_domain = idmap_init_default_domain(NULL);
}
if (default_idmap_domain == NULL) {
ok = idmap_init();
if (!ok) {
return NULL;
}
@ -407,38 +437,21 @@ static struct idmap_domain *idmap_find_domain(const char *domname)
}
}
if (idmap_domains == NULL) {
/*
* talloc context for all idmap domains
*/
idmap_domains = talloc_array(NULL, struct idmap_domain *, 1);
}
if (idmap_domains == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
result = idmap_init_named_domain(idmap_domains, domname);
if (result == NULL) {
/*
* Could not init that domain -- try the default one
*/
return default_idmap_domain;
}
ADD_TO_ARRAY(idmap_domains, struct idmap_domain *, result,
&idmap_domains, &num_domains);
return result;
return default_idmap_domain;
}
struct idmap_domain *idmap_find_domain_with_sid(const char *domname,
const struct dom_sid *sid)
{
idmap_init();
bool ok;
ok = idmap_init();
if (!ok) {
return NULL;
}
if (sid_check_is_for_passdb(sid)) {
return idmap_passdb_domain(NULL);
return passdb_idmap_domain;
}
return idmap_find_domain(domname);
@ -493,6 +506,12 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
{
struct idmap_domain *dom;
struct id_map *maps[2];
bool ok;
ok = idmap_init();
if (!ok) {
return NT_STATUS_NONE_MAPPED;
}
DEBUG(10, ("idmap_backend_unixid_to_sid: domain = '%s', xid = %d "
"(type %d)\n",
@ -505,7 +524,7 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
* Always give passdb a chance first
*/
dom = idmap_passdb_domain(NULL);
dom = passdb_idmap_domain;
if ((dom != NULL)
&& NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))
&& id->status == ID_MAPPED) {