Class: Cloudscaling::LDAPUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudscaling/ldap.rb

Overview

Tools for interacting with LDAP using a TCP connection

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, port = 389, auth_dn = nil, password = nil, tls_enable = true) ⇒ LDAPUtils

Returns a new instance of LDAPUtils.



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/cloudscaling/ldap.rb', line 137

def initialize(server, port = 389, auth_dn = nil, password = nil,
               tls_enable = true)
  args = { host: server,
           port: port }
  auth_dn && args.update(auth: { method: :simple,
                                 username: auth_dn,
                                 password: password })
  tls_enable && args.update(encryption: { method: :start_tls })
  @ldap = Net::LDAP.new(args)
  @ldap.bind || fail("LDAP bind failed: #{@ldap.get_operation_result}")
end

Class Method Details

.first_item(dn) ⇒ Object



171
172
173
174
# File 'lib/cloudscaling/ldap.rb', line 171

def self.first_item(dn)
  m = dn.match(/^([^=]+)=([^,]+)/)
  { m[1] => m[2] }
end

.openssl_extract_cert(rawcert) ⇒ Object



149
150
151
# File 'lib/cloudscaling/ldap.rb', line 149

def self.openssl_extract_cert(rawcert)
  OpenSSL::X509::Certificate.new(rawcert).to_s
end

.openssl_extract_key(rawcert, passphrase = nil) ⇒ Object



153
154
155
# File 'lib/cloudscaling/ldap.rb', line 153

def self.openssl_extract_key(rawcert, passphrase = nil)
  OpenSSL::PKey.read(rawcert, passphrase).to_s
end

.ssha_password(clear_password, salt = nil) ⇒ Object

Generate a rfc2307 SSHA-hashed password in the format that slapd likes www.openldap.org/faq/data/cache/347.html



159
160
161
162
163
164
165
166
167
168
169
# File 'lib/cloudscaling/ldap.rb', line 159

def self.ssha_password(clear_password, salt = nil)
  unless salt
    len = 16
    base = 16
    # rubocop:disable Style/SingleLineBlockParams
    salt = len.times.reduce('') { |a| a << rand(base).to_s(base) }
  end
  digest = Digest::SHA1.digest("#{clear_password}#{salt}")
  hash = Base64.encode64("#{digest}#{salt}").chomp
  "{SSHA}#{hash}"
end

Instance Method Details

#add_entry(dn, attrs) ⇒ Object

Add an entry to the directory dn: Distinguished name of the new entry attrs: hash of entry attributes



185
186
187
188
189
# File 'lib/cloudscaling/ldap.rb', line 185

def add_entry(dn, attrs)
  # Chef::Log.info "Add LDAP entry: #{dn} #{attrs}"
  @ldap.add(dn: dn, attributes: attrs) ||
    fail("LDAP add failure: #{@ldap.get_operation_result}")
end

#add_or_update_entry(dn, attrs) ⇒ Object

Add or update a directory entry. If the entry exists, any attributes provided to this function will be updated with a “replace” operation, which will add the attributes if necessary, and replace all values of the attribute otherwise.



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/cloudscaling/ldap.rb', line 195

def add_or_update_entry(dn, attrs)
  ret = @ldap.search(base: dn,
                     scope: Net::LAP::SearchScope_BaseObject,
                     return_result: true)
  entries && entries.size > 1 && fail("#{dn} matches more than one entry")
  if ret.nil?
    add_entry(dn, attrs)
  else
    entry = ret.first
    ops = attrs.each_with_object(Array.new) do |(k, v), acc|
      acc << [:replace, k, v] unless entry[k] == [v].flatten
    end
    # Chef::Log.info("Update LDAP entry: dn=#{dn}")
    @ldap.modify(dn: dn, operations: ops) ||
      fail("LDAP update failure: #{@ldap.get_operation_result}")
  end
end

#dn_exists?(dn) ⇒ Boolean

Returns:

  • (Boolean)


176
177
178
179
180
# File 'lib/cloudscaling/ldap.rb', line 176

def dn_exists?(dn)
  @ldap.search(base: dn,
               scope: Net::LDAP::SearchScope_BaseObject,
               return_result: false)
end