mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3:winbind: Convert PamLogOff from struct based to ndr based
Signed-off-by: Samuel Cabrero <scabrero@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
c27135adc7
commit
ce0be638b4
@ -217,6 +217,15 @@ interface winbind
|
|||||||
[out,ref] wbint_PamAuthCrapValidation *validation
|
[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 */
|
/* Public methods available via IRPC */
|
||||||
|
|
||||||
typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
|
typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
|
||||||
|
@ -30,10 +30,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
|
|||||||
.name = "INIT_CONNECTION",
|
.name = "INIT_CONNECTION",
|
||||||
.struct_cmd = WINBINDD_INIT_CONNECTION,
|
.struct_cmd = WINBINDD_INIT_CONNECTION,
|
||||||
.struct_fn = winbindd_dual_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",
|
.name = "CHNG_PSWD_AUTH_CRAP",
|
||||||
.struct_cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
|
.struct_cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
|
||||||
|
@ -3081,51 +3081,68 @@ process_result:
|
|||||||
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
|
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
|
NTSTATUS _wbint_PamLogOff(struct pipes_struct *p, struct wbint_PamLogOff *r)
|
||||||
struct winbindd_cli_state *state)
|
|
||||||
{
|
{
|
||||||
|
struct winbindd_domain *domain = wb_child_domain();
|
||||||
NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
|
NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
|
||||||
|
pid_t client_pid;
|
||||||
|
uid_t user_uid;
|
||||||
|
|
||||||
DEBUG(3, ("[%5lu]: pam dual logoff %s\n", (unsigned long)state->pid,
|
if (domain == NULL) {
|
||||||
state->request->data.logoff.user));
|
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(state->request->flags & WBFLAG_PAM_KRB5)) {
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_NOTICE("[%"PRIu32"]: pam dual logoff %s\n", client_pid, r->in.user);
|
||||||
|
|
||||||
|
if (!(r->in.flags & WBFLAG_PAM_KRB5)) {
|
||||||
result = NT_STATUS_OK;
|
result = NT_STATUS_OK;
|
||||||
goto process_result;
|
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;
|
result = NT_STATUS_OK;
|
||||||
goto process_result;
|
goto process_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_KRB5
|
#ifdef HAVE_KRB5
|
||||||
|
|
||||||
if (state->request->data.logoff.uid == (uid_t)-1) {
|
if (user_uid == (uid_t)-1) {
|
||||||
DEBUG(0,("winbindd_pam_logoff: invalid uid\n"));
|
DBG_DEBUG("Invalid uid for user '%s'\n", r->in.user);
|
||||||
goto process_result;
|
goto process_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* what we need here is to find the corresponding krb5 ccache name *we*
|
/* what we need here is to find the corresponding krb5 ccache name *we*
|
||||||
* created for a given username and destroy it */
|
* 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;
|
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;
|
goto process_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ccache_entry_identical(state->request->data.logoff.user,
|
if (!ccache_entry_identical(r->in.user, user_uid, r->in.krb5ccname)) {
|
||||||
state->request->data.logoff.uid,
|
DBG_DEBUG("Cached entry differs for user '%s'\n", r->in.user);
|
||||||
state->request->data.logoff.krb5ccname)) {
|
|
||||||
DEBUG(0,("winbindd_pam_logoff: cached entry differs.\n"));
|
|
||||||
goto process_result;
|
goto process_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = remove_ccache(state->request->data.logoff.user);
|
result = remove_ccache(r->in.user);
|
||||||
if (!NT_STATUS_IS_OK(result)) {
|
if (!NT_STATUS_IS_OK(result)) {
|
||||||
DEBUG(0,("winbindd_pam_logoff: failed to remove ccache: %s\n",
|
DBG_DEBUG("Failed to remove ccache for user '%s': %s\n",
|
||||||
nt_errstr(result)));
|
r->in.user, nt_errstr(result));
|
||||||
goto process_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.
|
* 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
|
#else
|
||||||
result = NT_STATUS_NOT_SUPPORTED;
|
result = NT_STATUS_NOT_SUPPORTED;
|
||||||
@ -3142,10 +3159,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
|
|||||||
|
|
||||||
process_result:
|
process_result:
|
||||||
|
|
||||||
|
return result;
|
||||||
set_auth_errors(state->response, result);
|
|
||||||
|
|
||||||
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change user password with auth crap*/
|
/* Change user password with auth crap*/
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "winbindd.h"
|
#include "winbindd.h"
|
||||||
#include "lib/global_contexts.h"
|
#include "lib/global_contexts.h"
|
||||||
|
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||||
|
|
||||||
struct winbindd_pam_logoff_state {
|
struct winbindd_pam_logoff_state {
|
||||||
struct winbindd_request *request;
|
struct wbint_PamLogOff r;
|
||||||
struct winbindd_response *response;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void winbindd_pam_logoff_done(struct tevent_req *subreq);
|
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) {
|
if (req == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
state->request = request;
|
|
||||||
|
|
||||||
/* Ensure null termination */
|
/* Ensure null termination */
|
||||||
/* Ensure null termination */
|
/* Ensure null termination */
|
||||||
@ -99,8 +98,28 @@ struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
subreq = wb_domain_request_send(state, global_event_context(), domain,
|
state->r.in.client_name = talloc_strdup(state, request->client_name);
|
||||||
request);
|
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)) {
|
if (tevent_req_nomem(subreq, req)) {
|
||||||
return tevent_req_post(req, ev);
|
return tevent_req_post(req, ev);
|
||||||
}
|
}
|
||||||
@ -118,14 +137,14 @@ static void winbindd_pam_logoff_done(struct tevent_req *subreq)
|
|||||||
subreq, struct tevent_req);
|
subreq, struct tevent_req);
|
||||||
struct winbindd_pam_logoff_state *state = tevent_req_data(
|
struct winbindd_pam_logoff_state *state = tevent_req_data(
|
||||||
req, struct winbindd_pam_logoff_state);
|
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);
|
TALLOC_FREE(subreq);
|
||||||
if (res == -1) {
|
if (tevent_req_nterror(req, status)) {
|
||||||
tevent_req_nterror(req, map_nt_error_from_unix(err));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tevent_req_done(req);
|
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(
|
struct winbindd_pam_logoff_state *state = tevent_req_data(
|
||||||
req, struct winbindd_pam_logoff_state);
|
req, struct winbindd_pam_logoff_state);
|
||||||
NTSTATUS status;
|
NTSTATUS status = NT_STATUS_OK;
|
||||||
|
|
||||||
if (tevent_req_is_nterror(req, &status)) {
|
if (tevent_req_is_nterror(req, &status)) {
|
||||||
set_auth_errors(response, status);
|
set_auth_errors(response, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
*response = *state->response;
|
|
||||||
response->result = WINBINDD_PENDING;
|
|
||||||
state->response = talloc_move(response, &state->response);
|
|
||||||
|
|
||||||
status = NT_STATUS(response->data.auth.nt_status);
|
response->result = WINBINDD_PENDING;
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
set_auth_errors(response, state->r.out.result);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -445,8 +445,8 @@ NTSTATUS _wbint_PamAuthCrap(struct pipes_struct *p,
|
|||||||
struct wbint_PamAuthCrap *r);
|
struct wbint_PamAuthCrap *r);
|
||||||
enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
|
enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
|
||||||
struct winbindd_cli_state *state);
|
struct winbindd_cli_state *state);
|
||||||
enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain,
|
NTSTATUS _wbint_PamLogOff(struct pipes_struct *p,
|
||||||
struct winbindd_cli_state *state) ;
|
struct wbint_PamLogOff *r);
|
||||||
enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state);
|
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,
|
NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
|
Loading…
Reference in New Issue
Block a user