summaryrefslogtreecommitdiff
path: root/source3/smbd/reply.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2001-09-26 13:55:59 +0000
committerAndrew Bartlett <abartlet@samba.org>2001-09-26 13:55:59 +0000
commit41821943daef5a4fd077e38068539ae4e24121b3 (patch)
tree3694b89ec3ea0c5fb67c97a112940b2a16210f26 /source3/smbd/reply.c
parent865467c82f39a98afa3c65f25b7e24137f904e93 (diff)
downloadsamba-41821943daef5a4fd077e38068539ae4e24121b3.tar.gz
samba-41821943daef5a4fd077e38068539ae4e24121b3.tar.bz2
samba-41821943daef5a4fd077e38068539ae4e24121b3.zip
Kill of the reply.c end of the workstaion trust account mess.
Fix the NT errror codes, this time in line with WinXP/2k. - Return the normal error codes, expect for bad user/bad password. These map to logon failure, as a quick security hack. We follow suit. Simplfy some of the password extraction code, the auth subsytem has the intelegence to sort this stuff out, no need to do it here. Move to 'global_encrypted_passwords_negotiated' to determine the use of unencrypted hacks, replacing the current mess. Andrew Bartlett (This used to be commit c04f063573c61d8ef3f43815bbb9b6b076dc23eb)
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r--source3/smbd/reply.c198
1 files changed, 43 insertions, 155 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 572ed90b32..dbd149afcf 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -43,6 +43,7 @@ uint32 global_client_caps = 0;
unsigned int smb_echo_count = 0;
extern fstring remote_machine;
+extern BOOL global_encrypted_passwords_negotiated;
/****************************************************************************
report a possible attack via the password buffer overflow bug
@@ -246,7 +247,6 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
passlen = strlen(password);
}
-
/*
* the service name can be either: \\server\share
* or share directly like on the DELL PowerVault 705
@@ -374,107 +374,6 @@ int reply_ioctl(connection_struct *conn,
}
/****************************************************************************
- This function breaks the authentication split. It needs sorting out.
- I can't see why we can't hadle this INSIDE the check_password, as in then
- end all it does it spit out an nt_status code.
- ****************************************************************************/
-/****************************************************************************
- always return an error: it's just a matter of which one...
- ****************************************************************************/
-static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
- char *smb_passwd, int smb_passlen,
- char *smb_nt_passwd, int smb_nt_passlen)
-{
- /* check if trust account exists */
- SAM_ACCOUNT *sam_trust_acct = NULL;
- uint16 acct_ctrl;
- BOOL ret;
- auth_usersupplied_info user_info;
- auth_serversupplied_info server_info;
- AUTH_STR domain, smb_username, wksta_name;
-
- ZERO_STRUCT(user_info);
- ZERO_STRUCT(server_info);
- ZERO_STRUCT(domain);
- ZERO_STRUCT(smb_username);
- ZERO_STRUCT(wksta_name);
-
- domain.str = lp_workgroup();
- domain.len = strlen(domain.str);
-
- user_info.requested_domain = domain;
- user_info.domain = domain;
-
- smb_username.str = user;
- smb_username.len = strlen(smb_username.str);
-
- user_info.unix_username = smb_username; /* For the time-being */
- user_info.smb_username = smb_username;
-
- user_info.wksta_name = wksta_name;
-
- user_info.lm_resp.buffer = (uint8 *)smb_passwd;
- user_info.lm_resp.len = smb_passlen;
- user_info.nt_resp.buffer = (uint8 *)smb_nt_passwd;
- user_info.nt_resp.len = smb_nt_passlen;
-
- if (!last_challenge(user_info.chal)) {
- DEBUG(1,("smb_password_ok: no challenge done - password failed\n"));
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- pdb_init_sam(&sam_trust_acct);
-
- if (lp_security() == SEC_USER) {
- ret = pdb_getsampwnam(sam_trust_acct, user);
- } else {
- DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
- pdb_free_sam(sam_trust_acct);
- return(ERROR_NT(NT_STATUS_LOGON_FAILURE));
- }
-
- if (ret == False) {
- /* lkclXXXX: workstation entry doesn't exist */
- DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
- pdb_free_sam(sam_trust_acct);
- return(ERROR_NT(NT_STATUS_NO_SUCH_USER));
- } else {
- if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
- DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
- pdb_free_sam(sam_trust_acct);
- return(ERROR_NT(NT_STATUS_LOGON_FAILURE));
- }
-
- if (!NT_STATUS_IS_OK(smb_password_ok(sam_trust_acct, &user_info, &server_info))) {
- DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
- pdb_free_sam(sam_trust_acct);
- return(ERROR_NT(NT_STATUS_LOGON_FAILURE));
- }
-
- acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct);
- pdb_free_sam(sam_trust_acct);
- if (acct_ctrl & ACB_DOMTRUST) {
- DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
- return(ERROR_NT(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
- }
-
- if (acct_ctrl & ACB_SVRTRUST) {
- DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
- return(ERROR_NT(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
- }
-
- if (acct_ctrl & ACB_WSTRUST) {
- DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
- return(ERROR_NT(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
- }
- }
-
- /* don't know what to do: indicate logon failure */
- return(ERROR_NT(NT_STATUS_LOGON_FAILURE));
-}
-
-
-/****************************************************************************
reply to a session setup command
****************************************************************************/
@@ -496,14 +395,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
fstring native_lanman;
BOOL guest=False;
static BOOL done_sesssetup = False;
- BOOL doencrypt = lp_encrypted_passwords();
+ BOOL doencrypt = global_encrypted_passwords_negotiated;
START_PROFILE(SMBsesssetupX);
- ZERO_STRUCT(smb_apasswd);
- ZERO_STRUCT(smb_ntpasswd);
+ *smb_apasswd = *smb_ntpasswd = 0;
smb_bufsize = SVAL(inbuf,smb_vwv2);
-
+
if (Protocol < PROTOCOL_NT1) {
smb_apasslen = SVAL(inbuf,smb_vwv7);
if (smb_apasslen > MAX_PASS_LEN) {
@@ -513,7 +411,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
srvstr_pull(inbuf, user, smb_buf(inbuf)+smb_apasslen, sizeof(user), -1, STR_TERMINATE);
-
+
if (!doencrypt && (lp_security() != SEC_SERVER)) {
smb_apasslen = strlen(smb_apasswd);
}
@@ -585,27 +483,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
}
}
- if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
- /* Save the lanman2 password and the NT md4 password. */
- smb_apasslen = passlen1;
- memcpy(smb_apasswd,p,smb_apasslen);
- smb_apasswd[smb_apasslen] = 0;
- smb_ntpasslen = passlen2;
- memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
- smb_ntpasswd[smb_ntpasslen] = 0;
- } else {
- /* we use the first password that they gave */
- smb_apasslen = passlen1;
- StrnCpy(smb_apasswd,p,smb_apasslen);
-
- /* trim the password */
- smb_apasslen = strlen(smb_apasswd);
+ /* Save the lanman2 password and the NT md4 password. */
+ smb_apasslen = passlen1;
+ memcpy(smb_apasswd,p,smb_apasslen);
- /* wfwg sometimes uses a space instead of a null */
- if (strequal(smb_apasswd," ")) {
- smb_apasslen = 0;
- *smb_apasswd = 0;
- }
+ smb_ntpasslen = passlen2;
+ memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
+
+ if (smb_apasslen != 24 || !doencrypt) {
+ /* trim the password */
+ smb_apasslen = strlen(smb_apasswd);
+
+ /* wfwg sometimes uses a space instead of a null */
+ if (strequal(smb_apasswd," ")) {
+ smb_apasslen = 0;
+ *smb_apasswd = 0;
+ }
}
p += passlen1 + passlen2;
@@ -640,18 +533,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
}
- DEBUG(3,("sesssetupX:name=[%s]@[%s]\n",user, remote_machine));
-
- /* If name ends in $ then I think it's asking about whether a */
- /* computer with that name (minus the $) has access. For now */
- /* say yes to everything ending in $. */
-
- if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
- END_PROFILE(SMBsesssetupX);
- return session_trust_account(conn, inbuf, outbuf, user,
- smb_apasswd, smb_apasslen,
- smb_ntpasswd, smb_ntpasslen);
- }
+ DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",user, domain, remote_machine));
if (done_sesssetup && lp_restrict_anonymous()) {
/* tests show that even if browsing is done over already validated connections
@@ -731,21 +613,27 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if NT_STATUS_IS_OK(nt_status) {
- } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)
- && lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) {
- DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
- pstrcpy(user,lp_guestaccount(-1));
- guest = True;
-
- } else if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)
- || NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER))
- && (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
- pstrcpy(user,lp_guestaccount(-1));
- DEBUG(3,("Registered username %s for guest access\n",user));
- guest = True;
-
+ } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+ if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
+ (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
+ DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain));
+ pstrcpy(user,lp_guestaccount(-1));
+ guest = True;
+ } else {
+ /* Match WinXP and don't give the game away */
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
+ } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
+ pstrcpy(user,lp_guestaccount(-1));
+ DEBUG(3,("Registered username %s for guest access\n",user));
+ guest = True;
+ } else {
+ /* Match WinXP and don't give the game away */
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
} else {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ return ERROR_NT(nt_status);
}
}
@@ -792,10 +680,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest, full_name);
+ sess_vuid = register_vuid(uid,gid,user,orig_user,domain,guest, full_name);
if (sess_vuid == -1) {
- return ERROR_DOS(ERRDOS,ERRnoaccess);
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}