RubyでLDAP

使ったのはRuby/LDAPなのだけど日本語の資料が全然ない気がする.RailsだとActiveLDAPとかあるようなんだけど,生で使ってる人がいないのかな(それとも書くまでもない?).ここの人のを参考にしたのだけど(それとRDoc),今後何度か使うこともあり,初期化とか面倒なことやらなくていいようにファサードなクラスに.
・simpleldap.rb

require 'ldap'

class SimpleLDAP
  DEFAULT_OPTIONS = {:host    => 'localhost',
                     :port    => LDAP::LDAP_PORT,
                     :version => 3}

  def initialize(base, opts = {})
    opts = DEFAULT_OPTIONS.merge(opts)
    ldap = LDAP::Conn.new(opts[:host], opts[:port])
    ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, opts[:version])
    @ldap = ldap
    @base = base
  end

  attr_reader :base, :dn

  def invoke(attr, password)
    @dn = build_dn(attr)
    @ldap.bind(@dn, password) { |conn| yield conn, @dn }
  end
  alias execute invoke

  def build_dn(attr, base = nil)
    dn     = ""
    base ||= @base

    attr.each do |pair|
      dn += pair.join('=')
    end
    [dn, base].join(',')
  end
end

RubyのハッシュがPHP連想配列みたいにOrderedHashならbuild_dnの使い道が増えるのだが(1.9ならそうなのだけど).まぁ書き捨てだしいいかなと.*1

ldap = SimpleLDAP.new("o=example,dc=com")
ldap.invoke({:cn => 'admin'}, 'hogehoge') { |conn, dn|
  test_dn = ldap.build_dn({:ou => 'test'})
  conn.search2(test_dn, LDAP::LDAP_SCOPE_SUBTREE, "(uid=*)") do |entry|
    p entry
  end
  hoge_dn = ldap.build_dn({:uid => 'hoge'}, test_dn)
  conn.modify(hoge_dn, {'userPassword' => ['foo']})
}

今更だけど,moduleでも良かった気がする…

OpenLDAPでのMD5

これはメモ.LDIFにパスワードを記述して登録するにはslappasswdを使ってパスワードを生成するのだけど,他で32バイト長の16進数で出力済みのデータの場合は変換が必要なので変換する(特にPHPmd5だとデフォルト).Ruby 1.8だとこんな感じ?*2

require 'base64'
require 'digest/md5'

raw = Digest::MD5.new.update('foo').digest
hex = Digest::MD5.new.update('foo').hexdigest

raw == [hex].pack('H*') # => true
Base64.encode64([hex].pack('H*')).chomp # => この結果の頭に{MD5}をつける

最初どうやって変換するのかと思ったら,packを使うだけで行けるという.正直Rubyの中でもpack/unpackはよく分からないorz

*1:現状属性2個以上考慮してないw

*2:1.9だとライブラリ構成が変わってるはず