diff --git a/resources/lib/UnityGroup.php b/resources/lib/UnityGroup.php index 43362d26..d1616225 100644 --- a/resources/lib/UnityGroup.php +++ b/resources/lib/UnityGroup.php @@ -482,7 +482,7 @@ private function init() $ldapPiGroupEntry = $this->getLDAPPiGroup(); if (!$ldapPiGroupEntry->exists()) { - $nextGID = $this->LDAP->getNextPiGIDNumber(); + $nextGID = $this->LDAP->getNextPiGIDNumber($this->SQL); $ldapPiGroupEntry->setAttribute("objectclass", UnityLDAP::POSIX_GROUP_CLASS); $ldapPiGroupEntry->setAttribute("gidnumber", strval($nextGID)); diff --git a/resources/lib/UnityLDAP.php b/resources/lib/UnityLDAP.php index 91612579..fc44cd4f 100644 --- a/resources/lib/UnityLDAP.php +++ b/resources/lib/UnityLDAP.php @@ -115,67 +115,46 @@ public function getDefUserShell() // // ID Number selection functions // - public function getNextUIDNumber() + public function getNextUIDNumber($UnitySQL) { - $users = $this->userOU->getChildrenArray(true); + $max_uid = $UnitySQL->getSiteVar('MAX_UID'); + $new_uid = $max_uid + 1; - // This could become inefficient with more users - usort($users, function ($a, $b) { - return $a["uidnumber"] <=> $b["uidnumber"]; - }); - - $id = self::ID_MAP[0]; - foreach ($users as $acc) { - if ($id == $acc["uidnumber"][0]) { - $id++; - } else { - if (!$this->GIDNumInUse($id)) { - break; - } - } + while ($this->UIDNumInUse($new_uid)) { + $new_uid++; } - return $id; + $UnitySQL->updateSiteVar('MAX_UID', $new_uid); + + return $new_uid; } - public function getNextPiGIDNumber() + public function getNextPiGIDNumber($UnitySQL) { - $groups = $this->pi_groupOU->getChildrenArray(true); - - usort($groups, function ($a, $b) { - return $a["gidnumber"] <=> $b["gidnumber"]; - }); - - $id = self::PI_ID_MAP[0]; - foreach ($groups as $acc) { - if ($id == $acc["gidnumber"][0]) { - $id++; - } else { - break; - } + $max_pigid = $UnitySQL->getSiteVar('MAX_PIGID'); + $new_pigid = $max_pigid + 1; + + while ($this->PIGIDNumInUse($new_pigid)) { + $new_pigid++; } - return $id; + $UnitySQL->updateSiteVar('MAX_PIGID', $new_pigid); + + return $new_pigid; } - public function getNextOrgGIDNumber() + public function getNextOrgGIDNumber($UnitySQL) { - $groups = $this->org_groupOU->getChildrenArray(true); - - usort($groups, function ($a, $b) { - return $a["gidnumber"] <=> $b["gidnumber"]; - }); - - $id = self::ORG_ID_MAP[0]; - foreach ($groups as $acc) { - if ($id == $acc["gidnumber"][0]) { - $id++; - } else { - break; - } + $max_gid = $UnitySQL->getSiteVar('MAX_GID'); + $new_gid = $max_gid + 1; + + while ($this->GIDNumInUse($new_gid)) { + $new_gid++; } - return $id; + $UnitySQL->updateSiteVar('MAX_GID', $new_gid); + + return $new_gid; } private function UIDNumInUse($id) @@ -190,11 +169,23 @@ private function UIDNumInUse($id) return false; } + private function PIGIDNumInUse($id) + { + $pi_groups = $this->pi_groupOU->getChildrenArray(true); + foreach ($pi_groups as $pi_group) { + if ($pi_group["gidnumber"][0] == $id) { + return true; + } + } + + return false; + } + private function GIDNumInUse($id) { - $users = $this->groupOU->getChildrenArray(true); - foreach ($users as $user) { - if ($user["gidnumber"][0] == $id) { + $groups = $this->groupOU->getChildrenArray(true); + foreach ($groups as $group) { + if ($group["gidnumber"][0] == $id) { return true; } } @@ -202,7 +193,7 @@ private function GIDNumInUse($id) return false; } - public function getUnassignedID($uid) + public function getUnassignedID($uid, $UnitySQL) { $netid = strtok($uid, "_"); // extract netid // scrape all files in custom folder @@ -226,7 +217,7 @@ public function getUnassignedID($uid) } // didn't find anything from existing mappings, use next available - $next_uid = $this->getNextUIDNumber(); + $next_uid = $this->getNextUIDNumber($UnitySQL); return $next_uid; } diff --git a/resources/lib/UnityOrg.php b/resources/lib/UnityOrg.php index 73a69396..03f85818 100644 --- a/resources/lib/UnityOrg.php +++ b/resources/lib/UnityOrg.php @@ -30,7 +30,7 @@ public function init() $org_group = $this->getLDAPOrgGroup(); if (!$org_group->exists()) { - $nextGID = $this->LDAP->getNextOrgGIDNumber(); + $nextGID = $this->LDAP->getNextOrgGIDNumber($this->SQL); $org_group->setAttribute("objectclass", UnityLDAP::POSIX_GROUP_CLASS); $org_group->setAttribute("gidnumber", strval($nextGID)); diff --git a/resources/lib/UnitySQL.php b/resources/lib/UnitySQL.php index 6067376e..1dccc711 100644 --- a/resources/lib/UnitySQL.php +++ b/resources/lib/UnitySQL.php @@ -13,6 +13,7 @@ class UnitySQL private const TABLE_EVENTS = "events"; private const TABLE_AUDIT_LOG = "audit_log"; private const TABLE_ACCOUNT_DELETION_REQUESTS = "account_deletion_requests"; + private const TABLE_SITEVARS = "sitevars"; private const REQUEST_ADMIN = "admin"; @@ -275,4 +276,27 @@ public function accDeletionRequestExists($uid) return count($stmt->fetchAll()) > 0; } + + public function getSiteVar($name) + { + $stmt = $this->conn->prepare( + "SELECT * FROM " . self::TABLE_SITEVARS . " WHERE name=:name" + ); + $stmt->bindParam(":name", $name); + + $stmt->execute(); + + return $stmt->fetchAll()[0]['value']; + } + + public function updateSiteVar($name, $value) + { + $stmt = $this->conn->prepare( + "UPDATE " . self::TABLE_SITEVARS . " SET value=:value WHERE name=:name" + ); + $stmt->bindParam(":name", $name); + $stmt->bindParam(":value", $value); + + $stmt->execute(); + } } diff --git a/resources/lib/UnityUser.php b/resources/lib/UnityUser.php index 08a83ad2..d2cc6d23 100644 --- a/resources/lib/UnityUser.php +++ b/resources/lib/UnityUser.php @@ -53,7 +53,7 @@ public function init($send_mail = true) // Create LDAP group // $ldapGroupEntry = $this->getLDAPGroup(); - $id = $this->LDAP->getUnassignedID($this->getUID()); + $id = $this->LDAP->getUnassignedID($this->getUID(), $this->SQL); if (!$ldapGroupEntry->exists()) { $ldapGroupEntry->setAttribute("objectclass", UnityLDAP::POSIX_GROUP_CLASS); diff --git a/tools/docker-dev/sql/bootstrap.sql b/tools/docker-dev/sql/bootstrap.sql index 644178c1..88cf04b5 100644 --- a/tools/docker-dev/sql/bootstrap.sql +++ b/tools/docker-dev/sql/bootstrap.sql @@ -122,6 +122,20 @@ CREATE TABLE `account_deletion_requests` ( -- -------------------------------------------------------- +-- -------------------------------------------------------- + +-- +-- Table structure for table `sitevars` +-- + +CREATE TABLE `sitevars` ( + `id` int(11) NOT NULL, + `name` varchar(1000) NOT NULL, + `value` varchar(1000) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- -------------------------------------------------------- + -- -- Indexes for dumped tables -- @@ -168,6 +182,12 @@ ALTER TABLE `audit_log` ALTER TABLE `account_deletion_requests` ADD PRIMARY KEY (`id`); +-- +-- Indexes for table `sitevars` +-- +ALTER TABLE `sitevars` + ADD PRIMARY KEY (`id`); + -- -- AUTO_INCREMENT for dumped tables -- @@ -217,6 +237,13 @@ ALTER TABLE `account_deletion_requests` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; COMMIT; +-- +-- AUTO_INCREMENT for table `sitevars` +-- +ALTER TABLE `sitevars` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; +COMMIT; + /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;