diff options
Diffstat (limited to 'vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap')
5 files changed, 929 insertions, 0 deletions
diff --git a/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/dataset.rb b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/dataset.rb new file mode 100644 index 000000000..1480a8f84 --- /dev/null +++ b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/dataset.rb @@ -0,0 +1,108 @@ +# $Id: dataset.rb 78 2006-04-26 02:57:34Z blackhedd $ +# +# +#---------------------------------------------------------------------------- +# +# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. +# +# Gmail: garbagecat10 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--------------------------------------------------------------------------- +# +# + + + + +module Net +class LDAP + +class Dataset < Hash + + attr_reader :comments + + + def Dataset::read_ldif io + ds = Dataset.new + + line = io.gets && chomp + dn = nil + + while line + io.gets and chomp + if $_ =~ /^[\s]+/ + line << " " << $' + else + nextline = $_ + + if line =~ /^\#/ + ds.comments << line + elsif line =~ /^dn:[\s]*/i + dn = $' + ds[dn] = Hash.new {|k,v| k[v] = []} + elsif line.length == 0 + dn = nil + elsif line =~ /^([^:]+):([\:]?)[\s]*/ + # $1 is the attribute name + # $2 is a colon iff the attr-value is base-64 encoded + # $' is the attr-value + # Avoid the Base64 class because not all Ruby versions have it. + attrvalue = ($2 == ":") ? $'.unpack('m').shift : $' + ds[dn][$1.downcase.intern] << attrvalue + end + + line = nextline + end + end + + ds + end + + + def initialize + @comments = [] + end + + + def to_ldif + ary = [] + ary += (@comments || []) + + keys.sort.each {|dn| + ary << "dn: #{dn}" + + self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr| + self[dn][attr.intern].each {|val| + ary << "#{attr}: #{val}" + } + } + + ary << "" + } + + block_given? and ary.each {|line| yield line} + + ary + end + + +end # Dataset + +end # LDAP +end # Net + + diff --git a/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/entry.rb b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/entry.rb new file mode 100644 index 000000000..8978545ee --- /dev/null +++ b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/entry.rb @@ -0,0 +1,165 @@ +# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $ +# +# LDAP Entry (search-result) support classes +# +# +#---------------------------------------------------------------------------- +# +# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. +# +# Gmail: garbagecat10 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--------------------------------------------------------------------------- +# + + + + +module Net +class LDAP + + + # Objects of this class represent individual entries in an LDAP + # directory. User code generally does not instantiate this class. + # Net::LDAP#search provides objects of this class to user code, + # either as block parameters or as return values. + # + # In LDAP-land, an "entry" is a collection of attributes that are + # uniquely and globally identified by a DN ("Distinguished Name"). + # Attributes are identified by short, descriptive words or phrases. + # Although a directory is + # free to implement any attribute name, most of them follow rigorous + # standards so that the range of commonly-encountered attribute + # names is not large. + # + # An attribute name is case-insensitive. Most directories also + # restrict the range of characters allowed in attribute names. + # To simplify handling attribute names, Net::LDAP::Entry + # internally converts them to a standard format. Therefore, the + # methods which take attribute names can take Strings or Symbols, + # and work correctly regardless of case or capitalization. + # + # An attribute consists of zero or more data items called + # <i>values.</i> An entry is the combination of a unique DN, a set of attribute + # names, and a (possibly-empty) array of values for each attribute. + # + # Class Net::LDAP::Entry provides convenience methods for dealing + # with LDAP entries. + # In addition to the methods documented below, you may access individual + # attributes of an entry simply by giving the attribute name as + # the name of a method call. For example: + # ldap.search( ... ) do |entry| + # puts "Common name: #{entry.cn}" + # puts "Email addresses:" + # entry.mail.each {|ma| puts ma} + # end + # If you use this technique to access an attribute that is not present + # in a particular Entry object, a NoMethodError exception will be raised. + # + #-- + # Ugly problem to fix someday: We key off the internal hash with + # a canonical form of the attribute name: convert to a string, + # downcase, then take the symbol. Unfortunately we do this in + # at least three places. Should do it in ONE place. + class Entry + + # This constructor is not generally called by user code. + def initialize dn = nil # :nodoc: + @myhash = Hash.new {|k,v| k[v] = [] } + @myhash[:dn] = [dn] + end + + + def []= name, value # :nodoc: + sym = name.to_s.downcase.intern + @myhash[sym] = value + end + + + #-- + # We have to deal with this one as we do with []= + # because this one and not the other one gets called + # in formulations like entry["CN"] << cn. + # + def [] name # :nodoc: + name = name.to_s.downcase.intern unless name.is_a?(Symbol) + @myhash[name] + end + + # Returns the dn of the Entry as a String. + def dn + self[:dn][0] + end + + # Returns an array of the attribute names present in the Entry. + def attribute_names + @myhash.keys + end + + # Accesses each of the attributes present in the Entry. + # Calls a user-supplied block with each attribute in turn, + # passing two arguments to the block: a Symbol giving + # the name of the attribute, and a (possibly empty) + # Array of data values. + # + def each + if block_given? + attribute_names.each {|a| + attr_name,values = a,self[a] + yield attr_name, values + } + end + end + + alias_method :each_attribute, :each + + + #-- + # Convenience method to convert unknown method names + # to attribute references. Of course the method name + # comes to us as a symbol, so let's save a little time + # and not bother with the to_s.downcase two-step. + # Of course that means that a method name like mAIL + # won't work, but we shouldn't be encouraging that + # kind of bad behavior in the first place. + # Maybe we should thow something if the caller sends + # arguments or a block... + # + def method_missing *args, &block # :nodoc: + s = args[0].to_s.downcase.intern + if attribute_names.include?(s) + self[s] + elsif s.to_s[-1] == 61 and s.to_s.length > 1 + value = args[1] or raise RuntimeError.new( "unable to set value" ) + value = [value] unless value.is_a?(Array) + name = s.to_s[0..-2].intern + self[name] = value + else + raise NoMethodError.new( "undefined method '#{s}'" ) + end + end + + def write + end + + end # class Entry + + +end # class LDAP +end # module Net + + diff --git a/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/filter.rb b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/filter.rb new file mode 100644 index 000000000..38944a710 --- /dev/null +++ b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/filter.rb @@ -0,0 +1,387 @@ +# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $ +# +# +#---------------------------------------------------------------------------- +# +# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. +# +# Gmail: garbagecat10 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--------------------------------------------------------------------------- +# +# + + +module Net +class LDAP + + +# 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 <tt>:filter</tt> parameter of Net::LDAP#search. +# +# See the individual class and instance methods below for more examples. +# +class Filter + + def initialize op, a, b + @op = op + @left = a + @right = b + end + + # #eq creates a filter object indicating that the value of + # a paticular attribute must be either <i>present</i> 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 <tt>mail.</tt> + # 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 <tt>sAMAccountName:</tt> + # 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 <i>not</i> supported + # due to limitations in the underlying LDAP protocol. + # This example selects any entry with a <tt>mail</tt> value containing + # the substring "anderson": + # f = Net::LDAP::Filter.eq( "mail", "*anderson*" ) + #-- + # Removed gt and lt. They ain't in the standard! + # + def Filter::eq attribute, value; Filter.new :eq, attribute, value; end + def Filter::ne attribute, value; Filter.new :ne, attribute, value; end + #def Filter::gt attribute, value; Filter.new :gt, attribute, value; end + #def Filter::lt attribute, value; Filter.new :lt, attribute, value; end + def Filter::ge attribute, value; Filter.new :ge, attribute, value; end + def Filter::le attribute, value; Filter.new :le, attribute, value; end + + # #pres( attribute ) is a synonym for #eq( attribute, "*" ) + # + def Filter::pres attribute; Filter.eq attribute, "*"; end + + # operator & ("AND") is used to conjoin two or more filters. + # This expression will select only entries that have an <tt>objectclass</tt> + # attribute AND have a <tt>mail</tt> attribute that begins with "George": + # f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" ) + # + def & filter; Filter.new :and, self, filter; end + + # operator | ("OR") is used to disjoin two or more filters. + # This expression will select entries that have either an <tt>objectclass</tt> + # attribute OR a <tt>mail</tt> attribute that begins with "George": + # f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" ) + # + def | filter; Filter.new :or, self, filter; end + + + # + # operator ~ ("NOT") is used to negate a filter. + # This expression will select only entries that <i>do not</i> have an <tt>objectclass</tt> + # attribute: + # f = ~ Net::LDAP::Filter.pres( "objectclass" ) + # + #-- + # This operator can't be !, evidently. Try it. + # Removed GT and LT. They're not in the RFC. + def ~@; Filter.new :not, self, nil; end + + + 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 + + + #-- + # to_ber + # Filter ::= + # CHOICE { + # and [0] SET OF Filter, + # or [1] SET OF Filter, + # not [2] Filter, + # equalityMatch [3] AttributeValueAssertion, + # substrings [4] SubstringFilter, + # greaterOrEqual [5] AttributeValueAssertion, + # lessOrEqual [6] AttributeValueAssertion, + # present [7] AttributeType, + # approxMatch [8] AttributeValueAssertion + # } + # + # SubstringFilter + # SEQUENCE { + # type AttributeType, + # SEQUENCE OF CHOICE { + # initial [0] LDAPString, + # any [1] LDAPString, + # final [2] LDAPString + # } + # } + # + # Parsing substrings is a little tricky. + # We use the split method to break a string into substrings + # delimited by the * (star) character. But we also need + # to know whether there is a star at the head and tail + # of the string. A Ruby particularity comes into play here: + # if you split on * and the first character of the string is + # a star, then split will return an array whose first element + # is an _empty_ string. But if the _last_ character of the + # string is star, then split will return an array that does + # _not_ add an empty string at the end. So we have to deal + # with all that specifically. + # + 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 + + #-- + # coalesce + # This is a private helper method for dealing with chains of ANDs and ORs + # that are longer than two. If BOTH of our branches are of the specified + # type of joining operator, then return both of them as an array (calling + # coalesce recursively). If they're not, then return an array consisting + # only of self. + # + def coalesce operator + if @op == operator + [@left.coalesce( operator ), @right.coalesce( operator )] + else + [self] + end + end + + + + #-- + # We get a Ruby object which comes from parsing an RFC-1777 "Filter" + # object. Convert it to a Net::LDAP::Filter. + # TODO, we're hardcoding the RFC-1777 BER-encodings of the various + # filter types. Could pull them out into a constant. + # + 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 + + + #-- + # We got a hash of attribute values. + # Do we match the attributes? + # Return T/F, and call match recursively as necessary. + 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 + + # Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254) + # to a Net::LDAP::Filter. + def self.construct ldap_filter_string + FilterParser.new(ldap_filter_string).filter + end + + # Synonym for #construct. + # to a Net::LDAP::Filter. + def self.from_rfc2254 ldap_filter_string + construct ldap_filter_string + end + +end # class Net::LDAP::Filter + + + +class FilterParser #:nodoc: + + attr_reader :filter + + def initialize str + require 'strscan' + @filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" ) + end + + def parse scanner + parse_filter_branch(scanner) or parse_paren_expression(scanner) + end + + def parse_paren_expression scanner + if scanner.scan /\s*\(\s*/ + b = if scanner.scan /\s*\&\s*/ + a = nil + branches = [] + while br = parse_paren_expression(scanner) + branches << br + end + if branches.length >= 2 + a = branches.shift + while branches.length > 0 + a = a & branches.shift + end + a + end + elsif scanner.scan /\s*\|\s*/ + # TODO: DRY! + a = nil + branches = [] + while br = parse_paren_expression(scanner) + branches << br + end + if branches.length >= 2 + a = branches.shift + while branches.length > 0 + a = a | branches.shift + end + a + end + elsif scanner.scan /\s*\!\s*/ + br = parse_paren_expression(scanner) + if br + ~ br + end + else + parse_filter_branch( scanner ) + end + + if b and scanner.scan( /\s*\)\s*/ ) + b + end + end + end + + # Added a greatly-augmented filter contributed by Andre Nathan + # for detecting special characters in values. (15Aug06) + def parse_filter_branch scanner + scanner.scan /\s*/ + if token = scanner.scan( /[\w\-_]+/ ) + scanner.scan /\s*/ + if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ ) + scanner.scan /\s*/ + #if value = scanner.scan( /[\w\*\.]+/ ) (ORG) + if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ ) + case op + when "=" + Filter.eq( token, value ) + when "!=" + Filter.ne( token, value ) + when "<" + Filter.lt( token, value ) + when "<=" + Filter.le( token, value ) + when ">" + Filter.gt( token, value ) + when ">=" + Filter.ge( token, value ) + end + end + end + end + end + +end # class Net::LDAP::FilterParser + +end # class Net::LDAP +end # module Net + + diff --git a/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/pdu.rb b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/pdu.rb new file mode 100644 index 000000000..dbc0d6f10 --- /dev/null +++ b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/pdu.rb @@ -0,0 +1,205 @@ +# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $ +# +# LDAP PDU support classes +# +# +#---------------------------------------------------------------------------- +# +# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. +# +# Gmail: garbagecat10 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--------------------------------------------------------------------------- +# + + + +module Net + + +class LdapPduError < Exception; end + + +class LdapPdu + + BindResult = 1 + SearchReturnedData = 4 + SearchResult = 5 + ModifyResponse = 7 + AddResponse = 9 + DeleteResponse = 11 + ModifyRDNResponse = 13 + SearchResultReferral = 19 + + attr_reader :msg_id, :app_tag + attr_reader :search_dn, :search_attributes, :search_entry + attr_reader :search_referrals + + # + # initialize + # An LDAP PDU always looks like a BerSequence with + # at least two elements: an integer (message-id number), and + # an application-specific sequence. + # Some LDAPv3 packets also include an optional + # third element, which is a sequence of "controls" + # (See RFC 2251, section 4.1.12). + # The application-specific tag in the sequence tells + # us what kind of packet it is, and each kind has its + # own format, defined in RFC-1777. + # Observe that many clients (such as ldapsearch) + # do not necessarily enforce the expected application + # tags on received protocol packets. This implementation + # does interpret the RFC strictly in this regard, and + # it remains to be seen whether there are servers out + # there that will not work well with our approach. + # + # Added a controls-processor to SearchResult. + # Didn't add it everywhere because it just _feels_ + # like it will need to be refactored. + # + def initialize ber_object + begin + @msg_id = ber_object[0].to_i + @app_tag = ber_object[1].ber_identifier - 0x60 + rescue + # any error becomes a data-format error + raise LdapPduError.new( "ldap-pdu format error" ) + end + + case @app_tag + when BindResult + parse_ldap_result ber_object[1] + when SearchReturnedData + parse_search_return ber_object[1] + when SearchResultReferral + parse_search_referral ber_object[1] + when SearchResult + parse_ldap_result ber_object[1] + parse_controls(ber_object[2]) if ber_object[2] + when ModifyResponse + parse_ldap_result ber_object[1] + when AddResponse + parse_ldap_result ber_object[1] + when DeleteResponse + parse_ldap_result ber_object[1] + when ModifyRDNResponse + parse_ldap_result ber_object[1] + else + raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" ) + end + end + + # + # result_code + # This returns an LDAP result code taken from the PDU, + # but it will be nil if there wasn't a result code. + # That can easily happen depending on the type of packet. + # + def result_code code = :resultCode + @ldap_result and @ldap_result[code] + end + + # Return RFC-2251 Controls if any. + # Messy. Does this functionality belong somewhere else? + def result_controls + @ldap_controls || [] + end + + + # + # parse_ldap_result + # + def parse_ldap_result sequence + sequence.length >= 3 or raise LdapPduError + @ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]} + end + private :parse_ldap_result + + # + # parse_search_return + # Definition from RFC 1777 (we're handling application-4 here) + # + # Search Response ::= + # CHOICE { + # entry [APPLICATION 4] SEQUENCE { + # objectName LDAPDN, + # attributes SEQUENCE OF SEQUENCE { + # AttributeType, + # SET OF AttributeValue + # } + # }, + # resultCode [APPLICATION 5] LDAPResult + # } + # + # We concoct a search response that is a hash of the returned attribute values. + # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES. + # This is to make them more predictable for user programs, but it + # may not be a good idea. Maybe this should be configurable. + # ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes, + # we also return @search_entry, which is an LDAP::Entry object. + # If that works out well, then we'll remove the first two. + # + # Provisionally removed obsolete search_attributes and search_dn, 04May06. + # + def parse_search_return sequence + sequence.length >= 2 or raise LdapPduError + @search_entry = LDAP::Entry.new( sequence[0] ) + #@search_dn = sequence[0] + #@search_attributes = {} + sequence[1].each {|seq| + @search_entry[seq[0]] = seq[1] + #@search_attributes[seq[0].downcase.intern] = seq[1] + } + end + + # + # A search referral is a sequence of one or more LDAP URIs. + # Any number of search-referral replies can be returned by the server, interspersed + # with normal replies in any order. + # Until I can think of a better way to do this, we'll return the referrals as an array. + # It'll be up to higher-level handlers to expose something reasonable to the client. + def parse_search_referral uris + @search_referrals = uris + end + + + # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting + # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL + # Octet String. If only two fields are given, the second one may be + # either criticality or data, since criticality has a default value. + # Someday we may want to come back here and add support for some of + # more-widely used controls. RFC-2696 is a good example. + # + def parse_controls sequence + @ldap_controls = sequence.map do |control| + o = OpenStruct.new + o.oid,o.criticality,o.value = control[0],control[1],control[2] + if o.criticality and o.criticality.is_a?(String) + o.value = o.criticality + o.criticality = false + end + o + end + end + private :parse_controls + + +end + + +end # module Net + diff --git a/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/psw.rb b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/psw.rb new file mode 100644 index 000000000..89d1ffdf2 --- /dev/null +++ b/vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/psw.rb @@ -0,0 +1,64 @@ +# $Id: psw.rb 73 2006-04-24 21:59:35Z blackhedd $ +# +# +#---------------------------------------------------------------------------- +# +# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. +# +# Gmail: garbagecat10 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +#--------------------------------------------------------------------------- +# +# + + +module Net +class LDAP + + +class Password + class << self + + # Generate a password-hash suitable for inclusion in an LDAP attribute. + # Pass a hash type (currently supported: :md5 and :sha) and a plaintext + # password. This function will return a hashed representation. + # STUB: This is here to fulfill the requirements of an RFC, which one? + # TODO, gotta do salted-sha and (maybe) salted-md5. + # Should we provide sha1 as a synonym for sha1? I vote no because then + # should you also provide ssha1 for symmetry? + def generate( type, str ) + case type + when :md5 + require 'md5' + "{MD5}#{ [MD5.new( str.to_s ).digest].pack("m").chomp }" + when :sha + require 'sha1' + "{SHA}#{ [SHA1.new( str.to_s ).digest].pack("m").chomp }" + # when ssha + else + raise Net::LDAP::LdapError.new( "unsupported password-hash type (#{type})" ) + end + end + + end +end + + +end # class LDAP +end # module Net + + |