PerlのCPANモジュール、Net::LDAPを使ってEntryを追加しようとしたら’no values for attribute type’というエラーにハマってしまったので備忘録。
前提:
- LDAPサーバー(OpenLDAP)へのBINDはSimple Bind
- 追加するのはposixAccount
- オリジナルobjectClassでAuthorizedHostという属性を追加して、このAuthorizedHostに記述のあるホストにはアクセス可能という制御をしている。
- AuthorizedHostという属性は複数設定可能。
- 受け取った結果はJSONで返す
Web画面から新しいOSユーザーを作るという画面を作るためにサーバーサイド側のプログラムをPerlで記述した。
この時にAuthorizedHostをJSONの配列で受け取るようにしていたのだが、その値が空であることをWeb画面側で許していたため、空である場合に”no values for attribute type”で返ってきてしまった。
よって、最終的には以下のようにAuthorizedHostの値を確認した上で、エントリー追加後にAuthorizedHostの値のみ追加するような処理にした。(エラーやバリデーション処理については省いています。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#!/usr/bin/perl use utf8; use Net::LDAP; use JSON; use CGI; $q = new CGI; print $q->>header({ -charset=>"utf-8", -type=>"application/json" }); $ldapInfo = setLDAPInfo($env); #LDAP環境をセットアップするサブルーチン $cn = $q->param('cn'); $uidNumber = setUIDNumber($cn); #uidNumberの設定値を現在のLDAP情報をもとに割り当てるサブルーチン $dn = setDN($cn); #DNをセットするサブルーチン $jsonstring = $q->param('data'); #CN以外の属性/値はJSONの文字列で受け取る $receivedData = from_json($jsonstring); #受け取ったJSON文字列を無名ハッシュにパース ($password, $hashedPassword) = genPassword(); #パスワードを生成、LDAP用のハッシュされたパスワードも返すサブルーチン $attr = [ objectClass => ['GenericUser','posixAccount','pwdPolicy','shadowAccount','top'], cn => $cn, sn => $cn, uid => $cn, homeDirectory => "/home/$cn", gidNumber => 3000, uidNumber => $uidNumber, pwdAttribute => 'userPassword', PwdMustChange => 'TRUE', shadowLastChange => 0, shadowMax => 65535, shadowMin => 0, userPassword => $hashedPassword, loginShell => "/bin/bash" ]; $return = $ldap->bind("$ldapInfo->{'user'}",password=>"$ldapInfo->{'pass'}",version=>3); $result = $ldap->add($dn, attrs => $attr); $ldap->unbind(); $response->{'errorMessage'} = $result->{'errorMessage'}; $response->{'resultCode'} = $result->{'resultCode'}; #AuthorizedHostの配列を処理( if ( $result->{'resultCode'} == 0 ) { foreach my $host ( @{$info->{$cn}->{'AuthorizedHost'}} ) { my $return = $ldap->bind("$ldapInfo->{'user'}",password=>"$ldapInfo->{'pass'}",version=>3); my $ldap = Net::LDAP->new("$info->{'server'}"); my $res = $ldap->modify( $dn, add => { 'AuthorizedHost' => $host } ); $ldap->unbind(); } } print to_json($response); |
そもそもNet::LDAPの実装としてattrsを配列でなく、ハッシュで受け取るようにして、値がない場合、どの属性に値がないかを返してくれたらもっと時間かからずに済んだなと思った次第。
「[Perl]Net::LDAPを使ったEntry追加」への1件のフィードバック