summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb/sesssetup.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-04-13 12:00:06 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-04-14 10:30:51 +1000
commit589a42e2da7d7cd382deb94c57b0c6dbca269e55 (patch)
tree843f90acec386e763b37a3dda77d986cb4ead6de /source4/smb_server/smb/sesssetup.c
parent4e2384e2426745023553afb21270165872c61b02 (diff)
downloadsamba-589a42e2da7d7cd382deb94c57b0c6dbca269e55.tar.gz
samba-589a42e2da7d7cd382deb94c57b0c6dbca269e55.tar.bz2
samba-589a42e2da7d7cd382deb94c57b0c6dbca269e55.zip
s4:auth Change auth_generate_session_info to take an auth context
The auth context was in the past only for NTLM authentication, but we need a SAM, an event context and and loadparm context for calculating the local groups too, so re-use that infrustructure we already have in place. However, to avoid problems where we may not have an auth_context (in torture tests, for example), allow a simpler 'session_info' to be generated, by passing this via an indirection in gensec and an generate_session_info() function pointer in the struct auth_context. In the smb_server (for old-style session setups) we need to change the async context to a new 'struct sesssetup_context'. This allows us to use the auth_context in processing the authentication reply . Andrew Bartlett
Diffstat (limited to 'source4/smb_server/smb/sesssetup.c')
-rw-r--r--source4/smb_server/smb/sesssetup.c79
1 files changed, 61 insertions, 18 deletions
diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
index aecd49fb0b..afc33dd3c6 100644
--- a/source4/smb_server/smb/sesssetup.c
+++ b/source4/smb_server/smb/sesssetup.c
@@ -32,6 +32,11 @@
#include "param/param.h"
#include "../lib/tsocket/tsocket.h"
+struct sesssetup_context {
+ struct auth_context *auth_context;
+ struct smbsrv_request *req;
+};
+
/*
setup the OS, Lanman and domain portions of a session setup reply
*/
@@ -58,8 +63,9 @@ static void smbsrv_sesssetup_backend_send(struct smbsrv_request *req,
static void sesssetup_old_send(struct tevent_req *subreq)
{
- struct smbsrv_request *req =
- tevent_req_callback_data(subreq, struct smbsrv_request);
+ struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
+ struct smbsrv_request *req = state->req;
+
union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info;
@@ -71,8 +77,9 @@ static void sesssetup_old_send(struct tevent_req *subreq)
if (!NT_STATUS_IS_OK(status)) goto failed;
/* This references server_info into session_info */
- status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, req->smb_conn->lp_ctx,
- server_info, &session_info);
+ status = req->smb_conn->negotiate.auth_context->generate_session_info(req,
+ req->smb_conn->negotiate.auth_context,
+ server_info, &session_info);
if (!NT_STATUS_IS_OK(status)) goto failed;
/* allocate a new session */
@@ -106,6 +113,7 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
struct tsocket_address *remote_address;
const char *remote_machine = NULL;
struct tevent_req *subreq;
+ struct sesssetup_context *state;
sess->old.out.vuid = 0;
sess->old.out.action = 0;
@@ -147,12 +155,32 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
user_info->password.response.lanman.data = talloc_steal(user_info, sess->old.in.password.data);
user_info->password.response.nt = data_blob(NULL, 0);
- subreq = auth_check_password_send(req,
+ state = talloc(req, struct sesssetup_context);
+ if (!state) goto nomem;
+
+ if (req->smb_conn->negotiate.auth_context) {
+ state->auth_context = req->smb_conn->negotiate.auth_context;
+ } else {
+ /* TODO: should we use just "anonymous" here? */
+ NTSTATUS status = auth_context_create(state,
+ req->smb_conn->connection->event.ctx,
+ req->smb_conn->connection->msg_ctx,
+ req->smb_conn->lp_ctx,
+ &state->auth_context);
+ if (!NT_STATUS_IS_OK(status)) {
+ smbsrv_sesssetup_backend_send(req, sess, status);
+ return;
+ }
+ }
+
+ state->req = req;
+
+ subreq = auth_check_password_send(state,
req->smb_conn->connection->event.ctx,
req->smb_conn->negotiate.auth_context,
user_info);
if (!subreq) goto nomem;
- tevent_req_set_callback(subreq, sesssetup_old_send, req);
+ tevent_req_set_callback(subreq, sesssetup_old_send, state);
return;
nomem:
@@ -161,12 +189,13 @@ nomem:
static void sesssetup_nt1_send(struct tevent_req *subreq)
{
- struct smbsrv_request *req =
- tevent_req_callback_data(subreq, struct smbsrv_request);
+ struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
+ struct smbsrv_request *req = state->req;
union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info;
struct smbsrv_session *smb_sess;
+
NTSTATUS status;
status = auth_check_password_recv(subreq, req, &server_info);
@@ -174,9 +203,10 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
if (!NT_STATUS_IS_OK(status)) goto failed;
/* This references server_info into session_info */
- status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx,
- req->smb_conn->lp_ctx,
- server_info, &session_info);
+ status = state->auth_context->generate_session_info(req,
+ state->auth_context,
+ server_info,
+ &session_info);
if (!NT_STATUS_IS_OK(status)) goto failed;
/* allocate a new session */
@@ -214,11 +244,11 @@ failed:
static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
{
NTSTATUS status;
- struct auth_context *auth_context;
struct auth_usersupplied_info *user_info = NULL;
struct tsocket_address *remote_address;
const char *remote_machine = NULL;
struct tevent_req *subreq;
+ struct sesssetup_context *state;
sess->nt1.out.vuid = 0;
sess->nt1.out.action = 0;
@@ -233,6 +263,11 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
}
+ state = talloc(req, struct sesssetup_context);
+ if (!state) goto nomem;
+
+ state->req = req;
+
if (req->smb_conn->negotiate.oid) {
if (sess->nt1.in.user && *sess->nt1.in.user) {
/* We can't accept a normal login, because we
@@ -242,14 +277,22 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
}
/* TODO: should we use just "anonymous" here? */
- status = auth_context_create(req,
+ status = auth_context_create(state,
req->smb_conn->connection->event.ctx,
req->smb_conn->connection->msg_ctx,
req->smb_conn->lp_ctx,
- &auth_context);
+ &state->auth_context);
if (!NT_STATUS_IS_OK(status)) goto failed;
+ } else if (req->smb_conn->negotiate.auth_context) {
+ state->auth_context = req->smb_conn->negotiate.auth_context;
} else {
- auth_context = req->smb_conn->negotiate.auth_context;
+ /* TODO: should we use just "anonymous" here? */
+ status = auth_context_create(state,
+ req->smb_conn->connection->event.ctx,
+ req->smb_conn->connection->msg_ctx,
+ req->smb_conn->lp_ctx,
+ &state->auth_context);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
}
if (req->smb_conn->negotiate.calling_name) {
@@ -281,12 +324,12 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
user_info->password.response.nt = sess->nt1.in.password2;
user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);
- subreq = auth_check_password_send(req,
+ subreq = auth_check_password_send(state,
req->smb_conn->connection->event.ctx,
- auth_context,
+ state->auth_context,
user_info);
if (!subreq) goto nomem;
- tevent_req_set_callback(subreq, sesssetup_nt1_send, req);
+ tevent_req_set_callback(subreq, sesssetup_nt1_send, state);
return;