Skip to content

Commit ed84f2b

Browse files
committed
Merge pull request #116 from jch/connection-write-request
Add private Net::LDAP::Connection#write_request
2 parents cf39451 + b807113 commit ed84f2b

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

lib/net/ldap/connection.rb

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def initialize(server)
1010
@instrumentation_service = server[:instrumentation_service]
1111

1212
begin
13-
@conn = TCPSocket.new(server[:host], server[:port])
13+
@conn = server[:socket] || TCPSocket.new(server[:host], server[:port])
1414
rescue SocketError
1515
raise Net::LDAP::LdapError, "No such address or other socket error."
1616
rescue Errno::ECONNREFUSED
@@ -87,10 +87,8 @@ def setup_encryption(args)
8787
# additional branches requiring server validation and peer certs, etc.
8888
# go here.
8989
when :start_tls
90-
msgid = next_msgid.to_ber
9190
request = [Net::LDAP::StartTlsOid.to_ber_contextspecific(0)].to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
92-
request_pkt = [msgid, request].to_ber_sequence
93-
write request_pkt
91+
write(request)
9492
be = read
9593
raise Net::LDAP::LdapError, "no start_tls result" if be.nil?
9694
pdu = Net::LDAP::PDU.new(be)
@@ -130,14 +128,17 @@ def read(syntax = Net::LDAP::AsnSyntax)
130128
end
131129
private :read
132130

133-
# Internal: Writes the given packet to the configured connection.
131+
# Internal: Write a BER formatted packet with the next message id to the
132+
# configured connection.
134133
#
135-
# - packet: the BER data packet to write on the socket.
134+
# - request: required BER formatted request
135+
# - controls: optional BER formatted controls
136136
#
137137
# Returns the return value from writing to the connection, which in some
138138
# cases is the Integer number of bytes written to the socket.
139-
def write(packet)
139+
def write(request, controls = nil)
140140
instrument "write.net_ldap_connection" do |payload|
141+
packet = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
141142
payload[:content_length] = @conn.write(packet)
142143
end
143144
end
@@ -176,11 +177,9 @@ def bind_simple(auth)
176177

177178
raise Net::LDAP::LdapError, "Invalid binding information" unless (user && psw)
178179

179-
msgid = next_msgid.to_ber
180180
request = [LdapVersion.to_ber, user.to_ber,
181181
psw.to_ber_contextspecific(0)].to_ber_appsequence(0)
182-
request_pkt = [msgid, request].to_ber_sequence
183-
write request_pkt
182+
write(request)
184183

185184
(be = read and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
186185

@@ -215,11 +214,9 @@ def bind_sasl(auth)
215214

216215
n = 0
217216
loop {
218-
msgid = next_msgid.to_ber
219217
sasl = [mech.to_ber, cred.to_ber].to_ber_contextspecific(3)
220218
request = [LdapVersion.to_ber, "".to_ber, sasl].to_ber_appsequence(0)
221-
request_pkt = [msgid, request].to_ber_sequence
222-
write request_pkt
219+
write(request)
223220

224221
(be = read and pdu = Net::LDAP::PDU.new(be)) or raise Net::LDAP::LdapError, "no bind result"
225222
return pdu unless pdu.result_code == 14 # saslBindInProgress
@@ -393,8 +390,7 @@ def search(args = {})
393390
controls << sort_control if sort_control
394391
controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
395392

396-
pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
397-
write pkt
393+
write(request, controls)
398394

399395
result_pdu = nil
400396
controls = []
@@ -502,8 +498,7 @@ def modify(args)
502498
ops = self.class.modify_ops args[:operations]
503499
request = [ modify_dn.to_ber,
504500
ops.to_ber_sequence ].to_ber_appsequence(6)
505-
pkt = [ next_msgid.to_ber, request ].to_ber_sequence
506-
write pkt
501+
write(request)
507502

508503
(be = read) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == Net::LDAP::PDU::ModifyResponse) or raise Net::LDAP::LdapError, "response missing or invalid"
509504

@@ -525,8 +520,7 @@ def add(args)
525520
}
526521

527522
request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(8)
528-
pkt = [next_msgid.to_ber, request].to_ber_sequence
529-
write pkt
523+
write(request)
530524

531525
(be = read) &&
532526
(pdu = Net::LDAP::PDU.new(be)) &&
@@ -548,8 +542,7 @@ def rename(args)
548542
request = [old_dn.to_ber, new_rdn.to_ber, delete_attrs.to_ber]
549543
request << new_superior.to_ber_contextspecific(0) unless new_superior == nil
550544

551-
pkt = [next_msgid.to_ber, request.to_ber_appsequence(12)].to_ber_sequence
552-
write pkt
545+
write(request.to_ber_appsequence(12))
553546

554547
(be = read) &&
555548
(pdu = Net::LDAP::PDU.new( be )) && (pdu.app_tag == Net::LDAP::PDU::ModifyRDNResponse) or
@@ -565,8 +558,7 @@ def delete(args)
565558
dn = args[:dn] or raise "Unable to delete empty DN"
566559
controls = args.include?(:control_codes) ? args[:control_codes].to_ber_control : nil #use nil so we can compact later
567560
request = dn.to_s.to_ber_application_string(10)
568-
pkt = [next_msgid.to_ber, request, controls].compact.to_ber_sequence
569-
write pkt
561+
write(request, controls)
570562

571563
(be = read) && (pdu = Net::LDAP::PDU.new(be)) && (pdu.app_tag == Net::LDAP::PDU::DeleteResponse) or raise Net::LDAP::LdapError, "response missing or invalid"
572564

test/test_ldap_connection.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ def test_modify_ops_replace
4242
expected = [ "0#\n\x01\x020\x1E\x04\x04mail1\x16\x04\x14testuser@example.com" ]
4343
assert_equal(expected, result)
4444
end
45+
46+
def test_write
47+
mock = flexmock("socket")
48+
mock.should_receive(:write).with([1.to_ber, "request"].to_ber_sequence).and_return(true)
49+
conn = Net::LDAP::Connection.new(:socket => mock)
50+
conn.send(:write, "request")
51+
end
52+
53+
def test_write_with_controls
54+
mock = flexmock("socket")
55+
mock.should_receive(:write).with([1.to_ber, "request", "controls"].to_ber_sequence).and_return(true)
56+
conn = Net::LDAP::Connection.new(:socket => mock)
57+
conn.send(:write, "request", "controls")
58+
end
59+
60+
def test_write_increments_msgid
61+
mock = flexmock("socket")
62+
mock.should_receive(:write).with([1.to_ber, "request1"].to_ber_sequence).and_return(true)
63+
mock.should_receive(:write).with([2.to_ber, "request2"].to_ber_sequence).and_return(true)
64+
conn = Net::LDAP::Connection.new(:socket => mock)
65+
conn.send(:write, "request1")
66+
conn.send(:write, "request2")
67+
end
4568
end
4669

4770

0 commit comments

Comments
 (0)