Search code examples
rubyldap

ruby throws exception by ldap search by empty field


I try to get some information from the LDAP (internal AD). Everything work as it should, except when I want get the data out of an empty field.

require 'net/ldap'
...

def getDatafromAD(ad_hostname,ad_dn,ad_password,username)
  ldap = Net::LDAP.new :host => ad_hostname, :port => 389, :auth => {
          :method => :simple,
          :username => ad_dn,
          :password => ad_password }

  filter = Net::LDAP::Filter.eq("cn", username)
  treebase = "ou=myOU,dc=example,dc=com"
  attrs = ["givenName", "mobile", "mail", "cn", "sn", "person"]

  ldap.search( :base => treebase, :filter => filter, :attributes => attrs ) do |entry|
         puts "UID: #{entry.dn}"
         puts "#{entry.cn.first}: Surename: #{entry.sn.first} Givenname: #{entry.givenName.first} Mail: #{entry.mail.first} Mobile: #{entry.mobile.first}"
  end

end

This is running fine until one field is empty (in this case mobile):

Traceback (most recent call last):
    16: from query_userdata.rb:79:in `<main>'
    15: from query_userdata.rb:79:in `each'
    14: from query_userdata.rb:81:in `block in <main>'
    13: from query_userdata.rb:58:in `getDatafromAD'
    12: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap.rb:782:in `search'
    11: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/instrumentation.rb:19:in `instrument'
    10: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap.rb:783:in `block in search'
     9: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap.rb:1311:in `use_connection'
     8: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap.rb:784:in `block (2 levels) in search'
     7: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/connection.rb:388:in `search'
     6: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/instrumentation.rb:19:in `instrument'
     5: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/connection.rb:399:in `block in search'
     4: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/connection.rb:399:in `loop'
     3: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/connection.rb:445:in `block (2 levels) in search'
     2: from /usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap.rb:786:in `block (3 levels) in search'
     1: from query_userdata.rb:62:in `block in getDatafromAD'
/usr/share/gems/gems/net-ldap-0.17.0/lib/net/ldap/entry.rb:185:in `method_missing': undefined method `mobile' for #<Net::LDAP::Entry:0x000055c0d912ac60> (NoMethodError)

Can someone please give me a hint how to solve this. My knowledge/XP can not handle this. I tried with .empty?() to check in advance, but it looks like in the moment of accessing the empty field the exception is here. If a field is empty I would like to put a custom string ("data not there") in the output. Probably it is just a little switch and I can not find it...

Many thanks!


Solution

  • I've faced the same issue 2 days ago ! I can recommend 2 things:

    • Access entry attributes through hash keys. Calling missing methods will rise an error, but trying to access a missing key's value will return an empty array
    entry[:missing_key]
    # => []
    
    entry[:missing_key][0]
    # => nil
    
    entry.missing_key.first
    # => *** NoMethodError Exception: undefined method `missing_key' for #<Net::LDAP::Entry:0x00005605a06bbf88>
    
    • Use a || operator when concatenating potential nil values with a String.
    puts "SN:     #{(entry[:sn][0]     || 'data not there')}" +
         "Mobile: #{(entry[:mobile][0] || 'data not there')}" +
         "Foo:    #{(entry[:foo][0]    || 'data not there')}"