winbind: Use talloc for allocating domain, dns, forest and dc name.
authorAndreas Schneider <asn@samba.org>
Mon, 18 Feb 2013 15:36:22 +0000 (16:36 +0100)
committerDavid Disseldorp <ddiss@suse.de>
Tue, 5 Mar 2013 22:29:11 +0000 (23:29 +0100)
Reviewed-by: David Disseldorp <ddiss@samba.org>
source3/winbindd/winbindd.h
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_cache.c
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_util.c

index 5a8aed193075a7db17e2ece763a5a4aa77a5aae1..72eb3ec3dc04222072c284fcef4813d366162a8d 100644 (file)
@@ -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 */
index 921d4086a11d12d13ced86228871e731ea045fa6..e27ad5705acdb3c7626a06b9422610d873dcd176 100644 (file)
@@ -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 {
index d0603d11c9b1eff8391daef60c694e282e944232..0e47a38f15a3a6a94562d582271dad47bb19d601 100644 (file)
@@ -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;
index 289b9b275b386268e8c6ed30deb32b72b6b48d29..57d6b1df79700c3ee98689cfca5a90cbadd745e9 100644 (file)
@@ -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);
index 8ba82d7e0619c62add3f15f71ca804c5589e635f..c752ffeaac92527f117e5178d7fe7631cb696c9b 100644 (file)
@@ -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;
index c32feb895163034e513070fc1e3fb56fe4c31876..4759fd51099cdf47750f918bdc82a2224906cdc0 100644 (file)
@@ -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;