mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
s3:winbind: Convert winbindd_dual_pam_chauthtok() 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
ba40aad05b
commit
cc0ef447cd
librpc/idl
source3/winbindd
@ -347,7 +347,7 @@ import "misc.idl", "lsa.idl", "security.idl";
|
||||
DOMAIN_SERVER_DISABLED = 2
|
||||
} samr_DomainServerState;
|
||||
|
||||
typedef struct {
|
||||
typedef [public] struct {
|
||||
uint16 min_password_length;
|
||||
uint16 password_history_length;
|
||||
samr_PasswordProperties password_properties;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "idl_types.h"
|
||||
import "lsa.idl", "netlogon.idl", "misc.idl", "security.idl", "idmap.idl";
|
||||
import "lsa.idl", "netlogon.idl", "samr.idl", "misc.idl", "security.idl", "idmap.idl";
|
||||
|
||||
[
|
||||
uuid("bf09192c-ed60-4928-9dff-d0d7bcb03ed8"),
|
||||
@ -237,6 +237,17 @@ interface winbind
|
||||
[in,flag(NDR_SECRET)] DATA_BLOB old_lm_hash_enc
|
||||
);
|
||||
|
||||
NTSTATUS wbint_PamAuthChangePassword(
|
||||
[in,string,charset(UTF8)] char *client_name,
|
||||
[in] hyper client_pid,
|
||||
[in] uint32 flags,
|
||||
[in,string,charset(UTF8)] char *user,
|
||||
[in,string,charset(UTF8),flag(NDR_SECRET)] char *old_password,
|
||||
[in,string,charset(UTF8),flag(NDR_SECRET)] char *new_password,
|
||||
[out,ref] samr_DomInfo1 **dominfo,
|
||||
[out,ref] samPwdChangeReason *reject_reason
|
||||
);
|
||||
|
||||
/* 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 = "PAM_CHAUTHTOK",
|
||||
.struct_cmd = WINBINDD_PAM_CHAUTHTOK,
|
||||
.struct_fn = winbindd_dual_pam_chauthtok,
|
||||
},{
|
||||
.name = "NDRCMD",
|
||||
.struct_cmd = WINBINDD_DUAL_NDRCMD,
|
||||
|
@ -548,21 +548,6 @@ struct winbindd_domain *find_auth_domain(uint8_t flags,
|
||||
return find_our_domain();
|
||||
}
|
||||
|
||||
static void fill_in_password_policy(struct winbindd_response *r,
|
||||
const struct samr_DomInfo1 *p)
|
||||
{
|
||||
r->data.auth.policy.min_length_password =
|
||||
p->min_password_length;
|
||||
r->data.auth.policy.password_history =
|
||||
p->password_history_length;
|
||||
r->data.auth.policy.password_properties =
|
||||
p->password_properties;
|
||||
r->data.auth.policy.expire =
|
||||
nt_time_to_unix_abs((const NTTIME *)&(p->max_password_age));
|
||||
r->data.auth.policy.min_passwordage =
|
||||
nt_time_to_unix_abs((const NTTIME *)&(p->min_password_age));
|
||||
}
|
||||
|
||||
static NTSTATUS get_password_policy(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct samr_DomInfo1 **_policy)
|
||||
@ -2918,11 +2903,10 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
|
||||
struct winbindd_cli_state *state)
|
||||
NTSTATUS _wbint_PamAuthChangePassword(struct pipes_struct *p,
|
||||
struct wbint_PamAuthChangePassword *r)
|
||||
{
|
||||
char *oldpass;
|
||||
char *newpass = NULL;
|
||||
struct winbindd_domain *contact_domain = wb_child_domain();
|
||||
struct policy_handle dom_pol;
|
||||
struct rpc_pipe_client *cli = NULL;
|
||||
bool got_info = false;
|
||||
@ -2932,13 +2916,25 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
fstring namespace, domain, user;
|
||||
struct dcerpc_binding_handle *b = NULL;
|
||||
bool ok;
|
||||
pid_t client_pid;
|
||||
|
||||
ZERO_STRUCT(dom_pol);
|
||||
|
||||
DEBUG(3, ("[%5lu]: dual pam chauthtok %s\n", (unsigned long)state->pid,
|
||||
state->request->data.auth.user));
|
||||
if (contact_domain == NULL) {
|
||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
ok = parse_domain_user(state->request->data.chauthtok.user,
|
||||
/* 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;
|
||||
}
|
||||
|
||||
DBG_NOTICE("[%"PRIu32"]: dual pam chauthtok %s\n",
|
||||
client_pid, r->in.user);
|
||||
|
||||
ok = parse_domain_user(r->in.user,
|
||||
namespace,
|
||||
domain,
|
||||
user);
|
||||
@ -2954,17 +2950,15 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Change password */
|
||||
|
||||
oldpass = state->request->data.chauthtok.oldpass;
|
||||
newpass = state->request->data.chauthtok.newpass;
|
||||
|
||||
/* Initialize reject reason */
|
||||
state->response->data.auth.reject_reason = Undefined;
|
||||
*r->out.reject_reason = Undefined;
|
||||
|
||||
/* Get sam handle */
|
||||
|
||||
result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli,
|
||||
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));
|
||||
@ -2973,10 +2967,11 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
|
||||
b = cli->binding_handle;
|
||||
|
||||
result = rpccli_samr_chgpasswd_user3(cli, state->mem_ctx,
|
||||
result = rpccli_samr_chgpasswd_user3(cli,
|
||||
p->mem_ctx,
|
||||
user,
|
||||
newpass,
|
||||
oldpass,
|
||||
r->in.new_password,
|
||||
r->in.old_password,
|
||||
&info,
|
||||
&reject);
|
||||
|
||||
@ -2984,10 +2979,8 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
|
||||
if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) {
|
||||
|
||||
fill_in_password_policy(state->response, info);
|
||||
|
||||
state->response->data.auth.reject_reason =
|
||||
reject->extendedFailureReason;
|
||||
*r->out.dominfo = talloc_steal(p->mem_ctx, info);
|
||||
*r->out.reject_reason = reject->extendedFailureReason;
|
||||
|
||||
got_info = true;
|
||||
}
|
||||
@ -3006,7 +2999,11 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n",
|
||||
nt_errstr(result)));
|
||||
|
||||
result = rpccli_samr_chgpasswd_user2(cli, state->mem_ctx, user, newpass, oldpass);
|
||||
result = rpccli_samr_chgpasswd_user2(cli,
|
||||
p->mem_ctx,
|
||||
user,
|
||||
r->in.new_password,
|
||||
r->in.old_password);
|
||||
|
||||
/* Windows 2000 returns NT_STATUS_ACCOUNT_RESTRICTION.
|
||||
Map to the same status code as Windows 2003. */
|
||||
@ -3019,10 +3016,10 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
|
||||
done:
|
||||
|
||||
if (NT_STATUS_IS_OK(result)
|
||||
&& (state->request->flags & WBFLAG_PAM_CACHED_LOGIN)
|
||||
&& (r->in.flags & WBFLAG_PAM_CACHED_LOGIN)
|
||||
&& lp_winbind_offline_logon()) {
|
||||
result = winbindd_update_creds_by_name(contact_domain, user,
|
||||
newpass);
|
||||
r->in.new_password);
|
||||
/* Again, this happens when we login from gdm or xdm
|
||||
* and the password expires, *BUT* cached crendentials
|
||||
* doesn't exist. winbindd_update_creds_by_name()
|
||||
@ -3046,7 +3043,7 @@ done:
|
||||
NTSTATUS policy_ret;
|
||||
|
||||
policy_ret = get_password_policy(contact_domain,
|
||||
state->mem_ctx,
|
||||
p->mem_ctx,
|
||||
&info);
|
||||
|
||||
/* failure of this is non critical, it will just provide no
|
||||
@ -3058,8 +3055,7 @@ done:
|
||||
goto process_result;
|
||||
}
|
||||
|
||||
fill_in_password_policy(state->response, info);
|
||||
TALLOC_FREE(info);
|
||||
*r->out.dominfo = talloc_steal(p->mem_ctx, info);
|
||||
}
|
||||
|
||||
process_result:
|
||||
@ -3069,22 +3065,23 @@ process_result:
|
||||
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;
|
||||
}
|
||||
|
||||
NTSTATUS _wbint_PamLogOff(struct pipes_struct *p, struct wbint_PamLogOff *r)
|
||||
|
@ -21,10 +21,25 @@
|
||||
#include "winbindd.h"
|
||||
#include "lib/util/string_wrappers.h"
|
||||
#include "lib/global_contexts.h"
|
||||
#include "librpc/gen_ndr/ndr_winbind_c.h"
|
||||
|
||||
static void fill_in_password_policy(struct winbindd_response *r,
|
||||
const struct samr_DomInfo1 *p)
|
||||
{
|
||||
r->data.auth.policy.min_length_password =
|
||||
p->min_password_length;
|
||||
r->data.auth.policy.password_history =
|
||||
p->password_history_length;
|
||||
r->data.auth.policy.password_properties =
|
||||
p->password_properties;
|
||||
r->data.auth.policy.expire =
|
||||
nt_time_to_unix_abs((const NTTIME *)&(p->max_password_age));
|
||||
r->data.auth.policy.min_passwordage =
|
||||
nt_time_to_unix_abs((const NTTIME *)&(p->min_password_age));
|
||||
}
|
||||
|
||||
struct winbindd_pam_chauthtok_state {
|
||||
struct winbindd_request *request;
|
||||
struct winbindd_response *response;
|
||||
struct wbint_PamAuthChangePassword r;
|
||||
};
|
||||
|
||||
static void winbindd_pam_chauthtok_done(struct tevent_req *subreq);
|
||||
@ -48,7 +63,6 @@ struct tevent_req *winbindd_pam_chauthtok_send(
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->request = request;
|
||||
|
||||
/* Ensure null termination */
|
||||
request->data.chauthtok.user[
|
||||
@ -85,8 +99,35 @@ struct tevent_req *winbindd_pam_chauthtok_send(
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = wb_domain_request_send(state, global_event_context(),
|
||||
contact_domain, request);
|
||||
state->r.in.client_pid = request->pid;
|
||||
state->r.in.flags = request->flags;
|
||||
|
||||
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.user = talloc_strdup(state, request->data.chauthtok.user);
|
||||
if (tevent_req_nomem(state->r.in.user, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->r.in.old_password = talloc_strdup(state,
|
||||
request->data.chauthtok.oldpass);
|
||||
if (tevent_req_nomem(state->r.in.old_password, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->r.in.new_password = talloc_strdup(state,
|
||||
request->data.chauthtok.newpass);
|
||||
if (tevent_req_nomem(state->r.in.new_password, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = dcerpc_wbint_PamAuthChangePassword_r_send(state,
|
||||
global_event_context(),
|
||||
dom_child_handle(contact_domain),
|
||||
&state->r);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
@ -100,14 +141,14 @@ static void winbindd_pam_chauthtok_done(struct tevent_req *subreq)
|
||||
subreq, struct tevent_req);
|
||||
struct winbindd_pam_chauthtok_state *state = tevent_req_data(
|
||||
req, struct winbindd_pam_chauthtok_state);
|
||||
int res, err;
|
||||
NTSTATUS status;
|
||||
|
||||
res = wb_domain_request_recv(subreq, state, &state->response, &err);
|
||||
status = dcerpc_wbint_PamAuthChangePassword_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);
|
||||
}
|
||||
|
||||
@ -116,27 +157,26 @@ NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req,
|
||||
{
|
||||
struct winbindd_pam_chauthtok_state *state = tevent_req_data(
|
||||
req, struct winbindd_pam_chauthtok_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);
|
||||
|
||||
status = NT_STATUS(response->data.auth.nt_status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
set_auth_errors(response, state->r.out.result);
|
||||
if (*state->r.out.dominfo != NULL) {
|
||||
fill_in_password_policy(response, *state->r.out.dominfo);
|
||||
}
|
||||
response->data.auth.reject_reason = *state->r.out.reject_reason;
|
||||
|
||||
if (state->request->flags & WBFLAG_PAM_CACHED_LOGIN) {
|
||||
if (state->r.in.flags & WBFLAG_PAM_CACHED_LOGIN) {
|
||||
|
||||
/* Update the single sign-on memory creds. */
|
||||
status = winbindd_replace_memory_creds(
|
||||
state->request->data.chauthtok.user,
|
||||
state->request->data.chauthtok.newpass);
|
||||
state->r.in.user, state->r.in.new_password);
|
||||
|
||||
DEBUG(10, ("winbindd_replace_memory_creds returned %s\n",
|
||||
nt_errstr(status)));
|
||||
@ -152,5 +192,6 @@ NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req,
|
||||
status = NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
|
||||
return NT_STATUS(response->data.auth.nt_status);
|
||||
}
|
||||
|
@ -443,8 +443,8 @@ NTSTATUS _wbint_PamAuth(struct pipes_struct *p,
|
||||
struct wbint_PamAuth *r);
|
||||
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);
|
||||
NTSTATUS _wbint_PamAuthChangePassword(struct pipes_struct *p,
|
||||
struct wbint_PamAuthChangePassword *r);
|
||||
NTSTATUS _wbint_PamLogOff(struct pipes_struct *p,
|
||||
struct wbint_PamLogOff *r);
|
||||
NTSTATUS _wbint_PamAuthCrapChangePassword(struct pipes_struct *p,
|
||||
|
Loading…
Reference in New Issue
Block a user