From c9990fa1899ecc6afa43b9269196b17de047dca7 Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Tue, 7 Apr 2020 17:52:57 +0200 Subject: [PATCH] allow to create Unix group when creating a user --- lam/HISTORY | 1 + lam/lib/modules/posixAccount.inc | 76 +++++++++++++++++++++++++++----- lam/style/500_layout.css | 4 ++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/lam/HISTORY b/lam/HISTORY index b71088c7..f7ff148c 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,4 +1,5 @@ June 2020 7.2 + - Unix: allow to create group with same name during user creation - LAM Pro: -> EMail sending can be done via SMTP without local mail server -> License expiration warning can be sent via email or disabled diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index bdf72c3a..bf04640d 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -1076,7 +1076,7 @@ class posixAccount extends baseModule implements passwordService { } $this->attributes['uidNumber'][0] = trim($_POST['uidNumber']); $this->attributes['gidNumber'][0] = $_POST['gidNumber']; - if ($this->get_scope()=='user') { + if ($this->get_scope() == 'user') { if (($this->attributes['uid'][0] != $_POST['uid']) && !get_preg($_POST['uid'], '!upper')) { $errors[] = $this->messages['uid'][1]; } @@ -1202,10 +1202,57 @@ class posixAccount extends baseModule implements passwordService { $this->attributes[$this->getPasswordAttrName($modules)][0] = pwd_hash('x', true, $this->moduleSettings['posixAccount_pwdHash'][0]); } } + if (isset($_POST['posixAccount_createGroup']) + && !$this->isBooleanConfigOptionSet('posixAccount_' . $typeId . '_hideCreateGroup') + && ($this->get_scope() == 'user') + && $this->getAccountContainer()->isNewAccount && get_preg($this->attributes['uid'][0], 'username')) { + $groupType = $this->getPosixGroupType(); + $sessionKey = 'TMP' . getRandomNumber(); + $accountContainerTmp = new accountContainer($groupType, $sessionKey); + $_SESSION[$sessionKey] = &$accountContainerTmp; + $accountContainerTmp->new_account(); + $posixGroupModule = $accountContainerTmp->getAccountModule('posixGroup'); + $nextGid = $posixGroupModule->getNextGIDs(1, $errors, $groupType); + if ($nextGid !== null) { + $newGroupName = $this->attributes['uid'][0]; + $dnNewGroup = 'cn=' . $newGroupName . ',' . $groupType->getSuffix(); + $attributesNewGroup = array( + 'cn' => array($newGroupName), + 'gidNumber' => $nextGid[0], + 'objectClass' => array('posixGroup'), + ); + $newGroupSuccess = @ldap_add(getLDAPServerHandle(), $dnNewGroup, $attributesNewGroup); + if ($newGroupSuccess) { + $errors[] = array('INFO', _('Created new group.'), htmlspecialchars($newGroupName)); + $this->attributes['gidNumber'][0] = $nextGid[0]; + $this->groupCache = null; + } + else { + $errors[] = array('ERROR', _('Unable to create new group.'), getDefaultLDAPErrorString(getLDAPServerHandle())); + } + } + } // Return error-messages return $errors; } + /** + * Returns the first found group type that contains posixGroup. + * + * @return ConfiguredType|null type + */ + private function getPosixGroupType() { + $typeManager = new TypeManager(); + $groupTypes = $typeManager->getConfiguredTypesForScope('group'); + foreach ($groupTypes as $groupType) { + $modules = $groupType->getModules(); + if (in_array('posixGroup', $modules)) { + return $groupType; + } + } + return null; + } + /** * Checks if an attribute contains only ASCII characters and replaces invalid characters. * @@ -1634,7 +1681,16 @@ class posixAccount extends baseModule implements passwordService { $gidNumberSelect->setHasDescriptiveElements(true); $return->add($gidNumberSelect, 12); - if ($this->get_scope()=='user') { + if ($this->get_scope() == 'user') { + // new Unix group with same name + $posixGroupType = $this->getPosixGroupType(); + if ($this->getAccountContainer()->isNewAccount + && !$this->isBooleanConfigOptionSet('posixAccount_' . $typeId . '_hideCreateGroup') + && ($posixGroupType !== null) + && (!isset($this->attributes['uid'][0]) || !isset($groups[$this->attributes['uid'][0]]))) { + $return->addLabel(new htmlOutputText(' ', false)); + $return->addField(new htmlButton('posixAccount_createGroup', _('Create group with same name'))); + } // additional groups if (!$this->isBooleanConfigOptionSet('posixAccount_' . $typeId . '_hidegon') || !$this->isBooleanConfigOptionSet('posixAccount_' . $typeId . '_hideposixGroups')) { $return->addLabel(new htmlOutputText(_('Additional groups'))); @@ -2215,18 +2271,18 @@ class posixAccount extends baseModule implements passwordService { $hiddenOptionsContainerHead = new htmlGroup(); $hiddenOptionsContainerHead->addElement(new htmlOutputText(_('Hidden options'))); $hiddenOptionsContainerHead->addElement(new htmlHelpLink('hiddenOptions')); - $configUserContainer->addLabel($hiddenOptionsContainerHead, 12); - $configUserContainer->addField(new htmlOutputText('')); + $configUserContainer->add($hiddenOptionsContainerHead, 12); $configUserContainer->addVerticalSpacer('0.5rem'); - $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidegecos', false, _('Gecos'), null, false), 12); - $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidepassword', false, _('Password'), null, false), 12); + $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidegecos', false, _('Gecos'), null, true), 12, 4, 4); + $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidepassword', false, _('Password'), null, true), 12, 4, 4); $confActiveGONModules = array_merge($_SESSION['conf_config']->get_AccountModules('group'), $_SESSION['conf_config']->get_AccountModules('gon')); if (in_array('groupOfNames', $confActiveGONModules) || in_array('groupOfMembers', $confActiveGONModules) || in_array('groupOfUniqueNames', $confActiveGONModules)) { - $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidegon', false, _('Groups of names'), null, false), 12); - $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hideposixGroups', false, _('Unix groups'), null, false), 12); - $syncGroupsCheckbox = new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_syncGroups', false, _('Sync groups'), null, false); + $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hidegon', false, _('Groups of names'), null, true), 12, 4, 4); + $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hideCreateGroup', false, _('Create group with same name'), null, true), 12, 4, 4); + $configUserContainer->add(new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_hideposixGroups', false, _('Unix groups'), null, true), 12, 4, 4); + $syncGroupsCheckbox = new htmlResponsiveInputCheckbox('posixAccount_' . $typeId . '_syncGroups', false, _('Sync groups'), null, true); $syncGroupsCheckbox->setTableRowsToHide(array('posixAccount_' . $typeId . '_syncGroupsExclusions')); - $configUserContainer->add($syncGroupsCheckbox, 12); + $configUserContainer->add($syncGroupsCheckbox, 12, 4, 4); $configUserContainer->add(new htmlResponsiveInputTextarea('posixAccount_' . $typeId . '_syncGroupsExclusions', '', 20, 4, _('Exclude from group sync'), 'excludeFromGroupSync'), 12); } } diff --git a/lam/style/500_layout.css b/lam/style/500_layout.css index f881bd7e..114a243d 100644 --- a/lam/style/500_layout.css +++ b/lam/style/500_layout.css @@ -107,6 +107,10 @@ legend { color:black; } +button { + margin: 0.2rem; +} + input.listPageInput { width: 3em; text-align: center;