winbindd: introduce a cm_connect_netlogon_secure() which gives a valid netlogon_creds_ctx
authorStefan Metzmacher <metze@samba.org>
Fri, 2 Feb 2018 14:24:00 +0000 (15:24 +0100)
committerRalph Boehme <slow@samba.org>
Sat, 10 Feb 2018 07:35:17 +0000 (08:35 +0100)
At lot of callers require a valid schannel connection.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13259

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_dual_srv.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_proto.h

index b7fd981547f7a0fef0628ad39e7b333c32cb2c9c..54416e02dcdae4155f0183acc8974daaf4b58bee 100644 (file)
@@ -2623,16 +2623,11 @@ static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
                return NT_STATUS_OK;
        }
 
-       result = cm_connect_netlogon(domain, &netlogon_pipe);
+       result = cm_connect_netlogon_secure(domain, &netlogon_pipe, ppdc);
        if (!NT_STATUS_IS_OK(result)) {
                return result;
        }
 
-       if (domain->conn.netlogon_creds_ctx == NULL) {
-               return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
-       }
-
-       *ppdc = domain->conn.netlogon_creds_ctx;
        return NT_STATUS_OK;
 }
 
@@ -3325,6 +3320,29 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
        return status;
 }
 
+NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain,
+                                   struct rpc_pipe_client **cli,
+                                   struct netlogon_creds_cli_context **ppdc)
+{
+       NTSTATUS status;
+
+       if (domain->secure_channel_type == SEC_CHAN_NULL) {
+               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+       }
+
+       status = cm_connect_netlogon(domain, cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (domain->conn.netlogon_creds_ctx == NULL) {
+               return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+       }
+
+       *ppdc = domain->conn.netlogon_creds_ctx;
+       return NT_STATUS_OK;
+}
+
 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
                            void *private_data,
                            uint32_t msg_type,
index a05644d2c341b4f8421e93c076a07282364eeda4..33f1393e08203a7d0fd374bd8104895f476aa00e 100644 (file)
@@ -1055,6 +1055,7 @@ static void machine_password_change_handler(struct tevent_context *ctx,
        struct winbindd_child *child =
                (struct winbindd_child *)private_data;
        struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        NTSTATUS result;
        struct timeval next_change;
 
@@ -1083,7 +1084,9 @@ static void machine_password_change_handler(struct tevent_context *ctx,
                return;
        }
 
-       result = cm_connect_netlogon(child->domain, &netlogon_pipe);
+       result = cm_connect_netlogon_secure(child->domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        if (!NT_STATUS_IS_OK(result)) {
                DEBUG(10,("machine_password_change_handler: "
                        "failed to connect netlogon pipe: %s\n",
@@ -1091,7 +1094,7 @@ static void machine_password_change_handler(struct tevent_context *ctx,
                return;
        }
 
-       result = trust_pw_change(child->domain->conn.netlogon_creds_ctx,
+       result = trust_pw_change(netlogon_creds_ctx,
                                 msg_ctx,
                                 netlogon_pipe->binding_handle,
                                 child->domain->name,
index 4804da91583b62e33580aada4dbde5629d11cbf1..5c12414fd25c209e7ef167286cb466322697445d 100644 (file)
@@ -679,8 +679,11 @@ again:
        domain->conn.netlogon_force_reauth = true;
 
        {
-               struct rpc_pipe_client *netlogon_pipe;
-               status = cm_connect_netlogon(domain, &netlogon_pipe);
+               struct rpc_pipe_client *netlogon_pipe = NULL;
+               struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
+               status = cm_connect_netlogon_secure(domain,
+                                                   &netlogon_pipe,
+                                                   &netlogon_creds_ctx);
        }
 
         /* There is a race condition between fetching the trust account
@@ -721,20 +724,23 @@ NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p,
        struct messaging_context *msg_ctx = server_messaging_context();
        struct winbindd_domain *domain;
        NTSTATUS status;
-       struct rpc_pipe_client *netlogon_pipe;
+       struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
 
        domain = wb_child_domain();
        if (domain == NULL) {
                return NT_STATUS_REQUEST_NOT_ACCEPTED;
        }
 
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
                goto done;
        }
 
-       status = trust_pw_change(domain->conn.netlogon_creds_ctx,
+       status = trust_pw_change(netlogon_creds_ctx,
                                 msg_ctx,
                                 netlogon_pipe->binding_handle,
                                 domain->name,
@@ -830,20 +836,23 @@ NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
 {
        struct winbindd_domain *domain;
        NTSTATUS status;
-       struct rpc_pipe_client *netlogon_pipe;
+       struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
 
        domain = wb_child_domain();
        if (domain == NULL) {
                return NT_STATUS_REQUEST_NOT_ACCEPTED;
        }
 
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
                goto done;
        }
 
-       status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds_ctx,
+       status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(netlogon_creds_ctx,
                                                                      netlogon_pipe->binding_handle,
                                                                      r->in.site_name,
                                                                      r->in.dns_ttl,
@@ -973,6 +982,7 @@ static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p,
 {
        NTSTATUS status;
        struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        struct netr_NETLOGON_INFO_2 *info2 = NULL;
        WERROR check_result = WERR_INTERNAL_ERROR;
 
@@ -993,7 +1003,9 @@ static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p,
         */
        invalidate_cm_connection(domain);
        domain->conn.netlogon_force_reauth = true;
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        reset_cm_connection_on_error(domain, status);
        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
                status = NT_STATUS_NO_LOGON_SERVERS;
@@ -1049,6 +1061,7 @@ static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p,
 {
        NTSTATUS status;
        struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        struct netr_NETLOGON_INFO_2 *info2 = NULL;
        WERROR check_result = WERR_INTERNAL_ERROR;
 
@@ -1062,7 +1075,9 @@ static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p,
                goto check_return;
        }
 
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        reset_cm_connection_on_error(domain, status);
        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
                status = NT_STATUS_NO_LOGON_SERVERS;
@@ -1121,6 +1136,7 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p,
        struct policy_handle local_lsa_policy = {};
        struct dcerpc_binding_handle *local_lsa = NULL;
        struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        struct cli_credentials *creds = NULL;
        struct samr_Password *cur_nt_hash = NULL;
        uint32_t trust_attributes = 0;
@@ -1241,7 +1257,9 @@ static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p,
        }
 
 reconnect:
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        reset_cm_connection_on_error(domain, status);
        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
                status = NT_STATUS_NO_LOGON_SERVERS;
@@ -1261,7 +1279,7 @@ reconnect:
        }
 
        if (fetch_fti) {
-               status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds_ctx,
+               status = netlogon_creds_cli_GetForestTrustInformation(netlogon_creds_ctx,
                                                                      b, frame,
                                                                      &new_fti);
                if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
@@ -1323,7 +1341,7 @@ reconnect:
                }
        }
 
-       status = netlogon_creds_cli_ServerGetTrustInfo(domain->conn.netlogon_creds_ctx,
+       status = netlogon_creds_cli_ServerGetTrustInfo(netlogon_creds_ctx,
                                                       b, frame,
                                                       &new_owf_password,
                                                       &old_owf_password,
@@ -1434,7 +1452,8 @@ static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p,
 {
        struct messaging_context *msg_ctx = server_messaging_context();
        NTSTATUS status;
-       struct rpc_pipe_client *netlogon_pipe;
+       struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        struct cli_credentials *creds = NULL;
        struct samr_Password *cur_nt_hash = NULL;
        struct netr_NETLOGON_INFO_1 *info1 = NULL;
@@ -1461,7 +1480,9 @@ static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p,
        }
 
 reconnect:
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        reset_cm_connection_on_error(domain, status);
        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
                status = NT_STATUS_NO_LOGON_SERVERS;
@@ -1484,7 +1505,7 @@ reconnect:
        }
        TALLOC_FREE(cur_nt_hash);
 
-       status = trust_pw_change(domain->conn.netlogon_creds_ctx,
+       status = trust_pw_change(netlogon_creds_ctx,
                                 msg_ctx, b, domain->name,
                                 domain->dcname,
                                 true); /* force */
@@ -1567,7 +1588,8 @@ WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p,
        TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status, result;
        struct winbindd_domain *domain;
-       struct rpc_pipe_client *netlogon_pipe;
+       struct rpc_pipe_client *netlogon_pipe = NULL;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
        struct dcerpc_binding_handle *b;
        bool retry = false;
        struct lsa_String trusted_domain_name = {};
@@ -1666,7 +1688,9 @@ WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p,
        }
 
 reconnect:
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        reset_cm_connection_on_error(domain, status);
        if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
                status = NT_STATUS_NO_LOGON_SERVERS;
@@ -1679,7 +1703,7 @@ reconnect:
        }
        b = netlogon_pipe->binding_handle;
 
-       status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds_ctx,
+       status = netlogon_creds_cli_GetForestTrustInformation(netlogon_creds_ctx,
                                                              b, p->mem_ctx,
                                                              &new_fti);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1778,6 +1802,7 @@ NTSTATUS _winbind_SendToSam(struct pipes_struct *p, struct winbind_SendToSam *r)
        struct winbindd_domain *domain;
        NTSTATUS status;
        struct rpc_pipe_client *netlogon_pipe;
+       struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
 
        DEBUG(5, ("_winbind_SendToSam received\n"));
        domain = wb_child_domain();
@@ -1785,13 +1810,15 @@ NTSTATUS _winbind_SendToSam(struct pipes_struct *p, struct winbind_SendToSam *r)
                return NT_STATUS_REQUEST_NOT_ACCEPTED;
        }
 
-       status = cm_connect_netlogon(domain, &netlogon_pipe);
+       status = cm_connect_netlogon_secure(domain,
+                                           &netlogon_pipe,
+                                           &netlogon_creds_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
                return status;
        }
 
-       status = netlogon_creds_cli_SendToSam(domain->conn.netlogon_creds_ctx,
+       status = netlogon_creds_cli_SendToSam(netlogon_creds_ctx,
                                              netlogon_pipe->binding_handle,
                                              &r->in.message);
 
index 9cab59dd6400b4eb1257cd309fbb48578396ece8..9c598d71855145217181261ea4899cd3a7568b65 100644 (file)
@@ -1442,10 +1442,12 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 
        do {
                struct rpc_pipe_client *netlogon_pipe;
+               struct netlogon_creds_cli_context *netlogon_creds_ctx = NULL;
 
                retry = false;
 
-               result = cm_connect_netlogon(domain, &netlogon_pipe);
+               result = cm_connect_netlogon_secure(domain, &netlogon_pipe,
+                                                   &netlogon_creds_ctx);
 
                if (NT_STATUS_EQUAL(result,
                                    NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
@@ -1521,13 +1523,9 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                }
 
                netr_attempts = 0;
-               if (domain->conn.netlogon_creds_ctx == NULL) {
-                       DBG_NOTICE("No security credentials available for "
-                                 "domain [%s]\n", domainname);
-                       result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
-               } else if (plaintext_given) {
+               if (plaintext_given) {
                        result = rpccli_netlogon_password_logon(
-                               domain->conn.netlogon_creds_ctx,
+                               netlogon_creds_ctx,
                                netlogon_pipe->binding_handle,
                                mem_ctx,
                                logon_parameters,
@@ -1542,7 +1540,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                                &validation);
                } else if (interactive) {
                        result = rpccli_netlogon_interactive_logon(
-                               domain->conn.netlogon_creds_ctx,
+                               netlogon_creds_ctx,
                                netlogon_pipe->binding_handle,
                                mem_ctx,
                                logon_parameters,
@@ -1558,7 +1556,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
                                &validation);
                } else {
                        result = rpccli_netlogon_network_logon(
-                               domain->conn.netlogon_creds_ctx,
+                               netlogon_creds_ctx,
                                netlogon_pipe->binding_handle,
                                mem_ctx,
                                logon_parameters,
index 568978141c9b9677a8eef4b281342ec795a4acf2..015fd717b34fce443f5a87c1d3d012c8da9cdd83 100644 (file)
@@ -210,6 +210,9 @@ NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
                         struct policy_handle *lsa_policy);
 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
                             struct rpc_pipe_client **cli);
+NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain,
+                                   struct rpc_pipe_client **cli,
+                                   struct netlogon_creds_cli_context **ppdc);
 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
                                    const char *domain_name,
                                    char **p_dc_name, char **p_dc_ip);