net-ldap 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8d5def02bd0ce6b44457f5c1c7983f8730131a1a7082b3765791b14a0ee576b
4
- data.tar.gz: 41a50fda89f8c8e7a6a1c182e894181d910367a356c67f031dec8072e1544e3e
3
+ metadata.gz: 8f1ae20f7f3f599999e4178becdc139f1aaa81b97021696ab3dd8aa78442ca7f
4
+ data.tar.gz: 7dc05aad5c2d2e6cb2ca9abd22654139fa236cd97d5e16467733f64dd3cf398e
5
5
  SHA512:
6
- metadata.gz: c5ae1310f3668a7f12f4817ede1cdd9310b8b262a40f41639d29e6cf0ba105f3bd6df8f6b892abed3924b03987c18f0e3f0c9bb2c848ed9d33a4662d53783f83
7
- data.tar.gz: f2b4573b1af8db1dd16b9b31202a53edd08829d399fb94bd27cb400b8b1246929dca87744bd5156c4910a4fd53a4c4689a3917258d165e472135fbf50afceb7c
6
+ metadata.gz: e39aaf763a7e29c4f271958a4cc93216afef8705661fc8483c2facf67796a67f1e42d2683efe4bca4b908178d251bb2acb1d2dc3fae8e2c489067e2767d547ce
7
+ data.tar.gz: fb6c7de22a5584d39e9a08bc2b270870cde9c6454af49eeadaccaf4717a6432763bdb0ced4488821b7dfaa9875635e6b4683baf8cd851f48aca743927c54af8a
data/History.rdoc CHANGED
@@ -1,3 +1,20 @@
1
+ === Net::LDAP 0.20.0
2
+ * Update test.yml by @HarlemSquirrel in #433
3
+ * Add `ostruct` as a dependency to the gemspec by @Ivanov-Anton in #432
4
+ * Require Ruby >= 3.0 by @HarlemSquirrel in #435
5
+ * Link to usage examples by @sebbASF in #428
6
+ * Add controls for modify and add operations by @zeroSteiner in #426
7
+ * Add support for ldapwhoami (RFC4532) (now with tests) by @zeroSteiner in #425
8
+ * Update for ruby 3.4 by @HarlemSquirrel in #439
9
+ * Add ruby 3.4 to CI by @hakeem0114 in #438
10
+ * Add support for UTF-8 encoded passwords by @frankwalentowski in #430
11
+
12
+ === Net::LDAP 0.19.0
13
+ * Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412
14
+ * Add in ability for users to specify LDAP controls when conducting searches #411
15
+ * Document connect_timeout in Constructor Details #415
16
+ * Fix openssl error when using multiple hosts #417
17
+
1
18
  === Net::LDAP 0.18.0
2
19
  * Fix escaping of # and space in attrs #408
3
20
  * Add support to use SNI #406
data/README.rdoc CHANGED
@@ -23,7 +23,7 @@ the most recent LDAP RFCs (4510–4519, plus portions of 4520–4532).
23
23
 
24
24
  == Synopsis
25
25
 
26
- See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap] for documentation and usage samples.
26
+ See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap/Net/LDAP] for documentation and usage samples.
27
27
 
28
28
  == Requirements
29
29
 
@@ -20,7 +20,7 @@ module Net
20
20
  require 'ntlm'
21
21
 
22
22
  user, psw = [auth[:username] || auth[:dn], auth[:password]]
23
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
23
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw
24
24
 
25
25
  nego = proc do |challenge|
26
26
  t2_msg = NTLM::Message.parse(challenge)
@@ -30,7 +30,7 @@ module Net
30
30
  def bind(auth)
31
31
  mech, cred, chall = auth[:mechanism], auth[:initial_credential],
32
32
  auth[:challenge_response]
33
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
33
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless mech && cred && chall
34
34
 
35
35
  message_id = @connection.next_msgid
36
36
 
@@ -11,7 +11,7 @@ module Net
11
11
  ["", ""]
12
12
  end
13
13
 
14
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
14
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw
15
15
 
16
16
  message_id = @connection.next_msgid
17
17
  request = [
@@ -30,10 +30,9 @@ class Net::LDAP::Connection #:nodoc:
30
30
  @socket_class = socket_class
31
31
  end
32
32
 
33
- def prepare_socket(server, timeout=nil)
33
+ def prepare_socket(server, timeout=nil, hostname='127.0.0.1')
34
34
  socket = server[:socket]
35
35
  encryption = server[:encryption]
36
- hostname = server[:host]
37
36
 
38
37
  @conn = socket
39
38
  setup_encryption(encryption, timeout, hostname) if encryption
@@ -51,7 +50,7 @@ class Net::LDAP::Connection #:nodoc:
51
50
  errors = []
52
51
  hosts.each do |host, port|
53
52
  begin
54
- prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout)
53
+ prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout, host)
55
54
  if encryption
56
55
  if encryption[:tls_options] &&
57
56
  encryption[:tls_options][:verify_mode] &&
@@ -425,6 +424,7 @@ class Net::LDAP::Connection #:nodoc:
425
424
  # this breaks when calling to_ber. (Can't force binary data to UTF-8)
426
425
  # we have to disable paging (even though server supports it) to get around this...
427
426
 
427
+ user_controls = args.fetch(:controls, [])
428
428
  controls = []
429
429
  controls <<
430
430
  [
@@ -434,7 +434,12 @@ class Net::LDAP::Connection #:nodoc:
434
434
  rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber,
435
435
  ].to_ber_sequence if paged
436
436
  controls << ber_sort if ber_sort
437
- controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
437
+ if controls.empty? && user_controls.empty?
438
+ controls = nil
439
+ else
440
+ controls += user_controls
441
+ controls = controls.to_ber_contextspecific(0)
442
+ end
438
443
 
439
444
  write(request, controls, message_id)
440
445
 
@@ -564,7 +569,12 @@ class Net::LDAP::Connection #:nodoc:
564
569
  ops.to_ber_sequence,
565
570
  ].to_ber_appsequence(Net::LDAP::PDU::ModifyRequest)
566
571
 
567
- write(request, nil, message_id)
572
+ controls = args.fetch(:controls, nil)
573
+ unless controls.nil?
574
+ controls = controls.to_ber_contextspecific(0)
575
+ end
576
+
577
+ write(request, controls, message_id)
568
578
  pdu = queued_read(message_id)
569
579
 
570
580
  if !pdu || pdu.app_tag != Net::LDAP::PDU::ModifyResponse
@@ -636,7 +646,12 @@ class Net::LDAP::Connection #:nodoc:
636
646
  message_id = next_msgid
637
647
  request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(Net::LDAP::PDU::AddRequest)
638
648
 
639
- write(request, nil, message_id)
649
+ controls = args.fetch(:controls, nil)
650
+ unless controls.nil?
651
+ controls = controls.to_ber_contextspecific(0)
652
+ end
653
+
654
+ write(request, controls, message_id)
640
655
  pdu = queued_read(message_id)
641
656
 
642
657
  if !pdu || pdu.app_tag != Net::LDAP::PDU::AddResponse
@@ -688,6 +703,22 @@ class Net::LDAP::Connection #:nodoc:
688
703
  pdu
689
704
  end
690
705
 
706
+ def ldapwhoami
707
+ ext_seq = [Net::LDAP::WhoamiOid.to_ber_contextspecific(0)]
708
+ request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
709
+
710
+ message_id = next_msgid
711
+
712
+ write(request, nil, message_id)
713
+ pdu = queued_read(message_id)
714
+
715
+ if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
716
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
717
+ end
718
+
719
+ pdu
720
+ end
721
+
691
722
  # Internal: Returns a Socket like object used internally to communicate with
692
723
  # LDAP server.
693
724
  #
data/lib/net/ldap/dn.rb CHANGED
@@ -81,7 +81,7 @@ class Net::LDAP::DN
81
81
  value << char
82
82
  when ',' then
83
83
  state = :key
84
- yield key.string.strip, value.string.rstrip
84
+ yield key.string.strip, value.string
85
85
  key = StringIO.new
86
86
  value = StringIO.new;
87
87
  else
@@ -93,7 +93,7 @@ class Net::LDAP::DN
93
93
  when '\\' then state = :value_normal_escape
94
94
  when ',' then
95
95
  state = :key
96
- yield key.string.strip, value.string.rstrip
96
+ yield key.string.strip, value.string
97
97
  key = StringIO.new
98
98
  value = StringIO.new;
99
99
  else value << char
@@ -142,7 +142,7 @@ class Net::LDAP::DN
142
142
  when ' ' then state = :value_end
143
143
  when ',' then
144
144
  state = :key
145
- yield key.string.strip, value.string.rstrip
145
+ yield key.string.strip, value.string
146
146
  key = StringIO.new
147
147
  value = StringIO.new;
148
148
  else raise Net::LDAP::InvalidDNError, "DN badly formed"
@@ -159,7 +159,7 @@ class Net::LDAP::DN
159
159
  when ' ' then state = :value_end
160
160
  when ',' then
161
161
  state = :key
162
- yield key.string.strip, value.string.rstrip
162
+ yield key.string.strip, value.string
163
163
  key = StringIO.new
164
164
  value = StringIO.new;
165
165
  else raise Net::LDAP::InvalidDNError, "DN badly formed"
@@ -172,7 +172,7 @@ class Net::LDAP::DN
172
172
  raise Net::LDAP::InvalidDNError, "DN badly formed" unless
173
173
  [:value, :value_normal, :value_hexstring, :value_end].include? state
174
174
 
175
- yield key.string.strip, value.string.rstrip
175
+ yield key.string.strip, value.string
176
176
  end
177
177
 
178
178
  ##
@@ -28,10 +28,14 @@ class Net::LDAP::Password
28
28
  '{SHA}' + Base64.strict_encode64(Digest::SHA1.digest(str))
29
29
  when :ssha
30
30
  salt = SecureRandom.random_bytes(16)
31
- '{SSHA}' + Base64.strict_encode64(Digest::SHA1.digest(str + salt) + salt)
31
+ digest = Digest::SHA1.new
32
+ digest << str << salt
33
+ '{SSHA}' + Base64.strict_encode64(digest.digest + salt)
32
34
  when :ssha256
33
35
  salt = SecureRandom.random_bytes(16)
34
- '{SSHA256}' + Base64.strict_encode64(Digest::SHA256.digest(str + salt) + salt)
36
+ digest = Digest::SHA256.new
37
+ digest << str << salt
38
+ '{SSHA256}' + Base64.strict_encode64(digest.digest + salt)
35
39
  else
36
40
  raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})"
37
41
  end
data/lib/net/ldap/pdu.rb CHANGED
@@ -194,13 +194,13 @@ class Net::LDAP::PDU
194
194
  # requestValue [1] OCTET STRING OPTIONAL }
195
195
 
196
196
  def parse_extended_response(sequence)
197
- sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
197
+ sequence.length.between?(3, 5) or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
198
198
  @ldap_result = {
199
199
  :resultCode => sequence[0],
200
200
  :matchedDN => sequence[1],
201
201
  :errorMessage => sequence[2],
202
202
  }
203
- @extended_response = sequence[3]
203
+ @extended_response = sequence.length == 3 ? nil : sequence.last
204
204
  end
205
205
  private :parse_extended_response
206
206
 
@@ -1,5 +1,5 @@
1
1
  module Net
2
2
  class LDAP
3
- VERSION = "0.18.0"
3
+ VERSION = "0.20.0"
4
4
  end
5
5
  end
data/lib/net/ldap.rb CHANGED
@@ -311,7 +311,7 @@ class Net::LDAP
311
311
  0 => :array, # RFC-2251 Control and Filter-AND
312
312
  1 => :array, # SearchFilter-OR
313
313
  2 => :array, # SearchFilter-NOT
314
- 3 => :array, # Seach referral
314
+ 3 => :array, # Search referral
315
315
  4 => :array, # unknown use in Microsoft Outlook
316
316
  5 => :array, # SearchFilter-GE
317
317
  6 => :array, # SearchFilter-LE
@@ -325,7 +325,7 @@ class Net::LDAP
325
325
 
326
326
  universal = {
327
327
  constructed: {
328
- 107 => :array, #ExtendedResponse (PasswdModifyResponseValue)
328
+ 107 => :string, # ExtendedResponse
329
329
  },
330
330
  }
331
331
 
@@ -341,6 +341,7 @@ class Net::LDAP
341
341
 
342
342
  StartTlsOid = '1.3.6.1.4.1.1466.20037'
343
343
  PasswdModifyOid = '1.3.6.1.4.1.4203.1.11.1'
344
+ WhoamiOid = '1.3.6.1.4.1.4203.1.11.3'
344
345
 
345
346
  # https://tools.ietf.org/html/rfc4511#section-4.1.9
346
347
  # https://tools.ietf.org/html/rfc4511#appendix-A
@@ -480,6 +481,8 @@ class Net::LDAP
480
481
  # server says it supports them. This is a fix for MS Active Directory
481
482
  # * :instrumentation_service => An object responsible for instrumenting
482
483
  # operations, compatible with ActiveSupport::Notifications' public API.
484
+ # * :connect_timeout => The TCP socket timeout (in seconds) to use when
485
+ # connecting to the LDAP server (default 5 seconds).
483
486
  # * :encryption => specifies the encryption to be used in communicating
484
487
  # with the LDAP server. The value must be a Hash containing additional
485
488
  # parameters, which consists of two keys:
@@ -1198,6 +1201,23 @@ class Net::LDAP
1198
1201
  end
1199
1202
  end
1200
1203
 
1204
+ # Return the authorization identity of the client that issues the
1205
+ # ldapwhoami request. The method does not support any arguments.
1206
+ #
1207
+ # Returns True or False to indicate whether the request was successfull.
1208
+ # The result is available in the extended status information when calling
1209
+ # #get_operation_result.
1210
+ #
1211
+ # ldap.ldapwhoami
1212
+ # puts ldap.get_operation_result.extended_response
1213
+ def ldapwhoami(args = {})
1214
+ instrument "ldapwhoami.net_ldap", args do |payload|
1215
+ @result = use_connection(args, &:ldapwhoami)
1216
+ @result.success? ? @result.extended_response : nil
1217
+ end
1218
+ end
1219
+ alias_method :whoami, :ldapwhoami
1220
+
1201
1221
  # This method is experimental and subject to change. Return the rootDSE
1202
1222
  # record from the LDAP server as a Net::LDAP::Entry, or an empty Entry if
1203
1223
  # the server doesn't return the record.
@@ -1255,10 +1275,10 @@ class Net::LDAP
1255
1275
  rs = search(:ignore_server_caps => true, :base => "",
1256
1276
  :scope => SearchScope_BaseObject,
1257
1277
  :attributes => [:subschemaSubentry])
1258
- return Net::LDAP::Entry.new unless (rs and rs.first)
1278
+ return Net::LDAP::Entry.new unless rs and rs.first
1259
1279
 
1260
1280
  subschema_name = rs.first.subschemasubentry
1261
- return Net::LDAP::Entry.new unless (subschema_name and subschema_name.first)
1281
+ return Net::LDAP::Entry.new unless subschema_name and subschema_name.first
1262
1282
 
1263
1283
  rs = search(:ignore_server_caps => true, :base => subschema_name.first,
1264
1284
  :scope => SearchScope_BaseObject,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francis Cianfrocca
@@ -10,81 +10,38 @@ authors:
10
10
  - Kaspar Schiess
11
11
  - Austin Ziegler
12
12
  - Michael Schaarschmidt
13
- autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2023-04-04 00:00:00.000000000 Z
15
+ date: 2025-08-22 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
- name: flexmock
18
+ name: base64
20
19
  requirement: !ruby/object:Gem::Requirement
21
20
  requirements:
22
- - - "~>"
21
+ - - ">="
23
22
  - !ruby/object:Gem::Version
24
- version: '1.3'
25
- type: :development
23
+ version: '0'
24
+ type: :runtime
26
25
  prerelease: false
27
26
  version_requirements: !ruby/object:Gem::Requirement
28
27
  requirements:
29
- - - "~>"
28
+ - - ">="
30
29
  - !ruby/object:Gem::Version
31
- version: '1.3'
30
+ version: '0'
32
31
  - !ruby/object:Gem::Dependency
33
- name: rake
32
+ name: ostruct
34
33
  requirement: !ruby/object:Gem::Requirement
35
34
  requirements:
36
- - - "~>"
35
+ - - ">="
37
36
  - !ruby/object:Gem::Version
38
- version: 12.3.3
39
- type: :development
37
+ version: '0'
38
+ type: :runtime
40
39
  prerelease: false
41
40
  version_requirements: !ruby/object:Gem::Requirement
42
41
  requirements:
43
- - - "~>"
42
+ - - ">="
44
43
  - !ruby/object:Gem::Version
45
- version: 12.3.3
46
- - !ruby/object:Gem::Dependency
47
- name: rubocop
48
- requirement: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - "~>"
51
- - !ruby/object:Gem::Version
52
- version: '1.48'
53
- type: :development
54
- prerelease: false
55
- version_requirements: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '1.48'
60
- - !ruby/object:Gem::Dependency
61
- name: test-unit
62
- requirement: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - "~>"
65
- - !ruby/object:Gem::Version
66
- version: '3.3'
67
- type: :development
68
- prerelease: false
69
- version_requirements: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - "~>"
72
- - !ruby/object:Gem::Version
73
- version: '3.3'
74
- - !ruby/object:Gem::Dependency
75
- name: byebug
76
- requirement: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - "~>"
79
- - !ruby/object:Gem::Version
80
- version: 9.0.6
81
- type: :development
82
- prerelease: false
83
- version_requirements: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - "~>"
86
- - !ruby/object:Gem::Version
87
- version: 9.0.6
44
+ version: '0'
88
45
  description: |-
89
46
  Net::LDAP for Ruby (also called net-ldap) implements client access for the
90
47
  Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for
@@ -146,7 +103,6 @@ homepage: http://github.com/ruby-ldap/ruby-net-ldap
146
103
  licenses:
147
104
  - MIT
148
105
  metadata: {}
149
- post_install_message:
150
106
  rdoc_options:
151
107
  - "--main"
152
108
  - README.rdoc
@@ -156,15 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
112
  requirements:
157
113
  - - ">="
158
114
  - !ruby/object:Gem::Version
159
- version: 2.0.0
115
+ version: 3.0.0
160
116
  required_rubygems_version: !ruby/object:Gem::Requirement
161
117
  requirements:
162
118
  - - ">="
163
119
  - !ruby/object:Gem::Version
164
120
  version: '0'
165
121
  requirements: []
166
- rubygems_version: 3.4.7
167
- signing_key:
122
+ rubygems_version: 3.6.2
168
123
  specification_version: 4
169
124
  summary: Net::LDAP for Ruby (also called net-ldap) implements client access for the
170
125
  Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing