概要
前回 Ruby から ldap を操作してみました
グループの追加まで確認できたので今回はユーザ周りの操作を試してみました
環境
- CentOS 7.3.1611
- openldap 2.4.40
- Ruby 2.3.1p112
- net-ldap 0.16.0
ユーザを追加する
- vim user_add.rb
require 'net/ldap'
require 'pp'
PORT = 389
HOST = '192.168.100.5'
BASE = 'dc=example,dc=com'
AUTH = {
:method => :simple,
:username => "cn=Manager,#{BASE}",
:password => 'password'
}
ldap = Net::LDAP.new(
host: HOST,
port: PORT,
base: BASE,
auth: AUTH
)
raise 'bind failed' unless ldap.bind
dn = "uid=hawk,ou=People,#{BASE}"
attr = {
:sn => 'hawk',
:cn => 'snowlog',
:objectclass => ['posixAccount', 'inetOrgPerson'],
:displayName => 'hawksnowlog',
:uid => 'hawk',
:uidNumber => '1001',
:gidNumber => '1000',
:homeDirectory => '/home/hawk',
:loginShell => '/bin/bash',
:userPassword => '{CRYPT}E1N/hpjy8pfc6',
:mail => 'hawk@hawksnowlog.cf'
}
ldap.add(
:dn => dn,
:attributes => attr
)
pp ldap.get_operation_result
前半の接続部分は前回のコードをそのまま使用しています
ユーザを追加するための処理は dn の定義からです
ポイントは objectclass
を配列で指定しているところ
そうしないと後に定義した objectclass に上書きされてしまいます
もし inetOrgPerson を後に記載した場合 'uidNumber' not allowed
と言われ uid の指定ができません
#<OpenStruct extended_response=nil, code=65, error_message="attribute 'uidNumber' not allowed", matched_dn="", message="Object Class Violation">
では、posixAccount だけ objectclass に指定するとそんなクラスはないと言われます
#<OpenStruct extended_response=nil, code=65, error_message="no structural object class provided", matched_dn="", message="Object Class Violation">
結局 objectclass を配列にして posixAccount と inetOrgPerson を一緒に指定する必要がありました
あとは実行してエラーが表示されなければ OK です
- bundle exec ruby user_add.rb
#<OpenStruct extended_response=nil, code=0, error_message="", matched_dn="", message="Success">
userPassword の部分は slappasswd
コマンドで作成した暗号化済みのパスワードになります
ユーザを削除する
- vim user_delete.rb
dn = "uid=hawk,ou=People,#{BASE}"
ldap.delete(
:dn => dn
)
pp ldap.get_operation_result
削除は dn を指定するだけなので簡単です
add のときと同じように結果が返ってくれば OK です
ユーザを取得する
- vim user_search.rb
users = ldap.search(base: "ou=People,#{BASE}")
pp users
で以下の表に表示されれば OK です
[#<Net::LDAP::Entry:0x000000015a61e8
@myhash=
{:dn=>["ou=People,dc=example,dc=com"],
:objectclass=>["organizationalUnit"],
:ou=>["People"]}>,
#<Net::LDAP::Entry:0x000000015a4258
@myhash=
{:dn=>["uid=hawk,ou=People,dc=example,dc=com"],
:sn=>["hawk"],
:cn=>["snowlog"],
:objectclass=>["posixAccount", "inetOrgPerson"],
:displayname=>["hawksnowlog"],
:uid=>["hawk"],
:uidnumber=>["1001"],
:gidnumber=>["1000"],
:homedirectory=>["/home/hawk"],
:loginshell=>["/bin/bash"],
:userpassword=>["{CRYPT}E1N/hpjy8pfc6"],
:mail=>["hawk@hawksnowlog.cf"]}>]
特定のグループに所属するユーザを取得する
ということをしたいケースはよくあると思います
search の際に filter という機能を使うことで実現できました
自分は gidNumber を指定してその gidNumber を持つユーザを取得する方法で実現しましたが、他にもやり方はいろいろとあると思います
group = "group1"
groups = ldap.search(base: "cn=#{group},ou=Group,#{BASE}")
groups.each { |group|
gidNumber = group['gidNumber'][0]
group_name_filter = Net::LDAP::Filter.eq( "gidNumber", "#{gidNumber}" )
users = ldap.search(base: "ou=People,#{BASE}", filter: group_name_filter, return_result: true)
pp users
}
ちょっと複雑なように見えますが一旦 group 名から gidNumber を取得して、取得した gidNumber を元に再度 search をかけています
ポイントは取得した groups をループしたときのクラスが Net::BER::BerIdentifiedArray
というクラスなのですが配列になっているので、先頭だけを取得して使っています
今回はグループに 1 つの gidNumber しか持たせていないので先頭を無条件で使っていますが、複数の gidNumber を持つグループの場合は少し考慮が必要になります
最後に
Ruby + net-ldap を使って ldap に基本的なユーザ操作をしてみました
特につまるところはなかった感じです
今回作成したユーザは posixAccount として作成してるので Linux などから SSH ログインすることも可能です
0 件のコメント:
コメントを投稿