From 28aa4bff8d6be031c6089fe5c7ab010f1cc48340 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Sep 2007 12:03:58 +0000 Subject: r25154: move winbindd code into winbindd/ metze (This used to be commit 3ac7566ae14c48ff9b0f6b232e0ec4b2f73df558) --- source3/winbindd/idmap.c | 1562 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1562 insertions(+) create mode 100644 source3/winbindd/idmap.c (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c new file mode 100644 index 0000000000..2c7acc185c --- /dev/null +++ b/source3/winbindd/idmap.c @@ -0,0 +1,1562 @@ +/* + Unix SMB/CIFS implementation. + ID Mapping + Copyright (C) Tim Potter 2000 + Copyright (C) Jim McDonough 2003 + Copyright (C) Simo Sorce 2003-2007 + Copyright (C) Jeremy Allison 2006 + + 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 "includes.h" +#include "winbindd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +static_decl_idmap; + +struct idmap_backend { + const char *name; + struct idmap_methods *methods; + struct idmap_backend *prev, *next; +}; + +struct idmap_alloc_backend { + const char *name; + struct idmap_alloc_methods *methods; + struct idmap_alloc_backend *prev, *next; +}; + +struct idmap_cache_ctx; + +struct idmap_alloc_context { + const char *params; + struct idmap_alloc_methods *methods; + BOOL initialized; +}; + +static TALLOC_CTX *idmap_ctx = NULL; +static struct idmap_cache_ctx *idmap_cache; + +static struct idmap_backend *backends = NULL; +static struct idmap_domain **idmap_domains = NULL; +static int num_domains = 0; +static int pdb_dom_num = -1; +static int def_dom_num = -1; + +static struct idmap_alloc_backend *alloc_backends = NULL; +static struct idmap_alloc_context *idmap_alloc_ctx = NULL; + +#define IDMAP_CHECK_RET(ret) do { \ + if ( ! NT_STATUS_IS_OK(ret)) { \ + DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \ + goto done; \ + } } while(0) +#define IDMAP_REPORT_RET(ret) do { \ + if ( ! NT_STATUS_IS_OK(ret)) { \ + DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \ + } } while(0) +#define IDMAP_CHECK_ALLOC(mem) do { \ + if (!mem) { \ + DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; \ + goto done; \ + } } while(0) + +static struct idmap_methods *get_methods(struct idmap_backend *be, + const char *name) +{ + struct idmap_backend *b; + + for (b = be; b; b = b->next) { + if (strequal(b->name, name)) { + return b->methods; + } + } + + return NULL; +} + +static struct idmap_alloc_methods *get_alloc_methods( + struct idmap_alloc_backend *be, + const char *name) +{ + struct idmap_alloc_backend *b; + + for (b = be; b; b = b->next) { + if (strequal(b->name, name)) { + return b->methods; + } + } + + return NULL; +} + +BOOL idmap_is_offline(void) +{ + return ( lp_winbind_offline_logon() && + get_global_winbindd_state_offline() ); +} + +/********************************************************************** + Allow a module to register itself as a method. +**********************************************************************/ + +NTSTATUS smb_register_idmap(int version, const char *name, + struct idmap_methods *methods) +{ + struct idmap_methods *test; + struct idmap_backend *entry; + + if (!idmap_ctx) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + if ((version != SMB_IDMAP_INTERFACE_VERSION)) { + DEBUG(0, ("Failed to register idmap module.\n" + "The module was compiled against " + "SMB_IDMAP_INTERFACE_VERSION %d,\n" + "current SMB_IDMAP_INTERFACE_VERSION is %d.\n" + "Please recompile against the current version " + "of samba!\n", + version, SMB_IDMAP_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!name || !name[0] || !methods) { + DEBUG(0,("Called with NULL pointer or empty name!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + test = get_methods(backends, name); + if (test) { + DEBUG(0,("Idmap module %s already registered!\n", name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + entry = talloc(idmap_ctx, struct idmap_backend); + if ( ! entry) { + DEBUG(0,("Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + entry->name = talloc_strdup(idmap_ctx, name); + if ( ! entry->name) { + DEBUG(0,("Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + entry->methods = methods; + + DLIST_ADD(backends, entry); + DEBUG(5, ("Successfully added idmap backend '%s'\n", name)); + return NT_STATUS_OK; +} + +/********************************************************************** + Allow a module to register itself as a method. +**********************************************************************/ + +NTSTATUS smb_register_idmap_alloc(int version, const char *name, + struct idmap_alloc_methods *methods) +{ + struct idmap_alloc_methods *test; + struct idmap_alloc_backend *entry; + + if (!idmap_ctx) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + if ((version != SMB_IDMAP_INTERFACE_VERSION)) { + DEBUG(0, ("Failed to register idmap alloc module.\n" + "The module was compiled against " + "SMB_IDMAP_INTERFACE_VERSION %d,\n" + "current SMB_IDMAP_INTERFACE_VERSION is %d.\n" + "Please recompile against the current version " + "of samba!\n", + version, SMB_IDMAP_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!name || !name[0] || !methods) { + DEBUG(0,("Called with NULL pointer or empty name!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + test = get_alloc_methods(alloc_backends, name); + if (test) { + DEBUG(0,("idmap_alloc module %s already registered!\n", name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + entry = talloc(idmap_ctx, struct idmap_alloc_backend); + if ( ! entry) { + DEBUG(0,("Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + entry->name = talloc_strdup(idmap_ctx, name); + if ( ! entry->name) { + DEBUG(0,("Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + entry->methods = methods; + + DLIST_ADD(alloc_backends, entry); + DEBUG(5, ("Successfully added idmap alloc backend '%s'\n", name)); + return NT_STATUS_OK; +} + +static int close_domain_destructor(struct idmap_domain *dom) +{ + NTSTATUS ret; + + ret = dom->methods->close_fn(dom); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(3, ("Failed to close idmap domain [%s]!\n", dom->name)); + } + + return 0; +} + +/************************************************************************** + Shutdown. +**************************************************************************/ + +NTSTATUS idmap_close(void) +{ + /* close the alloc backend first before freeing idmap_ctx */ + if (idmap_alloc_ctx) { + idmap_alloc_ctx->methods->close_fn(); + idmap_alloc_ctx->methods = NULL; + } + alloc_backends = NULL; + + /* this talloc_free call will fire the talloc destructors + * that will free all active backends resources */ + TALLOC_FREE(idmap_ctx); + idmap_cache = NULL; + idmap_domains = NULL; + backends = NULL; + + return NT_STATUS_OK; +} + +/********************************************************************** + Initialise idmap cache and a remote backend (if configured). +**********************************************************************/ + +static const char *idmap_default_domain[] = { "default domain", NULL }; + +/**************************************************************************** + ****************************************************************************/ + +NTSTATUS idmap_init_cache(void) +{ + /* Always initialize the cache. We'll have to delay initialization + of backends if we are offline */ + + if ( idmap_ctx ) { + return NT_STATUS_OK; + } + + if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) { + return NT_STATUS_NO_MEMORY; + } + + if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) { + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +/**************************************************************************** + ****************************************************************************/ + +NTSTATUS idmap_init(void) +{ + NTSTATUS ret; + static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL; + struct idmap_domain *dom; + char *compat_backend = NULL; + char *compat_params = NULL; + const char **dom_list = NULL; + char *alloc_backend = NULL; + BOOL default_already_defined = False; + BOOL pri_dom_is_in_list = False; + int compat = 0; + int i; + + ret = idmap_init_cache(); + if (!NT_STATUS_IS_OK(ret)) + return ret; + + if (NT_STATUS_IS_OK(idmap_init_status)) { + return NT_STATUS_OK; + } + + /* We can't reliably call intialization code here unless + we are online. But return NT_STATUS_OK so the upper + level code doesn't abort idmap lookups. */ + + if ( get_global_winbindd_state_offline() ) { + idmap_init_status = NT_STATUS_FILE_IS_OFFLINE; + return NT_STATUS_OK; + } + + static_init_idmap; + + dom_list = lp_idmap_domains(); + + if ( lp_idmap_backend() ) { + const char **compat_list = lp_idmap_backend(); + char *p = NULL; + const char *q = NULL; + + if ( dom_list ) { + DEBUG(0, ("WARNING: idmap backend and idmap domains are" + " mutually exclusive!\n")); + DEBUGADD(0,("idmap backend option will be IGNORED!\n")); + } else { + compat = 1; + + compat_backend = talloc_strdup(idmap_ctx, *compat_list); + if (compat_backend == NULL ) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + + /* strip any leading idmap_ prefix of */ + if (strncmp(*compat_list, "idmap_", 6) == 0 ) { + q = *compat_list += 6; + DEBUG(0, ("WARNING: idmap backend uses obsolete" + " and deprecated 'idmap_' prefix.\n" + "Please replace 'idmap_%s' by '%s' in" + " %s\n", q, q, dyn_CONFIGFILE)); + compat_backend = talloc_strdup(idmap_ctx, q); + } else { + compat_backend = talloc_strdup(idmap_ctx, + *compat_list); + } + + /* separate the backend and module arguements */ + if ((p = strchr(compat_backend, ':')) != NULL) { + *p = '\0'; + compat_params = p + 1; + } + } + } else if ( !dom_list ) { + /* Back compatible: without idmap domains and explicit + idmap backend. Taking default idmap backend: tdb */ + + compat = 1; + compat_backend = talloc_strdup( idmap_ctx, "tdb"); + compat_params = compat_backend; + } + + if ( ! dom_list) { + dom_list = idmap_default_domain; + } + + /*************************** + * initialize idmap domains + */ + DEBUG(1, ("Initializing idmap domains\n")); + + for (i = 0; dom_list[i]; i++) { + const char *parm_backend; + char *config_option; + + /* ignore BUILTIN and local MACHINE domains */ + if (strequal(dom_list[i], "BUILTIN") + || strequal(dom_list[i], get_global_sam_name())) + { + DEBUG(0,("idmap_init: Ignoring invalid domain %s\n", + dom_list[i])); + continue; + } + + if (strequal(dom_list[i], lp_workgroup())) { + pri_dom_is_in_list = True; + } + /* init domain */ + + dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); + IDMAP_CHECK_ALLOC(dom); + + dom->name = talloc_strdup(dom, dom_list[i]); + IDMAP_CHECK_ALLOC(dom->name); + + config_option = talloc_asprintf(dom, "idmap config %s", + dom->name); + IDMAP_CHECK_ALLOC(config_option); + + /* default or specific ? */ + + dom->default_domain = lp_parm_bool(-1, config_option, + "default", False); + + if (dom->default_domain || + strequal(dom_list[i], idmap_default_domain[0])) { + + /* make sure this is set even when we match + * idmap_default_domain[0] */ + dom->default_domain = True; + + if (default_already_defined) { + DEBUG(1, ("ERROR: Multiple domains defined as" + " default!\n")); + ret = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + default_already_defined = True; + + } + + dom->readonly = lp_parm_bool(-1, config_option, + "readonly", False); + + /* find associated backend (default: tdb) */ + if (compat) { + parm_backend = talloc_strdup(idmap_ctx, compat_backend); + } else { + parm_backend = talloc_strdup(idmap_ctx, + lp_parm_const_string( + -1, config_option, + "backend", "tdb")); + } + IDMAP_CHECK_ALLOC(parm_backend); + + /* get the backend methods for this domain */ + dom->methods = get_methods(backends, parm_backend); + + if ( ! dom->methods) { + ret = smb_probe_module("idmap", parm_backend); + if (NT_STATUS_IS_OK(ret)) { + dom->methods = get_methods(backends, + parm_backend); + } + } + if ( ! dom->methods) { + DEBUG(0, ("ERROR: Could not get methods for " + "backend %s\n", parm_backend)); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* check the set_mapping function exists otherwise mark the + * module as readonly */ + if ( ! dom->methods->set_mapping) { + DEBUG(5, ("Forcing to readonly, as this module can't" + " store arbitrary mappings.\n")); + dom->readonly = True; + } + + /* now that we have methods, + * set the destructor for this domain */ + talloc_set_destructor(dom, close_domain_destructor); + + if (compat_params) { + dom->params = talloc_strdup(dom, compat_params); + IDMAP_CHECK_ALLOC(dom->params); + } else { + dom->params = NULL; + } + + /* Finally instance a backend copy for this domain */ + ret = dom->methods->init(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Initialization failed for backend " + "%s (domain %s), deferred!\n", + parm_backend, dom->name)); + } + idmap_domains = talloc_realloc(idmap_ctx, idmap_domains, + struct idmap_domain *, i+1); + if ( ! idmap_domains) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + idmap_domains[i] = dom; + + /* save default domain position for future uses */ + if (dom->default_domain) { + def_dom_num = i; + } + + DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n", + dom->name, parm_backend, + dom->default_domain?"":"not ", + dom->readonly?"":"not ")); + + talloc_free(config_option); + } + + /* save the number of domains we have */ + num_domains = i; + + /* automatically add idmap_nss backend if needed */ + if ((lp_server_role() == ROLE_DOMAIN_MEMBER) && + ( ! pri_dom_is_in_list) && + lp_winbind_trusted_domains_only()) { + + dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); + IDMAP_CHECK_ALLOC(dom); + + dom->name = talloc_strdup(dom, lp_workgroup()); + IDMAP_CHECK_ALLOC(dom->name); + + dom->default_domain = False; + dom->readonly = True; + + /* get the backend methods for passdb */ + dom->methods = get_methods(backends, "nss"); + + /* (the nss module is always statically linked) */ + if ( ! dom->methods) { + DEBUG(0, ("ERROR: No methods for idmap_nss ?!\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* now that we have methods, + * set the destructor for this domain */ + talloc_set_destructor(dom, close_domain_destructor); + + if (compat_params) { + dom->params = talloc_strdup(dom, compat_params); + IDMAP_CHECK_ALLOC(dom->params); + } else { + dom->params = NULL; + } + + /* Finally instance a backend copy for this domain */ + ret = dom->methods->init(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Init. failed for idmap_nss ?!\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + idmap_domains = talloc_realloc(idmap_ctx, + idmap_domains, + struct idmap_domain *, + num_domains+1); + if ( ! idmap_domains) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + idmap_domains[num_domains] = dom; + + DEBUG(10, ("Domain %s - Backend nss - not default - readonly\n", + dom->name )); + + num_domains++; + } + + /**** automatically add idmap_passdb backend ****/ + dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); + IDMAP_CHECK_ALLOC(dom); + + dom->name = talloc_strdup(dom, get_global_sam_name()); + IDMAP_CHECK_ALLOC(dom->name); + + dom->default_domain = False; + dom->readonly = True; + + /* get the backend methods for passdb */ + dom->methods = get_methods(backends, "passdb"); + + /* (the passdb module is always statically linked) */ + if ( ! dom->methods) { + DEBUG(0, ("ERROR: No methods for idmap_passdb ?!\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* now that we have methods, set the destructor for this domain */ + talloc_set_destructor(dom, close_domain_destructor); + + if (compat_params) { + dom->params = talloc_strdup(dom, compat_params); + IDMAP_CHECK_ALLOC(dom->params); + } else { + dom->params = NULL; + } + + /* Finally instance a backend copy for this domain */ + ret = dom->methods->init(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Init. failed for idmap_passdb ?!\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + idmap_domains = talloc_realloc(idmap_ctx, + idmap_domains, + struct idmap_domain *, + num_domains+1); + if ( ! idmap_domains) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + idmap_domains[num_domains] = dom; + + /* needed to handle special BUILTIN and wellknown SIDs cases */ + pdb_dom_num = num_domains; + + DEBUG(10, ("Domain %s - Backend passdb - not default - readonly\n", + dom->name)); + + num_domains++; + /**** finished adding idmap_passdb backend ****/ + + /* sort domains so that the default is the last one */ + /* don't sort if no default domain defined */ + if (def_dom_num != -1 && def_dom_num != num_domains-1) { + /* default is not last, move it */ + struct idmap_domain *tmp; + + if (pdb_dom_num > def_dom_num) { + pdb_dom_num --; + + } else if (pdb_dom_num == def_dom_num) { /* ?? */ + pdb_dom_num = num_domains - 1; + } + + tmp = idmap_domains[def_dom_num]; + + for (i = def_dom_num; i < num_domains-1; i++) { + idmap_domains[i] = idmap_domains[i+1]; + } + idmap_domains[i] = tmp; + def_dom_num = i; + } + + + /* Initialize alloc module */ + + DEBUG(3, ("Initializing idmap alloc module\n")); + + alloc_backend = NULL; + if (compat) { + alloc_backend = talloc_strdup(idmap_ctx, compat_backend); + } else { + char *ab = lp_idmap_alloc_backend(); + + if (ab && (ab[0] != '\0')) { + alloc_backend = talloc_strdup(idmap_ctx, + lp_idmap_alloc_backend()); + } + } + + if ( alloc_backend ) { + + idmap_alloc_ctx = TALLOC_ZERO_P(idmap_ctx, + struct idmap_alloc_context); + IDMAP_CHECK_ALLOC(idmap_alloc_ctx); + + idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, + alloc_backend); + if ( ! idmap_alloc_ctx->methods) { + ret = smb_probe_module("idmap", alloc_backend); + if (NT_STATUS_IS_OK(ret)) { + idmap_alloc_ctx->methods = + get_alloc_methods(alloc_backends, + alloc_backend); + } + } + if (idmap_alloc_ctx->methods) { + + if (compat_params) { + idmap_alloc_ctx->params = + talloc_strdup(idmap_alloc_ctx, + compat_params); + IDMAP_CHECK_ALLOC(idmap_alloc_ctx->params); + } else { + idmap_alloc_ctx->params = NULL; + } + + ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Initialization failed for " + "alloc backend %s, deferred!\n", + alloc_backend)); + } else { + idmap_alloc_ctx->initialized = True; + } + } else { + DEBUG(2, ("idmap_init: Unable to get methods for " + "alloc backend %s\n", + alloc_backend)); + /* certain compat backends are just readonly */ + if ( compat ) { + TALLOC_FREE(idmap_alloc_ctx); + ret = NT_STATUS_OK; + } else { + ret = NT_STATUS_UNSUCCESSFUL; + } + } + } + + /* cleanpu temporary strings */ + TALLOC_FREE( compat_backend ); + + idmap_init_status = NT_STATUS_OK; + + return ret; + +done: + DEBUG(0, ("Aborting IDMAP Initialization ...\n")); + idmap_close(); + + return ret; +} + +static NTSTATUS idmap_alloc_init(void) +{ + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_init())) { + return ret; + } + + if ( ! idmap_alloc_ctx) { + return NT_STATUS_NOT_SUPPORTED; + } + + if ( ! idmap_alloc_ctx->initialized) { + ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Initialization failed for alloc " + "backend, deferred!\n")); + return ret; + } else { + idmap_alloc_ctx->initialized = True; + } + } + + return NT_STATUS_OK; +} + +/************************************************************************** + idmap allocator interface functions +**************************************************************************/ + +NTSTATUS idmap_allocate_uid(struct unixid *id) +{ + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + return ret; + } + + id->type = ID_TYPE_UID; + return idmap_alloc_ctx->methods->allocate_id(id); +} + +NTSTATUS idmap_allocate_gid(struct unixid *id) +{ + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + return ret; + } + + id->type = ID_TYPE_GID; + return idmap_alloc_ctx->methods->allocate_id(id); +} + +NTSTATUS idmap_set_uid_hwm(struct unixid *id) +{ + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + return ret; + } + + id->type = ID_TYPE_UID; + return idmap_alloc_ctx->methods->set_id_hwm(id); +} + +NTSTATUS idmap_set_gid_hwm(struct unixid *id) +{ + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + return ret; + } + + id->type = ID_TYPE_GID; + return idmap_alloc_ctx->methods->set_id_hwm(id); +} + +/****************************************************************************** + Lookup an idmap_domain give a full user or group SID + ******************************************************************************/ + +static struct idmap_domain* find_idmap_domain_from_sid( DOM_SID *account_sid ) +{ + DOM_SID domain_sid; + uint32 rid; + struct winbindd_domain *domain = NULL; + int i; + + /* 1. Handle BUILTIN or Special SIDs and prevent them from + falling into the default domain space (if we have a + configured passdb backend. */ + + if ( (pdb_dom_num != -1) && + (sid_check_is_in_builtin(account_sid) || + sid_check_is_in_wellknown_domain(account_sid) || + sid_check_is_in_unix_groups(account_sid) || + sid_check_is_in_unix_users(account_sid)) ) + { + return idmap_domains[pdb_dom_num]; + } + + /* 2. Lookup the winbindd_domain from the account_sid */ + + sid_copy( &domain_sid, account_sid ); + sid_split_rid( &domain_sid, &rid ); + domain = find_domain_from_sid_noinit( &domain_sid ); + + for (i = 0; domain && i < num_domains; i++) { + if ( strequal( idmap_domains[i]->name, domain->name ) ) { + return idmap_domains[i]; + } + } + + /* 3. Fall back to the default domain */ + + if ( def_dom_num != -1 ) { + return idmap_domains[def_dom_num]; + } + + return NULL; +} + +/****************************************************************************** + Lookup an index given an idmap_domain pointer + ******************************************************************************/ + +static uint32 find_idmap_domain_index( struct idmap_domain *id_domain) +{ + int i; + + for (i = 0; i < num_domains; i++) { + if ( idmap_domains[i] == id_domain ) + return i; + } + + return -1; +} + + +/********************************************************* + Check if creating a mapping is permitted for the domain +*********************************************************/ + +static NTSTATUS idmap_can_map(const struct id_map *map, + struct idmap_domain **ret_dom) +{ + struct idmap_domain *dom; + + /* Check we do not create mappings for our own local domain, + * or BUILTIN or special SIDs */ + if ((sid_compare_domain(map->sid, get_global_sam_sid()) == 0) || + sid_check_is_in_builtin(map->sid) || + sid_check_is_in_wellknown_domain(map->sid) || + sid_check_is_in_unix_users(map->sid) || + sid_check_is_in_unix_groups(map->sid) ) + { + DEBUG(10, ("We are not supposed to create mappings for our own " + "domains (local, builtin, specials)\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + /* Special check for trusted domain only = Yes */ + if (lp_winbind_trusted_domains_only()) { + struct winbindd_domain *wdom = find_our_domain(); + if (wdom && (sid_compare_domain(map->sid, &wdom->sid) == 0)) { + DEBUG(10, ("We are not supposed to create mappings for " + "our primary domain when is True\n")); + DEBUGADD(10, ("Leave [%s] unmapped\n", + sid_string_static(map->sid))); + return NT_STATUS_UNSUCCESSFUL; + } + } + + if ( (dom = find_idmap_domain_from_sid( map->sid )) == NULL ) { + /* huh, couldn't find a suitable domain, + * let's just leave it unmapped */ + DEBUG(10, ("Could not find idmap backend for SID %s", + sid_string_static(map->sid))); + return NT_STATUS_NO_SUCH_DOMAIN; + } + + if (dom->readonly) { + /* ouch the domain is read only, + * let's just leave it unmapped */ + DEBUG(10, ("idmap backend for SID %s is READONLY!\n", + sid_string_static(map->sid))); + return NT_STATUS_UNSUCCESSFUL; + } + + *ret_dom = dom; + return NT_STATUS_OK; +} + +static NTSTATUS idmap_new_mapping(TALLOC_CTX *ctx, struct id_map *map) +{ + NTSTATUS ret; + struct idmap_domain *dom; + + /* If we are offline we cannot lookup SIDs, deny mapping */ + if (idmap_is_offline()) { + return NT_STATUS_FILE_IS_OFFLINE; + } + + ret = idmap_can_map(map, &dom); + if ( ! NT_STATUS_IS_OK(ret)) { + return NT_STATUS_NONE_MAPPED; + } + + /* check if this is a valid SID and then map it */ + switch (map->xid.type) { + case ID_TYPE_UID: + ret = idmap_allocate_uid(&map->xid); + if ( ! NT_STATUS_IS_OK(ret)) { + /* can't allocate id, let's just leave it unmapped */ + DEBUG(2, ("uid allocation failed! " + "Can't create mapping\n")); + return NT_STATUS_NONE_MAPPED; + } + break; + case ID_TYPE_GID: + ret = idmap_allocate_gid(&map->xid); + if ( ! NT_STATUS_IS_OK(ret)) { + /* can't allocate id, let's just leave it unmapped */ + DEBUG(2, ("gid allocation failed! " + "Can't create mapping\n")); + return NT_STATUS_NONE_MAPPED; + } + break; + default: + /* invalid sid, let's just leave it unmapped */ + DEBUG(3,("idmap_new_mapping: Refusing to create a " + "mapping for an unspecified ID type.\n")); + return NT_STATUS_NONE_MAPPED; + } + + /* ok, got a new id, let's set a mapping */ + map->status = ID_MAPPED; + + DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", + sid_string_static(map->sid), + (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", + (unsigned long)map->xid.id)); + ret = dom->methods->set_mapping(dom, map); + + if ( ! NT_STATUS_IS_OK(ret)) { + /* something wrong here :-( */ + DEBUG(2, ("Failed to commit mapping\n!")); + + /* TODO: would it make sense to have an "unalloc_id function?" */ + + return NT_STATUS_NONE_MAPPED; + } + + return NT_STATUS_OK; +} + +static NTSTATUS idmap_backends_set_mapping(const struct id_map *map) +{ + struct idmap_domain *dom; + NTSTATUS ret; + + DEBUG(10, ("Setting mapping %s <-> %s %lu\n", + sid_string_static(map->sid), + (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", + (unsigned long)map->xid.id)); + + ret = idmap_can_map(map, &dom); + if ( ! NT_STATUS_IS_OK(ret)) { + return ret; + } + + DEBUG(10,("set_mapping for domain %s\n", dom->name )); + + return dom->methods->set_mapping(dom, map); +} + +static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids) +{ + struct idmap_domain *dom; + struct id_map **unmapped; + struct id_map **_ids; + TALLOC_CTX *ctx; + NTSTATUS ret; + int i, u, n; + + if (!ids || !*ids) { + DEBUG(1, ("Invalid list of maps\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + ctx = talloc_named_const(NULL, 0, "idmap_backends_unixids_to_sids ctx"); + if ( ! ctx) { + DEBUG(0, ("Out of memory!\n")); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10, ("Query backends to map ids->sids\n")); + + /* start from the default (the last one) and then if there are still + * unmapped entries cycle through the others */ + + _ids = ids; + + unmapped = NULL; + for (n = num_domains-1; n >= 0; n--) { /* cycle backwards */ + + dom = idmap_domains[n]; + + DEBUG(10, ("Query sids from domain %s\n", dom->name)); + + ret = dom->methods->unixids_to_sids(dom, _ids); + IDMAP_REPORT_RET(ret); + + unmapped = NULL; + + for (i = 0, u = 0; _ids[i]; i++) { + if (_ids[i]->status != ID_MAPPED) { + unmapped = talloc_realloc(ctx, unmapped, + struct id_map *, u + 2); + IDMAP_CHECK_ALLOC(unmapped); + unmapped[u] = _ids[i]; + u++; + } + } + if (unmapped) { + /* terminate the unmapped list */ + unmapped[u] = NULL; + } else { /* no more entries, get out */ + break; + } + + _ids = unmapped; + + } + + if (unmapped) { + /* there are still unmapped ids, + * map them to the unix users/groups domains */ + /* except for expired entries, + * these will be returned as valid (offline mode) */ + for (i = 0; unmapped[i]; i++) { + if (unmapped[i]->status == ID_EXPIRED) continue; + switch (unmapped[i]->xid.type) { + case ID_TYPE_UID: + uid_to_unix_users_sid( + (uid_t)unmapped[i]->xid.id, + unmapped[i]->sid); + unmapped[i]->status = ID_MAPPED; + break; + case ID_TYPE_GID: + gid_to_unix_groups_sid( + (gid_t)unmapped[i]->xid.id, + unmapped[i]->sid); + unmapped[i]->status = ID_MAPPED; + break; + default: /* what?! */ + unmapped[i]->status = ID_UNKNOWN; + break; + } + } + } + + ret = NT_STATUS_OK; + +done: + talloc_free(ctx); + return ret; +} + +static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) +{ + struct id_map ***dom_ids; + struct idmap_domain *dom; + TALLOC_CTX *ctx; + NTSTATUS ret; + int i, *counters; + + if ( (ctx = talloc_named_const(NULL, 0, "be_sids_to_ids")) == NULL ) { + DEBUG(1, ("failed to allocate talloc context, OOM?\n")); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10, ("Query backends to map sids->ids\n")); + + /* split list per domain */ + if (num_domains == 0) { + DEBUG(1, ("No domains available?\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + dom_ids = TALLOC_ZERO_ARRAY(ctx, struct id_map **, num_domains); + IDMAP_CHECK_ALLOC(dom_ids); + counters = TALLOC_ZERO_ARRAY(ctx, int, num_domains); + IDMAP_CHECK_ALLOC(counters); + + /* partition the requests by domain */ + + for (i = 0; ids[i]; i++) { + uint32 idx; + + if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) { + /* no available idmap_domain. Move on */ + continue; + } + + DEBUG(10,("SID %s is being handled by %s\n", + sid_string_static(ids[i]->sid), + dom ? dom->name : "none" )); + + idx = find_idmap_domain_index( dom ); + SMB_ASSERT( idx != -1 ); + + dom_ids[idx] = talloc_realloc(ctx, dom_ids[idx], + struct id_map *, + counters[idx] + 2); + IDMAP_CHECK_ALLOC(dom_ids[idx]); + + dom_ids[idx][counters[idx]] = ids[i]; + counters[idx]++; + dom_ids[idx][counters[idx]] = NULL; + } + + /* All the ids have been dispatched in the right queues. + Let's cycle through the filled ones */ + + for (i = 0; i < num_domains; i++) { + if (dom_ids[i]) { + dom = idmap_domains[i]; + DEBUG(10, ("Query ids from domain %s\n", dom->name)); + ret = dom->methods->sids_to_unixids(dom, dom_ids[i]); + IDMAP_REPORT_RET(ret); + } + } + + /* ok all the backends have been contacted at this point */ + /* let's see if we have any unmapped SID left and act accordingly */ + + for (i = 0; ids[i]; i++) { + /* NOTE: this will NOT touch ID_EXPIRED entries that the backend + * was not able to confirm/deny (offline mode) */ + if (ids[i]->status == ID_UNKNOWN || + ids[i]->status == ID_UNMAPPED) { + /* ok this is an unmapped one, see if we can map it */ + ret = idmap_new_mapping(ctx, ids[i]); + if (NT_STATUS_IS_OK(ret)) { + /* successfully mapped */ + ids[i]->status = ID_MAPPED; + } else + if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { + /* could not map it */ + ids[i]->status = ID_UNMAPPED; + } else { + /* Something very bad happened down there + * OR we are offline */ + ids[i]->status = ID_UNKNOWN; + } + } + } + + ret = NT_STATUS_OK; + +done: + talloc_free(ctx); + return ret; +} + +/************************************************************************** + idmap interface functions +**************************************************************************/ + +NTSTATUS idmap_unixids_to_sids(struct id_map **ids) +{ + TALLOC_CTX *ctx; + NTSTATUS ret; + struct id_map **bids; + int i, bi; + int bn = 0; + struct winbindd_domain *our_domain = find_our_domain(); + + if (! NT_STATUS_IS_OK(ret = idmap_init())) { + return ret; + } + + if (!ids || !*ids) { + DEBUG(1, ("Invalid list of maps\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + ctx = talloc_named_const(NULL, 0, "idmap_unixids_to_sids ctx"); + if ( ! ctx) { + DEBUG(1, ("failed to allocate talloc context, OOM?\n")); + return NT_STATUS_NO_MEMORY; + } + + /* no ids to be asked to the backends by default */ + bids = NULL; + bi = 0; + + for (i = 0; ids[i]; i++) { + + if ( ! ids[i]->sid) { + DEBUG(1, ("invalid null SID in id_map array")); + talloc_free(ctx); + return NT_STATUS_INVALID_PARAMETER; + } + + ret = idmap_cache_map_id(idmap_cache, ids[i]); + + if ( ! NT_STATUS_IS_OK(ret)) { + + if ( ! bids) { + /* alloc space for ids to be resolved by + * backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + bn = 10; + } + + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; + + /* check if we need to allocate new space + * on the rids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, + struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + } + + /* make sure the last element is NULL */ + bids[bi] = NULL; + } + } + + /* let's see if there is any id mapping to be retieved + * from the backends */ + if (bi) { + /* Only do query if we are online */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + ret = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } + + ret = idmap_backends_unixids_to_sids(bids); + IDMAP_CHECK_RET(ret); + + /* update the cache */ + for (i = 0; i < bi; i++) { + if (bids[i]->status == ID_MAPPED) { + ret = idmap_cache_set(idmap_cache, bids[i]); + } else if (bids[i]->status == ID_EXPIRED) { + /* the cache returned an expired entry and the + * backend was not able to clear the situation + * (offline). This handles a previous + * NT_STATUS_SYNCHRONIZATION_REQUIRED + * for disconnected mode, */ + bids[i]->status = ID_MAPPED; + } else if (bids[i]->status == ID_UNKNOWN) { + /* something bad here. We were not able to + * handle this for some reason, mark it as + * unmapped and hope next time things will + * settle down. */ + bids[i]->status = ID_UNMAPPED; + } else { /* unmapped */ + ret = idmap_cache_set_negative_id(idmap_cache, + bids[i]); + } + IDMAP_CHECK_RET(ret); + } + } + + ret = NT_STATUS_OK; +done: + talloc_free(ctx); + return ret; +} + +NTSTATUS idmap_sids_to_unixids(struct id_map **ids) +{ + TALLOC_CTX *ctx; + NTSTATUS ret; + struct id_map **bids; + int i, bi; + int bn = 0; + struct winbindd_domain *our_domain = find_our_domain(); + + if (! NT_STATUS_IS_OK(ret = idmap_init())) { + return ret; + } + + if (!ids || !*ids) { + DEBUG(1, ("Invalid list of maps\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + ctx = talloc_named_const(NULL, 0, "idmap_sids_to_unixids ctx"); + if ( ! ctx) { + DEBUG(1, ("failed to allocate talloc context, OOM?\n")); + return NT_STATUS_NO_MEMORY; + } + + /* no ids to be asked to the backends by default */ + bids = NULL; + bi = 0; + + for (i = 0; ids[i]; i++) { + + if ( ! ids[i]->sid) { + DEBUG(1, ("invalid null SID in id_map array\n")); + talloc_free(ctx); + return NT_STATUS_INVALID_PARAMETER; + } + + ret = idmap_cache_map_sid(idmap_cache, ids[i]); + + if ( ! NT_STATUS_IS_OK(ret)) { + + if ( ! bids) { + /* alloc space for ids to be resolved + by backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + bn = 10; + } + + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; + + /* check if we need to allocate new space + * on the ids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, + struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + } + + /* make sure the last element is NULL */ + bids[bi] = NULL; + } + } + + /* let's see if there is any id mapping to be retieved + * from the backends */ + if (bids) { + /* Only do query if we are online */ + if ( IS_DOMAIN_OFFLINE(our_domain) ) { + ret = NT_STATUS_FILE_IS_OFFLINE; + goto done; + } + + ret = idmap_backends_sids_to_unixids(bids); + IDMAP_CHECK_RET(ret); + + /* update the cache */ + for (i = 0; bids[i]; i++) { + if (bids[i]->status == ID_MAPPED) { + ret = idmap_cache_set(idmap_cache, bids[i]); + } else if (bids[i]->status == ID_EXPIRED) { + /* the cache returned an expired entry and the + * backend was not able to clear the situation + * (offline). This handles a previous + * NT_STATUS_SYNCHRONIZATION_REQUIRED + * for disconnected mode, */ + bids[i]->status = ID_MAPPED; + } else if (bids[i]->status == ID_UNKNOWN) { + /* something bad here. We were not able to + * handle this for some reason, mark it as + * unmapped and hope next time things will + * settle down. */ + bids[i]->status = ID_UNMAPPED; + } else { /* unmapped */ + ret = idmap_cache_set_negative_sid(idmap_cache, + bids[i]); + } + IDMAP_CHECK_RET(ret); + } + } + + ret = NT_STATUS_OK; +done: + talloc_free(ctx); + return ret; +} + +NTSTATUS idmap_set_mapping(const struct id_map *id) +{ + TALLOC_CTX *ctx; + NTSTATUS ret; + + if (! NT_STATUS_IS_OK(ret = idmap_init())) { + return ret; + } + + /* sanity checks */ + if ((id->sid == NULL) || (id->status != ID_MAPPED)) { + DEBUG(1, ("NULL SID or unmapped entry\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* TODO: check uid/gid range ? */ + + ctx = talloc_named_const(NULL, 0, "idmap_set_mapping ctx"); + if ( ! ctx) { + DEBUG(1, ("failed to allocate talloc context, OOM?\n")); + return NT_STATUS_NO_MEMORY; + } + + /* set the new mapping */ + ret = idmap_backends_set_mapping(id); + IDMAP_CHECK_RET(ret); + + /* set the mapping in the cache */ + ret = idmap_cache_set(idmap_cache, id); + IDMAP_CHECK_RET(ret); + +done: + talloc_free(ctx); + return ret; +} + +/************************************************************************** + Dump backend status. +**************************************************************************/ + +void idmap_dump_maps(char *logfile) +{ + NTSTATUS ret; + struct unixid allid; + struct id_map *maps; + int num_maps; + FILE *dump; + int i; + + if (! NT_STATUS_IS_OK(ret = idmap_init())) { + return; + } + + dump = fopen(logfile, "w"); + if ( ! dump) { + DEBUG(0, ("Unable to open open stream for file [%s], " + "errno: %d\n", logfile, errno)); + return; + } + + if (NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + allid.type = ID_TYPE_UID; + allid.id = 0; + idmap_alloc_ctx->methods->get_id_hwm(&allid); + fprintf(dump, "USER HWM %lu\n", (unsigned long)allid.id); + + allid.type = ID_TYPE_GID; + allid.id = 0; + idmap_alloc_ctx->methods->get_id_hwm(&allid); + fprintf(dump, "GROUP HWM %lu\n", (unsigned long)allid.id); + } + + maps = talloc(idmap_ctx, struct id_map); + num_maps = 0; + + for (i = 0; i < num_domains; i++) { + if (idmap_domains[i]->methods->dump_data) { + idmap_domains[i]->methods->dump_data(idmap_domains[i], + &maps, &num_maps); + } + } + + for (i = 0; i < num_maps; i++) { + switch (maps[i].xid.type) { + case ID_TYPE_UID: + fprintf(dump, "UID %lu %s\n", + (unsigned long)maps[i].xid.id, + sid_string_static(maps[i].sid)); + break; + case ID_TYPE_GID: + fprintf(dump, "GID %lu %s\n", + (unsigned long)maps[i].xid.id, + sid_string_static(maps[i].sid)); + break; + case ID_TYPE_NOT_SPECIFIED: + break; + } + } + + fflush(dump); + fclose(dump); +} + +char *idmap_fetch_secret(const char *backend, bool alloc, + const char *domain, const char *identity) +{ + char *tmp, *ret; + int r; + + if (alloc) { + r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend); + } else { + r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); + } + + if (r < 0) + return NULL; + + strupper_m(tmp); /* make sure the key is case insensitive */ + ret = secrets_fetch_generic(tmp, identity); + + SAFE_FREE(tmp); + + return ret; +} + -- cgit From b111d543a580694f2909c75a280a42a27bbe6dd0 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 16 Oct 2007 14:16:03 -0400 Subject: Fix default domains support using compat syntax. Without this fix idmap_rid can't be used with the compatible syntax. Includes fix to keep trusted domains working (This used to be commit 8c770c367c71d118651964fef63e2fd0fa4a05a5) --- source3/winbindd/idmap.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 2c7acc185c..022a2291a3 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -251,12 +251,6 @@ NTSTATUS idmap_close(void) return NT_STATUS_OK; } -/********************************************************************** - Initialise idmap cache and a remote backend (if configured). -**********************************************************************/ - -static const char *idmap_default_domain[] = { "default domain", NULL }; - /**************************************************************************** ****************************************************************************/ @@ -291,6 +285,7 @@ NTSTATUS idmap_init(void) char *compat_backend = NULL; char *compat_params = NULL; const char **dom_list = NULL; + const char *default_domain = NULL; char *alloc_backend = NULL; BOOL default_already_defined = False; BOOL pri_dom_is_in_list = False; @@ -331,10 +326,6 @@ NTSTATUS idmap_init(void) compat = 1; compat_backend = talloc_strdup(idmap_ctx, *compat_list); - if (compat_backend == NULL ) { - ret = NT_STATUS_NO_MEMORY; - goto done; - } /* strip any leading idmap_ prefix of */ if (strncmp(*compat_list, "idmap_", 6) == 0 ) { @@ -349,6 +340,11 @@ NTSTATUS idmap_init(void) *compat_list); } + if (compat_backend == NULL ) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + /* separate the backend and module arguements */ if ((p = strchr(compat_backend, ':')) != NULL) { *p = '\0'; @@ -365,7 +361,25 @@ NTSTATUS idmap_init(void) } if ( ! dom_list) { - dom_list = idmap_default_domain; + /* generate a list with our main domain */ + char ** dl; + + dl = talloc_array(idmap_ctx, char *, 2); + if (dl == NULL) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + dl[0] = talloc_strdup(dl, lp_workgroup()); + if (dl[0] == NULL) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + + /* terminate */ + dl[1] = NULL; + + dom_list = dl; + default_domain = dl[0]; } /*************************** @@ -386,7 +400,8 @@ NTSTATUS idmap_init(void) continue; } - if (strequal(dom_list[i], lp_workgroup())) { + if ((dom_list[i] != default_domain) && + strequal(dom_list[i], lp_workgroup())) { pri_dom_is_in_list = True; } /* init domain */ @@ -407,10 +422,10 @@ NTSTATUS idmap_init(void) "default", False); if (dom->default_domain || - strequal(dom_list[i], idmap_default_domain[0])) { + (default_domain && strequal(dom_list[i], default_domain))) { /* make sure this is set even when we match - * idmap_default_domain[0] */ + * default_domain */ dom->default_domain = True; if (default_already_defined) { -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/winbindd/idmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 022a2291a3..9800e32505 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -45,7 +45,7 @@ struct idmap_cache_ctx; struct idmap_alloc_context { const char *params; struct idmap_alloc_methods *methods; - BOOL initialized; + bool initialized; }; static TALLOC_CTX *idmap_ctx = NULL; @@ -104,7 +104,7 @@ static struct idmap_alloc_methods *get_alloc_methods( return NULL; } -BOOL idmap_is_offline(void) +bool idmap_is_offline(void) { return ( lp_winbind_offline_logon() && get_global_winbindd_state_offline() ); @@ -287,8 +287,8 @@ NTSTATUS idmap_init(void) const char **dom_list = NULL; const char *default_domain = NULL; char *alloc_backend = NULL; - BOOL default_already_defined = False; - BOOL pri_dom_is_in_list = False; + bool default_already_defined = False; + bool pri_dom_is_in_list = False; int compat = 0; int i; -- cgit From 8f391ae47176f1acaef2e1f448b1c0168a069cf9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Oct 2007 23:21:01 +0200 Subject: Fix an incompatible pointer type warning (This used to be commit 3c50caa9620899f982cd4a833356d965f47ec843) --- source3/winbindd/idmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 9800e32505..e89ad735b6 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -362,9 +362,9 @@ NTSTATUS idmap_init(void) if ( ! dom_list) { /* generate a list with our main domain */ - char ** dl; + const char ** dl; - dl = talloc_array(idmap_ctx, char *, 2); + dl = talloc_array(idmap_ctx, const char *, 2); if (dl == NULL) { ret = NT_STATUS_NO_MEMORY; goto done; -- cgit From 2545457268610ab8fe71911bab167b4aeebc4ca3 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Tue, 20 Nov 2007 13:24:03 -0600 Subject: Prevent segv in winbindd running on a DC using the "idmap backend" syntax. The number of domains should be counted as they are added and not assumed to match the loop counter. manually cherry-picked 8ad2826c48a0d4d26abc3bb209860c776f55822f (This used to be commit 99b75cada2c4caaec5d30c8351080f0a41e44bd1) --- source3/winbindd/idmap.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index e89ad735b6..6756c2a23b 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -387,7 +387,7 @@ NTSTATUS idmap_init(void) */ DEBUG(1, ("Initializing idmap domains\n")); - for (i = 0; dom_list[i]; i++) { + for (i=0, num_domains=0; dom_list[i]; i++) { const char *parm_backend; char *config_option; @@ -395,7 +395,7 @@ NTSTATUS idmap_init(void) if (strequal(dom_list[i], "BUILTIN") || strequal(dom_list[i], get_global_sam_name())) { - DEBUG(0,("idmap_init: Ignoring invalid domain %s\n", + DEBUG(0,("idmap_init: Ignoring domain %s\n", dom_list[i])); continue; } @@ -503,13 +503,17 @@ NTSTATUS idmap_init(void) ret = NT_STATUS_NO_MEMORY; goto done; } - idmap_domains[i] = dom; + idmap_domains[num_domains] = dom; /* save default domain position for future uses */ if (dom->default_domain) { - def_dom_num = i; + def_dom_num = num_domains; } + /* Bump counter to next available slot */ + + num_domains++; + DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n", dom->name, parm_backend, dom->default_domain?"":"not ", @@ -518,9 +522,6 @@ NTSTATUS idmap_init(void) talloc_free(config_option); } - /* save the number of domains we have */ - num_domains = i; - /* automatically add idmap_nss backend if needed */ if ((lp_server_role() == ROLE_DOMAIN_MEMBER) && ( ! pri_dom_is_in_list) && -- cgit From bf13b9f180caf95d88a6c282cbd12c73a9cbe338 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 5 Dec 2007 17:14:12 +0100 Subject: Fix a debug message (missing newline). Michael (This used to be commit 2a1755327f6cef6c969308e9ebcb238048535533) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 6756c2a23b..d2c13ab8b7 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -920,7 +920,7 @@ static NTSTATUS idmap_can_map(const struct id_map *map, if ( (dom = find_idmap_domain_from_sid( map->sid )) == NULL ) { /* huh, couldn't find a suitable domain, * let's just leave it unmapped */ - DEBUG(10, ("Could not find idmap backend for SID %s", + DEBUG(10, ("Could not find idmap backend for SID %s\n", sid_string_static(map->sid))); return NT_STATUS_NO_SUCH_DOMAIN; } -- cgit From 7faee02d0d351c5c039e8f1be7e82ce3a93cbe96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2007 11:30:37 -0800 Subject: Remove the char[1024] strings from dynconfig. Replace them with malloc'ing accessor functions. Should save a lot of static space :-). Jeremy. (This used to be commit 52dc5eaef2106015b3a8b659e818bdb15ad94b05) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index d2c13ab8b7..af8ec17b4e 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -333,7 +333,7 @@ NTSTATUS idmap_init(void) DEBUG(0, ("WARNING: idmap backend uses obsolete" " and deprecated 'idmap_' prefix.\n" "Please replace 'idmap_%s' by '%s' in" - " %s\n", q, q, dyn_CONFIGFILE)); + " %s\n", q, q, get_dyn_CONFIGFILE())); compat_backend = talloc_strdup(idmap_ctx, q); } else { compat_backend = talloc_strdup(idmap_ctx, -- cgit From 92482e5667c9bc5ea99f4ffd1b6eab2847a6805a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Dec 2007 19:19:54 +0100 Subject: idmap: add a const to idmap_dump_maps() metze (This used to be commit de31913f0a4fd407d935ec4e27a6123ab7847ab5) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index af8ec17b4e..e825ed9da7 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1490,7 +1490,7 @@ done: Dump backend status. **************************************************************************/ -void idmap_dump_maps(char *logfile) +void idmap_dump_maps(const char *logfile) { NTSTATUS ret; struct unixid allid; -- cgit From 38f8d32d10f7486ee570275aff185994697203f3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Dec 2007 09:51:56 +0100 Subject: winbindd: remove unused WINBINDD_DUMP_MAPS support Also the design of this function was really bad, instead do the dump into a file, the client should get back the list of mappings. metze (This used to be commit ce7fe8acf41e90553431c7cda6823700701835c7) --- source3/winbindd/idmap.c | 67 ------------------------------------------------ 1 file changed, 67 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index e825ed9da7..6b4af10f6f 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1486,73 +1486,6 @@ done: return ret; } -/************************************************************************** - Dump backend status. -**************************************************************************/ - -void idmap_dump_maps(const char *logfile) -{ - NTSTATUS ret; - struct unixid allid; - struct id_map *maps; - int num_maps; - FILE *dump; - int i; - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return; - } - - dump = fopen(logfile, "w"); - if ( ! dump) { - DEBUG(0, ("Unable to open open stream for file [%s], " - "errno: %d\n", logfile, errno)); - return; - } - - if (NT_STATUS_IS_OK(ret = idmap_alloc_init())) { - allid.type = ID_TYPE_UID; - allid.id = 0; - idmap_alloc_ctx->methods->get_id_hwm(&allid); - fprintf(dump, "USER HWM %lu\n", (unsigned long)allid.id); - - allid.type = ID_TYPE_GID; - allid.id = 0; - idmap_alloc_ctx->methods->get_id_hwm(&allid); - fprintf(dump, "GROUP HWM %lu\n", (unsigned long)allid.id); - } - - maps = talloc(idmap_ctx, struct id_map); - num_maps = 0; - - for (i = 0; i < num_domains; i++) { - if (idmap_domains[i]->methods->dump_data) { - idmap_domains[i]->methods->dump_data(idmap_domains[i], - &maps, &num_maps); - } - } - - for (i = 0; i < num_maps; i++) { - switch (maps[i].xid.type) { - case ID_TYPE_UID: - fprintf(dump, "UID %lu %s\n", - (unsigned long)maps[i].xid.id, - sid_string_static(maps[i].sid)); - break; - case ID_TYPE_GID: - fprintf(dump, "GID %lu %s\n", - (unsigned long)maps[i].xid.id, - sid_string_static(maps[i].sid)); - break; - case ID_TYPE_NOT_SPECIFIED: - break; - } - } - - fflush(dump); - fclose(dump); -} - char *idmap_fetch_secret(const char *backend, bool alloc, const char *domain, const char *identity) { -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/winbindd/idmap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 6b4af10f6f..c1b4e10adf 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -912,7 +912,7 @@ static NTSTATUS idmap_can_map(const struct id_map *map, "our primary domain when is True\n")); DEBUGADD(10, ("Leave [%s] unmapped\n", - sid_string_static(map->sid))); + sid_string_dbg(map->sid))); return NT_STATUS_UNSUCCESSFUL; } } @@ -921,7 +921,7 @@ static NTSTATUS idmap_can_map(const struct id_map *map, /* huh, couldn't find a suitable domain, * let's just leave it unmapped */ DEBUG(10, ("Could not find idmap backend for SID %s\n", - sid_string_static(map->sid))); + sid_string_dbg(map->sid))); return NT_STATUS_NO_SUCH_DOMAIN; } @@ -929,7 +929,7 @@ static NTSTATUS idmap_can_map(const struct id_map *map, /* ouch the domain is read only, * let's just leave it unmapped */ DEBUG(10, ("idmap backend for SID %s is READONLY!\n", - sid_string_static(map->sid))); + sid_string_dbg(map->sid))); return NT_STATUS_UNSUCCESSFUL; } @@ -983,7 +983,7 @@ static NTSTATUS idmap_new_mapping(TALLOC_CTX *ctx, struct id_map *map) map->status = ID_MAPPED; DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", - sid_string_static(map->sid), + sid_string_dbg(map->sid), (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", (unsigned long)map->xid.id)); ret = dom->methods->set_mapping(dom, map); @@ -1006,7 +1006,7 @@ static NTSTATUS idmap_backends_set_mapping(const struct id_map *map) NTSTATUS ret; DEBUG(10, ("Setting mapping %s <-> %s %lu\n", - sid_string_static(map->sid), + sid_string_dbg(map->sid), (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", (unsigned long)map->xid.id)); @@ -1150,7 +1150,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) } DEBUG(10,("SID %s is being handled by %s\n", - sid_string_static(ids[i]->sid), + sid_string_dbg(ids[i]->sid), dom ? dom->name : "none" )); idx = find_idmap_domain_index( dom ); -- cgit From a123abdb912e9fefed501d2621b719f3584c2a2b Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 1 Apr 2008 18:25:47 -0400 Subject: Fix trusted users on a DC that uses the old idmap syntax. There was no default backend therefore on IDs were mapped by default. (This used to be commit f6069126e5e6d239b1ae00e897a420227f923e3f) --- source3/winbindd/idmap.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index c1b4e10adf..10807e6640 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -522,6 +522,76 @@ NTSTATUS idmap_init(void) talloc_free(config_option); } + /* on DCs we need to add idmap_tdb as the default backend if compat is + * defined (when the old implicit configuration is used) + * This is not done in the previous loop a on member server we exclude + * the local domain. But on a DC the local domain is the only domain + * available therefore we are left with no default domain */ + if (((lp_server_role() == ROLE_DOMAIN_PDC) || + (lp_server_role() == ROLE_DOMAIN_BDC)) && + ((num_domains == 0) && (compat == 1))) { + + dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); + IDMAP_CHECK_ALLOC(dom); + + dom->name = talloc_strdup(dom, "__default__"); + IDMAP_CHECK_ALLOC(dom->name); + + dom->default_domain = True; + dom->readonly = False; + + /* get the backend methods for this domain */ + dom->methods = get_methods(backends, compat_backend); + + if ( ! dom->methods) { + ret = smb_probe_module("idmap", compat_backend); + if (NT_STATUS_IS_OK(ret)) { + dom->methods = get_methods(backends, + compat_backend); + } + } + if ( ! dom->methods) { + DEBUG(0, ("ERROR: Could not get methods for " + "backend %s\n", compat_backend)); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* now that we have methods, + * set the destructor for this domain */ + talloc_set_destructor(dom, close_domain_destructor); + + dom->params = talloc_strdup(dom, compat_params); + IDMAP_CHECK_ALLOC(dom->params); + + /* Finally instance a backend copy for this domain */ + ret = dom->methods->init(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Initialization failed for backend " + "%s (domain %s), deferred!\n", + compat_backend, dom->name)); + } + idmap_domains = talloc_realloc(idmap_ctx, idmap_domains, + struct idmap_domain *, 2); + if ( ! idmap_domains) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; + } + idmap_domains[num_domains] = dom; + + def_dom_num = num_domains; + + /* Bump counter to next available slot */ + + num_domains++; + + DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n", + dom->name, compat_backend, + dom->default_domain?"":"not ", + dom->readonly?"":"not ")); + } + /* automatically add idmap_nss backend if needed */ if ((lp_server_role() == ROLE_DOMAIN_MEMBER) && ( ! pri_dom_is_in_list) && -- cgit From 98ed31a107ee6c02d12253d175834359deaa2a64 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Tue, 17 Jun 2008 09:44:21 +0200 Subject: Fix typo. arguements -> arguments Karolin (This used to be commit 16b5b772d216d10613d433884634b1215efbd6e6) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 10807e6640..d710dd2ce3 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -345,7 +345,7 @@ NTSTATUS idmap_init(void) goto done; } - /* separate the backend and module arguements */ + /* separate the backend and module arguments */ if ((p = strchr(compat_backend, ':')) != NULL) { *p = '\0'; compat_params = p + 1; -- cgit From a7cf0bd32aa3b5a26d361e300247638d1e0e159e Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Tue, 17 Jun 2008 10:30:19 +0200 Subject: idmap: Fix typos in comments. Karolin (This used to be commit 94a4d7fa3209eb668161b8110af6f877b4833fa7) --- source3/winbindd/idmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index d710dd2ce3..8b16f27f7d 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -798,7 +798,7 @@ NTSTATUS idmap_init(void) } } - /* cleanpu temporary strings */ + /* cleanup temporary strings */ TALLOC_FREE( compat_backend ); idmap_init_status = NT_STATUS_OK; @@ -1359,7 +1359,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) } } - /* let's see if there is any id mapping to be retieved + /* let's see if there is any id mapping to be retrieved * from the backends */ if (bi) { /* Only do query if we are online */ @@ -1477,7 +1477,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) } } - /* let's see if there is any id mapping to be retieved + /* let's see if there is any id mapping to be retrieved * from the backends */ if (bids) { /* Only do query if we are online */ -- cgit From ab57861686e90d1639f9836d964d8a642c644953 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Jul 2008 12:22:15 +0200 Subject: Fix two memory leaks in an error path in idmap.c (This used to be commit 7cec389e19323e99b6b6258e539be9d1fd65810f) --- source3/winbindd/idmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 8b16f27f7d..c056596470 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -154,6 +154,7 @@ NTSTATUS smb_register_idmap(int version, const char *name, entry->name = talloc_strdup(idmap_ctx, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); + TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->methods = methods; @@ -207,6 +208,7 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name, entry->name = talloc_strdup(idmap_ctx, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); + TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->methods = methods; -- cgit From 1999791b7cedb6f25d6d638513a5b9aa647bb977 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Jul 2008 13:33:25 +0200 Subject: Make idmap_init() static This is called only from idmap_alloc_init, which feels kindof weird. Digging deeper in the code... (This used to be commit c8d1bbfddce41cd6bf37dd0a622ef3437a24b492) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index c056596470..32fc3dc975 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -279,7 +279,7 @@ NTSTATUS idmap_init_cache(void) /**************************************************************************** ****************************************************************************/ -NTSTATUS idmap_init(void) +static NTSTATUS idmap_init(void) { NTSTATUS ret; static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL; -- cgit From 0234276af848343ba13332de9d3f6dee0a529c0c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jul 2008 23:12:22 +0200 Subject: Convert idmap_cache to gencache (This used to be commit 0bf0434f22b0ea46fda3ccc4dd612adbc88dd4f2) --- source3/winbindd/idmap.c | 54 +++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 19 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 32fc3dc975..db17245b92 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -40,8 +40,6 @@ struct idmap_alloc_backend { struct idmap_alloc_backend *prev, *next; }; -struct idmap_cache_ctx; - struct idmap_alloc_context { const char *params; struct idmap_alloc_methods *methods; @@ -49,7 +47,6 @@ struct idmap_alloc_context { }; static TALLOC_CTX *idmap_ctx = NULL; -static struct idmap_cache_ctx *idmap_cache; static struct idmap_backend *backends = NULL; static struct idmap_domain **idmap_domains = NULL; @@ -246,7 +243,6 @@ NTSTATUS idmap_close(void) /* this talloc_free call will fire the talloc destructors * that will free all active backends resources */ TALLOC_FREE(idmap_ctx); - idmap_cache = NULL; idmap_domains = NULL; backends = NULL; @@ -269,10 +265,6 @@ NTSTATUS idmap_init_cache(void) return NT_STATUS_NO_MEMORY; } - if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; } @@ -1316,15 +1308,28 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) for (i = 0; ids[i]; i++) { + bool found, mapped, expired; + if ( ! ids[i]->sid) { DEBUG(1, ("invalid null SID in id_map array")); talloc_free(ctx); return NT_STATUS_INVALID_PARAMETER; } - ret = idmap_cache_map_id(idmap_cache, ids[i]); + ids[i]->status = ID_UNKNOWN; - if ( ! NT_STATUS_IS_OK(ret)) { + found = idmap_cache_map_id(&ids[i]->xid, ids[i]->sid, + &mapped, &expired); + + if (found) { + ids[i]->status = mapped ? ID_MAPPED : ID_UNMAPPED; + } + + if (!found || (expired && IS_DOMAIN_ONLINE(our_domain))) { + + /* + * Need to ask the backend + */ if ( ! bids) { /* alloc space for ids to be resolved by @@ -1376,7 +1381,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) /* update the cache */ for (i = 0; i < bi; i++) { if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); + ret = idmap_cache_set(bids[i]); } else if (bids[i]->status == ID_EXPIRED) { /* the cache returned an expired entry and the * backend was not able to clear the situation @@ -1391,8 +1396,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) * settle down. */ bids[i]->status = ID_UNMAPPED; } else { /* unmapped */ - ret = idmap_cache_set_negative_id(idmap_cache, - bids[i]); + ret = idmap_cache_set_negative_id(bids[i]); } IDMAP_CHECK_RET(ret); } @@ -1434,15 +1438,28 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) for (i = 0; ids[i]; i++) { + bool found, mapped, expired; + if ( ! ids[i]->sid) { DEBUG(1, ("invalid null SID in id_map array\n")); talloc_free(ctx); return NT_STATUS_INVALID_PARAMETER; } - ret = idmap_cache_map_sid(idmap_cache, ids[i]); + ids[i]->status = ID_UNKNOWN; - if ( ! NT_STATUS_IS_OK(ret)) { + found = idmap_cache_map_sid(ids[i]->sid, &ids[i]->xid, + &mapped, &expired); + + if (found) { + ids[i]->status = mapped ? ID_MAPPED : ID_UNMAPPED; + } + + if (!found || (expired && IS_DOMAIN_ONLINE(our_domain))) { + + /* + * Need to ask the backends + */ if ( ! bids) { /* alloc space for ids to be resolved @@ -1494,7 +1511,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) /* update the cache */ for (i = 0; bids[i]; i++) { if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); + ret = idmap_cache_set(bids[i]); } else if (bids[i]->status == ID_EXPIRED) { /* the cache returned an expired entry and the * backend was not able to clear the situation @@ -1509,8 +1526,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) * settle down. */ bids[i]->status = ID_UNMAPPED; } else { /* unmapped */ - ret = idmap_cache_set_negative_sid(idmap_cache, - bids[i]); + ret = idmap_cache_set_negative_sid(bids[i]); } IDMAP_CHECK_RET(ret); } @@ -1550,7 +1566,7 @@ NTSTATUS idmap_set_mapping(const struct id_map *id) IDMAP_CHECK_RET(ret); /* set the mapping in the cache */ - ret = idmap_cache_set(idmap_cache, id); + ret = idmap_cache_set(id); IDMAP_CHECK_RET(ret); done: -- cgit From ca342870639f8720b1becb9b6a5587feafbeec11 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jul 2008 23:29:49 +0200 Subject: Make use of ADD_TO_ARRAY (This used to be commit 81f334bd6da601a040f754c46705cfa2fd4f8c45) --- source3/winbindd/idmap.c | 94 +++++++++++------------------------------------- 1 file changed, 21 insertions(+), 73 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index db17245b92..504be22292 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1177,7 +1177,8 @@ done: return ret; } -static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) +static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids, int + num_ids) { struct id_map ***dom_ids; struct idmap_domain *dom; @@ -1205,7 +1206,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) /* partition the requests by domain */ - for (i = 0; ids[i]; i++) { + for (i = 0; i < num_ids; i++) { uint32 idx; if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) { @@ -1245,7 +1246,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) /* ok all the backends have been contacted at this point */ /* let's see if we have any unmapped SID left and act accordingly */ - for (i = 0; ids[i]; i++) { + for (i = 0; i < num_ids; i++) { /* NOTE: this will NOT touch ID_EXPIRED entries that the backend * was not able to confirm/deny (offline mode) */ if (ids[i]->status == ID_UNKNOWN || @@ -1278,7 +1279,7 @@ done: idmap interface functions **************************************************************************/ -NTSTATUS idmap_unixids_to_sids(struct id_map **ids) +NTSTATUS idmap_unixids_to_sids(struct id_map **ids, int n_ids) { TALLOC_CTX *ctx; NTSTATUS ret; @@ -1306,7 +1307,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) bids = NULL; bi = 0; - for (i = 0; ids[i]; i++) { + for (i = 0; i < n_ids; i++) { bool found, mapped, expired; @@ -1331,38 +1332,12 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) * Need to ask the backend */ - if ( ! bids) { - /* alloc space for ids to be resolved by - * backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; + ADD_TO_ARRAY(ctx, struct id_map *, ids[i], &bids, &bn); + if (bids == NULL) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the rids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, - struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } - - /* make sure the last element is NULL */ - bids[bi] = NULL; } } @@ -1408,12 +1383,12 @@ done: return ret; } -NTSTATUS idmap_sids_to_unixids(struct id_map **ids) +NTSTATUS idmap_sids_to_unixids(struct id_map **ids, int n_ids) { TALLOC_CTX *ctx; NTSTATUS ret; struct id_map **bids; - int i, bi; + int i; int bn = 0; struct winbindd_domain *our_domain = find_our_domain(); @@ -1434,9 +1409,8 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) /* no ids to be asked to the backends by default */ bids = NULL; - bi = 0; - for (i = 0; ids[i]; i++) { + for (i = 0; i < n_ids; i++) { bool found, mapped, expired; @@ -1461,38 +1435,12 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) * Need to ask the backends */ - if ( ! bids) { - /* alloc space for ids to be resolved - by backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; - } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the ids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, - struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } + ADD_TO_ARRAY(ctx, struct id_map *, ids[i], &bids, &bn); + if (bids == NULL) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; } - - /* make sure the last element is NULL */ - bids[bi] = NULL; } } @@ -1505,11 +1453,11 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) goto done; } - ret = idmap_backends_sids_to_unixids(bids); + ret = idmap_backends_sids_to_unixids(bids, bn); IDMAP_CHECK_RET(ret); /* update the cache */ - for (i = 0; bids[i]; i++) { + for (i = 0; i < bn; i++) { if (bids[i]->status == ID_MAPPED) { ret = idmap_cache_set(bids[i]); } else if (bids[i]->status == ID_EXPIRED) { -- cgit From ebb2d70a607cf33f3d2084d715c2d9d4329f2e7b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:42:48 +0200 Subject: Revert "Make use of ADD_TO_ARRAY" This reverts commit 81f334bd6da601a040f754c46705cfa2fd4f8c45. (This used to be commit d4d106776af3f475d46a4dd78794b7b48a3572af) --- source3/winbindd/idmap.c | 94 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 21 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 504be22292..db17245b92 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1177,8 +1177,7 @@ done: return ret; } -static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids, int - num_ids) +static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) { struct id_map ***dom_ids; struct idmap_domain *dom; @@ -1206,7 +1205,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids, int /* partition the requests by domain */ - for (i = 0; i < num_ids; i++) { + for (i = 0; ids[i]; i++) { uint32 idx; if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) { @@ -1246,7 +1245,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids, int /* ok all the backends have been contacted at this point */ /* let's see if we have any unmapped SID left and act accordingly */ - for (i = 0; i < num_ids; i++) { + for (i = 0; ids[i]; i++) { /* NOTE: this will NOT touch ID_EXPIRED entries that the backend * was not able to confirm/deny (offline mode) */ if (ids[i]->status == ID_UNKNOWN || @@ -1279,7 +1278,7 @@ done: idmap interface functions **************************************************************************/ -NTSTATUS idmap_unixids_to_sids(struct id_map **ids, int n_ids) +NTSTATUS idmap_unixids_to_sids(struct id_map **ids) { TALLOC_CTX *ctx; NTSTATUS ret; @@ -1307,7 +1306,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids, int n_ids) bids = NULL; bi = 0; - for (i = 0; i < n_ids; i++) { + for (i = 0; ids[i]; i++) { bool found, mapped, expired; @@ -1332,12 +1331,38 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids, int n_ids) * Need to ask the backend */ - ADD_TO_ARRAY(ctx, struct id_map *, ids[i], &bids, &bn); - if (bids == NULL) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; + if ( ! bids) { + /* alloc space for ids to be resolved by + * backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + bn = 10; } + + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; + + /* check if we need to allocate new space + * on the rids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, + struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + } + + /* make sure the last element is NULL */ + bids[bi] = NULL; } } @@ -1383,12 +1408,12 @@ done: return ret; } -NTSTATUS idmap_sids_to_unixids(struct id_map **ids, int n_ids) +NTSTATUS idmap_sids_to_unixids(struct id_map **ids) { TALLOC_CTX *ctx; NTSTATUS ret; struct id_map **bids; - int i; + int i, bi; int bn = 0; struct winbindd_domain *our_domain = find_our_domain(); @@ -1409,8 +1434,9 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids, int n_ids) /* no ids to be asked to the backends by default */ bids = NULL; + bi = 0; - for (i = 0; i < n_ids; i++) { + for (i = 0; ids[i]; i++) { bool found, mapped, expired; @@ -1435,12 +1461,38 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids, int n_ids) * Need to ask the backends */ - ADD_TO_ARRAY(ctx, struct id_map *, ids[i], &bids, &bn); - if (bids == NULL) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; + if ( ! bids) { + /* alloc space for ids to be resolved + by backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + bn = 10; + } + + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; + + /* check if we need to allocate new space + * on the ids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, + struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } } + + /* make sure the last element is NULL */ + bids[bi] = NULL; } } @@ -1453,11 +1505,11 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids, int n_ids) goto done; } - ret = idmap_backends_sids_to_unixids(bids, bn); + ret = idmap_backends_sids_to_unixids(bids); IDMAP_CHECK_RET(ret); /* update the cache */ - for (i = 0; i < bn; i++) { + for (i = 0; bids[i]; i++) { if (bids[i]->status == ID_MAPPED) { ret = idmap_cache_set(bids[i]); } else if (bids[i]->status == ID_EXPIRED) { -- cgit From b6dcc24987c5c8790502c70687cb0c302333d12c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:42:58 +0200 Subject: Revert "Convert idmap_cache to gencache" This reverts commit 0bf0434f22b0ea46fda3ccc4dd612adbc88dd4f2. (This used to be commit cc536677735ecc318cbd2176ce53b124f44d85a0) --- source3/winbindd/idmap.c | 54 +++++++++++++++++------------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index db17245b92..32fc3dc975 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -40,6 +40,8 @@ struct idmap_alloc_backend { struct idmap_alloc_backend *prev, *next; }; +struct idmap_cache_ctx; + struct idmap_alloc_context { const char *params; struct idmap_alloc_methods *methods; @@ -47,6 +49,7 @@ struct idmap_alloc_context { }; static TALLOC_CTX *idmap_ctx = NULL; +static struct idmap_cache_ctx *idmap_cache; static struct idmap_backend *backends = NULL; static struct idmap_domain **idmap_domains = NULL; @@ -243,6 +246,7 @@ NTSTATUS idmap_close(void) /* this talloc_free call will fire the talloc destructors * that will free all active backends resources */ TALLOC_FREE(idmap_ctx); + idmap_cache = NULL; idmap_domains = NULL; backends = NULL; @@ -265,6 +269,10 @@ NTSTATUS idmap_init_cache(void) return NT_STATUS_NO_MEMORY; } + if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) { + return NT_STATUS_UNSUCCESSFUL; + } + return NT_STATUS_OK; } @@ -1308,28 +1316,15 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) for (i = 0; ids[i]; i++) { - bool found, mapped, expired; - if ( ! ids[i]->sid) { DEBUG(1, ("invalid null SID in id_map array")); talloc_free(ctx); return NT_STATUS_INVALID_PARAMETER; } - ids[i]->status = ID_UNKNOWN; - - found = idmap_cache_map_id(&ids[i]->xid, ids[i]->sid, - &mapped, &expired); - - if (found) { - ids[i]->status = mapped ? ID_MAPPED : ID_UNMAPPED; - } - - if (!found || (expired && IS_DOMAIN_ONLINE(our_domain))) { + ret = idmap_cache_map_id(idmap_cache, ids[i]); - /* - * Need to ask the backend - */ + if ( ! NT_STATUS_IS_OK(ret)) { if ( ! bids) { /* alloc space for ids to be resolved by @@ -1381,7 +1376,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) /* update the cache */ for (i = 0; i < bi; i++) { if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(bids[i]); + ret = idmap_cache_set(idmap_cache, bids[i]); } else if (bids[i]->status == ID_EXPIRED) { /* the cache returned an expired entry and the * backend was not able to clear the situation @@ -1396,7 +1391,8 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) * settle down. */ bids[i]->status = ID_UNMAPPED; } else { /* unmapped */ - ret = idmap_cache_set_negative_id(bids[i]); + ret = idmap_cache_set_negative_id(idmap_cache, + bids[i]); } IDMAP_CHECK_RET(ret); } @@ -1438,28 +1434,15 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) for (i = 0; ids[i]; i++) { - bool found, mapped, expired; - if ( ! ids[i]->sid) { DEBUG(1, ("invalid null SID in id_map array\n")); talloc_free(ctx); return NT_STATUS_INVALID_PARAMETER; } - ids[i]->status = ID_UNKNOWN; - - found = idmap_cache_map_sid(ids[i]->sid, &ids[i]->xid, - &mapped, &expired); - - if (found) { - ids[i]->status = mapped ? ID_MAPPED : ID_UNMAPPED; - } - - if (!found || (expired && IS_DOMAIN_ONLINE(our_domain))) { + ret = idmap_cache_map_sid(idmap_cache, ids[i]); - /* - * Need to ask the backends - */ + if ( ! NT_STATUS_IS_OK(ret)) { if ( ! bids) { /* alloc space for ids to be resolved @@ -1511,7 +1494,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) /* update the cache */ for (i = 0; bids[i]; i++) { if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(bids[i]); + ret = idmap_cache_set(idmap_cache, bids[i]); } else if (bids[i]->status == ID_EXPIRED) { /* the cache returned an expired entry and the * backend was not able to clear the situation @@ -1526,7 +1509,8 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) * settle down. */ bids[i]->status = ID_UNMAPPED; } else { /* unmapped */ - ret = idmap_cache_set_negative_sid(bids[i]); + ret = idmap_cache_set_negative_sid(idmap_cache, + bids[i]); } IDMAP_CHECK_RET(ret); } @@ -1566,7 +1550,7 @@ NTSTATUS idmap_set_mapping(const struct id_map *id) IDMAP_CHECK_RET(ret); /* set the mapping in the cache */ - ret = idmap_cache_set(id); + ret = idmap_cache_set(idmap_cache, id); IDMAP_CHECK_RET(ret); done: -- cgit From 622d36aa41683e122892cd6674279bf52f496e9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:46:00 +0200 Subject: Revert "Make idmap_init() static" This reverts commit c8d1bbfddce41cd6bf37dd0a622ef3437a24b492. (This used to be commit 5cded3da00c0af40a98d86011507553f97fe6a22) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 32fc3dc975..c056596470 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -279,7 +279,7 @@ NTSTATUS idmap_init_cache(void) /**************************************************************************** ****************************************************************************/ -static NTSTATUS idmap_init(void) +NTSTATUS idmap_init(void) { NTSTATUS ret; static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL; -- cgit From 343c7ff3d2f2125a873692c635f1fddedaecf242 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:46:09 +0200 Subject: Revert "Fix two memory leaks in an error path in idmap.c" This reverts commit 7cec389e19323e99b6b6258e539be9d1fd65810f. (This used to be commit d0b34cbb4eba2b6543402af2c9f95407546cefad) --- source3/winbindd/idmap.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index c056596470..8b16f27f7d 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -154,7 +154,6 @@ NTSTATUS smb_register_idmap(int version, const char *name, entry->name = talloc_strdup(idmap_ctx, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); - TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->methods = methods; @@ -208,7 +207,6 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name, entry->name = talloc_strdup(idmap_ctx, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); - TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->methods = methods; -- cgit From 02e592486fc3130ebd365fe337d8597ebf9071ad Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 12 Jul 2008 21:13:05 -0400 Subject: Make again idmap_init static (This used to be commit e113b7c13f2457676fdec9e52f09046286e25b60) --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 8b16f27f7d..b793c47969 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -277,7 +277,7 @@ NTSTATUS idmap_init_cache(void) /**************************************************************************** ****************************************************************************/ -NTSTATUS idmap_init(void) +static NTSTATUS idmap_init(void) { NTSTATUS ret; static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL; -- cgit From eda1a267e1a70506107100a853884c49978acc01 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 12 Jul 2008 21:13:44 -0400 Subject: Add back mem leak fixes (This used to be commit 2adea093c5709e128bdde1e37c6a897db7cbc3b1) --- source3/winbindd/idmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index b793c47969..1f28c50930 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -149,11 +149,13 @@ NTSTATUS smb_register_idmap(int version, const char *name, entry = talloc(idmap_ctx, struct idmap_backend); if ( ! entry) { DEBUG(0,("Out of memory!\n")); + TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->name = talloc_strdup(idmap_ctx, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); + TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } entry->methods = methods; -- cgit From 8812606c43baa796f6164484fb7cac3d9b0dc9c8 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 12 Jul 2008 21:23:16 -0400 Subject: Remove one nested level by reversing if condition (This used to be commit 657a2f20dd4d422d45d7e054f463641cdff16816) --- source3/winbindd/idmap.c | 112 +++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 58 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 1f28c50930..7a9462b7fd 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1324,41 +1324,39 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) ret = idmap_cache_map_id(idmap_cache, ids[i]); - if ( ! NT_STATUS_IS_OK(ret)) { + if (NT_STATUS_IS_OK(ret)) continue; + if ( ! bids) { + /* alloc space for ids to be resolved by + * backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); if ( ! bids) { - /* alloc space for ids to be resolved by - * backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; } + bn = 10; + } - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the rids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, - struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; - /* make sure the last element is NULL */ - bids[bi] = NULL; + /* check if we need to allocate new space + * on the rids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } } + + /* make sure the last element is NULL */ + bids[bi] = NULL; } /* let's see if there is any id mapping to be retrieved @@ -1442,41 +1440,39 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) ret = idmap_cache_map_sid(idmap_cache, ids[i]); - if ( ! NT_STATUS_IS_OK(ret)) { + if (NT_STATUS_IS_OK(ret)) continue; + if ( ! bids) { + /* alloc space for ids to be resolved + by backends (realloc ten by ten) */ + bids = TALLOC_ARRAY(ctx, struct id_map *, 10); if ( ! bids) { - /* alloc space for ids to be resolved - by backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; } + bn = 10; + } - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the ids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, - struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } + /* add this id to the ones to be retrieved + * from the backends */ + bids[bi] = ids[i]; + bi++; - /* make sure the last element is NULL */ - bids[bi] = NULL; + /* check if we need to allocate new space + * on the ids array */ + if (bi == bn) { + bn += 10; + bids = talloc_realloc(ctx, bids, struct id_map *, bn); + if ( ! bids) { + DEBUG(1, ("Out of memory!\n")); + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } } + + /* make sure the last element is NULL */ + bids[bi] = NULL; } /* let's see if there is any id mapping to be retrieved -- cgit From 9669411d1ea30ca6d2c2bc6bfa4bca8231901b58 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 12 Jul 2008 21:28:18 -0400 Subject: Fix regression introduced with 4086ef15b395f1a536fb669af2103a33ecc14de4 We must not return an error here just because we are offline. We must instead fix the mappings to the best of our knowledge (ie mark as mapped, expired ones, and as unmapped, unknown ones) (This used to be commit 4436272dd4d6cdd223b1dc3d217a97cbe3bc887b) --- source3/winbindd/idmap.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 7a9462b7fd..95ff923d0f 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1361,16 +1361,16 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) /* let's see if there is any id mapping to be retrieved * from the backends */ - if (bi) { + if (bids) { + bool online; + /* Only do query if we are online */ - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - ret = NT_STATUS_FILE_IS_OFFLINE; - goto done; + online = !IS_DOMAIN_OFFLINE(our_domain); + if (online) { + ret = idmap_backends_unixids_to_sids(bids); + IDMAP_CHECK_RET(ret); } - ret = idmap_backends_unixids_to_sids(bids); - IDMAP_CHECK_RET(ret); - /* update the cache */ for (i = 0; i < bi; i++) { if (bids[i]->status == ID_MAPPED) { @@ -1388,7 +1388,7 @@ NTSTATUS idmap_unixids_to_sids(struct id_map **ids) * unmapped and hope next time things will * settle down. */ bids[i]->status = ID_UNMAPPED; - } else { /* unmapped */ + } else if (online) { /* unmapped */ ret = idmap_cache_set_negative_id(idmap_cache, bids[i]); } @@ -1478,15 +1478,15 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) /* let's see if there is any id mapping to be retrieved * from the backends */ if (bids) { + bool online; + /* Only do query if we are online */ - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - ret = NT_STATUS_FILE_IS_OFFLINE; - goto done; + online = !IS_DOMAIN_OFFLINE(our_domain); + if (online) { + ret = idmap_backends_sids_to_unixids(bids); + IDMAP_CHECK_RET(ret); } - ret = idmap_backends_sids_to_unixids(bids); - IDMAP_CHECK_RET(ret); - /* update the cache */ for (i = 0; bids[i]; i++) { if (bids[i]->status == ID_MAPPED) { @@ -1504,7 +1504,7 @@ NTSTATUS idmap_sids_to_unixids(struct id_map **ids) * unmapped and hope next time things will * settle down. */ bids[i]->status = ID_UNMAPPED; - } else { /* unmapped */ + } else if (online) { /* unmapped */ ret = idmap_cache_set_negative_sid(idmap_cache, bids[i]); } -- cgit From 0c1e27abf69855abef396e4c93989964b70fcf1f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Jul 2008 12:32:18 +0200 Subject: Directly call backends from idmap_[ugs]_to_[ugs]id (This used to be commit f955407042e6d2384acccc399d72ff65ba0e721c) --- source3/winbindd/idmap.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 95ff923d0f..f0d2c03e0b 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -1282,6 +1282,45 @@ done: return ret; } +NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id) +{ + struct id_map *maps[2]; + int i; + + maps[0] = id; + maps[1] = NULL; + + for (i = num_domains-1; i>=0; i--) { + struct idmap_domain *dom = idmap_domains[i]; + NTSTATUS status; + + DEBUG(10, ("Query sids from domain %s\n", dom->name)); + + status = dom->methods->unixids_to_sids(dom, maps); + if (NT_STATUS_IS_OK(status)) { + return NT_STATUS_OK; + } + } + + return NT_STATUS_NONE_MAPPED; +} + +NTSTATUS idmap_backends_sid_to_unixid(struct id_map *id) +{ + struct idmap_domain *dom; + struct id_map *maps[2]; + + dom = find_idmap_domain_from_sid(id->sid); + if (dom == NULL) { + return NT_STATUS_NONE_MAPPED; + } + + maps[0] = id; + maps[1] = NULL; + + return dom->methods->sids_to_unixids(dom, maps); +} + /************************************************************************** idmap interface functions **************************************************************************/ -- cgit From 8d4bd2d960ebf11bc85891210c6f72a371e08417 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 13 Jul 2008 09:59:57 +0200 Subject: Remove the multi-ID lookup code and the 3.2.0 version of idmap_cache (This used to be commit 1bd98521dc3f16ad77ccccd3979288c58e03ebe8) --- source3/winbindd/idmap.c | 434 ----------------------------------------------- 1 file changed, 434 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index f0d2c03e0b..2c18164f8c 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -269,10 +269,6 @@ NTSTATUS idmap_init_cache(void) return NT_STATUS_NO_MEMORY; } - if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; } @@ -1092,196 +1088,6 @@ static NTSTATUS idmap_backends_set_mapping(const struct id_map *map) return dom->methods->set_mapping(dom, map); } -static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids) -{ - struct idmap_domain *dom; - struct id_map **unmapped; - struct id_map **_ids; - TALLOC_CTX *ctx; - NTSTATUS ret; - int i, u, n; - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_backends_unixids_to_sids ctx"); - if ( ! ctx) { - DEBUG(0, ("Out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10, ("Query backends to map ids->sids\n")); - - /* start from the default (the last one) and then if there are still - * unmapped entries cycle through the others */ - - _ids = ids; - - unmapped = NULL; - for (n = num_domains-1; n >= 0; n--) { /* cycle backwards */ - - dom = idmap_domains[n]; - - DEBUG(10, ("Query sids from domain %s\n", dom->name)); - - ret = dom->methods->unixids_to_sids(dom, _ids); - IDMAP_REPORT_RET(ret); - - unmapped = NULL; - - for (i = 0, u = 0; _ids[i]; i++) { - if (_ids[i]->status != ID_MAPPED) { - unmapped = talloc_realloc(ctx, unmapped, - struct id_map *, u + 2); - IDMAP_CHECK_ALLOC(unmapped); - unmapped[u] = _ids[i]; - u++; - } - } - if (unmapped) { - /* terminate the unmapped list */ - unmapped[u] = NULL; - } else { /* no more entries, get out */ - break; - } - - _ids = unmapped; - - } - - if (unmapped) { - /* there are still unmapped ids, - * map them to the unix users/groups domains */ - /* except for expired entries, - * these will be returned as valid (offline mode) */ - for (i = 0; unmapped[i]; i++) { - if (unmapped[i]->status == ID_EXPIRED) continue; - switch (unmapped[i]->xid.type) { - case ID_TYPE_UID: - uid_to_unix_users_sid( - (uid_t)unmapped[i]->xid.id, - unmapped[i]->sid); - unmapped[i]->status = ID_MAPPED; - break; - case ID_TYPE_GID: - gid_to_unix_groups_sid( - (gid_t)unmapped[i]->xid.id, - unmapped[i]->sid); - unmapped[i]->status = ID_MAPPED; - break; - default: /* what?! */ - unmapped[i]->status = ID_UNKNOWN; - break; - } - } - } - - ret = NT_STATUS_OK; - -done: - talloc_free(ctx); - return ret; -} - -static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) -{ - struct id_map ***dom_ids; - struct idmap_domain *dom; - TALLOC_CTX *ctx; - NTSTATUS ret; - int i, *counters; - - if ( (ctx = talloc_named_const(NULL, 0, "be_sids_to_ids")) == NULL ) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10, ("Query backends to map sids->ids\n")); - - /* split list per domain */ - if (num_domains == 0) { - DEBUG(1, ("No domains available?\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - dom_ids = TALLOC_ZERO_ARRAY(ctx, struct id_map **, num_domains); - IDMAP_CHECK_ALLOC(dom_ids); - counters = TALLOC_ZERO_ARRAY(ctx, int, num_domains); - IDMAP_CHECK_ALLOC(counters); - - /* partition the requests by domain */ - - for (i = 0; ids[i]; i++) { - uint32 idx; - - if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) { - /* no available idmap_domain. Move on */ - continue; - } - - DEBUG(10,("SID %s is being handled by %s\n", - sid_string_dbg(ids[i]->sid), - dom ? dom->name : "none" )); - - idx = find_idmap_domain_index( dom ); - SMB_ASSERT( idx != -1 ); - - dom_ids[idx] = talloc_realloc(ctx, dom_ids[idx], - struct id_map *, - counters[idx] + 2); - IDMAP_CHECK_ALLOC(dom_ids[idx]); - - dom_ids[idx][counters[idx]] = ids[i]; - counters[idx]++; - dom_ids[idx][counters[idx]] = NULL; - } - - /* All the ids have been dispatched in the right queues. - Let's cycle through the filled ones */ - - for (i = 0; i < num_domains; i++) { - if (dom_ids[i]) { - dom = idmap_domains[i]; - DEBUG(10, ("Query ids from domain %s\n", dom->name)); - ret = dom->methods->sids_to_unixids(dom, dom_ids[i]); - IDMAP_REPORT_RET(ret); - } - } - - /* ok all the backends have been contacted at this point */ - /* let's see if we have any unmapped SID left and act accordingly */ - - for (i = 0; ids[i]; i++) { - /* NOTE: this will NOT touch ID_EXPIRED entries that the backend - * was not able to confirm/deny (offline mode) */ - if (ids[i]->status == ID_UNKNOWN || - ids[i]->status == ID_UNMAPPED) { - /* ok this is an unmapped one, see if we can map it */ - ret = idmap_new_mapping(ctx, ids[i]); - if (NT_STATUS_IS_OK(ret)) { - /* successfully mapped */ - ids[i]->status = ID_MAPPED; - } else - if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { - /* could not map it */ - ids[i]->status = ID_UNMAPPED; - } else { - /* Something very bad happened down there - * OR we are offline */ - ids[i]->status = ID_UNKNOWN; - } - } - } - - ret = NT_STATUS_OK; - -done: - talloc_free(ctx); - return ret; -} - NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id) { struct id_map *maps[2]; @@ -1321,242 +1127,6 @@ NTSTATUS idmap_backends_sid_to_unixid(struct id_map *id) return dom->methods->sids_to_unixids(dom, maps); } -/************************************************************************** - idmap interface functions -**************************************************************************/ - -NTSTATUS idmap_unixids_to_sids(struct id_map **ids) -{ - TALLOC_CTX *ctx; - NTSTATUS ret; - struct id_map **bids; - int i, bi; - int bn = 0; - struct winbindd_domain *our_domain = find_our_domain(); - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_unixids_to_sids ctx"); - if ( ! ctx) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - /* no ids to be asked to the backends by default */ - bids = NULL; - bi = 0; - - for (i = 0; ids[i]; i++) { - - if ( ! ids[i]->sid) { - DEBUG(1, ("invalid null SID in id_map array")); - talloc_free(ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - ret = idmap_cache_map_id(idmap_cache, ids[i]); - - if (NT_STATUS_IS_OK(ret)) continue; - - if ( ! bids) { - /* alloc space for ids to be resolved by - * backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; - } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the rids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } - - /* make sure the last element is NULL */ - bids[bi] = NULL; - } - - /* let's see if there is any id mapping to be retrieved - * from the backends */ - if (bids) { - bool online; - - /* Only do query if we are online */ - online = !IS_DOMAIN_OFFLINE(our_domain); - if (online) { - ret = idmap_backends_unixids_to_sids(bids); - IDMAP_CHECK_RET(ret); - } - - /* update the cache */ - for (i = 0; i < bi; i++) { - if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); - } else if (bids[i]->status == ID_EXPIRED) { - /* the cache returned an expired entry and the - * backend was not able to clear the situation - * (offline). This handles a previous - * NT_STATUS_SYNCHRONIZATION_REQUIRED - * for disconnected mode, */ - bids[i]->status = ID_MAPPED; - } else if (bids[i]->status == ID_UNKNOWN) { - /* something bad here. We were not able to - * handle this for some reason, mark it as - * unmapped and hope next time things will - * settle down. */ - bids[i]->status = ID_UNMAPPED; - } else if (online) { /* unmapped */ - ret = idmap_cache_set_negative_id(idmap_cache, - bids[i]); - } - IDMAP_CHECK_RET(ret); - } - } - - ret = NT_STATUS_OK; -done: - talloc_free(ctx); - return ret; -} - -NTSTATUS idmap_sids_to_unixids(struct id_map **ids) -{ - TALLOC_CTX *ctx; - NTSTATUS ret; - struct id_map **bids; - int i, bi; - int bn = 0; - struct winbindd_domain *our_domain = find_our_domain(); - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_sids_to_unixids ctx"); - if ( ! ctx) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - /* no ids to be asked to the backends by default */ - bids = NULL; - bi = 0; - - for (i = 0; ids[i]; i++) { - - if ( ! ids[i]->sid) { - DEBUG(1, ("invalid null SID in id_map array\n")); - talloc_free(ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - ret = idmap_cache_map_sid(idmap_cache, ids[i]); - - if (NT_STATUS_IS_OK(ret)) continue; - - if ( ! bids) { - /* alloc space for ids to be resolved - by backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; - } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the ids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } - - /* make sure the last element is NULL */ - bids[bi] = NULL; - } - - /* let's see if there is any id mapping to be retrieved - * from the backends */ - if (bids) { - bool online; - - /* Only do query if we are online */ - online = !IS_DOMAIN_OFFLINE(our_domain); - if (online) { - ret = idmap_backends_sids_to_unixids(bids); - IDMAP_CHECK_RET(ret); - } - - /* update the cache */ - for (i = 0; bids[i]; i++) { - if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); - } else if (bids[i]->status == ID_EXPIRED) { - /* the cache returned an expired entry and the - * backend was not able to clear the situation - * (offline). This handles a previous - * NT_STATUS_SYNCHRONIZATION_REQUIRED - * for disconnected mode, */ - bids[i]->status = ID_MAPPED; - } else if (bids[i]->status == ID_UNKNOWN) { - /* something bad here. We were not able to - * handle this for some reason, mark it as - * unmapped and hope next time things will - * settle down. */ - bids[i]->status = ID_UNMAPPED; - } else if (online) { /* unmapped */ - ret = idmap_cache_set_negative_sid(idmap_cache, - bids[i]); - } - IDMAP_CHECK_RET(ret); - } - } - - ret = NT_STATUS_OK; -done: - talloc_free(ctx); - return ret; -} - NTSTATUS idmap_set_mapping(const struct id_map *id) { TALLOC_CTX *ctx; @@ -1584,10 +1154,6 @@ NTSTATUS idmap_set_mapping(const struct id_map *id) ret = idmap_backends_set_mapping(id); IDMAP_CHECK_RET(ret); - /* set the mapping in the cache */ - ret = idmap_cache_set(idmap_cache, id); - IDMAP_CHECK_RET(ret); - done: talloc_free(ctx); return ret; -- cgit From 340ab6a256802a22c11b7f707748397249075b65 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 13 Jul 2008 12:07:40 +0200 Subject: idmap rewrite (This used to be commit 30a180f2fce8cf6a3e5548f6bba453272ba70b33) --- source3/winbindd/idmap.c | 1151 ++++++++++++++-------------------------------- 1 file changed, 336 insertions(+), 815 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 2c18164f8c..bace38876b 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -40,41 +40,25 @@ struct idmap_alloc_backend { struct idmap_alloc_backend *prev, *next; }; -struct idmap_cache_ctx; - struct idmap_alloc_context { - const char *params; struct idmap_alloc_methods *methods; - bool initialized; }; -static TALLOC_CTX *idmap_ctx = NULL; -static struct idmap_cache_ctx *idmap_cache; - +/* + * Lists for the module initializations + */ static struct idmap_backend *backends = NULL; +static struct idmap_alloc_backend *alloc_backends = NULL; + + +static struct idmap_domain *default_idmap_domain; +static struct idmap_domain *passdb_idmap_domain; + static struct idmap_domain **idmap_domains = NULL; static int num_domains = 0; -static int pdb_dom_num = -1; -static int def_dom_num = -1; -static struct idmap_alloc_backend *alloc_backends = NULL; static struct idmap_alloc_context *idmap_alloc_ctx = NULL; -#define IDMAP_CHECK_RET(ret) do { \ - if ( ! NT_STATUS_IS_OK(ret)) { \ - DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \ - goto done; \ - } } while(0) -#define IDMAP_REPORT_RET(ret) do { \ - if ( ! NT_STATUS_IS_OK(ret)) { \ - DEBUG(2, ("ERROR: NTSTATUS = 0x%08x\n", NT_STATUS_V(ret))); \ - } } while(0) -#define IDMAP_CHECK_ALLOC(mem) do { \ - if (!mem) { \ - DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; \ - goto done; \ - } } while(0) - static struct idmap_methods *get_methods(struct idmap_backend *be, const char *name) { @@ -110,6 +94,11 @@ bool idmap_is_offline(void) get_global_winbindd_state_offline() ); } +bool idmap_is_online(void) +{ + return !idmap_is_offline(); +} + /********************************************************************** Allow a module to register itself as a method. **********************************************************************/ @@ -117,13 +106,8 @@ bool idmap_is_offline(void) NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods) { - struct idmap_methods *test; struct idmap_backend *entry; - if (!idmap_ctx) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - if ((version != SMB_IDMAP_INTERFACE_VERSION)) { DEBUG(0, ("Failed to register idmap module.\n" "The module was compiled against " @@ -140,19 +124,20 @@ NTSTATUS smb_register_idmap(int version, const char *name, return NT_STATUS_INVALID_PARAMETER; } - test = get_methods(backends, name); - if (test) { - DEBUG(0,("Idmap module %s already registered!\n", name)); - return NT_STATUS_OBJECT_NAME_COLLISION; + for (entry = backends; entry != NULL; entry = entry->next) { + if (strequal(entry->name, name)) { + DEBUG(0,("Idmap module %s already registered!\n", name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } } - entry = talloc(idmap_ctx, struct idmap_backend); + entry = talloc(NULL, struct idmap_backend); if ( ! entry) { DEBUG(0,("Out of memory!\n")); TALLOC_FREE(entry); return NT_STATUS_NO_MEMORY; } - entry->name = talloc_strdup(idmap_ctx, name); + entry->name = talloc_strdup(entry, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); TALLOC_FREE(entry); @@ -175,10 +160,6 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name, struct idmap_alloc_methods *test; struct idmap_alloc_backend *entry; - if (!idmap_ctx) { - return NT_STATUS_INTERNAL_DB_ERROR; - } - if ((version != SMB_IDMAP_INTERFACE_VERSION)) { DEBUG(0, ("Failed to register idmap alloc module.\n" "The module was compiled against " @@ -201,12 +182,12 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name, return NT_STATUS_OBJECT_NAME_COLLISION; } - entry = talloc(idmap_ctx, struct idmap_alloc_backend); + entry = talloc(NULL, struct idmap_alloc_backend); if ( ! entry) { DEBUG(0,("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } - entry->name = talloc_strdup(idmap_ctx, name); + entry->name = talloc_strdup(entry, name); if ( ! entry->name) { DEBUG(0,("Out of memory!\n")); return NT_STATUS_NO_MEMORY; @@ -230,610 +211,313 @@ static int close_domain_destructor(struct idmap_domain *dom) return 0; } -/************************************************************************** - Shutdown. -**************************************************************************/ - -NTSTATUS idmap_close(void) +static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param, + char **pmodulename, char **pargs) { - /* close the alloc backend first before freeing idmap_ctx */ - if (idmap_alloc_ctx) { - idmap_alloc_ctx->methods->close_fn(); - idmap_alloc_ctx->methods = NULL; - } - alloc_backends = NULL; - - /* this talloc_free call will fire the talloc destructors - * that will free all active backends resources */ - TALLOC_FREE(idmap_ctx); - idmap_cache = NULL; - idmap_domains = NULL; - backends = NULL; - - return NT_STATUS_OK; -} + char *modulename; + char *args; -/**************************************************************************** - ****************************************************************************/ + if (strncmp(param, "idmap_", 6) == 0) { + param += 6; + DEBUG(1, ("idmap_init: idmap backend uses deprecated " + "'idmap_' prefix. Please replace 'idmap_%s' by " + "'%s'\n", param, param)); + } -NTSTATUS idmap_init_cache(void) -{ - /* Always initialize the cache. We'll have to delay initialization - of backends if we are offline */ + modulename = talloc_strdup(mem_ctx, param); + if (modulename == NULL) { + return false; + } - if ( idmap_ctx ) { - return NT_STATUS_OK; + args = strchr(modulename, ':'); + if (args == NULL) { + *pmodulename = modulename; + *pargs = NULL; + return true; } - if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) { - return NT_STATUS_NO_MEMORY; + *args = '\0'; + + args = talloc_strdup(mem_ctx, args+1); + if (args == NULL) { + TALLOC_FREE(modulename); + return false; } - return NT_STATUS_OK; + *pmodulename = modulename; + *pargs = args; + return true; } -/**************************************************************************** - ****************************************************************************/ - -static NTSTATUS idmap_init(void) +static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, + const char *domainname, + const char *modulename, + const char *params) { - NTSTATUS ret; - static NTSTATUS idmap_init_status = NT_STATUS_UNSUCCESSFUL; - struct idmap_domain *dom; - char *compat_backend = NULL; - char *compat_params = NULL; - const char **dom_list = NULL; - const char *default_domain = NULL; - char *alloc_backend = NULL; - bool default_already_defined = False; - bool pri_dom_is_in_list = False; - int compat = 0; - int i; + struct idmap_domain *result; + NTSTATUS status; - ret = idmap_init_cache(); - if (!NT_STATUS_IS_OK(ret)) - return ret; - - if (NT_STATUS_IS_OK(idmap_init_status)) { - return NT_STATUS_OK; + result = talloc_zero(mem_ctx, struct idmap_domain); + if (result == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; } - /* We can't reliably call intialization code here unless - we are online. But return NT_STATUS_OK so the upper - level code doesn't abort idmap lookups. */ - - if ( get_global_winbindd_state_offline() ) { - idmap_init_status = NT_STATUS_FILE_IS_OFFLINE; - return NT_STATUS_OK; + result->name = talloc_strdup(result, domainname); + if (result->name == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; } - static_init_idmap; + result->methods = get_methods(backends, modulename); + if (result->methods == NULL) { + DEBUG(3, ("idmap backend %s not found\n", modulename)); - dom_list = lp_idmap_domains(); - - if ( lp_idmap_backend() ) { - const char **compat_list = lp_idmap_backend(); - char *p = NULL; - const char *q = NULL; - - if ( dom_list ) { - DEBUG(0, ("WARNING: idmap backend and idmap domains are" - " mutually exclusive!\n")); - DEBUGADD(0,("idmap backend option will be IGNORED!\n")); - } else { - compat = 1; - - compat_backend = talloc_strdup(idmap_ctx, *compat_list); - - /* strip any leading idmap_ prefix of */ - if (strncmp(*compat_list, "idmap_", 6) == 0 ) { - q = *compat_list += 6; - DEBUG(0, ("WARNING: idmap backend uses obsolete" - " and deprecated 'idmap_' prefix.\n" - "Please replace 'idmap_%s' by '%s' in" - " %s\n", q, q, get_dyn_CONFIGFILE())); - compat_backend = talloc_strdup(idmap_ctx, q); - } else { - compat_backend = talloc_strdup(idmap_ctx, - *compat_list); - } - - if (compat_backend == NULL ) { - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - /* separate the backend and module arguments */ - if ((p = strchr(compat_backend, ':')) != NULL) { - *p = '\0'; - compat_params = p + 1; - } + status = smb_probe_module("idmap", modulename); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not probe idmap module %s\n", + modulename)); + goto fail; } - } else if ( !dom_list ) { - /* Back compatible: without idmap domains and explicit - idmap backend. Taking default idmap backend: tdb */ - compat = 1; - compat_backend = talloc_strdup( idmap_ctx, "tdb"); - compat_params = compat_backend; + result->methods = get_methods(backends, modulename); } - - if ( ! dom_list) { - /* generate a list with our main domain */ - const char ** dl; - - dl = talloc_array(idmap_ctx, const char *, 2); - if (dl == NULL) { - ret = NT_STATUS_NO_MEMORY; - goto done; - } - dl[0] = talloc_strdup(dl, lp_workgroup()); - if (dl[0] == NULL) { - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - /* terminate */ - dl[1] = NULL; - - dom_list = dl; - default_domain = dl[0]; + if (result->methods == NULL) { + DEBUG(1, ("idmap backend %s not found\n", modulename)); + goto fail; } - /*************************** - * initialize idmap domains - */ - DEBUG(1, ("Initializing idmap domains\n")); - - for (i=0, num_domains=0; dom_list[i]; i++) { - const char *parm_backend; - char *config_option; - - /* ignore BUILTIN and local MACHINE domains */ - if (strequal(dom_list[i], "BUILTIN") - || strequal(dom_list[i], get_global_sam_name())) - { - DEBUG(0,("idmap_init: Ignoring domain %s\n", - dom_list[i])); - continue; - } - - if ((dom_list[i] != default_domain) && - strequal(dom_list[i], lp_workgroup())) { - pri_dom_is_in_list = True; - } - /* init domain */ - - dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); - IDMAP_CHECK_ALLOC(dom); - - dom->name = talloc_strdup(dom, dom_list[i]); - IDMAP_CHECK_ALLOC(dom->name); - - config_option = talloc_asprintf(dom, "idmap config %s", - dom->name); - IDMAP_CHECK_ALLOC(config_option); - - /* default or specific ? */ - - dom->default_domain = lp_parm_bool(-1, config_option, - "default", False); - - if (dom->default_domain || - (default_domain && strequal(dom_list[i], default_domain))) { - - /* make sure this is set even when we match - * default_domain */ - dom->default_domain = True; - - if (default_already_defined) { - DEBUG(1, ("ERROR: Multiple domains defined as" - " default!\n")); - ret = NT_STATUS_INVALID_PARAMETER; - goto done; - } - - default_already_defined = True; - - } - - dom->readonly = lp_parm_bool(-1, config_option, - "readonly", False); - - /* find associated backend (default: tdb) */ - if (compat) { - parm_backend = talloc_strdup(idmap_ctx, compat_backend); - } else { - parm_backend = talloc_strdup(idmap_ctx, - lp_parm_const_string( - -1, config_option, - "backend", "tdb")); - } - IDMAP_CHECK_ALLOC(parm_backend); - - /* get the backend methods for this domain */ - dom->methods = get_methods(backends, parm_backend); - - if ( ! dom->methods) { - ret = smb_probe_module("idmap", parm_backend); - if (NT_STATUS_IS_OK(ret)) { - dom->methods = get_methods(backends, - parm_backend); - } - } - if ( ! dom->methods) { - DEBUG(0, ("ERROR: Could not get methods for " - "backend %s\n", parm_backend)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* check the set_mapping function exists otherwise mark the - * module as readonly */ - if ( ! dom->methods->set_mapping) { - DEBUG(5, ("Forcing to readonly, as this module can't" - " store arbitrary mappings.\n")); - dom->readonly = True; - } - - /* now that we have methods, - * set the destructor for this domain */ - talloc_set_destructor(dom, close_domain_destructor); + status = result->methods->init(result, params); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("idmap initialization returned %s\n", + nt_errstr(status))); + goto fail; + } - if (compat_params) { - dom->params = talloc_strdup(dom, compat_params); - IDMAP_CHECK_ALLOC(dom->params); - } else { - dom->params = NULL; - } + talloc_set_destructor(result, close_domain_destructor); - /* Finally instance a backend copy for this domain */ - ret = dom->methods->init(dom); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Initialization failed for backend " - "%s (domain %s), deferred!\n", - parm_backend, dom->name)); - } - idmap_domains = talloc_realloc(idmap_ctx, idmap_domains, - struct idmap_domain *, i+1); - if ( ! idmap_domains) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - idmap_domains[num_domains] = dom; + return result; - /* save default domain position for future uses */ - if (dom->default_domain) { - def_dom_num = num_domains; - } +fail: + TALLOC_FREE(result); + return NULL; +} - /* Bump counter to next available slot */ +static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx) +{ + struct idmap_domain *result; + char *modulename; + char *params; - num_domains++; + DEBUG(10, ("idmap_init_default_domain: calling static_init_idmap\n")); - DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n", - dom->name, parm_backend, - dom->default_domain?"":"not ", - dom->readonly?"":"not ")); + static_init_idmap; - talloc_free(config_option); + if (!parse_idmap_module(talloc_tos(), lp_idmap_backend(), &modulename, + ¶ms)) { + DEBUG(1, ("parse_idmap_module failed\n")); + return NULL; } - /* on DCs we need to add idmap_tdb as the default backend if compat is - * defined (when the old implicit configuration is used) - * This is not done in the previous loop a on member server we exclude - * the local domain. But on a DC the local domain is the only domain - * available therefore we are left with no default domain */ - if (((lp_server_role() == ROLE_DOMAIN_PDC) || - (lp_server_role() == ROLE_DOMAIN_BDC)) && - ((num_domains == 0) && (compat == 1))) { - - dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); - IDMAP_CHECK_ALLOC(dom); - - dom->name = talloc_strdup(dom, "__default__"); - IDMAP_CHECK_ALLOC(dom->name); - - dom->default_domain = True; - dom->readonly = False; - - /* get the backend methods for this domain */ - dom->methods = get_methods(backends, compat_backend); - - if ( ! dom->methods) { - ret = smb_probe_module("idmap", compat_backend); - if (NT_STATUS_IS_OK(ret)) { - dom->methods = get_methods(backends, - compat_backend); - } - } - if ( ! dom->methods) { - DEBUG(0, ("ERROR: Could not get methods for " - "backend %s\n", compat_backend)); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* now that we have methods, - * set the destructor for this domain */ - talloc_set_destructor(dom, close_domain_destructor); + DEBUG(3, ("idmap_init: using '%s' as remote backend\n", modulename)); - dom->params = talloc_strdup(dom, compat_params); - IDMAP_CHECK_ALLOC(dom->params); + result = idmap_init_domain(mem_ctx, "*", modulename, params); + if (result == NULL) { + goto fail; + } - /* Finally instance a backend copy for this domain */ - ret = dom->methods->init(dom); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Initialization failed for backend " - "%s (domain %s), deferred!\n", - compat_backend, dom->name)); - } - idmap_domains = talloc_realloc(idmap_ctx, idmap_domains, - struct idmap_domain *, 2); - if ( ! idmap_domains) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - idmap_domains[num_domains] = dom; + TALLOC_FREE(modulename); + TALLOC_FREE(params); + return result; - def_dom_num = num_domains; +fail: + TALLOC_FREE(modulename); + TALLOC_FREE(params); + TALLOC_FREE(result); + return NULL; +} - /* Bump counter to next available slot */ +static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx, + const char *domname) +{ + struct idmap_domain *result = NULL; + char *config_option; + const char *backend; - num_domains++; + config_option = talloc_asprintf(talloc_tos(), "idmap config %s", + domname); + if (config_option == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } - DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n", - dom->name, compat_backend, - dom->default_domain?"":"not ", - dom->readonly?"":"not ")); + backend = lp_parm_const_string(-1, config_option, "backend", NULL); + if (backend == NULL) { + DEBUG(1, ("no backend defined for %s\n", config_option)); + goto fail; } - /* automatically add idmap_nss backend if needed */ - if ((lp_server_role() == ROLE_DOMAIN_MEMBER) && - ( ! pri_dom_is_in_list) && - lp_winbind_trusted_domains_only()) { + result = idmap_init_domain(mem_ctx, domname, backend, NULL); + if (result == NULL) { + goto fail; + } - dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); - IDMAP_CHECK_ALLOC(dom); + TALLOC_FREE(config_option); + return result; - dom->name = talloc_strdup(dom, lp_workgroup()); - IDMAP_CHECK_ALLOC(dom->name); +fail: + TALLOC_FREE(config_option); + TALLOC_FREE(result); + return NULL; +} - dom->default_domain = False; - dom->readonly = True; +static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx) +{ + if (passdb_idmap_domain != NULL) { + return passdb_idmap_domain; + } - /* get the backend methods for passdb */ - dom->methods = get_methods(backends, "nss"); + passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(), + "passdb", NULL); + if (passdb_idmap_domain == NULL) { + DEBUG(1, ("Could not init passdb idmap domain\n")); + } - /* (the nss module is always statically linked) */ - if ( ! dom->methods) { - DEBUG(0, ("ERROR: No methods for idmap_nss ?!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } + return passdb_idmap_domain; +} - /* now that we have methods, - * set the destructor for this domain */ - talloc_set_destructor(dom, close_domain_destructor); +static struct idmap_domain *idmap_find_domain(const char *domname) +{ + struct idmap_domain *result; + int i; - if (compat_params) { - dom->params = talloc_strdup(dom, compat_params); - IDMAP_CHECK_ALLOC(dom->params); - } else { - dom->params = NULL; - } + /* + * 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; + } - /* Finally instance a backend copy for this domain */ - ret = dom->methods->init(dom); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Init. failed for idmap_nss ?!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if ((domname == NULL) || (domname[0] == '\0')) { + return default_idmap_domain; + } - idmap_domains = talloc_realloc(idmap_ctx, - idmap_domains, - struct idmap_domain *, - num_domains+1); - if ( ! idmap_domains) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; + for (i=0; iname, domname)) { + return idmap_domains[i]; } - idmap_domains[num_domains] = dom; + } - DEBUG(10, ("Domain %s - Backend nss - not default - readonly\n", - dom->name )); + if (idmap_domains == NULL) { + /* + * talloc context for all idmap domains + */ + idmap_domains = TALLOC_ARRAY(NULL, struct idmap_domain *, 1); + } - num_domains++; + if (idmap_domains == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; } - /**** automatically add idmap_passdb backend ****/ - dom = TALLOC_ZERO_P(idmap_ctx, struct idmap_domain); - IDMAP_CHECK_ALLOC(dom); + result = idmap_init_named_domain(idmap_domains, domname); + if (result == NULL) { + /* + * Could not init that domain -- try the default one + */ + return default_idmap_domain; + } - dom->name = talloc_strdup(dom, get_global_sam_name()); - IDMAP_CHECK_ALLOC(dom->name); + ADD_TO_ARRAY(idmap_domains, struct idmap_domain *, result, + &idmap_domains, &num_domains); + return result; +} - dom->default_domain = False; - dom->readonly = True; +void idmap_close(void) +{ + if (idmap_alloc_ctx) { + idmap_alloc_ctx->methods->close_fn(); + idmap_alloc_ctx->methods = NULL; + } + alloc_backends = NULL; + TALLOC_FREE(default_idmap_domain); + TALLOC_FREE(passdb_idmap_domain); + TALLOC_FREE(idmap_domains); + num_domains = 0; +} - /* get the backend methods for passdb */ - dom->methods = get_methods(backends, "passdb"); +static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx) +{ + const char *backend; + char *modulename, *params; + NTSTATUS ret = NT_STATUS_NO_MEMORY;; - /* (the passdb module is always statically linked) */ - if ( ! dom->methods) { - DEBUG(0, ("ERROR: No methods for idmap_passdb ?!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; + if (idmap_alloc_ctx != NULL) { + *ctx = idmap_alloc_ctx; + return NT_STATUS_OK; } - /* now that we have methods, set the destructor for this domain */ - talloc_set_destructor(dom, close_domain_destructor); - - if (compat_params) { - dom->params = talloc_strdup(dom, compat_params); - IDMAP_CHECK_ALLOC(dom->params); - } else { - dom->params = NULL; + idmap_alloc_ctx = talloc(NULL, struct idmap_alloc_context); + if (idmap_alloc_ctx == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; } - /* Finally instance a backend copy for this domain */ - ret = dom->methods->init(dom); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Init. failed for idmap_passdb ?!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; + backend = lp_idmap_alloc_backend(); + if ((backend == NULL) || (backend[0] == '\0')) { + backend = lp_idmap_backend(); } - idmap_domains = talloc_realloc(idmap_ctx, - idmap_domains, - struct idmap_domain *, - num_domains+1); - if ( ! idmap_domains) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; + if (backend == NULL) { + DEBUG(3, ("no idmap alloc backend defined\n")); + ret = NT_STATUS_INVALID_PARAMETER; + goto fail; } - idmap_domains[num_domains] = dom; - - /* needed to handle special BUILTIN and wellknown SIDs cases */ - pdb_dom_num = num_domains; - - DEBUG(10, ("Domain %s - Backend passdb - not default - readonly\n", - dom->name)); - - num_domains++; - /**** finished adding idmap_passdb backend ****/ - - /* sort domains so that the default is the last one */ - /* don't sort if no default domain defined */ - if (def_dom_num != -1 && def_dom_num != num_domains-1) { - /* default is not last, move it */ - struct idmap_domain *tmp; - - if (pdb_dom_num > def_dom_num) { - pdb_dom_num --; - - } else if (pdb_dom_num == def_dom_num) { /* ?? */ - pdb_dom_num = num_domains - 1; - } - - tmp = idmap_domains[def_dom_num]; - for (i = def_dom_num; i < num_domains-1; i++) { - idmap_domains[i] = idmap_domains[i+1]; - } - idmap_domains[i] = tmp; - def_dom_num = i; + if (!parse_idmap_module(idmap_alloc_ctx, backend, &modulename, + ¶ms)) { + DEBUG(1, ("parse_idmap_module %s failed\n", backend)); + goto fail; } + idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, + modulename); - /* Initialize alloc module */ - - DEBUG(3, ("Initializing idmap alloc module\n")); - - alloc_backend = NULL; - if (compat) { - alloc_backend = talloc_strdup(idmap_ctx, compat_backend); - } else { - char *ab = lp_idmap_alloc_backend(); - - if (ab && (ab[0] != '\0')) { - alloc_backend = talloc_strdup(idmap_ctx, - lp_idmap_alloc_backend()); + if (idmap_alloc_ctx->methods == NULL) { + ret = smb_probe_module("idmap", modulename); + if (NT_STATUS_IS_OK(ret)) { + idmap_alloc_ctx->methods = + get_alloc_methods(alloc_backends, + modulename); } } - if ( alloc_backend ) { - - idmap_alloc_ctx = TALLOC_ZERO_P(idmap_ctx, - struct idmap_alloc_context); - IDMAP_CHECK_ALLOC(idmap_alloc_ctx); - - idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, - alloc_backend); - if ( ! idmap_alloc_ctx->methods) { - ret = smb_probe_module("idmap", alloc_backend); - if (NT_STATUS_IS_OK(ret)) { - idmap_alloc_ctx->methods = - get_alloc_methods(alloc_backends, - alloc_backend); - } - } - if (idmap_alloc_ctx->methods) { - - if (compat_params) { - idmap_alloc_ctx->params = - talloc_strdup(idmap_alloc_ctx, - compat_params); - IDMAP_CHECK_ALLOC(idmap_alloc_ctx->params); - } else { - idmap_alloc_ctx->params = NULL; - } - - ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Initialization failed for " - "alloc backend %s, deferred!\n", - alloc_backend)); - } else { - idmap_alloc_ctx->initialized = True; - } - } else { - DEBUG(2, ("idmap_init: Unable to get methods for " - "alloc backend %s\n", - alloc_backend)); - /* certain compat backends are just readonly */ - if ( compat ) { - TALLOC_FREE(idmap_alloc_ctx); - ret = NT_STATUS_OK; - } else { - ret = NT_STATUS_UNSUCCESSFUL; - } - } + if (idmap_alloc_ctx->methods == NULL) { + DEBUG(1, ("could not find idmap alloc module %s\n", backend)); + ret = NT_STATUS_INVALID_PARAMETER; + goto fail; } - /* cleanup temporary strings */ - TALLOC_FREE( compat_backend ); - - idmap_init_status = NT_STATUS_OK; - - return ret; + ret = idmap_alloc_ctx->methods->init(params); -done: - DEBUG(0, ("Aborting IDMAP Initialization ...\n")); - idmap_close(); - - return ret; -} - -static NTSTATUS idmap_alloc_init(void) -{ - NTSTATUS ret; - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } - - if ( ! idmap_alloc_ctx) { - return NT_STATUS_NOT_SUPPORTED; + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("ERROR: Initialization failed for alloc " + "backend, deferred!\n")); + goto fail; } - if ( ! idmap_alloc_ctx->initialized) { - ret = idmap_alloc_ctx->methods->init(idmap_alloc_ctx->params); - if ( ! NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("ERROR: Initialization failed for alloc " - "backend, deferred!\n")); - return ret; - } else { - idmap_alloc_ctx->initialized = True; - } - } + TALLOC_FREE(modulename); + TALLOC_FREE(params); + *ctx = idmap_alloc_ctx; return NT_STATUS_OK; + +fail: + TALLOC_FREE(idmap_alloc_ctx); + return ret; } /************************************************************************** @@ -842,343 +526,180 @@ static NTSTATUS idmap_alloc_init(void) NTSTATUS idmap_allocate_uid(struct unixid *id) { + struct idmap_alloc_context *ctx; NTSTATUS ret; - if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { return ret; } id->type = ID_TYPE_UID; - return idmap_alloc_ctx->methods->allocate_id(id); + return ctx->methods->allocate_id(id); } NTSTATUS idmap_allocate_gid(struct unixid *id) { + struct idmap_alloc_context *ctx; NTSTATUS ret; - if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { return ret; } id->type = ID_TYPE_GID; - return idmap_alloc_ctx->methods->allocate_id(id); + return ctx->methods->allocate_id(id); } NTSTATUS idmap_set_uid_hwm(struct unixid *id) { + struct idmap_alloc_context *ctx; NTSTATUS ret; - if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { return ret; } id->type = ID_TYPE_UID; - return idmap_alloc_ctx->methods->set_id_hwm(id); + return ctx->methods->set_id_hwm(id); } NTSTATUS idmap_set_gid_hwm(struct unixid *id) { + struct idmap_alloc_context *ctx; NTSTATUS ret; - if (! NT_STATUS_IS_OK(ret = idmap_alloc_init())) { + if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { return ret; } id->type = ID_TYPE_GID; - return idmap_alloc_ctx->methods->set_id_hwm(id); -} - -/****************************************************************************** - Lookup an idmap_domain give a full user or group SID - ******************************************************************************/ - -static struct idmap_domain* find_idmap_domain_from_sid( DOM_SID *account_sid ) -{ - DOM_SID domain_sid; - uint32 rid; - struct winbindd_domain *domain = NULL; - int i; - - /* 1. Handle BUILTIN or Special SIDs and prevent them from - falling into the default domain space (if we have a - configured passdb backend. */ - - if ( (pdb_dom_num != -1) && - (sid_check_is_in_builtin(account_sid) || - sid_check_is_in_wellknown_domain(account_sid) || - sid_check_is_in_unix_groups(account_sid) || - sid_check_is_in_unix_users(account_sid)) ) - { - return idmap_domains[pdb_dom_num]; - } - - /* 2. Lookup the winbindd_domain from the account_sid */ - - sid_copy( &domain_sid, account_sid ); - sid_split_rid( &domain_sid, &rid ); - domain = find_domain_from_sid_noinit( &domain_sid ); - - for (i = 0; domain && i < num_domains; i++) { - if ( strequal( idmap_domains[i]->name, domain->name ) ) { - return idmap_domains[i]; - } - } - - /* 3. Fall back to the default domain */ - - if ( def_dom_num != -1 ) { - return idmap_domains[def_dom_num]; - } - - return NULL; + return ctx->methods->set_id_hwm(id); } -/****************************************************************************** - Lookup an index given an idmap_domain pointer - ******************************************************************************/ - -static uint32 find_idmap_domain_index( struct idmap_domain *id_domain) -{ - int i; - - for (i = 0; i < num_domains; i++) { - if ( idmap_domains[i] == id_domain ) - return i; - } - - return -1; -} - - -/********************************************************* - Check if creating a mapping is permitted for the domain -*********************************************************/ - -static NTSTATUS idmap_can_map(const struct id_map *map, - struct idmap_domain **ret_dom) +NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type, + struct unixid *pxid) { + struct dom_sid sid; struct idmap_domain *dom; + struct id_map map; + NTSTATUS status; - /* Check we do not create mappings for our own local domain, - * or BUILTIN or special SIDs */ - if ((sid_compare_domain(map->sid, get_global_sam_sid()) == 0) || - sid_check_is_in_builtin(map->sid) || - sid_check_is_in_wellknown_domain(map->sid) || - sid_check_is_in_unix_users(map->sid) || - sid_check_is_in_unix_groups(map->sid) ) - { - DEBUG(10, ("We are not supposed to create mappings for our own " - "domains (local, builtin, specials)\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - /* Special check for trusted domain only = Yes */ - if (lp_winbind_trusted_domains_only()) { - struct winbindd_domain *wdom = find_our_domain(); - if (wdom && (sid_compare_domain(map->sid, &wdom->sid) == 0)) { - DEBUG(10, ("We are not supposed to create mappings for " - "our primary domain when is True\n")); - DEBUGADD(10, ("Leave [%s] unmapped\n", - sid_string_dbg(map->sid))); - return NT_STATUS_UNSUCCESSFUL; - } - } - - if ( (dom = find_idmap_domain_from_sid( map->sid )) == NULL ) { - /* huh, couldn't find a suitable domain, - * let's just leave it unmapped */ - DEBUG(10, ("Could not find idmap backend for SID %s\n", - sid_string_dbg(map->sid))); - return NT_STATUS_NO_SUCH_DOMAIN; + dom = idmap_find_domain(NULL); + if (dom == NULL) { + DEBUG(3, ("no default domain, no place to write\n")); + return NT_STATUS_ACCESS_DENIED; } - - if (dom->readonly) { - /* ouch the domain is read only, - * let's just leave it unmapped */ - DEBUG(10, ("idmap backend for SID %s is READONLY!\n", - sid_string_dbg(map->sid))); - return NT_STATUS_UNSUCCESSFUL; + if (dom->methods->set_mapping == NULL) { + DEBUG(3, ("default domain not writable\n")); + return NT_STATUS_MEDIA_WRITE_PROTECTED; } - *ret_dom = dom; - return NT_STATUS_OK; -} - -static NTSTATUS idmap_new_mapping(TALLOC_CTX *ctx, struct id_map *map) -{ - NTSTATUS ret; - struct idmap_domain *dom; + sid_copy(&sid, psid); + map.sid = &sid; + map.xid.type = type; - /* If we are offline we cannot lookup SIDs, deny mapping */ - if (idmap_is_offline()) { - return NT_STATUS_FILE_IS_OFFLINE; - } - - ret = idmap_can_map(map, &dom); - if ( ! NT_STATUS_IS_OK(ret)) { - return NT_STATUS_NONE_MAPPED; - } - - /* check if this is a valid SID and then map it */ - switch (map->xid.type) { + switch (type) { case ID_TYPE_UID: - ret = idmap_allocate_uid(&map->xid); - if ( ! NT_STATUS_IS_OK(ret)) { - /* can't allocate id, let's just leave it unmapped */ - DEBUG(2, ("uid allocation failed! " - "Can't create mapping\n")); - return NT_STATUS_NONE_MAPPED; - } + status = idmap_allocate_uid(&map.xid); break; case ID_TYPE_GID: - ret = idmap_allocate_gid(&map->xid); - if ( ! NT_STATUS_IS_OK(ret)) { - /* can't allocate id, let's just leave it unmapped */ - DEBUG(2, ("gid allocation failed! " - "Can't create mapping\n")); - return NT_STATUS_NONE_MAPPED; - } + status = idmap_allocate_gid(&map.xid); break; default: - /* invalid sid, let's just leave it unmapped */ - DEBUG(3,("idmap_new_mapping: Refusing to create a " - "mapping for an unspecified ID type.\n")); - return NT_STATUS_NONE_MAPPED; + status = NT_STATUS_INVALID_PARAMETER; + break; } - /* ok, got a new id, let's set a mapping */ - map->status = ID_MAPPED; - - DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", - sid_string_dbg(map->sid), - (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", - (unsigned long)map->xid.id)); - ret = dom->methods->set_mapping(dom, map); - - if ( ! NT_STATUS_IS_OK(ret)) { - /* something wrong here :-( */ - DEBUG(2, ("Failed to commit mapping\n!")); - - /* TODO: would it make sense to have an "unalloc_id function?" */ - - return NT_STATUS_NONE_MAPPED; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status))); + return status; } - return NT_STATUS_OK; -} + map.status = ID_MAPPED; -static NTSTATUS idmap_backends_set_mapping(const struct id_map *map) -{ - struct idmap_domain *dom; - NTSTATUS ret; + DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", + sid_string_dbg(map.sid), + (map.xid.type == ID_TYPE_UID) ? "UID" : "GID", + (unsigned long)map.xid.id)); - DEBUG(10, ("Setting mapping %s <-> %s %lu\n", - sid_string_dbg(map->sid), - (map->xid.type == ID_TYPE_UID) ? "UID" : "GID", - (unsigned long)map->xid.id)); + status = dom->methods->set_mapping(dom, &map); - ret = idmap_can_map(map, &dom); - if ( ! NT_STATUS_IS_OK(ret)) { - return ret; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not store the new mapping: %s\n", + nt_errstr(status))); + return status; } - DEBUG(10,("set_mapping for domain %s\n", dom->name )); + *pxid = map.xid; - return dom->methods->set_mapping(dom, map); + return NT_STATUS_OK; } -NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id) +NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id) { + struct idmap_domain *dom; struct id_map *maps[2]; - int i; maps[0] = id; maps[1] = NULL; - for (i = num_domains-1; i>=0; i--) { - struct idmap_domain *dom = idmap_domains[i]; - NTSTATUS status; + /* + * Always give passdb a chance first + */ - DEBUG(10, ("Query sids from domain %s\n", dom->name)); + dom = idmap_init_passdb_domain(NULL); + if ((dom != NULL) + && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))) { + return NT_STATUS_OK; + } - status = dom->methods->unixids_to_sids(dom, maps); - if (NT_STATUS_IS_OK(status)) { - return NT_STATUS_OK; - } + dom = idmap_find_domain(domname); + if (dom == NULL) { + return NT_STATUS_NONE_MAPPED; } - return NT_STATUS_NONE_MAPPED; + return dom->methods->unixids_to_sids(dom, maps); } -NTSTATUS idmap_backends_sid_to_unixid(struct id_map *id) +NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id) { struct idmap_domain *dom; struct id_map *maps[2]; - dom = find_idmap_domain_from_sid(id->sid); - if (dom == NULL) { - return NT_STATUS_NONE_MAPPED; - } - maps[0] = id; maps[1] = NULL; - return dom->methods->sids_to_unixids(dom, maps); -} - -NTSTATUS idmap_set_mapping(const struct id_map *id) -{ - TALLOC_CTX *ctx; - NTSTATUS ret; - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } + if (sid_check_is_in_builtin(id->sid) + || (sid_check_is_in_our_domain(id->sid))) { - /* sanity checks */ - if ((id->sid == NULL) || (id->status != ID_MAPPED)) { - DEBUG(1, ("NULL SID or unmapped entry\n")); - return NT_STATUS_INVALID_PARAMETER; + dom = idmap_init_passdb_domain(NULL); + if (dom == NULL) { + return NT_STATUS_NONE_MAPPED; + } + return dom->methods->sids_to_unixids(dom, maps); } - /* TODO: check uid/gid range ? */ - - ctx = talloc_named_const(NULL, 0, "idmap_set_mapping ctx"); - if ( ! ctx) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; + dom = idmap_find_domain(domain); + if (dom == NULL) { + return NT_STATUS_NONE_MAPPED; } - /* set the new mapping */ - ret = idmap_backends_set_mapping(id); - IDMAP_CHECK_RET(ret); - -done: - talloc_free(ctx); - return ret; + return dom->methods->sids_to_unixids(dom, maps); } -char *idmap_fetch_secret(const char *backend, bool alloc, - const char *domain, const char *identity) +NTSTATUS idmap_set_mapping(const struct id_map *map) { - char *tmp, *ret; - int r; + struct idmap_domain *dom; - if (alloc) { - r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend); - } else { - r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); + dom = idmap_find_domain(NULL); + if (dom == NULL) { + DEBUG(3, ("no default domain, no place to write\n")); + return NT_STATUS_ACCESS_DENIED; + } + if (dom->methods->set_mapping == NULL) { + DEBUG(3, ("default domain not writable\n")); + return NT_STATUS_MEDIA_WRITE_PROTECTED; } - if (r < 0) - return NULL; - - strupper_m(tmp); /* make sure the key is case insensitive */ - ret = secrets_fetch_generic(tmp, identity); - - SAFE_FREE(tmp); - - return ret; + return dom->methods->set_mapping(dom, map); } - -- cgit From 18bc97287cbaffb03a54c0b1e635d443a3d54d8d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 17 Jul 2008 13:32:28 +0200 Subject: Some doxygen comments for idmap (This used to be commit adecc6d91338e7e34afd0672aada5d0e47247a33) --- source3/winbindd/idmap.c | 101 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 10 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index bace38876b..c23919fb18 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -28,37 +28,59 @@ static_decl_idmap; +/** + * Pointer to the backend methods. Modules register themselves here via + * smb_register_idmap. + */ + struct idmap_backend { const char *name; struct idmap_methods *methods; struct idmap_backend *prev, *next; }; +static struct idmap_backend *backends = NULL; +/** + * Pointer to the alloc backend methods. Modules register themselves here via + * smb_register_idmap_alloc. + */ struct idmap_alloc_backend { const char *name; struct idmap_alloc_methods *methods; struct idmap_alloc_backend *prev, *next; }; +static struct idmap_alloc_backend *alloc_backends = NULL; +/** + * The idmap alloc context that is configured via "idmap alloc + * backend". Defaults to "idmap backend" in case the module (tdb, ldap) also + * provides alloc methods. + */ struct idmap_alloc_context { struct idmap_alloc_methods *methods; }; +static struct idmap_alloc_context *idmap_alloc_ctx = NULL; -/* - * Lists for the module initializations +/** + * Default idmap domain configured via "idmap backend". */ -static struct idmap_backend *backends = NULL; -static struct idmap_alloc_backend *alloc_backends = NULL; - - static struct idmap_domain *default_idmap_domain; + +/** + * Passdb idmap domain, not configurable. winbind must always give passdb a + * chance to map ids. + */ static struct idmap_domain *passdb_idmap_domain; +/** + * List of specially configured idmap domains. This list is filled on demand + * in the winbind idmap child when the parent winbind figures out via the + * special range parameter or via the domain SID that a special "idmap config + * domain" configuration is present. + */ static struct idmap_domain **idmap_domains = NULL; static int num_domains = 0; -static struct idmap_alloc_context *idmap_alloc_ctx = NULL; - static struct idmap_methods *get_methods(struct idmap_backend *be, const char *name) { @@ -126,7 +148,8 @@ NTSTATUS smb_register_idmap(int version, const char *name, for (entry = backends; entry != NULL; entry = entry->next) { if (strequal(entry->name, name)) { - DEBUG(0,("Idmap module %s already registered!\n", name)); + DEBUG(0,("Idmap module %s already registered!\n", + name)); return NT_STATUS_OBJECT_NAME_COLLISION; } } @@ -151,7 +174,7 @@ NTSTATUS smb_register_idmap(int version, const char *name, } /********************************************************************** - Allow a module to register itself as a method. + Allow a module to register itself as an alloc method. **********************************************************************/ NTSTATUS smb_register_idmap_alloc(int version, const char *name, @@ -249,6 +272,14 @@ static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param, return true; } +/** + * Initialize a domain structure + * @param[in] mem_ctx memory context for the result + * @param[in] domainname which domain is this for + * @param[in] modulename which backend module + * @param[in] params parameter to pass to the init function + * @result The initialized structure + */ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, const char *domainname, const char *modulename, @@ -303,6 +334,15 @@ 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) { struct idmap_domain *result; @@ -337,6 +377,16 @@ fail: return NULL; } +/** + * Initialize a named domain structure + * @param[in] mem_ctx memory context for the result + * @param[in] domname the domain name + * @result The default domain structure + * + * This routine looks at the "idmap config " parameters to figure out + * the configuration. + */ + static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx, const char *domname) { @@ -371,6 +421,14 @@ fail: return NULL; } +/** + * 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_init_passdb_domain(TALLOC_CTX *mem_ctx) { if (passdb_idmap_domain != NULL) { @@ -386,6 +444,21 @@ static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx) return passdb_idmap_domain; } +/** + * Find a domain struct according to a domain name + * @param[in] domname Domain name to get the config for + * @result The default domain structure that fits + * + * This is the central routine in the winbindd-idmap child to pick the correct + * domain for looking up IDs. If domname is NULL or empty, we use the default + * domain. If it contains something, we try to use idmap_init_named_domain() + * to fetch the correct backend. + * + * The choice about "domname" is being made by the winbind parent, look at the + * "have_idmap_config" of "struct winbindd_domain" which is set in + * add_trusted_domain. + */ + static struct idmap_domain *idmap_find_domain(const char *domname) { struct idmap_domain *result; @@ -449,6 +522,14 @@ void idmap_close(void) num_domains = 0; } +/** + * Initialize the idmap alloc backend + * @param[out] ctx Where to put the alloc_ctx? + * @result Did it work fine? + * + * This routine first looks at "idmap alloc backend" and if that is not + * defined, it uses "idmap backend" for the module name. + */ static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx) { const char *backend; -- cgit From 620d87318381a417e3f0843e8cb5f0257ebf9873 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 7 Aug 2008 02:03:22 +0200 Subject: idmap tdb2: fix inconsistent mappings by checking for race and retrying to fetch mapping. Michael (This used to be commit cb4c74c9c206e5a445ca636fa6562ce721ea5839) --- source3/winbindd/idmap.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index c23919fb18..2962fe6c1c 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -705,6 +705,15 @@ NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type, status = dom->methods->set_mapping(dom, &map); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + struct id_map *ids[2]; + DEBUG(5, ("Mapping for %s exists - retrying to map sid\n", + sid_string_dbg(map.sid))); + ids[0] = ↦ + ids[1] = NULL; + status = dom->methods->sids_to_unixids(dom, ids); + } + if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not store the new mapping: %s\n", nt_errstr(status))); -- cgit From 24992010cb57556ee2b65776f26e586ea0e3895d Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 4 Sep 2008 14:35:27 -0700 Subject: get rid of unneeded argument in get_methods and get_alloc_methods (This used to be commit 07b0323472b78d49cff06b78924c3015bea52a30) --- source3/winbindd/idmap.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'source3/winbindd/idmap.c') diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 2962fe6c1c..cfc5597f42 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -81,12 +81,11 @@ static struct idmap_domain *passdb_idmap_domain; static struct idmap_domain **idmap_domains = NULL; static int num_domains = 0; -static struct idmap_methods *get_methods(struct idmap_backend *be, - const char *name) +static struct idmap_methods *get_methods(const char *name) { struct idmap_backend *b; - for (b = be; b; b = b->next) { + for (b = backends; b; b = b->next) { if (strequal(b->name, name)) { return b->methods; } @@ -95,13 +94,11 @@ static struct idmap_methods *get_methods(struct idmap_backend *be, return NULL; } -static struct idmap_alloc_methods *get_alloc_methods( - struct idmap_alloc_backend *be, - const char *name) +static struct idmap_alloc_methods *get_alloc_methods(const char *name) { struct idmap_alloc_backend *b; - for (b = be; b; b = b->next) { + for (b = alloc_backends; b; b = b->next) { if (strequal(b->name, name)) { return b->methods; } @@ -199,7 +196,7 @@ NTSTATUS smb_register_idmap_alloc(int version, const char *name, return NT_STATUS_INVALID_PARAMETER; } - test = get_alloc_methods(alloc_backends, name); + test = get_alloc_methods(name); if (test) { DEBUG(0,("idmap_alloc module %s already registered!\n", name)); return NT_STATUS_OBJECT_NAME_COLLISION; @@ -300,7 +297,7 @@ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, goto fail; } - result->methods = get_methods(backends, modulename); + result->methods = get_methods(modulename); if (result->methods == NULL) { DEBUG(3, ("idmap backend %s not found\n", modulename)); @@ -311,7 +308,7 @@ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, goto fail; } - result->methods = get_methods(backends, modulename); + result->methods = get_methods(modulename); } if (result->methods == NULL) { DEBUG(1, ("idmap backend %s not found\n", modulename)); @@ -564,15 +561,13 @@ static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx) goto fail; } - idmap_alloc_ctx->methods = get_alloc_methods(alloc_backends, - modulename); + idmap_alloc_ctx->methods = get_alloc_methods(modulename); if (idmap_alloc_ctx->methods == NULL) { ret = smb_probe_module("idmap", modulename); if (NT_STATUS_IS_OK(ret)) { idmap_alloc_ctx->methods = - get_alloc_methods(alloc_backends, - modulename); + get_alloc_methods(modulename); } } -- cgit