diff --git a/workers/update-ldap-cache.php b/workers/update-ldap-cache.php index a62b19f..4b2a0ed 100755 --- a/workers/update-ldap-cache.php +++ b/workers/update-ldap-cache.php @@ -14,25 +14,6 @@ use UnityWebPortal\lib\UnityWebhook; use PHPOpenLDAPer\LDAPEntry; -// in PHP LDAP all attributes are arrays, we need these as strings instead -// it's possible but probably difficult to find this out using LDAP schema information -$user_string_attributes = [ - "gidnumber", - "givenname", - "homedirectory", - "loginshell", - "mail", - "o", - "sn", - "uid", - "uidnumber", - "gecos", -]; - -$pi_group_string_attributes = [ - "gidnumber", -]; - $options = getopt("fuh", ["help"]); if (array_key_exists("h", $options) or array_key_exists("help", $options)) { echo "arguments: @@ -51,40 +32,44 @@ echo " use -f argument to flush cache, or -u argument to update without flush.\n"; } else { echo "updating cache...\n"; - echo "waiting for LDAP response (users)...\n"; + + // search entire tree, some users created for admin purposes might not be in the normal OU + echo "waiting for LDAP search (users)...\n"; $users = $LDAP->search("objectClass=posixAccount", $CONFIG["ldap"]["basedn"]); echo "response received.\n"; - // phpcs:disable - $user_CNs = array_map(function ($x){return $x->getAttribute("cn")[0];}, $users); - // phpcs:enable + $user_CNs = $LDAP->getUserGroup()->getAttribute("memberuid"); sort($user_CNs); $REDIS->setCache("sorted_users", "", $user_CNs); foreach ($users as $user) { - $cn = $user->getAttribute("cn")[0]; - foreach ($user->getAttributes() as $key => $val) { - if (in_array($key, $user_string_attributes)) { - $REDIS->setCache($cn, $key, $val[0]); - } else { - $REDIS->setCache($cn, $key, $val); - } + $uid = $user->getAttribute("cn")[0]; + if (!in_array($uid, $user_CNs)) { + continue; } + $REDIS->setCache($uid, "firstname", $user->getAttribute("givenname")[0]); + $REDIS->setCache($uid, "lastname", $user->getAttribute("sn")[0]); + $REDIS->setCache($uid, "org", $user->getAttribute("o")[0]); + $REDIS->setCache($uid, "mail", $user->getAttribute("mail")[0]); + $REDIS->setCache($uid, "sshkeys", $user->getAttribute("sshpublickey")); + $REDIS->setCache($uid, "loginshell", $user->getAttribute("loginshell")[0]); + $REDIS->setCache($uid, "homedir", $user->getAttribute("homedirectory")[0]); } $org_group_ou = new LDAPEntry($LDAP->getConn(), $CONFIG["ldap"]["orggroup_ou"]); - echo "waiting for LDAP response (org_groups)...\n"; - $org_groups = $LDAP->search("objectClass=posixGroup", $CONFIG["ldap"]["basedn"]); + echo "waiting for LDAP search (org groups)...\n"; + $org_groups = $org_group_ou->getChildrenArray(true); echo "response received.\n"; // phpcs:disable - $org_group_CNs = array_map(function($x){return $x->getAttribute("cn")[0];}, $org_groups); + $org_group_CNs = array_map(function($x){return $x["cn"][0];}, $org_groups); // phpcs:enable sort($org_group_CNs); $REDIS->setCache("sorted_orgs", "", $org_group_CNs); foreach ($org_groups as $org_group) { - $REDIS->setCache($org_group->getAttribute("cn")[0], "members", $org_group->getAttribute("memberuid")); + $gid = $org_group["cn"][0]; + $REDIS->setCache($gid, "members", (@$org_group["memberuid"] ?? [])); } $pi_group_ou = new LDAPEntry($LDAP->getConn(), $CONFIG["ldap"]["pigroup_ou"]); - echo "waiting for LDAP response (pi_groups)...\n"; + echo "waiting for LDAP search (pi groups)...\n"; $pi_groups = $pi_group_ou->getChildrenArray(true); echo "response received.\n"; // phpcs:disable @@ -93,19 +78,22 @@ sort($pi_group_CNs); // FIXME should be sorted_pi_groups $REDIS->setCache("sorted_groups", "", $pi_group_CNs); + $user_pi_group_member_of = []; foreach ($user_CNs as $uid) { $user_pi_group_member_of[$uid] = []; } foreach ($pi_groups as $pi_group) { - if (array_key_exists("memberuid", $pi_group)) { - $REDIS->setCache($pi_group["cn"][0], "members", $pi_group["memberuid"]); - foreach ($pi_group["memberuid"] as $member_uid) { - array_push($user_pi_group_member_of[$member_uid], $pi_group["cn"][0]); + $gid = $pi_group["cn"][0]; + $members = (@$pi_group["memberuid"] ?? []); + foreach ($members as $uid) { + if (in_array($uid, $user_CNs)) { + array_push($user_pi_group_member_of[$uid], $gid); + } else { + echo "warning: group '$gid' has member '$uid' who is not in the users group!\n"; } - } else { - $REDIS->setCache($pi_group["cn"][0], "members", []); } + $REDIS->setCache($gid, "members", (@$pi_group["memberuid"] ?? [])); } foreach ($user_pi_group_member_of as $uid => $pi_groups) { // FIXME should be pi_groups