Class: Rex::Proto::LDAP::Client

Inherits:
Net::LDAP
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Client

Returns a new instance of Client.



14
15
16
17
# File 'lib/rex/proto/ldap/client.rb', line 14

def initialize(args)
  @base_dn = args[:base]
  super
end

Instance Attribute Details

#socketRex::Socket (readonly)

Returns:

  • (Rex::Socket)


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

Parameters:

  • connect_opts (Hash)

    Options for the LDAP connection.



54
55
56
57
# File 'lib/rex/proto/ldap/client.rb', line 54

def self._open(connect_opts)
  client = new(connect_opts)
  client._open
end

Instance Method Details

#_openObject

Raises:

  • (Net::LDAP::AlreadyOpenedError)


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rex/proto/ldap/client.rb', line 60

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)
    return self
  end
end

#base_dnString

Returns LDAP servers Base DN.

Returns:

  • (String)

    LDAP servers Base DN



25
26
27
# File 'lib/rex/proto/ldap/client.rb', line 25

def base_dn
  @base_dn ||= discover_base_dn
end

#discover_base_dnObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rex/proto/ldap/client.rb', line 83

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_contextObject



72
73
74
75
76
77
78
79
80
81
# File 'lib/rex/proto/ldap/client.rb', line 72

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

#naming_contextsArray<String>

Returns LDAP servers naming contexts.

Returns:

  • (Array<String>)

    LDAP servers naming contexts



20
21
22
# File 'lib/rex/proto/ldap/client.rb', line 20

def naming_contexts
  @naming_contexts ||= search_root_dse[:namingcontexts]
end

#peerhostString

Returns The remote IP address that LDAP is running on.

Returns:

  • (String)

    The remote IP address that LDAP is running on



35
36
37
# File 'lib/rex/proto/ldap/client.rb', line 35

def peerhost
  host
end

#peerinfoString

Returns The remote peer information containing IP and port.

Returns:

  • (String)

    The remote peer information containing IP and port



45
46
47
# File 'lib/rex/proto/ldap/client.rb', line 45

def peerinfo
  "#{peerhost}:#{peerport}"
end

#peerportInteger

Returns The remote port that LDAP is running on.

Returns:

  • (Integer)

    The remote port that LDAP is running on



40
41
42
# File 'lib/rex/proto/ldap/client.rb', line 40

def peerport
  port
end

#schema_dnString?

Returns LDAP servers Schema DN, nil if one isn’t found.

Returns:

  • (String, nil)

    LDAP servers Schema DN, nil if one isn’t found



30
31
32
# File 'lib/rex/proto/ldap/client.rb', line 30

def schema_dn
  @schema_dn ||= discover_schema_naming_context
end