summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2007-01-22 16:54:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:21 -0500
commit37cc3e3d62a5bfad80a666839b8b0b78472ac11d (patch)
treec9b4b005cc340e566a6568db8a6fec89cbb14a76
parent0de21e951544b5ee85b074427bda30fff3a1c9f4 (diff)
downloadsamba-37cc3e3d62a5bfad80a666839b8b0b78472ac11d.tar.gz
samba-37cc3e3d62a5bfad80a666839b8b0b78472ac11d.tar.bz2
samba-37cc3e3d62a5bfad80a666839b8b0b78472ac11d.zip
r20951: Remove the DOM_SID field in the struct idmap_domain and bounce
domain SID lookups through the struct winbindd_domain *domain_list by searching by name. Refactor the order lookup when searching for the correct idmap_domain to a single function and remove the requirement that the default domain be listed first in the config file. I would still like to make the idmap_domain array a linked list and remove the existing code which makes use of indexes into the list. Basic testing with tdb pans out ok. (This used to be commit e6c300829ff08dd354f6e9460d396261681e4809)
-rw-r--r--source3/include/idmap.h1
-rw-r--r--source3/nsswitch/idmap.c239
-rw-r--r--source3/nsswitch/idmap_rid.c30
3 files changed, 128 insertions, 142 deletions
diff --git a/source3/include/idmap.h b/source3/include/idmap.h
index 069aaa73a3..80bd541a23 100644
--- a/source3/include/idmap.h
+++ b/source3/include/idmap.h
@@ -37,7 +37,6 @@
#define SMB_IDMAP_INTERFACE_VERSION 4
struct idmap_domain {
- DOM_SID *sid;
const char *name;
BOOL default_domain;
BOOL readonly;
diff --git a/source3/nsswitch/idmap.c b/source3/nsswitch/idmap.c
index 2bcff7b717..6e3e125ae4 100644
--- a/source3/nsswitch/idmap.c
+++ b/source3/nsswitch/idmap.c
@@ -18,7 +18,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
#include "includes.h"
#include "winbindd.h"
@@ -225,7 +226,7 @@ NTSTATUS idmap_close(void)
static const char *idmap_default_domain[] = { "default domain", NULL };
NTSTATUS idmap_init(void)
-{
+{
NTSTATUS ret;
struct idmap_domain *dom;
const char *compat_backend = NULL;
@@ -241,27 +242,23 @@ NTSTATUS idmap_init(void)
return NT_STATUS_OK;
}
- idmap_ctx = talloc_named_const(NULL, 0, "IDMAP MEMORY CONTEXT");
- if ( ! idmap_ctx) {
+ if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
return NT_STATUS_NO_MEMORY;
}
- /* init cache */
- idmap_cache = idmap_cache_init(idmap_ctx);
- if ( ! idmap_cache) {
+ if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
return NT_STATUS_UNSUCCESSFUL;
}
- /* register static backends */
static_init_idmap;
- if ((dom_list = lp_idmap_domains()) != NULL) {
- if (lp_idmap_backend()) {
- DEBUG(0, ("WARNING: idmap backend and idmap domains are mutually excusive!\n"));
- DEBUGADD(0, (" idmap backend option will be IGNORED!\n"));
- }
-
- } else if (lp_idmap_backend()) {
+ dom_list = lp_idmap_domains();
+
+ if ( dom_list && lp_idmap_backend() ) {
+ DEBUG(0, ("WARNING: idmap backend and idmap domains are "
+ "mutually excusive!\n"));
+ DEBUGADD(0,("idmap backend option will be IGNORED!\n"));
+ } else if ( lp_idmap_backend() ) {
const char **compat_list = lp_idmap_backend();
const char *p;
@@ -313,19 +310,13 @@ NTSTATUS idmap_init(void)
/* 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])) {
- /* the default domain is a cacth all domain
- * so no specific domain sid is provided */
- dom->sid = NULL;
+
/* make sure this is set even when we match idmap_default_domain[0] */
dom->default_domain = True;
- if (lp_parm_const_string(-1, config_option, "domain sid", NULL)) {
- DEBUG(1, ("WARNING: Can't force a /domain sid/ on the DEFAULT domain, Ignoring!"));
- }
-
- /* only one default domain is permitted */
if (default_already_defined) {
DEBUG(1, ("ERROR: Multiple domains defined as default!\n"));
ret = NT_STATUS_INVALID_PARAMETER;
@@ -334,38 +325,16 @@ NTSTATUS idmap_init(void)
default_already_defined = True;
- } else {
- const char *sid;
+ }
- sid = lp_parm_const_string(-1, config_option, "domain sid", NULL);
- if (sid) {
- dom->sid = string_sid_talloc(dom, sid);
- } else {
- struct winbindd_domain *wdom = find_domain_from_name(dom->name);
- if (wdom) {
- dom->sid = sid_dup_talloc(dom, &wdom->sid);
- IDMAP_CHECK_ALLOC(dom->sid);
- }
- }
-
- if ( ! dom->sid) {
- DEBUG(1, ("ERROR: Could not find DOMAIN SID for domain %s\n", dom->name));
- DEBUGADD(1, (" Consider to set explicitly the /domain sid/ option\n"));
- ret = NT_STATUS_NO_SUCH_DOMAIN;
- goto done;
- }
- }
-
- /* is this a readonly domain ? */
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"));
+ parm_backend = talloc_strdup(idmap_ctx,
+ lp_parm_const_string(-1, config_option, "backend", "tdb"));
}
IDMAP_CHECK_ALLOC(parm_backend);
@@ -412,8 +381,8 @@ NTSTATUS idmap_init(void)
def_dom_num = i;
}
- DEBUG(10, ("Domain %s - Sid %s - Backend %s - %sdefault - %sreadonly\n",
- dom->name, sid_string_static(dom->sid), parm_backend,
+ DEBUG(10, ("Domain %s - Backend %s - %sdefault - %sreadonly\n",
+ dom->name, parm_backend,
dom->default_domain?"":"not ", dom->readonly?"":"not "));
talloc_free(config_option);
@@ -426,13 +395,6 @@ NTSTATUS idmap_init(void)
if ((lp_server_role() == ROLE_DOMAIN_MEMBER) &&
( ! pri_dom_is_in_list) &&
lp_winbind_trusted_domains_only()) {
- DOM_SID our_sid;
-
- if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
- DEBUG(0, ("Could not fetch our SID - did we join?\n"));
- ret = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
dom = talloc_zero(idmap_ctx, struct idmap_domain);
IDMAP_CHECK_ALLOC(dom);
@@ -443,9 +405,6 @@ NTSTATUS idmap_init(void)
dom->default_domain = False;
dom->readonly = True;
- dom->sid = sid_dup_talloc(dom, &our_sid);
- IDMAP_CHECK_ALLOC(dom->sid);
-
/* get the backend methods for passdb */
dom->methods = get_methods(backends, "nss");
@@ -475,8 +434,7 @@ NTSTATUS idmap_init(void)
}
idmap_domains[num_domains] = dom;
- DEBUG(10, ("Domain %s - Sid %s - Backend nss - not default - readonly\n",
- dom->name, sid_string_static(dom->sid)));
+ DEBUG(10, ("Domain %s - Backend nss - not default - readonly\n", dom->name ));
num_domains++;
}
@@ -491,9 +449,6 @@ NTSTATUS idmap_init(void)
dom->default_domain = False;
dom->readonly = True;
- dom->sid = sid_dup_talloc(dom, get_global_sam_sid());
- IDMAP_CHECK_ALLOC(dom->sid);
-
/* get the backend methods for passdb */
dom->methods = get_methods(backends, "passdb");
@@ -526,9 +481,7 @@ NTSTATUS idmap_init(void)
/* needed to handle special BUILTIN and wellknown SIDs cases */
pdb_dom_num = num_domains;
- DEBUG(10, ("Domain %s - Sid %s - Backend passdb - not default - readonly\n",
- dom->name, sid_string_static(dom->sid)));
- DEBUGADD(10, (" (special: includes handling BUILTIN and Wellknown SIDs as well)\n"));
+ DEBUG(10, ("Domain %s - Backend passdb - not default - readonly\n", dom->name));
num_domains++;
/**** finished adding idmap_passdb backend ****/
@@ -652,6 +605,66 @@ NTSTATUS idmap_set_gid_hwm(struct unixid *id)
return alloc_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)) )
+ {
+ 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
*********************************************************/
@@ -659,7 +672,6 @@ NTSTATUS idmap_set_gid_hwm(struct unixid *id)
static NTSTATUS idmap_can_map(const struct id_map *map, struct idmap_domain **ret_dom)
{
struct idmap_domain *dom;
- int i;
/* 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) ||
@@ -679,23 +691,15 @@ static NTSTATUS idmap_can_map(const struct id_map *map, struct idmap_domain **re
}
}
- for (i = 0, dom = NULL; i < num_domains; i++) {
- if ((idmap_domains[i]->default_domain) || /* ok set it into the default domain */
- (sid_compare_domain(idmap_domains[i]->sid, map->sid) == 0)) { /* ok found a specific domain */
- dom = idmap_domains[i];
- break;
- }
- }
-
- if (! dom) {
+ 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 imdap backend for SID %s", sid_string_static(map->sid)));
+ 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, ("imdap backend for SID %s is READONLY!\n", sid_string_static(map->sid)));
+ DEBUG(10, ("idmap backend for SID %s is READONLY!\n", sid_string_static(map->sid)));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -790,7 +794,7 @@ static NTSTATUS idmap_backends_set_mapping(const struct id_map *map)
return ret;
}
- DEBUG(10, ("set_mapping for domain %s(%s)\n", dom->name, sid_string_static(dom->sid)));
+ DEBUG(10,("set_mapping for domain %s\n", dom->name ));
return dom->methods->set_mapping(dom, map);
}
@@ -832,7 +836,7 @@ static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids)
dom = idmap_domains[n];
- DEBUG(10, ("Query sids from domain %s(%s)\n", dom->name, sid_string_static(dom->sid)));
+ DEBUG(10, ("Query sids from domain %s\n", dom->name));
ret = dom->methods->unixids_to_sids(dom, _ids);
IDMAP_CHECK_RET(ret);
@@ -892,13 +896,7 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
NTSTATUS ret;
int i, *counters;
- if (!ids || !*ids) {
- DEBUG(1, ("Invalid list of maps\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- ctx = talloc_named_const(NULL, 0, "idmap_backends_sids_to_unixids ctx");
- if ( ! ctx) {
+ 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;
}
@@ -906,66 +904,47 @@ static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids)
DEBUG(10, ("Query backends to map sids->ids\n"));
/* split list per domain */
+
dom_ids = talloc_zero_array(ctx, struct id_map **, num_domains);
IDMAP_CHECK_ALLOC(dom_ids);
counters = talloc_zero_array(ctx, int, num_domains);
+ /* partition the requests by domain */
+
for (i = 0; ids[i]; i++) {
- int dom_num;
+ uint32 idx;
/* make sure they are unknown to start off */
ids[i]->status = ID_UNKNOWN;
- for (dom_num = 0, dom = NULL; dom_num < num_domains; dom_num++) {
- if (idmap_domains[dom_num]->default_domain) {
- /* we got to the default domain */
- dom = idmap_domains[dom_num];
- break;
- }
- if (sid_compare_domain(idmap_domains[dom_num]->sid, ids[i]->sid) == 0) {
- dom = idmap_domains[dom_num];
- break;
- }
- }
- if (( ! dom) || dom->default_domain) {
- /* handle BUILTIN or Special SIDs
- * and prevent them from falling into the default domain space */
- if ((sid_check_is_in_builtin(ids[i]->sid) ||
- sid_check_is_in_wellknown_domain(ids[i]->sid))) {
-
- if (pdb_dom_num != -1) {
- dom = idmap_domains[pdb_dom_num];
- dom_num = pdb_dom_num;
- } else {
- dom = NULL;
- }
- }
- }
- if ( ! dom) {
- /* no dom move on */
+ if ( (dom = find_idmap_domain_from_sid( ids[i]->sid )) == NULL ) {
+ /* no vailable idmap_domain. Move on */
continue;
}
- DEBUG(10, ("SID %s is being handled by %s(%d)\n",
- sid_string_static(ids[i]->sid),
- dom?dom->name:"none",
- dom_num));
+ DEBUG(10,("SID %s is being handled by %s\n",
+ sid_string_static(ids[i]->sid),
+ dom ? dom->name : "none" ));
- dom_ids[dom_num] = talloc_realloc(ctx, dom_ids[dom_num], struct id_map *, counters[dom_num] + 2);
- IDMAP_CHECK_ALLOC(dom_ids[dom_num]);
+ 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[dom_num][counters[dom_num]] = ids[i];
- counters[dom_num]++;
- dom_ids[dom_num][counters[dom_num]] = NULL;
+ dom_ids[idx][counters[idx]] = ids[i];
+ counters[idx]++;
+ dom_ids[idx][counters[idx]] = NULL;
}
- /* ok all the ids have been dispatched in the right queues
- * let's cycle through the filled ones */
+ /* 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]) { /* ok, we have ids in this one */
+ if (dom_ids[i]) {
dom = idmap_domains[i];
- DEBUG(10, ("Query ids from domain %s(%s)\n", dom->name, sid_string_static(dom->sid)));
+ DEBUG(10, ("Query ids from domain %s\n", dom->name));
ret = dom->methods->sids_to_unixids(dom, dom_ids[i]);
IDMAP_CHECK_RET(ret);
}
diff --git a/source3/nsswitch/idmap_rid.c b/source3/nsswitch/idmap_rid.c
index 5949aa4ba5..298d6fed35 100644
--- a/source3/nsswitch/idmap_rid.c
+++ b/source3/nsswitch/idmap_rid.c
@@ -26,13 +26,17 @@
#define DBGC_CLASS DBGC_IDMAP
struct idmap_rid_context {
- DOM_SID dom_sid;
+ const char *domain_name;
uint32_t low_id;
uint32_t high_id;
uint32_t base_rid;
};
-/* compat params can't be used because of the completely different way we support multiple domains in the new idmap */
+/******************************************************************************
+ compat params can't be used because of the completely different way
+ we support multiple domains in the new idmap
+ *****************************************************************************/
+
static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom, const char *compat_params)
{
NTSTATUS ret;
@@ -40,8 +44,7 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom, const char *compa
char *config_option = NULL;
const char *range;
- ctx = talloc_zero(dom, struct idmap_rid_context);
- if ( ! ctx) {
+ if ( (ctx = talloc_zero(dom, struct idmap_rid_context)) == NULL ) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -54,23 +57,23 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom, const char *compa
}
range = lp_parm_const_string(-1, config_option, "range", NULL);
- if (( ! range) ||
+ if ( !range ||
(sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) ||
- (ctx->low_id > ctx->high_id)) {
+ (ctx->low_id > ctx->high_id))
+ {
ctx->low_id = 0;
ctx->high_id = 0;
}
- if (( ! ctx->low_id) || ( ! ctx->high_id)) {
+ if ( !ctx->low_id || !ctx->high_id ) {
DEBUG(1, ("ERROR: Invalid configuration, ID range missing\n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
-
- sid_copy(&ctx->dom_sid, dom->sid);
-
+ ctx->domain_name = talloc_strdup( ctx, dom->name );
+
dom->private_data = ctx;
talloc_free(config_option);
@@ -86,6 +89,7 @@ static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context
const char *domname, *name;
enum lsa_SidType sid_type;
BOOL ret;
+ struct winbindd_domain *domain;
/* apply filters before checking */
if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
@@ -94,7 +98,11 @@ static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context
return NT_STATUS_NONE_MAPPED;
}
- sid_compose(map->sid, &ctx->dom_sid, map->xid.id - ctx->low_id + ctx->base_rid);
+ if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);
/* by default calls to winbindd are disabled
the following call will not recurse so this is safe */