s3: Convert WINBINDD_PAM_LOGOFF to the new async API
authorVolker Lendecke <vl@samba.org>
Thu, 1 Apr 2010 14:44:16 +0000 (16:44 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 19 Apr 2010 12:27:20 +0000 (14:27 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_pam_logoff.c [new file with mode: 0644]
source3/winbindd/winbindd_proto.h

index d05c57d52dda53e4332c9495be4d51c0db8a824b..c28dec466cc514c7aba9a1e89e466fef53707942 100644 (file)
@@ -1240,6 +1240,7 @@ WINBINDD_OBJ1 = \
                winbindd/winbindd_pam_auth.o \
                winbindd/winbindd_pam_auth_crap.o \
                winbindd/winbindd_pam_chauthtok.o \
+               winbindd/winbindd_pam_logoff.o \
                auth/token_util.o \
                auth/check_samsec.o \
                auth/server_info.o \
index cc273eb50e9ec1af0fb24504492997323146c795..3bd2ad7c09ddc29369d270492a4dd548178070f9 100644 (file)
@@ -444,7 +444,6 @@ static struct winbindd_dispatch_table {
 
        /* PAM auth functions */
 
-       { WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" },
        { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, winbindd_pam_chng_pswd_auth_crap, "CHNG_PSWD_AUTH_CRAP" },
 
        /* Enumeration functions */
@@ -551,6 +550,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_ping_dc_send, winbindd_ping_dc_recv },
        { WINBINDD_PAM_AUTH, "PAM_AUTH",
          winbindd_pam_auth_send, winbindd_pam_auth_recv },
+       { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
+         winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
        { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
          winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
 
index 61c8c298f1b615d1823e45ce6266184abf0a81cb..6aeeb2d1436b321eb4402dce5d88446e1634ccbb 100644 (file)
@@ -2051,72 +2051,6 @@ process_result:
        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
 }
 
-void winbindd_pam_logoff(struct winbindd_cli_state *state)
-{
-       struct winbindd_domain *domain;
-       fstring name_domain, user;
-       uid_t caller_uid = (uid_t)-1;
-       uid_t request_uid = state->request->data.logoff.uid;
-
-       /* Ensure null termination */
-       state->request->data.logoff.user
-               [sizeof(state->request->data.logoff.user)-1]='\0';
-
-       state->request->data.logoff.krb5ccname
-               [sizeof(state->request->data.logoff.krb5ccname)-1]='\0';
-
-       DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,
-               state->request->data.logoff.user));
-
-       if (request_uid == (uid_t)-1) {
-               goto failed;
-       }
-
-       if (!canonicalize_username(state->request->data.logoff.user, name_domain, user)) {
-               goto failed;
-       }
-
-       if ((domain = find_auth_domain(state->request->flags,
-                                      name_domain)) == NULL) {
-               goto failed;
-       }
-
-       if ((sys_getpeereid(state->sock, &caller_uid)) != 0) {
-               DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
-                       strerror(errno)));
-               goto failed;
-       }
-
-       switch (caller_uid) {
-               case -1:
-                       goto failed;
-               case 0:
-                       /* root must be able to logoff any user - gd */
-                       state->request->data.logoff.uid = request_uid;
-                       break;
-               default:
-                       if (caller_uid != request_uid) {
-                               DEBUG(1,("winbindd_pam_logoff: caller requested invalid uid\n"));
-                               goto failed;
-                       }
-                       state->request->data.logoff.uid = caller_uid;
-                       break;
-       }
-
-       sendto_domain(state, domain);
-       return;
-
- failed:
-       set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);
-       DEBUG(5, ("Pam Logoff for %s returned %s "
-                 "(PAM: %d)\n",
-                 state->request->data.logoff.user,
-                 state->response->data.auth.nt_status_string,
-                 state->response->data.auth.pam_error));
-       request_error(state);
-       return;
-}
-
 enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
                                              struct winbindd_cli_state *state)
 {
diff --git a/source3/winbindd/winbindd_pam_logoff.c b/source3/winbindd/winbindd_pam_logoff.c
new file mode 100644 (file)
index 0000000..9cf7f17
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_PAM_LOGOFF
+   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_logoff_state {
+       struct winbindd_response *response;
+};
+
+static void winbindd_pam_logoff_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_pam_logoff_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_logoff_state *state;
+       struct winbindd_domain *domain;
+       fstring name_domain, user;
+       uid_t caller_uid;
+       int res;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_pam_logoff_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       /* Ensure null termination */
+       /* Ensure null termination */
+       request->data.logoff.user[sizeof(request->data.logoff.user)-1]='\0';
+       request->data.logoff.krb5ccname[
+               sizeof(request->data.logoff.krb5ccname)-1]='\0';
+
+       DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)cli->pid,
+                 request->data.auth.user));
+
+       if (request->data.logoff.uid == (uid_t)-1) {
+               goto failed;
+       }
+
+       if (!canonicalize_username(request->data.logoff.user, name_domain,
+                                  user)) {
+               goto failed;
+       }
+
+       domain = find_auth_domain(request->flags, name_domain);
+       if (domain == NULL) {
+               goto failed;
+       }
+
+       caller_uid = (uid_t)-1;
+
+       res = sys_getpeereid(cli->sock, &caller_uid);
+       if (res != 0) {
+               DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",
+                       strerror(errno)));
+               goto failed;
+       }
+
+       switch (caller_uid) {
+       case -1:
+               goto failed;
+       case 0:
+               /* root must be able to logoff any user - gd */
+               break;
+       default:
+               if (caller_uid != request->data.logoff.uid) {
+                       DEBUG(1,("winbindd_pam_logoff: caller requested "
+                                "invalid uid\n"));
+                       goto failed;
+               }
+               break;
+       }
+
+       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_logoff_done, req);
+       return req;
+
+failed:
+       tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
+       return tevent_req_post(req, ev);
+}
+
+static void winbindd_pam_logoff_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_pam_logoff_state *state = tevent_req_data(
+               req, struct winbindd_pam_logoff_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_logoff_recv(struct tevent_req *req,
+                                 struct winbindd_response *response)
+{
+       struct winbindd_pam_logoff_state *state = tevent_req_data(
+               req, struct winbindd_pam_logoff_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 c72a1fe81d9c5fdb048da1f904b2044c1af2af5f..e47f300ab731a85feb56b4785a90be87c0c227cc 100644 (file)
@@ -388,7 +388,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                                                 struct winbindd_cli_state *state) ;
 enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
                                                 struct winbindd_cli_state *state);
-void winbindd_pam_logoff(struct winbindd_cli_state *state);
 enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
                                              struct winbindd_cli_state *state) ;
 void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state);
@@ -872,4 +871,11 @@ struct tevent_req *winbindd_pam_chauthtok_send(
 NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req,
                                     struct winbindd_response *response);
 
+struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct winbindd_cli_state *cli,
+                                           struct winbindd_request *request);
+NTSTATUS winbindd_pam_logoff_recv(struct tevent_req *req,
+                                 struct winbindd_response *response);
+
 #endif /*  _WINBINDD_PROTO_H_  */