Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/ruby_smb/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,18 @@ def send_recv(packet, encrypt: false)
break
end unless version == 'SMB1'

# Handle STATUS_NETWORK_SESSION_EXPIRED. The 'net use' client upon receiving this error will automatically attempt
# to re-authenticate, which makes relaying ntlm authentication to multiple targets possible. This block ensures
# ruby_smb behaves in the same manner as 'net use'.
if smb2_header && smb2_header.nt_status == WindowsError::NTStatus::STATUS_NETWORK_SESSION_EXPIRED && !@mech_type.nil?
if @mech_type == :ntlm || @mech_type == :anonymous
session_setup(self.username, self.password, self.domain, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
raw_response = send_recv(packet, encrypt: encrypt) # Retry the request after re-authentication
elsif @mech_type == :kerberos
raise RubySMB::Error::RubySMBError, 'WindowsError::NTStatus::STATUS_NETWORK_SESSION_EXPIRED received, but kerberos authentication is being used, so automatic re-authentication cannot be attempted.'
end
end

self.sequence_counter += 1 if signing_required && !session_key.empty?
# update the SMB2 message ID according to the received Credit Charged
self.smb2_message_id += smb2_header.credit_charge - 1 if smb2_header && self.server_supports_multi_credit
Expand Down
3 changes: 3 additions & 0 deletions lib/ruby_smb/client/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def authenticate
#
# @return [WindowsError::ErrorCode] the status code the server returned
def smb1_anonymous_auth
@mech_type = :anonymous
request = smb1_anonymous_auth_request
raw_response = send_recv(request)
response = smb1_anonymous_auth_response(raw_response)
Expand Down Expand Up @@ -73,6 +74,7 @@ def smb1_anonymous_auth_response(raw_response)
# Handles the SMB1 NTLMSSP 4-way handshake for Authentication and store
# information about the peer/server.
def smb1_authenticate
@mech_type = :ntlm
response = smb1_ntlmssp_negotiate
challenge_packet = smb1_ntlmssp_challenge_packet(response)

Expand Down Expand Up @@ -205,6 +207,7 @@ def smb1_type2_message(response_packet)
# Handles the SMB2 NTLMSSP 4-way handshake for Authentication and store
# information about the peer/server.
def smb2_authenticate
@mech_type = :ntlm
response = smb2_ntlmssp_negotiate
challenge_packet = smb2_ntlmssp_challenge_packet(response)
if @dialect == '0x0311'
Expand Down
Loading