diff options
-rw-r--r-- | source3/auth/auth_compat.c | 26 | ||||
-rw-r--r-- | source3/include/proto.h | 3 | ||||
-rw-r--r-- | source3/smbd/globals.c | 5 | ||||
-rw-r--r-- | source3/smbd/globals.h | 12 | ||||
-rw-r--r-- | source3/smbd/negprot.c | 69 | ||||
-rw-r--r-- | source3/smbd/password.c | 18 | ||||
-rw-r--r-- | source3/smbd/reply.c | 3 | ||||
-rw-r--r-- | source3/smbd/server.c | 6 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 15 |
9 files changed, 96 insertions, 61 deletions
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index 925c0d4f815..d8087e65887 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 81d254f1ffb..8726e979271 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 73a3a15ab8c..8126989bbf1 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 333f4f12a89..46c52fea120 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 6d15f486df3..4e14ee8aad4 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 076965e783c..460cba35a0f 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 8657bd6e180..f6d5f11f13a 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 685b26fa1ae..b357b97f8a1 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 e82de0ae98c..8a517994cc4 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); } |