DOMAIN_SERVER_DISABLED = 2
} samr_DomainServerState;
- typedef struct {
+ typedef [public] struct {
uint16 min_password_length;
uint16 password_history_length;
samr_PasswordProperties password_properties;
#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"),
[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;
.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,
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)
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;
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;
+ }
+
+ /* 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(state->request->data.chauthtok.user,
+ ok = parse_domain_user(r->in.user,
namespace,
domain,
user);
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));
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);
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;
}
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. */
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()
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
goto process_result;
}
- fill_in_password_policy(state->response, info);
- TALLOC_FREE(info);
+ *r->out.dominfo = talloc_steal(p->mem_ctx, info);
}
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)
#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);
if (req == NULL) {
return NULL;
}
- state->request = request;
/* Ensure null termination */
request->data.chauthtok.user[
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);
}
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);
}
{
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)));
status = NT_STATUS_OK;
}
}
- return status;
+
+ return NT_STATUS(response->data.auth.nt_status);
}
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,