OpenLDAPのslapd.access(5)の話

ここ最近OpenLDAPを触っているんだけど、以下のような設定をするのにだいぶ悩んだ。

 access to 
        by 

みたいな設定をするときに、特定グループに所属するユーザには管理者権限を与えたい。
つまり、管理者グループに所属するユーザにはLDAPの情報をRead/Writeする権限を与えたい。

例えば

 uid=hoge,ou=People,dc=example,dc=com
 uid=fuga,ou=People,dc=example,dc=com
 
 cn=admin,ou=Groups,dc=example,dc=com

のような感じで登録してあったとして、
hogeユーザは一般人だけどfugaユーザは管理者なので、こいつには管理者権限を与えたい。

と言ったときに adminグループに所属していれば管理者だよーと出来ればラクかなぁと。

の部分に直接ユーザのDNを書けばいけるのは分かるんだけど、そうするといちいちslapdの再起動が必要そうなのでそれはさすがに嫌だ。
で、man slapd.access(5) を見ていたらどうやら以下を使えば出来そう。

 group[/[/]]
      [.]=

要は、上記式 group= の右辺で指定するDNのとあるattributeに記述されているDNにはアクセスを認めるよ、ということか。
説明を読むとデフォルト値は groupOfNames オブジェクトクラスの member アトリビュートに所属するユーザ、ということになるので上記式に当てはめるとこうなる。

 group/groupOfNames/member="cn=admin,ou=Groups,dc=example,dc=com"
 省略してこう書ける。
 group="cn=admin,ou=Groups,dc=example,dc=com"
 実際書くとしたら
 by group="cn=admin,ou=Groups,dc=example,dc=com" write
 などと書くだろう。

ただ、groupOfNames オブジェクトクラスを使おうとすると、posixGroup オブジェクトクラスの cn とかぶってしまうのが困る。なのでposixGroupオブジェクトクラスのmemberUidが使えないかなぁと思ったりして以下のように設定してみた。

 group/posixGroup/memberUid="cn=admin,ou=Groups,dc=example,dc=com"

ところがこうすると、

 Checking configuration files for slapd:  /etc/openldap/slapd.conf: line 75: group "cn=admin,ou=Groups,dc=example,dc=com": inappropriate syntax: 1.3.6.1.4.1.1466.115.121.1.26.


というエラーが出た。
データ型(SYNTAX)
1.3.6.1.4.1.1466.115.121.1.26 ASCII文字列
という意味らしい??
スキーマを読むとわかるのだが、memberUidにはASCII文字列しか書いてはいけないようだ。
つまり、右辺にDNは書けないことになる。うーむ。

色々悩んだ挙句、結局のところデフォルトの groupOfNames を使うことにした。
管理者用のグループは特殊扱いということで posixGroupオブジェクトクラスは入れずに top, groupOfNames オブジェクトクラスにして他とは別にした。他にいい案が浮かばなかったので仕方ない。
で、このmemberアトリビュートに uid=fuga,ou=People,dc=example,dc=com を登録すればよい。

以下のようなLDIFを作る。

dn: cn=ldapadmin,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: ldapadmin
member: uid=fuga,ou=People,dc=example,dc=com

ldapaddコマンドで登録。

ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f ldapadmin.ldif

それで slapd.conf に

access to attrs=userPassword
        by dn="cn=Manager,dc=example,dc=com" write
        by group="cn=ldapadmin,ou=Groups,dc=example,dc=com" write
        by self write
        by anonymous auth
        by * none
access to *
        by dn="cn=Manager,dc=example,dc=com" write
        by group="cn=ldapadmin,ou=Groups,dc=example,dc=com" write
        by * read


とか書けば思った通りの動作をした。