DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

has posted 1 posts at DZone. View Full User Profile

Query Ldap With Ruby Ffi And Native Ldap C Api

02.09.2010
| 1297 views |
  • submit to reddit
        Simple example how to use ffi for query a ldap repository with the native ldap c api. Below the public ldap server <i>x500.bund.de</i> is used.
The example includes the usage of pointers as output parameters.

Tested on ubuntu with openLdap and ldap dev libs(libldap-2.4-2, libldap2-dev) installed.
require 'ffi'

module Ldap
	extend FFI::Library
  ffi_lib "/usr/lib/libldap.so"

#LDAP *ldap_open( char *hostname, int portno );
  attach_function :ldap_open, [:string, :int], :pointer
  
#   int ldap_search_s(
#                   LDAP            *ld,
#                   char            *base,
#                   int             scope,
#                   char            *filter,
#                   char            *attrs[],
#                   int             attrsonly,
#                   LDAPMessage     **res
#           );
  attach_function :ldap_search_s,[:pointer, :string, :int, :string, :pointer, :int, :pointer] , :int

# char *ldap_err2string( int err );
	attach_function :ldap_err2string, [:int], :string

#int ldap_count_entries( LDAP *ld, LDAPMessage *res );
	attach_function :ldap_count_entries, [:pointer, :pointer], :int
	
#LDAPMesage *ldap_next_entry( LDAP *ld, LDAPMessage *entry );
	attach_function :ldap_next_entry, [:pointer, :pointer], :pointer

#char *ldap_next_attribute(LDAP *ld, LDAPMessage     *entry, void *ptr );
	attach_function :ldap_next_attribute, [:pointer, :pointer, :pointer], :pointer

#char *ldap_get_dn( LDAP *ld, LDAPMessage *entry );
	attach_function :ldap_get_dn, [:pointer, :pointer], :string

  class Connection
  	include Ldap
  	
  	def self.open 
  		Connection.new 'x500.bund.de', 389
  	end
  	
  	def initialize host, port
  		@host = host
  		@port = port
  		
  		@con_handle = ldap_open host, port
  		raise "Unable to conect to #{host}:#{port}" if @con_handle.null?
  	end
  	
  	def search
  		objptr = FFI::MemoryPointer.new :pointer
  		res = ldap_search_s @con_handle, "o=Bund,c=DE", 2, nil, nil,0, objptr
  		puts "result: #{ldap_err2string res}"
  		
  		objptr = objptr.get_pointer(0)
  		puts "result count #{ldap_count_entries @con_handle, objptr}"
  		
  		while !objptr.null? 
  			puts "the entry name: #{ldap_get_dn @con_handle, objptr}"
  			objptr = ldap_next_entry @con_handle, objptr
  		end
	end
  end
end