Fix bug 7636 - winbind internal error, backtrace.
[samba.git] / source3 / winbindd / winbindd_cm.c
index 5878a8abe38e15fd95a173c37c46abb0891b9a0a..0a5c147fd57fed3df2b6c717ebb6fac9eff00466 100644 (file)
@@ -794,11 +794,31 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
 
        peeraddr_len = sizeof(peeraddr);
 
-       if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
-           (peeraddr_len != sizeof(struct sockaddr_in)) ||
-           (peeraddr_in->sin_family != PF_INET))
-       {
-               DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
+       if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
+               DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
+                       strerror(errno)));
+               result = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       if ((peeraddr_len != sizeof(struct sockaddr_in))
+#ifdef HAVE_IPV6
+           && (peeraddr_len != sizeof(struct sockaddr_in6))
+#endif
+           ) {
+               DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
+                       peeraddr_len));
+               result = NT_STATUS_UNSUCCESSFUL;
+               goto done;
+       }
+
+       if ((peeraddr_in->sin_family != PF_INET)
+#ifdef HAVE_IPV6
+           && (peeraddr_in->sin_family != PF_INET6)
+#endif
+           ) {
+               DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
+                       peeraddr_in->sin_family));
                result = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
@@ -1116,7 +1136,8 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
                                        create_local_private_krb5_conf_for_domain(domain->alt_name,
                                                                        domain->name,
                                                                        sitename,
-                                                                       pss);
+                                                                       pss,
+                                                                       name);
 
                                        SAFE_FREE(sitename);
                                } else {
@@ -1124,7 +1145,8 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
                                        create_local_private_krb5_conf_for_domain(domain->alt_name,
                                                                        domain->name,
                                                                        NULL,
-                                                                       pss);
+                                                                       pss,
+                                                                       name);
                                }
                                winbindd_set_locator_kdc_envs(domain);
 
@@ -1614,7 +1636,13 @@ static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
        NTSTATUS result;
 
        /* Internal connections never use the network. */
-       if (domain->internal || !winbindd_can_contact_domain(domain)) {
+       if (domain->internal) {
+               domain->initialized = True;
+               return NT_STATUS_OK;
+       }
+
+       if (!winbindd_can_contact_domain(domain)) {
+               invalidate_cm_connection(&domain->conn);
                domain->initialized = True;
                return NT_STATUS_OK;
        }
@@ -1647,6 +1675,23 @@ NTSTATUS init_dc_connection(struct winbindd_domain *domain)
        return init_dc_connection_network(domain);
 }
 
+static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
+{
+       NTSTATUS status;
+
+       status = init_dc_connection(domain);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (!domain->internal && domain->conn.cli == NULL) {
+               /* happens for trusted domains without inbound trust */
+               return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+       }
+
+       return NT_STATUS_OK;
+}
+
 /******************************************************************************
  Set the trust flags (direction and forest location) for a domain
 ******************************************************************************/
@@ -1993,7 +2038,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
        char *machine_account = NULL;
        char *domain_name = NULL;
 
-       result = init_dc_connection(domain);
+       result = init_dc_connection_rpc(domain);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
@@ -2172,11 +2217,12 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
                            struct rpc_pipe_client **cli)
 {
        struct winbindd_cm_conn *conn;
+       struct dcinfo *dcinfo;
        NTSTATUS status;
 
        DEBUG(10,("cm_connect_lsa_tcp\n"));
 
-       status = init_dc_connection(domain);
+       status = init_dc_connection_rpc(domain);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -2192,14 +2238,20 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
 
        TALLOC_FREE(conn->lsa_pipe_tcp);
 
-       status = cli_rpc_pipe_open_schannel(conn->cli,
-                                           &ndr_table_lsarpc.syntax_id,
-                                           NCACN_IP_TCP,
-                                           PIPE_AUTH_LEVEL_PRIVACY,
-                                           domain->name,
-                                           &conn->lsa_pipe_tcp);
+       if (!cm_get_schannel_dcinfo(domain, &dcinfo)) {
+               status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+               goto done;
+       }
+
+       status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
+                                                    &ndr_table_lsarpc.syntax_id,
+                                                    NCACN_IP_TCP,
+                                                    PIPE_AUTH_LEVEL_PRIVACY,
+                                                    domain->name,
+                                                    dcinfo,
+                                                    &conn->lsa_pipe_tcp);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10,("cli_rpc_pipe_open_schannel failed: %s\n",
+               DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
                        nt_errstr(status)));
                goto done;
        }
@@ -2222,7 +2274,7 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        struct dcinfo *p_dcinfo;
 
-       result = init_dc_connection(domain);
+       result = init_dc_connection_rpc(domain);
        if (!NT_STATUS_IS_OK(result))
                return result;
 
@@ -2354,7 +2406,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
 
        *cli = NULL;
 
-       result = init_dc_connection(domain);
+       result = init_dc_connection_rpc(domain);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }