ldap(ActiveDirectory)と認証連携について

ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
返信数: 14
はじめまして。入江と申します。

企業内でも使えないかと、moodleをインストールして、機能を
試しています。

ユーザ認証の部分でちょっとつまづいています。解決のヒントを
いただけると幸いです。

認証オプションで、LDAPサーバを使用すると設定しました。
新規ユーザがログインした後に「プロフィールの編集」を
行うと、処理が止まってしまいます。ブラウザを再起動して
ログイン後プロフィールのデータを見ると更新は正常におこなわ
れています。
プロフィール更新した際に、ldap(ActiveDirectory)サーバに対して
なんらかの処理を行おうとして失敗しているように思えます。

この問題に対して解決方法を御存じないでしょうか?

moodleのバージョンは1.5です。

ldapサーバは認証の情報(UserID , password)だけを利用して
他のプロフィール属性はmoodleのDBにデータを置きたいと
考えています。管理画面を探してみましたが、そのようなオプション
を見つける事ができませんでした。




Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators
下記の投稿を参考にされてはいかがでしょうか。

http://moodle.org/mod/forum/discuss.php?d=1892
Mitsuhiro Yoshida への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
情報ありがとうございます。
試してみて、結果報告致します。

Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators
実際にLDAPを試した方は多くないと思いますので、よろしくお願いします。 笑顔
Mitsuhiro Yoshida への返信

Re: ldap(ActiveDirectory)と認証連携について

- Toshihiro KITA の投稿
# 横からの投稿で失礼します。 > Takao Irie さま

熊本大学でも OpenLDAPサーバとの組み合わせで
運用を始めています。

ただ,
Bug #3992 - LDAP password including a quote does not work

にも投稿したように,パスワードに ' (シングルクォート) が含まれている時に
うまく認証が通らないようです。

この現象が再現する方はいらっしゃいますか?

Toshihiro KITA への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
はじめまして。
LDAPの認証について、moodleはphpの標準的な関数をCallしてますので
シングルクォートが影響するとは考えにくいです。
Openldap側の問題なのか、moodle側の問題なのか切り分けるとよいかも
しれません。

(1)標準的なツールを使ってldapサーバにログインできるか?
  ldapsearchやsofterra ldap browserを使って、
  認証できないUserDNとパスワードでBINDできるか?

(2)認証できない時のopenldap側ログ確認
  /etc/syslog.confに
  local4.*     /var/log/ldap.log
  といった記述が必要になります。
  search で失敗しているのか、bindで失敗しているのか。

(3)moodleのデバグログ(debugをyesとした結果)
  これは、あまり有益な情報は得られないかもしれませんが
   念のため。

phpのプログラミングは経験が浅いので的外れかもしれませんが
php.ini の magic_quotes_gpcが邪魔している事はありませんか。


Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Toshihiro KITA の投稿
どうもコメント大変ありがとうございます。
> phpのプログラミングは経験が浅いので的外れかもしれませんが
> php.ini の magic_quotes_gpcが邪魔している事はありませんか。
が大きなヒントになりました。

色々調べてみた結果,
Moodle は,php.ini の magic_quotes_gpc の設定に関わらず,
フォームからの入力データを全て addslashes() することが分かりました。
# lib/setup.php の 250行目辺りの  addslashes_deep() の定義および
#  $_POST = array_map('addslashes_deep', $_POST);
# の辺りです。これに気づくのに1週間かかった。 もうろうとした目

つまり,
abc'def
というパスワードは,フォームデータのsubmit 直後に
abc\'def
となってしまうことが分かりました。
# シングルクォート('), ダブルクォート("),バックスラッシュ (\) ,NUL (NULL バイト) が
# クォートの対象らしいです。

もちろん,パスワード設定も,認証画面でのパスワード入力も
両方とも Moodle 上であれば,結局同一になるので問題ありません。

LDAP での認証の様に,パスワード設定は別のツールで行った場合に問題となります。

とりあえずの対処法としては, auth/ldap/lib.php の 73行目付近の
       // Try to bind with current username and password
       $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, $password);
       ldap_close($ldapconnection);

の真ん中の行を
      $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, stripslashes($password));
のように変更して,stripslashes() で バックスラッシュを取り除いてやればいいです。
# 本当は,他にも stripslashes() を入れた方が良い箇所もあるでしょうが...

# しかしまあ,POP3 での認証とか,同じ問題は生じないのかな?



Mitsuhiro Yoshida への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
色々と試していますが、なかなかうまくいきません。
ldapの認証連携は、細かな制御ができるようですが
どのパラメータが必須なのか、不要(nullで良い)のか
わかりにくいです。デバグモードにしてもエラー
メッセージが少なく原因を特定するのが結構難しい
です。ちょっとメゲてしまいました。複雑な

ActiveDirectoryの認証部分だけ使いたい場合は、
pam経由がシンプルで理解しやすいのかもしれませんね。

moodleはpop3と認証の連携が簡単にできたりするので
結構面白いです。笑顔

Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
原因が若干わかってきました。

ユーザのプロフィール編集をして、更新処理を行う時に何故かldap(ActiveDirectory)に対して検索を行います。その際にmoodleで登録したldap serverだけでなくwww.example.comというアドレスにも検索にいきます
(Redhat Linux ES V3デフォルトの設定で検証してます)

検証しているNW環境がイントラネット内なので、www.example.comにldapアクセスした際、到達不可能なHOSTなので、TCPのタイムアウトまでじっとまっていたというのが原因でした。
(ファイアウォールがICMPアンリーチャブルで返してくれれば、早くあきらめてくれるのでしょうけど)

phpのldap実装は、イマイチ理解不足なんではっきりした事がわからないの
ですが、openldapのldap.confのHOSTにActiveDirectoryのアドレス
をいれるとwww.example.comにアクセスいこうとするのは止めることはできました。(ldap.confのhostは localhostになっていて、www.example.comにアクセスにいこうとするのは解せないのですが。。)

しかし、まだ問題があります。
ユーザプロフィール編集の更新処理を行うと、ldap検索フィルタとして(sAMAccountName=)を指定し検索しています。通常であれば、sAMAccountNameはログインした人のUserIDが=の次に入るべきなんですが、なぜか空白が入ります。($usernameに値がセットされてない)相手がopenldap serverの場合は問題ないのですが、ActiveDirectoryの場合は、=の次に値が入らない場合、シンタックスエラーとなります。

そして、moodleでエラーが表示されてしまいます。
書式は間違ってないので、ActiveDirectoryが検索結果0件でかえしてくれてもよさそうなもんですがヘトヘト

一時しのぎとして、auth/ldap/lib.phpのauth_ldap_find_userdn()に$usernameが空の場合、ありえない値をいれるという処理をいれるとうまくいきそうなんですが、根本的な解決にならないです。複雑な
Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Mitsuhiro Yoshida の投稿
画像 Developers 画像 Particularly helpful Moodlers 画像 Translators
詳細な情報ありがとうございます。

ldap.confには下記のような設定項目がありますので、これも影響しているのかもしれません。

# The distinguished name of the search base.
base dc=example,dc=com


auth_ldap_find_userdn()を使っているauth_user_login()では、$usernameの空の場合のチェックをしていますので、ご指摘のように「ありえない値をいれるという処理」も良いと思います。もちろん根本的な解決ではありませんね。

参考になるか分かりませんがActiveDirectoryに関して下記のページもご覧ください。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=5736&forum=12&5
Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
CentOS Ver4を使ってmoodleをインストールしてみました。
RedhatES V3で発生した問題は出ませんでした。驚き
つまり、なにも問題なくActiveDirectoryと認証連携できました。

簡単にですが、設定内容等報告します。

・moodle側
      CentOS Ver4
      moodle1.5 + (2005.6.30)
・ActiveDirectory
      Windows2003 SP1

・設定
  ldap_host_url          : ldap://**.**.**/
  ldap_version           : 3
  ldap_bind_dn          : UserID@your.Domain
  ldap_bind_pw          : ****
  ldap_user_type       : MS ActiveDirectory
  ldap_contexts         : ou=****,dc=your,dc=domain
  ldap_search_sub     : yes
  ldap_opt_deref        : yes
  ldap_user_attribute: sAMAccountName
  ldap_objectclass     : user
  データマッピング
  名 givenName
  姓 sn
  メール mail
  電話 telephoneNumber

Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
追記です。
・ActiveDirectory側にメールアドレスの登録がないと最初の
   ログイン後、プロフィールの編集更新でうまくいきません。
・/etc/ldap.conf  /etc/openldap/ldap.confの記述は必須です。
・氏名、名前が日本語の場合化けます。

  
Takao Irie への返信

Re: ldap(ActiveDirectory)と認証連携について

- Takao Irie の投稿
ActiveDirectoryから日本語ユーザ名を取得した際に文字化けが発生する問題について解決しましたので報告します。

ソースコード:auth/ldap/lib.php
128行目近辺変更
$result[$key]=addslashes[stripslashed($user_entry[0][strtolower($value)][0]));

utf8_decode();は不要だと思うので外しただけです。