From 9c8525c1b852ffc0bd62295195bb711022527d50 Mon Sep 17 00:00:00 2001 From: gwillcox-r7 Date: Tue, 6 Dec 2022 23:03:47 -0600 Subject: [PATCH 01/22] Add in ability for users to specify LDAP controls when conducting searches --- lib/net/ldap/connection.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index be0db04b..48dd7af3 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -425,6 +425,7 @@ def search(args = nil) # this breaks when calling to_ber. (Can't force binary data to UTF-8) # we have to disable paging (even though server supports it) to get around this... + controls_temp = args.fetch(:controls, []) controls = [] controls << [ @@ -434,7 +435,12 @@ def search(args = nil) rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber, ].to_ber_sequence if paged controls << ber_sort if ber_sort - controls = controls.empty? ? nil : controls.to_ber_contextspecific(0) + if controls.empty? + controls = nil + else + controls += controls_temp unless controls_temp.blank? + controls = controls.to_ber_contextspecific(0) + end write(request, controls, message_id) From e896715eee5e2f85be6e7211e6813044ba457d9d Mon Sep 17 00:00:00 2001 From: Grant Willcox Date: Wed, 7 Dec 2022 08:58:53 -0600 Subject: [PATCH 02/22] Fix using blank? since that might not exist, and also allow for adding user controls even if the paged and ber_sort flags weren't set --- lib/net/ldap/connection.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 48dd7af3..83887e5e 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -425,7 +425,7 @@ def search(args = nil) # this breaks when calling to_ber. (Can't force binary data to UTF-8) # we have to disable paging (even though server supports it) to get around this... - controls_temp = args.fetch(:controls, []) + user_controls = args.fetch(:controls, []) controls = [] controls << [ @@ -435,10 +435,10 @@ def search(args = nil) rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber, ].to_ber_sequence if paged controls << ber_sort if ber_sort - if controls.empty? + if controls.empty? && user_controls.empty? controls = nil else - controls += controls_temp unless controls_temp.blank? + controls += user_controls controls = controls.to_ber_contextspecific(0) end From e7896d830f01a1984f0b4b21fea20a012092d52d Mon Sep 17 00:00:00 2001 From: Alexander Fisher Date: Thu, 25 May 2023 11:29:29 +0100 Subject: [PATCH 03/22] Document `connect_timeout` in Constructor Details Previously, this was only documented in the `Overview` section and missing from https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap/Net%2FLDAP:initialize --- lib/net/ldap.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index 1547597f..af01dd1d 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -480,6 +480,8 @@ def self.result2string(code) #:nodoc: # server says it supports them. This is a fix for MS Active Directory # * :instrumentation_service => An object responsible for instrumenting # operations, compatible with ActiveSupport::Notifications' public API. + # * :connect_timeout => The TCP socket timeout (in seconds) to use when + # connecting to the LDAP server (default 5 seconds). # * :encryption => specifies the encryption to be used in communicating # with the LDAP server. The value must be a Hash containing additional # parameters, which consists of two keys: From d2d500b12b25b9bf8714c683b253fc57bbfaddd8 Mon Sep 17 00:00:00 2001 From: Grant Willcox Date: Mon, 5 Jun 2023 09:54:52 -0500 Subject: [PATCH 04/22] Add in tests --- test/test_ldap_connection.rb | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/test_ldap_connection.rb b/test/test_ldap_connection.rb index dcb4ce72..74de115c 100644 --- a/test/test_ldap_connection.rb +++ b/test/test_ldap_connection.rb @@ -501,4 +501,43 @@ def test_search_net_ldap_connection_event # ensure no unread assert unread.empty?, "should not have any leftover unread messages" end + + def test_search_with_controls + # search data + search_data_ber = Net::BER::BerIdentifiedArray.new([1, [ + "uid=user1,ou=People,dc=rubyldap,dc=com", + [["uid", ["user1"]]], + ]]) + search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData + search_data = [1, search_data_ber] + # search result (end of results) + search_result_ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""]) + search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult + search_result = [1, search_result_ber] + @tcp_socket.should_receive(:read_ber).and_return(search_data) + .and_return(search_result) + + events = @service.subscribe "search.net_ldap_connection" + unread = @service.subscribe "search_messages_unread.net_ldap_connection" + + all_but_sacl_flag = 0x1 | 0x2 | 0x4 # OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION + control_values = [all_but_sacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber + controls = [] + # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID + ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze + controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence + + result = @connection.search(filter: "(uid=user1)", base: "ou=People,dc=rubyldap,dc=com", controls: controls) + assert result.success?, "should be success" + + # a search event + payload, result = events.pop + assert payload.key?(:result) + assert payload.key?(:filter) + assert_equal "(uid=user1)", payload[:filter].to_s + assert result + + # ensure no unread + assert unread.empty?, "should not have any leftover unread messages" + end end From 06acd16a09d5edbdfe8876de1e12503c571a4381 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Tue, 6 Jun 2023 00:21:07 -0400 Subject: [PATCH 05/22] Update rubocop todo --- .rubocop_todo.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c1d8b87a..ed69b335 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -277,7 +277,7 @@ Lint/UselessAssignment: # Offense count: 38 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: - Max: 120 + Max: 124 # Offense count: 3 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. @@ -298,12 +298,12 @@ Metrics/ClassLength: # Offense count: 20 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: - Max: 44 + Max: 45 # Offense count: 74 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 128 + Max: 130 # Offense count: 1 # Configuration parameters: CountComments, CountAsOne. @@ -313,7 +313,7 @@ Metrics/ModuleLength: # Offense count: 12 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: - Max: 44 + Max: 46 # Offense count: 1 Naming/AccessorMethodName: From 84bfc385cfad73c3e24ee36b014f2e81dc10ea81 Mon Sep 17 00:00:00 2001 From: Julian Paul Dasmarinas Date: Tue, 27 Jun 2023 09:58:45 +0800 Subject: [PATCH 06/22] Fix openssl error when using multiple hosts --- lib/net/ldap/connection.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 83887e5e..f51b7b7e 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -30,10 +30,9 @@ def socket_class=(socket_class) @socket_class = socket_class end - def prepare_socket(server, timeout=nil) + def prepare_socket(server, timeout=nil, hostname='127.0.0.1') socket = server[:socket] encryption = server[:encryption] - hostname = server[:host] @conn = socket setup_encryption(encryption, timeout, hostname) if encryption @@ -51,7 +50,7 @@ def open_connection(server) errors = [] hosts.each do |host, port| begin - prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout) + prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout, host) if encryption if encryption[:tls_options] && encryption[:tls_options][:verify_mode] && From a40d20363d34df7032182ee3e58323d93a43c316 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Wed, 3 Jan 2024 12:06:46 -0500 Subject: [PATCH 07/22] Prepare 0.19.0 --- History.rdoc | 6 ++++++ lib/net/ldap/version.rb | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/History.rdoc b/History.rdoc index db63cbf6..3f6248ee 100644 --- a/History.rdoc +++ b/History.rdoc @@ -1,3 +1,9 @@ +=== Net::LDAP 0.19.0 +* Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412 +* Add in ability for users to specify LDAP controls when conducting searches #411 +* Document connect_timeout in Constructor Details #415 +* Fix openssl error when using multiple hosts #417 + === Net::LDAP 0.18.0 * Fix escaping of # and space in attrs #408 * Add support to use SNI #406 diff --git a/lib/net/ldap/version.rb b/lib/net/ldap/version.rb index 6ca72fca..536b2f89 100644 --- a/lib/net/ldap/version.rb +++ b/lib/net/ldap/version.rb @@ -1,5 +1,5 @@ module Net class LDAP - VERSION = "0.18.0" + VERSION = "0.19.0" end end From 7f060e1f3a02592b35c350082297f17d7eac73f1 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Wed, 3 Jan 2024 12:13:05 -0500 Subject: [PATCH 08/22] Rubocop autocorrect --- lib/net/ldap.rb | 4 ++-- lib/net/ldap/auth_adapter/gss_spnego.rb | 2 +- lib/net/ldap/auth_adapter/sasl.rb | 2 +- lib/net/ldap/auth_adapter/simple.rb | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index af01dd1d..bf9dcc83 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -1257,10 +1257,10 @@ def search_subschema_entry rs = search(:ignore_server_caps => true, :base => "", :scope => SearchScope_BaseObject, :attributes => [:subschemaSubentry]) - return Net::LDAP::Entry.new unless (rs and rs.first) + return Net::LDAP::Entry.new unless rs and rs.first subschema_name = rs.first.subschemasubentry - return Net::LDAP::Entry.new unless (subschema_name and subschema_name.first) + return Net::LDAP::Entry.new unless subschema_name and subschema_name.first rs = search(:ignore_server_caps => true, :base => subschema_name.first, :scope => SearchScope_BaseObject, diff --git a/lib/net/ldap/auth_adapter/gss_spnego.rb b/lib/net/ldap/auth_adapter/gss_spnego.rb index 4a451ffb..b4c3e519 100644 --- a/lib/net/ldap/auth_adapter/gss_spnego.rb +++ b/lib/net/ldap/auth_adapter/gss_spnego.rb @@ -20,7 +20,7 @@ def bind(auth) require 'ntlm' user, psw = [auth[:username] || auth[:dn], auth[:password]] - raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw) + raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw nego = proc do |challenge| t2_msg = NTLM::Message.parse(challenge) diff --git a/lib/net/ldap/auth_adapter/sasl.rb b/lib/net/ldap/auth_adapter/sasl.rb index 4489bda4..bfebfc94 100644 --- a/lib/net/ldap/auth_adapter/sasl.rb +++ b/lib/net/ldap/auth_adapter/sasl.rb @@ -30,7 +30,7 @@ class Sasl < Net::LDAP::AuthAdapter def bind(auth) mech, cred, chall = auth[:mechanism], auth[:initial_credential], auth[:challenge_response] - raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall) + raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless mech && cred && chall message_id = @connection.next_msgid diff --git a/lib/net/ldap/auth_adapter/simple.rb b/lib/net/ldap/auth_adapter/simple.rb index d8e61c7b..8a753ea6 100644 --- a/lib/net/ldap/auth_adapter/simple.rb +++ b/lib/net/ldap/auth_adapter/simple.rb @@ -11,7 +11,7 @@ def bind(auth) ["", ""] end - raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw) + raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw message_id = @connection.next_msgid request = [ From 7557c6f4e1e4709f39737a97e8fa29b2a9c0e8aa Mon Sep 17 00:00:00 2001 From: Anton-Ivanov Date: Sat, 26 Oct 2024 17:38:17 +0300 Subject: [PATCH 09/22] #431, Add `ostruct` as a dependency to the gemspec This commit adds `ostruct` as an explicit dependency in the net-ldap gemspec. With the release of Ruby 3.3.5 and later versions, users of net-ldap may encounter warnings related to the use of `ostruct` if it is not declared as a dependency. By including `ostruct`, we aim to enhance clarity regarding the gem's requirements and prevent any runtime issues related to missing dependencies. --- net-ldap.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/net-ldap.gemspec b/net-ldap.gemspec index a5e53b88..1b72a753 100644 --- a/net-ldap.gemspec +++ b/net-ldap.gemspec @@ -29,6 +29,7 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).} s.required_ruby_version = ">= 2.0.0" s.summary = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing distributed directory services} + s.add_dependency("ostruct") s.add_development_dependency("flexmock", "~> 1.3") s.add_development_dependency("rake", "~> 12.3.3") s.add_development_dependency("rubocop", "~> 1.48") From 5eec272b76bfa7c396d54dc38d2ec6e5ee2512a2 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 21:39:46 -0400 Subject: [PATCH 10/22] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b035e809..0cacf25b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,4 +30,4 @@ jobs: steps: - uses: actions/checkout@v2 - name: Run tests with Ruby ${{ matrix.ruby }} - run: docker-compose run ci-${{ matrix.ruby }} + run: docker compose run ci-${{ matrix.ruby }} From 60f2bc35dbc58b7b1ab0e6bdde14b02c300f3e34 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 21:43:43 -0400 Subject: [PATCH 11/22] Update docker-compose --- docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6ada67bf..46ef00cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.8" - networks: integration_test_network: From 16ebec42a8c99777ae3e1adf9016ac90109d1c9f Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 21:46:20 -0400 Subject: [PATCH 12/22] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0cacf25b..945d1787 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - "3.2" - "jruby-9.3" - "jruby-9.4" - - "truffleruby-22" + - "truffleruby-24" steps: - uses: actions/checkout@v2 - name: Run tests with Ruby ${{ matrix.ruby }} From 8a737ce0fdefaeba97c171f1ced021766607fea5 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 21:49:37 -0400 Subject: [PATCH 13/22] Update test.yml --- .github/workflows/test.yml | 2 +- docker-compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 945d1787..6f335bc0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - "3.2" - "jruby-9.3" - "jruby-9.4" - - "truffleruby-24" + - "truffleruby" steps: - uses: actions/checkout@v2 - name: Run tests with Ruby ${{ matrix.ruby }} diff --git a/docker-compose.yml b/docker-compose.yml index 46ef00cf..ea9d5865 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -93,8 +93,8 @@ services: working_dir: /code # https://github.com/flavorjones/truffleruby/pkgs/container/truffleruby - ci-truffleruby-22: - image: ghcr.io/flavorjones/truffleruby:22.3.1 + ci-truffleruby: + image: ghcr.io/flavorjones/truffleruby:stable entrypoint: /code/ci-run.sh environment: INTEGRATION: openldap From ed83108ea1bb549a76bab1e8e48995ae8306614b Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 21:53:02 -0400 Subject: [PATCH 14/22] Update test.yml --- .github/workflows/test.yml | 3 +-- docker-compose.yml | 30 ++++++++---------------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f335bc0..3a405a39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,11 +19,10 @@ jobs: strategy: matrix: ruby: - - "2.6" - - "2.7" - "3.0" - "3.1" - "3.2" + - "3.3" - "jruby-9.3" - "jruby-9.4" - "truffleruby" diff --git a/docker-compose.yml b/docker-compose.yml index ea9d5865..11f93ba2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,22 +22,8 @@ services: volumes: - ./test/fixtures/ldif:/ldif:ro - ci-2.6: - image: ruby:2.7 - entrypoint: /code/ci-run.sh - environment: - INTEGRATION: openldap - INTEGRATION_HOST: ldap.example.org - depends_on: - - openldap - networks: - integration_test_network: - volumes: - - .:/code - working_dir: /code - - ci-2.7: - image: ruby:2.7 + ci-3.0: + image: ruby:3.0 entrypoint: /code/ci-run.sh environment: INTEGRATION: openldap @@ -50,8 +36,8 @@ services: - .:/code working_dir: /code - ci-3.0: - image: ruby:3.0 + ci-3.1: + image: ruby:3.1 entrypoint: /code/ci-run.sh environment: INTEGRATION: openldap @@ -64,8 +50,8 @@ services: - .:/code working_dir: /code - ci-3.1: - image: ruby:3.1 + ci-3.2: + image: ruby:3.2 entrypoint: /code/ci-run.sh environment: INTEGRATION: openldap @@ -78,8 +64,8 @@ services: - .:/code working_dir: /code - ci-3.2: - image: ruby:3.2 + ci-3.3: + image: ruby:3.3 entrypoint: /code/ci-run.sh environment: INTEGRATION: openldap From 2605a02920a87b1abaa32f12c2bed658b3e7b6ba Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Mon, 28 Oct 2024 22:04:52 -0400 Subject: [PATCH 15/22] Require Ruby >= 3.0 (#435) * Require Ruby >= 3.0.0 * Update test.yml --- .github/workflows/test.yml | 1 - net-ldap.gemspec | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a405a39..7cc5019d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,6 @@ jobs: - "3.1" - "3.2" - "3.3" - - "jruby-9.3" - "jruby-9.4" - "truffleruby" steps: diff --git a/net-ldap.gemspec b/net-ldap.gemspec index 1b72a753..3def4c20 100644 --- a/net-ldap.gemspec +++ b/net-ldap.gemspec @@ -26,7 +26,7 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).} s.homepage = %q{http://github.com/ruby-ldap/ruby-net-ldap} s.rdoc_options = ["--main", "README.rdoc"] s.require_paths = ["lib"] - s.required_ruby_version = ">= 2.0.0" + s.required_ruby_version = ">= 3.0.0" s.summary = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing distributed directory services} s.add_dependency("ostruct") From a515dadd24d2ff49ce0c62f5cb49629740a0edd8 Mon Sep 17 00:00:00 2001 From: Sebb Date: Tue, 29 Oct 2024 02:09:53 +0000 Subject: [PATCH 16/22] Link to usage examples (#428) * Link to usage doc * Better link --------- Co-authored-by: Kevin McCormack --- README.rdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rdoc b/README.rdoc index 6daafda6..88bdba61 100644 --- a/README.rdoc +++ b/README.rdoc @@ -23,7 +23,7 @@ the most recent LDAP RFCs (4510–4519, plus portions of 4520–4532). == Synopsis -See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap] for documentation and usage samples. +See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap/Net/LDAP] for documentation and usage samples. == Requirements From 75c0bcbda4b91f981fb6b88896346d3259de20a1 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Mon, 28 Oct 2024 22:12:31 -0400 Subject: [PATCH 17/22] Add controls for modify and add operations (#426) * Allow controls for add and modify * Add tests for add and modify --------- Co-authored-by: Kevin McCormack --- lib/net/ldap/connection.rb | 14 ++++++++++++-- test/test_ldap_connection.rb | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index f51b7b7e..65fa5330 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -569,7 +569,12 @@ def modify(args) ops.to_ber_sequence, ].to_ber_appsequence(Net::LDAP::PDU::ModifyRequest) - write(request, nil, message_id) + controls = args.fetch(:controls, nil) + unless controls.nil? + controls = controls.to_ber_contextspecific(0) + end + + write(request, controls, message_id) pdu = queued_read(message_id) if !pdu || pdu.app_tag != Net::LDAP::PDU::ModifyResponse @@ -641,7 +646,12 @@ def add(args) message_id = next_msgid request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(Net::LDAP::PDU::AddRequest) - write(request, nil, message_id) + controls = args.fetch(:controls, nil) + unless controls.nil? + controls = controls.to_ber_contextspecific(0) + end + + write(request, controls, message_id) pdu = queued_read(message_id) if !pdu || pdu.app_tag != Net::LDAP::PDU::AddResponse diff --git a/test/test_ldap_connection.rb b/test/test_ldap_connection.rb index 74de115c..ca9bcb0b 100644 --- a/test/test_ldap_connection.rb +++ b/test/test_ldap_connection.rb @@ -502,6 +502,40 @@ def test_search_net_ldap_connection_event assert unread.empty?, "should not have any leftover unread messages" end + def test_add_with_controls + dacl_flag = 0x4 # DACL_SECURITY_INFORMATION + control_values = [dacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber + controls = [] + # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID + ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze + controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence + + ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""]) + ber.ber_identifier = Net::LDAP::PDU::AddResponse + @tcp_socket.should_receive(:read_ber).and_return([1, ber]) + + result = @connection.add(:dn => "uid=added-user1,ou=People,dc=rubyldap,dc=com", :controls => controls) + assert result.success?, "should be success" + assert_equal "", result.error_message + end + + def test_modify_with_controls + dacl_flag = 0x4 # DACL_SECURITY_INFORMATION + control_values = [dacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber + controls = [] + # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID + ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze + controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence + + ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""]) + ber.ber_identifier = Net::LDAP::PDU::ModifyResponse + @tcp_socket.should_receive(:read_ber).and_return([1, ber]) + + result = @connection.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]], :controls => controls) + assert result.success?, "should be success" + assert_equal "", result.error_message + end + def test_search_with_controls # search data search_data_ber = Net::BER::BerIdentifiedArray.new([1, [ From a56279079b0a6125a336c931c0dcf520c7d7d27e Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Sun, 24 Nov 2024 08:58:34 -0500 Subject: [PATCH 18/22] Add support for ldapwhoami (RFC4532) (now with tests) (#425) * Add support for ldapwhoami (RFC4532) * Do not break Net::LDAP#modify_password * Return the extended response data * Add test for connection.ldapwhoami * Fix processing password modify responses Per RFC4511 section 4.12, the responseValue field of an ExtendedResponse object is an optional string. Per RFC3062 section 2, the response to a passsword modify request is a sequence. This means the extended response must be parsed. --------- Co-authored-by: a7b81a9086 <> Co-authored-by: Kevin McCormack --- .rubocop_todo.yml | 2 +- lib/net/ldap.rb | 22 ++++++++++++++++++++-- lib/net/ldap/connection.rb | 16 ++++++++++++++++ lib/net/ldap/pdu.rb | 4 ++-- test/integration/test_password_modify.rb | 24 +++++++++++++++++++++--- test/test_ldap_connection.rb | 11 +++++++++++ 6 files changed, 71 insertions(+), 8 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ed69b335..426a2aed 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -293,7 +293,7 @@ Metrics/BlockNesting: # Offense count: 11 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: - Max: 443 + Max: 451 # Offense count: 20 # Configuration parameters: AllowedMethods, AllowedPatterns. diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index bf9dcc83..8dca73c0 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -311,7 +311,7 @@ class Net::LDAP 0 => :array, # RFC-2251 Control and Filter-AND 1 => :array, # SearchFilter-OR 2 => :array, # SearchFilter-NOT - 3 => :array, # Seach referral + 3 => :array, # Search referral 4 => :array, # unknown use in Microsoft Outlook 5 => :array, # SearchFilter-GE 6 => :array, # SearchFilter-LE @@ -325,7 +325,7 @@ class Net::LDAP universal = { constructed: { - 107 => :array, #ExtendedResponse (PasswdModifyResponseValue) + 107 => :string, # ExtendedResponse }, } @@ -341,6 +341,7 @@ class Net::LDAP StartTlsOid = '1.3.6.1.4.1.1466.20037' PasswdModifyOid = '1.3.6.1.4.1.4203.1.11.1' + WhoamiOid = '1.3.6.1.4.1.4203.1.11.3' # https://tools.ietf.org/html/rfc4511#section-4.1.9 # https://tools.ietf.org/html/rfc4511#appendix-A @@ -1200,6 +1201,23 @@ def delete_tree(args) end end + # Return the authorization identity of the client that issues the + # ldapwhoami request. The method does not support any arguments. + # + # Returns True or False to indicate whether the request was successfull. + # The result is available in the extended status information when calling + # #get_operation_result. + # + # ldap.ldapwhoami + # puts ldap.get_operation_result.extended_response + def ldapwhoami(args = {}) + instrument "ldapwhoami.net_ldap", args do |payload| + @result = use_connection(args, &:ldapwhoami) + @result.success? ? @result.extended_response : nil + end + end + alias_method :whoami, :ldapwhoami + # This method is experimental and subject to change. Return the rootDSE # record from the LDAP server as a Net::LDAP::Entry, or an empty Entry if # the server doesn't return the record. diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 65fa5330..f1a70b18 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -703,6 +703,22 @@ def delete(args) pdu end + def ldapwhoami + ext_seq = [Net::LDAP::WhoamiOid.to_ber_contextspecific(0)] + request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest) + + message_id = next_msgid + + write(request, nil, message_id) + pdu = queued_read(message_id) + + if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse + raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid" + end + + pdu + end + # Internal: Returns a Socket like object used internally to communicate with # LDAP server. # diff --git a/lib/net/ldap/pdu.rb b/lib/net/ldap/pdu.rb index 564a23cc..83a609b7 100644 --- a/lib/net/ldap/pdu.rb +++ b/lib/net/ldap/pdu.rb @@ -194,13 +194,13 @@ def parse_ldap_result(sequence) # requestValue [1] OCTET STRING OPTIONAL } def parse_extended_response(sequence) - sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP result length." + sequence.length.between?(3, 5) or raise Net::LDAP::PDU::Error, "Invalid LDAP result length." @ldap_result = { :resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2], } - @extended_response = sequence[3] + @extended_response = sequence.length == 3 ? nil : sequence.last end private :parse_extended_response diff --git a/test/integration/test_password_modify.rb b/test/integration/test_password_modify.rb index 65507c80..e7d8d670 100644 --- a/test/integration/test_password_modify.rb +++ b/test/integration/test_password_modify.rb @@ -1,6 +1,13 @@ require_relative '../test_helper' class TestPasswordModifyIntegration < LDAPIntegrationTestCase + # see: https://www.rfc-editor.org/rfc/rfc3062#section-2 + PASSWORD_MODIFY_SYNTAX = Net::BER.compile_syntax( + application: {}, + universal: {}, + context_specific: { primitive: { 0 => :string } }, + ) + def setup super @admin_account = { dn: 'cn=admin,dc=example,dc=org', password: 'admin', method: :simple } @@ -49,7 +56,13 @@ def test_password_modify_generate auth: @auth, old_password: 'admin') - generated_password = @ldap.get_operation_result.extended_response[0][0] + passwd_modify_response_value = @ldap.get_operation_result.extended_response + seq = Net::BER::BerIdentifiedArray.new + sio = StringIO.new(passwd_modify_response_value) + until (e = sio.read_ber(PASSWORD_MODIFY_SYNTAX)).nil? + seq << e + end + generated_password = seq[0][0] assert generated_password, 'Should have generated a password' @@ -64,8 +77,13 @@ def test_password_modify_generate_no_old_password assert @ldap.password_modify(dn: @dn, auth: @auth) - generated_password = @ldap.get_operation_result.extended_response[0][0] - + passwd_modify_response_value = @ldap.get_operation_result.extended_response + seq = Net::BER::BerIdentifiedArray.new + sio = StringIO.new(passwd_modify_response_value) + until (e = sio.read_ber(PASSWORD_MODIFY_SYNTAX)).nil? + seq << e + end + generated_password = seq[0][0] assert generated_password, 'Should have generated a password' refute @ldap.bind(username: @dn, password: 'admin', method: :simple), diff --git a/test/test_ldap_connection.rb b/test/test_ldap_connection.rb index ca9bcb0b..fdfa418c 100644 --- a/test/test_ldap_connection.rb +++ b/test/test_ldap_connection.rb @@ -574,4 +574,15 @@ def test_search_with_controls # ensure no unread assert unread.empty?, "should not have any leftover unread messages" end + + def test_ldapwhoami + ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, '', '', 0, 'dn:uid=zerosteiner,ou=users,dc=example,dc=org']) + ber.ber_identifier = Net::LDAP::PDU::ExtendedResponse + response = [1, ber] + + @tcp_socket.should_receive(:read_ber).and_return(response) + + result = @connection.ldapwhoami + assert result.extended_response == 'dn:uid=zerosteiner,ou=users,dc=example,dc=org' + end end From 16d76259566c0bf840dfc5c0009e92129bed5093 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Sat, 31 May 2025 16:43:44 -0400 Subject: [PATCH 19/22] Update for ruby 3.4 (#439) * Update for ruby 3.4 * Update gemfile * Update test workflow * Update ci --- .github/workflows/test.yml | 3 +- .rubocop_todo.yml | 105 ++++++++++++++++++------------------- Gemfile | 6 +++ ci-run.sh | 1 + docker-compose.yml | 14 ++--- net-ldap.gemspec | 6 +-- 6 files changed, 68 insertions(+), 67 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7cc5019d..605b66e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: test: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: ruby: - "3.0" @@ -26,6 +27,6 @@ jobs: - "jruby-9.4" - "truffleruby" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Run tests with Ruby ${{ matrix.ruby }} run: docker compose run ci-${{ matrix.ruby }} diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 426a2aed..50901661 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,26 +1,11 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2023-03-29 17:13:45 UTC using RuboCop version 1.48.1. +# on 2025-05-31 20:03:27 UTC using RuboCop version 1.75.8. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. -# Include: **/*.gemspec -Gemspec/OrderedDependencies: - Exclude: - - 'net-ldap.gemspec' - -# Offense count: 1 -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec -Gemspec/RequiredRubyVersion: - Exclude: - - 'net-ldap.gemspec' - # Offense count: 3 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, IndentationWidth. @@ -61,7 +46,7 @@ Layout/EmptyLineAfterMagicComment: # Offense count: 6 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, DefLikeMacros, AllowAdjacentOneLineDefs, NumberOfEmptyLines. Layout/EmptyLineBetweenDefs: Exclude: - 'lib/net/ldap/dataset.rb' @@ -104,7 +89,7 @@ Layout/EndAlignment: Exclude: - 'testserver/ldapserver.rb' -# Offense count: 2 +# Offense count: 6 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: IndentationWidth. # SupportedStyles: special_inside_parentheses, consistent, align_brackets @@ -148,9 +133,9 @@ Layout/IndentationWidth: - 'lib/net/ldap/password.rb' - 'lib/net/snmp.rb' -# Offense count: 15 +# Offense count: 14 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment. +# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment, AllowRBSInlineAnnotation, AllowSteepAnnotation. Layout/LeadingCommentSpace: Exclude: - 'lib/net/ber/core_ext/array.rb' @@ -168,7 +153,7 @@ Layout/MultilineMethodCallBraceLayout: Exclude: - 'lib/net/ldap/filter.rb' -# Offense count: 7 +# Offense count: 8 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space @@ -186,8 +171,9 @@ Layout/SpaceAroundKeyword: # Offense count: 7 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. +# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator, EnforcedStyleForRationalLiterals. # SupportedStylesForExponentOperator: space, no_space +# SupportedStylesForRationalLiterals: space, no_space Layout/SpaceAroundOperators: Exclude: - 'lib/net/ber/ber_parser.rb' @@ -214,8 +200,8 @@ Layout/SpaceInsideParens: - 'lib/net/snmp.rb' # Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowComments. +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect, AllowComments. Lint/EmptyConditionalBody: Exclude: - 'lib/net/ldap/filter.rb' @@ -227,6 +213,7 @@ Lint/EmptyWhen: - 'lib/net/ldap/pdu.rb' # Offense count: 30 +# This cop supports safe autocorrection (--autocorrect). Lint/ImplicitStringConcatenation: Exclude: - 'test/test_filter.rb' @@ -241,9 +228,9 @@ Lint/RescueException: Exclude: - 'lib/net/ldap/pdu.rb' -# Offense count: 9 +# Offense count: 10 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. +# Configuration parameters: AutoCorrect, IgnoreEmptyBlocks, AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: Exclude: - 'lib/net/ldap.rb' @@ -251,7 +238,8 @@ Lint/UnusedBlockArgument: # Offense count: 7 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. +# Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions. +# NotImplementedExceptions: NotImplementedError Lint/UnusedMethodArgument: Exclude: - 'lib/net/ldap/entry.rb' @@ -262,19 +250,21 @@ Lint/UnusedMethodArgument: # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods. +# Configuration parameters: AutoCorrect, ContextCreatingMethods, MethodCreatingMethods. Lint/UselessAccessModifier: Exclude: - 'lib/net/ldap/connection.rb' # Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AutoCorrect. Lint/UselessAssignment: Exclude: - 'test/integration/test_add.rb' - 'test/test_ldap_connection.rb' - 'test/test_search.rb' -# Offense count: 38 +# Offense count: 42 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 124 @@ -285,22 +275,22 @@ Metrics/AbcSize: Metrics/BlockLength: Max: 119 -# Offense count: 11 -# Configuration parameters: CountBlocks. +# Offense count: 6 +# Configuration parameters: CountBlocks, CountModifierForms. Metrics/BlockNesting: Max: 4 -# Offense count: 11 +# Offense count: 12 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: Max: 451 -# Offense count: 20 +# Offense count: 21 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: Max: 45 -# Offense count: 74 +# Offense count: 79 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 130 @@ -333,7 +323,7 @@ Naming/ClassAndModuleCamelCase: Exclude: - 'lib/net/ldap/auth_adapter/gss_spnego.rb' -# Offense count: 87 +# Offense count: 88 Naming/ConstantName: Exclude: - 'lib/net/ldap.rb' @@ -350,6 +340,7 @@ Naming/ConstantName: # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS Naming/FileName: Exclude: + - 'Rakefile.rb' - 'lib/net-ldap.rb' # Offense count: 11 @@ -380,7 +371,7 @@ Style/AccessorGrouping: - 'lib/net/ldap.rb' - 'lib/net/ldap/pdu.rb' -# Offense count: 10 +# Offense count: 11 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: prefer_alias, prefer_alias_method @@ -434,8 +425,10 @@ Style/CharacterLiteral: # Offense count: 23 # This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. +# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules. # SupportedStyles: nested, compact +# SupportedStylesForClasses: ~, nested, compact +# SupportedStylesForModules: ~, nested, compact Style/ClassAndModuleChildren: Enabled: false @@ -493,7 +486,7 @@ Style/Documentation: # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. +# Configuration parameters: AutoCorrect, EnforcedStyle. # SupportedStyles: compact, expanded Style/EmptyMethod: Exclude: @@ -525,7 +518,7 @@ Style/ExplicitBlockArgument: - 'lib/net/ldap.rb' - 'lib/net/ldap/dataset.rb' -# Offense count: 54 +# Offense count: 57 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never @@ -545,11 +538,11 @@ Style/GuardClause: Exclude: - 'lib/net/ldap/filter.rb' -# Offense count: 159 +# Offense count: 164 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. # SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys -# SupportedShorthandSyntax: always, never, either, consistent +# SupportedShorthandSyntax: always, never, either, consistent, either_consistent Style/HashSyntax: Exclude: - 'lib/net/ber.rb' @@ -573,7 +566,7 @@ Style/IfInsideElse: Exclude: - 'lib/net/ldap/instrumentation.rb' -# Offense count: 25 +# Offense count: 28 # This cop supports safe autocorrection (--autocorrect). Style/IfUnlessModifier: Exclude: @@ -618,7 +611,14 @@ Style/MultilineWhenThen: Exclude: - 'lib/net/ldap/dn.rb' -# Offense count: 25 +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowMethodComparison, ComparisonsThreshold. +Style/MultipleComparison: + Exclude: + - 'lib/net/ldap/dataset.rb' + +# Offense count: 26 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: literals, strict @@ -650,7 +650,7 @@ Style/NegatedWhile: # Offense count: 3 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, MinBodyLength. +# Configuration parameters: EnforcedStyle, MinBodyLength, AllowConsecutiveConditionals. # SupportedStyles: skip_modifier_ifs, always Style/Next: Exclude: @@ -678,7 +678,7 @@ Style/Not: Exclude: - 'lib/net/ldap/filter.rb' -# Offense count: 11 +# Offense count: 13 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Strict, AllowedNumbers, AllowedPatterns. Style/NumericLiterals: @@ -704,15 +704,12 @@ Style/OptionalBooleanParameter: Exclude: - 'lib/net/ldap/entry.rb' -# Offense count: 6 +# Offense count: 1 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. Style/ParenthesesAroundCondition: Exclude: - - 'lib/net/ldap.rb' - - 'lib/net/ldap/auth_adapter/gss_spnego.rb' - 'lib/net/ldap/auth_adapter/sasl.rb' - - 'lib/net/ldap/auth_adapter/simple.rb' # Offense count: 13 # This cop supports safe autocorrection (--autocorrect). @@ -737,7 +734,7 @@ Style/PerlBackrefs: - 'testserver/ldapserver.rb' # Offense count: 10 -# This cop supports safe autocorrection (--autocorrect). +# This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, AllowedCompactTypes. # SupportedStyles: compact, exploded Style/RaiseArgs: @@ -874,7 +871,7 @@ Style/StringConcatenation: - 'test/test_ldif.rb' - 'test/test_snmp.rb' -# Offense count: 683 +# Offense count: 728 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes @@ -907,7 +904,7 @@ Style/TernaryParentheses: # Offense count: 38 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma +# SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma Style/TrailingCommaInHashLiteral: Enabled: false @@ -955,9 +952,9 @@ Style/ZeroLengthPredicate: - 'lib/net/ldap/filter.rb' - 'testserver/ldapserver.rb' -# Offense count: 24 +# Offense count: 27 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings. # URISchemes: http, https Layout/LineLength: Max: 360 diff --git a/Gemfile b/Gemfile index 851fabc2..10d2031f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,8 @@ source 'https://rubygems.org/' gemspec + +gem "debug", platform: :mri +gem "flexmock", "~> 1.3" +gem "rake", "~> 12.3.3" +gem "rubocop", "~> 1.48" +gem "test-unit" diff --git a/ci-run.sh b/ci-run.sh index 27024a77..cef309c0 100755 --- a/ci-run.sh +++ b/ci-run.sh @@ -3,5 +3,6 @@ set -e gem install bundler +ruby -v | grep jruby && apt update && apt install -y gcc bundle check || bundle install bundle exec rake ci diff --git a/docker-compose.yml b/docker-compose.yml index 11f93ba2..cf715da5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,7 +24,7 @@ services: ci-3.0: image: ruby:3.0 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -38,7 +38,7 @@ services: ci-3.1: image: ruby:3.1 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -52,7 +52,7 @@ services: ci-3.2: image: ruby:3.2 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -66,7 +66,7 @@ services: ci-3.3: image: ruby:3.3 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -81,7 +81,7 @@ services: # https://github.com/flavorjones/truffleruby/pkgs/container/truffleruby ci-truffleruby: image: ghcr.io/flavorjones/truffleruby:stable - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -95,7 +95,7 @@ services: ci-jruby-9.3: image: jruby:9.3 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org @@ -109,7 +109,7 @@ services: ci-jruby-9.4: image: jruby:9.4 - entrypoint: /code/ci-run.sh + command: /code/ci-run.sh environment: INTEGRATION: openldap INTEGRATION_HOST: ldap.example.org diff --git a/net-ldap.gemspec b/net-ldap.gemspec index 3def4c20..077077f2 100644 --- a/net-ldap.gemspec +++ b/net-ldap.gemspec @@ -29,10 +29,6 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).} s.required_ruby_version = ">= 3.0.0" s.summary = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing distributed directory services} + s.add_dependency("base64") s.add_dependency("ostruct") - s.add_development_dependency("flexmock", "~> 1.3") - s.add_development_dependency("rake", "~> 12.3.3") - s.add_development_dependency("rubocop", "~> 1.48") - s.add_development_dependency("test-unit", "~> 3.3") - s.add_development_dependency("byebug", "~> 9.0.6") unless RUBY_PLATFORM == "java" end From 990a666f654cca34afa6858abcd6fc70974dd6bd Mon Sep 17 00:00:00 2001 From: Hakeem <94065808+hakeem0114@users.noreply.github.com> Date: Sat, 31 May 2025 16:46:15 -0400 Subject: [PATCH 20/22] Add ruby 3.4 to CI (#438) * Add ruby 3.4 to CI * Add ruby 3.4 to docker-compose.yml --------- Co-authored-by: Kevin McCormack --- .github/workflows/test.yml | 1 + docker-compose.yml | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 605b66e6..a1ce7996 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,7 @@ jobs: - "3.1" - "3.2" - "3.3" + - "3.4" - "jruby-9.4" - "truffleruby" steps: diff --git a/docker-compose.yml b/docker-compose.yml index cf715da5..4fbfbec8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -78,6 +78,20 @@ services: - .:/code working_dir: /code + ci-3.4: + image: ruby:3.4 + entrypoint: /code/ci-run.sh + environment: + INTEGRATION: openldap + INTEGRATION_HOST: ldap.example.org + depends_on: + - openldap + networks: + integration_test_network: + volumes: + - .:/code + working_dir: /code + # https://github.com/flavorjones/truffleruby/pkgs/container/truffleruby ci-truffleruby: image: ghcr.io/flavorjones/truffleruby:stable From 223c46bc2ee6accbacac126053415a736c99daae Mon Sep 17 00:00:00 2001 From: Frank Walentowski Date: Fri, 22 Aug 2025 14:58:58 +0200 Subject: [PATCH 21/22] Add support for UTF-8 encoded passwords when using the hash types :ssha and ssha256 (#430) --- lib/net/ldap/password.rb | 8 ++++++-- test/test_password.rb | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/net/ldap/password.rb b/lib/net/ldap/password.rb index 9a6658ed..4a6a1ae7 100644 --- a/lib/net/ldap/password.rb +++ b/lib/net/ldap/password.rb @@ -28,10 +28,14 @@ def generate(type, str) '{SHA}' + Base64.strict_encode64(Digest::SHA1.digest(str)) when :ssha salt = SecureRandom.random_bytes(16) - '{SSHA}' + Base64.strict_encode64(Digest::SHA1.digest(str + salt) + salt) + digest = Digest::SHA1.new + digest << str << salt + '{SSHA}' + Base64.strict_encode64(digest.digest + salt) when :ssha256 salt = SecureRandom.random_bytes(16) - '{SSHA256}' + Base64.strict_encode64(Digest::SHA256.digest(str + salt) + salt) + digest = Digest::SHA256.new + digest << str << salt + '{SSHA256}' + Base64.strict_encode64(digest.digest + salt) else raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})" end diff --git a/test/test_password.rb b/test/test_password.rb index cc1878da..407cde94 100644 --- a/test/test_password.rb +++ b/test/test_password.rb @@ -12,4 +12,11 @@ def test_psw_with_ssha256_should_not_contain_linefeed flexmock(SecureRandom).should_receive(:random_bytes).and_return('\xE5\x8A\x99\xF8\xCB\x15GW\xE8\xEA\xAD\x0F\xBF\x95\xB0\xDC') assert_equal("{SSHA256}Cc7MXboTyUP5PnPAeJeCrgMy8+7Gus0sw7kBJuTrmf1ceEU1XHg4QVx4OTlceEY4XHhDQlx4MTVHV1x4RThceEVBXHhBRFx4MEZceEJGXHg5NVx4QjBceERD", Net::LDAP::Password.generate(:ssha256, "cashflow")) end + + def test_utf8_psw + flexmock(SecureRandom).should_receive(:random_bytes).and_return('\xE5\x8A\x99\xF8\xCB\x15GW\xE8\xEA\xAD\x0F\xBF\x95\xB0\xDC') + utf8_psw = "iHVh©NjrLR§h!cru" + assert_equal("{SSHA}shzNiWgSPr3DoDm+Re7QPCcu1g1ceEU1XHg4QVx4OTlceEY4XHhDQlx4MTVHV1x4RThceEVBXHhBRFx4MEZceEJGXHg5NVx4QjBceERD", Net::LDAP::Password.generate(:ssha, utf8_psw)) + assert_equal("{SSHA256}/aS06GodUyRYx+z436t+WZsH2aQCSac9FY4ewaXzhSNceEU1XHg4QVx4OTlceEY4XHhDQlx4MTVHV1x4RThceEVBXHhBRFx4MEZceEJGXHg5NVx4QjBceERD", Net::LDAP::Password.generate(:ssha256, utf8_psw)) + end end From de197ea192c717c37ec6132ab08451aacae25bf1 Mon Sep 17 00:00:00 2001 From: Kevin McCormack Date: Fri, 22 Aug 2025 09:07:29 -0400 Subject: [PATCH 22/22] Prepare v0.20.0 (#441) --- History.rdoc | 11 +++++++++++ lib/net/ldap/version.rb | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/History.rdoc b/History.rdoc index 3f6248ee..919eaf67 100644 --- a/History.rdoc +++ b/History.rdoc @@ -1,3 +1,14 @@ +=== Net::LDAP 0.20.0 +* Update test.yml by @HarlemSquirrel in #433 +* Add `ostruct` as a dependency to the gemspec by @Ivanov-Anton in #432 +* Require Ruby >= 3.0 by @HarlemSquirrel in #435 +* Link to usage examples by @sebbASF in #428 +* Add controls for modify and add operations by @zeroSteiner in #426 +* Add support for ldapwhoami (RFC4532) (now with tests) by @zeroSteiner in #425 +* Update for ruby 3.4 by @HarlemSquirrel in #439 +* Add ruby 3.4 to CI by @hakeem0114 in #438 +* Add support for UTF-8 encoded passwords by @frankwalentowski in #430 + === Net::LDAP 0.19.0 * Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412 * Add in ability for users to specify LDAP controls when conducting searches #411 diff --git a/lib/net/ldap/version.rb b/lib/net/ldap/version.rb index 536b2f89..2caeaa5f 100644 --- a/lib/net/ldap/version.rb +++ b/lib/net/ldap/version.rb @@ -1,5 +1,5 @@ module Net class LDAP - VERSION = "0.19.0" + VERSION = "0.20.0" end end