パスワード変更UI向けphpLDAPadminカスタマイズ

phpLDAPadminをカスタマイズして次の機能を得る。
  1. エンドユーザ向けのパスワード変更UI
  2. パスワード強度強制

(参考)http://d.palmtb.net/2011/08/15/150308.html

基本構成

項目内容
URLhttp://server1.hoge.local/phpldapadmin_orghttp://server1.hoge.local/pwmgr
用途OpenLDAPの管理全般エンドユーザ向けパスワード変更
コンテンツオリジナルのままパスワード変更に必要なものに絞込み
コンテンツパス/usr/share/phpldapadmin/usr/share/phpldapadmin_pwmgr
設定用ディレクトリ/etc/phpldapadmin/etc/phpldapadmin_pwmgr

phpLDAPadminの導入

  1. EPELリポジトリを導入
  2. phpLDAPadminはCentOSの標準リポジトリではなくEPELリポジトリにある。
    # yum search phpldapadmin
    	:
    警告: 一致するものが見つかりません: phpldapadmin
    # yum install epel-release
    	:
    インストール:
      epel-release.norach 0:7-9
    
    完了しました!
    
  3. phpLDAPadminのインストール
  4. # yum install phpldapadmin
    	:
    インストール:
      phpldapadmin.norarch 0:1.2.3-10.el7
    
    依存性関連をインストールしました:
    	:
    
    完了しました!
    
  5. EPELリポジトリ検索の無効化(任意)
  6. /etc/yum.repos.d/epel.repoの[epel]セクション、enabled=1を0に変更しておく。
    [epel]
    name=Extra Packages for Enterprise Linux 7 - $basearch
    #baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
    mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
    failovermethod=priority
    enabled=0
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
    	:
    

phpLDAPadminの設定

  1. 設定ディレクトリの複製
  2. # cp -rp /etc/phpldapadmin /etc/phpldapadmin_pwmgr
    
  3. コンテンツの複製
  4. # cp -rp /usr/share/phpldapadmin /usr/share/phpldapadmin_pwmgr
    
  5. 複製コンテンツの設定ディレクトリへのシンボリックリンク修正
  6. # rm /usr/share/phpldapadmin_pwmgr/config
    # ln -s /etc/phpldapadmin_pwmgr /usr/share/phpldapadmin_pwmgr/config
    
  7. Apache側のphpLDAPadmin向け設定
  8. /etc/httpd/conf.d/phpldapadmin.confを次のように記述。前半は管理用URLのため管理者オフィスからのアクセスに限定、後半はパスワード変更画面なので社内すべてからのアクセスを許可。
    #
    #  Web-based tool for managing LDAP servers
    #
    
    Alias /phpldapadmin_org /usr/share/phpldapadmin/htdocs
    Alias /ldapadmin_org /usr/share/phpldapadmin/htdocs
    
    <Directory /usr/share/phpldapadmin/htdocs>
      <IfModule mod_authz_core.c>
        # Apache 2.4
        #Require local
        Require ip 192.168.200.0/24
        Require ip (administrator's office lan)/24
      </IfModule>
      <IfModule !mod_authz_core.c>
        # Apache 2.2
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
        Allow from ::1
      </IfModule>
    </Directory>
    
    
    Alias /pwmgr /usr/share/phpldapadmin_pwmgr/htdocs
    
    <Directory /usr/share/phpldapadmin_pwmgr/htdocs>
      <IfModule mod_authz_core.c>
        # Apache 2.4
        #Require local
        Require all granted
      </IfModule>
      <IfModule !mod_authz_core.c>
        # Apache 2.2
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
        Allow from ::1
      </IfModule>
    </Directory>
    
    # systemctl restart httpd
    
    ブラウザからhttp://server1.hoge.local/phpldapadmin, http://server1.hoge.local/pwmgrにアクセスするとphpLDAPadminの画面応答があるはず。

パスワード変更機能に絞り込むカスタマイズ(config)

pwmgr側のphpLDAPadminの画面をパスワード変更のみに絞り込む等の設定。/etc/phpldapadmin_pwmgr/config.phpを次のように調整する。
  1. 機能アイコンとスクリプト調整の有効化
  2. 99〜148行目付近の、次の2つのarray定義をコメントアウトしている大外の/*,*/をはずし、有効化する。
    $config->custom->commands['cmd'] = array(
    	:
    );
    
    $config->custom->command['script'] = array(
    	:
    );
    
  3. 機能・画面の無効化詳細
  4. cmdのほうが機能アイコン(とリンク)、scriptのほうが実際のスクリプト処理、の有効無効を意味する。どれが何を意味するかは、実際の画面のリンク先を確認するとわかる。

    例えば、インポート(フロッピーのアイコン)のリンク先は次のとおり。

    http://server1.hoge.local/pwmgr/cmd.php?cmd=import_form&server_id=1

    上記から、cmdのarray、scriptのarrayそれぞれで、「'import_form' => false」と設定することで無効化できる。設定→画面リロード、の繰り返しで絞り込みが進められる。設定例は以下。

    $config->custom->commands['cmd'] = array(
            'add_attr_form' => false,
            'add_oclass_form' => false,
            'add_value_form' => false,
            'compare' => false,
            'compare_form' => false,
            'create' => false,
            'create_form' => false,
            'delete' => false,
            'delete_attr' => false,
            'delete_form' => false,
            'entry_internal_attributes_show' => true,
            'entry_refresh' => true,
            'export' => false,
            'export_form' => false,
            'import' => false,
            'import_form' => false,
            'login' => true,
            'login_form' => true,
            'logout' => true,
            'mass_delete' => false,
            'mass_edit' => false,
            'mass_update' => false,
            'modify_member_form' => false,
            'monitor' => false,
            'purge_cache' => true,
            'query_engine' => false,
            'rename' => false,
            'rename_form' => false,
            'oslinks' => false,
            'schema' => false,
            'server_info' => false,
            'show_cache' => false,
            'show_internal_attrs' => false,
            'switch_template' => false,
            'template_engine' => true
    );
    
    $config->custom->commands['script'] = array(
            'add_attr_form' => false,
            'add_oclass_form' => false,
            'add_value_form' => false,
            'collapse' => true,
            'compare' => false,
            'compare_form' => false,
            'copy' => false,
            'copy_form' => false,
            'create' => false,
            'create_confirm' => false,
            'delete' => false,
            'delete_attr' => false,
            'delete_form' => false,
            'draw_tree_node' => true,
            'expand' => true,
            'export' => false,
            'export_form' => false,
            'import' => false,
            'import_form' => false,
            'login' => true,
            'logout' => true,
            'login_form' => true,
            'mass_delete' => false,
            'mass_edit' => false,
            'mass_update' => false,
            'modify_member_form' => false,
            'monitor' => false,
            'purge_cache' => true,
            'query_engine' => false,
            'rename' => false,
            'rename_form' => false,
            'oslinks' => false,
            'rdelete' => true,
            'refresh' => true,
            'schema' => false,
            'server_info' => false,
            'show_cache' => false,
            'show_internal_attrs' => false,
            'template_engine' => true,
            'update_confirm' => true,
            'update' => true
    );
    
  5. テンプレート関連の警告メッセージを無効化
  6. $config->custom->appearance['hide_template_warning'] = true;
    
  7. ou=People以下のinetOrgPersonクラスエントリのみ表示する
  8. $config->custom->appearance['tree_filter'] = '(&(ou=People)(objectClass=inetOrgPerson));
    
  9. userPassword以外の属性を非表示・読み取り専用に
  10. $config->custom->appearance['hide_attrs'] = array('uid','uidNumber','gidNumber','homeDirectory','loginShell','objectClass','sshPublicKey','gecos','cn','sn','givenName','mail','o');
    
  11. デフォルトの「Local LDAP Server」表示の変更(任意)
  12. $servers->setValue('server', 'name', 'hoge.local');
    
  13. 匿名参照の無効化
  14. ログイン画面の、anonymousログインを許可するチェックボックスが非表示になる。
    $servers->setValue('server', 'anon_bind', false);
    

パスワード変更機能に絞り込むカスタマイズ(コンテンツ)

/usr/share/phpldapadmin_pwmgr/以下のコンテンツを必要に応じて調整。
  1. ロゴ画像の差し替え
  2. htdocs/images/{logo.png,logo-small.png}を差し替えることで、ログイン時中央の画像と左上ヘッダに表示される画像を好みのものに差し替える。
  3. 微妙な日本語メッセージの修正
  4. cd /usr/share/phpldapadmin_pwmgr/locale/ja_JP/LC_MESSAGES
    cp -p messages.mo messages.mo.org
    msgunfmt messages.mo -o /tmp/messages.po
    
    次のように修正
    # vi /tmp/messages.po
    サーバに認証 → サーバ認証
    左へのメニューを使用して操作します → 左のメニューを使用して操作します
    飛ばす → skip
    オブジェクト更新 → 更新
    これらの変更しますか? → 変更しますか?
    
    msgfmt /tmp/messages.po -o ./messages.mo
    
  5. lib/function.php
  6. lib/page.php
  7. lib/TemplateRender.php
  8. htdocs/update_confirm.php
  9. パスワード変更において、userPassword属性ひとつの更新となることから次の調整。

パスワード強度強制

パスワード情報をphpLDAPadminでハッシュ化してslapdに渡す仕組みでは、 slapdのppolicyが実質機能しない (渡ってきたものがcleartextではないので最小文字数などをチェックできない)ので、 phpLDAPadminの段階でパスワード強度をチェック・強制する次のようなカスタマイズを実施。 カスタマイズのポイントは次のとおり。
# diff /usr/share/phpldapadmin_pwmgr/lib/PageRender.php /usr/share/phpldapadmin/lib/PageRender.php
261,293d260
< # ----- パスワード強度チェック 開始 ------------------
<                               # 現ハッシュ値の控え
<                               $oval = array();
<                               $oval = $attribute->getOldValues();
<                                       // userPassword 属性はハッシュ値一つだけ
<                                       //      printf('%s', count($oval));
<                                       //      printf('%s', $oval[0]);
<
<                               # パスワードの適切さ(強度など)フラグ
<                               $suitablePasswd = true;
<
<                               # 最小文字数
<                               $passwdMinLen = 6;
<
<                               # NG パスワードリスト
<                               $ngPasswds = ["password", "123456", "000000", "redmine"];
<
<                               if (strlen($passwordvalue) < $passwdMinLen) {
<                                       system_message(array(
<                                               'title'=>_('最小文字数未満'),
<                                               'body'=>sprintf('最小文字数 %s 文字未満です。',$passwdMinLen),
<                                               'type'=>'warn'));
<                                       $suitablePasswd = false;
<                               } elseif (in_array($passwordvalue, $ngPasswds)) {
<                                       system_message(array(
<                                               'title'=>_('不適切なパスワード'),
<                                               'body'=>sprintf('%s は不適切なパスワードです。', $passwordvalue),
<                                               'type'=>'warn'));
<                                       $suitablePasswd = false;
<                               }
<
< # ----- パスワード強度チェック 終了 ------------------
<
323,332c290
<                                               # 不適切なパスワードのときは、便宜的に入力値に
<                                               # 現ハッシュ値をセットし、 update_confirm.php の
<                                               #       if (count($request['template']->getLDAPmodify(true))) {
<                                               # が false になるようにし
<                                               # 本来変更なし時の画面遷移処理ブロックを間借りして
<                                               # 戻る画面に移る
<                                               if ($suitablePasswd !== true)
<                                                       $vals[$i] = $oval[0];
<                                               else
<                                                       $vals[$i] = pla_password_hash($passwordvalue,$enc);
---
>                                               $vals[$i] = pla_password_hash($passwordvalue,$enc);
352d309
<
# diff /usr/share/phpldapadmin_pwmgr/htdocs/update_confirm.php /usr/share/phpldapadmin/htdocs/update_confirm.php
233,236d222
<
<       // 最初のフォームで更新を押したものの、現行の値から変化がないときに、
<       // 変更無いよ、と表示しつつ、前のフォームに戻るリンクを表示、が本来。
<
241,242c227
<       // echo _('You made no changes');
<       echo _('変更が無いか、パスワードが不適切です。');
---
>       echo _('You made no changes');

「OpenLDAPとphpLDAPadminによるLinuxとRedmineの認証基盤」に戻る
2018/10/11 Taikou Yamada (t-yamada _at_ ceres.dti.ne.jp)