1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

s3-auth: Add a way to get an auth4_context from the auth stack

This will allow us to use the same layer that auth_ntlmssp does
in the non-SPNEGO session setup, which will in turn make the
authentication code more consistent in the AD server case.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2012-02-03 16:14:42 +11:00
parent aed0735862
commit 8a9b6fe26d
5 changed files with 114 additions and 12 deletions

View File

@ -460,10 +460,12 @@ static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx,
(*auth_context)->auth_method_list = list;
/* Look for the first module to provide a start_gensec hook, and set that if provided */
/* Look for the first module to provide a prepare_gensec and
* make_auth4_context hook, and set that if provided */
for (method = (*auth_context)->auth_method_list; method; method = method->next) {
if (method->prepare_gensec) {
if (method->prepare_gensec && method->make_auth4_context) {
(*auth_context)->prepare_gensec = method->prepare_gensec;
(*auth_context)->make_auth4_context = method->make_auth4_context;
break;
}
}

View File

@ -154,6 +154,54 @@ done:
return status;
}
static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
{
struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
if (auth4_context == NULL) {
DEBUG(10, ("failed to allocate auth4_context failed\n"));
return NULL;
}
auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
auth4_context->generate_session_info = auth3_generate_session_info;
auth4_context->get_challenge = auth3_get_challenge;
auth4_context->set_challenge = auth3_set_challenge;
auth4_context->challenge_may_be_modified = auth3_may_set_challenge;
auth4_context->check_password = auth3_check_password;
auth4_context->private_data = talloc_steal(auth4_context, auth_context);
return auth4_context;
}
NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
{
struct auth_context *auth_context;
NTSTATUS nt_status;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
nt_status = make_auth_context_subsystem(tmp_ctx, &auth_context);
if (!NT_STATUS_IS_OK(nt_status)) {
TALLOC_FREE(tmp_ctx);
return nt_status;
}
if (auth_context->make_auth4_context) {
nt_status = auth_context->make_auth4_context(mem_ctx, auth4_context_out);
TALLOC_FREE(tmp_ctx);
return nt_status;
} else {
struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
if (auth4_context == NULL) {
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
*auth4_context_out = talloc_steal(mem_ctx, auth4_context);
TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
}
NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
const struct tsocket_address *remote_address,
struct gensec_security **gensec_security_out)
@ -185,19 +233,11 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
struct cli_credentials *server_credentials;
const char *dns_name;
const char *dns_domain;
struct auth4_context *auth4_context = talloc_zero(tmp_ctx, struct auth4_context);
struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
if (auth4_context == NULL) {
DEBUG(10, ("failed to allocate auth4_context failed\n"));
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
auth4_context->generate_session_info = auth3_generate_session_info;
auth4_context->get_challenge = auth3_get_challenge;
auth4_context->set_challenge = auth3_set_challenge;
auth4_context->challenge_may_be_modified = auth3_may_set_challenge;
auth4_context->check_password = auth3_check_password;
auth4_context->private_data = talloc_steal(auth4_context, auth_context);
lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_context());
if (lp_ctx == NULL) {

View File

@ -169,6 +169,59 @@ static NTSTATUS prepare_gensec(TALLOC_CTX *mem_ctx,
return status;
}
/* Hook to allow handling of NTLM authentication for AD operation
* without directly linking the s4 auth stack */
static NTSTATUS make_auth4_context_s4(TALLOC_CTX *mem_ctx,
struct auth4_context **auth4_context)
{
NTSTATUS status;
struct loadparm_context *lp_ctx;
struct tevent_context *event_ctx;
TALLOC_CTX *frame = talloc_stackframe();
struct imessaging_context *msg_ctx;
lp_ctx = loadparm_init_s3(frame, loadparm_s3_context());
if (lp_ctx == NULL) {
DEBUG(1, ("loadparm_init_s3 failed\n"));
TALLOC_FREE(frame);
return NT_STATUS_INVALID_SERVER_STATE;
}
event_ctx = s4_event_context_init(frame);
if (event_ctx == NULL) {
DEBUG(1, ("s4_event_context_init failed\n"));
TALLOC_FREE(frame);
return NT_STATUS_INVALID_SERVER_STATE;
}
msg_ctx = imessaging_client_init(frame,
lp_ctx,
event_ctx);
if (msg_ctx == NULL) {
DEBUG(1, ("imessaging_init failed\n"));
TALLOC_FREE(frame);
return NT_STATUS_INVALID_SERVER_STATE;
}
status = auth_context_create(mem_ctx,
event_ctx,
msg_ctx,
lp_ctx,
auth4_context);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(status)));
TALLOC_FREE(frame);
return status;
}
talloc_reparent(frame, *auth4_context, msg_ctx);
talloc_reparent(frame, *auth4_context, event_ctx);
talloc_reparent(frame, *auth4_context, lp_ctx);
TALLOC_FREE(frame);
return status;
}
/* module initialisation */
static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
const char *param,
@ -185,6 +238,7 @@ static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
result->name = "samba4";
result->auth = check_samba4_security;
result->prepare_gensec = prepare_gensec;
result->make_auth4_context = make_auth4_context_s4;
*auth_method = result;
return NT_STATUS_OK;

View File

@ -69,6 +69,7 @@ NTSTATUS auth_netlogond_init(void);
/* The following definitions come from auth/auth_generic.c */
NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out);
NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx, const struct tsocket_address *remote_address,
struct gensec_security **gensec_security_out);

View File

@ -69,6 +69,9 @@ struct auth_serversupplied_info {
typedef NTSTATUS (*prepare_gensec_fn)(TALLOC_CTX *mem_ctx,
struct gensec_security **gensec_context);
typedef NTSTATUS (*make_auth4_context_fn)(TALLOC_CTX *mem_ctx,
struct auth4_context **auth4_context);
struct auth_context {
DATA_BLOB challenge;
@ -88,6 +91,7 @@ struct auth_context {
struct auth_serversupplied_info **server_info);
prepare_gensec_fn prepare_gensec;
make_auth4_context_fn make_auth4_context;
};
typedef struct auth_methods
@ -109,8 +113,9 @@ typedef struct auth_methods
void **my_private_data,
TALLOC_CTX *mem_ctx);
/* Optional methods allowing this module to provide a way to get a gensec context */
/* Optional methods allowing this module to provide a way to get a gensec context and an auth4_context */
prepare_gensec_fn prepare_gensec;
make_auth4_context_fn make_auth4_context;
/* Used to keep tabs on things like the cli for SMB server authentication */
void *private_data;