Project

General

Profile

Feature #1060 » net-ldap-0.2.2_r5657.patch

Florian Mutter, 2011-05-06 01:13

View differences:

vendor/plugins/ruby-net-ldap-0.0.4/tests/testldif.rb (working copy)
1
# $Id: testldif.rb 61 2006-04-18 20:55:55Z blackhedd $
2
#
3
#
4

  
5

  
6
$:.unshift "lib"
7

  
8
require 'test/unit'
9

  
10
require 'net/ldap'
11
require 'net/ldif'
12

  
13
require 'sha1'
14
require 'base64'
15

  
16
class TestLdif < Test::Unit::TestCase
17

  
18
  TestLdifFilename = "tests/testdata.ldif"
19

  
20
  def test_empty_ldif
21
    ds = Net::LDAP::Dataset::read_ldif( StringIO.new )
22
    assert_equal( true, ds.empty? )
23
  end
24

  
25
  def test_ldif_with_comments
26
    str = ["# Hello from LDIF-land", "# This is an unterminated comment"]
27
    io = StringIO.new( str[0] + "\r\n" + str[1] )
28
    ds = Net::LDAP::Dataset::read_ldif( io )
29
    assert_equal( str, ds.comments )
30
  end
31

  
32
  def test_ldif_with_password
33
    psw = "goldbricks"
34
    hashed_psw = "{SHA}" + Base64::encode64( SHA1.new(psw).digest ).chomp
35

  
36
    ldif_encoded = Base64::encode64( hashed_psw ).chomp
37
    ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n" ))
38
    recovered_psw = ds["Goldbrick"][:userpassword].shift
39
    assert_equal( hashed_psw, recovered_psw )
40
  end
41

  
42
  def test_ldif_with_continuation_lines
43
    ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: abcdefg\r\n   hijklmn\r\n\r\n" ))
44
    assert_equal( true, ds.has_key?( "abcdefg hijklmn" ))
45
  end
46

  
47
  # TODO, INADEQUATE. We need some more tests
48
  # to verify the content.
49
  def test_ldif
50
    File.open( TestLdifFilename, "r" ) {|f|
51
      ds = Net::LDAP::Dataset::read_ldif( f )
52
      assert_equal( 13, ds.length )
53
    }
54
  end
55

  
56
  # TODO, need some tests.
57
  # Must test folded lines and base64-encoded lines as well as normal ones.
58
  def test_to_ldif
59
    File.open( TestLdifFilename, "r" ) {|f|
60
      ds = Net::LDAP::Dataset::read_ldif( f )
61
      ds.to_ldif
62
      assert_equal( true, false ) # REMOVE WHEN WE HAVE SOME TESTS HERE.
63
    }
64
  end
65

  
66

  
67
end
68

  
69

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testldap.rb (working copy)
1
# $Id: testldap.rb 65 2006-04-23 01:17:49Z blackhedd $
2
#
3
#
4

  
5

  
6
$:.unshift "lib"
7

  
8
require 'test/unit'
9

  
10
require 'net/ldap'
11
require 'stringio'
12

  
13

  
14
class TestLdapClient < Test::Unit::TestCase
15

  
16
  # TODO: these tests crash and burn if the associated
17
  # LDAP testserver isn't up and running.
18
  # We rely on being able to read a file with test data
19
  # in LDIF format.
20
  # TODO, WARNING: for the moment, this data is in a file
21
  # whose name and location are HARDCODED into the
22
  # instance method load_test_data.
23

  
24
  def setup
25
    @host = "127.0.0.1"
26
    @port = 3890
27
    @auth = {
28
      :method => :simple,
29
      :username => "cn=bigshot,dc=bayshorenetworks,dc=com",
30
      :password => "opensesame"
31
    }
32

  
33
    @ldif = load_test_data
34
  end
35

  
36

  
37

  
38
  # Get some test data which will be used to validate
39
  # the responses from the test LDAP server we will
40
  # connect to.
41
  # TODO, Bogus: we are HARDCODING the location of the file for now.
42
  #
43
  def load_test_data
44
    ary = File.readlines( "tests/testdata.ldif" )
45
    hash = {}
46
    while line = ary.shift and line.chomp!
47
      if line =~ /^dn:[\s]*/i
48
        dn = $'
49
        hash[dn] = {}
50
        while attr = ary.shift and attr.chomp! and attr =~ /^([\w]+)[\s]*:[\s]*/
51
          hash[dn][$1.downcase.intern] ||= []
52
          hash[dn][$1.downcase.intern] << $'
53
        end
54
      end
55
    end
56
    hash
57
  end
58

  
59

  
60

  
61
  # Binding tests.
62
  # Need tests for all kinds of network failures and incorrect auth.
63
  # TODO: Implement a class-level timeout for operations like bind.
64
  # Search has a timeout defined at the protocol level, other ops do not.
65
  # TODO, use constants for the LDAP result codes, rather than hardcoding them.
66
  def test_bind
67
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
68
    assert_equal( true, ldap.bind )
69
    assert_equal( 0, ldap.get_operation_result.code )
70
    assert_equal( "Success", ldap.get_operation_result.message )
71

  
72
    bad_username = @auth.merge( {:username => "cn=badguy,dc=imposters,dc=com"} )
73
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_username
74
    assert_equal( false, ldap.bind )
75
    assert_equal( 48, ldap.get_operation_result.code )
76
    assert_equal( "Inappropriate Authentication", ldap.get_operation_result.message )
77

  
78
    bad_password = @auth.merge( {:password => "cornhusk"} )
79
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_password
80
    assert_equal( false, ldap.bind )
81
    assert_equal( 49, ldap.get_operation_result.code )
82
    assert_equal( "Invalid Credentials", ldap.get_operation_result.message )
83
  end
84

  
85

  
86

  
87
  def test_search
88
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
89

  
90
    search = {:base => "dc=smalldomain,dc=com"}
91
    assert_equal( false, ldap.search( search ))
92
    assert_equal( 32, ldap.get_operation_result.code )
93
    
94
    search = {:base => "dc=bayshorenetworks,dc=com"}
95
    assert_equal( true, ldap.search( search ))
96
    assert_equal( 0, ldap.get_operation_result.code )
97
    
98
    ldap.search( search ) {|res|
99
      assert_equal( res, @ldif )
100
    }
101
  end
102
    
103

  
104

  
105

  
106
  # This is a helper routine for test_search_attributes.
107
  def internal_test_search_attributes attrs_to_search
108
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
109
    assert( ldap.bind )
110

  
111
    search = {
112
      :base => "dc=bayshorenetworks,dc=com",
113
      :attributes => attrs_to_search
114
    }
115

  
116
    ldif = @ldif
117
    ldif.each {|dn,entry|
118
      entry.delete_if {|attr,value|
119
        ! attrs_to_search.include?(attr)
120
      }
121
    }
122
  
123
    assert_equal( true, ldap.search( search ))
124
    ldap.search( search ) {|res|
125
      res_keys = res.keys.sort
126
      ldif_keys = ldif.keys.sort
127
      assert( res_keys, ldif_keys )
128
      res.keys.each {|rk|
129
        assert( res[rk], ldif[rk] )
130
      }
131
    }
132
  end
133

  
134

  
135
  def test_search_attributes
136
    internal_test_search_attributes [:mail]
137
    internal_test_search_attributes [:cn]
138
    internal_test_search_attributes [:ou]
139
    internal_test_search_attributes [:hasaccessprivilege]
140
    internal_test_search_attributes ["mail"]
141
    internal_test_search_attributes ["cn"]
142
    internal_test_search_attributes ["ou"]
143
    internal_test_search_attributes ["hasaccessrole"]
144

  
145
    internal_test_search_attributes [:mail, :cn, :ou, :hasaccessrole]
146
    internal_test_search_attributes [:mail, "cn", :ou, "hasaccessrole"]
147
  end
148

  
149

  
150
  def test_search_filters
151
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
152
    search = {
153
      :base => "dc=bayshorenetworks,dc=com",
154
      :filter => Net::LDAP::Filter.eq( "sn", "Fosse" )
155
    }
156

  
157
    ldap.search( search ) {|res|
158
      p res
159
    }
160
  end
161

  
162

  
163

  
164
  def test_open
165
    ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth
166
    ldap.open {|ldap|
167
      10.times {
168
        rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
169
        assert_equal( true, rc )
170
      }
171
    }
172
  end
173

  
174

  
175
  def test_ldap_open
176
    Net::LDAP.open( :host => @host, :port => @port, :auth => @auth ) {|ldap|
177
      10.times {
178
        rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" )
179
        assert_equal( true, rc )
180
      }
181
    }
182
  end
183

  
184

  
185

  
186

  
187

  
188
end
189

  
190

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testem.rb (working copy)
1
# $Id: testem.rb 121 2006-05-15 18:36:24Z blackhedd $
2
#
3
#
4

  
5
require 'test/unit'
6
require 'tests/testber'
7
require 'tests/testldif'
8
require 'tests/testldap'
9
require 'tests/testpsw'
10
require 'tests/testfilter'
11

  
12

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testdata.ldif (working copy)
1
# $Id: testdata.ldif 50 2006-04-17 17:57:33Z blackhedd $
2
#
3
# This is test-data for an LDAP server in LDIF format.
4
#
5
dn: dc=bayshorenetworks,dc=com
6
objectClass: dcObject
7
objectClass: organization
8
o: Bayshore Networks LLC
9
dc: bayshorenetworks
10

  
11
dn: cn=Manager,dc=bayshorenetworks,dc=com
12
objectClass: organizationalrole
13
cn: Manager
14

  
15
dn: ou=people,dc=bayshorenetworks,dc=com
16
objectClass: organizationalunit
17
ou: people
18

  
19
dn: ou=privileges,dc=bayshorenetworks,dc=com
20
objectClass: organizationalunit
21
ou: privileges
22

  
23
dn: ou=roles,dc=bayshorenetworks,dc=com
24
objectClass: organizationalunit
25
ou: roles
26

  
27
dn: ou=office,dc=bayshorenetworks,dc=com
28
objectClass: organizationalunit
29
ou: office
30

  
31
dn: mail=nogoodnik@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
32
cn: Bob Fosse
33
mail: nogoodnik@steamheat.net
34
sn: Fosse
35
ou: people
36
objectClass: top
37
objectClass: inetorgperson
38
objectClass: authorizedperson
39
hasAccessRole: uniqueIdentifier=engineer,ou=roles
40
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
41
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
42
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
43
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
44
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
45
hasAccessRole: uniqueIdentifier=brandplace_logging_user,ou=roles
46
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
47
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
48
hasAccessRole: uniqueIdentifier=bayshore_eagle_user,ou=roles
49
hasAccessRole: uniqueIdentifier=bayshore_eagle_superuser,ou=roles
50
hasAccessRole: uniqueIdentifier=kledaras_user,ou=roles
51

  
52
dn: mail=elephant@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
53
cn: Gwen Verdon
54
mail: elephant@steamheat.net
55
sn: Verdon
56
ou: people
57
objectClass: top
58
objectClass: inetorgperson
59
objectClass: authorizedperson
60
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles
61
hasAccessRole: uniqueIdentifier=engineer,ou=roles
62
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
63
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
64
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles
65

  
66
dn: uniqueIdentifier=engineering,ou=privileges,dc=bayshorenetworks,dc=com
67
uniqueIdentifier: engineering
68
ou: privileges
69
objectClass: accessPrivilege
70

  
71
dn: uniqueIdentifier=engineer,ou=roles,dc=bayshorenetworks,dc=com
72
uniqueIdentifier: engineer
73
ou: roles
74
objectClass: accessRole
75
hasAccessPrivilege: uniqueIdentifier=engineering,ou=privileges
76

  
77
dn: uniqueIdentifier=ldapadmin,ou=roles,dc=bayshorenetworks,dc=com
78
uniqueIdentifier: ldapadmin
79
ou: roles
80
objectClass: accessRole
81

  
82
dn: uniqueIdentifier=ldapsuperadmin,ou=roles,dc=bayshorenetworks,dc=com
83
uniqueIdentifier: ldapsuperadmin
84
ou: roles
85
objectClass: accessRole
86

  
87
dn: mail=catperson@steamheat.net,ou=people,dc=bayshorenetworks,dc=com
88
cn: Sid Sorokin
89
mail: catperson@steamheat.net
90
sn: Sorokin
91
ou: people
92
objectClass: top
93
objectClass: inetorgperson
94
objectClass: authorizedperson
95
hasAccessRole: uniqueIdentifier=engineer,ou=roles
96
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles
97
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles
98
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles
99
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles
100
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles
101

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testfilter.rb (working copy)
1
# $Id: testfilter.rb 122 2006-05-15 20:03:56Z blackhedd $
2
#
3
#
4

  
5
require 'test/unit'
6

  
7
$:.unshift "lib"
8

  
9
require 'net/ldap'
10

  
11

  
12
class TestFilter < Test::Unit::TestCase
13

  
14
  def setup
15
  end
16

  
17

  
18
  def teardown
19
  end
20

  
21
  def test_rfc_2254
22
    p Net::LDAP::Filter.from_rfc2254( " ( uid=george*   ) " )
23
    p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
24
    p Net::LDAP::Filter.from_rfc2254( "uid<george*" )
25
    p Net::LDAP::Filter.from_rfc2254( "uid <= george*" )
26
    p Net::LDAP::Filter.from_rfc2254( "uid>george*" )
27
    p Net::LDAP::Filter.from_rfc2254( "uid>=george*" )
28
    p Net::LDAP::Filter.from_rfc2254( "uid!=george*" )
29

  
30
    p Net::LDAP::Filter.from_rfc2254( "(& (uid!=george* ) (mail=*))" )
31
    p Net::LDAP::Filter.from_rfc2254( "(| (uid!=george* ) (mail=*))" )
32
    p Net::LDAP::Filter.from_rfc2254( "(! (mail=*))" )
33
  end
34

  
35

  
36
end
37

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testber.rb (working copy)
1
# $Id: testber.rb 57 2006-04-18 00:18:48Z blackhedd $
2
#
3
#
4

  
5

  
6
$:.unshift "lib"
7

  
8
require 'net/ldap'
9
require 'stringio'
10

  
11

  
12
class TestBer < Test::Unit::TestCase
13

  
14
  def setup
15
  end
16

  
17
  # TODO: Add some much bigger numbers
18
  # 5000000000 is a Bignum, which hits different code.
19
  def test_ber_integers
20
    assert_equal( "\002\001\005", 5.to_ber )
21
    assert_equal( "\002\002\203t", 500.to_ber )
22
    assert_equal( "\002\003\203\206P", 50000.to_ber )
23
    assert_equal( "\002\005\222\320\227\344\000", 5000000000.to_ber )
24
  end
25

  
26
  def test_ber_parsing
27
    assert_equal( 6, "\002\001\006".read_ber( Net::LDAP::AsnSyntax ))
28
    assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax ))
29
  end
30

  
31

  
32
  def test_ber_parser_on_ldap_bind_request
33
    s = StringIO.new "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus"
34
    assert_equal( [1, [3, "Administrator", "ad_is_bogus"]], s.read_ber( Net::LDAP::AsnSyntax ))
35
  end
36

  
37

  
38

  
39

  
40
end
41

  
42

  
vendor/plugins/ruby-net-ldap-0.0.4/tests/testpsw.rb (working copy)
1
# $Id: testpsw.rb 72 2006-04-24 21:58:14Z blackhedd $
2
#
3
#
4

  
5

  
6
$:.unshift "lib"
7

  
8
require 'net/ldap'
9
require 'stringio'
10

  
11

  
12
class TestPassword < Test::Unit::TestCase
13

  
14
  def setup
15
  end
16

  
17

  
18
  def test_psw
19
    assert_equal( "{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate( :md5, "cashflow" ))
20
    assert_equal( "{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate( :sha, "cashflow" ))
21
  end
22

  
23

  
24

  
25

  
26
end
27

  
28

  
vendor/plugins/ruby-net-ldap-0.0.4/LICENCE (working copy)
1
Net::LDAP is copyrighted free software by Francis Cianfrocca
2
<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either
3
the terms of the GPL (see the file COPYING), or the conditions below:
4

  
5
1. You may make and give away verbatim copies of the source form of the
6
   software without restriction, provided that you duplicate all of the
7
   original copyright notices and associated disclaimers.
8

  
9
2. You may modify your copy of the software in any way, provided that you do
10
   at least ONE of the following:
11

  
12
   a) place your modifications in the Public Domain or otherwise make them
13
      Freely Available, such as by posting said modifications to Usenet or
14
      an equivalent medium, or by allowing the author to include your
15
      modifications in the software.
16

  
17
   b) use the modified software only within your corporation or
18
      organization.
19

  
20
   c) rename any non-standard executables so the names do not conflict with
21
      standard executables, which must also be provided.
22

  
23
   d) make other distribution arrangements with the author.
24

  
25
3. You may distribute the software in object code or executable form,
26
   provided that you do at least ONE of the following:
27

  
28
   a) distribute the executables and library files of the software, together
29
      with instructions (in the manual page or equivalent) on where to get
30
      the original distribution.
31

  
32
   b) accompany the distribution with the machine-readable source of the
33
      software.
34

  
35
   c) give non-standard executables non-standard names, with instructions on
36
      where to get the original software distribution.
37

  
38
   d) make other distribution arrangements with the author.
39

  
40
4. You may modify and include the part of the software into any other
41
   software (possibly commercial).  But some files in the distribution are
42
   not written by the author, so that they are not under this terms.
43

  
44
   They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
   files under the ./missing directory.  See each file for the copying
46
   condition.
47

  
48
5. The scripts and library files supplied as input to or produced as output
49
   from the software do not automatically fall under the copyright of the
50
   software, but belong to whomever generated them, and may be sold
51
   commercially, and may be aggregated with this software.
52

  
53
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
54
   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
55
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/entry.rb (working copy)
1
# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $
2
#
3
# LDAP Entry (search-result) support classes
4
#
5
#
6
#----------------------------------------------------------------------------
7
#
8
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
9
#
10
# Gmail: garbagecat10
11
#
12
# This program is free software; you can redistribute it and/or modify
13
# it under the terms of the GNU General Public License as published by
14
# the Free Software Foundation; either version 2 of the License, or
15
# (at your option) any later version.
16
#
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
# GNU General Public License for more details.
21
#
22
# You should have received a copy of the GNU General Public License
23
# along with this program; if not, write to the Free Software
24
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25
#
26
#---------------------------------------------------------------------------
27
#
28

  
29

  
30

  
31

  
32
module Net
33
class LDAP
34

  
35

  
36
  # Objects of this class represent individual entries in an LDAP
37
  # directory. User code generally does not instantiate this class.
38
  # Net::LDAP#search provides objects of this class to user code,
39
  # either as block parameters or as return values.
40
  #
41
  # In LDAP-land, an "entry" is a collection of attributes that are
42
  # uniquely and globally identified by a DN ("Distinguished Name").
43
  # Attributes are identified by short, descriptive words or phrases.
44
  # Although a directory is
45
  # free to implement any attribute name, most of them follow rigorous
46
  # standards so that the range of commonly-encountered attribute
47
  # names is not large.
48
  #
49
  # An attribute name is case-insensitive. Most directories also
50
  # restrict the range of characters allowed in attribute names.
51
  # To simplify handling attribute names, Net::LDAP::Entry
52
  # internally converts them to a standard format. Therefore, the
53
  # methods which take attribute names can take Strings or Symbols,
54
  # and work correctly regardless of case or capitalization.
55
  #
56
  # An attribute consists of zero or more data items called
57
  # <i>values.</i> An entry is the combination of a unique DN, a set of attribute
58
  # names, and a (possibly-empty) array of values for each attribute.
59
  #
60
  # Class Net::LDAP::Entry provides convenience methods for dealing
61
  # with LDAP entries.
62
  # In addition to the methods documented below, you may access individual
63
  # attributes of an entry simply by giving the attribute name as
64
  # the name of a method call. For example:
65
  #  ldap.search( ... ) do |entry|
66
  #    puts "Common name: #{entry.cn}"
67
  #    puts "Email addresses:"
68
  #      entry.mail.each {|ma| puts ma}
69
  #  end
70
  # If you use this technique to access an attribute that is not present
71
  # in a particular Entry object, a NoMethodError exception will be raised.
72
  #
73
  #--
74
  # Ugly problem to fix someday: We key off the internal hash with
75
  # a canonical form of the attribute name: convert to a string,
76
  # downcase, then take the symbol. Unfortunately we do this in
77
  # at least three places. Should do it in ONE place.
78
  class Entry
79

  
80
    # This constructor is not generally called by user code.
81
    def initialize dn = nil # :nodoc:
82
      @myhash = Hash.new {|k,v| k[v] = [] }
83
      @myhash[:dn] = [dn]
84
    end
85

  
86

  
87
    def []= name, value # :nodoc:
88
      sym = name.to_s.downcase.intern
89
      @myhash[sym] = value
90
    end
91

  
92

  
93
    #--
94
    # We have to deal with this one as we do with []=
95
    # because this one and not the other one gets called
96
    # in formulations like entry["CN"] << cn.
97
    #
98
    def [] name # :nodoc:
99
      name = name.to_s.downcase.intern unless name.is_a?(Symbol)
100
      @myhash[name]
101
    end
102

  
103
    # Returns the dn of the Entry as a String.
104
    def dn
105
      self[:dn][0]
106
    end
107

  
108
    # Returns an array of the attribute names present in the Entry.
109
    def attribute_names
110
      @myhash.keys
111
    end
112

  
113
    # Accesses each of the attributes present in the Entry.
114
    # Calls a user-supplied block with each attribute in turn,
115
    # passing two arguments to the block: a Symbol giving
116
    # the name of the attribute, and a (possibly empty)
117
    # Array of data values.
118
    #
119
    def each
120
      if block_given?
121
        attribute_names.each {|a|
122
          attr_name,values = a,self[a]
123
          yield attr_name, values
124
        }
125
      end
126
    end
127

  
128
    alias_method :each_attribute, :each
129

  
130

  
131
    #--
132
    # Convenience method to convert unknown method names
133
    # to attribute references. Of course the method name
134
    # comes to us as a symbol, so let's save a little time
135
    # and not bother with the to_s.downcase two-step.
136
    # Of course that means that a method name like mAIL
137
    # won't work, but we shouldn't be encouraging that
138
    # kind of bad behavior in the first place.
139
    # Maybe we should thow something if the caller sends
140
    # arguments or a block...
141
    #
142
    def method_missing *args, &block # :nodoc:
143
      s = args[0].to_s.downcase.intern
144
      if attribute_names.include?(s)
145
        self[s]
146
      elsif s.to_s[-1] == 61 and s.to_s.length > 1
147
        value = args[1] or raise RuntimeError.new( "unable to set value" )
148
        value = [value] unless value.is_a?(Array)
149
        name = s.to_s[0..-2].intern
150
        self[name] = value
151
      else
152
        raise NoMethodError.new( "undefined method '#{s}'" )
153
      end
154
    end
155

  
156
    def write
157
    end
158

  
159
  end # class Entry
160

  
161

  
162
end # class LDAP
163
end # module Net
164

  
165

  
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/dataset.rb (working copy)
1
# $Id: dataset.rb 78 2006-04-26 02:57:34Z blackhedd $
2
#
3
#
4
#----------------------------------------------------------------------------
5
#
6
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
#
8
# Gmail: garbagecat10
9
#
10
# This program is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation; either version 2 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23
#
24
#---------------------------------------------------------------------------
25
#
26
#
27

  
28

  
29

  
30

  
31
module Net
32
class LDAP
33

  
34
class Dataset < Hash
35

  
36
  attr_reader :comments
37

  
38

  
39
  def Dataset::read_ldif io
40
    ds = Dataset.new
41

  
42
    line = io.gets && chomp
43
    dn = nil
44

  
45
    while line
46
      io.gets and chomp
47
      if $_ =~ /^[\s]+/
48
        line << " " << $'
49
      else
50
        nextline = $_
51

  
52
        if line =~ /^\#/
53
          ds.comments << line
54
        elsif line =~ /^dn:[\s]*/i
55
          dn = $'
56
          ds[dn] = Hash.new {|k,v| k[v] = []}
57
        elsif line.length == 0
58
          dn = nil
59
        elsif line =~ /^([^:]+):([\:]?)[\s]*/
60
          # $1 is the attribute name
61
          # $2 is a colon iff the attr-value is base-64 encoded
62
          # $' is the attr-value
63
          # Avoid the Base64 class because not all Ruby versions have it.
64
          attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
65
          ds[dn][$1.downcase.intern] << attrvalue
66
        end
67

  
68
        line = nextline
69
      end
70
    end
71
  
72
    ds
73
  end
74

  
75

  
76
  def initialize
77
    @comments = []
78
  end
79

  
80

  
81
  def to_ldif
82
    ary = []
83
    ary += (@comments || [])
84

  
85
    keys.sort.each {|dn|
86
      ary << "dn: #{dn}"
87

  
88
      self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr|
89
        self[dn][attr.intern].each {|val|
90
          ary << "#{attr}: #{val}"
91
        }
92
      }
93

  
94
      ary << ""
95
    }
96

  
97
    block_given? and ary.each {|line| yield line}
98

  
99
    ary
100
  end
101

  
102

  
103
end # Dataset
104

  
105
end # LDAP
106
end # Net
107

  
108

  
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/filter.rb (working copy)
1
# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $
2
#
3
#
4
#----------------------------------------------------------------------------
5
#
6
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
#
8
# Gmail: garbagecat10
9
#
10
# This program is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation; either version 2 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23
#
24
#---------------------------------------------------------------------------
25
#
26
#
27

  
28

  
29
module Net
30
class LDAP
31

  
32

  
33
# Class Net::LDAP::Filter is used to constrain
34
# LDAP searches. An object of this class is
35
# passed to Net::LDAP#search in the parameter :filter.
36
#
37
# Net::LDAP::Filter supports the complete set of search filters
38
# available in LDAP, including conjunction, disjunction and negation
39
# (AND, OR, and NOT). This class supplants the (infamous) RFC-2254
40
# standard notation for specifying LDAP search filters.
41
#
42
# Here's how to code the familiar "objectclass is present" filter:
43
#  f = Net::LDAP::Filter.pres( "objectclass" )
44
# The object returned by this code can be passed directly to
45
# the <tt>:filter</tt> parameter of Net::LDAP#search.
46
#
47
# See the individual class and instance methods below for more examples.
48
#
49
class Filter
50

  
51
  def initialize op, a, b
52
    @op = op
53
    @left = a
54
    @right = b
55
  end
56

  
57
  # #eq creates a filter object indicating that the value of
58
  # a paticular attribute must be either <i>present</i> or must
59
  # match a particular string.
60
  #
61
  # To specify that an attribute is "present" means that only
62
  # directory entries which contain a value for the particular
63
  # attribute will be selected by the filter. This is useful
64
  # in case of optional attributes such as <tt>mail.</tt>
65
  # Presence is indicated by giving the value "*" in the second
66
  # parameter to #eq. This example selects only entries that have
67
  # one or more values for <tt>sAMAccountName:</tt>
68
  #  f = Net::LDAP::Filter.eq( "sAMAccountName", "*" )
69
  #
70
  # To match a particular range of values, pass a string as the
71
  # second parameter to #eq. The string may contain one or more
72
  # "*" characters as wildcards: these match zero or more occurrences
73
  # of any character. Full regular-expressions are <i>not</i> supported
74
  # due to limitations in the underlying LDAP protocol.
75
  # This example selects any entry with a <tt>mail</tt> value containing
76
  # the substring "anderson":
77
  #  f = Net::LDAP::Filter.eq( "mail", "*anderson*" )
78
  #--
79
  # Removed gt and lt. They ain't in the standard!
80
  #
81
  def Filter::eq attribute, value; Filter.new :eq, attribute, value; end
82
  def Filter::ne attribute, value; Filter.new :ne, attribute, value; end
83
  #def Filter::gt attribute, value; Filter.new :gt, attribute, value; end
84
  #def Filter::lt attribute, value; Filter.new :lt, attribute, value; end
85
  def Filter::ge attribute, value; Filter.new :ge, attribute, value; end
86
  def Filter::le attribute, value; Filter.new :le, attribute, value; end
87

  
88
  # #pres( attribute ) is a synonym for #eq( attribute, "*" )
89
  #
90
  def Filter::pres attribute; Filter.eq attribute, "*"; end
91

  
92
  # operator & ("AND") is used to conjoin two or more filters.
93
  # This expression will select only entries that have an <tt>objectclass</tt>
94
  # attribute AND have a <tt>mail</tt> attribute that begins with "George":
95
  #  f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" )
96
  #
97
  def & filter; Filter.new :and, self, filter; end
98

  
99
  # operator | ("OR") is used to disjoin two or more filters.
100
  # This expression will select entries that have either an <tt>objectclass</tt>
101
  # attribute OR a <tt>mail</tt> attribute that begins with "George":
102
  #  f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" )
103
  #
104
  def | filter; Filter.new :or, self, filter; end
105

  
106

  
107
  #
108
  # operator ~ ("NOT") is used to negate a filter.
109
  # This expression will select only entries that <i>do not</i> have an <tt>objectclass</tt>
110
  # attribute:
111
  #  f = ~ Net::LDAP::Filter.pres( "objectclass" )
112
  #
113
  #--
114
  # This operator can't be !, evidently. Try it.
115
  # Removed GT and LT. They're not in the RFC.
116
  def ~@; Filter.new :not, self, nil; end
117

  
118

  
119
  def to_s
120
    case @op
121
    when :ne
122
      "(!(#{@left}=#{@right}))"
123
    when :eq
124
      "(#{@left}=#{@right})"
125
    #when :gt
126
     # "#{@left}>#{@right}"
127
    #when :lt
128
     # "#{@left}<#{@right}"
129
    when :ge
130
      "#{@left}>=#{@right}"
131
    when :le
132
      "#{@left}<=#{@right}"
133
    when :and
134
      "(&(#{@left})(#{@right}))"
135
    when :or
136
      "(|(#{@left})(#{@right}))"
137
    when :not
138
      "(!(#{@left}))"
139
    else
140
      raise "invalid or unsupported operator in LDAP Filter"
141
    end
142
  end
143

  
144

  
145
  #--
146
  # to_ber
147
  # Filter ::=
148
  #     CHOICE {
149
  #         and            [0] SET OF Filter,
150
  #         or             [1] SET OF Filter,
151
  #         not            [2] Filter,
152
  #         equalityMatch  [3] AttributeValueAssertion,
153
  #         substrings     [4] SubstringFilter,
154
  #         greaterOrEqual [5] AttributeValueAssertion,
155
  #         lessOrEqual    [6] AttributeValueAssertion,
156
  #         present        [7] AttributeType,
157
  #         approxMatch    [8] AttributeValueAssertion
158
  #     }
159
  #
160
  # SubstringFilter
161
  #     SEQUENCE {
162
  #         type               AttributeType,
163
  #         SEQUENCE OF CHOICE {
164
  #             initial        [0] LDAPString,
165
  #             any            [1] LDAPString,
166
  #             final          [2] LDAPString
167
  #         }
168
  #     }
169
  #
170
  # Parsing substrings is a little tricky.
171
  # We use the split method to break a string into substrings
172
  # delimited by the * (star) character. But we also need
173
  # to know whether there is a star at the head and tail
174
  # of the string. A Ruby particularity comes into play here:
175
  # if you split on * and the first character of the string is
176
  # a star, then split will return an array whose first element
177
  # is an _empty_ string. But if the _last_ character of the
178
  # string is star, then split will return an array that does
179
  # _not_ add an empty string at the end. So we have to deal
180
  # with all that specifically.
181
  #
182
  def to_ber
183
    case @op
184
    when :eq
185
      if @right == "*"          # present
186
        @left.to_s.to_ber_contextspecific 7
187
      elsif @right =~ /[\*]/    #substring
188
        ary = @right.split( /[\*]+/ )
189
        final_star = @right =~ /[\*]$/
190
        initial_star = ary.first == "" and ary.shift
191

  
192
        seq = []
193
        unless initial_star
194
          seq << ary.shift.to_ber_contextspecific(0)
195
        end
196
        n_any_strings = ary.length - (final_star ? 0 : 1)
197
        #p n_any_strings
198
        n_any_strings.times {
199
          seq << ary.shift.to_ber_contextspecific(1)
200
        }
201
        unless final_star
202
          seq << ary.shift.to_ber_contextspecific(2)
203
        end
204
        [@left.to_s.to_ber, seq.to_ber].to_ber_contextspecific 4
205
      else                      #equality
206
        [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 3
207
      end
208
    when :ge
209
      [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 5
210
    when :le
211
      [@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 6
212
    when :and
213
      ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten
214
      ary.map {|a| a.to_ber}.to_ber_contextspecific( 0 )
215
    when :or
216
      ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten
217
      ary.map {|a| a.to_ber}.to_ber_contextspecific( 1 )
218
    when :not
219
        [@left.to_ber].to_ber_contextspecific 2
220
    else
221
      # ERROR, we'll return objectclass=* to keep things from blowing up,
222
      # but that ain't a good answer and we need to kick out an error of some kind.
223
      raise "unimplemented search filter"
224
    end
225
  end
226

  
227
  #--
228
  # coalesce
229
  # This is a private helper method for dealing with chains of ANDs and ORs
230
  # that are longer than two. If BOTH of our branches are of the specified
231
  # type of joining operator, then return both of them as an array (calling
232
  # coalesce recursively). If they're not, then return an array consisting
233
  # only of self.
234
  #
235
  def coalesce operator
236
    if @op == operator
237
      [@left.coalesce( operator ), @right.coalesce( operator )]
238
    else
239
      [self]
240
    end
241
  end
242

  
243

  
244

  
245
  #--
246
  # We get a Ruby object which comes from parsing an RFC-1777 "Filter"
247
  # object. Convert it to a Net::LDAP::Filter.
248
  # TODO, we're hardcoding the RFC-1777 BER-encodings of the various
249
  # filter types. Could pull them out into a constant.
250
  #
251
  def Filter::parse_ldap_filter obj
252
    case obj.ber_identifier
253
    when 0x87         # present. context-specific primitive 7.
254
      Filter.eq( obj.to_s, "*" )
255
    when 0xa3         # equalityMatch. context-specific constructed 3.
256
      Filter.eq( obj[0], obj[1] )
257
    else
258
      raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" )
259
    end
260
  end
261

  
262

  
263
  #--
264
  # We got a hash of attribute values.
265
  # Do we match the attributes?
266
  # Return T/F, and call match recursively as necessary.
267
  def match entry
268
    case @op
269
    when :eq
270
      if @right == "*"
271
        l = entry[@left] and l.length > 0
272
      else
273
        l = entry[@left] and l = l.to_a and l.index(@right)
274
      end
275
    else
276
      raise LdapError.new( "unknown filter type in match: #{@op}" )
277
    end
278
  end
279

  
280
  # Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254)
281
  # to a Net::LDAP::Filter.
282
  def self.construct ldap_filter_string
283
    FilterParser.new(ldap_filter_string).filter
284
  end
285

  
286
  # Synonym for #construct.
287
  # to a Net::LDAP::Filter.
288
  def self.from_rfc2254 ldap_filter_string
289
    construct ldap_filter_string
290
  end
291

  
292
end # class Net::LDAP::Filter
293

  
294

  
295

  
296
class FilterParser #:nodoc:
297

  
298
  attr_reader :filter
299

  
300
  def initialize str
301
    require 'strscan'
302
    @filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" )
303
  end
304

  
305
  def parse scanner
306
    parse_filter_branch(scanner) or parse_paren_expression(scanner)
307
  end
308

  
309
  def parse_paren_expression scanner
310
    if scanner.scan(/\s*\(\s*/)
311
      b = if scanner.scan(/\s*\&\s*/)
312
        a = nil
313
        branches = []
314
        while br = parse_paren_expression(scanner)
315
          branches << br
316
        end
317
        if branches.length >= 2
318
          a = branches.shift
319
          while branches.length > 0
320
            a = a & branches.shift
321
          end
322
          a
323
        end
324
      elsif scanner.scan(/\s*\|\s*/)
325
        # TODO: DRY!
326
        a = nil
327
        branches = []
328
        while br = parse_paren_expression(scanner)
329
          branches << br
330
        end
331
        if branches.length >= 2
332
          a = branches.shift
333
          while branches.length > 0
334
            a = a | branches.shift
335
          end
336
          a
337
        end
338
      elsif scanner.scan(/\s*\!\s*/)
339
        br = parse_paren_expression(scanner)
340
        if br
341
          ~ br
342
        end
343
      else
344
        parse_filter_branch( scanner )
345
      end
346

  
347
      if b and scanner.scan( /\s*\)\s*/ )
348
        b
349
      end
350
    end
351
  end
352

  
353
  # Added a greatly-augmented filter contributed by Andre Nathan
354
  # for detecting special characters in values. (15Aug06)
355
  def parse_filter_branch scanner
356
    scanner.scan(/\s*/)
357
    if token = scanner.scan( /[\w\-_]+/ )
358
      scanner.scan(/\s*/)
359
      if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ )
360
        scanner.scan(/\s*/)
361
        #if value = scanner.scan( /[\w\*\.]+/ ) (ORG)
362
        if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ )
363
          case op
364
          when "="
365
            Filter.eq( token, value )
366
          when "!="
367
            Filter.ne( token, value )
368
          when "<"
369
            Filter.lt( token, value )
370
          when "<="
371
            Filter.le( token, value )
372
          when ">"
373
            Filter.gt( token, value )
374
          when ">="
375
            Filter.ge( token, value )
376
          end
377
        end
378
      end
379
    end
380
  end
381

  
382
end # class Net::LDAP::FilterParser
383

  
384
end # class Net::LDAP
385
end # module Net
386

  
387

  
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/pdu.rb (working copy)
1
# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $
2
#
3
# LDAP PDU support classes
4
#
5
#
6
#----------------------------------------------------------------------------
7
#
8
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
9
#
10
# Gmail: garbagecat10
11
#
12
# This program is free software; you can redistribute it and/or modify
13
# it under the terms of the GNU General Public License as published by
14
# the Free Software Foundation; either version 2 of the License, or
15
# (at your option) any later version.
16
#
17
# This program is distributed in the hope that it will be useful,
18
# but WITHOUT ANY WARRANTY; without even the implied warranty of
19
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
# GNU General Public License for more details.
21
#
22
# You should have received a copy of the GNU General Public License
23
# along with this program; if not, write to the Free Software
24
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
25
#
26
#---------------------------------------------------------------------------
27
#
28

  
29

  
30

  
31
module Net
32

  
33

  
34
class LdapPduError < Exception; end
35

  
36

  
37
class LdapPdu
38

  
39
  BindResult = 1
40
  SearchReturnedData = 4
41
  SearchResult = 5
42
  ModifyResponse = 7
43
  AddResponse = 9
44
  DeleteResponse = 11
45
  ModifyRDNResponse = 13
46
  SearchResultReferral = 19
47

  
48
  attr_reader :msg_id, :app_tag
49
  attr_reader :search_dn, :search_attributes, :search_entry
50
  attr_reader :search_referrals
51

  
52
  #
53
  # initialize
54
  # An LDAP PDU always looks like a BerSequence with
55
  # at least two elements: an integer (message-id number), and
56
  # an application-specific sequence.
57
  # Some LDAPv3 packets also include an optional
58
  # third element, which is a sequence of "controls"
59
  # (See RFC 2251, section 4.1.12).
60
  # The application-specific tag in the sequence tells
61
  # us what kind of packet it is, and each kind has its
62
  # own format, defined in RFC-1777.
63
  # Observe that many clients (such as ldapsearch)
64
  # do not necessarily enforce the expected application
65
  # tags on received protocol packets. This implementation
66
  # does interpret the RFC strictly in this regard, and
67
  # it remains to be seen whether there are servers out
68
  # there that will not work well with our approach.
69
  #
70
  # Added a controls-processor to SearchResult.
71
  # Didn't add it everywhere because it just _feels_
72
  # like it will need to be refactored.
73
  #
74
  def initialize ber_object
75
    begin
76
      @msg_id = ber_object[0].to_i
77
      @app_tag = ber_object[1].ber_identifier - 0x60
78
    rescue
79
      # any error becomes a data-format error
80
      raise LdapPduError.new( "ldap-pdu format error" )
81
    end
82

  
83
    case @app_tag
84
    when BindResult
85
      parse_ldap_result ber_object[1]
86
    when SearchReturnedData
87
      parse_search_return ber_object[1]
88
    when SearchResultReferral
89
      parse_search_referral ber_object[1]
90
    when SearchResult
91
      parse_ldap_result ber_object[1]
92
      parse_controls(ber_object[2]) if ber_object[2]
93
    when ModifyResponse
94
      parse_ldap_result ber_object[1]
95
    when AddResponse
96
      parse_ldap_result ber_object[1]
97
    when DeleteResponse
98
      parse_ldap_result ber_object[1]
99
    when ModifyRDNResponse
100
      parse_ldap_result ber_object[1]
101
    else
102
      raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" )
103
    end
104
  end
105

  
106
  #
107
  # result_code
108
  # This returns an LDAP result code taken from the PDU,
109
  # but it will be nil if there wasn't a result code.
110
  # That can easily happen depending on the type of packet.
111
  #
112
  def result_code code = :resultCode
113
    @ldap_result and @ldap_result[code]
114
  end
115

  
116
  # Return RFC-2251 Controls if any.
117
  # Messy. Does this functionality belong somewhere else?
118
  def result_controls
119
    @ldap_controls || []
120
  end
121

  
122

  
123
  #
124
  # parse_ldap_result
125
  #
126
  def parse_ldap_result sequence
127
    sequence.length >= 3 or raise LdapPduError
128
    @ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]}
129
  end
130
  private :parse_ldap_result
131

  
132
  #
133
  # parse_search_return
134
  # Definition from RFC 1777 (we're handling application-4 here)
135
  #
136
  # Search Response ::=
137
  #    CHOICE {
138
  #         entry          [APPLICATION 4] SEQUENCE {
139
  #                             objectName     LDAPDN,
140
  #                             attributes     SEQUENCE OF SEQUENCE {
141
  #                                                 AttributeType,
142
  #                                                 SET OF AttributeValue
143
  #                                            }
144
  #                        },
145
  #         resultCode     [APPLICATION 5] LDAPResult
146
  #     }
147
  #
148
  # We concoct a search response that is a hash of the returned attribute values.
149
  # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES.
150
  # This is to make them more predictable for user programs, but it
151
  # may not be a good idea. Maybe this should be configurable.
152
  # ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes,
153
  # we also return @search_entry, which is an LDAP::Entry object.
154
  # If that works out well, then we'll remove the first two.
155
  #
156
  # Provisionally removed obsolete search_attributes and search_dn, 04May06.
157
  #
158
  def parse_search_return sequence
159
    sequence.length >= 2 or raise LdapPduError
160
    @search_entry = LDAP::Entry.new( sequence[0] )
161
    #@search_dn = sequence[0]
162
    #@search_attributes = {}
163
    sequence[1].each {|seq|
164
      @search_entry[seq[0]] = seq[1]
165
      #@search_attributes[seq[0].downcase.intern] = seq[1]
166
    }
167
  end
168

  
169
  #
170
  # A search referral is a sequence of one or more LDAP URIs.
171
  # Any number of search-referral replies can be returned by the server, interspersed
172
  # with normal replies in any order.
173
  # Until I can think of a better way to do this, we'll return the referrals as an array.
174
  # It'll be up to higher-level handlers to expose something reasonable to the client.
175
  def parse_search_referral uris
176
    @search_referrals = uris
177
  end
178

  
179

  
180
  # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting
181
  # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL
182
  # Octet String. If only two fields are given, the second one may be
183
  # either criticality or data, since criticality has a default value.
184
  # Someday we may want to come back here and add support for some of
185
  # more-widely used controls. RFC-2696 is a good example.
186
  #
187
  def parse_controls sequence
188
    @ldap_controls = sequence.map do |control|
189
      o = OpenStruct.new
190
      o.oid,o.criticality,o.value = control[0],control[1],control[2]
191
      if o.criticality and o.criticality.is_a?(String)
192
        o.value = o.criticality
193
        o.criticality = false
194
      end
195
      o
196
    end
197
  end
198
  private :parse_controls
199

  
200

  
201
end
202

  
203

  
204
end # module Net
205

  
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/psw.rb (working copy)
1
# $Id: psw.rb 73 2006-04-24 21:59:35Z blackhedd $
2
#
3
#
4
#----------------------------------------------------------------------------
5
#
6
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
#
8
# Gmail: garbagecat10
9
#
10
# This program is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation; either version 2 of the License, or
13
# (at your option) any later version.
14
#
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
#
20
# You should have received a copy of the GNU General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23
#
24
#---------------------------------------------------------------------------
25
#
26
#
27

  
28

  
29
module Net
30
class LDAP
31

  
32

  
33
class Password
34
  class << self
35

  
36
  # Generate a password-hash suitable for inclusion in an LDAP attribute.
37
  # Pass a hash type (currently supported: :md5 and :sha) and a plaintext
... This diff was truncated because it exceeds the maximum size that can be displayed.
(4-4/4)