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.
This commit is contained in:
parent
3345c58dfb
commit
c46c93777e
4 changed files with 37 additions and 1 deletions
|
@ -19,3 +19,4 @@ Contributions since:
|
||||||
* Derek Harmel (derekharmel)
|
* Derek Harmel (derekharmel)
|
||||||
* Erik Hetzner (egh)
|
* Erik Hetzner (egh)
|
||||||
* nowhereman
|
* nowhereman
|
||||||
|
* David J. Lee (DavidJLee)
|
||||||
|
|
|
@ -16,6 +16,14 @@ module Net::BER::Extensions::String
|
||||||
[code].pack('C') + raw_string.length.to_ber_length_encoding + raw_string
|
[code].pack('C') + raw_string.length.to_ber_length_encoding + raw_string
|
||||||
end
|
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
|
def raw_utf8_encoded
|
||||||
if self.respond_to?(:encode)
|
if self.respond_to?(:encode)
|
||||||
# Strings should be UTF-8 encoded according to LDAP.
|
# Strings should be UTF-8 encoded according to LDAP.
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
class Net::LDAP::Filter
|
class Net::LDAP::Filter
|
||||||
##
|
##
|
||||||
# Known filter types.
|
# 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:
|
def initialize(op, left, right) #:nodoc:
|
||||||
unless FilterTypes.include?(op)
|
unless FilterTypes.include?(op)
|
||||||
|
@ -65,6 +65,23 @@ class Net::LDAP::Filter
|
||||||
new(:eq, attribute, value)
|
new(:eq, attribute, value)
|
||||||
end
|
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
|
# Creates a Filter object indicating extensible comparison. This Filter
|
||||||
# object is currently considered EXPERIMENTAL.
|
# object is currently considered EXPERIMENTAL.
|
||||||
|
@ -399,6 +416,8 @@ class Net::LDAP::Filter
|
||||||
"!(#{@left}=#{@right})"
|
"!(#{@left}=#{@right})"
|
||||||
when :eq
|
when :eq
|
||||||
"#{@left}=#{@right}"
|
"#{@left}=#{@right}"
|
||||||
|
when :bineq
|
||||||
|
"#{@left}=#{@right}"
|
||||||
when :ex
|
when :ex
|
||||||
"#{@left}:=#{@right}"
|
"#{@left}:=#{@right}"
|
||||||
when :ge
|
when :ge
|
||||||
|
@ -508,6 +527,9 @@ class Net::LDAP::Filter
|
||||||
else # equality
|
else # equality
|
||||||
[@left.to_s.to_ber, unescape(@right).to_ber].to_ber_contextspecific(3)
|
[@left.to_s.to_ber, unescape(@right).to_ber].to_ber_contextspecific(3)
|
||||||
end
|
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
|
when :ex
|
||||||
seq = []
|
seq = []
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,11 @@ describe "BER encoding of" do
|
||||||
it "should properly encode strings encodable as UTF-8" do
|
it "should properly encode strings encodable as UTF-8" do
|
||||||
"teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring"
|
"teststring".encode("US-ASCII").to_ber.should == "\x04\nteststring"
|
||||||
end
|
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
|
it "should fail on strings that can not be converted to UTF-8" do
|
||||||
error = Encoding::UndefinedConversionError
|
error = Encoding::UndefinedConversionError
|
||||||
lambda {"\x81".to_ber }.should raise_exception(error)
|
lambda {"\x81".to_ber }.should raise_exception(error)
|
||||||
|
|
Loading…
Reference in a new issue