mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
s3:winbind: Convert PAM_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
dd69be8020
commit
c68f21f26f
@ -196,6 +196,27 @@ interface winbind
|
||||
[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;
|
||||
|
@ -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 = "AUTH_CRAP",
|
||||
.struct_cmd = WINBINDD_PAM_AUTH_CRAP,
|
||||
.struct_fn = winbindd_dual_pam_auth_crap,
|
||||
},{
|
||||
.name = "PAM_LOGOFF",
|
||||
.struct_cmd = WINBINDD_PAM_LOGOFF,
|
||||
|
@ -2115,7 +2115,7 @@ done:
|
||||
* @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;
|
||||
@ -2141,7 +2141,7 @@ static struct tsocket_address *get_remote_address(TALLOC_CTX *mem_ctx, int sock)
|
||||
* @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;
|
||||
@ -2836,71 +2836,52 @@ done:
|
||||
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 */
|
||||
|
||||
/* 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;
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
if (domain == NULL) {
|
||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||
}
|
||||
chal = data_blob_const(state->request->data.auth_crap.chal, 8);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
logon_id = generate_random_u64();
|
||||
remote = dcesrv_connection_get_remote_address(p->dce_call->conn);
|
||||
local = dcesrv_connection_get_local_address(p->dce_call->conn);
|
||||
|
||||
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,
|
||||
@ -2912,7 +2893,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = map_validation_to_info3(state->mem_ctx,
|
||||
result = map_validation_to_info3(p->mem_ctx,
|
||||
validation_level,
|
||||
validation,
|
||||
&info3);
|
||||
@ -2920,32 +2901,19 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
||||
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] "
|
||||
@ -2956,45 +2924,48 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
|
||||
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,
|
||||
|
@ -23,14 +23,16 @@
|
||||
#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);
|
||||
@ -45,6 +47,11 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
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);
|
||||
@ -55,14 +62,12 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
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);
|
||||
}
|
||||
|
||||
@ -78,10 +83,12 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
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);
|
||||
@ -120,8 +127,67 @@ struct tevent_req *winbindd_pam_auth_crap_send(
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -135,12 +201,11 @@ static void winbindd_pam_auth_crap_done(struct tevent_req *subreq)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -155,52 +220,40 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
|
||||
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 (!state->pac_is_trusted) {
|
||||
/*
|
||||
* Clear the flag in state to do no add the domain
|
||||
* from auth below.
|
||||
*/
|
||||
state->flags &= ~WBFLAG_PAM_INFO3_TEXT;
|
||||
}
|
||||
if (NT_STATUS_IS_ERR(state->result)) {
|
||||
status = state->result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(NT_STATUS(state->response->data.auth.nt_status)) &&
|
||||
(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 (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");
|
||||
@ -211,8 +264,11 @@ NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req,
|
||||
}
|
||||
}
|
||||
|
||||
*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);
|
||||
}
|
||||
|
@ -441,8 +441,8 @@ struct pipes_struct;
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user