class Net::LDAP::Filter

Class Net::LDAP::Filter is used to constrain LDAP searches. An object of this class is passed to Net::LDAP#search in the parameter :filter.

Net::LDAP::Filter supports the complete set of search filters available in LDAP, including conjunction, disjunction and negation (AND, OR, and NOT). This class supplants the (infamous) RFC-2254 standard notation for specifying LDAP search filters.

Here’s how to code the familiar “objectclass is present” filter:

f = Net::LDAP::Filter.pres( "objectclass" )

The object returned by this code can be passed directly to the :filter parameter of Net::LDAP#search.

See the individual class and instance methods below for more examples.

Public Class Methods

construct(ldap_filter_string) click to toggle source

Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254) to a Net::LDAP::Filter.

# File lib/net/ldap/filter.rb, line 282
def self.construct ldap_filter_string
  FilterParser.new(ldap_filter_string).filter
end
eq(attribute, value;) click to toggle source

eq creates a filter object indicating that the value of a paticular attribute must be either present or must match a particular string.

To specify that an attribute is “present” means that only directory entries which contain a value for the particular attribute will be selected by the filter. This is useful in case of optional attributes such as mail. Presence is indicated by giving the value “*” in the second parameter to eq. This example selects only entries that have one or more values for sAMAccountName:

f = Net::LDAP::Filter.eq( "sAMAccountName", "*" )

To match a particular range of values, pass a string as the second parameter to eq. The string may contain one or more “*” characters as wildcards: these match zero or more occurrences of any character. Full regular-expressions are not supported due to limitations in the underlying LDAP protocol. This example selects any entry with a mail value containing the substring “anderson”:

f = Net::LDAP::Filter.eq( "mail", "*anderson*" )
# File lib/net/ldap/filter.rb, line 81
def Filter::eq attribute, value; Filter.new :eq, attribute, value; end
from_rfc2254(ldap_filter_string) click to toggle source

Synonym for construct. to a Net::LDAP::Filter.

# File lib/net/ldap/filter.rb, line 288
def self.from_rfc2254 ldap_filter_string
  construct ldap_filter_string
end
ge(attribute, value;) click to toggle source

def Filter::gt attribute, value; Filter.new :gt, attribute, value; end def Filter::lt attribute, value; Filter.new :lt, attribute, value; end

# File lib/net/ldap/filter.rb, line 85
def Filter::ge attribute, value; Filter.new :ge, attribute, value; end
le(attribute, value;) click to toggle source
# File lib/net/ldap/filter.rb, line 86
def Filter::le attribute, value; Filter.new :le, attribute, value; end
ne(attribute, value;) click to toggle source
# File lib/net/ldap/filter.rb, line 82
def Filter::ne attribute, value; Filter.new :ne, attribute, value; end
new(op, a, b) click to toggle source
# File lib/net/ldap/filter.rb, line 51
def initialize op, a, b
  @op = op
  @left = a
  @right = b
end
parse_ldap_filter(obj) click to toggle source
# File lib/net/ldap/filter.rb, line 251
def Filter::parse_ldap_filter obj
  case obj.ber_identifier
  when 0x87         # present. context-specific primitive 7.
    Filter.eq( obj.to_s, "*" )
  when 0xa3         # equalityMatch. context-specific constructed 3.
    Filter.eq( obj[0], obj[1] )
  else
    raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" )
  end
end
pres(attribute;) click to toggle source

pres( attribute ) is a synonym for eq( attribute, “*” )

# File lib/net/ldap/filter.rb, line 90
def Filter::pres attribute; Filter.eq attribute, "*"; end

Public Instance Methods

&(filter;) click to toggle source

operator & (“AND”) is used to conjoin two or more filters. This expression will select only entries that have an objectclass attribute AND have a mail attribute that begins with “George”:

f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" )
# File lib/net/ldap/filter.rb, line 97
def & filter; Filter.new :and, self, filter; end
coalesce(operator) click to toggle source
# File lib/net/ldap/filter.rb, line 235
def coalesce operator
  if @op == operator
    [@left.coalesce( operator ), @right.coalesce( operator )]
  else
    [self]
  end
end
match(entry) click to toggle source
# File lib/net/ldap/filter.rb, line 267
def match entry
  case @op
  when :eq
    if @right == "*"
      l = entry[@left] and l.length > 0
    else
      l = entry[@left] and l = l.to_a and l.index(@right)
    end
  else
    raise LdapError.new( "unknown filter type in match: #{@op}" )
  end
end
to_ber() click to toggle source
# File lib/net/ldap/filter.rb, line 182
def to_ber
  case @op
  when :eq
    if @right == "*"          # present
      @left.to_s.to_ber_contextspecific 7
    elsif @right =~ /[\*]/    #substring
      ary = @right.split( /[\*]+/ )
      final_star = @right =~ /[\*]$/
      initial_star = ary.first == "" and ary.shift

      seq = []
      unless initial_star
        seq << ary.shift.to_ber_contextspecific(0)
      end
      n_any_strings = ary.length - (final_star ? 0 : 1)
      #p n_any_strings
      n_any_strings.times {
        seq << ary.shift.to_ber_contextspecific(1)
      }
      unless final_star
        seq << ary.shift.to_ber_contextspecific(2)
      end
      [@left.to_s.to_ber, seq.to_ber].to_ber_contextspecific 4
    else                      #equality
      [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 3
    end
  when :ge
    [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 5
  when :le
    [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 6
  when :and
    ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten
    ary.map {|a| a.to_ber}.to_ber_contextspecific( 0 )
  when :or
    ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten
    ary.map {|a| a.to_ber}.to_ber_contextspecific( 1 )
  when :not
      [@left.to_ber].to_ber_contextspecific 2
  else
    # ERROR, we'll return objectclass=* to keep things from blowing up,
    # but that ain't a good answer and we need to kick out an error of some kind.
    raise "unimplemented search filter"
  end
end
to_s() click to toggle source
# File lib/net/ldap/filter.rb, line 119
def to_s
  case @op
  when :ne
    "(!(#{@left}=#{@right}))"
  when :eq
    "(#{@left}=#{@right})"
  #when :gt
   # "#{@left}>#{@right}"
  #when :lt
   # "#{@left}<#{@right}"
  when :ge
    "#{@left}>=#{@right}"
  when :le
    "#{@left}<=#{@right}"
  when :and
    "(&(#{@left})(#{@right}))"
  when :or
    "(|(#{@left})(#{@right}))"
  when :not
    "(!(#{@left}))"
  else
    raise "invalid or unsupported operator in LDAP Filter"
  end
end
|(filter;) click to toggle source

operator | (“OR”) is used to disjoin two or more filters. This expression will select entries that have either an objectclass attribute OR a mail attribute that begins with “George”:

f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" )
# File lib/net/ldap/filter.rb, line 104
def | filter; Filter.new :or, self, filter; end