[out,ref] wbint_Validation *validation
);
+ typedef [public] struct {
+ uint16 level;
+ [switch_is(level)] netr_Validation *validation;
+ } wbint_PamAuthCrapValidation;
+
+ NTSTATUS wbint_PamAuthCrap(
+ [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 *domain,
+ [in, string,charset(UTF8)] char *workstation,
+ [in] DATA_BLOB lm_resp,
+ [in] DATA_BLOB nt_resp,
+ [in] DATA_BLOB chal,
+ [in] uint32 logon_parameters,
+ [in] wbint_SidArray *require_membership_of_sid,
+ [out,ref] uint8 *authoritative,
+ [out,ref] wbint_PamAuthCrapValidation *validation
+ );
+
/* 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 = "AUTH_CRAP",
- .struct_cmd = WINBINDD_PAM_AUTH_CRAP,
- .struct_fn = winbindd_dual_pam_auth_crap,
},{
.name = "PAM_LOGOFF",
.struct_cmd = WINBINDD_PAM_LOGOFF,
* @brief build a tsocket_address for the remote address of the supplied socket
*
*/
-static struct tsocket_address *get_remote_address(TALLOC_CTX *mem_ctx, int sock)
+_UNUSED_ static struct tsocket_address *get_remote_address(TALLOC_CTX *mem_ctx, int sock)
{
struct sockaddr_storage st = {0};
struct sockaddr *sar = (struct sockaddr *)&st;
* @brief build a tsocket_address for the local address of the supplied socket
*
*/
-static struct tsocket_address *get_local_address(TALLOC_CTX *mem_ctx, int sock)
+_UNUSED_ static struct tsocket_address *get_local_address(TALLOC_CTX *mem_ctx, int sock)
{
struct sockaddr_storage st = {0};
struct sockaddr *sar = (struct sockaddr *)&st;
return NT_STATUS_OK;
}
-enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
+NTSTATUS _wbint_PamAuthCrap(struct pipes_struct *p, struct wbint_PamAuthCrap *r)
{
+ struct winbindd_domain *domain = wb_child_domain();
NTSTATUS result;
- const char *name_user = NULL;
- const char *name_domain = NULL;
- const char *workstation;
uint64_t logon_id = 0;
uint8_t authoritative = 1;
uint32_t flags = 0;
uint16_t validation_level = UINT16_MAX;
union netr_Validation *validation = NULL;
- DATA_BLOB lm_resp = { 0 }, nt_resp = { 0 };
- DATA_BLOB chal = data_blob_null;
const struct timeval start_time = timeval_current();
const struct tsocket_address *remote = NULL;
const struct tsocket_address *local = NULL;
struct netr_SamInfo3 *info3 = NULL;
- struct wbint_SidArray *sid_array = NULL;
+ pid_t client_pid;
- /* This is child-only, so no check for privileged access is needed
- anymore */
+ if (domain == NULL) {
+ return NT_STATUS_REQUEST_NOT_ACCEPTED;
+ }
- /* Ensure null termination */
- state->request->data.auth_crap.user[sizeof(state->request->data.auth_crap.user)-1]=0;
- state->request->data.auth_crap.domain[sizeof(state->request->data.auth_crap.domain)-1]=0;
+ /* 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;
+ }
- name_user = state->request->data.auth_crap.user;
- name_domain = state->request->data.auth_crap.domain;
- workstation = state->request->data.auth_crap.workstation;
logon_id = generate_random_u64();
- remote = get_remote_address(state->mem_ctx, state->sock);
- local = get_local_address(state->mem_ctx, state->sock);
-
- DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
- name_domain, name_user));
+ remote = dcesrv_connection_get_remote_address(p->dce_call->conn);
+ local = dcesrv_connection_get_local_address(p->dce_call->conn);
- lm_resp = data_blob_talloc(state->mem_ctx, state->request->data.auth_crap.lm_resp,
- state->request->data.auth_crap.lm_resp_len);
-
- if (state->request->flags & WBFLAG_BIG_NTLMV2_BLOB) {
- nt_resp = data_blob_talloc(state->mem_ctx,
- state->request->extra_data.data,
- state->request->data.auth_crap.nt_resp_len);
- } else {
- nt_resp = data_blob_talloc(state->mem_ctx,
- state->request->data.auth_crap.nt_resp,
- state->request->data.auth_crap.nt_resp_len);
- }
- chal = data_blob_const(state->request->data.auth_crap.chal, 8);
+ DBG_NOTICE("[%"PRIu32"]: pam auth crap domain: %s user: %s\n",
+ client_pid, r->in.domain, r->in.user);
result = winbind_dual_SamLogon(domain,
- state->mem_ctx,
+ p->mem_ctx,
false, /* interactive */
- state->request->data.auth_crap.logon_parameters,
- name_user,
- name_domain,
- /* Bug #3248 - found by Stefan Burkei. */
- workstation, /* We carefully set this above so use it... */
+ r->in.logon_parameters,
+ r->in.user,
+ r->in.domain,
+ r->in.workstation,
logon_id,
- state->request->client_name,
- state->request->pid,
- chal,
- lm_resp,
- nt_resp,
+ r->in.client_name,
+ client_pid,
+ r->in.chal,
+ r->in.lm_resp,
+ r->in.nt_resp,
remote,
local,
&authoritative,
goto done;
}
- result = map_validation_to_info3(state->mem_ctx,
+ result = map_validation_to_info3(p->mem_ctx,
validation_level,
validation,
&info3);
goto done;
}
- result = extra_data_to_sid_array(
- state->request->data.auth_crap.require_membership_of_sid,
- state->mem_ctx,
- &sid_array);
- if (!NT_STATUS_IS_OK(result)) {
- DBG_ERR("Failed to parse '%s' into a sid array: %s\n",
- state->request->data.auth_crap.require_membership_of_sid,
- nt_errstr(result));
- goto done;
- }
-
/* Check if the user is in the right group */
- result = check_info3_in_group(info3, sid_array);
+ result = check_info3_in_group(info3, r->in.require_membership_of_sid);
if (!NT_STATUS_IS_OK(result)) {
- char *s = NDR_PRINT_STRUCT_STRING(state->mem_ctx,
+ char *s = NDR_PRINT_STRUCT_STRING(p->mem_ctx,
wbint_SidArray,
- sid_array);
+ r->in.require_membership_of_sid);
DBG_NOTICE("User %s is not in the required groups:\n",
- state->request->data.auth_crap.user);
+ r->in.user);
DEBUGADD(DBGLVL_NOTICE, ("%s", s));
DEBUGADD(DBGLVL_NOTICE,
("CRAP authentication is rejected\n"));
- TALLOC_FREE(sid_array);
goto done;
}
- TALLOC_FREE(sid_array);
if (!is_allowed_domain(info3->base.logon_domain.string)) {
DBG_NOTICE("Authentication failed for user [%s] "
goto done;
}
- result = append_auth_data(state->mem_ctx, state->response,
- state->request->flags,
- validation_level,
- validation,
- name_domain, name_user);
+ r->out.validation = talloc_zero(p->mem_ctx,
+ struct wbint_PamAuthCrapValidation);
+ if (r->out.validation == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ r->out.validation->level = validation_level;
+ r->out.validation->validation = talloc_move(r->out.validation,
+ &validation);
done:
- if (state->request->flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
+ if (r->in.flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
result = nt_status_squash(result);
}
- set_auth_errors(state->response, result);
- state->response->data.auth.authoritative = authoritative;
+ *r->out.authoritative = authoritative;
/*
* Log the winbind pam authentication, the logon_id will tie this to
* any of the logons invoked from this request.
*/
log_authentication(
- state->mem_ctx,
+ p->mem_ctx,
domain,
- state->request->client_name,
- state->pid,
- validation_level,
- validation,
+ r->in.client_name,
+ client_pid,
+ r->out.validation->level,
+ r->out.validation->validation,
start_time,
logon_id,
"NTLM_AUTH",
- name_user,
- name_domain,
- workstation,
- lm_resp,
- nt_resp,
+ r->in.user,
+ r->in.domain,
+ r->in.workstation,
+ r->in.lm_resp,
+ r->in.nt_resp,
remote,
local,
result);
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+ return result;
}
enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain,
#include "libcli/security/dom_sid.h"
#include "lib/util/string_wrappers.h"
#include "lib/global_contexts.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
struct winbindd_pam_auth_crap_state {
- struct winbindd_response *response;
uint8_t authoritative;
uint32_t flags;
bool pac_is_trusted;
- uint16_t validation_level;
- union netr_Validation *validation;
+ char *domain;
+ char *user;
+ struct wbint_PamAuthCrapValidation validation;
+ NTSTATUS result;
};
static void winbindd_pam_auth_crap_done(struct tevent_req *subreq);
struct winbindd_pam_auth_crap_state *state;
struct winbindd_domain *domain;
const char *auth_domain = NULL;
+ DATA_BLOB lm_resp = data_blob_null;
+ DATA_BLOB nt_resp = data_blob_null;
+ DATA_BLOB chal = data_blob_null;
+ struct wbint_SidArray *require_membership_of_sid = NULL;
+ NTSTATUS status;
req = tevent_req_create(mem_ctx, &state,
struct winbindd_pam_auth_crap_state);
state->flags = request->flags;
if (state->flags & WBFLAG_PAM_AUTH_PAC) {
- NTSTATUS status;
-
- status = winbindd_pam_auth_pac_verify(cli,
- state,
- &state->pac_is_trusted,
- &state->validation_level,
- &state->validation);
- if (tevent_req_nterror(req, status)) {
+ state->result = winbindd_pam_auth_pac_verify(cli,
+ state,
+ &state->pac_is_trusted,
+ &state->validation.level,
+ &state->validation.validation);
+ if (tevent_req_nterror(req, state->result)) {
return tevent_req_post(req, ev);
}
request->data.auth_crap.workstation[
sizeof(request->data.auth_crap.workstation)-1] = '\0';
- DEBUG(3, ("[%5lu]: pam auth crap domain: [%s] user: %s\n",
- (unsigned long)cli->pid,
- request->data.auth_crap.domain,
- request->data.auth_crap.user));
+ DBG_NOTICE("[%5lu]: pam auth crap domain: [%s] user: [%s] "
+ "workstation: [%s]\n",
+ (unsigned long)cli->pid,
+ request->data.auth_crap.domain,
+ request->data.auth_crap.user,
+ request->data.auth_crap.workstation);
if (!check_request_flags(request->flags)) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
}
}
- subreq = wb_domain_request_send(state, global_event_context(), domain,
- request);
+ state->domain = talloc_strdup(state, request->data.auth_crap.domain);
+ if (tevent_req_nomem(state->domain, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ state->user = talloc_strdup(state, request->data.auth_crap.user);
+ if (tevent_req_nomem(state->user, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ status = extra_data_to_sid_array(
+ request->data.auth_crap.require_membership_of_sid,
+ state,
+ &require_membership_of_sid);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ lm_resp = data_blob_talloc(state,
+ request->data.auth_crap.lm_resp,
+ request->data.auth_crap.lm_resp_len);
+ if (tevent_req_nomem(lm_resp.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ if (request->flags & WBFLAG_BIG_NTLMV2_BLOB) {
+ nt_resp = data_blob_talloc(state,
+ request->extra_data.data,
+ request->data.auth_crap.nt_resp_len);
+ } else {
+ nt_resp = data_blob_talloc(state,
+ request->data.auth_crap.nt_resp,
+ request->data.auth_crap.nt_resp_len);
+ }
+ if (tevent_req_nomem(nt_resp.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ chal = data_blob_talloc(state,
+ request->data.auth_crap.chal,
+ 8);
+ if (tevent_req_nomem(chal.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = dcerpc_wbint_PamAuthCrap_send(state,
+ global_event_context(),
+ dom_child_handle(domain),
+ request->client_name,
+ request->pid,
+ request->flags,
+ request->data.auth_crap.user,
+ request->data.auth_crap.domain,
+ request->data.auth_crap.workstation,
+ lm_resp,
+ nt_resp,
+ chal,
+ request->data.auth_crap.logon_parameters,
+ require_membership_of_sid,
+ &state->authoritative,
+ &state->validation);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
subreq, struct tevent_req);
struct winbindd_pam_auth_crap_state *state = tevent_req_data(
req, struct winbindd_pam_auth_crap_state);
- int res, err;
+ NTSTATUS status;
- res = wb_domain_request_recv(subreq, state, &state->response, &err);
+ status = dcerpc_wbint_PamAuthCrap_recv(subreq, state, &state->result);
TALLOC_FREE(subreq);
- if (res == -1) {
- tevent_req_nterror(req, map_nt_error_from_unix(err));
+ if (tevent_req_nterror(req, status)) {
return;
}
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
- set_auth_errors(response, status);
- response->data.auth.authoritative = state->authoritative;
- return status;
+ goto out;
}
- if (state->flags & WBFLAG_PAM_AUTH_PAC) {
- state->response = talloc_zero(state,
- struct winbindd_response);
- if (state->response == NULL) {
- status = NT_STATUS_NO_MEMORY;
- set_auth_errors(response, status);
- response->data.auth.authoritative = state->authoritative;
- return status;
- }
- state->response->result = WINBINDD_PENDING;
- state->response->length = sizeof(struct winbindd_response);
-
- status = append_auth_data(state->response,
- state->response,
- state->flags,
- state->validation_level,
- state->validation,
- NULL, NULL);
- if (NT_STATUS_IS_ERR(status)) {
- set_auth_errors(response, status);
- response->data.auth.authoritative = state->authoritative;
- return status;
- }
+ if (NT_STATUS_IS_ERR(state->result)) {
+ status = state->result;
+ goto out;
+ }
- if (!state->pac_is_trusted) {
- /*
- * Clear the flag in state to do no add the domain
- * from auth below.
- */
- state->flags &= ~WBFLAG_PAM_INFO3_TEXT;
- }
+ status = append_auth_data(response,
+ response,
+ state->flags,
+ state->validation.level,
+ state->validation.validation,
+ state->domain,
+ state->user);
+ if (NT_STATUS_IS_ERR(status)) {
+ goto out;
}
- if (NT_STATUS_IS_OK(NT_STATUS(state->response->data.auth.nt_status)) &&
- (state->flags & WBFLAG_PAM_INFO3_TEXT)) {
+ if (state->flags & WBFLAG_PAM_AUTH_PAC && !state->pac_is_trusted) {
+ /*
+ * Clear the flag just in state to do no add the domain
+ * from auth below.
+ */
+ state->flags &= ~WBFLAG_PAM_INFO3_TEXT;
+ }
+
+ if (state->flags & WBFLAG_PAM_INFO3_TEXT) {
bool ok;
ok = add_trusted_domain_from_auth(
- state->response->data.auth.validation_level,
- &state->response->data.auth.info3,
- &state->response->data.auth.info6);
+ response->data.auth.validation_level,
+ &response->data.auth.info3,
+ &response->data.auth.info6);
if (!ok) {
status = NT_STATUS_LOGON_FAILURE;
DBG_ERR("add_trusted_domain_from_auth failed\n");
}
}
- *response = *state->response;
+ status = NT_STATUS_OK;
+
+out:
+ set_auth_errors(response, status);
+ response->data.auth.authoritative = state->authoritative;
response->result = WINBINDD_PENDING;
- state->response = talloc_move(response, &state->response);
return NT_STATUS(response->data.auth.nt_status);
}
struct wbint_PamAuth;
NTSTATUS _wbint_PamAuth(struct pipes_struct *p,
struct wbint_PamAuth *r);
-enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
- struct winbindd_cli_state *state) ;
+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,