From 61ec0f571ad81dc101fe6de7a8e9674a7119cf2b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 29 Mar 2010 17:52:38 +0200 Subject: s3: Convert WINBINDD_PAM_AUTH to the new async API --- source3/Makefile.in | 1 + source3/winbindd/winbindd.c | 3 +- source3/winbindd/winbindd_pam.c | 64 ------------------ source3/winbindd/winbindd_pam_auth.c | 125 +++++++++++++++++++++++++++++++++++ source3/winbindd/winbindd_proto.h | 8 ++- 5 files changed, 135 insertions(+), 66 deletions(-) create mode 100644 source3/winbindd/winbindd_pam_auth.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index f83450957e..a15ec2d0f6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1237,6 +1237,7 @@ WINBINDD_OBJ1 = \ winbindd/winbindd_set_mapping.o \ winbindd/winbindd_remove_mapping.o \ winbindd/winbindd_set_hwm.o \ + winbindd/winbindd_pam_auth.o \ auth/token_util.o \ auth/check_samsec.o \ auth/server_info.o \ diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index a7f3a600ca..d9335d08d5 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -444,7 +444,6 @@ static struct winbindd_dispatch_table { /* PAM auth functions */ - { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" }, { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" }, { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" }, { WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" }, @@ -552,6 +551,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv }, { WINBINDD_PING_DC, "PING_DC", winbindd_ping_dc_send, winbindd_ping_dc_recv }, + { WINBINDD_PAM_AUTH, "PAM_AUTH", + winbindd_pam_auth_send, winbindd_pam_auth_recv }, { 0, NULL, NULL, NULL } }; diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 796bc3eaed..2e1bc204e6 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -795,70 +795,6 @@ static NTSTATUS append_auth_data(struct winbindd_cli_state *state, return NT_STATUS_OK; } -void winbindd_pam_auth(struct winbindd_cli_state *state) -{ - struct winbindd_domain *domain; - fstring name_domain, name_user, mapped_user; - char *mapped = NULL; - NTSTATUS result; - NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; - - /* Ensure null termination */ - state->request->data.auth.user - [sizeof(state->request->data.auth.user)-1]='\0'; - - /* Ensure null termination */ - state->request->data.auth.pass - [sizeof(state->request->data.auth.pass)-1]='\0'; - - DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid, - state->request->data.auth.user)); - - if (!check_request_flags(state->request->flags)) { - result = NT_STATUS_INVALID_PARAMETER_MIX; - goto done; - } - - /* Parse domain and username */ - - name_map_status = normalize_name_unmap(state->mem_ctx, - state->request->data.auth.user, - &mapped); - - /* If the name normalization didnt' actually do anything, - just use the original name */ - - if (NT_STATUS_IS_OK(name_map_status) - ||NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) { - fstrcpy(mapped_user, mapped); - } else { - fstrcpy(mapped_user, state->request->data.auth.user); - } - - if (!canonicalize_username(mapped_user, name_domain, name_user)) { - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - - domain = find_auth_domain(state->request->flags, name_domain); - - if (domain == NULL) { - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - - sendto_domain(state, domain); - return; - done: - set_auth_errors(state->response, result); - DEBUG(5, ("Plain text authentication for %s returned %s " - "(PAM: %d)\n", - state->request->data.auth.user, - state->response->data.auth.nt_status_string, - state->response->data.auth.pam_error)); - request_error(state); -} - static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, struct winbindd_cli_state *state, struct netr_SamInfo3 **info3) diff --git a/source3/winbindd/winbindd_pam_auth.c b/source3/winbindd/winbindd_pam_auth.c new file mode 100644 index 0000000000..b32d882827 --- /dev/null +++ b/source3/winbindd/winbindd_pam_auth.c @@ -0,0 +1,125 @@ +/* + Unix SMB/CIFS implementation. + async implementation of WINBINDD_PAM_AUTH + Copyright (C) Volker Lendecke 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "winbindd.h" + +struct winbindd_pam_auth_state { + struct winbindd_response *response; +}; + +static void winbindd_pam_auth_done(struct tevent_req *subreq); + +struct tevent_req *winbindd_pam_auth_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request) +{ + struct tevent_req *req, *subreq; + struct winbindd_pam_auth_state *state; + struct winbindd_domain *domain; + fstring name_domain, name_user, mapped_user; + char *mapped = NULL; + NTSTATUS status; + + req = tevent_req_create(mem_ctx, &state, + struct winbindd_pam_auth_state); + if (req == NULL) { + return NULL; + } + + /* Ensure null termination */ + request->data.auth.user[sizeof(request->data.auth.user)-1] = '\0'; + request->data.auth.pass[sizeof(request->data.auth.pass)-1] = '\0'; + + DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)cli->pid, + request->data.auth.user)); + + if (!check_request_flags(request->flags)) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + + /* Parse domain and username */ + + status = normalize_name_unmap(state, request->data.auth.user, &mapped); + + /* If the name normalization didnt' actually do anything, + just use the original name */ + + if (NT_STATUS_IS_OK(status) + || NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) { + fstrcpy(mapped_user, mapped); + } else { + fstrcpy(mapped_user, request->data.auth.user); + } + + if (!canonicalize_username(mapped_user, name_domain, name_user)) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return tevent_req_post(req, ev); + } + + domain = find_auth_domain(request->flags, name_domain); + if (domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return tevent_req_post(req, ev); + } + + subreq = wb_domain_request_send(state, winbind_event_context(), domain, + request); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, winbindd_pam_auth_done, req); + return req; +} + +static void winbindd_pam_auth_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct winbindd_pam_auth_state *state = tevent_req_data( + req, struct winbindd_pam_auth_state); + int res, err; + + res = wb_domain_request_recv(subreq, state, &state->response, &err); + TALLOC_FREE(subreq); + if (res == -1) { + tevent_req_nterror(req, map_nt_error_from_unix(err)); + return; + } + tevent_req_done(req); +} + +NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req, + struct winbindd_response *response) +{ + struct winbindd_pam_auth_state *state = tevent_req_data( + req, struct winbindd_pam_auth_state); + NTSTATUS status; + + 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); + return NT_STATUS(response->data.auth.nt_status); +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index d481380bb5..4daf0857f2 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -382,7 +382,6 @@ void ndr_print_winbindd_domain(struct ndr_print *ndr, bool check_request_flags(uint32_t flags); struct winbindd_domain *find_auth_domain(uint8_t flags, const char *domain_name); -void winbindd_pam_auth(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, struct winbindd_cli_state *state) ; void winbindd_pam_auth_crap(struct winbindd_cli_state *state); @@ -852,4 +851,11 @@ struct tevent_req *winbindd_set_hwm_send(TALLOC_CTX *mem_ctx, NTSTATUS winbindd_set_hwm_recv(struct tevent_req *req, struct winbindd_response *response); +struct tevent_req *winbindd_pam_auth_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request); +NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req, + struct winbindd_response *response); + #endif /* _WINBINDD_PROTO_H_ */ -- cgit