Permalink
Browse files

Added a new filter type bineq that will create an equality filter and…

… NOT force

convert data to UTF-8. This is required for proper binary data filters in Microsoft
Active Directory.
  • Loading branch information...
DavidJLee authored and djlee2 committed Feb 24, 2012
1 parent 3345c58 commit c46c93777ee23e5b98f6a32ecfa0380bd0ad9560
Showing with 37 additions and 1 deletion.
  1. +1 −0 Contributors.rdoc
  2. +8 −0 lib/net/ber/core_ext/string.rb
  3. +23 −1 lib/net/ldap/filter.rb
  4. +5 −0 spec/unit/ber/ber_spec.rb
View
@@ -19,3 +19,4 @@ Contributions since:
* Derek Harmel (derekharmel)
* Erik Hetzner (egh)
* nowhereman
+* David J. Lee (DavidJLee)
@@ -16,6 +16,14 @@ def to_ber(code = 0x04)
[code].pack('C') + raw_string.length.to_ber_length_encoding + raw_string
end
+ ##
+ # Converts a string to a BER string but does *not* encode to UTF-8 first.
+ # This is required for proper representation of binary data for Microsoft
+ # Active Directory
+ def to_ber_bin(code = 0x04)
+ [code].pack('C') + length.to_ber_length_encoding + self
+ end
+
def raw_utf8_encoded
if self.respond_to?(:encode)
# Strings should be UTF-8 encoded according to LDAP.
View
@@ -23,7 +23,7 @@
class Net::LDAP::Filter
##
# Known filter types.
- FilterTypes = [ :ne, :eq, :ge, :le, :and, :or, :not, :ex ]
+ FilterTypes = [ :ne, :eq, :ge, :le, :and, :or, :not, :ex, :bineq ]
def initialize(op, left, right) #:nodoc:
unless FilterTypes.include?(op)
@@ -65,6 +65,23 @@ def eq(attribute, value)
new(:eq, attribute, value)
end
+ ##
+ # Creates a Filter object indicating a binary comparison.
+ # this prevents the search data from being forced into a UTF-8 string.
+ #
+ # This is primarily used for Microsoft Active Directory to compare
+ # GUID values.
+ #
+ # # for guid represented as hex charecters
+ # guid = "6a31b4a12aa27a41aca9603f27dd5116"
+ # guid_bin = [guid].pack("H*")
+ # f = Net::LDAP::Filter.bineq("objectGUID", guid_bin)
+ #
+ # This filter does not perform any escaping.
+ def bineq(attribute, value)
+ new(:bineq, attribute, value)
+ end
+
##
# Creates a Filter object indicating extensible comparison. This Filter
# object is currently considered EXPERIMENTAL.
@@ -399,6 +416,8 @@ def to_raw_rfc2254
"!(#{@left}=#{@right})"
when :eq
"#{@left}=#{@right}"
+ when :bineq
+ "#{@left}=#{@right}"
when :ex
"#{@left}:=#{@right}"
when :ge
@@ -508,6 +527,9 @@ def to_ber
else # equality
[@left.to_s.to_ber, unescape(@right).to_ber].to_ber_contextspecific(3)
end
+ when :bineq
+ # make sure data is not forced to UTF-8
+ [@left.to_s.to_ber, unescape(@right).to_ber_bin].to_ber_contextspecific(3)
when :ex
seq = []
@@ -84,6 +84,11 @@
it "should properly encode strings encodable as UTF-8" do
"teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring"
end
+ it "should properly encode binary data strings using to_ber_bin" do
+ # This is used for searching for GUIDs in Active Directory
+ ["6a31b4a12aa27a41aca9603f27dd5116"].pack("H*").to_ber_bin.should ==
+ "\x04\x10" + "j1\xB4\xA1*\xA2zA\xAC\xA9`?'\xDDQ\x16"
+ end
it "should fail on strings that can not be converted to UTF-8" do
error = Encoding::UndefinedConversionError
lambda {"\x81".to_ber }.should raise_exception(error)

0 comments on commit c46c937

Please sign in to comment.