summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-02-03 16:14:42 +1100
committerAndrew Bartlett <abartlet@samba.org>2012-02-24 11:23:18 +1100
commit8a9b6fe26dc347afd6dc17570354e0af391b351d (patch)
treeb53bed5dc786897fdca800b84ad2eba6afd5fe3a
parentaed0735862f9517c49918bb4e4b444427d924b2e (diff)
downloadsamba-8a9b6fe26dc347afd6dc17570354e0af391b351d.tar.gz
samba-8a9b6fe26dc347afd6dc17570354e0af391b351d.tar.bz2
samba-8a9b6fe26dc347afd6dc17570354e0af391b351d.zip
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
-rw-r--r--source3/auth/auth.c6
-rw-r--r--source3/auth/auth_generic.c58
-rw-r--r--source3/auth/auth_samba4.c54
-rw-r--r--source3/auth/proto.h1
-rw-r--r--source3/include/auth.h7
5 files changed, 114 insertions, 12 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 1e1ede45a4..1c813a429a 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -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;
}
}
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index 65b83f035f..681989e16b 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -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) {
diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
index 971f9d6898..6692f187be 100644
--- a/source3/auth/auth_samba4.c
+++ b/source3/auth/auth_samba4.c
@@ -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;
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 1697eda5be..2d123b0264 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -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);
diff --git a/source3/include/auth.h b/source3/include/auth.h
index 5fae94ca84..894b7dff81 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -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;