From 6f46002ff6b153730635bfd4a8380792a815ce6b Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Thu, 25 Sep 2008 10:43:56 -0700 Subject: idmap: Fix typo is gid2sid() that was caching using idmap_cache_set_sid2uid() --- source3/winbindd/idmap_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index b10a1a4ba9..9f876618be 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -121,7 +121,7 @@ backend: return NT_STATUS_NONE_MAPPED; } - idmap_cache_set_sid2uid(sid, gid); + idmap_cache_set_sid2gid(sid, gid); return NT_STATUS_OK; } -- cgit From b8c9daac6eb8a2bcdb14c71c1ddfbfeba4b9b54d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Sep 2008 16:15:40 +1000 Subject: fixed segv on startup with trusted domains With some setups, idmap_tdb2_allocate_id can be called before the allocate backend is initialised, leading to a segv. This change ensures that the db is opened in all paths that use it --- source3/winbindd/idmap_tdb2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c index 3066db6f3b..911f80c6a3 100644 --- a/source3/winbindd/idmap_tdb2.c +++ b/source3/winbindd/idmap_tdb2.c @@ -187,6 +187,10 @@ static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid) uint32_t high_hwm; uint32_t hwm; int res; + NTSTATUS status; + + status = idmap_tdb2_open_db(); + NT_STATUS_NOT_OK_RETURN(status); /* Get current high water mark */ switch (xid->type) { @@ -264,6 +268,10 @@ static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid) const char *hwmtype; uint32_t hwm; uint32_t high_hwm; + NTSTATUS status; + + status = idmap_tdb2_open_db(); + NT_STATUS_NOT_OK_RETURN(status); /* Get current high water mark */ switch (xid->type) { @@ -451,6 +459,10 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_m NTSTATUS ret; TDB_DATA data; char *keystr; + NTSTATUS status; + + status = idmap_tdb2_open_db(); + NT_STATUS_NOT_OK_RETURN(status); if (!ctx || !map) { return NT_STATUS_INVALID_PARAMETER; @@ -546,6 +558,10 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_m TDB_DATA data; char *keystr; unsigned long rec_id = 0; + NTSTATUS status; + + status = idmap_tdb2_open_db(); + NT_STATUS_NOT_OK_RETURN(status); if ((keystr = sid_string_talloc(ctx, map->sid)) == NULL) { DEBUG(0, ("Out of memory!\n")); -- cgit From a93dc2c8589428e409fca5a6c21db50db001fe92 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Sep 2008 16:23:17 +1000 Subject: removed unused variables --- source3/winbindd/idmap_tdb2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c index 911f80c6a3..8bde963c60 100644 --- a/source3/winbindd/idmap_tdb2.c +++ b/source3/winbindd/idmap_tdb2.c @@ -94,12 +94,11 @@ static NTSTATUS idmap_tdb2_open_db(void) */ static NTSTATUS idmap_tdb2_alloc_load(void) { - const char *range; uid_t low_uid = 0; uid_t high_uid = 0; gid_t low_gid = 0; gid_t high_gid = 0; - uint32 low_id, high_id; + uint32 low_id; /* see if a idmap script is configured */ idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", -- cgit From 86612b1163d2dae8f707b6a038ad1a361c975973 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Sep 2008 15:37:54 +1000 Subject: re-added "winbind:ignore domains" patch This option really is essential, as we discover again and again at customer sites. Due to bugs in winbind some domains are toxic. When you are installing at a site and a particular domain in a complex setup causes winbind to segfault or hang then you need a way to disable that domain and continue. In an ideal world winbind could handle arbitrarily complex ADS domains, but we are nowhere near that yet. If we ever get to that stage then we won't need this option. --- source3/winbindd/winbindd_util.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 5b5ca41a74..b8cb27c797 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -111,7 +111,16 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const const char *alternative_name = NULL; char *idmap_config_option; const char *param; + const char **ignored_domains, **dom; + ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL); + for (dom=ignored_domains; dom && *dom; dom++) { + if (gen_fnmatch(*dom, domain_name) == 0) { + DEBUG(2,("Ignoring domain '%s'\n", domain_name)); + return NULL; + } + } + /* ignore alt_name if we are not in an AD domain */ if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) { @@ -436,6 +445,10 @@ static void rescan_forest_root_trusts( void ) &dom_list[i].sid ); } + if (d == NULL) { + continue; + } + DEBUG(10,("rescan_forest_root_trusts: Following trust path " "for domain tree root %s (%s)\n", d->name, d->alt_name )); @@ -500,6 +513,10 @@ static void rescan_forest_trusts( void ) &cache_methods, &dom_list[i].sid ); } + + if (d == NULL) { + continue; + } DEBUG(10,("Following trust path for domain %s (%s)\n", d->name, d->alt_name )); -- cgit From e4f5bfb34b7a515e2cf107eb94489260594b8733 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 2008 13:15:54 -0700 Subject: Fix use of DLIST_REMOVE as spotted by Constantine Vetoshev . This API is unusual in that if used to remove a non-list head it nulls out the next and prev pointers. This is what you want for debugging (don't want an entry removed from the list to be still virtually linked into it) but means there is no consistent idiom for use as the next and prev pointers get trashed on removal from the list, meaning you must save them yourself. You can use it one way when deleting everything via the head pointer, as this preserves the next pointer, but you *must* use it another way when not deleting everything via the head pointer. Fix all known uses of this (the main one is in conn_free_internal() and would not free all the private data entries for vfs modules. The other changes in web/statuspage.c and winbindd_util.c are not strictly neccessary, as the head pointer is being used, but I've done them for consistency. Long term we must revisit this as this API is too hard to use correctly. Jeremy. --- source3/winbindd/winbindd_util.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/winbindd') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index b8cb27c797..fdfc8ed9d1 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1075,13 +1075,12 @@ void free_getent_state(struct getent_state *state) temp = state; while(temp != NULL) { - struct getent_state *next; + struct getent_state *next = temp->next; /* Free sam entries then list entry */ SAFE_FREE(state->sam_entries); DLIST_REMOVE(state, state); - next = temp->next; SAFE_FREE(temp); temp = next; -- cgit From 6aa8613b11b596fed115849262e96524b84a8fbe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 6 Oct 2008 10:57:13 +0200 Subject: Log in the parent winbind log where a request is going --- source3/winbindd/winbindd_dual.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 1600f05eb1..f6a9c1f26d 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -120,6 +120,10 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, SMB_ASSERT(continuation != NULL); + DEBUG(10, ("Sending request to child pid %d (domain=%s)\n", + (int)child->pid, + (child->domain != NULL) ? child->domain->name : "''")); + state = TALLOC_P(mem_ctx, struct winbindd_async_request); if (state == NULL) { -- cgit From 338f658a5a300e21cc69b1a84ebbdc7d63262448 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Mon, 6 Oct 2008 11:34:45 -0500 Subject: idmap_adex: Add log messages to dc_add_domain for easier debugging. Part of continue work on BUG 5806. --- source3/winbindd/idmap_adex/domain_util.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_adex/domain_util.c b/source3/winbindd/idmap_adex/domain_util.c index ab31ccef7a..6851503cc8 100644 --- a/source3/winbindd/idmap_adex/domain_util.c +++ b/source3/winbindd/idmap_adex/domain_util.c @@ -49,6 +49,12 @@ static NTSTATUS dc_add_domain(const char *domain) NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct dc_info *dc = NULL; + if (!domain) { + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain)); + /* Check for duplicates */ dc = dc_list_head(); @@ -73,6 +79,8 @@ static NTSTATUS dc_add_domain(const char *domain) nt_status = NT_STATUS_OK; + DEBUG(5,("dc_add_domain: Successfully added %s\n", domain)); + done: if (!NT_STATUS_IS_OK(nt_status)) { talloc_destroy(dc); -- cgit From 2a35985283be45adbba63b5d7ced8499bcb64f59 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Mon, 6 Oct 2008 11:47:57 -0500 Subject: idmap_adex: Add more debugging to the basic search function. Log the dn of all located entries in order to verify search results. --- source3/winbindd/idmap_adex/likewise_cell.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/idmap_adex/likewise_cell.c b/source3/winbindd/idmap_adex/likewise_cell.c index 77eeee406b..7723b3e015 100644 --- a/source3/winbindd/idmap_adex/likewise_cell.c +++ b/source3/winbindd/idmap_adex/likewise_cell.c @@ -389,6 +389,24 @@ done: status = ads_do_search(c->conn, search_base, scope, expr, attrs, msg); if (ADS_ERR_OK(status)) { + if (DEBUGLEVEL >= 10) { + LDAPMessage *e = NULL; + + int n = ads_count_replies(c->conn, *msg); + + DEBUG(10,("cell_do_search: Located %d entries\n", n)); + + for (e=ads_first_entry(c->conn, *msg); + e!=NULL; + e = ads_next_entry(c->conn, e)) + { + char *dn = ads_get_dn(c->conn, e); + + DEBUGADD(10,(" dn: %s\n", dn ? dn : "")); + SAFE_FREE(dn); + } + } + return status; } -- cgit From 14f835ba4b7e553d0cd75f3b311378c5c875e87c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Oct 2008 11:39:32 -0700 Subject: Fix bug #5814 - Winbindd dumping core in a strange manner while doing "rescan_trusted_domain". From analysis by hargagan : "The winbindd_child_died() is also getting called from process_loop() in case of SIGCHLD signal. In this case it doesn't make the timeout_handler to NULL for the first request. It then initiate a new request using schedule_async_request() which installs a new timeout handler for the same request. In such a case, for a badly unresponsive system both the timeout handler can be called. For the first call the "private_data" will be cleared and for another call the timeout handler will be detecting the double free. So, for such a case as well, the winbindd_child_died() should make the timeout_handler to NULL." Jeremy. --- source3/winbindd/winbindd_dual.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'source3/winbindd') diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index f6a9c1f26d..aeb52d9b5a 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -300,6 +300,18 @@ static void schedule_async_request(struct winbindd_child *child) return; /* Busy */ } + /* + * This may be a reschedule, so we might + * have an existing timeout event pending on + * the first entry in the child->requests list + * (we only send one request at a time). + * Ensure we free it before we reschedule. + * Bug #5814, from hargagan . + * JRA. + */ + + TALLOC_FREE(request->reply_timeout_event); + if ((child->pid == 0) && (!fork_domain_child(child))) { /* fork_domain_child failed. Cancel all outstanding requests */ @@ -495,6 +507,17 @@ void winbind_child_died(pid_t pid) child->event.flags = 0; child->pid = 0; + if (child->requests) { + /* + * schedule_async_request() will also + * clear this event but the call is + * idempotent so it doesn't hurt to + * cover all possible future code + * paths. JRA. + */ + TALLOC_FREE(child->requests->reply_timeout_event); + } + schedule_async_request(child); } -- cgit From 76a8da6f711ce13de6c4e3e1af6714b0475b71f5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 27 Sep 2008 03:09:07 +0200 Subject: s3-winbindd: use new, richer structures in WINBINDD_DSGETDCNAME implementation. Guenther --- source3/winbindd/winbindd_locator.c | 61 ++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 21 deletions(-) (limited to 'source3/winbindd') diff --git a/source3/winbindd/winbindd_locator.c b/source3/winbindd/winbindd_locator.c index b2a8bd7e30..b60d235f70 100644 --- a/source3/winbindd/winbindd_locator.c +++ b/source3/winbindd/winbindd_locator.c @@ -45,11 +45,15 @@ struct winbindd_child *locator_child(void) void winbindd_dsgetdcname(struct winbindd_cli_state *state) { - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; + state->request.data.dsgetdcname.domain_name + [sizeof(state->request.data.dsgetdcname.domain_name)-1] = '\0'; + state->request.data.dsgetdcname.site_name + [sizeof(state->request.data.dsgetdcname.site_name)-1] = '\0'; + state->request.data.dsgetdcname.domain_guid + [sizeof(state->request.data.dsgetdcname.domain_guid)-1] = '\0'; DEBUG(3, ("[%5lu]: dsgetdcname for %s\n", (unsigned long)state->pid, - state->request.domain_name)); + state->request.data.dsgetdcname.domain_name)); sendto_child(state, locator_child()); } @@ -94,44 +98,59 @@ static uint32_t get_dsgetdc_flags(uint32_t wbc_flags) return ds_flags; } - static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain, struct winbindd_cli_state *state) { NTSTATUS result; struct netr_DsRGetDCNameInfo *info = NULL; - const char *dc = NULL; uint32_t ds_flags = 0; + struct GUID guid, *guid_ptr = NULL; + const char *guid_str = NULL; - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; + state->request.data.dsgetdcname.domain_name + [sizeof(state->request.data.dsgetdcname.domain_name)-1] = '\0'; + state->request.data.dsgetdcname.site_name + [sizeof(state->request.data.dsgetdcname.site_name)-1] = '\0'; + state->request.data.dsgetdcname.domain_guid + [sizeof(state->request.data.dsgetdcname.domain_guid)-1] = '\0'; DEBUG(3, ("[%5lu]: dsgetdcname for %s\n", (unsigned long)state->pid, - state->request.domain_name)); + state->request.data.dsgetdcname.domain_name)); ds_flags = get_dsgetdc_flags(state->request.flags); - result = dsgetdcname(state->mem_ctx, winbind_messaging_context(), - state->request.domain_name, - NULL, NULL, ds_flags, &info); - - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; + result = GUID_from_string(state->request.data.dsgetdcname.domain_guid, + &guid); + if (NT_STATUS_IS_OK(result) && !GUID_all_zero(&guid)) { + guid_ptr = &guid; } - if (info->dc_address) { - dc = strip_hostname(info->dc_address); - } + result = dsgetdcname(state->mem_ctx, + winbind_messaging_context(), + state->request.data.dsgetdcname.domain_name, + guid_ptr, + state->request.data.dsgetdcname.site_name, + ds_flags, + &info); - if ((!dc || !is_ipaddress_v4(dc)) && info->dc_unc) { - dc = strip_hostname(info->dc_unc); + if (!NT_STATUS_IS_OK(result)) { + return WINBINDD_ERROR; } - if (!dc || !*dc) { + guid_str = GUID_string(state->mem_ctx, &info->domain_guid); + if (!guid_str) { return WINBINDD_ERROR; } - fstrcpy(state->response.data.dc_name, dc); + fstrcpy(state->response.data.dsgetdcname.dc_unc, info->dc_unc); + fstrcpy(state->response.data.dsgetdcname.dc_address, info->dc_address); + state->response.data.dsgetdcname.dc_address_type = info->dc_address_type; + fstrcpy(state->response.data.dsgetdcname.domain_guid, guid_str); + fstrcpy(state->response.data.dsgetdcname.domain_name, info->domain_name); + fstrcpy(state->response.data.dsgetdcname.forest_name, info->forest_name); + state->response.data.dsgetdcname.dc_flags = info->dc_flags; + fstrcpy(state->response.data.dsgetdcname.dc_site_name, info->dc_site_name); + fstrcpy(state->response.data.dsgetdcname.client_site_name, info->client_site_name); return WINBINDD_OK; } -- cgit