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
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 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
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
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
# File lib/net/ldap/filter.rb, line 86 def Filter::le attribute, value; Filter.new :le, attribute, value; end
# File lib/net/ldap/filter.rb, line 82 def Filter::ne attribute, value; Filter.new :ne, attribute, value; end
# File lib/net/ldap/filter.rb, line 51 def initialize op, a, b @op = op @left = a @right = b end
# 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 ) 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
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
# File lib/net/ldap/filter.rb, line 235 def coalesce operator if @op == operator [@left.coalesce( operator ), @right.coalesce( operator )] else [self] end end
# 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
# 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
# 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
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