LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_pam_chauthtok.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 46 79 58.2 %
Date: 2024-06-13 04:01:37 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async implementation of WINBINDD_PAM_CHAUTHTOK
       4             :    Copyright (C) Volker Lendecke 2010
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "winbindd.h"
      22             : #include "lib/util/string_wrappers.h"
      23             : #include "lib/global_contexts.h"
      24             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      25             : 
      26           0 : static void fill_in_password_policy(struct winbindd_response *r,
      27             :                                     const struct samr_DomInfo1 *p)
      28             : {
      29           0 :         r->data.auth.policy.min_length_password =
      30           0 :                 p->min_password_length;
      31           0 :         r->data.auth.policy.password_history =
      32           0 :                 p->password_history_length;
      33           0 :         r->data.auth.policy.password_properties =
      34           0 :                 p->password_properties;
      35           0 :         r->data.auth.policy.expire   =
      36           0 :                 nt_time_to_unix_abs((const NTTIME *)&(p->max_password_age));
      37           0 :         r->data.auth.policy.min_passwordage =
      38           0 :                 nt_time_to_unix_abs((const NTTIME *)&(p->min_password_age));
      39           0 : }
      40             : 
      41             : struct winbindd_pam_chauthtok_state {
      42             :         struct wbint_PamAuthChangePassword r;
      43             : };
      44             : 
      45             : static void winbindd_pam_chauthtok_done(struct tevent_req *subreq);
      46             : 
      47          13 : struct tevent_req *winbindd_pam_chauthtok_send(
      48             :         TALLOC_CTX *mem_ctx,
      49             :         struct tevent_context *ev,
      50             :         struct winbindd_cli_state *cli,
      51             :         struct winbindd_request *request)
      52             : {
      53             :         struct tevent_req *req, *subreq;
      54             :         struct winbindd_pam_chauthtok_state *state;
      55             :         struct winbindd_domain *contact_domain;
      56             :         fstring namespace, domain, user;
      57             :         char *mapped_user;
      58             :         NTSTATUS status;
      59             :         bool ok;
      60             : 
      61          13 :         req = tevent_req_create(mem_ctx, &state,
      62             :                                 struct winbindd_pam_chauthtok_state);
      63          13 :         if (req == NULL) {
      64           0 :                 return NULL;
      65             :         }
      66             : 
      67             :         /* Ensure null termination */
      68             :         request->data.chauthtok.user[
      69          13 :                 sizeof(request->data.chauthtok.user)-1]='\0';
      70             : 
      71          13 :         DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)cli->pid,
      72             :                   request->data.chauthtok.user));
      73             : 
      74          13 :         status = normalize_name_unmap(state, request->data.chauthtok.user,
      75             :                                       &mapped_user);
      76             : 
      77          20 :         if (NT_STATUS_IS_OK(status) ||
      78          13 :             NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
      79           0 :                 fstrcpy(request->data.chauthtok.user, mapped_user);
      80             :         }
      81             : 
      82          13 :         ok = canonicalize_username(request->data.chauthtok.user,
      83             :                                    namespace,
      84             :                                    domain,
      85             :                                    user);
      86          13 :         if (!ok) {
      87           0 :                 DEBUG(10, ("winbindd_pam_chauthtok: canonicalize_username %s "
      88             :                            "failed with\n", request->data.chauthtok.user));
      89           0 :                 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
      90           0 :                 return tevent_req_post(req, ev);
      91             :         }
      92             : 
      93          13 :         contact_domain = find_domain_from_name(namespace);
      94          13 :         if (contact_domain == NULL) {
      95           0 :                 DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] "
      96             :                           "as %s is not a trusted domain\n",
      97             :                           request->data.chauthtok.user, domain, user, domain));
      98           0 :                 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
      99           0 :                 return tevent_req_post(req, ev);
     100             :         }
     101             : 
     102          13 :         state->r.in.client_pid = request->pid;
     103          13 :         state->r.in.flags = request->flags;
     104             : 
     105          13 :         state->r.in.client_name = talloc_strdup(state, request->client_name);
     106          13 :         if (tevent_req_nomem(state->r.in.client_name, req)) {
     107           0 :                 return tevent_req_post(req, ev);
     108             :         }
     109             : 
     110          13 :         state->r.in.user = talloc_strdup(state, request->data.chauthtok.user);
     111          13 :         if (tevent_req_nomem(state->r.in.user, req)) {
     112           0 :                 return tevent_req_post(req, ev);
     113             :         }
     114             : 
     115          19 :         state->r.in.old_password = talloc_strdup(state,
     116          13 :                         request->data.chauthtok.oldpass);
     117          13 :         if (tevent_req_nomem(state->r.in.old_password, req)) {
     118           0 :                 return tevent_req_post(req, ev);
     119             :         }
     120             : 
     121          19 :         state->r.in.new_password = talloc_strdup(state,
     122          13 :                         request->data.chauthtok.newpass);
     123          13 :         if (tevent_req_nomem(state->r.in.new_password, req)) {
     124           0 :                 return tevent_req_post(req, ev);
     125             :         }
     126             : 
     127          13 :         subreq = dcerpc_wbint_PamAuthChangePassword_r_send(state,
     128             :                                         global_event_context(),
     129             :                                         dom_child_handle(contact_domain),
     130          13 :                                         &state->r);
     131          13 :         if (tevent_req_nomem(subreq, req)) {
     132           0 :                 return tevent_req_post(req, ev);
     133             :         }
     134          13 :         tevent_req_set_callback(subreq, winbindd_pam_chauthtok_done, req);
     135          13 :         return req;
     136             : }
     137             : 
     138          13 : static void winbindd_pam_chauthtok_done(struct tevent_req *subreq)
     139             : {
     140          13 :         struct tevent_req *req = tevent_req_callback_data(
     141             :                 subreq, struct tevent_req);
     142          13 :         struct winbindd_pam_chauthtok_state *state = tevent_req_data(
     143             :                 req, struct winbindd_pam_chauthtok_state);
     144             :         NTSTATUS status;
     145             : 
     146          13 :         status = dcerpc_wbint_PamAuthChangePassword_r_recv(subreq, state);
     147          13 :         TALLOC_FREE(subreq);
     148          13 :         if (tevent_req_nterror(req, status)) {
     149           0 :                 return;
     150             :         }
     151             : 
     152          13 :         tevent_req_done(req);
     153             : }
     154             : 
     155          13 : NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req,
     156             :                                      struct winbindd_response *response)
     157             : {
     158          13 :         struct winbindd_pam_chauthtok_state *state = tevent_req_data(
     159             :                 req, struct winbindd_pam_chauthtok_state);
     160          13 :         NTSTATUS status = NT_STATUS_OK;
     161             : 
     162          13 :         if (tevent_req_is_nterror(req, &status)) {
     163           0 :                 set_auth_errors(response, status);
     164           0 :                 return status;
     165             :         }
     166             : 
     167          13 :         response->result = WINBINDD_PENDING;
     168             : 
     169          13 :         set_auth_errors(response, state->r.out.result);
     170          13 :         if (*state->r.out.dominfo != NULL) {
     171           0 :                 fill_in_password_policy(response, *state->r.out.dominfo);
     172             :         }
     173          13 :         response->data.auth.reject_reason = *state->r.out.reject_reason;
     174             : 
     175          13 :         if (state->r.in.flags & WBFLAG_PAM_CACHED_LOGIN) {
     176             : 
     177             :                 /* Update the single sign-on memory creds. */
     178           0 :                 status = winbindd_replace_memory_creds(
     179             :                         state->r.in.user, state->r.in.new_password);
     180             : 
     181           0 :                 DEBUG(10, ("winbindd_replace_memory_creds returned %s\n",
     182             :                            nt_errstr(status)));
     183             : 
     184             :                 /*
     185             :                  * When we login from gdm or xdm and password expires,
     186             :                  * we change password, but there are no memory
     187             :                  * crendentials So, winbindd_replace_memory_creds()
     188             :                  * returns NT_STATUS_OBJECT_NAME_NOT_FOUND. This is
     189             :                  * not a failure.  --- BoYang
     190             :                  */
     191           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     192           0 :                         status = NT_STATUS_OK;
     193             :                 }
     194             :         }
     195             : 
     196          13 :         return NT_STATUS(response->data.auth.nt_status);
     197             : }

Generated by: LCOV version 1.13