Skip to content

Commit 157f579

Browse files
Merge pull request #292 from jheysel-r7/fix/lib/smb_relay_ruby_client_support
Reauth after STATUS_NETWORK_SESSION_EXPIRED
2 parents 727a0ff + 2d991f1 commit 157f579

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

lib/ruby_smb/client.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,18 @@ def send_recv(packet, encrypt: false)
517517
break
518518
end unless version == 'SMB1'
519519

520+
# Handle STATUS_NETWORK_SESSION_EXPIRED. The 'net use' client upon receiving this error will automatically attempt
521+
# to re-authenticate, which makes relaying ntlm authentication to multiple targets possible. This block ensures
522+
# ruby_smb behaves in the same manner as 'net use'.
523+
if smb2_header && smb2_header.nt_status == WindowsError::NTStatus::STATUS_NETWORK_SESSION_EXPIRED && !@mech_type.nil?
524+
if @mech_type == :ntlm || @mech_type == :anonymous
525+
session_setup(self.username, self.password, self.domain, local_workstation: self.local_workstation, ntlm_flags: NTLM::DEFAULT_CLIENT_FLAGS)
526+
raw_response = send_recv(packet, encrypt: encrypt) # Retry the request after re-authentication
527+
elsif @mech_type == :kerberos
528+
raise RubySMB::Error::RubySMBError, 'WindowsError::NTStatus::STATUS_NETWORK_SESSION_EXPIRED received, but kerberos authentication is being used, so automatic re-authentication cannot be attempted.'
529+
end
530+
end
531+
520532
self.sequence_counter += 1 if signing_required && !session_key.empty?
521533
# update the SMB2 message ID according to the received Credit Charged
522534
self.smb2_message_id += smb2_header.credit_charge - 1 if smb2_header && self.server_supports_multi_credit

lib/ruby_smb/client/authentication.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def authenticate
3131
#
3232
# @return [WindowsError::ErrorCode] the status code the server returned
3333
def smb1_anonymous_auth
34+
@mech_type = :anonymous
3435
request = smb1_anonymous_auth_request
3536
raw_response = send_recv(request)
3637
response = smb1_anonymous_auth_response(raw_response)
@@ -73,6 +74,7 @@ def smb1_anonymous_auth_response(raw_response)
7374
# Handles the SMB1 NTLMSSP 4-way handshake for Authentication and store
7475
# information about the peer/server.
7576
def smb1_authenticate
77+
@mech_type = :ntlm
7678
response = smb1_ntlmssp_negotiate
7779
challenge_packet = smb1_ntlmssp_challenge_packet(response)
7880

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

0 commit comments

Comments
 (0)