Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : async implementation of WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP
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/global_contexts.h"
23 : #include "librpc/gen_ndr/ndr_winbind_c.h"
24 :
25 : struct winbindd_pam_chng_pswd_auth_crap_state {
26 : struct wbint_PamAuthCrapChangePassword r;
27 : };
28 :
29 : static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq);
30 :
31 2 : struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
32 : TALLOC_CTX *mem_ctx,
33 : struct tevent_context *ev,
34 : struct winbindd_cli_state *cli,
35 : struct winbindd_request *request)
36 : {
37 0 : struct tevent_req *req, *subreq;
38 0 : struct winbindd_pam_chng_pswd_auth_crap_state *state;
39 0 : struct winbindd_domain *domain;
40 0 : const char *domain_name;
41 :
42 2 : req = tevent_req_create(mem_ctx, &state,
43 : struct winbindd_pam_chng_pswd_auth_crap_state);
44 2 : if (req == NULL) {
45 0 : return NULL;
46 : }
47 :
48 : /* Ensure null termination */
49 0 : request->data.chng_pswd_auth_crap.user[
50 2 : sizeof(request->data.chng_pswd_auth_crap.user)-1]='\0';
51 0 : request->data.chng_pswd_auth_crap.domain[
52 2 : sizeof(request->data.chng_pswd_auth_crap.domain)-1]=0;
53 :
54 2 : DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
55 : (unsigned long)cli->pid,
56 : request->data.chng_pswd_auth_crap.domain,
57 : request->data.chng_pswd_auth_crap.user));
58 :
59 2 : domain_name = NULL;
60 2 : if (*request->data.chng_pswd_auth_crap.domain != '\0') {
61 2 : domain_name = request->data.chng_pswd_auth_crap.domain;
62 0 : } else if (lp_winbind_use_default_domain()) {
63 0 : domain_name = lp_workgroup();
64 : }
65 :
66 2 : domain = NULL;
67 2 : if (domain_name != NULL) {
68 2 : domain = find_domain_from_name(domain_name);
69 : }
70 :
71 2 : if (domain == NULL) {
72 0 : tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
73 0 : return tevent_req_post(req, ev);
74 : }
75 :
76 2 : state->r.in.client_pid = request->pid;
77 2 : state->r.in.client_name = talloc_strdup(state, request->client_name);
78 2 : if (tevent_req_nomem(state->r.in.client_name, req)) {
79 0 : return tevent_req_post(req, ev);
80 : }
81 :
82 2 : state->r.in.domain = talloc_strdup(state, domain_name);
83 2 : if (tevent_req_nomem(state->r.in.domain, req)) {
84 0 : return tevent_req_post(req, ev);
85 : }
86 4 : state->r.in.user = talloc_strdup(state,
87 2 : request->data.chng_pswd_auth_crap.user);
88 2 : if (tevent_req_nomem(state->r.in.user, req)) {
89 0 : return tevent_req_post(req, ev);
90 : }
91 :
92 2 : state->r.in.new_nt_pswd = data_blob_talloc(state,
93 : request->data.chng_pswd_auth_crap.new_nt_pswd,
94 : request->data.chng_pswd_auth_crap.new_nt_pswd_len);
95 2 : if (tevent_req_nomem(state->r.in.new_nt_pswd.data, req)) {
96 0 : return tevent_req_post(req, ev);
97 : }
98 :
99 2 : state->r.in.old_nt_hash_enc = data_blob_talloc(state,
100 : request->data.chng_pswd_auth_crap.old_nt_hash_enc,
101 : request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
102 2 : if (tevent_req_nomem(state->r.in.old_nt_hash_enc.data, req)) {
103 0 : return tevent_req_post(req, ev);
104 : }
105 :
106 2 : if (request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0) {
107 0 : state->r.in.new_lm_pswd = data_blob_talloc(state,
108 : request->data.chng_pswd_auth_crap.new_lm_pswd,
109 : request->data.chng_pswd_auth_crap.new_lm_pswd_len);
110 0 : if (tevent_req_nomem(state->r.in.new_lm_pswd.data, req)) {
111 0 : return tevent_req_post(req, ev);
112 : }
113 :
114 0 : state->r.in.old_lm_hash_enc = data_blob_talloc(state,
115 : request->data.chng_pswd_auth_crap.old_lm_hash_enc,
116 : request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
117 0 : if (tevent_req_nomem(state->r.in.old_lm_hash_enc.data, req)) {
118 0 : return tevent_req_post(req, ev);
119 : }
120 : } else {
121 2 : state->r.in.new_lm_pswd = data_blob_null;
122 2 : state->r.in.old_lm_hash_enc = data_blob_null;
123 : }
124 :
125 2 : subreq = dcerpc_wbint_PamAuthCrapChangePassword_r_send(state,
126 : global_event_context(),
127 : dom_child_handle(domain),
128 2 : &state->r);
129 2 : if (tevent_req_nomem(subreq, req)) {
130 0 : return tevent_req_post(req, ev);
131 : }
132 2 : tevent_req_set_callback(subreq, winbindd_pam_chng_pswd_auth_crap_done,
133 : req);
134 2 : return req;
135 : }
136 :
137 2 : static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq)
138 : {
139 2 : struct tevent_req *req = tevent_req_callback_data(
140 : subreq, struct tevent_req);
141 2 : struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
142 : req, struct winbindd_pam_chng_pswd_auth_crap_state);
143 0 : NTSTATUS status;
144 :
145 2 : status = dcerpc_wbint_PamAuthCrapChangePassword_r_recv(subreq, state);
146 2 : TALLOC_FREE(subreq);
147 2 : if (tevent_req_nterror(req, status)) {
148 0 : return;
149 : }
150 :
151 2 : tevent_req_done(req);
152 : }
153 :
154 2 : NTSTATUS winbindd_pam_chng_pswd_auth_crap_recv(
155 : struct tevent_req *req,
156 : struct winbindd_response *response)
157 : {
158 2 : struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
159 : req, struct winbindd_pam_chng_pswd_auth_crap_state);
160 2 : NTSTATUS status = NT_STATUS_OK;
161 :
162 2 : if (tevent_req_is_nterror(req, &status)) {
163 0 : set_auth_errors(response, status);
164 0 : return status;
165 : }
166 :
167 2 : response->result = WINBINDD_PENDING;
168 2 : set_auth_errors(response, state->r.out.result);
169 :
170 2 : return NT_STATUS(response->data.auth.nt_status);
171 : }
|