s3:winbind: Convert winbindd_dual_pam_chng_pswd_auth_crap() from struct based to...
authorSamuel Cabrero <scabrero@samba.org>
Mon, 21 Jun 2021 11:51:53 +0000 (13:51 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 19 May 2022 17:51:33 +0000 (17:51 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/idl/winbind.idl
source3/winbindd/winbindd_domain.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_pam_chng_pswd_auth_crap.c
source3/winbindd/winbindd_proto.h

index 93fd56dff05608eede6c85aaeed056becebfbeea..9ec98bd0878407d1bfd9c6e41e2b6eaae9d103a7 100644 (file)
@@ -226,6 +226,17 @@ interface winbind
         [in] hyper uid
         );
 
+    NTSTATUS wbint_PamAuthCrapChangePassword(
+        [in,string,charset(UTF8)] char *client_name,
+        [in] hyper client_pid,
+        [in,string,charset(UTF8)] char *user,
+        [in,string,charset(UTF8)] char *domain,
+        [in,flag(NDR_SECRET)] DATA_BLOB new_nt_pswd,
+        [in,flag(NDR_SECRET)] DATA_BLOB old_nt_hash_enc,
+        [in,flag(NDR_SECRET)] DATA_BLOB new_lm_pswd,
+        [in,flag(NDR_SECRET)] DATA_BLOB old_lm_hash_enc
+        );
+
   /* Public methods available via IRPC */
 
     typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
index 1e19f67303844397e2860db7fc6277a87656eb14..6ea837065242ee9d9e2b84718abb0611b2e1579f 100644 (file)
@@ -30,10 +30,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
                .name           = "INIT_CONNECTION",
                .struct_cmd     = WINBINDD_INIT_CONNECTION,
                .struct_fn      = winbindd_dual_init_connection,
-       },{
-               .name           = "CHNG_PSWD_AUTH_CRAP",
-               .struct_cmd     = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
-               .struct_fn      = winbindd_dual_pam_chng_pswd_auth_crap,
        },{
                .name           = "PAM_CHAUTHTOK",
                .struct_cmd     = WINBINDD_PAM_CHAUTHTOK,
index 9395567510691b8e344010a7f93c862225a35903..868dc8138926dac791ec46482ff524b3b3bcffa8 100644 (file)
@@ -3164,34 +3164,36 @@ process_result:
 
 /* Change user password with auth crap*/
 
-enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state)
+NTSTATUS _wbint_PamAuthCrapChangePassword(struct pipes_struct *p,
+                               struct wbint_PamAuthCrapChangePassword *r)
 {
        NTSTATUS result;
-       DATA_BLOB new_nt_password;
-       DATA_BLOB old_nt_hash_enc;
-       DATA_BLOB new_lm_password;
-       DATA_BLOB old_lm_hash_enc;
        fstring  namespace, domain, user;
        struct policy_handle dom_pol;
-       struct winbindd_domain *contact_domain = domainSt;
+       struct winbindd_domain *contact_domain = wb_child_domain();
        struct rpc_pipe_client *cli = NULL;
        struct dcerpc_binding_handle *b = NULL;
+       pid_t client_pid;
 
        ZERO_STRUCT(dom_pol);
 
-       /* Ensure null termination */
-       state->request->data.chng_pswd_auth_crap.user[
-               sizeof(state->request->data.chng_pswd_auth_crap.user)-1]=0;
-       state->request->data.chng_pswd_auth_crap.domain[
-               sizeof(state->request->data.chng_pswd_auth_crap.domain)-1]=0;
+       if (contact_domain == NULL) {
+               return NT_STATUS_REQUEST_NOT_ACCEPTED;
+       }
+
+       /* Cut client_pid to 32bit */
+       client_pid = r->in.client_pid;
+       if ((uint64_t)client_pid != r->in.client_pid) {
+               DBG_DEBUG("pid out of range\n");
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        domain[0] = '\0';
        namespace[0] = '\0';
        user[0] = '\0';
 
-       DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
-                 (unsigned long)state->pid,
-                 state->request->data.chng_pswd_auth_crap.domain,
-                 state->request->data.chng_pswd_auth_crap.user));
+       DBG_NOTICE("[%"PRIu32"]: pam change pswd auth crap domain: %s "
+                  "user: %s\n", client_pid, r->in.domain, r->in.user);
 
        if (lp_winbind_offline_logon()) {
                DEBUG(0,("Refusing password change as winbind offline logons are enabled. "));
@@ -3200,12 +3202,12 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
                goto done;
        }
 
-       if (*state->request->data.chng_pswd_auth_crap.domain) {
-               fstrcpy(domain,state->request->data.chng_pswd_auth_crap.domain);
+       if (r->in.domain != NULL && strlen(r->in.domain) > 0) {
+               fstrcpy(domain, r->in.domain);
        } else {
                bool ok;
 
-               ok = parse_domain_user(state->request->data.chng_pswd_auth_crap.user,
+               ok = parse_domain_user(r->in.user,
                                       namespace,
                                       domain,
                                       user);
@@ -3214,10 +3216,9 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
                        goto done;
                }
 
-               if(!*domain) {
-                       DEBUG(3,("no domain specified with username (%s) - "
-                                "failing auth\n",
-                                state->request->data.chng_pswd_auth_crap.user));
+               if (strlen(domain) == 0) {
+                       DBG_NOTICE("no domain specified with username (%s) - "
+                                  "failing auth\n", r->in.user);
                        result = NT_STATUS_NO_SUCH_USER;
                        goto done;
                }
@@ -3230,44 +3231,23 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
        if (!is_allowed_domain(domain)) {
                DBG_NOTICE("Authentication failed for user [%s] "
                           "from firewalled domain [%s]\n",
-                          state->request->data.chng_pswd_auth_crap.user,
+                          r->in.user,
                           domain);
                result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
                goto done;
        }
 
        if(!*user) {
-               fstrcpy(user, state->request->data.chng_pswd_auth_crap.user);
-       }
-
-       DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n",
-                 (unsigned long)state->pid, domain, user));
-
-       /* Change password */
-       new_nt_password = data_blob_const(
-               state->request->data.chng_pswd_auth_crap.new_nt_pswd,
-               state->request->data.chng_pswd_auth_crap.new_nt_pswd_len);
-
-       old_nt_hash_enc = data_blob_const(
-               state->request->data.chng_pswd_auth_crap.old_nt_hash_enc,
-               state->request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
-
-       if(state->request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0)        {
-               new_lm_password = data_blob_const(
-                       state->request->data.chng_pswd_auth_crap.new_lm_pswd,
-                       state->request->data.chng_pswd_auth_crap.new_lm_pswd_len);
-
-               old_lm_hash_enc = data_blob_const(
-                       state->request->data.chng_pswd_auth_crap.old_lm_hash_enc,
-                       state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
-       } else {
-               new_lm_password = data_blob_null;
-               old_lm_hash_enc = data_blob_null;
+               fstrcpy(user, r->in.user);
        }
 
        /* Get sam handle */
 
-       result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli, &dom_pol);
+       result = cm_connect_sam(contact_domain,
+                               p->mem_ctx,
+                               true,
+                               &cli,
+                               &dom_pol);
        if (!NT_STATUS_IS_OK(result)) {
                DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
                goto done;
@@ -3275,9 +3255,13 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
 
        b = cli->binding_handle;
 
-       result = rpccli_samr_chng_pswd_auth_crap(
-               cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc,
-               new_lm_password, old_lm_hash_enc);
+       result = rpccli_samr_chng_pswd_auth_crap(cli,
+                                                p->mem_ctx,
+                                                user,
+                                                r->in.new_nt_pswd,
+                                                r->in.old_nt_hash_enc,
+                                                r->in.new_lm_pswd,
+                                                r->in.old_lm_hash_enc);
 
  done:
 
@@ -3286,21 +3270,22 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
                if (b) {
                        if (is_valid_policy_hnd(&dom_pol)) {
                                NTSTATUS _result;
-                               dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result);
+                               dcerpc_samr_Close(b,
+                                                 p->mem_ctx,
+                                                 &dom_pol,
+                                                 &_result);
                        }
                        TALLOC_FREE(cli);
                }
        }
 
-       set_auth_errors(state->response, result);
-
        DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
              ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
               domain, user,
-              state->response->data.auth.nt_status_string,
-              state->response->data.auth.pam_error));
+              nt_errstr(result),
+              nt_status_to_pam(result)));
 
-       return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+       return result;
 }
 
 #ifdef HAVE_KRB5
index 4c39ce0b5aca91391f54ea80f109f7bde01a8a54..8b69f024af1a40d8d3f37fa9cac0c3a3d1caf864 100644 (file)
 #include "includes.h"
 #include "winbindd.h"
 #include "lib/global_contexts.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
 
 struct winbindd_pam_chng_pswd_auth_crap_state {
-       struct winbindd_request *request;
-       struct winbindd_response *response;
+       struct wbint_PamAuthCrapChangePassword r;
 };
 
 static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq);
@@ -44,7 +44,6 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
        if (req == NULL) {
                return NULL;
        }
-       state->request = request;
 
        /* Ensure null termination */
        request->data.chng_pswd_auth_crap.user[
@@ -58,8 +57,8 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
                  request->data.chng_pswd_auth_crap.user));
 
        domain_name = NULL;
-       if (*state->request->data.chng_pswd_auth_crap.domain != '\0') {
-               domain_name = state->request->data.chng_pswd_auth_crap.domain;
+       if (*request->data.chng_pswd_auth_crap.domain != '\0') {
+               domain_name = request->data.chng_pswd_auth_crap.domain;
        } else if (lp_winbind_use_default_domain()) {
                domain_name = lp_workgroup();
        }
@@ -74,8 +73,59 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
                return tevent_req_post(req, ev);
        }
 
-       subreq = wb_domain_request_send(state, global_event_context(),
-                                       domain, request);
+       state->r.in.client_pid = request->pid;
+       state->r.in.client_name = talloc_strdup(state, request->client_name);
+       if (tevent_req_nomem(state->r.in.client_name, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       state->r.in.domain = talloc_strdup(state, domain_name);
+       if (tevent_req_nomem(state->r.in.domain, req)) {
+               return tevent_req_post(req, ev);
+       }
+       state->r.in.user = talloc_strdup(state,
+               request->data.chng_pswd_auth_crap.user);
+       if (tevent_req_nomem(state->r.in.user, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       state->r.in.new_nt_pswd = data_blob_talloc(state,
+               request->data.chng_pswd_auth_crap.new_nt_pswd,
+               request->data.chng_pswd_auth_crap.new_nt_pswd_len);
+       if (tevent_req_nomem(state->r.in.new_nt_pswd.data, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       state->r.in.old_nt_hash_enc = data_blob_talloc(state,
+               request->data.chng_pswd_auth_crap.old_nt_hash_enc,
+               request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
+       if (tevent_req_nomem(state->r.in.old_nt_hash_enc.data, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       if (request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0) {
+               state->r.in.new_lm_pswd = data_blob_talloc(state,
+                       request->data.chng_pswd_auth_crap.new_lm_pswd,
+                       request->data.chng_pswd_auth_crap.new_lm_pswd_len);
+               if (tevent_req_nomem(state->r.in.new_lm_pswd.data, req)) {
+                       return tevent_req_post(req, ev);
+               }
+
+               state->r.in.old_lm_hash_enc = data_blob_talloc(state,
+                       request->data.chng_pswd_auth_crap.old_lm_hash_enc,
+                       request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
+               if (tevent_req_nomem(state->r.in.old_lm_hash_enc.data, req)) {
+                       return tevent_req_post(req, ev);
+               }
+       } else {
+               state->r.in.new_lm_pswd = data_blob_null;
+               state->r.in.old_lm_hash_enc = data_blob_null;
+       }
+
+       subreq = dcerpc_wbint_PamAuthCrapChangePassword_r_send(state,
+                                               global_event_context(),
+                                               dom_child_handle(domain),
+                                               &state->r);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -90,14 +140,14 @@ static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
                req, struct winbindd_pam_chng_pswd_auth_crap_state);
-       int res, err;
+       NTSTATUS status;
 
-       res = wb_domain_request_recv(subreq, state, &state->response, &err);
+       status = dcerpc_wbint_PamAuthCrapChangePassword_r_recv(subreq, state);
        TALLOC_FREE(subreq);
-       if (res == -1) {
-               tevent_req_nterror(req, map_nt_error_from_unix(err));
+       if (tevent_req_nterror(req, status)) {
                return;
        }
+
        tevent_req_done(req);
 }
 
@@ -107,15 +157,15 @@ NTSTATUS winbindd_pam_chng_pswd_auth_crap_recv(
 {
        struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
                req, struct winbindd_pam_chng_pswd_auth_crap_state);
-       NTSTATUS status;
+       NTSTATUS status = NT_STATUS_OK;
 
        if (tevent_req_is_nterror(req, &status)) {
                set_auth_errors(response, status);
                return status;
        }
-       *response = *state->response;
+
        response->result = WINBINDD_PENDING;
-       state->response = talloc_move(response, &state->response);
+       set_auth_errors(response, state->r.out.result);
 
        return NT_STATUS(response->data.auth.nt_status);
 }
index 6dad82fc0a82922f2136bc243159a9b71e690509..76fd4cb0865839ea558083e1879e31150de68276 100644 (file)
@@ -447,7 +447,8 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
                                                 struct winbindd_cli_state *state);
 NTSTATUS _wbint_PamLogOff(struct pipes_struct *p,
                          struct wbint_PamLogOff *r);
-enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
+NTSTATUS _wbint_PamAuthCrapChangePassword(struct pipes_struct *p,
+                                         struct wbint_PamAuthCrapChangePassword *r);
 NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state,
                                      TALLOC_CTX *mem_ctx,
                                      bool *p_is_trusted,