mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
s3:winbind: Convert winbindd_dual_pam_chng_pswd_auth_crap() 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
5f213285b6
commit
0f3b1d5c1d
@ -226,6 +226,17 @@ interface winbind
|
||||
[in] hyper uid
|
||||
);
|
||||
|
||||
NTSTATUS wbint_PamAuthCrapChangePassword(
|
||||
[in,string,charset(UTF8)] char *client_name,
|
||||
[in] hyper client_pid,
|
||||
[in,string,charset(UTF8)] char *user,
|
||||
[in,string,charset(UTF8)] char *domain,
|
||||
[in,flag(NDR_SECRET)] DATA_BLOB new_nt_pswd,
|
||||
[in,flag(NDR_SECRET)] DATA_BLOB old_nt_hash_enc,
|
||||
[in,flag(NDR_SECRET)] DATA_BLOB new_lm_pswd,
|
||||
[in,flag(NDR_SECRET)] DATA_BLOB old_lm_hash_enc
|
||||
);
|
||||
|
||||
/* Public methods available via IRPC */
|
||||
|
||||
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",
|
||||
.struct_cmd = WINBINDD_INIT_CONNECTION,
|
||||
.struct_fn = winbindd_dual_init_connection,
|
||||
},{
|
||||
.name = "CHNG_PSWD_AUTH_CRAP",
|
||||
.struct_cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
|
||||
.struct_fn = winbindd_dual_pam_chng_pswd_auth_crap,
|
||||
},{
|
||||
.name = "PAM_CHAUTHTOK",
|
||||
.struct_cmd = WINBINDD_PAM_CHAUTHTOK,
|
||||
|
@ -3164,34 +3164,36 @@ process_result:
|
||||
|
||||
/* Change user password with auth crap*/
|
||||
|
||||
enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state)
|
||||
NTSTATUS _wbint_PamAuthCrapChangePassword(struct pipes_struct *p,
|
||||
struct wbint_PamAuthCrapChangePassword *r)
|
||||
{
|
||||
NTSTATUS result;
|
||||
DATA_BLOB new_nt_password;
|
||||
DATA_BLOB old_nt_hash_enc;
|
||||
DATA_BLOB new_lm_password;
|
||||
DATA_BLOB old_lm_hash_enc;
|
||||
fstring namespace, domain, user;
|
||||
struct policy_handle dom_pol;
|
||||
struct winbindd_domain *contact_domain = domainSt;
|
||||
struct winbindd_domain *contact_domain = wb_child_domain();
|
||||
struct rpc_pipe_client *cli = NULL;
|
||||
struct dcerpc_binding_handle *b = NULL;
|
||||
pid_t client_pid;
|
||||
|
||||
ZERO_STRUCT(dom_pol);
|
||||
|
||||
/* Ensure null termination */
|
||||
state->request->data.chng_pswd_auth_crap.user[
|
||||
sizeof(state->request->data.chng_pswd_auth_crap.user)-1]=0;
|
||||
state->request->data.chng_pswd_auth_crap.domain[
|
||||
sizeof(state->request->data.chng_pswd_auth_crap.domain)-1]=0;
|
||||
if (contact_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;
|
||||
}
|
||||
|
||||
domain[0] = '\0';
|
||||
namespace[0] = '\0';
|
||||
user[0] = '\0';
|
||||
|
||||
DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
|
||||
(unsigned long)state->pid,
|
||||
state->request->data.chng_pswd_auth_crap.domain,
|
||||
state->request->data.chng_pswd_auth_crap.user));
|
||||
DBG_NOTICE("[%"PRIu32"]: pam change pswd auth crap domain: %s "
|
||||
"user: %s\n", client_pid, r->in.domain, r->in.user);
|
||||
|
||||
if (lp_winbind_offline_logon()) {
|
||||
DEBUG(0,("Refusing password change as winbind offline logons are enabled. "));
|
||||
@ -3200,12 +3202,12 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*state->request->data.chng_pswd_auth_crap.domain) {
|
||||
fstrcpy(domain,state->request->data.chng_pswd_auth_crap.domain);
|
||||
if (r->in.domain != NULL && strlen(r->in.domain) > 0) {
|
||||
fstrcpy(domain, r->in.domain);
|
||||
} else {
|
||||
bool ok;
|
||||
|
||||
ok = parse_domain_user(state->request->data.chng_pswd_auth_crap.user,
|
||||
ok = parse_domain_user(r->in.user,
|
||||
namespace,
|
||||
domain,
|
||||
user);
|
||||
@ -3214,10 +3216,9 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(!*domain) {
|
||||
DEBUG(3,("no domain specified with username (%s) - "
|
||||
"failing auth\n",
|
||||
state->request->data.chng_pswd_auth_crap.user));
|
||||
if (strlen(domain) == 0) {
|
||||
DBG_NOTICE("no domain specified with username (%s) - "
|
||||
"failing auth\n", r->in.user);
|
||||
result = NT_STATUS_NO_SUCH_USER;
|
||||
goto done;
|
||||
}
|
||||
@ -3230,44 +3231,23 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
|
||||
if (!is_allowed_domain(domain)) {
|
||||
DBG_NOTICE("Authentication failed for user [%s] "
|
||||
"from firewalled domain [%s]\n",
|
||||
state->request->data.chng_pswd_auth_crap.user,
|
||||
r->in.user,
|
||||
domain);
|
||||
result = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(!*user) {
|
||||
fstrcpy(user, state->request->data.chng_pswd_auth_crap.user);
|
||||
}
|
||||
|
||||
DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n",
|
||||
(unsigned long)state->pid, domain, user));
|
||||
|
||||
/* Change password */
|
||||
new_nt_password = data_blob_const(
|
||||
state->request->data.chng_pswd_auth_crap.new_nt_pswd,
|
||||
state->request->data.chng_pswd_auth_crap.new_nt_pswd_len);
|
||||
|
||||
old_nt_hash_enc = data_blob_const(
|
||||
state->request->data.chng_pswd_auth_crap.old_nt_hash_enc,
|
||||
state->request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
|
||||
|
||||
if(state->request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0) {
|
||||
new_lm_password = data_blob_const(
|
||||
state->request->data.chng_pswd_auth_crap.new_lm_pswd,
|
||||
state->request->data.chng_pswd_auth_crap.new_lm_pswd_len);
|
||||
|
||||
old_lm_hash_enc = data_blob_const(
|
||||
state->request->data.chng_pswd_auth_crap.old_lm_hash_enc,
|
||||
state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
|
||||
} else {
|
||||
new_lm_password = data_blob_null;
|
||||
old_lm_hash_enc = data_blob_null;
|
||||
fstrcpy(user, r->in.user);
|
||||
}
|
||||
|
||||
/* Get sam handle */
|
||||
|
||||
result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli, &dom_pol);
|
||||
result = cm_connect_sam(contact_domain,
|
||||
p->mem_ctx,
|
||||
true,
|
||||
&cli,
|
||||
&dom_pol);
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
|
||||
goto done;
|
||||
@ -3275,9 +3255,13 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
|
||||
|
||||
b = cli->binding_handle;
|
||||
|
||||
result = rpccli_samr_chng_pswd_auth_crap(
|
||||
cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc,
|
||||
new_lm_password, old_lm_hash_enc);
|
||||
result = rpccli_samr_chng_pswd_auth_crap(cli,
|
||||
p->mem_ctx,
|
||||
user,
|
||||
r->in.new_nt_pswd,
|
||||
r->in.old_nt_hash_enc,
|
||||
r->in.new_lm_pswd,
|
||||
r->in.old_lm_hash_enc);
|
||||
|
||||
done:
|
||||
|
||||
@ -3286,21 +3270,22 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
|
||||
if (b) {
|
||||
if (is_valid_policy_hnd(&dom_pol)) {
|
||||
NTSTATUS _result;
|
||||
dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result);
|
||||
dcerpc_samr_Close(b,
|
||||
p->mem_ctx,
|
||||
&dom_pol,
|
||||
&_result);
|
||||
}
|
||||
TALLOC_FREE(cli);
|
||||
}
|
||||
}
|
||||
|
||||
set_auth_errors(state->response, result);
|
||||
|
||||
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
|
||||
("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
|
||||
domain, user,
|
||||
state->response->data.auth.nt_status_string,
|
||||
state->response->data.auth.pam_error));
|
||||
nt_errstr(result),
|
||||
nt_status_to_pam(result)));
|
||||
|
||||
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include "includes.h"
|
||||
#include "winbindd.h"
|
||||
#include "lib/global_contexts.h"
|
||||
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||
|
||||
struct winbindd_pam_chng_pswd_auth_crap_state {
|
||||
struct winbindd_request *request;
|
||||
struct winbindd_response *response;
|
||||
struct wbint_PamAuthCrapChangePassword r;
|
||||
};
|
||||
|
||||
static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq);
|
||||
@ -44,7 +44,6 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->request = request;
|
||||
|
||||
/* Ensure null termination */
|
||||
request->data.chng_pswd_auth_crap.user[
|
||||
@ -58,8 +57,8 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
|
||||
request->data.chng_pswd_auth_crap.user));
|
||||
|
||||
domain_name = NULL;
|
||||
if (*state->request->data.chng_pswd_auth_crap.domain != '\0') {
|
||||
domain_name = state->request->data.chng_pswd_auth_crap.domain;
|
||||
if (*request->data.chng_pswd_auth_crap.domain != '\0') {
|
||||
domain_name = request->data.chng_pswd_auth_crap.domain;
|
||||
} else if (lp_winbind_use_default_domain()) {
|
||||
domain_name = lp_workgroup();
|
||||
}
|
||||
@ -74,8 +73,59 @@ struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send(
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = wb_domain_request_send(state, global_event_context(),
|
||||
domain, request);
|
||||
state->r.in.client_pid = request->pid;
|
||||
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.domain = talloc_strdup(state, domain_name);
|
||||
if (tevent_req_nomem(state->r.in.domain, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
state->r.in.user = talloc_strdup(state,
|
||||
request->data.chng_pswd_auth_crap.user);
|
||||
if (tevent_req_nomem(state->r.in.user, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->r.in.new_nt_pswd = data_blob_talloc(state,
|
||||
request->data.chng_pswd_auth_crap.new_nt_pswd,
|
||||
request->data.chng_pswd_auth_crap.new_nt_pswd_len);
|
||||
if (tevent_req_nomem(state->r.in.new_nt_pswd.data, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->r.in.old_nt_hash_enc = data_blob_talloc(state,
|
||||
request->data.chng_pswd_auth_crap.old_nt_hash_enc,
|
||||
request->data.chng_pswd_auth_crap.old_nt_hash_enc_len);
|
||||
if (tevent_req_nomem(state->r.in.old_nt_hash_enc.data, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
if (request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0) {
|
||||
state->r.in.new_lm_pswd = data_blob_talloc(state,
|
||||
request->data.chng_pswd_auth_crap.new_lm_pswd,
|
||||
request->data.chng_pswd_auth_crap.new_lm_pswd_len);
|
||||
if (tevent_req_nomem(state->r.in.new_lm_pswd.data, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->r.in.old_lm_hash_enc = data_blob_talloc(state,
|
||||
request->data.chng_pswd_auth_crap.old_lm_hash_enc,
|
||||
request->data.chng_pswd_auth_crap.old_lm_hash_enc_len);
|
||||
if (tevent_req_nomem(state->r.in.old_lm_hash_enc.data, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
} else {
|
||||
state->r.in.new_lm_pswd = data_blob_null;
|
||||
state->r.in.old_lm_hash_enc = data_blob_null;
|
||||
}
|
||||
|
||||
subreq = dcerpc_wbint_PamAuthCrapChangePassword_r_send(state,
|
||||
global_event_context(),
|
||||
dom_child_handle(domain),
|
||||
&state->r);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
@ -90,14 +140,14 @@ static void winbindd_pam_chng_pswd_auth_crap_done(struct tevent_req *subreq)
|
||||
subreq, struct tevent_req);
|
||||
struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
|
||||
req, struct winbindd_pam_chng_pswd_auth_crap_state);
|
||||
int res, err;
|
||||
NTSTATUS status;
|
||||
|
||||
res = wb_domain_request_recv(subreq, state, &state->response, &err);
|
||||
status = dcerpc_wbint_PamAuthCrapChangePassword_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);
|
||||
}
|
||||
|
||||
@ -107,15 +157,15 @@ NTSTATUS winbindd_pam_chng_pswd_auth_crap_recv(
|
||||
{
|
||||
struct winbindd_pam_chng_pswd_auth_crap_state *state = tevent_req_data(
|
||||
req, struct winbindd_pam_chng_pswd_auth_crap_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);
|
||||
|
||||
return NT_STATUS(response->data.auth.nt_status);
|
||||
}
|
||||
|
@ -447,7 +447,8 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
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 _wbint_PamAuthCrapChangePassword(struct pipes_struct *p,
|
||||
struct wbint_PamAuthCrapChangePassword *r);
|
||||
NTSTATUS winbindd_pam_auth_pac_verify(struct winbindd_cli_state *state,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
bool *p_is_trusted,
|
||||
|
Loading…
x
Reference in New Issue
Block a user