1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

s3:smbd: move negprot related globals to struct smbd_server_connection

metze
This commit is contained in:
Stefan Metzmacher 2009-05-26 12:48:58 +02:00
parent f20ded603b
commit e16e7146b3
9 changed files with 96 additions and 61 deletions

View File

@ -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,
@ -74,12 +75,14 @@ static NTSTATUS pass_check_smb(const char *smb_name,
auth_serversupplied_info *server_info = NULL;
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;
}
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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,10 +318,12 @@ 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) {
@ -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"));

View File

@ -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: "

View File

@ -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) {
/*

View File

@ -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();

View File

@ -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);
}