winbind3: Fix CID 1107229 Uninitialized pointer read
[mat/samba.git] / source3 / winbindd / winbindd_cm.c
index d89ca9534315a4aa9faa849647642134befe359e..edb2c7bac48eb8dda60a55a32df996466ff23245 100644 (file)
@@ -340,6 +340,46 @@ static void calc_new_online_timeout_check(struct winbindd_domain *domain)
        }
 }
 
+void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
+                               void *private_data,
+                               uint32_t msg_type,
+                               struct server_id server_id,
+                               DATA_BLOB *data)
+{
+       const char *domain_name = (const char *)data->data;
+       struct winbindd_domain *domain;
+
+       domain = find_domain_from_name_noinit(domain_name);
+       if (domain == NULL) {
+               return;
+       }
+
+       domain->online = false;
+
+       DEBUG(10, ("Domain %s is marked as offline now.\n",
+                  domain_name));
+}
+
+void winbind_msg_domain_online(struct messaging_context *msg_ctx,
+                               void *private_data,
+                               uint32_t msg_type,
+                               struct server_id server_id,
+                               DATA_BLOB *data)
+{
+       const char *domain_name = (const char *)data->data;
+       struct winbindd_domain *domain;
+
+       domain = find_domain_from_name_noinit(domain_name);
+       if (domain == NULL) {
+               return;
+       }
+
+       domain->online = true;
+
+       DEBUG(10, ("Domain %s is marked as online now.\n",
+                  domain_name));
+}
+
 /****************************************************************
  Set domain offline and also add handler to put us back online
  if we detect a DC.
@@ -347,6 +387,8 @@ static void calc_new_online_timeout_check(struct winbindd_domain *domain)
 
 void set_domain_offline(struct winbindd_domain *domain)
 {
+       pid_t parent_pid = getppid();
+
        DEBUG(10,("set_domain_offline: called for domain %s\n",
                domain->name ));
 
@@ -394,6 +436,15 @@ void set_domain_offline(struct winbindd_domain *domain)
        DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
                domain->name ));
 
+       /* Send a message to the parent that the domain is offline. */
+       if (parent_pid > 1 && !domain->internal) {
+               messaging_send_buf(winbind_messaging_context(),
+                                  pid_to_procid(parent_pid),
+                                  MSG_WINBIND_DOMAIN_OFFLINE,
+                                  (uint8 *)domain->name,
+                                  strlen(domain->name) + 1);
+       }
+
        /* Send an offline message to the idmap child when our
           primary domain goes offline */
 
@@ -418,6 +469,8 @@ void set_domain_offline(struct winbindd_domain *domain)
 
 static void set_domain_online(struct winbindd_domain *domain)
 {
+       pid_t parent_pid = getppid();
+
        DEBUG(10,("set_domain_online: called for domain %s\n",
                domain->name ));
 
@@ -469,6 +522,15 @@ static void set_domain_online(struct winbindd_domain *domain)
 
        domain->online = True;
 
+       /* Send a message to the parent that the domain is online. */
+       if (parent_pid > 1 && !domain->internal) {
+               messaging_send_buf(winbind_messaging_context(),
+                                  pid_to_procid(parent_pid),
+                                  MSG_WINBIND_DOMAIN_ONLINE,
+                                  (uint8 *)domain->name,
+                                  strlen(domain->name) + 1);
+       }
+
        /* Send an online message to the idmap child when our
           primary domain comes online */
 
@@ -841,8 +903,9 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
 
        cli_set_timeout(*cli, 10000); /* 10 seconds */
 
-       result = smbXcli_negprot((*cli)->conn, (*cli)->timeout, PROTOCOL_CORE,
-                                PROTOCOL_LATEST);
+       result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
+                                lp_cli_minprotocol(),
+                                lp_cli_maxprotocol());
 
        if (!NT_STATUS_IS_OK(result)) {
                DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
@@ -1160,7 +1223,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
 
                        if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
                                if (ads_closest_dc(ads)) {
-                                       char *sitename = sitename_fetch(ads->config.realm);
+                                       char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
 
                                        /* We're going to use this KDC for this realm/domain.
                                           If we are using sites, then force the krb5 libs
@@ -1172,7 +1235,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
                                                                        pss,
                                                                        *name);
 
-                                       SAFE_FREE(sitename);
+                                       TALLOC_FREE(sitename);
                                } else {
                                        /* use an off site KDC */
                                        create_local_private_krb5_conf_for_domain(domain->alt_name,
@@ -1212,7 +1275,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
        /* try node status request */
 
        if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
-               namecache_store(*name, 0x20, 1, &ip_list);
+               namecache_store(nbtname, 0x20, 1, &ip_list);
 
                if (name != NULL) {
                        *name = talloc_strdup(mem_ctx, nbtname);
@@ -1278,7 +1341,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
 
                get_dc_name(domain->name, domain->alt_name, dcname, &ss);
 
-               sitename = sitename_fetch(domain->alt_name);
+               sitename = sitename_fetch(mem_ctx, domain->alt_name);
                if (sitename) {
 
                        /* Do the site-specific AD dns lookup first. */
@@ -1302,7 +1365,7 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
                        }
 
                        SAFE_FREE(ip_list);
-                       SAFE_FREE(sitename);
+                       TALLOC_FREE(sitename);
                        iplist_size = 0;
                }
 
@@ -1502,7 +1565,8 @@ bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
                                    const char *domain_name,
                                    char **p_dc_name, char **p_dc_ip)
 {
-       char *key, *value, *p;
+       char *key, *p;
+       char *value = NULL;
        bool ret = false;
        char *dc_name = NULL;
        char *dc_ip = NULL;
@@ -1511,7 +1575,7 @@ bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
        if (key == NULL) {
                goto done;
        }
-       if (!gencache_get(key, &value, NULL)) {
+       if (!gencache_get(key, mem_ctx, &value, NULL)) {
                goto done;
        }
        p = strchr(value, ' ');
@@ -1540,6 +1604,7 @@ done:
        TALLOC_FREE(dc_name);
        TALLOC_FREE(dc_ip);
        TALLOC_FREE(key);
+       TALLOC_FREE(value);
        return ret;
 }
 
@@ -1548,15 +1613,16 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
 {
        TALLOC_CTX *mem_ctx;
        NTSTATUS result;
-       char *saf_servername = saf_fetch( domain->name );
+       char *saf_servername;
        int retries;
 
        if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
-               SAFE_FREE(saf_servername);
                set_domain_offline(domain);
                return NT_STATUS_NO_MEMORY;
        }
 
+       saf_servername = saf_fetch(mem_ctx, domain->name );
+
        /* we have to check the server affinity cache here since 
           later we select a DC based on response time and not preference */
 
@@ -1576,13 +1642,14 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
 
                        if (!interpret_string_addr(&ss, saf_servername,
                                                AI_NUMERICHOST)) {
+                               TALLOC_FREE(mem_ctx);
                                return NT_STATUS_UNSUCCESSFUL;
                        }
                        if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
                                domain->dcname = talloc_strdup(domain,
                                                               dcname);
                                if (domain->dcname == NULL) {
-                                       SAFE_FREE(saf_servername);
+                                       TALLOC_FREE(mem_ctx);
                                        return NT_STATUS_NO_MEMORY;
                                }
                        } else {
@@ -1593,12 +1660,10 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
                } else {
                        domain->dcname = talloc_strdup(domain, saf_servername);
                        if (domain->dcname == NULL) {
-                               SAFE_FREE(saf_servername);
+                               TALLOC_FREE(mem_ctx);
                                return NT_STATUS_NO_MEMORY;
                        }
                }
-
-               SAFE_FREE( saf_servername );
        }
 
        for (retries = 0; retries < 3; retries++) {
@@ -2614,7 +2679,6 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
                                          &ndr_table_lsarpc,
                                          &conn->lsa_pipe);
        if (!NT_STATUS_IS_OK(result)) {
-               result = NT_STATUS_PIPE_NOT_AVAILABLE;
                goto done;
        }