diff options
-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 | ||||
-rw-r--r-- | source4/kdc/kpasswdd.c | 19 | ||||
-rw-r--r-- | source4/ldap_server/ldap_bind.c | 16 | ||||
-rw-r--r-- | source4/rpc_server/config.mk | 2 | ||||
-rw-r--r-- | source4/rpc_server/dcesrv_auth.c | 16 | ||||
-rw-r--r-- | source4/smb_server/smb/config.mk | 2 | ||||
-rw-r--r-- | source4/smb_server/smb/negprot.c | 36 | ||||
-rw-r--r-- | source4/smb_server/smb/sesssetup.c | 16 | ||||
-rw-r--r-- | source4/smb_server/smb2/config.mk | 2 | ||||
-rw-r--r-- | source4/smb_server/smb2/negprot.c | 25 | ||||
-rw-r--r-- | source4/smb_server/smb2/sesssetup.c | 16 | ||||
-rw-r--r-- | source4/torture/rpc/remote_pac.c | 2 | ||||
-rw-r--r-- | source4/utils/ntlm_auth.c | 21 |
22 files changed, 230 insertions, 110 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; +} diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index 27968620e0..39817d922b 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -483,14 +483,6 @@ bool kpasswdd_process(struct kdc_server *kdc, ap_req = data_blob_const(&input->data[header_len], ap_req_len); krb_priv_req = data_blob_const(&input->data[header_len + ap_req_len], krb_priv_len); - nt_status = gensec_server_start(tmp_ctx, kdc->task->event_ctx, - lp_gensec_settings(tmp_ctx, kdc->task->lp_ctx), kdc->task->msg_ctx, - &gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_free(tmp_ctx); - return false; - } - server_credentials = cli_credentials_init(tmp_ctx); if (!server_credentials) { DEBUG(1, ("Failed to init server credentials\n")); @@ -517,7 +509,16 @@ bool kpasswdd_process(struct kdc_server *kdc, return ret; } - nt_status = gensec_set_credentials(gensec_security, server_credentials); + /* We don't strictly need to call this wrapper, and could call + * gensec_server_start directly, as we have no need for NTLM + * and we have a PAC, but this ensures that the wrapper can be + * safely extended for other helpful things in future */ + nt_status = samba_server_gensec_start(tmp_ctx, kdc->task->event_ctx, + kdc->task->msg_ctx, + kdc->task->lp_ctx, + server_credentials, + "kpasswd", + &gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return false; diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index f3f843b920..9abc6115e6 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -140,11 +140,13 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) if (!conn->gensec) { conn->session_info = NULL; - status = gensec_server_start(conn, - conn->connection->event.ctx, - lp_gensec_settings(conn, conn->lp_ctx), - conn->connection->msg_ctx, - &conn->gensec); + status = samba_server_gensec_start(conn, + conn->connection->event.ctx, + conn->connection->msg_ctx, + conn->lp_ctx, + conn->server_credentials, + "ldap", + &conn->gensec); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status))); result = LDAP_OPERATIONS_ERROR; @@ -152,10 +154,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) nt_errstr(status)); } else { - gensec_set_target_service(conn->gensec, "ldap"); - - gensec_set_credentials(conn->gensec, conn->server_credentials); - gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); gensec_want_feature(conn->gensec, GENSEC_FEATURE_ASYNC_REPLIES); diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index a7d03ca22d..d05b0a0c0d 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -203,7 +203,7 @@ dcerpc_browser_OBJ_FILES = $(rpc_serversrcdir)/browser/dcesrv_browser.o PRIVATE_DEPENDENCIES = \ LIBCLI_AUTH \ LIBNDR \ - dcerpc + dcerpc samba_server_gensec dcerpc_server_OBJ_FILES = $(addprefix $(rpc_serversrcdir)/, \ dcerpc_server.o \ diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 5169031d16..e2e3b77948 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -27,6 +27,7 @@ #include "librpc/gen_ndr/ndr_dcerpc.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" +#include "auth/auth.h" #include "param/param.h" /* @@ -61,14 +62,6 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } - status = gensec_server_start(dce_conn, call->event_ctx, - lp_gensec_settings(dce_conn, call->conn->dce_ctx->lp_ctx), - call->msg_ctx, &auth->gensec_security); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC for DCERPC server: %s\n", nt_errstr(status))); - return false; - } - server_credentials = cli_credentials_init(call); if (!server_credentials) { @@ -84,7 +77,12 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) server_credentials = NULL; } - gensec_set_credentials(auth->gensec_security, server_credentials); + status = samba_server_gensec_start(dce_conn, call->event_ctx, + call->msg_ctx, + call->conn->dce_ctx->lp_ctx, + server_credentials, + NULL, + &auth->gensec_security); status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, auth->auth_info->auth_level); diff --git a/source4/smb_server/smb/config.mk b/source4/smb_server/smb/config.mk index 9adf334850..eadc122831 100644 --- a/source4/smb_server/smb/config.mk +++ b/source4/smb_server/smb/config.mk @@ -2,7 +2,7 @@ # Start SUBSYSTEM SMB_PROTOCOL [SUBSYSTEM::SMB_PROTOCOL] PUBLIC_DEPENDENCIES = \ - ntvfs LIBPACKET CREDENTIALS + ntvfs LIBPACKET CREDENTIALS samba_server_gensec # End SUBSYSTEM SMB_PROTOCOL ####################### diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index 71ee82d162..c3399fdd48 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -350,23 +350,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) DATA_BLOB blob; const char *oid; NTSTATUS nt_status; - - nt_status = gensec_server_start(req->smb_conn, - req->smb_conn->connection->event.ctx, - lp_gensec_settings(req->smb_conn, req->smb_conn->lp_ctx), - req->smb_conn->connection->msg_ctx, - &gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status))); - smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n"); - return; - } - - if (req->smb_conn->negotiate.auth_context) { - smbsrv_terminate_connection(req->smb_conn, "reply_nt1: is this a secondary negprot? auth_context is non-NULL!\n"); - return; - } - + server_credentials = cli_credentials_init(req); if (!server_credentials) { @@ -382,6 +366,24 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) server_credentials = NULL; } + nt_status = samba_server_gensec_start(req, + req->smb_conn->connection->event.ctx, + req->smb_conn->connection->msg_ctx, + req->smb_conn->lp_ctx, + server_credentials, + "cifs", + &gensec_security); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status))); + smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n"); + return; + } + + if (req->smb_conn->negotiate.auth_context) { + smbsrv_terminate_connection(req->smb_conn, "reply_nt1: is this a secondary negprot? auth_context is non-NULL!\n"); + return; + } req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials); gensec_set_target_service(gensec_security, "cifs"); diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index 0767a187e5..e38447703b 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -363,20 +363,18 @@ static void sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup *se if (!smb_sess) { struct gensec_security *gensec_ctx; - status = gensec_server_start(req, - req->smb_conn->connection->event.ctx, - lp_gensec_settings(req, req->smb_conn->lp_ctx), - req->smb_conn->connection->msg_ctx, - &gensec_ctx); + status = samba_server_gensec_start(req, + req->smb_conn->connection->event.ctx, + req->smb_conn->connection->msg_ctx, + req->smb_conn->lp_ctx, + req->smb_conn->negotiate.server_credentials, + "cifs", + &gensec_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status))); goto failed; } - gensec_set_credentials(gensec_ctx, req->smb_conn->negotiate.server_credentials); - - gensec_set_target_service(gensec_ctx, "cifs"); - gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY); status = gensec_start_mech_by_oid(gensec_ctx, req->smb_conn->negotiate.oid); diff --git a/source4/smb_server/smb2/config.mk b/source4/smb_server/smb2/config.mk index 68ee6e58f6..f0c3739926 100644 --- a/source4/smb_server/smb2/config.mk +++ b/source4/smb_server/smb2/config.mk @@ -2,7 +2,7 @@ # Start SUBSYSTEM SMB2_PROTOCOL [SUBSYSTEM::SMB2_PROTOCOL] PUBLIC_DEPENDENCIES = \ - ntvfs LIBPACKET LIBCLI_SMB2 + ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec # End SUBSYSTEM SMB2_PROTOCOL ####################### diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 03e5c9356d..0b65a19634 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -20,6 +20,7 @@ #include "includes.h" #include "auth/credentials/credentials.h" +#include "auth/auth.h" #include "auth/gensec/gensec.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" @@ -40,17 +41,6 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * NTSTATUS nt_status; struct cli_credentials *server_credentials; - nt_status = gensec_server_start(req, - req->smb_conn->connection->event.ctx, - lp_gensec_settings(req, req->smb_conn->lp_ctx), - req->smb_conn->connection->msg_ctx, - &gensec_security); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status))); - smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n"); - return nt_status; - } - server_credentials = cli_credentials_init(req); if (!server_credentials) { smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n"); @@ -67,6 +57,19 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials); + nt_status = samba_server_gensec_start(req, + req->smb_conn->connection->event.ctx, + req->smb_conn->connection->msg_ctx, + req->smb_conn->lp_ctx, + server_credentials, + "cifs", + &gensec_security); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("Failed to start GENSEC: %s\n", nt_errstr(nt_status))); + smbsrv_terminate_connection(req->smb_conn, "Failed to start GENSEC\n"); + return nt_status; + } + gensec_set_target_service(gensec_security, "cifs"); gensec_set_credentials(gensec_security, server_credentials); diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 176be0b3ea..9a8c1bfaa9 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -124,20 +124,18 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses if (vuid == 0) { struct gensec_security *gensec_ctx; - status = gensec_server_start(req, - req->smb_conn->connection->event.ctx, - lp_gensec_settings(req, req->smb_conn->lp_ctx), - req->smb_conn->connection->msg_ctx, - &gensec_ctx); + status = samba_server_gensec_start(req, + req->smb_conn->connection->event.ctx, + req->smb_conn->connection->msg_ctx, + req->smb_conn->lp_ctx, + req->smb_conn->negotiate.server_credentials, + "cifs", + &gensec_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status))); goto failed; } - gensec_set_credentials(gensec_ctx, req->smb_conn->negotiate.server_credentials); - - gensec_set_target_service(gensec_ctx, "cifs"); - gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY); status = gensec_start_mech_by_oid(gensec_ctx, GENSEC_OID_SPNEGO); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 0d18228563..5603152ddb 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -106,7 +106,7 @@ static bool test_PACVerify(struct torture_context *tctx, status = gensec_server_start(tctx, tctx->ev, lp_gensec_settings(tctx, tctx->lp_ctx), - msg_server_ctx, &gensec_server_context); + NULL, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); status = gensec_set_credentials(gensec_server_context, credentials); diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c index bd262683d5..2c6f353252 100644 --- a/source4/utils/ntlm_auth.c +++ b/source4/utils/ntlm_auth.c @@ -482,16 +482,33 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, break; case GSS_SPNEGO_SERVER: case SQUID_2_5_NTLMSSP: + { + const char *winbind_method[] = { "winbind", NULL }; + struct auth_context *auth_context; + msg = messaging_client_init(state, lp_messaging_path(state, lp_ctx), lp_iconv_convenience(lp_ctx), ev); if (!msg) { exit(1); } - if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, lp_gensec_settings(state, lp_ctx), - msg, &state->gensec_state))) { + nt_status = auth_context_create_methods(mem_ctx, + winbind_method, + ev, + msg, + lp_ctx, + &auth_context); + + if (!NT_STATUS_IS_OK(nt_status)) { + exit(1); + } + + if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, + lp_gensec_settings(state, lp_ctx), + auth_context, &state->gensec_state))) { exit(1); } break; + } default: abort(); } |