diff options
Diffstat (limited to 'source4/auth')
-rw-r--r-- | source4/auth/auth.h | 24 | ||||
-rw-r--r-- | source4/auth/config.mk | 5 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.c | 22 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.h | 9 | ||||
-rw-r--r-- | source4/auth/gensec/gensec_krb5.c | 2 | ||||
-rw-r--r-- | source4/auth/ntlm/auth.c | 7 | ||||
-rw-r--r-- | source4/auth/ntlmssp/config.mk | 2 | ||||
-rw-r--r-- | source4/auth/ntlmssp/ntlmssp.c | 2 | ||||
-rw-r--r-- | source4/auth/ntlmssp/ntlmssp_server.c | 21 | ||||
-rw-r--r-- | source4/auth/samba_server_gensec.c | 73 |
10 files changed, 136 insertions, 31 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h index e184776140..0ef1e24cd3 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -175,6 +175,20 @@ struct auth_context { /* loadparm context */ struct loadparm_context *lp_ctx; + + NTSTATUS (*check_password)(struct auth_context *auth_ctx, + TALLOC_CTX *mem_ctx, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info); + + NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, const uint8_t **_chal); + + bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); + + NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); + + + }; /* this structure is used by backends to determine the size of some critical types */ @@ -197,6 +211,8 @@ struct auth_critical_sizes { struct ldb_message; struct ldb_context; +struct gensec_security; + NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal); NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, @@ -254,4 +270,12 @@ void auth_check_password_send(struct auth_context *auth_ctx, void *private_data); NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); +NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, + struct tevent_context *event_ctx, + struct messaging_context *msg_ctx, + struct loadparm_context *lp_ctx, + struct cli_credentials *server_credentials, + const char *target_service, + struct gensec_security **gensec_context); + #endif /* _SMBAUTH_H_ */ diff --git a/source4/auth/config.mk b/source4/auth/config.mk index baf4346b4a..7d5050919e 100644 --- a/source4/auth/config.mk +++ b/source4/auth/config.mk @@ -15,6 +15,11 @@ auth_session_OBJ_FILES = $(addprefix $(authsrcdir)/, session.o) $(eval $(call proto_header_template,$(authsrcdir)/session_proto.h,$(auth_session_OBJ_FILES:.o=.c))) +[SUBSYSTEM::samba_server_gensec] +PUBLIC_DEPENDENCIES = CREDENTIALS GENSEC auth + +samba_server_gensec_OBJ_FILES = $(addprefix $(authsrcdir)/, samba_server_gensec.o) + [SUBSYSTEM::auth_system_session] PUBLIC_DEPENDENCIES = CREDENTIALS PRIVATE_DEPENDENCIES = auth_session LIBSAMBA-UTIL LIBSECURITY diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 7169b074e3..2feb545f53 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -508,7 +508,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct messaging_context *msg, + struct auth_context *auth_context, struct gensec_security **gensec_security) { if (ev == NULL) { @@ -530,9 +530,9 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, (*gensec_security)->want_features = 0; (*gensec_security)->event_ctx = ev; - (*gensec_security)->msg_ctx = msg; SMB_ASSERT(settings->lp_ctx != NULL); (*gensec_security)->settings = talloc_reference(*gensec_security, settings); + (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context); return NT_STATUS_OK; } @@ -559,8 +559,9 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->subcontext = true; (*gensec_security)->want_features = parent->want_features; (*gensec_security)->event_ctx = parent->event_ctx; - (*gensec_security)->msg_ctx = parent->msg_ctx; + (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context); (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings); + (*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context); return NT_STATUS_OK; } @@ -599,10 +600,10 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, @note The mem_ctx is only a parent and may be NULL. */ _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct gensec_settings *settings, - struct messaging_context *msg, - struct gensec_security **gensec_security) + struct tevent_context *ev, + struct gensec_settings *settings, + struct auth_context *auth_context, + struct gensec_security **gensec_security) { NTSTATUS status; @@ -611,17 +612,12 @@ _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_ERROR; } - if (!msg) { - DEBUG(0,("gensec_server_start: no messaging context given!\n")); - return NT_STATUS_INTERNAL_ERROR; - } - if (!settings) { DEBUG(0,("gensec_server_start: no settings given!\n")); return NT_STATUS_INTERNAL_ERROR; } - status = gensec_start(mem_ctx, ev, settings, msg, gensec_security); + status = gensec_start(mem_ctx, ev, settings, auth_context, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index c627bda024..c4e93ee97b 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -169,9 +169,13 @@ struct gensec_security { bool subcontext; uint32_t want_features; struct tevent_context *event_ctx; - struct messaging_context *msg_ctx; /* only valid as server */ struct socket_address *my_addr, *peer_addr; struct gensec_settings *settings; + + /* When we are a server, this may be filled in to provide an + * NTLM authentication backend, and user lookup (such as if no + * PAC is found) */ + struct auth_context *auth_context; }; /* this structure is used by backends to determine the size of some critical types */ @@ -185,6 +189,7 @@ struct gensec_critical_sizes { struct gensec_security; struct socket_context; +struct auth_context; NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, @@ -274,7 +279,7 @@ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct messaging_context *msg, + struct auth_context *auth_context, struct gensec_security **gensec_security); NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info); diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 6c6b928917..6e715d0090 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -793,8 +793,6 @@ _PUBLIC_ NTSTATUS gensec_krb5_init(void) { NTSTATUS ret; - auth_init(); - ret = gensec_register(&gensec_krb5_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 20967a6bda..2aae4a075e 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -359,6 +359,8 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** int i; struct auth_context *ctx; + auth_init(); + if (!methods) { DEBUG(0,("auth_context_create: No auth method list!?\n")); return NT_STATUS_INTERNAL_ERROR; @@ -405,6 +407,11 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** return NT_STATUS_INTERNAL_ERROR; } + ctx->check_password = auth_check_password; + ctx->get_challenge = auth_get_challenge; + ctx->set_challenge = auth_context_set_challenge; + ctx->challenge_may_be_modified = auth_challenge_may_be_modified; + *auth_ctx = ctx; return NT_STATUS_OK; diff --git a/source4/auth/ntlmssp/config.mk b/source4/auth/ntlmssp/config.mk index 129f58de83..c0446bcac1 100644 --- a/source4/auth/ntlmssp/config.mk +++ b/source4/auth/ntlmssp/config.mk @@ -9,7 +9,7 @@ $(eval $(call proto_header_template,$(authsrcdir)/ntlmssp/msrpc_parse.h,$(MSRPC_ [MODULE::gensec_ntlmssp] SUBSYSTEM = gensec INIT_FUNCTION = gensec_ntlmssp_init -PRIVATE_DEPENDENCIES = MSRPC_PARSE CREDENTIALS auth +PRIVATE_DEPENDENCIES = MSRPC_PARSE CREDENTIALS OUTPUT_TYPE = MERGED_OBJ # End MODULE gensec_ntlmssp ################################################ diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c index 1b14e461c3..c4b3a31365 100644 --- a/source4/auth/ntlmssp/ntlmssp.c +++ b/source4/auth/ntlmssp/ntlmssp.c @@ -434,8 +434,6 @@ _PUBLIC_ NTSTATUS gensec_ntlmssp_init(void) { NTSTATUS ret; - auth_init(); - ret = gensec_register(&gensec_ntlmssp_security_ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register '%s' gensec backend!\n", diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 30bf159df1..9215ccac8c 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -608,7 +608,7 @@ static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_sta NTSTATUS status; const uint8_t *chal; - status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal); + status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n", nt_errstr(status))); @@ -625,7 +625,7 @@ static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_sta */ static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state) { - return auth_challenge_may_be_modified(gensec_ntlmssp_state->auth_context); + return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context); } /** @@ -644,7 +644,9 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_n chal = challenge->data; - nt_status = auth_context_set_challenge(auth_context, chal, "NTLMSSP callback (NTLM2)"); + nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context, + chal, + "NTLMSSP callback (NTLM2)"); return nt_status; } @@ -679,8 +681,10 @@ static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ user_info->password.response.nt = gensec_ntlmssp_state->nt_resp; user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data); - nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, mem_ctx, - user_info, &gensec_ntlmssp_state->server_info); + nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context, + mem_ctx, + user_info, + &gensec_ntlmssp_state->server_info); talloc_free(user_info); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -795,12 +799,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } - nt_status = auth_context_create(gensec_ntlmssp_state, - gensec_security->event_ctx, - gensec_security->msg_ctx, - gensec_security->settings->lp_ctx, - &gensec_ntlmssp_state->auth_context); - NT_STATUS_NOT_OK_RETURN(nt_status); + gensec_ntlmssp_state->auth_context = gensec_security->auth_context; gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; diff --git a/source4/auth/samba_server_gensec.c b/source4/auth/samba_server_gensec.c new file mode 100644 index 0000000000..0576b15eb3 --- /dev/null +++ b/source4/auth/samba_server_gensec.c @@ -0,0 +1,73 @@ +/* + Unix SMB/CIFS implementation. + + Generic Authentication Interface for Samba Servers + + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* This code sets up GENSEC in the way that all Samba servers want + * (becaue they have presumed access to the sam.ldb etc */ + +#include "includes.h" +#include "auth/auth.h" +#include "auth/gensec/gensec.h" +#include "param/param.h" + +NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, + struct tevent_context *event_ctx, + struct messaging_context *msg_ctx, + struct loadparm_context *lp_ctx, + struct cli_credentials *server_credentials, + const char *target_service, + struct gensec_security **gensec_context) +{ + NTSTATUS nt_status; + struct gensec_security *gensec_ctx; + struct auth_context *auth_context; + + nt_status = auth_context_create(mem_ctx, + event_ctx, + msg_ctx, + lp_ctx, + &auth_context); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(nt_status))); + return nt_status; + } + + nt_status = gensec_server_start(mem_ctx, + event_ctx, + lp_gensec_settings(mem_ctx, lp_ctx), + auth_context, + &gensec_ctx); + if (!NT_STATUS_IS_OK(nt_status)) { + talloc_free(auth_context); + DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(nt_status))); + return nt_status; + } + + talloc_steal(gensec_ctx, auth_context); + + gensec_set_credentials(gensec_ctx, server_credentials); + + if (target_service) { + gensec_set_target_service(gensec_ctx, target_service); + } + *gensec_context = gensec_ctx; + return nt_status; +} |