diff --git a/lam/HISTORY b/lam/HISTORY index cb372c2c..e1daa99d 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -2,6 +2,7 @@ March 2014 4.5 - IMAP: allow dynamic admin user names by replacing wildcards with LDAP attributes - Personal: allow to set fields read-only - Added option to server profile if referrals should be followed (fixes problems with Samba 4 and AD) + - Windows user/group: NIS support (msSFU30NisDomain, msSFU30Name) - LAM Pro: -> Allow to set single account types read-only -> Support for organizationalRole entries diff --git a/lam/docs/manual-sources/howto.xml b/lam/docs/manual-sources/howto.xml index 58f19d0f..2ed1123c 100644 --- a/lam/docs/manual-sources/howto.xml +++ b/lam/docs/manual-sources/howto.xml @@ -1713,7 +1713,7 @@ Have fun! - Samba 4: + Samba 4/Active Directory: Account types: @@ -2601,6 +2601,9 @@ Have fun! domain names and if pre-Windows 2000 user names should be managed. + NIS support is deactivated by default. Enable it if + needed. + @@ -3360,6 +3363,17 @@ Have fun! + NIS support is deactivated by default. Enable it if needed on + tab "Module settings". + + + + + + + + + Now you can edit your groups inside LAM. You can manage the group name, description and its type. Of course, you can also set the group members. diff --git a/lam/docs/manual-sources/images/mod_windowsGroup4.png b/lam/docs/manual-sources/images/mod_windowsGroup4.png new file mode 100644 index 00000000..310188f8 Binary files /dev/null and b/lam/docs/manual-sources/images/mod_windowsGroup4.png differ diff --git a/lam/docs/manual-sources/images/mod_windowsUser5.png b/lam/docs/manual-sources/images/mod_windowsUser5.png index b6148cd6..8077ed56 100644 Binary files a/lam/docs/manual-sources/images/mod_windowsUser5.png and b/lam/docs/manual-sources/images/mod_windowsUser5.png differ diff --git a/lam/lib/modules/windowsGroup.inc b/lam/lib/modules/windowsGroup.inc index a8d1b97d..b4e6f2ec 100644 --- a/lam/lib/modules/windowsGroup.inc +++ b/lam/lib/modules/windowsGroup.inc @@ -3,7 +3,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2013 Roland Gruber + Copyright (C) 2013 - 2014 Roland Gruber This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -95,7 +95,8 @@ class windowsGroup extends baseModule { // managed object classes $return['objectClasses'] = array('group', 'securityPrincipal', 'mailRecipient'); // managed attributes - $return['attributes'] = array('cn', 'description', 'info', 'mail', 'member', 'sAMAccountName', 'groupType', 'managedBy'); + $return['attributes'] = array('cn', 'description', 'info', 'mail', 'member', 'sAMAccountName', 'groupType', + 'managedBy', 'msSFU30Name', 'msSFU30NisDomain'); // help Entries $return['help'] = array( 'hiddenOptions' => array( @@ -138,6 +139,14 @@ class windowsGroup extends baseModule { "Headline" => _('Managed by'), 'attr' => 'managedBy', "Text" => _('The group is managed by this contact person.') ), + 'msSFU30Name' => array( + "Headline" => _('NIS name'), 'attr' => 'msSFU30Name', + "Text" => _('Group name for NIS.') + ), + 'msSFU30NisDomain' => array( + "Headline" => _('NIS domain'), 'attr' => 'msSFU30NisDomain', + "Text" => _('NIS domain name.') + ), ); // configuration settings $configContainer = new htmlTable(); @@ -149,6 +158,8 @@ class windowsGroup extends baseModule { $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsGroup_hidemail', false, _('Email address'), null, false)); $configContainerOptions->addElement(new htmlOutputText(' ')); $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsGroup_hidemanagedBy', false, _('Managed by'), null, false)); + $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsGroup_hidemsSFU30Name', true, _('NIS name'), null, false)); + $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsGroup_hidemsSFU30NisDomain', true, _('NIS domain'), null, false)); $configContainer->addElement($configContainerOptions, true); $return['config_options']['all'] = $configContainer; // upload fields @@ -211,6 +222,29 @@ class windowsGroup extends baseModule { 'example' => 'cn=user1,o=test', ); } + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + $return['upload_columns'][] = array( + 'name' => 'windowsGroup_msSFU30Name', + 'description' => _('NIS name'), + 'help' => 'msSFU30Name', + 'example' => _('adminstrators'), + ); + } + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + $return['upload_columns'][] = array( + 'name' => 'windowsGroup_msSFU30NisDomain', + 'description' => _('NIS domain'), + 'help' => 'msSFU30NisDomain', + 'example' => _('domain'), + ); + } + // profile options + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + $profileContainer = new htmlTable(); + $profileContainer->addElement(new htmlTableExtendedInputField(_('NIS domain'), 'windowsGroup_msSFU30NisDomain', null, 'msSFU30NisDomain'), true); + $return['profile_options'] = $profileContainer; + $return['profile_mappings']['windowsGroup_msSFU30NisDomain'] = 'msSFU30NisDomain'; + } // available PDF fields $return['PDF_fields'] = array( 'cn' => _('Group name'), @@ -226,6 +260,12 @@ class windowsGroup extends baseModule { if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemanagedBy')) { $return['PDF_fields']['managedBy'] = _('Managed by'); } + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + $return['PDF_fields']['msSFU30Name'] = _('NIS name'); + } + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + $return['PDF_fields']['msSFU30NisDomain'] = _('NIS domain'); + } return $return; } @@ -239,6 +279,8 @@ class windowsGroup extends baseModule { $this->messages['mail'][1] = array('ERROR', _('Account %s:') . ' windowsGroup_mail', _('Please enter a valid email address!')); $this->messages['groupScope'][0] = array('ERROR', _('Account %s:') . ' windowsGroup_groupScope', _('Please enter a valid group scope.')); $this->messages['groupType'][0] = array('ERROR', _('Account %s:') . ' windowsGroup_groupType', _('Please enter a valid group type.')); + $this->messages['msSFU30Name'][0] = array('ERROR', _('NIS name'), _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); + $this->messages['msSFU30Name'][1] = array('ERROR', _('Account %s:') . ' windowsGroup_msSFU30Name', _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); } /** @@ -316,6 +358,17 @@ class windowsGroup extends baseModule { } $container->addElement($managedByButtons, true); } + // NIS + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true) || !$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + $container->addElement(new htmlSubTitle(_('NIS')), true); + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + $this->addSimpleInputTextField($container, 'msSFU30Name', _('NIS name')); + } + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + $this->addSimpleInputTextField($container, 'msSFU30NisDomain', _('NIS domain')); + } + $container->addVerticalSpace('20px'); + } // group members $container->addElement(new htmlSpacer(null, '10px'), true); $container->addElement(new htmlOutputText(_("Group members"))); @@ -389,6 +442,22 @@ class windowsGroup extends baseModule { unset($this->attributes['managedBy']); } } + // NIS name + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + if ($this->getAccountContainer()->isNewAccount && !isset($this->attributes['msSFU30Name']) && empty($_POST['msSFU30Name'])) { + $this->attributes['msSFU30Name'][0] = $_POST['cn']; + } + else { + $this->attributes['msSFU30Name'][0] = $_POST['msSFU30Name']; + } + if (!empty($this->attributes['msSFU30Name'][0]) && !get_preg($this->attributes['msSFU30Name'][0], 'groupname')) { + $return[] = $this->messages['msSFU30Name'][0]; + } + } + // NIS domain + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + $this->attributes['msSFU30NisDomain'][0] = $_POST['msSFU30NisDomain']; + } return $return; } @@ -658,6 +727,25 @@ class windowsGroup extends baseModule { else { $partialAccounts[$i]['groupType'] = $partialAccounts[$i]['groupType'] - 2147483648; } + // NIS name + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30Name', true)) { + if (!empty($rawAccounts[$i][$ids['windowsGroup_msSFU30Name']])) { + if (get_preg($rawAccounts[$i][$ids['windowsGroup_msSFU30Name']], 'groupname')) { + $partialAccounts[$i]['msSFU30Name'] = $rawAccounts[$i][$ids['windowsGroup_msSFU30Name']]; + } + else { + $errMsg = $this->messages['msSFU30Name'][1]; + array_push($errMsg, array($i)); + $errors[] = $errMsg; + } + } + } + // NIS domain + if (!$this->isBooleanConfigOptionSet('windowsGroup_hidemsSFU30NisDomain', true)) { + if (!empty($rawAccounts[$i][$ids['windowsGroup_msSFU30NisDomain']])) { + $partialAccounts[$i]['msSFU30NisDomain'] = $rawAccounts[$i][$ids['windowsGroup_msSFU30NisDomain']]; + } + } } return $errors; } @@ -671,6 +759,8 @@ class windowsGroup extends baseModule { $this->addSimplePDFField($return, 'description', _('Description')); $this->addSimplePDFField($return, 'info', _('Notes')); $this->addSimplePDFField($return, 'mail', _('Email address')); + $this->addSimplePDFField($return, 'msSFU30Name', _('NIS name')); + $this->addSimplePDFField($return, 'msSFU30NisDomain', _('NIS domain')); // group type $groupType = windowsGroup::TYPE_SECURITY; $groupScope = windowsGroup::SCOPE_GLOBAL; diff --git a/lam/lib/modules/windowsUser.inc b/lam/lib/modules/windowsUser.inc index a9e539d7..f27e6e44 100644 --- a/lam/lib/modules/windowsUser.inc +++ b/lam/lib/modules/windowsUser.inc @@ -88,7 +88,7 @@ class windowsUser extends baseModule implements passwordService { $return['attributes'] = array('userPrincipalName', 'cn', 'sAMAccountName', 'description', 'displayName', 'givenName', 'initials', 'l', 'mail', 'otherTelephone', 'physicalDeliveryOfficeName', 'postalCode', 'postOfficeBox', 'sn', 'st', 'streetAddress', 'telephoneNumber', 'url', 'wWWHomePage', 'userAccountControl', 'profilePath', 'scriptPath', - 'pwdLastSet', 'otherMailbox', 'homeDirectory', 'homeDrive'); + 'pwdLastSet', 'otherMailbox', 'homeDirectory', 'homeDrive', 'msSFU30Name', 'msSFU30NisDomain'); // help Entries $return['help'] = array( 'cn' => array( @@ -241,6 +241,14 @@ class windowsUser extends baseModule implements passwordService { "Text" => _('UNC-path (\\\\server\\share\) of home directory. If no home drive is set then this directory must start with a drive letter (e.g. "c:\dir\user").') . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.') ), + 'msSFU30Name' => array( + "Headline" => _('NIS name'), 'attr' => 'msSFU30Name', + "Text" => _('User name for NIS.') + ), + 'msSFU30NisDomain' => array( + "Headline" => _('NIS domain'), 'attr' => 'msSFU30NisDomain', + "Text" => _('NIS domain name.') + ), ); // upload fields $return['upload_columns'] = array( @@ -437,6 +445,22 @@ class windowsUser extends baseModule implements passwordService { 'unique' => true, ); } + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + $return['upload_columns'][] = array( + 'name' => 'windowsUser_msSFU30Name', + 'description' => _('NIS name'), + 'help' => 'msSFU30Name', + 'example' => _('smiller'), + ); + } + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $return['upload_columns'][] = array( + 'name' => 'windowsUser_msSFU30NisDomain', + 'description' => _('NIS domain'), + 'help' => 'msSFU30NisDomain', + 'example' => _('domain'), + ); + } // profile options $profileContainer = new htmlTable(); $profileContainer->addElement(new htmlTableExtendedInputField(_('Common name'), 'windowsUser_cn', null, 'cn'), true); @@ -446,6 +470,9 @@ class windowsUser extends baseModule implements passwordService { $profileContainer->addElement(new htmlTableExtendedInputField(_('Logon script'), 'windowsUser_scriptPath', null, 'scriptPath'), true); $profileContainer->addElement(new htmlTableExtendedInputField(_('Profile path'), 'windowsUser_profilePath', null, 'profilePath'), true); $profileContainer->addElement(new htmlTableExtendedInputField(_('Home directory'), 'windowsUser_homeDirectory', null, 'homeDirectory'), true); + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $profileContainer->addElement(new htmlTableExtendedInputField(_('NIS domain'), 'windowsUser_msSFU30NisDomain', null, 'msSFU30NisDomain'), true); + } $return['profile_options'] = $profileContainer; // profile mappings $return['profile_mappings'] = array( @@ -456,6 +483,9 @@ class windowsUser extends baseModule implements passwordService { 'windowsUser_profilePath' => 'profilePath', 'windowsUser_homeDirectory' => 'homeDirectory', ); + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $return['profile_mappings']['windowsUser_msSFU30NisDomain'] = 'msSFU30NisDomain'; + } // available PDF fields $return['PDF_fields'] = array( 'userPrincipalName' => _('User name'), @@ -491,6 +521,12 @@ class windowsUser extends baseModule implements passwordService { if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) { $return['PDF_fields']['sAMAccountName'] = _('User name (pre W2K)'); } + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + $return['PDF_fields']['msSFU30Name'] = _('NIS name'); + } + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $return['PDF_fields']['msSFU30NisDomain'] = _('NIS domain'); + } // self service search attributes $return['selfServiceSearchAttributes'] = array('sAMAccountName'); // self service field settings @@ -520,6 +556,8 @@ class windowsUser extends baseModule implements passwordService { $configContainer->addElement($configHiddenGroup, true); $configContainerOptions = new htmlTable(); $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidesAMAccountName', true, _('User name (pre W2K)'), null, false)); + $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidemsSFU30Name', true, _('NIS name'), null, false)); + $configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidemsSFU30NisDomain', true, _('NIS domain'), null, false)); $configContainer->addElement($configContainerOptions, true); $return['config_options']['all'] = $configContainer; return $return; @@ -572,6 +610,8 @@ class windowsUser extends baseModule implements passwordService { $this->messages['homeDrive'][0] = array('ERROR', _('Account %s:') . ' windowsUser_homeDrive', _('Please enter a valid drive letter.')); $this->messages['homeDirectory'][0] = array('ERROR', _('Home directory'), _('Homedirectory contains invalid characters.')); $this->messages['homeDirectory'][1] = array('ERROR', _('Account %s:') . ' windowsUser_homeDirectory', _('Homedirectory contains invalid characters.')); + $this->messages['msSFU30Name'][0] = array('ERROR', _('NIS name'), _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); + $this->messages['msSFU30Name'][1] = array('ERROR', _('Account %s:') . ' windowsUser_msSFU30Name', _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); } /** @@ -718,9 +758,20 @@ class windowsUser extends baseModule implements passwordService { } $containerLeft->addElement(new htmlTableExtendedSelect('homeDrive', $drives, $selected, _('Home drive'), 'homeDrive'), true); // home directory - $this->addSimpleInputTextField($containerLeft, 'homeDirectory', _('Home directory')); + $this->addSimpleInputTextField($containerLeft, 'homeDirectory', _('Home directory'), true); - $containerLeft->addElement(new htmlEqualWidth(array('streetAddress', 'cn'))); + // NIS attributes + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true) || !$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $containerLeft->addElement(new htmlSubTitle(_('NIS')), true); + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + $this->addSimpleInputTextField($containerLeft, 'msSFU30Name', _('NIS name')); + } + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + $this->addSimpleInputTextField($containerLeft, 'msSFU30NisDomain', _('NIS domain')); + } + } + + $containerLeft->addElement(new htmlEqualWidth(array('streetAddress', 'cn')), true); $containerRight = new htmlTable(); $containerRight->alignment = htmlElement::ALIGN_TOP; @@ -935,6 +986,22 @@ class windowsUser extends baseModule implements passwordService { if (!empty($this->attributes['homeDrive'][0]) && !get_preg($this->attributes['homeDirectory'][0], 'UNC')) { $return[] = $this->messages['homeDirectory'][0]; } + // NIS name + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + if ($this->getAccountContainer()->isNewAccount && !isset($this->attributes['msSFU30Name']) && empty($_POST['msSFU30Name'])) { + $this->attributes['msSFU30Name'][0] = $_POST['userPrincipalName']; + } + else { + $this->attributes['msSFU30Name'][0] = $_POST['msSFU30Name']; + } + if (!empty($this->attributes['msSFU30Name'][0]) && !get_preg($this->attributes['msSFU30Name'][0], 'username')) { + $return[] = $this->messages['msSFU30Name'][0]; + } + } + // NIS domain + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + $this->attributes['msSFU30NisDomain'][0] = $_POST['msSFU30NisDomain']; + } return $return; } @@ -1407,6 +1474,25 @@ class windowsUser extends baseModule implements passwordService { _('LAM was unable to find a group with this name!') . '
' . htmlspecialchars(implode('; ', $invalidGroups))); } } + // NIS name + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) { + if (!empty($rawAccounts[$i][$ids['windowsUser_msSFU30Name']])) { + if (get_preg($rawAccounts[$i][$ids['windowsUser_msSFU30Name']], 'username')) { + $partialAccounts[$i]['msSFU30Name'] = $rawAccounts[$i][$ids['windowsUser_msSFU30Name']]; + } + else { + $errMsg = $this->messages['msSFU30Name'][1]; + array_push($errMsg, array($i)); + $errors[] = $errMsg; + } + } + } + // NIS domain + if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { + if (!empty($rawAccounts[$i][$ids['windowsUser_msSFU30NisDomain']])) { + $partialAccounts[$i]['msSFU30NisDomain'] = $rawAccounts[$i][$ids['windowsUser_msSFU30NisDomain']]; + } + } } return $errors; } @@ -1551,6 +1637,8 @@ class windowsUser extends baseModule implements passwordService { $this->addSimplePDFField($return, 'telephoneNumber', _('Telephone number')); $this->addSimplePDFField($return, 'url', _('Other web sites')); $this->addSimplePDFField($return, 'wWWHomePage', _('Web site')); + $this->addSimplePDFField($return, 'msSFU30Name', _('NIS name')); + $this->addSimplePDFField($return, 'msSFU30NisDomain', _('NIS domain')); $deactivated = _('no'); if ($this->isDeactivated($this->attributes)) { $deactivated = _('yes');