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/winbindd_misc.c | 634 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 634 insertions(+) create mode 100644 source3/winbindd/winbindd_misc.c (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c new file mode 100644 index 0000000000..9c3f634534 --- /dev/null +++ b/source3/winbindd/winbindd_misc.c @@ -0,0 +1,634 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon - miscellaneous other functions + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Bartlett 2002 + + 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_WINBIND + +/* Check the machine account password is valid */ + +void winbindd_check_machine_acct(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: check machine account\n", + (unsigned long)state->pid)); + + sendto_domain(state, find_our_domain()); +} + +enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + int num_retries = 0; + struct winbindd_domain *contact_domain; + + DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid)); + + /* Get trust account password */ + + again: + + contact_domain = find_our_domain(); + + /* This call does a cli_nt_setup_creds() which implicitly checks + the trust account password. */ + + invalidate_cm_connection(&contact_domain->conn); + + { + struct rpc_pipe_client *netlogon_pipe; + result = cm_connect_netlogon(contact_domain, &netlogon_pipe); + } + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + goto done; + } + + /* There is a race condition between fetching the trust account + password and the periodic machine password change. So it's + possible that the trust account password has been changed on us. + We are returned NT_STATUS_ACCESS_DENIED if this happens. */ + +#define MAX_RETRIES 8 + + if ((num_retries < MAX_RETRIES) && + NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) { + num_retries++; + goto again; + } + + /* Pass back result code - zero for success, other values for + specific failures. */ + + DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ? + "good" : "bad")); + + done: + state->response.data.auth.nt_status = NT_STATUS_V(result); + fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); + fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); + state->response.data.auth.pam_error = nt_status_to_pam(result); + + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n", + state->response.data.auth.nt_status_string)); + + return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; +} + +void winbindd_list_trusted_domains(struct winbindd_cli_state *state) +{ + struct winbindd_domain *d = NULL; + int extra_data_len = 0; + char *extra_data = NULL; + + DEBUG(3, ("[%5lu]: list trusted domains\n", + (unsigned long)state->pid)); + + for ( d=domain_list(); d; d=d->next ) { + if ( !extra_data ) { + extra_data = talloc_asprintf(state->mem_ctx, "%s\\%s\\%s", + d->name, + d->alt_name ? d->alt_name : d->name, + sid_string_static(&d->sid)); + } else { + extra_data = talloc_asprintf(state->mem_ctx, "%s\n%s\\%s\\%s", + extra_data, + d->name, + d->alt_name ? d->alt_name : d->name, + sid_string_static(&d->sid)); + } + } + + extra_data_len = 0; + if (extra_data != NULL) { + extra_data_len = strlen(extra_data); + } + + if (extra_data_len > 0) { + state->response.extra_data.data = SMB_STRDUP(extra_data); + state->response.length += extra_data_len+1; + } + + TALLOC_FREE( extra_data ); + + request_ok(state); +} + +enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + uint32 i, num_domains; + char **names, **alt_names; + DOM_SID *sids; + int extra_data_len = 0; + char *extra_data; + NTSTATUS result; + BOOL have_own_domain = False; + + DEBUG(3, ("[%5lu]: list trusted domains\n", + (unsigned long)state->pid)); + + result = domain->methods->trusted_domains(domain, state->mem_ctx, + &num_domains, &names, + &alt_names, &sids); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n", + nt_errstr(result) )); + return WINBINDD_ERROR; + } + + extra_data = talloc_strdup(state->mem_ctx, ""); + + if (num_domains > 0) + extra_data = talloc_asprintf(state->mem_ctx, "%s\\%s\\%s", + names[0], + alt_names[0] ? alt_names[0] : names[0], + sid_string_static(&sids[0])); + + for (i=1; imem_ctx, "%s\n%s\\%s\\%s", + extra_data, + names[i], + alt_names[i] ? alt_names[i] : names[i], + sid_string_static(&sids[i])); + /* add our primary domain */ + + for (i=0; iname)) { + have_own_domain = True; + break; + } + } + + if (state->request.data.list_all_domains && !have_own_domain) { + extra_data = talloc_asprintf(state->mem_ctx, "%s\n%s\\%s\\%s", + extra_data, + domain->name, + domain->alt_name ? domain->alt_name : domain->name, + sid_string_static(&domain->sid)); + } + + /* This is a bit excessive, but the extra data sooner or later will be + talloc'ed */ + + extra_data_len = 0; + if (extra_data != NULL) { + extra_data_len = strlen(extra_data); + } + + if (extra_data_len > 0) { + state->response.extra_data.data = SMB_STRDUP(extra_data); + state->response.length += extra_data_len+1; + } + + return WINBINDD_OK; +} + +void winbindd_getdcname(struct winbindd_cli_state *state) +{ + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + sendto_domain(state, find_our_domain()); +} + +enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + fstring dcname_slash; + char *p; + struct rpc_pipe_client *netlogon_pipe; + NTSTATUS result; + WERROR werr; + unsigned int orig_timeout; + + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + result = cm_connect_netlogon(domain, &netlogon_pipe); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(1, ("Can't contact the NETLOGON pipe\n")); + return WINBINDD_ERROR; + } + + /* This call can take a long time - allow the server to time out. + 35 seconds should do it. */ + + orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000); + + werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname, + state->request.domain_name, + dcname_slash); + /* And restore our original timeout. */ + cli_set_timeout(netlogon_pipe->cli, orig_timeout); + + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("Error requesting DCname for domain %s: %s\n", + state->request.domain_name, dos_errstr(werr))); + return WINBINDD_ERROR; + } + + p = dcname_slash; + if (*p == '\\') { + p+=1; + } + if (*p == '\\') { + p+=1; + } + + fstrcpy(state->response.data.dc_name, p); + return WINBINDD_OK; +} + +static struct winbindd_child static_locator_child; + +void init_locator_child(void) +{ + setup_domain_child(NULL, &static_locator_child, "locator"); +} + +struct winbindd_child *locator_child(void) +{ + return &static_locator_child; +} + +void winbindd_dsgetdcname(struct winbindd_cli_state *state) +{ + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + sendto_child(state, locator_child()); +} + +enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + NTSTATUS result; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + const char *dc = NULL; + + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name, + NULL, NULL, state->request.flags, &info); + + if (!NT_STATUS_IS_OK(result)) { + return WINBINDD_ERROR; + } + + if (info->domain_controller_address) { + dc = info->domain_controller_address; + if ((dc[0] == '\\') && (dc[1] == '\\')) { + dc += 2; + } + } + + if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) { + dc = info->domain_controller_name; + } + + if (!dc || !*dc) { + return WINBINDD_ERROR; + } + + fstrcpy(state->response.data.dc_name, dc); + + return WINBINDD_OK; +} + + +struct sequence_state { + TALLOC_CTX *mem_ctx; + struct winbindd_cli_state *cli_state; + struct winbindd_domain *domain; + struct winbindd_request *request; + struct winbindd_response *response; + char *extra_data; +}; + +static void sequence_recv(void *private_data, BOOL success); + +void winbindd_show_sequence(struct winbindd_cli_state *state) +{ + struct sequence_state *seq; + + /* Ensure null termination */ + state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; + + if (strlen(state->request.domain_name) > 0) { + struct winbindd_domain *domain; + domain = find_domain_from_name_noinit( + state->request.domain_name); + if (domain == NULL) { + request_error(state); + return; + } + sendto_domain(state, domain); + return; + } + + /* Ask all domains in sequence, collect the results in sequence_recv */ + + seq = TALLOC_P(state->mem_ctx, struct sequence_state); + if (seq == NULL) { + DEBUG(0, ("talloc failed\n")); + request_error(state); + return; + } + + seq->mem_ctx = state->mem_ctx; + seq->cli_state = state; + seq->domain = domain_list(); + if (seq->domain == NULL) { + DEBUG(0, ("domain list empty\n")); + request_error(state); + return; + } + seq->request = TALLOC_ZERO_P(state->mem_ctx, + struct winbindd_request); + seq->response = TALLOC_ZERO_P(state->mem_ctx, + struct winbindd_response); + seq->extra_data = talloc_strdup(state->mem_ctx, ""); + + if ((seq->request == NULL) || (seq->response == NULL) || + (seq->extra_data == NULL)) { + DEBUG(0, ("talloc failed\n")); + request_error(state); + return; + } + + seq->request->length = sizeof(*seq->request); + seq->request->cmd = WINBINDD_SHOW_SEQUENCE; + fstrcpy(seq->request->domain_name, seq->domain->name); + + async_domain_request(state->mem_ctx, seq->domain, + seq->request, seq->response, + sequence_recv, seq); +} + +static void sequence_recv(void *private_data, BOOL success) +{ + struct sequence_state *state = + (struct sequence_state *)private_data; + uint32 seq = DOM_SEQUENCE_NONE; + + if ((success) && (state->response->result == WINBINDD_OK)) + seq = state->response->data.domain_info.sequence_number; + + if (seq == DOM_SEQUENCE_NONE) { + state->extra_data = talloc_asprintf(state->mem_ctx, + "%s%s : DISCONNECTED\n", + state->extra_data, + state->domain->name); + } else { + state->extra_data = talloc_asprintf(state->mem_ctx, + "%s%s : %d\n", + state->extra_data, + state->domain->name, seq); + } + + state->domain->sequence_number = seq; + + state->domain = state->domain->next; + + if (state->domain == NULL) { + struct winbindd_cli_state *cli_state = state->cli_state; + cli_state->response.length = + sizeof(cli_state->response) + + strlen(state->extra_data) + 1; + cli_state->response.extra_data.data = + SMB_STRDUP(state->extra_data); + request_ok(cli_state); + return; + } + + /* Ask the next domain */ + fstrcpy(state->request->domain_name, state->domain->name); + async_domain_request(state->mem_ctx, state->domain, + state->request, state->response, + sequence_recv, state); +} + +/* This is the child-only version of --sequence. It only allows for a single + * domain (ie "our" one) to be displayed. */ + +enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid)); + + /* Ensure null termination */ + state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; + + domain->methods->sequence_number(domain, &domain->sequence_number); + + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + return WINBINDD_OK; +} + +struct domain_info_state { + struct winbindd_domain *domain; + struct winbindd_cli_state *cli_state; +}; + +static void domain_info_init_recv(void *private_data, BOOL success); + +void winbindd_domain_info(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + + DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)state->pid, + state->request.domain_name)); + + domain = find_domain_from_name_noinit(state->request.domain_name); + + if (domain == NULL) { + DEBUG(3, ("Did not find domain [%s]\n", + state->request.domain_name)); + request_error(state); + return; + } + + if (!domain->initialized) { + struct domain_info_state *istate; + + istate = TALLOC_P(state->mem_ctx, struct domain_info_state); + if (istate == NULL) { + DEBUG(0, ("talloc failed\n")); + request_error(state); + return; + } + + istate->cli_state = state; + istate->domain = domain; + + init_child_connection(domain, domain_info_init_recv, istate); + + return; + } + + fstrcpy(state->response.data.domain_info.name, + domain->name); + fstrcpy(state->response.data.domain_info.alt_name, + domain->alt_name); + fstrcpy(state->response.data.domain_info.sid, + sid_string_static(&domain->sid)); + + state->response.data.domain_info.native_mode = + domain->native_mode; + state->response.data.domain_info.active_directory = + domain->active_directory; + state->response.data.domain_info.primary = + domain->primary; + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + request_ok(state); +} + +static void domain_info_init_recv(void *private_data, BOOL success) +{ + struct domain_info_state *istate = + (struct domain_info_state *)private_data; + struct winbindd_cli_state *state = istate->cli_state; + struct winbindd_domain *domain = istate->domain; + + DEBUG(10, ("Got back from child init: %d\n", success)); + + if ((!success) || (!domain->initialized)) { + DEBUG(5, ("Could not init child for domain %s\n", + domain->name)); + request_error(state); + return; + } + + fstrcpy(state->response.data.domain_info.name, + domain->name); + fstrcpy(state->response.data.domain_info.alt_name, + domain->alt_name); + fstrcpy(state->response.data.domain_info.sid, + sid_string_static(&domain->sid)); + + state->response.data.domain_info.native_mode = + domain->native_mode; + state->response.data.domain_info.active_directory = + domain->active_directory; + state->response.data.domain_info.primary = + domain->primary; + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + request_ok(state); +} + +void winbindd_ping(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid)); + request_ok(state); +} + +/* List various tidbits of information */ + +void winbindd_info(struct winbindd_cli_state *state) +{ + + DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid)); + + state->response.data.info.winbind_separator = *lp_winbind_separator(); + fstrcpy(state->response.data.info.samba_version, SAMBA_VERSION_STRING); + request_ok(state); +} + +/* Tell the client the current interface version */ + +void winbindd_interface_version(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: request interface version\n", + (unsigned long)state->pid)); + + state->response.data.interface_version = WINBIND_INTERFACE_VERSION; + request_ok(state); +} + +/* What domain are we a member of? */ + +void winbindd_domain_name(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid)); + + fstrcpy(state->response.data.domain_name, lp_workgroup()); + request_ok(state); +} + +/* What's my name again? */ + +void winbindd_netbios_name(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: request netbios name\n", + (unsigned long)state->pid)); + + fstrcpy(state->response.data.netbios_name, global_myname()); + request_ok(state); +} + +/* Where can I find the privilaged pipe? */ + +void winbindd_priv_pipe_dir(struct winbindd_cli_state *state) +{ + + DEBUG(3, ("[%5lu]: request location of privileged pipe\n", + (unsigned long)state->pid)); + + state->response.extra_data.data = SMB_STRDUP(get_winbind_priv_pipe_dir()); + if (!state->response.extra_data.data) { + DEBUG(0, ("malloc failed\n")); + request_error(state); + return; + } + + /* must add one to length to copy the 0 for string termination */ + state->response.length += + strlen((char *)state->response.extra_data.data) + 1; + + request_ok(state); +} + -- cgit From 1edf050ad8682f2cd0781babf9b9db132e1e7493 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2007 19:05:54 +0000 Subject: r25241: remove sequence_number out of WINBINDD_DOMAIN_INFO call as this is always answered by the winbindd parent and will most times return old sequence number values. metze (This used to be commit 9caf54c868e8c0109730860e772c9cc404e2f899) --- source3/winbindd/winbindd_misc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 9c3f634534..1f23bf1bee 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -410,7 +410,7 @@ static void sequence_recv(void *private_data, BOOL success) uint32 seq = DOM_SEQUENCE_NONE; if ((success) && (state->response->result == WINBINDD_OK)) - seq = state->response->data.domain_info.sequence_number; + seq = state->response->data.sequence_number; if (seq == DOM_SEQUENCE_NONE) { state->extra_data = talloc_asprintf(state->mem_ctx, @@ -459,7 +459,7 @@ enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain, domain->methods->sequence_number(domain, &domain->sequence_number); - state->response.data.domain_info.sequence_number = + state->response.data.sequence_number = domain->sequence_number; return WINBINDD_OK; @@ -519,8 +519,6 @@ void winbindd_domain_info(struct winbindd_cli_state *state) domain->active_directory; state->response.data.domain_info.primary = domain->primary; - state->response.data.domain_info.sequence_number = - domain->sequence_number; request_ok(state); } @@ -554,8 +552,6 @@ static void domain_info_init_recv(void *private_data, BOOL success) domain->active_directory; state->response.data.domain_info.primary = domain->primary; - state->response.data.domain_info.sequence_number = - domain->sequence_number; request_ok(state); } -- cgit From 4ab70e8438361fd41b71c959d0d20137959a51ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 21 Sep 2007 09:35:53 +0000 Subject: r25270: for internal domains we should not ask a remote DC. metze (This used to be commit 579ed8ae87e449dbd5e4f78609754df0556fbf68) --- source3/winbindd/winbindd_misc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 1f23bf1bee..30386cc6eb 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -209,12 +209,21 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * void winbindd_getdcname(struct winbindd_cli_state *state) { + struct winbindd_domain *domain; + state->request.domain_name [sizeof(state->request.domain_name)-1] = '\0'; DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, state->request.domain_name)); + domain = find_domain_from_name_noinit(state->request.domain_name); + if (domain && domain->internal) { + fstrcpy(state->response.data.dc_name, global_myname()); + request_ok(state); + return; + } + sendto_domain(state, find_our_domain()); } -- cgit From ba93d0e5c8418eb11a5fa0bb48c1ec3a0ebd403b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 21 Sep 2007 10:25:33 +0000 Subject: r25275: w2k3 (as PDC emulator) returns WERR_NO_SUCH_DOMAIN to netlogon_getanydcname() when called for it's own domain. So we should use netlogon_getdcname() which returns WERR_OK:-) gd: feel free to usage rpccli_netlogon_dsr_getdcname(), but please make sure the new WINBIND-STRUCT-GETDCNAME test is still passing. metze (This used to be commit 9a9c164366a252ab8268b687699d54048ced993f) --- source3/winbindd/winbindd_misc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 30386cc6eb..5513e1790b 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -236,6 +236,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, NTSTATUS result; WERROR werr; unsigned int orig_timeout; + struct winbindd_domain *req_domain; state->request.domain_name [sizeof(state->request.domain_name)-1] = '\0'; @@ -255,9 +256,18 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000); - werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname, - state->request.domain_name, - dcname_slash); + req_domain = find_domain_from_name_noinit(state->request.domain_name); + if (req_domain == domain) { + werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, + domain->dcname, + state->request.domain_name, + dcname_slash); + } else { + werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, + domain->dcname, + state->request.domain_name, + dcname_slash); + } /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); -- cgit From 971cc997debc82a86a653757d0fb16c8d748345f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Oct 2007 11:15:28 +0000 Subject: r25570: move code of the locator child into its own file metze (This used to be commit 2dbc168e543b84d05b85bc0a44aa8fc10adc4511) --- source3/winbindd/winbindd_misc.c | 64 ---------------------------------------- 1 file changed, 64 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 5513e1790b..987926e398 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -289,70 +289,6 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, return WINBINDD_OK; } -static struct winbindd_child static_locator_child; - -void init_locator_child(void) -{ - setup_domain_child(NULL, &static_locator_child, "locator"); -} - -struct winbindd_child *locator_child(void) -{ - return &static_locator_child; -} - -void winbindd_dsgetdcname(struct winbindd_cli_state *state) -{ - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, - state->request.domain_name)); - - sendto_child(state, locator_child()); -} - -enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - NTSTATUS result; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; - const char *dc = NULL; - - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, - state->request.domain_name)); - - result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name, - NULL, NULL, state->request.flags, &info); - - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; - } - - if (info->domain_controller_address) { - dc = info->domain_controller_address; - if ((dc[0] == '\\') && (dc[1] == '\\')) { - dc += 2; - } - } - - if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) { - dc = info->domain_controller_name; - } - - if (!dc || !*dc) { - return WINBINDD_ERROR; - } - - fstrcpy(state->response.data.dc_name, dc); - - return WINBINDD_OK; -} - - struct sequence_state { TALLOC_CTX *mem_ctx; struct winbindd_cli_state *cli_state; -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/winbindd/winbindd_misc.c | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 987926e398..5513e1790b 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -289,6 +289,70 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, return WINBINDD_OK; } +static struct winbindd_child static_locator_child; + +void init_locator_child(void) +{ + setup_domain_child(NULL, &static_locator_child, "locator"); +} + +struct winbindd_child *locator_child(void) +{ + return &static_locator_child; +} + +void winbindd_dsgetdcname(struct winbindd_cli_state *state) +{ + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + sendto_child(state, locator_child()); +} + +enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + NTSTATUS result; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + const char *dc = NULL; + + state->request.domain_name + [sizeof(state->request.domain_name)-1] = '\0'; + + DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, + state->request.domain_name)); + + result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name, + NULL, NULL, state->request.flags, &info); + + if (!NT_STATUS_IS_OK(result)) { + return WINBINDD_ERROR; + } + + if (info->domain_controller_address) { + dc = info->domain_controller_address; + if ((dc[0] == '\\') && (dc[1] == '\\')) { + dc += 2; + } + } + + if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) { + dc = info->domain_controller_name; + } + + if (!dc || !*dc) { + return WINBINDD_ERROR; + } + + fstrcpy(state->response.data.dc_name, dc); + + return WINBINDD_OK; +} + + struct sequence_state { TALLOC_CTX *mem_ctx; struct winbindd_cli_state *cli_state; -- cgit From 1a2d1628f7ae761457656bcf95a6f3d2eb630ff2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Oct 2007 18:47:41 -0700 Subject: Added missing is_ipaddress is_ipaddress_v4 not in initial port from old svn code. Jeremy. (This used to be commit 169c5857b7e7922fe3fffef997ced0e014e925a8) --- source3/winbindd/winbindd_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 5513e1790b..366f58a403 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -339,7 +339,7 @@ enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain, } } - if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) { + if ((!dc || !is_ipaddress_v4(dc)) && info->domain_controller_name) { dc = info->domain_controller_name; } -- 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/winbindd_misc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 366f58a403..dc2e35884e 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -145,7 +145,7 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * int extra_data_len = 0; char *extra_data; NTSTATUS result; - BOOL have_own_domain = False; + bool have_own_domain = False; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); @@ -362,7 +362,7 @@ struct sequence_state { char *extra_data; }; -static void sequence_recv(void *private_data, BOOL success); +static void sequence_recv(void *private_data, bool success); void winbindd_show_sequence(struct winbindd_cli_state *state) { @@ -422,7 +422,7 @@ void winbindd_show_sequence(struct winbindd_cli_state *state) sequence_recv, seq); } -static void sequence_recv(void *private_data, BOOL success) +static void sequence_recv(void *private_data, bool success) { struct sequence_state *state = (struct sequence_state *)private_data; @@ -489,7 +489,7 @@ struct domain_info_state { struct winbindd_cli_state *cli_state; }; -static void domain_info_init_recv(void *private_data, BOOL success); +static void domain_info_init_recv(void *private_data, bool success); void winbindd_domain_info(struct winbindd_cli_state *state) { @@ -542,7 +542,7 @@ void winbindd_domain_info(struct winbindd_cli_state *state) request_ok(state); } -static void domain_info_init_recv(void *private_data, BOOL success) +static void domain_info_init_recv(void *private_data, bool success) { struct domain_info_state *istate = (struct domain_info_state *)private_data; -- cgit From 6ded271f7719483faee19aba502d787a279c1689 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Oct 2007 11:15:28 +0000 Subject: r25570: move code of the locator child into its own file metze (This used to be commit 56640908a6367acfdfd53568a0d329c13330e5eb) --- source3/winbindd/winbindd_misc.c | 64 ---------------------------------------- 1 file changed, 64 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index dc2e35884e..9d77879e76 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -289,70 +289,6 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, return WINBINDD_OK; } -static struct winbindd_child static_locator_child; - -void init_locator_child(void) -{ - setup_domain_child(NULL, &static_locator_child, "locator"); -} - -struct winbindd_child *locator_child(void) -{ - return &static_locator_child; -} - -void winbindd_dsgetdcname(struct winbindd_cli_state *state) -{ - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, - state->request.domain_name)); - - sendto_child(state, locator_child()); -} - -enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - NTSTATUS result; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; - const char *dc = NULL; - - state->request.domain_name - [sizeof(state->request.domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid, - state->request.domain_name)); - - result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name, - NULL, NULL, state->request.flags, &info); - - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; - } - - if (info->domain_controller_address) { - dc = info->domain_controller_address; - if ((dc[0] == '\\') && (dc[1] == '\\')) { - dc += 2; - } - } - - if ((!dc || !is_ipaddress_v4(dc)) && info->domain_controller_name) { - dc = info->domain_controller_name; - } - - if (!dc || !*dc) { - return WINBINDD_ERROR; - } - - fstrcpy(state->response.data.dc_name, dc); - - return WINBINDD_OK; -} - - struct sequence_state { TALLOC_CTX *mem_ctx; struct winbindd_cli_state *cli_state; -- cgit From 54ae9dfcbce727ae3107f21eee68762502acda60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:49:15 +0100 Subject: Use sid_string_talloc where we have a tmp talloc ctx (This used to be commit 0a911d38b8f4be382a9df60f9c6de0c500464b3a) --- source3/winbindd/winbindd_misc.c | 47 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 9d77879e76..43ec5c6d9a 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -108,16 +108,16 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) for ( d=domain_list(); d; d=d->next ) { if ( !extra_data ) { - extra_data = talloc_asprintf(state->mem_ctx, "%s\\%s\\%s", - d->name, - d->alt_name ? d->alt_name : d->name, - sid_string_static(&d->sid)); + extra_data = talloc_asprintf( + state->mem_ctx, "%s\\%s\\%s", + d->name, d->alt_name ? d->alt_name : d->name, + sid_string_talloc(state->mem_ctx, &d->sid)); } else { - extra_data = talloc_asprintf(state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, - d->name, - d->alt_name ? d->alt_name : d->name, - sid_string_static(&d->sid)); + extra_data = talloc_asprintf( + state->mem_ctx, "%s\n%s\\%s\\%s", + extra_data, d->name, + d->alt_name ? d->alt_name : d->name, + sid_string_talloc(state->mem_ctx, &d->sid)); } } @@ -163,17 +163,18 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * extra_data = talloc_strdup(state->mem_ctx, ""); if (num_domains > 0) - extra_data = talloc_asprintf(state->mem_ctx, "%s\\%s\\%s", - names[0], - alt_names[0] ? alt_names[0] : names[0], - sid_string_static(&sids[0])); + extra_data = talloc_asprintf( + state->mem_ctx, "%s\\%s\\%s", + names[0], alt_names[0] ? alt_names[0] : names[0], + sid_string_talloc(state->mem_ctx, &sids[0])); for (i=1; imem_ctx, "%s\n%s\\%s\\%s", - extra_data, - names[i], - alt_names[i] ? alt_names[i] : names[i], - sid_string_static(&sids[i])); + extra_data = talloc_asprintf( + state->mem_ctx, "%s\n%s\\%s\\%s", + extra_data, names[i], + alt_names[i] ? alt_names[i] : names[i], + sid_string_talloc(state->mem_ctx, &sids[i])); + /* add our primary domain */ for (i=0; irequest.data.list_all_domains && !have_own_domain) { - extra_data = talloc_asprintf(state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, - domain->name, - domain->alt_name ? domain->alt_name : domain->name, - sid_string_static(&domain->sid)); + extra_data = talloc_asprintf( + state->mem_ctx, "%s\n%s\\%s\\%s", + extra_data, domain->name, + domain->alt_name ? domain->alt_name : domain->name, + sid_string_talloc(state->mem_ctx, &domain->sid)); } /* This is a bit excessive, but the extra data sooner or later will be -- cgit From d899b8c56ad6556baf2d2374704cc8cd1b15d5ad Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:58:28 +0100 Subject: Use sid_to_string directly It seems a bit pointless to do a fstrcpy(dst, sid_string_static(src)) (This used to be commit c221c246b10e2dbbd54a9af2dc45de2eae237380) --- source3/winbindd/winbindd_misc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 43ec5c6d9a..2771faf152 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -466,8 +466,7 @@ void winbindd_domain_info(struct winbindd_cli_state *state) domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - fstrcpy(state->response.data.domain_info.sid, - sid_string_static(&domain->sid)); + sid_to_string(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; @@ -499,8 +498,7 @@ static void domain_info_init_recv(void *private_data, bool success) domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - fstrcpy(state->response.data.domain_info.sid, - sid_string_static(&domain->sid)); + sid_to_string(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; -- cgit From 2e07c2ade89f4ff281c61f74cb88e09990cf5f46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:47:30 +0100 Subject: s/sid_to_string/sid_to_fstring/ least surprise for callers (This used to be commit eb523ba77697346a365589101aac379febecd546) --- source3/winbindd/winbindd_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 2771faf152..8c3ef5bb6f 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -466,7 +466,7 @@ void winbindd_domain_info(struct winbindd_cli_state *state) domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - sid_to_string(state->response.data.domain_info.sid, &domain->sid); + sid_to_fstring(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; @@ -498,7 +498,7 @@ static void domain_info_init_recv(void *private_data, bool success) domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - sid_to_string(state->response.data.domain_info.sid, &domain->sid); + sid_to_fstring(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; -- cgit From 8ded1df76739363259edce0515b097510e342595 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 15:12:40 +0100 Subject: Kill fstring in getdcname & getanydcname return. Guenther (This used to be commit b7383818168863a7ba43c2456f8c44e96e76707a) --- source3/winbindd/winbindd_misc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 8c3ef5bb6f..76f2554122 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -231,7 +231,7 @@ void winbindd_getdcname(struct winbindd_cli_state *state) enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, struct winbindd_cli_state *state) { - fstring dcname_slash; + char *dcname_slash = NULL; char *p; struct rpc_pipe_client *netlogon_pipe; NTSTATUS result; @@ -262,12 +262,12 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, domain->dcname, state->request.domain_name, - dcname_slash); + &dcname_slash); } else { werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname, state->request.domain_name, - dcname_slash); + &dcname_slash); } /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); -- cgit From bca0ef0ed769bfbee6e7041aae8256be872813c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 7 Feb 2008 10:24:18 +0100 Subject: Use rpccli_netr_GetAnyDCName and rpccli_netr_GetDCName everywhere. Guenther (This used to be commit 8abeea9922ac09e7307730ee7695453718356873) --- source3/winbindd/winbindd_misc.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 76f2554122..c22da3e8ef 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -231,8 +231,8 @@ void winbindd_getdcname(struct winbindd_cli_state *state) enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, struct winbindd_cli_state *state) { - char *dcname_slash = NULL; - char *p; + const char *dcname_slash = NULL; + const char *p; struct rpc_pipe_client *netlogon_pipe; NTSTATUS result; WERROR werr; @@ -259,19 +259,29 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, req_domain = find_domain_from_name_noinit(state->request.domain_name); if (req_domain == domain) { - werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, - domain->dcname, - state->request.domain_name, - &dcname_slash); + result = rpccli_netr_GetDcName(netlogon_pipe, + state->mem_ctx, + domain->dcname, + state->request.domain_name, + &dcname_slash, + &werr); } else { - werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, - domain->dcname, - state->request.domain_name, - &dcname_slash); + result = rpccli_netr_GetAnyDCName(netlogon_pipe, + state->mem_ctx, + domain->dcname, + state->request.domain_name, + &dcname_slash, + &werr); } /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(5,("Error requesting DCname for domain %s: %s\n", + state->request.domain_name, nt_errstr(result))); + return WINBINDD_ERROR; + } + if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error requesting DCname for domain %s: %s\n", state->request.domain_name, dos_errstr(werr))); -- cgit From 2b70174e1bcef3b34acb406c9f8d79b0ec0cacfa Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Tue, 25 Mar 2008 16:58:40 -0700 Subject: Augmented "wbinfo -m" to list additional information about the type, direction, and transitivty of trusts. * added several helper functions to convert the trust_flags field in the winbindd_tdc_domain to more useful administrator ideas of trust type, trust direction, and trust transitivity. * converted winbindd_list_trusted_domains() to enumerate the trusted domain cache, instead of the domain list, and return additional trust information to the calling process * modified wbinfo to pretty print this additional trust information when a new --verbose switch is given with -m. Thus "wbinfo -m" and "wbinfo -all-domains" output as before, but "wbinfo --verbose -m" prints extra trust info. * updated some comments and fixed typos (This used to be commit e7827bb6afa264c12ecdc0858f49707ca3d6104f) --- source3/winbindd/winbindd_misc.c | 104 ++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 13 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index c22da3e8ef..93986d174e 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -97,27 +97,104 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } +/* Constants and helper functions for determining domain trust types */ + +enum trust_type { + EXTERNAL = 0, + FOREST, + IN_FOREST, + NONE, +}; + +const char *trust_type_strings[] = {"External", + "Forest", + "In Forest", + "None"}; + +static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain) +{ + if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) + return EXTERNAL; + else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) + return FOREST; + else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) && + ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0)) + return IN_FOREST; + return NONE; +} + +static const char *get_trust_type_string(struct winbindd_tdc_domain *domain) +{ + return trust_type_strings[get_trust_type(domain)]; +} + +static bool trust_is_inbound(struct winbindd_tdc_domain *domain) +{ + return (domain->trust_flags == 0x0) || + ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == + NETR_TRUST_FLAG_IN_FOREST) || + ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) == + NETR_TRUST_FLAG_INBOUND); +} + +static bool trust_is_outbound(struct winbindd_tdc_domain *domain) +{ + return (domain->trust_flags == 0x0) || + ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == + NETR_TRUST_FLAG_IN_FOREST) || + ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) == + NETR_TRUST_FLAG_OUTBOUND); +} + +static bool trust_is_transitive(struct winbindd_tdc_domain *domain) +{ + if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) || + (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) || + (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL)) + return False; + return True; +} + void winbindd_list_trusted_domains(struct winbindd_cli_state *state) { - struct winbindd_domain *d = NULL; + struct winbindd_tdc_domain *dom_list = NULL; + struct winbindd_tdc_domain *d = NULL; + size_t num_domains = 0; int extra_data_len = 0; char *extra_data = NULL; + int i = 0; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); - for ( d=domain_list(); d; d=d->next ) { + if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) { + request_error(state); + goto done; + } + + for ( i = 0; i < num_domains; i++ ) { + d = &dom_list[i]; if ( !extra_data ) { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\\%s\\%s", - d->name, d->alt_name ? d->alt_name : d->name, - sid_string_talloc(state->mem_ctx, &d->sid)); + extra_data = talloc_asprintf(state->mem_ctx, + "%s\\%s\\%s\\%s\\%s\\%s\\%s", + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No"); } else { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, d->name, - d->alt_name ? d->alt_name : d->name, - sid_string_talloc(state->mem_ctx, &d->sid)); + extra_data = talloc_asprintf(state->mem_ctx, + "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s", + extra_data, + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No"); } } @@ -131,9 +208,10 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) state->response.length += extra_data_len+1; } - TALLOC_FREE( extra_data ); - request_ok(state); +done: + TALLOC_FREE( dom_list ); + TALLOC_FREE( extra_data ); } enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, -- cgit From e1102b8f48aeebe7d4e730d2b432a1503b425210 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 23:27:35 +0200 Subject: Introduce rpccli_set_timeout() Reduce dependency on "cli" member of rpc_pipe_client struct (This used to be commit 2e4c1ba38963cffe4c3f25ab24bc28975f2fc291) --- source3/winbindd/winbindd_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 93986d174e..bde2eafb53 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -333,7 +333,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, /* This call can take a long time - allow the server to time out. 35 seconds should do it. */ - orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000); + orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); req_domain = find_domain_from_name_noinit(state->request.domain_name); if (req_domain == domain) { @@ -352,7 +352,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, &werr); } /* And restore our original timeout. */ - cli_set_timeout(netlogon_pipe->cli, orig_timeout); + rpccli_set_timeout(netlogon_pipe, orig_timeout); if (!NT_STATUS_IS_OK(result)) { DEBUG(5,("Error requesting DCname for domain %s: %s\n", -- cgit From de154dcf92ebaed23a33b6849af8aa14dc767a7d Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Tue, 22 Apr 2008 15:29:53 -0500 Subject: Mark a domain offline in the wbcDomainInfo structure using the domain_flags. Use the existing domain_flags fiueld in wbcDomainInfo to set a bit if the domain is marked as offline by Winbind. (This used to be commit 59cfba2c3d6d4594f08cbe3b7295ab36a7cfb044) --- source3/winbindd/winbindd_misc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index bde2eafb53..8933cf2794 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -173,20 +173,29 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) } for ( i = 0; i < num_domains; i++ ) { + struct winbindd_domain *domain; + bool is_online = true; + d = &dom_list[i]; + domain = find_domain_from_name_noinit(d->domain_name); + if (domain) { + is_online = domain->online; + } + if ( !extra_data ) { extra_data = talloc_asprintf(state->mem_ctx, - "%s\\%s\\%s\\%s\\%s\\%s\\%s", + "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", d->domain_name, d->dns_name ? d->dns_name : d->domain_name, sid_string_talloc(state->mem_ctx, &d->sid), get_trust_type_string(d), trust_is_transitive(d) ? "Yes" : "No", trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No"); + trust_is_outbound(d) ? "Yes" : "No", + is_online ? "Online" : "Offline" ); } else { extra_data = talloc_asprintf(state->mem_ctx, - "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s", + "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", extra_data, d->domain_name, d->dns_name ? d->dns_name : d->domain_name, @@ -194,7 +203,8 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) get_trust_type_string(d), trust_is_transitive(d) ? "Yes" : "No", trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No"); + trust_is_outbound(d) ? "Yes" : "No", + is_online ? "Online" : "Offline" ); } } -- cgit From 120c09b125f656d6d03b979560f3ef6652217691 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2008 14:02:39 -0700 Subject: From Steve Danneman @ Isilon. Attached is the companion patch to (037b9689d9042a398cb91e4628a82fcdfa913c21), which made handling of WINBINDD_LIST_GROUPS asynchronous. Because most all of the list_groups code was reusable, I abstracted it, and implemented both list_groups and list_users on top of it. On my large test domain a "wbinfo -u" call went from 70 seconds to 30 seconds with this patch. Plus, the parent process is no longer blocked from receiving new requests during that time. Steven Danneman | Software Development Engineer Isilon Systems P +1-206-315-7500 F +1-206-315-7501 www.isilon.com (This used to be commit 5188f2861137ff06d5399561d55d7d00c3a08644) --- source3/winbindd/winbindd_misc.c | 123 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 8933cf2794..01a4054d44 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -97,6 +97,129 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } +/* Helpers for listing user and group names */ + +const char *ent_type_strings[] = {"users", + "groups"}; + +static const char *get_ent_type_string(enum ent_type type) +{ + return ent_type_strings[type]; +} + +struct listent_state { + TALLOC_CTX *mem_ctx; + struct winbindd_cli_state *cli_state; + enum ent_type type; + int domain_count; + char *extra_data; + uint32_t extra_data_len; +}; + +static void listent_recv(void *private_data, bool success, fstring dom_name, + char *extra_data); + +/* List domain users/groups without mapping to unix ids */ +void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type) +{ + struct winbindd_domain *domain; + const char *which_domain; + struct listent_state *ent_state; + + DEBUG(3, ("[%5lu]: list %s\n", (unsigned long)state->pid, + get_ent_type_string(type))); + + /* Ensure null termination */ + state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; + which_domain = state->request.domain_name; + + /* Initialize listent_state */ + ent_state = TALLOC_P(state->mem_ctx, struct listent_state); + if (ent_state == NULL) { + DEBUG(0, ("talloc failed\n")); + request_error(state); + return; + } + + ent_state->mem_ctx = state->mem_ctx; + ent_state->cli_state = state; + ent_state->type = type; + ent_state->domain_count = 0; + ent_state->extra_data = NULL; + ent_state->extra_data_len = 0; + + /* Must count the full list of expected domains before we request data + * from any of them. Otherwise it's possible for a connection to the + * first domain to fail, call listent_recv(), and return to the + * client without checking any other domains. */ + for (domain = domain_list(); domain; domain = domain->next) { + /* if we have a domain name restricting the request and this + one in the list doesn't match, then just bypass the remainder + of the loop */ + if ( *which_domain && !strequal(which_domain, domain->name) ) + continue; + + ent_state->domain_count++; + } + + /* Make sure we're enumerating at least one domain */ + if (!ent_state->domain_count) { + request_ok(state); + return; + } + + /* Enumerate list of trusted domains and request user/group list from + * each */ + for (domain = domain_list(); domain; domain = domain->next) { + if ( *which_domain && !strequal(which_domain, domain->name) ) + continue; + + winbindd_listent_async(state->mem_ctx, domain, + listent_recv, ent_state, type); + } +} + +static void listent_recv(void *private_data, bool success, fstring dom_name, + char *extra_data) +{ + /* extra_data comes to us as a '\0' terminated string of comma + separated users or groups */ + struct listent_state *state = talloc_get_type_abort( + private_data, struct listent_state); + + /* Append users/groups from one domain onto the whole list */ + if (extra_data) { + DEBUG(5, ("listent_recv: %s returned %s.\n", + dom_name, get_ent_type_string(state->type))); + if (!state->extra_data) + state->extra_data = talloc_asprintf(state->mem_ctx, + "%s", extra_data); + else + state->extra_data = talloc_asprintf_append( + state->extra_data, + ",%s", extra_data); + /* Add one for the '\0' and each additional ',' */ + state->extra_data_len += strlen(extra_data) + 1; + } + else { + DEBUG(5, ("listent_recv: %s returned no %s.\n", + dom_name, get_ent_type_string(state->type))); + } + + if (--state->domain_count) + /* Still waiting for some child domains to return */ + return; + + /* Return list of all users/groups to the client */ + if (state->extra_data) { + state->cli_state->response.extra_data.data = + SMB_STRDUP(state->extra_data); + state->cli_state->response.length += state->extra_data_len; + } + + request_ok(state->cli_state); +} + /* Constants and helper functions for determining domain trust types */ enum trust_type { -- cgit From e682f09da5dccd531dd908b62f1902a555bfc772 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 25 Aug 2008 13:03:15 +0200 Subject: winbindd: use set_auth_errors() in winbindd_dual_check_machine_acct as well. Guenther (This used to be commit bb9c59e892cc9d3047bde89a15cc341e2bd21bc5) --- source3/winbindd/winbindd_misc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/winbindd/winbindd_misc.c') diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 01a4054d44..50936c01a3 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -86,10 +86,7 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do "good" : "bad")); done: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n", state->response.data.auth.nt_status_string)); -- cgit