2 Unix SMB/CIFS implementation.
3 async implementation of WINBINDD_PAM_AUTH_CRAP
4 Copyright (C) Volker Lendecke 2010
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.
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.
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/>.
22 #include "rpc_client/util_netlogon.h"
23 #include "libcli/security/dom_sid.h"
25 struct winbindd_pam_auth_crap_state
{
26 struct winbindd_response
*response
;
30 static void winbindd_pam_auth_crap_done(struct tevent_req
*subreq
);
32 struct tevent_req
*winbindd_pam_auth_crap_send(
34 struct tevent_context
*ev
,
35 struct winbindd_cli_state
*cli
,
36 struct winbindd_request
*request
)
38 struct tevent_req
*req
, *subreq
;
39 struct winbindd_pam_auth_crap_state
*state
;
40 struct winbindd_domain
*domain
;
41 const char *auth_domain
= NULL
;
43 req
= tevent_req_create(mem_ctx
, &state
,
44 struct winbindd_pam_auth_crap_state
);
49 state
->flags
= request
->flags
;
51 if (state
->flags
& WBFLAG_PAM_AUTH_PAC
) {
52 bool is_trusted
= false;
53 uint16_t validation_level
;
54 union netr_Validation
*validation
= NULL
;
57 status
= winbindd_pam_auth_pac_verify(cli
,
61 if (tevent_req_nterror(req
, status
)) {
62 return tevent_req_post(req
, ev
);
65 state
->response
= talloc_zero(state
,
66 struct winbindd_response
);
67 if (tevent_req_nomem(state
->response
, req
)) {
68 return tevent_req_post(req
, ev
);
70 state
->response
->result
= WINBINDD_PENDING
;
71 state
->response
->length
= sizeof(struct winbindd_response
);
73 status
= append_auth_data(state
->response
,
79 TALLOC_FREE(validation
);
80 if (tevent_req_nterror(req
, status
)) {
81 return tevent_req_post(req
, ev
);
84 if (is_trusted
&& (state
->flags
& WBFLAG_PAM_INFO3_TEXT
)) {
87 ok
= add_trusted_domain_from_auth(
88 state
->response
->data
.auth
.validation_level
,
89 &state
->response
->data
.auth
.info3
,
90 &state
->response
->data
.auth
.info6
);
92 DBG_ERR("add_trusted_domain_from_auth failed\n");
93 tevent_req_nterror(req
, NT_STATUS_LOGON_FAILURE
);
94 return tevent_req_post(req
, ev
);
99 return tevent_req_post(req
, ev
);
102 /* Ensure null termination */
103 request
->data
.auth_crap
.user
[
104 sizeof(request
->data
.auth_crap
.user
)-1] = '\0';
105 request
->data
.auth_crap
.domain
[
106 sizeof(request
->data
.auth_crap
.domain
)-1] = '\0';
107 request
->data
.auth_crap
.workstation
[
108 sizeof(request
->data
.auth_crap
.workstation
)-1] = '\0';
110 DEBUG(3, ("[%5lu]: pam auth crap domain: [%s] user: %s\n",
111 (unsigned long)cli
->pid
,
112 request
->data
.auth_crap
.domain
,
113 request
->data
.auth_crap
.user
));
115 if (!check_request_flags(request
->flags
)) {
116 tevent_req_nterror(req
, NT_STATUS_INVALID_PARAMETER_MIX
);
117 return tevent_req_post(req
, ev
);
120 auth_domain
= request
->data
.auth_crap
.domain
;
121 if (auth_domain
[0] == '\0') {
122 auth_domain
= lp_workgroup();
125 domain
= find_auth_domain(request
->flags
, auth_domain
);
126 if (domain
== NULL
) {
127 tevent_req_nterror(req
, NT_STATUS_NO_SUCH_USER
);
128 return tevent_req_post(req
, ev
);
131 if (request
->data
.auth_crap
.workstation
[0] == '\0') {
132 fstrcpy(request
->data
.auth_crap
.workstation
, lp_netbios_name());
135 subreq
= wb_domain_request_send(state
, server_event_context(), domain
,
137 if (tevent_req_nomem(subreq
, req
)) {
138 return tevent_req_post(req
, ev
);
140 tevent_req_set_callback(subreq
, winbindd_pam_auth_crap_done
, req
);
144 static void winbindd_pam_auth_crap_done(struct tevent_req
*subreq
)
146 struct tevent_req
*req
= tevent_req_callback_data(
147 subreq
, struct tevent_req
);
148 struct winbindd_pam_auth_crap_state
*state
= tevent_req_data(
149 req
, struct winbindd_pam_auth_crap_state
);
152 res
= wb_domain_request_recv(subreq
, state
, &state
->response
, &err
);
155 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
159 if (NT_STATUS_IS_OK(NT_STATUS(state
->response
->data
.auth
.nt_status
)) &&
160 (state
->flags
& WBFLAG_PAM_INFO3_TEXT
))
164 ok
= add_trusted_domain_from_auth(
165 state
->response
->data
.auth
.validation_level
,
166 &state
->response
->data
.auth
.info3
,
167 &state
->response
->data
.auth
.info6
);
169 DBG_ERR("add_trusted_domain_from_auth failed\n");
170 tevent_req_nterror(req
, NT_STATUS_LOGON_FAILURE
);
175 tevent_req_done(req
);
178 NTSTATUS
winbindd_pam_auth_crap_recv(struct tevent_req
*req
,
179 struct winbindd_response
*response
)
181 struct winbindd_pam_auth_crap_state
*state
= tevent_req_data(
182 req
, struct winbindd_pam_auth_crap_state
);
185 if (tevent_req_is_nterror(req
, &status
)) {
186 set_auth_errors(response
, status
);
190 *response
= *state
->response
;
191 response
->result
= WINBINDD_PENDING
;
192 state
->response
= talloc_move(response
, &state
->response
);
193 return NT_STATUS(response
->data
.auth
.nt_status
);