PHP에서 ActiveDirectory 사용자 목록을 보았습니다.

ActiveDirectory에서 관리하는 직원의 로그인 시간 등을 사내 인트라 웹 사이트에서 볼 수 있으면 편리한 상황이 많이 있다.
그래서 PHP로 간단한 도구를 써 보았다.

실행 환경




서버
소프트웨어 버전


AD/DNS 서버
Windows Server 2016 Standard Edition

사내 인트라용 웹 서버
CentOS 7.6 + Apache 2.4 + PHP 7.2


LDAP 모듈 사용



ActiveDirectory는 LDAP를 구현하고 있기 때문에 PHP 내장 LDAP 함수로 바인딩한다.
CentOS 7에서 php-ldap를 활성화하는 단계는 다음과 같습니다.

LDAP 모듈이 있는지 확인
# rpm -qa | grep php
php-json-7.0.16-1.el7.remi.x86_64
php-mcrypt-7.0.16-1.el7.remi.x86_64
php-pear-1.10.1-10.el7.remi.noarch
php-common-7.0.16-1.el7.remi.x86_64
php-mysqlnd-7.0.16-1.el7.remi.x86_64
php-mbstring-7.0.16-1.el7.remi.x86_64
php-gd-7.0.16-1.el7.remi.x86_64
php-cli-7.0.16-1.el7.remi.x86_64
php-devel-7.0.16-1.el7.remi.x86_64
php-fpm-7.0.16-1.el7.remi.x86_64
php-pdo-7.0.16-1.el7.remi.x86_64
php-7.0.16-1.el7.remi.x86_64
php-process-7.0.16-1.el7.remi.x86_64
php-pgsql-7.0.16-1.el7.remi.x86_64
php-xml-7.0.16-1.el7.remi.x86_64

없으면 Remi 저장소에서 설치
yum -y install --enablerepo=remi-php70 php-ldap

/etc/php.d/20-ldap.ini
extension=ldap

전용 사용자 계정 만들기



PHP가 LDAP로 액세스하기위한 전용 사용자 계정을 만들고 Account Operators에 속합니다.
Account Operators는 내장 로컬 그룹 중 하나이며 도메인의 사용자 계정 관리 권한을가집니다.

코드



PHP를 포함한 HTML
<html lang="ja">
<head><meta charset="utf-8"><title>在席確認ツール</title>
<style type="text/css">
* {
  font-family: "MS ゴシック", "MS Gothic"
}
table {
  width: 100%;
}
table, th, td {
  border-collapse: collapse;
  border: 1px solid #999;
  line-height: 1.5;
}
th {
  color: #fff;
  background: #008;
}
tr:nth-child(even) {
  background: #eee;
}
td {
  text-align: center;
}
</style>
</head>
<body>
<h1>在席確認</h1>
<?php
date_default_timezone_set('Asia/Tokyo');

# ユーザアカウントの管理権限を持つアカウント
$user = 'XXXXXX';
$passwd = 'YYYYYY';

# ADサーバのアドレス
$ldapConn = ldap_connect('ldap://10.123.123.123');

ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);

# バインドできたら
if (ldap_bind($ldapConn, $user . '@foo.example.ne.jp', $passwd)) {
    $sr = ldap_list ($ldapConn, 'ou=Users,ou=BAR,dc=foo,dc=example,dc=ne,dc=jp', '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))', array('samaccountname','description','displayname','lastlogon','pwdlastset','mail'));

    ldap_sort($ldapConn, $sr, 'description');
    $info = ldap_get_entries($ldapConn, $sr);
    $count = $info['count'];

    echo '<table border="1">';
    echo '<tr><th>No.</th><th>アカウント名</th><th>Description</th><th>氏名</th><th>メールアドレス</th><th>最終ログイン日時</th><th>最終パスワード変更日時</th></tr>';

    $n = 1;
    for ($i = 0; $i < $count; $i++) {
      $ent = $info[$i];
      $samaccountname = $ent['samaccountname'][0];
      $desc = $ent['description'][0];
      $displayname = $ent['displayname'][0];
      # メールアドレスが設定されている人は表示
      if (array_key_exists('mail', $ent)) {
        $mail = $ent['mail'][0];
      } else {
        $mail = '-';
      }
      $lastlogontime = round($ent['lastlogon'][0] / 10000000) - 11644473600;
      # 直近にログインしている人ほど背景を赤くする
      $diff = time() - $lastlogontime;
      if ($diff < 86400) {
          $bgcolor = 'bgcolor=#ff' . str_repeat(str_pad(dechex(255 * log(1 + $diff, 86400) ^ 2), 2, 0, STR_PAD_LEFT), 2);
      } else {
          $bgcolor = '';
      }
      $lastlogon = date('Y-m-d H:i:s', $lastlogontime);
      $pwdlastset = date('Y-m-d H:i:s', round($ent['pwdlastset'][0] / 10000000) - 11644473600);

      echo "<tr><td>$n</td><td>$samaccountname</td><td>$desc</td><td>$displayname</td><td>$mail</td><td $bgcolor>$lastlogon</td><td>$pwdlastset</td></tr>";
      $n++;
    }
    echo '</table>';
} else {
    echo 'Failed';
}
ldap_close($ldapConn);
?>
</body></html>

실행 결과



최근까지 로그인한 사람일수록 배경색을 더 빨갛게 만들어 보았다.
이 응용 프로그램에서 예를 들어 1 년 이상 암호를 변경하지 않은 사람에게는 색을 칠 수 있습니다.

좋은 웹페이지 즐겨찾기