summaryrefslogtreecommitdiff
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
parent4e2384e2426745023553afb21270165872c61b02 (diff)
downloadsamba-589a42e2da7d7cd382deb94c57b0c6dbca269e55.tar.gz
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
-rw-r--r--source4/auth/auth.h8
-rw-r--r--source4/auth/gensec/gensec.c21
-rw-r--r--source4/auth/gensec/gensec.h1
-rw-r--r--source4/auth/gensec/gensec_gssapi.c4
-rw-r--r--source4/auth/gensec/gensec_krb5.c2
-rw-r--r--source4/auth/ntlm/auth.c5
-rw-r--r--source4/auth/ntlm/auth_sam.c24
-rw-r--r--source4/auth/ntlm/auth_simple.c3
-rw-r--r--source4/auth/ntlmssp/ntlmssp_server.c10
-rw-r--r--source4/auth/sam.c1
-rw-r--r--source4/auth/session.c13
-rw-r--r--source4/auth/session.h9
-rw-r--r--source4/auth/system_session.c10
-rw-r--r--source4/smb_server/smb/sesssetup.c79
-rw-r--r--source4/smbd/service_named_pipe.c62
15 files changed, 180 insertions, 72 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index bbdbbc3127a..915d10397ba 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -126,6 +126,7 @@ struct auth_serversupplied_info
struct auth_method_context;
struct auth_check_password_request;
struct auth_context;
+struct auth_session_info;
struct auth_operations {
const char *name;
@@ -185,6 +186,9 @@ struct auth_context {
/* loadparm context */
struct loadparm_context *lp_ctx;
+ /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */
+ struct ldb_context *sam_ctx;
+
NTSTATUS (*check_password)(struct auth_context *auth_ctx,
TALLOC_CTX *mem_ctx,
const struct auth_usersupplied_info *user_info,
@@ -201,6 +205,10 @@ struct auth_context {
const char *principal,
struct auth_serversupplied_info **server_info);
+ NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,
+ struct auth_context *auth_context,
+ struct auth_serversupplied_info *server_info,
+ struct auth_session_info **session_info);
};
/* this structure is used by backends to determine the size of some critical types */
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c
index 7430eef9572..b532c1502d3 100644
--- a/source4/auth/gensec/gensec.c
+++ b/source4/auth/gensec/gensec.c
@@ -29,6 +29,8 @@
#include "librpc/rpc/dcerpc.h"
#include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h"
+#include "auth/auth.h"
+#include "auth/system_session_proto.h"
#include "param/param.h"
#include "lib/util/tsort.h"
@@ -596,6 +598,8 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx,
return status;
}
+
+
/**
Start the GENSEC system, in server mode, returning a context pointer.
@param mem_ctx The parent TALLOC memory context.
@@ -1292,7 +1296,6 @@ _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_s
return gensec_security->remote_addr;
}
-
/**
* Set the target principal (assuming it it known, say from the SPNEGO reply)
* - ensures it is talloc()ed
@@ -1317,6 +1320,22 @@ const char *gensec_get_target_principal(struct gensec_security *gensec_security)
return NULL;
}
+NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx,
+ struct gensec_security *gensec_security,
+ struct auth_serversupplied_info *server_info,
+ struct auth_session_info **session_info)
+{
+ NTSTATUS nt_status;
+ if (gensec_security->auth_context) {
+ nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context,
+ server_info, session_info);
+ } else {
+ nt_status = auth_generate_simple_session_info(mem_ctx,
+ server_info, session_info);
+ }
+ return nt_status;
+}
+
/*
register a GENSEC backend.
diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h
index 232f1a4500d..47adf039c0d 100644
--- a/source4/auth/gensec/gensec.h
+++ b/source4/auth/gensec/gensec.h
@@ -179,6 +179,7 @@ struct gensec_critical_sizes {
struct gensec_security;
struct socket_context;
struct auth_context;
+struct auth_serversupplied_info;
NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 6d59bbe612b..fe9aaa3b90f 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1320,8 +1320,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
}
/* references the server_info into the session_info */
- nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx,
- gensec_security->settings->lp_ctx, server_info, &session_info);
+ nt_status = gensec_generate_session_info(mem_ctx, gensec_security,
+ server_info, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
return nt_status;
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 9a96e5e9838..bb9ace70b1d 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -703,7 +703,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
}
/* references the server_info into the session_info */
- nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info);
+ nt_status = gensec_generate_session_info(mem_ctx, gensec_security, server_info, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index d5df387d806..e9e72fa2a5d 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -25,6 +25,8 @@
#include "auth/auth.h"
#include "auth/ntlm/auth_proto.h"
#include "param/param.h"
+#include "dsdb/samdb/samdb.h"
+
/***************************************************************************
Set a fixed challenge
@@ -435,6 +437,8 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **
ctx->msg_ctx = msg;
ctx->lp_ctx = lp_ctx;
+ ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx));
+
for (i=0; methods[i] ; i++) {
struct auth_method_context *method;
@@ -461,6 +465,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **
ctx->set_challenge = auth_context_set_challenge;
ctx->challenge_may_be_modified = auth_challenge_may_be_modified;
ctx->get_server_info_principal = auth_get_server_info_principal;
+ ctx->generate_session_info = auth_generate_session_info;
*auth_ctx = ctx;
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index f476e1c3b2c..e4e56e1219a 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -144,7 +144,7 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
struct samr_Password *lm_pwd, *nt_pwd;
NTSTATUS nt_status;
- uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
+ uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn);
/* Quit if the account was locked out. */
if (acct_flags & ACB_AUTOLOCK) {
@@ -168,7 +168,7 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
user_info, user_sess_key, lm_sess_key);
NT_STATUS_NOT_OK_RETURN(nt_status);
- nt_status = authsam_account_ok(mem_ctx, sam_ctx,
+ nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx,
user_info->logon_parameters,
domain_dn,
msg,
@@ -189,11 +189,15 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
NTSTATUS nt_status;
const char *account_name = user_info->mapped.account_name;
struct ldb_message *msg;
- struct ldb_context *sam_ctx;
struct ldb_dn *domain_dn;
DATA_BLOB user_sess_key, lm_sess_key;
TALLOC_CTX *tmp_ctx;
+ if (ctx->auth_ctx->sam_ctx == NULL) {
+ DEBUG(0, ("No SAM available, cannot log in users\n"));
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
+
if (!account_name || !*account_name) {
/* 'not for me' */
return NT_STATUS_NOT_IMPLEMENTED;
@@ -204,32 +208,26 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
return NT_STATUS_NO_MEMORY;
}
- sam_ctx = samdb_connect(tmp_ctx, ctx->auth_ctx->event_ctx, ctx->auth_ctx->lp_ctx, system_session(ctx->auth_ctx->lp_ctx));
- if (sam_ctx == NULL) {
- talloc_free(tmp_ctx);
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
- domain_dn = ldb_get_default_basedn(sam_ctx);
+ domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
if (domain_dn == NULL) {
talloc_free(tmp_ctx);
return NT_STATUS_NO_SUCH_DOMAIN;
}
- nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msg);
+ nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
return nt_status;
}
- nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msg, user_info,
+ nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info,
&user_sess_key, &lm_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
return nt_status;
}
- nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
+ nt_status = authsam_make_server_info(tmp_ctx, ctx->auth_ctx->sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
lp_sam_name(ctx->auth_ctx->lp_ctx),
domain_dn,
msg,
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index 1de74ec2e29..7f972ac2969 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -87,7 +87,8 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
}
if (session_info) {
- nt_status = auth_generate_session_info(tmp_ctx, ev, lp_ctx, server_info, session_info);
+ nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
+ server_info, session_info);
if (NT_STATUS_IS_OK(nt_status)) {
talloc_steal(mem_ctx, *session_info);
diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c
index fc7d6d78038..8a8c579c687 100644
--- a/source4/auth/ntlmssp/ntlmssp_server.c
+++ b/source4/auth/ntlmssp/ntlmssp_server.c
@@ -28,6 +28,7 @@
#include "../libcli/auth/libcli_auth.h"
#include "../lib/crypto/crypto.h"
#include "auth/gensec/gensec.h"
+#include "auth/gensec/gensec_proto.h"
#include "auth/auth.h"
#include "param/param.h"
@@ -722,11 +723,10 @@ NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
struct gensec_ntlmssp_context);
struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
- nt_status = auth_generate_session_info(ntlmssp_state,
- gensec_security->event_ctx,
- gensec_security->settings->lp_ctx,
- gensec_ntlmssp->server_info,
- session_info);
+ nt_status = gensec_generate_session_info(ntlmssp_state,
+ gensec_security,
+ gensec_ntlmssp->server_info,
+ session_info);
NT_STATUS_NOT_OK_RETURN(nt_status);
(*session_info)->session_key = data_blob_talloc(*session_info,
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index fc3e810ef7f..201185cf4de 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -283,6 +283,7 @@ static bool sids_contains_sid(const struct dom_sid **sids,
return false;
}
+
/*
* This function generates the transitive closure of a given SID "sid" (it
* basically expands nested groups of a SID).
diff --git a/source4/auth/session.c b/source4/auth/session.c
index 8efdcd88075..03d1c91054b 100644
--- a/source4/auth/session.c
+++ b/source4/auth/session.c
@@ -42,11 +42,10 @@ _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
return session_info;
}
-_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
- struct tevent_context *event_ctx,
- struct loadparm_context *lp_ctx,
- struct auth_serversupplied_info *server_info,
- struct auth_session_info **_session_info)
+_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
+ struct auth_context *auth_context,
+ struct auth_serversupplied_info *server_info,
+ struct auth_session_info **_session_info)
{
struct auth_session_info *session_info;
NTSTATUS nt_status;
@@ -61,8 +60,8 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
session_info->session_key = server_info->user_session_key;
nt_status = security_token_create(session_info,
- event_ctx,
- lp_ctx,
+ auth_context->event_ctx,
+ auth_context->lp_ctx,
server_info->account_sid,
server_info->primary_group_sid,
server_info->n_domain_groups,
diff --git a/source4/auth/session.h b/source4/auth/session.h
index e988855a155..574b76946e1 100644
--- a/source4/auth/session.h
+++ b/source4/auth/session.h
@@ -31,7 +31,7 @@ struct auth_session_info {
#include "librpc/gen_ndr/netlogon.h"
struct tevent_context;
-
+struct auth_context;
/* Create a security token for a session SYSTEM (the most
* trusted/prvilaged account), including the local machine account as
* the off-host credentials */
@@ -47,11 +47,10 @@ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadpa
NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
const char *netbios_name,
struct auth_serversupplied_info **_server_info) ;
-NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
- struct tevent_context *event_ctx,
- struct loadparm_context *lp_ctx,
+NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
+ struct auth_context *auth_context,
struct auth_serversupplied_info *server_info,
- struct auth_session_info **_session_info) ;
+ struct auth_session_info **_session_info);
NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
struct loadparm_context *lp_ctx,
diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c
index 4df96884ca3..c6df082f697 100644
--- a/source4/auth/system_session.c
+++ b/source4/auth/system_session.c
@@ -114,9 +114,9 @@ static NTSTATUS create_token(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS generate_simple_session_info(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- struct auth_session_info **_session_info)
+NTSTATUS auth_generate_simple_session_info(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ struct auth_session_info **_session_info)
{
struct auth_session_info *session_info;
NTSTATUS nt_status;
@@ -197,7 +197,7 @@ static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx,
}
/* references the server_info into the session_info */
- nt_status = generate_simple_session_info(parent_ctx, server_info, &session_info);
+ nt_status = auth_generate_simple_session_info(parent_ctx, server_info, &session_info);
talloc_free(mem_ctx);
NT_STATUS_NOT_OK_RETURN(nt_status);
@@ -528,7 +528,7 @@ _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
}
/* references the server_info into the session_info */
- nt_status = generate_simple_session_info(parent_ctx, server_info, &session_info);
+ nt_status = auth_generate_simple_session_info(parent_ctx, server_info, &session_info);
talloc_free(mem_ctx);
NT_STATUS_NOT_OK_RETURN(nt_status);
diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
index aecd49fb0b7..afc33dd3c6c 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;
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index ec833d0c5a9..6409a0099ef 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -23,6 +23,7 @@
#include <tevent.h>
#include "smbd/service.h"
#include "param/param.h"
+#include "auth/auth.h"
#include "auth/session.h"
#include "auth/auth_sam_reply.h"
#include "lib/socket/socket.h"
@@ -162,6 +163,7 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
struct auth_serversupplied_info *server_info;
struct named_pipe_auth_req pipe_request;
struct named_pipe_auth_rep pipe_reply;
+ struct auth_context *auth_context;
NTSTATUS status;
call = talloc(pipe_conn, struct named_pipe_call);
@@ -252,12 +254,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
goto reply;
}
+ pipe_reply.status = auth_context_create(conn,
+ conn->event.ctx, conn->msg_ctx,
+ conn->lp_ctx,
+ &auth_context);
+ if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+ DEBUG(2, ("auth_context_create returned "
+ "%s\n", nt_errstr(pipe_reply.status)));
+ goto reply;
+ }
+
+
/* setup the session_info on the connection */
- pipe_reply.status = auth_generate_session_info(conn,
- conn->event.ctx,
- conn->lp_ctx,
- server_info,
- &conn->session_info);
+ pipe_reply.status = auth_context->generate_session_info(conn,
+ auth_context,
+ server_info,
+ &conn->session_info);
+ talloc_free(auth_context);
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
DEBUG(2, ("auth_generate_session_info failed: %s\n",
nt_errstr(pipe_reply.status)));
@@ -292,11 +305,21 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
}
/* setup the session_info on the connection */
- pipe_reply.status = auth_generate_session_info(conn,
- conn->event.ctx,
+ pipe_reply.status = auth_context_create(conn,
+ conn->event.ctx, conn->msg_ctx,
conn->lp_ctx,
- server_info,
- &conn->session_info);
+ &auth_context);
+ if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+ DEBUG(2, ("auth_context_create returned "
+ "%s\n", nt_errstr(pipe_reply.status)));
+ goto reply;
+ }
+
+ pipe_reply.status = auth_context->generate_session_info(conn,
+ auth_context,
+ server_info,
+ &conn->session_info);
+ talloc_free(auth_context);
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
DEBUG(2, ("auth_generate_session_info failed: %s\n",
nt_errstr(pipe_reply.status)));
@@ -335,11 +358,22 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
}
/* setup the session_info on the connection */
- pipe_reply.status = auth_generate_session_info(conn,
- conn->event.ctx,
- conn->lp_ctx,
- server_info,
- &conn->session_info);
+ pipe_reply.status = auth_context_create(conn,
+ conn->event.ctx, conn->msg_ctx,
+ conn->lp_ctx,
+ &auth_context);
+ if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+ DEBUG(2, ("auth_context_create returned "
+ "%s\n", nt_errstr(pipe_reply.status)));
+ goto reply;
+ }
+
+ /* setup the session_info on the connection */
+ pipe_reply.status = auth_context->generate_session_info(conn,
+ auth_context,
+ server_info,
+ &conn->session_info);
+ talloc_free(auth_context);
if (!NT_STATUS_IS_OK(pipe_reply.status)) {
DEBUG(2, ("auth_generate_session_info failed: %s\n",
nt_errstr(pipe_reply.status)));