s3: Convert WINBINDD_PAM_AUTH to the new async API
authorVolker Lendecke <vl@samba.org>
Mon, 29 Mar 2010 15:52:38 +0000 (17:52 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 19 Apr 2010 12:27:19 +0000 (14:27 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_pam_auth.c [new file with mode: 0644]
source3/winbindd/winbindd_proto.h

index f83450957e7fd22f153f3e6ed955dfe08e985452..a15ec2d0f6b55b7b1e7526b9f1ecdaec89122c81 100644 (file)
@@ -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 \
index a7f3a600ca7db6bda4fdcfb36d7522fbf5a2b9fc..d9335d08d53c00b7da9449ed58f8f18b13754725 100644 (file)
@@ -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 }
 };
index 796bc3eaed7930570e55e89a77baf4ef410165cb..2e1bc204e6793a66680ab62085258a6a1e2e7cff 100644 (file)
@@ -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 (file)
index 0000000..b32d882
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+
+#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);
+}
index d481380bb50e4ef23852fb6b687cfc22b0651606..4daf0857f2de186b94d316074c963c3fb1038eb2 100644 (file)
@@ -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_  */