ITDB(IT 資產管理系統)原生 LDAP 功能僅支援認證,無法滿足「硬體指派使用者需從 LDAP 選人」的業務需求。本文示範如何修改 init.php 實現 LDAP 用戶**自動同步入庫**、預設唯讀權限、管理員可提權的完整方案。
LDAP (ou=People,dc=company,dc=com)
│
│ 定時/每請求觸發
▼
ITDB init.php 掛鉤
│
├─ ldap_connect → ldap_search (cn=*)
├─ 遍歷條目 → 取 cn (uid)
├─ getuserbyname(uid) 檢查是否存在
└─ 不存在 → INSERT users (username, cookie1, usertype=2)
存在 → 略過(保留 ITDB 內權限設定)
?> 前)////////////////////////////////////////////////////////////////////////////////
// LDAP 用戶自動同步到 ITDB
////////////////////////////////////////////////////////////////////////////////
$ldap_host = '192.168.1.16';
$ldap_base = 'ou=People,dc=bawo,dc=cn';
$ldap_filter = '(cn=*)';
$ds = ldap_connect($ldap_host);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$sr = ldap_search($ds, $ldap_base, $ldap_filter);
$info = ldap_get_entries($ds, $sr);
for ($i = 1; $i < $info['count']; $i++) { // $i=1 跳過 count 元素
$username = strtolower(trim($info[$i]['cn'][0]));
if (empty($username)) continue;
// 檢查 ITDB 現有用戶
$u = getuserbyname($username);
if ($u == -1) {
$cookie = mt_rand();
// usertype=2 為唯讀用戶
db_execute2($dbh,
"INSERT INTO users (username, cookie1, usertype) VALUES (:username, :cookie1, :usertype)",
array('username' => $username, 'cookie1' => $cookie, 'usertype' => 2)
);
db_exec($dbh, "UPDATE users SET cookie1='$cookie' WHERE username='$username'", 1, 1);
error_log("ITDB-LDAP: Auto-created user $username (readonly)");
}
}
ldap_close($ds);
}
////////////////////////////////////////////////////////////////////////////////
| 函數 | 作用 |
|---|---|
getuserbyname($name) | 查用戶是否存在,存在回傳 uid,不存在回傳 -1 |
db_execute2($dbh, $sql, $params) | 參數化執行 INSERT/UPDATE,防注入 |
db_exec($dbh, $sql, ...) | 執行原生 SQL |
usertype | 1=Admin, 2=ReadOnly, 3=Normal, 4=Guest(依版本而異) |
// 1. TLS 加密
ldap_start_tls($ds); // 需 LDAPS (636) 或 StartTLS (389)
// 2. 綁定服務帳號(而非匿名)
$bind_dn = 'cn=itdb-sync,ou=ServiceAccounts,dc=company,dc=com';
$bind_pw = 'StrongPasswordFromVault';
ldap_bind($ds, $bind_dn, $bind_pw);
// 3. 分頁查詢(避免超過 1000 條限制)
ldap_control_paged_result($ds, 500);
do {
$sr = ldap_search($ds, $ldap_base, $ldap_filter);
$info = ldap_get_entries($ds, $sr);
// 處理 $info
$cookie = ldap_control_paged_result_response($ds, $sr);
} while ($cookie !== null && $cookie != '');
ldap_control_paged_result($ds, 0);
#!/bin/bash
# /usr/local/bin/itdb_ldap_sync.sh — 每小時跑一次
PHP_SCRIPT="/var/www/itdb/scripts/ldap_sync.php"
LOG="/var/log/itdb_ldap_sync.log"
cd /var/www/itdb
php "$PHP_SCRIPT" >>"$LOG" 2>&1
# 腳本內容同 init.php 邏輯,獨立於 Web 請求
| LDAP 屬性 | ITDB 欄位 | 映射規則 |
|---|---|---|
cn / uid | username | 小寫、去空白、唯一 |
mail | email | 同步更新 |
displayName | realname | 同步更新 |
memberOf (群組) | usertype | 含 CN=ITDB_Admins → usertype=1,否則保持 2 |
employeeNumber | employee_id | 同步更新 |
init.php 做大量 LDAP 查詢 → 首頁載入極慢。✅ 改為**定時腳本**或**快取 + 非同步佇列**。try-catch、記錄錯誤日誌、靜默失敗不拋出例外。結語: ITDB + LDAP 核心在「同步不覆蓋、權限分層、失敗靜默」。把同步邏輯剝離到獨立定時腳本,配合 LDAPS、服務帳號、分頁查詢、群組映射權限,即可實現企業級身分整合,滿足「硬體指派人」下拉框即時可選的業務需求。