From 14bae61ba36814ea5eca7c51cf1cc039e9e6803f Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 18 Feb 2013 16:36:22 +0100 Subject: winbind: Use talloc for allocating domain, dns, forest and dc name. Reviewed-by: David Disseldorp --- source3/winbindd/winbindd.h | 8 +-- source3/winbindd/winbindd_ads.c | 5 +- source3/winbindd/winbindd_cache.c | 11 +++- source3/winbindd/winbindd_cm.c | 126 +++++++++++++++++++++++++++----------- source3/winbindd/winbindd_dual.c | 19 +++++- source3/winbindd/winbindd_util.c | 34 +++++----- 6 files changed, 142 insertions(+), 61 deletions(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 5a8aed1930..72eb3ec3dc 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -146,9 +146,9 @@ struct winbindd_child { /* Structures to hold per domain information */ struct winbindd_domain { - fstring name; /* Domain name (NetBIOS) */ - fstring alt_name; /* alt Domain name, if any (FQDN for ADS) */ - fstring forest_name; /* Name of the AD forest we're in */ + char *name; /* Domain name (NetBIOS) */ + char *alt_name; /* alt Domain name, if any (FQDN for ADS) */ + char *forest_name; /* Name of the AD forest we're in */ struct dom_sid sid; /* SID for this domain */ uint32 domain_flags; /* Domain flags from netlogon.h */ uint32 domain_type; /* Domain type from netlogon.h */ @@ -193,7 +193,7 @@ struct winbindd_domain { /* A working DC */ pid_t dc_probe_pid; /* Child we're using to detect the DC. */ - fstring dcname; + char *dcname; struct sockaddr_storage dcaddr; /* Sequence number stuff */ diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 921d4086a1..e27ad5705a 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -1390,8 +1390,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, /* add to the trusted domain cache */ - fstrcpy(d.name, trust->netbios_name); - fstrcpy(d.alt_name, trust->dns_name); + d.name = discard_const_p(char, trust->netbios_name); + d.alt_name = discard_const_p(char, trust->dns_name); + if (trust->sid) { sid_copy(&d.sid, trust->sid); } else { diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index d0603d11c9..0e47a38f15 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -4619,10 +4619,15 @@ static struct winbindd_tdc_domain *wcache_tdc_dup_domain( if (dst->domain_name == NULL) { goto fail; } - dst->dns_name = talloc_strdup(dst, src->dns_name); - if (dst->dns_name == NULL) { - goto fail; + + dst->dns_name = NULL; + if (src->dns_name != NULL) { + dst->dns_name = talloc_strdup(dst, src->dns_name); + if (dst->dns_name == NULL) { + goto fail; + } } + sid_copy(&dst->sid, &src->sid); dst->trust_flags = src->trust_flags; dst->trust_type = src->trust_type; diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 289b9b275b..57d6b1df79 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -665,13 +665,23 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, talloc_destroy(mem_ctx); return false; } - if (strlen(domain->alt_name) == 0) { - fstrcpy(domain->alt_name, - domain_info->domain_name); + if (domain->alt_name == NULL) { + domain->alt_name = talloc_strdup(domain, + domain_info->domain_name); + if (domain->alt_name == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + talloc_destroy(mem_ctx); + return false; + } } - if (strlen(domain->forest_name) == 0) { - fstrcpy(domain->forest_name, - domain_info->forest_name); + if (domain->forest_name == NULL) { + domain->forest_name = talloc_strdup(domain, + domain_info->forest_name); + if (domain->forest_name == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + talloc_destroy(mem_ctx); + return false; + } } } } else { @@ -1111,7 +1121,7 @@ static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx, static bool dcip_to_name(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain, struct sockaddr_storage *pss, - fstring name ) + char **name) { struct ip_service ip_list; uint32_t nt_version = NETLOGON_NT_VERSION_1; @@ -1138,8 +1148,12 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx, ads_status = ads_connect(ads); if (ADS_ERR_OK(ads_status)) { /* We got a cldap packet. */ - fstrcpy(name, ads->config.ldap_server_name); - namecache_store(name, 0x20, 1, &ip_list); + *name = talloc_strdup(mem_ctx, + ads->config.ldap_server_name); + if (*name == NULL) { + return false; + } + namecache_store(*name, 0x20, 1, &ip_list); DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags)); @@ -1155,7 +1169,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx, domain->name, sitename, pss, - name); + *name); SAFE_FREE(sitename); } else { @@ -1164,13 +1178,13 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx, domain->name, NULL, pss, - name); + *name); } winbindd_set_locator_kdc_envs(domain); /* Ensure we contact this DC also. */ - saf_store( domain->name, name); - saf_store( domain->alt_name, name); + saf_store(domain->name, *name); + saf_store(domain->alt_name, *name); } ads_destroy( &ads ); @@ -1186,15 +1200,18 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx, &domain->sid, nt_version, mem_ctx, &nt_version, &dc_name, NULL); if (NT_STATUS_IS_OK(status)) { - fstrcpy(name, dc_name); - namecache_store(name, 0x20, 1, &ip_list); + *name = talloc_strdup(mem_ctx, dc_name); + if (*name == NULL) { + return false; + } + namecache_store(*name, 0x20, 1, &ip_list); return True; } /* try node status request */ - if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) { - namecache_store(name, 0x20, 1, &ip_list); + if (name_status_find(domain->name, 0x1c, 0x20, pss, *name) ) { + namecache_store(*name, 0x20, 1, &ip_list); return True; } return False; @@ -1344,7 +1361,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, static bool find_new_dc(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - fstring dcname, struct sockaddr_storage *pss, int *fd) + char **dcname, struct sockaddr_storage *pss, int *fd) { struct dc_name_ip *dcs = NULL; int num_dcs = 0; @@ -1403,8 +1420,11 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) { /* Ok, we've got a name for the DC */ - fstrcpy(dcname, dcnames[fd_index]); - return True; + *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]); + if (*dcname == NULL) { + return false; + } + return true; } /* Try to figure out the name */ @@ -1542,22 +1562,31 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, /* convert an ip address to a name */ if (is_ipaddress( saf_servername ) ) { - fstring saf_name; + char *dcname = NULL; struct sockaddr_storage ss; if (!interpret_string_addr(&ss, saf_servername, AI_NUMERICHOST)) { return NT_STATUS_UNSUCCESSFUL; } - if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) { - strlcpy(domain->dcname, saf_name, sizeof(domain->dcname)); + if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) { + domain->dcname = talloc_strdup(domain, + dcname); + if (domain->dcname == NULL) { + SAFE_FREE(saf_servername); + return NT_STATUS_NO_MEMORY; + } } else { winbind_add_failed_connection_entry( domain, saf_servername, NT_STATUS_UNSUCCESSFUL); } } else { - fstrcpy( domain->dcname, saf_servername ); + domain->dcname = talloc_strdup(domain, saf_servername); + if (domain->dcname == NULL) { + SAFE_FREE(saf_servername); + return NT_STATUS_NO_MEMORY; + } } SAFE_FREE( saf_servername ); @@ -1566,13 +1595,14 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, for (retries = 0; retries < 3; retries++) { int fd = -1; bool retry = False; + char *dcname = NULL; result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n", domain->dcname, domain->name )); - if (*domain->dcname + if (domain->dcname != NULL && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname)) && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true))) { @@ -1586,8 +1616,8 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, } } - if ((fd == -1) - && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd)) + if ((fd == -1) && + !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd)) { /* This is the one place where we will set the global winbindd offline state @@ -1596,6 +1626,15 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, set_global_winbindd_state_offline(); break; } + if (dcname != NULL) { + talloc_free(domain->dcname); + + domain->dcname = talloc_move(domain, &dcname); + if (domain->dcname == NULL) { + result = NT_STATUS_NO_MEMORY; + break; + } + } new_conn->cli = NULL; @@ -2046,20 +2085,35 @@ no_dssetup: domain->active_directory = True; if (lsa_info->dns.name.string) { - fstrcpy(domain->name, lsa_info->dns.name.string); + talloc_free(domain->name); + domain->name = talloc_strdup(domain, + lsa_info->dns.name.string); + if (domain->name == NULL) { + goto done; + } } if (lsa_info->dns.dns_domain.string) { - fstrcpy(domain->alt_name, - lsa_info->dns.dns_domain.string); + talloc_free(domain->alt_name); + domain->alt_name = + talloc_strdup(domain, + lsa_info->dns.dns_domain.string); + if (domain->alt_name == NULL) { + goto done; + } } /* See if we can set some domain trust flags about ourself */ if (lsa_info->dns.dns_forest.string) { - fstrcpy(domain->forest_name, - lsa_info->dns.dns_forest.string); + talloc_free(domain->forest_name); + domain->forest_name = + talloc_strdup(domain, + lsa_info->dns.dns_forest.string); + if (domain->forest_name == NULL) { + goto done; + } if (strequal(domain->forest_name, domain->alt_name)) { domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT; @@ -2088,8 +2142,10 @@ no_dssetup: if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { if (lsa_info->account_domain.name.string) { - fstrcpy(domain->name, - lsa_info->account_domain.name.string); + talloc_free(domain->name); + domain->name = + talloc_strdup(domain, + lsa_info->account_domain.name.string); } if (lsa_info->account_domain.sid) { @@ -2180,7 +2236,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, struct netlogon_creds_CredentialState *p_creds; char *machine_password = NULL; char *machine_account = NULL; - char *domain_name = NULL; + const char *domain_name = NULL; if (sid_check_is_our_sam(&domain->sid)) { return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle); diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 8ba82d7e06..c752ffeaac 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -369,8 +369,23 @@ static void wb_domain_request_initialized(struct tevent_req *subreq) tevent_req_error(req, EINVAL); return; } - fstrcpy(state->domain->name, response->data.domain_info.name); - fstrcpy(state->domain->alt_name, response->data.domain_info.alt_name); + + talloc_free(state->domain->name); + state->domain->name = talloc_strdup(state->domain, + response->data.domain_info.name); + if (state->domain->name == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + + talloc_free(state->domain->alt_name); + state->domain->alt_name = talloc_strdup(state->domain, + response->data.domain_info.alt_name); + if (state->domain->alt_name == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + state->domain->native_mode = response->data.domain_info.native_mode; state->domain->active_directory = response->data.domain_info.active_directory; diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index c32feb8951..4759fd5109 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -67,7 +67,7 @@ static void free_domain_list(void) struct winbindd_domain *next = domain->next; DLIST_REMOVE(_domain_list, domain); - SAFE_FREE(domain); + TALLOC_FREE(domain); domain = next; } } @@ -156,27 +156,31 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } /* Create new domain entry */ - - if ((domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL) + domain = talloc_zero(NULL, struct winbindd_domain); + if (domain == NULL) { return NULL; + } - /* Fill in fields */ - - ZERO_STRUCTP(domain); - - domain->children = SMB_MALLOC_ARRAY( - struct winbindd_child, lp_winbind_max_domain_connections()); + domain->children = talloc_zero_array(domain, + struct winbindd_child, + lp_winbind_max_domain_connections()); if (domain->children == NULL) { - SAFE_FREE(domain); + TALLOC_FREE(domain); + return NULL; + } + + domain->name = talloc_strdup(domain, domain_name); + if (domain->name == NULL) { + TALLOC_FREE(domain); return NULL; } - memset(domain->children, 0, - sizeof(struct winbindd_child) - * lp_winbind_max_domain_connections()); - fstrcpy(domain->name, domain_name); if (alternative_name) { - fstrcpy(domain->alt_name, alternative_name); + domain->alt_name = talloc_strdup(domain, alternative_name); + if (domain->alt_name == NULL) { + TALLOC_FREE(domain); + return NULL; + } } domain->methods = methods; -- cgit