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:
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user