From 0329ca030c8c32a52d34c5eae58c494536d2c5a6 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Fri, 7 Sep 2012 16:35:54 +0000 Subject: [PATCH] allow to specify alternative suffix for uniqueness check --- lam/lib/modules/posixAccount.inc | 102 +++++++++++++++++++++++++++---- lam/lib/modules/posixGroup.inc | 69 +++++++++++++++++---- 2 files changed, 148 insertions(+), 23 deletions(-) diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index 9966ef39..10523efd 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -64,6 +64,8 @@ class posixAccount extends baseModule implements passwordService { private $clearTextPassword; /** caches the list of known UIDs */ private $cachedUIDList = null; + /** caches the list of known user names */ + private $cachedUserNameList = null; /** if set to true the suggested user name for John Doe will be john.doe instead of jdoe */ protected $SUGGEST_LONG_USER_NAME = false; @@ -179,7 +181,8 @@ class posixAccount extends baseModule implements passwordService { $configUserContainer->addElement($minUid, true); $maxUid = new htmlTableExtendedInputField(_('Maximum UID number'), 'posixAccount_maxUID', null, 'minMaxUser'); $maxUid->setRequired(true); - $configUserContainer->addElement($maxUid); + $configUserContainer->addElement($maxUid, true); + $configUserContainer->addElement(new htmlTableExtendedInputField(_('Suffix for UID/user name check'), 'posixAccount_uidCheckSuffixUser', '', 'uidCheckSuffix'), true); $return['config_options']['user'] = $configUserContainer; $configHostContainer = new htmlTable(); $configHostContainer->addElement(new htmlSubTitle(_("Hosts")), true); @@ -188,7 +191,8 @@ class posixAccount extends baseModule implements passwordService { $configHostContainer->addElement($minUid, true); $maxUid = new htmlTableExtendedInputField(_('Maximum UID number'), 'posixAccount_maxMachine', null, 'minMaxHost'); $maxUid->setRequired(true); - $configHostContainer->addElement($maxUid); + $configHostContainer->addElement($maxUid, true); + $configHostContainer->addElement(new htmlTableExtendedInputField(_('Suffix for UID/user name check'), 'posixAccount_uidCheckSuffixHost', '', 'uidCheckSuffix'), true); $return['config_options']['host'] = $configHostContainer; $configOptionsContainer = new htmlTable(); $configOptionsContainer->addElement(new htmlSubTitle(_('Options')), true); @@ -376,6 +380,10 @@ class posixAccount extends baseModule implements passwordService { "Headline" => _("Home directory"), "Text" => _("This will create the user's home directory on the specified server.") ), + 'uidCheckSuffix' => array ( + "Headline" => _("Suffix for UID/user name check"), + "Text" => _("LAM checks if the entered user name and UID are unique. Here you can enter the LDAP suffix that is used to search for duplicates. By default the account type suffix is used. You only need to change this if you use multiple server profiles with different OUs but need unique user names or UIDs.") + ), 'user' => array( 'uid' => array( "Headline" => _("User name"), 'attr' => 'uid', @@ -546,7 +554,7 @@ class posixAccount extends baseModule implements passwordService { } // Set additional group memberships - if ($this->orig['uid'][0]!='' && $this->attributes['uid'][0]!=$this->orig['uid'][0]) { + if (isset($this->orig['uid'][0]) && ($this->orig['uid'][0] != '') && ($this->attributes['uid'][0] != $this->orig['uid'][0])) { // find affected groups $groupList = searchLDAPByAttribute('memberUid', $this->orig['uid'][0], 'posixGroup', array('dn'), array('group')); for ($i = 0; $i < sizeof($groupList); $i++) { @@ -868,12 +876,12 @@ class posixAccount extends baseModule implements passwordService { // Create automatic useraccount with number if original user already exists // Reset name to original name if new name is in use // Set username back to original name if new username is in use - if ((sizeof(searchLDAPByAttribute('uid', $this->attributes['uid'][0], 'posixAccount', array('uid'), array('user', 'host'))) > 0) && isset($this->orig['uid'][0]) && ($this->orig['uid'][0]!='')) { + if ($this->userNameExists($this->attributes['uid'][0]) && isset($this->orig['uid'][0]) && ($this->orig['uid'][0]!='')) { $this->attributes['uid'][0] = $this->orig['uid'][0]; } else { // Change uid to a new uid until a free uid is found - while (sizeof(searchLDAPByAttribute('uid', $this->attributes['uid'][0], 'posixAccount', array('uid'), array('user', 'host'))) > 0) { + while ($this->userNameExists($this->attributes['uid'][0])) { if ($this->get_scope()=='host') $this->attributes['uid'][0] = substr($this->attributes['uid'][0], 0, -1); // get last character of username $lastchar = substr($this->attributes['uid'][0], strlen($this->attributes['uid'][0])-1, 1); @@ -1601,10 +1609,7 @@ class posixAccount extends baseModule implements passwordService { $errors = array(); $needAutoUID = array(); // get list of existing users - $existingUsers = searchLDAPByAttribute('uid', '*', 'posixAccount', array('uid'), array('user', 'host')); - for ($i = 0; $i < sizeof($existingUsers); $i++) { - $existingUsers[$i] = $existingUsers[$i]['uid'][0]; - } + $existingUsers = $this->getUserNames(); // get list of existing groups $groupList = $this->findGroups(); $groupMap = array(); @@ -2366,15 +2371,88 @@ class posixAccount extends baseModule implements passwordService { if ($this->cachedUIDList != null) { return $this->cachedUIDList; } - $result = searchLDAPByAttribute('uidNumber', '*', 'posixAccount', array('uidNumber'), array('user', 'host')); $this->cachedUIDList = array(); - for ($i = 0; $i < sizeof($result); $i++) { - $this->cachedUIDList[] = $result[$i]['uidnumber'][0]; + $attrs = array('uidNumber'); + $filter = '(&(objectClass=posixAccount)(uidNumber=*))'; + $types = $_SESSION['config']->get_ActiveTypes(); + // get user UIDs + if (in_array('user', $types)) { + $suffixUsers = $_SESSION['config']->get_Suffix('user'); + if (isset($this->moduleSettings['posixAccount_uidCheckSuffixUser'][0]) && ($this->moduleSettings['posixAccount_uidCheckSuffixUser'][0] != '')) { + $suffixUsers = $this->moduleSettings['posixAccount_uidCheckSuffixUser'][0]; + } + $result = searchLDAP($suffixUsers, $filter, $attrs); + for ($i = 0; $i < sizeof($result); $i++) { + $this->cachedUIDList[] = $result[$i]['uidnumber'][0]; + } + } + // get host UIDs + if (in_array('host', $types)) { + $suffixHosts = $_SESSION['config']->get_Suffix('host'); + if (isset($this->moduleSettings['posixAccount_uidCheckSuffixHost'][0]) && ($this->moduleSettings['posixAccount_uidCheckSuffixHost'][0] != '')) { + $suffixHosts = $this->moduleSettings['posixAccount_uidCheckSuffixHost'][0]; + } + if ($suffixUsers != $suffixHosts) { + $result = searchLDAP($suffixHosts, $filter, $attrs); + for ($i = 0; $i < sizeof($result); $i++) { + $this->cachedUIDList[] = $result[$i]['uidnumber'][0]; + } + } } sort($this->cachedUIDList, SORT_NUMERIC); return $this->cachedUIDList; } + /** + * Checks if the given user name already exists in LDAP. + * + * @param String $userName user name + * @return boolean true if already exists + */ + private function userNameExists($userName) { + return in_array($userName, $this->getUserNames()); + } + + /** + * Returns a list of all user names in LDAP. + * + * @return array user names + */ + private function getUserNames() { + if ($this->cachedUserNameList != null) { + return $this->cachedUserNameList; + } + $this->cachedUserNameList = array(); + $attrs = array('uid'); + $filter = '(&(objectClass=posixAccount)(uid=*))'; + $types = $_SESSION['config']->get_ActiveTypes(); + // get user names + if (in_array('user', $types)) { + $suffixUsers = $_SESSION['config']->get_Suffix('user'); + if (isset($this->moduleSettings['posixAccount_uidCheckSuffixUser'][0]) && ($this->moduleSettings['posixAccount_uidCheckSuffixUser'][0] != '')) { + $suffixUsers = $this->moduleSettings['posixAccount_uidCheckSuffixUser'][0]; + } + $result = searchLDAP($suffixUsers, $filter, $attrs); + for ($i = 0; $i < sizeof($result); $i++) { + $this->cachedUserNameList[] = $result[$i]['uid'][0]; + } + } + // get host UIDs + if (in_array('host', $types)) { + $suffixHosts = $_SESSION['config']->get_Suffix('host'); + if (isset($this->moduleSettings['posixAccount_uidCheckSuffixHost'][0]) && ($this->moduleSettings['posixAccount_uidCheckSuffixHost'][0] != '')) { + $suffixHosts = $this->moduleSettings['posixAccount_uidCheckSuffixHost'][0]; + } + if ($suffixUsers != $suffixHosts) { + $result = searchLDAP($suffixHosts, $filter, $attrs); + for ($i = 0; $i < sizeof($result); $i++) { + $this->cachedUserNameList[] = $result[$i]['uid'][0]; + } + } + } + return $this->cachedUserNameList; + } + /** * Returns if LAM manages group of names entries. * diff --git a/lam/lib/modules/posixGroup.inc b/lam/lib/modules/posixGroup.inc index 9f9e11a8..8541236d 100644 --- a/lam/lib/modules/posixGroup.inc +++ b/lam/lib/modules/posixGroup.inc @@ -49,6 +49,8 @@ class posixGroup extends baseModule implements passwordService { private $cachedGIDList = null; /** cache for existing users and their GIDs */ private $cachedUserToGIDList = null; + /** cache for existing groups */ + private $cachedGroupNameList = null; /** * In this function the LDAP account is built up. @@ -317,6 +319,7 @@ class posixGroup extends baseModule implements passwordService { $maxGidInput = new htmlTableExtendedInputField(_('Maximum GID number'), 'posixGroup_maxGID', null, 'minMaxGID'); $maxGidInput->setRequired(true); $configContainer->addElement($maxGidInput, true); + $configContainer->addElement(new htmlTableExtendedInputField(_('Suffix for GID/group name check'), 'posixGroup_gidCheckSuffix', '', 'gidCheckSuffix'), true); $return['config_options']['group'] = $configContainer; // configuration checks $return['config_checks']['group']['posixGroup_minGID'] = array ( @@ -427,6 +430,10 @@ class posixGroup extends baseModule implements passwordService { 'changegids' => array( "Headline" => _("Change GID number of users and hosts"), "Text" => _("The ID of this group was changed. You can update all user and host entries to the new group ID.") + ), + 'gidCheckSuffix' => array ( + "Headline" => _("Suffix for GID/group name check"), + "Text" => _("LAM checks if the entered group name and GID are unique. Here you can enter the LDAP suffix that is used to search for duplicates. By default the account type suffix is used. You only need to change this if you use multiple server profiles with different OUs but need unique group names or GIDs.") ) ); @@ -607,7 +614,7 @@ class posixGroup extends baseModule implements passwordService { } } } - if ($this->manageCnAttribute && ($this->attributes['cn'][0]!=$_POST['cn'])) { + if ($this->manageCnAttribute) { $this->attributes['cn'][0] = $_POST['cn']; if (preg_match('/^[A-Z]+$/', $_POST['cn'])) { $errors[] = $this->messages['cn'][0]; @@ -617,13 +624,13 @@ class posixGroup extends baseModule implements passwordService { $errors[] = $this->messages['cn'][2]; // Create automatic useraccount with number if original user already exists // Reset name to original name if new name is in use - // Set username back to original name if new username is in use - if ((sizeof(searchLDAPByAttribute('cn', $this->attributes['cn'][0], 'posixGroup', array('cn'), array('group'))) > 0) && ($this->orig['cn'][0]!='')) { + // Set username back to original name if new group name is in use + if ($this->groupNameExists($this->attributes['cn'][0]) && ($this->orig['cn'][0] != '')) { $this->attributes['cn'][0] = $this->orig['cn'][0]; } // Change gid to a new gid until a free gid is found - else while (sizeof(searchLDAPByAttribute('cn', $this->attributes['cn'][0], 'posixGroup', array('cn'), array('group'))) > 0) { - // get last character of username + else while ($this->groupNameExists($this->attributes['cn'][0])) { + // get last character of group name $lastchar = substr($this->attributes['cn'][0], strlen($this->attributes['cn'][0])-1, 1); // Last character is no number if ( !preg_match('/^([0-9])+$/', $lastchar)) @@ -652,14 +659,15 @@ class posixGroup extends baseModule implements passwordService { $this->attributes['cn'][0] = $firstchars . (intval($lastchars)+1); } } - // Show warning if lam has changed username + // Show warning if lam has changed group name if ($this->attributes['cn'][0] != $_POST['cn']) { $errors[] = $this->messages['cn'][1]; } - // show info when gidnumber has changed - if (($this->orig['gidNumber'][0]!=$this->attributes['gidNumber'][0]) && $this->orig['gidNumber'][0]!='' && $_POST['gidNumber']!=$this->attributes['gidNumber'][0]) { - $errors[] = $this->messages['gidNumber'][0]; - } + } + // show info when gidnumber has changed + if (isset($this->orig['gidNumber'][0]) && ($this->orig['gidNumber'][0] != $this->attributes['gidNumber'][0]) + && ($this->orig['gidNumber'][0] != '') && !$this->changegids) { + $errors[] = $this->messages['gidNumber'][0]; } // Return error-messages return $errors; @@ -818,8 +826,14 @@ class posixGroup extends baseModule implements passwordService { if ($this->cachedGIDList != null) { return $this->cachedGIDList; } - $result = searchLDAPByAttribute('gidNumber', '*', 'posixGroup', array('gidNumber'), array('group')); $this->cachedGIDList = array(); + $attrs = array('gidNumber'); + $filter = '(&(objectClass=posixGroup)(gidNumber=*))'; + $suffix = $_SESSION['config']->get_Suffix('group'); + if (isset($this->moduleSettings['posixGroup_gidCheckSuffix'][0]) && ($this->moduleSettings['posixGroup_gidCheckSuffix'][0] != '')) { + $suffix = $this->moduleSettings['posixGroup_gidCheckSuffix'][0]; + } + $result = searchLDAP($suffix, $filter, $attrs); for ($i = 0; $i < sizeof($result); $i++) { $this->cachedGIDList[] = $result[$i]['gidnumber'][0]; } @@ -844,6 +858,39 @@ class posixGroup extends baseModule implements passwordService { return $this->cachedUserToGIDList; } + /** + * Checks if the given group name already exists in LDAP. + * + * @param String $groupName group name + * @return boolean true if already exists + */ + private function groupNameExists($groupName) { + return in_array($groupName, $this->getGroupNames()); + } + + /** + * Returns a list of all group names in LDAP. + * + * @return array group names + */ + private function getGroupNames() { + if ($this->cachedGroupNameList != null) { + return $this->cachedGroupNameList; + } + $this->cachedGroupNameList = array(); + $attrs = array('cn'); + $filter = '(&(objectClass=posixGroup)(cn=*))'; + $suffix = $_SESSION['config']->get_Suffix('group'); + if (isset($this->moduleSettings['posixGroup_gidCheckSuffix'][0]) && ($this->moduleSettings['posixGroup_gidCheckSuffix'][0] != '')) { + $suffix = $this->moduleSettings['posixGroup_gidCheckSuffix'][0]; + } + $result = searchLDAP($suffix, $filter, $attrs); + for ($i = 0; $i < sizeof($result); $i++) { + $this->cachedGroupNameList[] = $result[$i]['cn'][0]; + } + return $this->cachedGroupNameList; + } + } ?>