]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:winbind: Convert PamLogOff from struct based to ndr based
authorSamuel Cabrero <scabrero@samba.org>
Wed, 16 Jun 2021 15:39:02 +0000 (17:39 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 19 May 2022 17:51:33 +0000 (17:51 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/idl/winbind.idl
source3/winbindd/winbindd_domain.c
source3/winbindd/winbindd_pam.c
source3/winbindd/winbindd_pam_logoff.c
source3/winbindd/winbindd_proto.h

index 3686809030af33bc528341dc55a5e14562316f2d..93fd56dff05608eede6c85aaeed056becebfbeea 100644 (file)
@@ -217,6 +217,15 @@ interface winbind
         [out,ref] wbint_PamAuthCrapValidation *validation
         );
 
+    NTSTATUS wbint_PamLogOff(
+        [in,string,charset(UTF8)] char *client_name,
+        [in] hyper client_pid,
+        [in] uint32 flags,
+        [in,string,charset(UTF8)] char *user,
+        [in,string,charset(UTF8)] char *krb5ccname,
+        [in] hyper uid
+        );
+
   /* Public methods available via IRPC */
 
     typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
index 80df55a5819783211b5054ee4b61386949b16ab8..1e19f67303844397e2860db7fc6277a87656eb14 100644 (file)
@@ -30,10 +30,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
                .name           = "INIT_CONNECTION",
                .struct_cmd     = WINBINDD_INIT_CONNECTION,
                .struct_fn      = winbindd_dual_init_connection,
-       },{
-               .name           = "PAM_LOGOFF",
-               .struct_cmd     = WINBINDD_PAM_LOGOFF,
-               .struct_fn      = winbindd_dual_pam_logoff,
        },{
                .name           = "CHNG_PSWD_AUTH_CRAP",
                .struct_cmd     = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
index 49a2cd7c83bfa9c5f15e7d5a1de841590ef2b09f..9395567510691b8e344010a7f93c862225a35903 100644 (file)
@@ -3081,51 +3081,68 @@ process_result:
        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
 }
 
-enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
-                                             struct winbindd_cli_state *state)
+NTSTATUS _wbint_PamLogOff(struct pipes_struct *p, struct wbint_PamLogOff *r)
 {
+       struct winbindd_domain *domain = wb_child_domain();
        NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
+       pid_t client_pid;
+       uid_t user_uid;
+
+       if (domain == NULL) {
+               return NT_STATUS_REQUEST_NOT_ACCEPTED;
+       }
+
+       /* Cut client_pid to 32bit */
+       client_pid = r->in.client_pid;
+       if ((uint64_t)client_pid != r->in.client_pid) {
+               DBG_DEBUG("pid out of range\n");
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* Cut uid to 32bit */
+       user_uid = r->in.uid;
+       if ((uint64_t)user_uid != r->in.uid) {
+               DBG_DEBUG("uid out of range\n");
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
-       DEBUG(3, ("[%5lu]: pam dual logoff %s\n", (unsigned long)state->pid,
-               state->request->data.logoff.user));
+       DBG_NOTICE("[%"PRIu32"]: pam dual logoff %s\n", client_pid, r->in.user);
 
-       if (!(state->request->flags & WBFLAG_PAM_KRB5)) {
+       if (!(r->in.flags & WBFLAG_PAM_KRB5)) {
                result = NT_STATUS_OK;
                goto process_result;
        }
 
-       if (state->request->data.logoff.krb5ccname[0] == '\0') {
+       if ((r->in.krb5ccname == NULL) || (strlen(r->in.krb5ccname) == 0)) {
                result = NT_STATUS_OK;
                goto process_result;
        }
 
 #ifdef HAVE_KRB5
 
-       if (state->request->data.logoff.uid == (uid_t)-1) {
-               DEBUG(0,("winbindd_pam_logoff: invalid uid\n"));
+       if (user_uid == (uid_t)-1) {
+               DBG_DEBUG("Invalid uid for user '%s'\n", r->in.user);
                goto process_result;
        }
 
        /* what we need here is to find the corresponding krb5 ccache name *we*
         * created for a given username and destroy it */
 
-       if (!ccache_entry_exists(state->request->data.logoff.user)) {
+       if (!ccache_entry_exists(r->in.user)) {
                result = NT_STATUS_OK;
-               DEBUG(10,("winbindd_pam_logoff: no entry found.\n"));
+               DBG_DEBUG("No entry found for user '%s'.\n", r->in.user);
                goto process_result;
        }
 
-       if (!ccache_entry_identical(state->request->data.logoff.user,
-                                       state->request->data.logoff.uid,
-                                       state->request->data.logoff.krb5ccname)) {
-               DEBUG(0,("winbindd_pam_logoff: cached entry differs.\n"));
+       if (!ccache_entry_identical(r->in.user, user_uid, r->in.krb5ccname)) {
+               DBG_DEBUG("Cached entry differs for user '%s'\n", r->in.user);
                goto process_result;
        }
 
-       result = remove_ccache(state->request->data.logoff.user);
+       result = remove_ccache(r->in.user);
        if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(0,("winbindd_pam_logoff: failed to remove ccache: %s\n",
-                       nt_errstr(result)));
+               DBG_DEBUG("Failed to remove ccache for user '%s': %s\n",
+                         r->in.user, nt_errstr(result));
                goto process_result;
        }
 
@@ -3134,7 +3151,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
         * we might be using for krb5 ticket renewal.
         */
 
-       winbindd_delete_memory_creds(state->request->data.logoff.user);
+       winbindd_delete_memory_creds(r->in.user);
 
 #else
        result = NT_STATUS_NOT_SUPPORTED;
@@ -3142,10 +3159,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
 
 process_result:
 
-
-       set_auth_errors(state->response, result);
-
-       return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+       return result;
 }
 
 /* Change user password with auth crap*/
index 553b1e5833b33d36e463d1470a5d6bdcf159615c..5578f887dcc8bc20086167d5701b98bc50b35d75 100644 (file)
 #include "includes.h"
 #include "winbindd.h"
 #include "lib/global_contexts.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
 
 struct winbindd_pam_logoff_state {
-       struct winbindd_request *request;
-       struct winbindd_response *response;
+       struct wbint_PamLogOff r;
 };
 
 static void winbindd_pam_logoff_done(struct tevent_req *subreq);
@@ -47,7 +47,6 @@ struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
-       state->request = request;
 
        /* Ensure null termination */
        /* Ensure null termination */
@@ -99,8 +98,28 @@ struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx,
                break;
        }
 
-       subreq = wb_domain_request_send(state, global_event_context(), domain,
-                                       request);
+       state->r.in.client_name = talloc_strdup(state, request->client_name);
+       if (tevent_req_nomem(state->r.in.client_name, req)) {
+               return tevent_req_post(req, ev);
+       }
+       state->r.in.client_pid = request->pid;
+
+       state->r.in.flags = request->flags;
+       state->r.in.user = talloc_strdup(state, request->data.logoff.user);
+       if (tevent_req_nomem(state->r.in.user, req)) {
+               return tevent_req_post(req, ev);
+       }
+       state->r.in.uid = request->data.logoff.uid;
+       state->r.in.krb5ccname = talloc_strdup(state,
+                                       request->data.logoff.krb5ccname);
+       if (tevent_req_nomem(state->r.in.krb5ccname, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       subreq = dcerpc_wbint_PamLogOff_r_send(state,
+                                              global_event_context(),
+                                              dom_child_handle(domain),
+                                              &state->r);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -118,14 +137,14 @@ static void winbindd_pam_logoff_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct winbindd_pam_logoff_state *state = tevent_req_data(
                req, struct winbindd_pam_logoff_state);
-       int res, err;
+       NTSTATUS status;
 
-       res = wb_domain_request_recv(subreq, state, &state->response, &err);
+       status = dcerpc_wbint_PamLogOff_r_recv(subreq, state);
        TALLOC_FREE(subreq);
-       if (res == -1) {
-               tevent_req_nterror(req, map_nt_error_from_unix(err));
+       if (tevent_req_nterror(req, status)) {
                return;
        }
+
        tevent_req_done(req);
 }
 
@@ -134,20 +153,19 @@ NTSTATUS winbindd_pam_logoff_recv(struct tevent_req *req,
 {
        struct winbindd_pam_logoff_state *state = tevent_req_data(
                req, struct winbindd_pam_logoff_state);
-       NTSTATUS status;
+       NTSTATUS status = NT_STATUS_OK;
 
        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);
+       set_auth_errors(response, state->r.out.result);
 
-       status = NT_STATUS(response->data.auth.nt_status);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       if (NT_STATUS_IS_OK(state->r.out.result)) {
+               winbindd_delete_memory_creds(state->r.in.user);
        }
-       winbindd_delete_memory_creds(state->request->data.logoff.user);
-       return status;
+
+       return NT_STATUS(response->data.auth.nt_status);
 }
index 2641101ee0ceae18dd3792303cf75cafabb4f833..6dad82fc0a82922f2136bc243159a9b71e690509 100644 (file)
@@ -445,8 +445,8 @@ NTSTATUS _wbint_PamAuthCrap(struct pipes_struct *p,
                            struct wbint_PamAuthCrap *r);
 enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
                                                 struct winbindd_cli_state *state);
-enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
-                                             struct winbindd_cli_state *state) ;
+NTSTATUS _wbint_PamLogOff(struct pipes_struct *p,
+                         struct wbint_PamLogOff *r);
 enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
 NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state,
                                      TALLOC_CTX *mem_ctx,