summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_compat.c26
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/smbd/globals.c5
-rw-r--r--source3/smbd/globals.h12
-rw-r--r--source3/smbd/negprot.c69
-rw-r--r--source3/smbd/password.c18
-rw-r--r--source3/smbd/reply.c3
-rw-r--r--source3/smbd/server.c6
-rw-r--r--source3/smbd/sesssetup.c15
9 files changed, 96 insertions, 61 deletions
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c
index 925c0d4f81..d8087e6588 100644
--- a/source3/auth/auth_compat.c
+++ b/source3/auth/auth_compat.c
@@ -62,7 +62,8 @@ NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_pass
return nt_status;
}
-static NTSTATUS pass_check_smb(const char *smb_name,
+static NTSTATUS pass_check_smb(struct auth_context *actx,
+ const char *smb_name,
const char *domain,
DATA_BLOB lm_pwd,
DATA_BLOB nt_pwd,
@@ -72,14 +73,16 @@ static NTSTATUS pass_check_smb(const char *smb_name,
{
NTSTATUS nt_status;
auth_serversupplied_info *server_info = NULL;
- if (encrypted) {
+ if (encrypted) {
auth_usersupplied_info *user_info = NULL;
+ if (actx == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
make_user_info_for_reply_enc(&user_info, smb_name,
domain,
lm_pwd,
nt_pwd);
- nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
- user_info, &server_info);
+ nt_status = actx->check_ntlm_password(actx, user_info, &server_info);
free_user_info(&user_info);
} else {
nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info);
@@ -93,11 +96,12 @@ check if a username/password pair is ok via the auth subsystem.
return True if the password is correct, False otherwise
****************************************************************************/
-bool password_ok(const char *smb_name, DATA_BLOB password_blob)
+bool password_ok(struct auth_context *actx, bool global_encrypted,
+ const char *smb_name, DATA_BLOB password_blob)
{
DATA_BLOB null_password = data_blob_null;
- bool encrypted = (global_encrypted_passwords_negotiated && (password_blob.length == 24 || password_blob.length > 46));
+ bool encrypted = (global_encrypted && (password_blob.length == 24 || password_blob.length > 46));
if (encrypted) {
/*
@@ -106,23 +110,23 @@ bool password_ok(const char *smb_name, DATA_BLOB password_blob)
* Vista sends NTLMv2 here - we need to try the client given workgroup.
*/
if (get_session_workgroup()) {
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, get_session_workgroup(), null_password, password_blob, null_password, encrypted))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, get_session_workgroup(), null_password, password_blob, null_password, encrypted))) {
return True;
}
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, get_session_workgroup(), password_blob, null_password, null_password, encrypted))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, get_session_workgroup(), password_blob, null_password, null_password, encrypted))) {
return True;
}
}
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
return True;
}
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
return True;
}
} else {
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
return True;
}
}
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 81d254f1ff..8726e97927 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -39,7 +39,8 @@ NTSTATUS auth_builtin_init(void);
/* The following definitions come from auth/auth_compat.c */
NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info);
-bool password_ok(const char *smb_name, DATA_BLOB password_blob);
+bool password_ok(struct auth_context *actx, bool global_encrypted,
+ const char *smb_name, DATA_BLOB password_blob);
/* The following definitions come from auth/auth_domain.c */
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 73a3a15ab8..8126989bbf 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -93,11 +93,6 @@ char *last_to = NULL;
struct msg_state *smbd_msg_state = NULL;
-bool global_encrypted_passwords_negotiated = false;
-bool global_spnego_negotiated = false;
-struct auth_context *negprot_global_auth_context = NULL;
-bool done_negprot = false;
-
bool logged_ioctl_message = false;
/* users from session setup */
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 333f4f12a8..46c52fea12 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -91,11 +91,6 @@ extern char *last_to;
struct msg_state;
extern struct msg_state *smbd_msg_state;
-extern bool global_encrypted_passwords_negotiated;
-extern bool global_spnego_negotiated;
-extern struct auth_context *negprot_global_auth_context;
-extern bool done_negprot;
-
extern bool logged_ioctl_message;
/* users from session setup */
@@ -330,6 +325,13 @@ struct smbd_server_connection {
struct {
struct fd_event *fde;
uint64_t num_requests;
+ struct {
+ bool encrypted_passwords;
+ bool spnego;
+ struct auth_context *auth_context;
+ bool done;
+ } negprot;
+
struct smb_signing_state *signing_state;
/* List to store partial SPNEGO auth fragments. */
struct pending_auth_data *pd_list;
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 6d15f486df..4e14ee8aad 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -27,22 +27,28 @@ extern enum protocol_types Protocol;
static void get_challenge(uint8 buff[8])
{
NTSTATUS nt_status;
+ struct smbd_server_connection *sconn = smbd_server_conn;
/* We might be called more than once, multiple negprots are
* permitted */
- if (negprot_global_auth_context) {
- DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
- (negprot_global_auth_context->free)(&negprot_global_auth_context);
+ if (sconn->smb1.negprot.auth_context) {
+ DEBUG(3, ("get challenge: is this a secondary negprot? "
+ "sconn->negprot.auth_context is non-NULL!\n"));
+ sconn->smb1.negprot.auth_context->free(
+ &sconn->smb1.negprot.auth_context);
}
DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
- if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
- DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
+ nt_status = make_auth_context_subsystem(
+ &sconn->smb1.negprot.auth_context);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("make_auth_context_subsystem returned %s",
+ nt_errstr(nt_status)));
smb_panic("cannot make_negprot_global_auth_context!");
}
DEBUG(10, ("get challenge: getting challenge\n"));
- negprot_global_auth_context->get_ntlm_challenge(
- negprot_global_auth_context, buff);
+ sconn->smb1.negprot.auth_context->get_ntlm_challenge(
+ sconn->smb1.negprot.auth_context, buff);
}
/****************************************************************************
@@ -86,20 +92,23 @@ static void reply_lanman1(struct smb_request *req, uint16 choice)
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
int secword=0;
time_t t = time(NULL);
+ struct smbd_server_connection *sconn = smbd_server_conn;
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
+ sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
- if (lp_security()>=SEC_USER)
+ if (lp_security()>=SEC_USER) {
secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
+ }
+ if (sconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
+ }
- reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
+ reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
SSVAL(req->outbuf,smb_vwv0,choice);
SSVAL(req->outbuf,smb_vwv1,secword);
/* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
+ if (sconn->smb1.negprot.encrypted_passwords) {
get_challenge((uint8 *)smb_buf(req->outbuf));
SSVAL(req->outbuf,smb_vwv11, 8);
}
@@ -130,22 +139,25 @@ static void reply_lanman2(struct smb_request *req, uint16 choice)
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
int secword=0;
time_t t = time(NULL);
+ struct smbd_server_connection *sconn = smbd_server_conn;
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
+ sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
- if (lp_security()>=SEC_USER)
+ if (lp_security()>=SEC_USER) {
secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
+ }
+ if (sconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
+ }
- reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
+ reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
SSVAL(req->outbuf,smb_vwv0,choice);
SSVAL(req->outbuf,smb_vwv1,secword);
SIVAL(req->outbuf,smb_vwv6,sys_getpid());
/* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
+ if (sconn->smb1.negprot.encrypted_passwords) {
get_challenge((uint8 *)smb_buf(req->outbuf));
SSVAL(req->outbuf,smb_vwv11, 8);
}
@@ -180,8 +192,9 @@ DATA_BLOB negprot_spnego(void)
OID_NTLMSSP,
NULL};
const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
+ struct smbd_server_connection *sconn = smbd_server_conn;
- global_spnego_negotiated = True;
+ sconn->smb1.negprot.spnego = true;
memset(guid, '\0', sizeof(guid));
@@ -250,8 +263,9 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
bool negotiate_spnego = False;
time_t t = time(NULL);
ssize_t ret;
+ struct smbd_server_connection *sconn = smbd_server_conn;
- global_encrypted_passwords_negotiated = lp_encrypted_passwords();
+ sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
/* Check the flags field to see if this is Vista.
WinXP sets it and Vista does not. But we have to
@@ -270,7 +284,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
/* do spnego in user level security if the client
supports it and we can do encrypted passwords */
- if (global_encrypted_passwords_negotiated &&
+ if (sconn->smb1.negprot.encrypted_passwords &&
(lp_security() != SEC_SHARE) &&
lp_use_spnego() &&
(req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
@@ -304,11 +318,13 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
if (lp_host_msdfs())
capabilities |= CAP_DFS;
- if (lp_security() >= SEC_USER)
+ if (lp_security() >= SEC_USER) {
secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- if (global_encrypted_passwords_negotiated)
+ }
+ if (sconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
-
+ }
+
if (lp_server_signing()) {
if (lp_security() >= SEC_USER) {
secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
@@ -342,7 +358,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
p = q = smb_buf(req->outbuf);
if (!negotiate_spnego) {
/* Create a token value and add it to the outgoing packet. */
- if (global_encrypted_passwords_negotiated) {
+ if (sconn->smb1.negprot.encrypted_passwords) {
uint8 chal[8];
/* note that we do not send a challenge at all if
we are using plaintext */
@@ -511,14 +527,15 @@ void reply_negprot(struct smb_request *req)
char **cliprotos;
int i;
size_t converted_size;
+ struct smbd_server_connection *sconn = smbd_server_conn;
START_PROFILE(SMBnegprot);
- if (done_negprot) {
+ if (sconn->smb1.negprot.done) {
END_PROFILE(SMBnegprot);
exit_server_cleanly("multiple negprot's are not permitted");
}
- done_negprot = True;
+ sconn->smb1.negprot.done = true;
if (req->buflen == 0) {
DEBUG(0, ("negprot got no protocols\n"));
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 076965e783..460cba35a0 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -581,11 +581,14 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
#ifdef HAVE_NETGROUP
{
char *host, *user, *domain;
+ struct smbd_server_connection *sconn = smbd_server_conn;
+ struct auth_context *actx = sconn->smb1.negprot.auth_context;
+ bool enc = sconn->smb1.negprot.encrypted_passwords;
setnetgrent(group);
while (getnetgrent(&host, &user, &domain)) {
if (user) {
if (user_ok(user, snum) &&
- password_ok(user,password)) {
+ password_ok(actx, enc, user,password)) {
endnetgrent();
return(user);
}
@@ -598,6 +601,10 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
#ifdef HAVE_GETGRENT
{
struct group *gptr;
+ struct smbd_server_connection *sconn = smbd_server_conn;
+ struct auth_context *actx = sconn->smb1.negprot.auth_context;
+ bool enc = sconn->smb1.negprot.encrypted_passwords;
+
setgrent();
while ((gptr = (struct group *)getgrent())) {
if (strequal(gptr->gr_name,group))
@@ -646,7 +653,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum)
member = member_list;
while (*member) {
if (user_ok(member,snum) &&
- password_ok(member,password)) {
+ password_ok(actx, enc, member,password)) {
char *name = talloc_strdup(talloc_tos(),
member);
SAFE_FREE(member_list);
@@ -678,6 +685,9 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,
bool *guest)
{
bool ok = False;
+ struct smbd_server_connection *sconn = smbd_server_conn;
+ struct auth_context *actx = sconn->smb1.negprot.auth_context;
+ bool enc = sconn->smb1.negprot.encrypted_passwords;
#ifdef DEBUG_PASSWORD
DEBUG(100,("authorise_login: checking authorisation on "
@@ -722,7 +732,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,
if (!user_ok(user2,snum))
continue;
- if (password_ok(user2,password)) {
+ if (password_ok(actx, enc, user2,password)) {
ok = True;
fstrcpy(user,user2);
DEBUG(3,("authorise_login: ACCEPTED: session "
@@ -770,7 +780,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password,
fstring user2;
fstrcpy(user2,auser);
if (user_ok(user2,snum) &&
- password_ok(user2,password)) {
+ password_ok(actx, enc, user2,password)) {
ok = True;
fstrcpy(user,user2);
DEBUG(3,("authorise_login: ACCEPTED: "
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 8657bd6e18..f6d5f11f13 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -685,6 +685,7 @@ void reply_tcon_and_X(struct smb_request *req)
char *path = NULL;
const char *p, *q;
uint16 tcon_flags;
+ struct smbd_server_connection *sconn = smbd_server_conn;
START_PROFILE(SMBtconX);
@@ -710,7 +711,7 @@ void reply_tcon_and_X(struct smb_request *req)
return;
}
- if (global_encrypted_passwords_negotiated) {
+ if (sconn->smb1.negprot.encrypted_passwords) {
password = data_blob_talloc(talloc_tos(), req->buf, passlen);
if (lp_security() == SEC_SHARE) {
/*
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 685b26fa1a..b357b97f8a 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -785,6 +785,7 @@ static void exit_server_common(enum server_exit_reason how,
const char *const reason)
{
bool had_open_conn;
+ struct smbd_server_connection *sconn = smbd_server_conn;
if (!exit_firsttime)
exit(0);
@@ -792,8 +793,9 @@ static void exit_server_common(enum server_exit_reason how,
change_to_root_user();
- if (negprot_global_auth_context) {
- (negprot_global_auth_context->free)(&negprot_global_auth_context);
+ if (sconn && sconn->smb1.negprot.auth_context) {
+ struct auth_context *a = sconn->smb1.negprot.auth_context;
+ a->free(&sconn->smb1.negprot.auth_context);
}
had_open_conn = conn_close_all();
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index e82de0ae98..8a517994cc 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1388,8 +1388,9 @@ void reply_sesssetup_and_X(struct smb_request *req)
uint16 smb_flag2 = req->flags2;
NTSTATUS nt_status;
+ struct smbd_server_connection *sconn = smbd_server_conn;
- bool doencrypt = global_encrypted_passwords_negotiated;
+ bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
START_PROFILE(SMBsesssetupX);
@@ -1404,7 +1405,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
if (req->wct == 12 &&
(req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
- if (!global_spnego_negotiated) {
+ if (!sconn->smb1.negprot.spnego) {
DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt "
"at SPNEGO session setup when it was not "
"negotiated.\n"));
@@ -1619,7 +1620,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
domain, user, get_remote_machine_name()));
if (*user) {
- if (global_spnego_negotiated) {
+ if (sconn->smb1.negprot.spnego) {
/* This has to be here, because this is a perfectly
* valid behaviour for guest logons :-( */
@@ -1660,7 +1661,9 @@ void reply_sesssetup_and_X(struct smb_request *req)
nt_status = check_guest_password(&server_info);
} else if (doencrypt) {
- if (!negprot_global_auth_context) {
+ struct auth_context *negprot_auth_context = NULL;
+ negprot_auth_context = sconn->smb1.negprot.auth_context;
+ if (!negprot_auth_context) {
DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted "
"session setup without negprot denied!\n"));
reply_nterror(req, nt_status_squash(
@@ -1672,8 +1675,8 @@ void reply_sesssetup_and_X(struct smb_request *req)
domain,
lm_resp, nt_resp);
if (NT_STATUS_IS_OK(nt_status)) {
- nt_status = negprot_global_auth_context->check_ntlm_password(
- negprot_global_auth_context,
+ nt_status = negprot_auth_context->check_ntlm_password(
+ negprot_auth_context,
user_info,
&server_info);
}