Class: Rex::Proto::LDAP::Client
- Inherits:
-
Net::LDAP
- Object
- Net::LDAP
- Rex::Proto::LDAP::Client
- Defined in:
- lib/rex/proto/ldap/client.rb
Overview
This is a Rex Proto wrapper around the Net::LDAP client which is currently coming from the ‘net-ldap’ gem. The purpose of this wrapper is to provide ‘peerhost’ and ‘peerport’ methods to ensure the client interfaces are consistent between various session clients.
Instance Attribute Summary collapse
-
#connection_use_mutex ⇒ Object
readonly
- Mutex
-
Control access to the connection.
-
#last_interaction ⇒ Object
readonly
- Time
-
The last time an interaction occurred on the connection (for keep-alive purposes).
- #socket ⇒ Rex::Socket readonly
Class Method Summary collapse
-
._open(connect_opts) ⇒ Object
github.com/ruby-ldap/ruby-net-ldap/issues/11 We want to keep the ldap connection open to use later but there’s no built in way within the ‘Net::LDAP` library to do that so we’re adding this function to do it instead.
Instance Method Summary collapse
- #_open ⇒ Object
-
#base_dn ⇒ String
LDAP servers Base DN.
- #discover_base_dn ⇒ Object
- #discover_schema_naming_context ⇒ Object
-
#initialize(args) ⇒ Client
constructor
A new instance of Client.
-
#ldapwhoami(args = {}) ⇒ Object
Monkeypatch upstream library to support the extended Whoami request.
-
#naming_contexts ⇒ Array<String>
LDAP servers naming contexts.
-
#peerhost ⇒ String
The remote IP address that LDAP is running on.
-
#peerinfo ⇒ String
The remote peer information containing IP and port.
-
#peerport ⇒ Integer
The remote port that LDAP is running on.
- #register_interaction ⇒ Object
-
#schema_dn ⇒ String?
LDAP servers Schema DN, nil if one isn’t found.
- #use_connection(args) ⇒ Object
Constructor Details
#initialize(args) ⇒ Client
Returns a new instance of Client.
20 21 22 23 24 25 |
# File 'lib/rex/proto/ldap/client.rb', line 20 def initialize(args) @base_dn = args[:base] @last_interaction = nil @connection_use_mutex = Mutex.new super end |
Instance Attribute Details
#connection_use_mutex ⇒ Object (readonly)
- Mutex
-
Control access to the connection. One at a time.
18 19 20 |
# File 'lib/rex/proto/ldap/client.rb', line 18 def connection_use_mutex @connection_use_mutex end |
#last_interaction ⇒ Object (readonly)
- Time
-
The last time an interaction occurred on the connection (for keep-alive purposes)
15 16 17 |
# File 'lib/rex/proto/ldap/client.rb', line 15 def last_interaction @last_interaction end |
#socket ⇒ Rex::Socket (readonly)
12 13 14 |
# File 'lib/rex/proto/ldap/client.rb', line 12 def socket @socket end |
Class Method Details
._open(connect_opts) ⇒ Object
github.com/ruby-ldap/ruby-net-ldap/issues/11 We want to keep the ldap connection open to use later but there’s no built in way within the ‘Net::LDAP` library to do that so we’re adding this function to do it instead
74 75 76 77 |
# File 'lib/rex/proto/ldap/client.rb', line 74 def self._open(connect_opts) client = new(connect_opts) client._open end |
Instance Method Details
#_open ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rex/proto/ldap/client.rb', line 80 def _open raise Net::LDAP::AlreadyOpenedError, 'Open already in progress' if @open_connection instrument 'open.net_ldap' do |payload| @open_connection = new_connection @socket = @open_connection.socket payload[:connection] = @open_connection payload[:bind] = @result = @open_connection.bind(@auth) register_interaction return self end end |
#base_dn ⇒ String
Returns LDAP servers Base DN.
37 38 39 |
# File 'lib/rex/proto/ldap/client.rb', line 37 def base_dn @base_dn ||= discover_base_dn end |
#discover_base_dn ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/rex/proto/ldap/client.rb', line 104 def discover_base_dn unless naming_contexts elog("#{peerinfo} Base DN cannot be determined, no naming contexts available") return end # NOTE: Find the first entry that starts with `DC=` as this will likely be the base DN. result = naming_contexts.select { |context| context =~ /^([Dd][Cc]=[A-Za-z0-9-]+,?)+$/ } .reject { |context| context =~ /(Configuration)|(Schema)|(ForestDnsZones)/ } if result.blank? elog("#{peerinfo} A base DN matching the expected format could not be found!") return end base_dn = result[0] dlog("#{peerinfo} Discovered base DN: #{base_dn}") base_dn end |
#discover_schema_naming_context ⇒ Object
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rex/proto/ldap/client.rb', line 93 def discover_schema_naming_context result = search(base: '', attributes: [:schemanamingcontext], scope: Net::LDAP::SearchScope_BaseObject) if result.first && !result.first[:schemanamingcontext].empty? schema_dn = result.first[:schemanamingcontext].first ilog("#{peerinfo} Discovered Schema DN: #{schema_dn}") return schema_dn end wlog("#{peerinfo} Could not discover Schema DN") nil end |
#ldapwhoami(args = {}) ⇒ Object
Monkeypatch upstream library to support the extended Whoami request. Delete this after github.com/ruby-ldap/ruby-net-ldap/pull/425 is landed. This is not the only occurrence of a patch for this functionality.
126 127 128 129 130 131 |
# File 'lib/rex/proto/ldap/client.rb', line 126 def ldapwhoami(args = {}) instrument "ldapwhoami.net_ldap", args do |payload| @result = use_connection(args, &:ldapwhoami) @result.success? ? @result.extended_response : nil end end |
#naming_contexts ⇒ Array<String>
Returns LDAP servers naming contexts.
32 33 34 |
# File 'lib/rex/proto/ldap/client.rb', line 32 def naming_contexts @naming_contexts ||= search_root_dse[:namingcontexts] end |
#peerhost ⇒ String
Returns The remote IP address that LDAP is running on.
47 48 49 |
# File 'lib/rex/proto/ldap/client.rb', line 47 def peerhost host end |
#peerinfo ⇒ String
Returns The remote peer information containing IP and port.
57 58 59 |
# File 'lib/rex/proto/ldap/client.rb', line 57 def peerinfo "#{peerhost}:#{peerport}" end |
#peerport ⇒ Integer
Returns The remote port that LDAP is running on.
52 53 54 |
# File 'lib/rex/proto/ldap/client.rb', line 52 def peerport port end |
#register_interaction ⇒ Object
27 28 29 |
# File 'lib/rex/proto/ldap/client.rb', line 27 def register_interaction @last_interaction = Process.clock_gettime(Process::CLOCK_MONOTONIC) end |
#schema_dn ⇒ String?
Returns LDAP servers Schema DN, nil if one isn’t found.
42 43 44 |
# File 'lib/rex/proto/ldap/client.rb', line 42 def schema_dn @schema_dn ||= discover_schema_naming_context end |
#use_connection(args) ⇒ Object
61 62 63 64 65 66 67 |
# File 'lib/rex/proto/ldap/client.rb', line 61 def use_connection(args) @connection_use_mutex.synchronize do return super(args) ensure register_interaction end end |