mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3:smbd: move negprot related globals to struct smbd_server_connection
metze
This commit is contained in:
parent
f20ded603b
commit
e16e7146b3
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -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: "
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user