mirror of
https://github.com/LDAPAccountManager/lam.git
synced 2025-10-03 17:59:21 +02:00
Merge pull request #400 from LDAPAccountManager/feature/390_no-default-passwords
Feature/390 no default passwords
This commit is contained in:
commit
1a489d6688
22 changed files with 534 additions and 319 deletions
|
@ -14,7 +14,6 @@ Configuration:
|
|||
All settings can be edited via the webfrontend. Please
|
||||
point your browser to the LAM start page and then select
|
||||
"LAM configuration".
|
||||
The default password for the configuration is "lam".
|
||||
|
||||
|
||||
Lamdaemon:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
# Copyright (C) 2019 Felix Bartels
|
||||
# 2019 - 2024 Roland Gruber
|
||||
# 2019 - 2025 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
|
||||
|
@ -59,7 +59,6 @@ if [ "$LAM_SKIP_PRECONFIGURE" != "true" ]; then
|
|||
LAM_CONFIGURATION_PASSWORD="${LAM_CONFIGURATION_PASSWORD:-}"
|
||||
|
||||
sed -i -f- /etc/ldap-account-manager/config.cfg <<- EOF
|
||||
s|"password": "[^"]*"|"password": "${LAM_PASSWORD_SSHA}"|;
|
||||
s|"license": "[^"]*"|"license": "${LAM_LICENSE}"|;
|
||||
s|"configDatabaseType": "[^"]*"|"configDatabaseType": "${LAM_CONFIGURATION_DATABASE}"|;
|
||||
s|"configDatabaseServer": "[^"]*"|"configDatabaseServer": "${LAM_CONFIGURATION_HOST}"|;
|
||||
|
@ -68,6 +67,9 @@ if [ "$LAM_SKIP_PRECONFIGURE" != "true" ]; then
|
|||
s|"configDatabaseUser": "[^"]*"|"configDatabaseUser": "${LAM_CONFIGURATION_USER}"|;
|
||||
s|"configDatabasePassword": "[^"]*"|"configDatabasePassword": "${LAM_CONFIGURATION_PASSWORD}"|;
|
||||
EOF
|
||||
if ! grep -e '"password":' /etc/ldap-account-manager/config.cfg > /dev/null; then
|
||||
sed -i "2i\ \ \"password\": \"${LAM_PASSWORD_SSHA}\"," /etc/ldap-account-manager/config.cfg
|
||||
fi
|
||||
unset LAM_PASSWORD
|
||||
|
||||
set +e
|
||||
|
@ -82,12 +84,14 @@ EOF
|
|||
sed -i -f- /var/lib/ldap-account-manager/config/lam.conf <<- EOF
|
||||
s|"ServerURL": "[^"]*"|"ServerURL": "${LDAP_SERVER}"|;
|
||||
s|"Admins": "[^"]*"|"Admins": "${LDAP_ADMIN_USER}"|;
|
||||
s|"Passwd": "[^"]*"|"Passwd": "${LAM_PASSWORD_SSHA}"|;
|
||||
s|"treeViewSuffix": "[^"]*"|"treeViewSuffix": "${LDAP_BASE_DN}"|;
|
||||
s|"defaultLanguage": "[^"]*"|"defaultLanguage": "${LAM_LANG}.utf8"|;
|
||||
s|"suffix_user": "[^"]*"|"suffix_user": "${LDAP_USERS_DN}"|;
|
||||
s|"suffix_group": "[^"]*"|"suffix_group": "${LDAP_GROUPS_DN}"|;
|
||||
EOF
|
||||
if ! grep -e '"Passwd":' /var/lib/ldap-account-manager/config/lam.conf > /dev/null; then
|
||||
sed -i "2i\ \ \"Passwd\": \"${LAM_PASSWORD_SSHA}\"," /var/lib/ldap-account-manager/config/lam.conf
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
March 2025 9.1
|
||||
- Usability improvements (348, 360)
|
||||
- Security: LAM no longer ships with any default passwords, main configuration password is requested on login if not yet set (#390)
|
||||
- Fixed bugs:
|
||||
-> Ambiguous tooltip on profile editor for Shadow users (#394)
|
||||
-> Self service photo file enhancements (#396)
|
||||
|
|
|
@ -15,9 +15,6 @@ LAM - Readme
|
|||
Installation and documentation:
|
||||
Please see the LAM manual in docs/manual/index.html.
|
||||
|
||||
Default password:
|
||||
The default password to edit the configuration options is "lam".
|
||||
|
||||
Download:
|
||||
You can get the newest version at https://www.ldap-account-manager.org/.
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"useTLS": "yes",
|
||||
"followReferrals": "false",
|
||||
"pagedResults": "false",
|
||||
"Passwd": "{CRYPT-SHA512}$6$ZJcXwaxHP0GQH0Rd$Ggkn8Wz\/8ntCM9v0TywomjkgSvV.3BoayFwnc9QP3MV.b7HWaqLOA8urP2e7HyEmU\/JmC8xR7jTqrXCHC4kFr. WkpjWHdheEhQMEdRSDBSZA==",
|
||||
"Admins": "cn=Manager,dc=my-domain,dc=com",
|
||||
"defaultLanguage": "en_GB.utf8",
|
||||
"scriptPath": "",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"password": "{CRYPT-SHA512}$6$WheNHdlVwDoL4s.x$DrZ10TpIGQa5wd0jbvtm8eaTleJCf1nec3ihOaNwMdPUKVFCphXwtnTSmFFXjhGa45RlrSEWhDVyjLCMiV\/.c. V2hlTkhkbFZ3RG9MNHMueA==",
|
||||
"default": "lam",
|
||||
"sessionTimeout": "30",
|
||||
"hideLoginErrorDetails": "false",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"useTLS": "yes",
|
||||
"followReferrals": "false",
|
||||
"pagedResults": "false",
|
||||
"Passwd": "{CRYPT-SHA512}$6$MUWJEkvtUY7G5sFA$QS6voQCksH9gNbbbQpjDKt65iez9bgKQI2x60DAffCK5.LO\/\/QfYTetQ6V2PlUR32CTkuhlSXSGXnH9scD\/zb0 TVVXSkVrdnRVWTdHNXNGQQ==",
|
||||
"Admins": "cn=Manager,dc=my-domain,dc=com",
|
||||
"defaultLanguage": "en_GB.utf8",
|
||||
"scriptPath": "",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"useTLS": "no",
|
||||
"followReferrals": "false",
|
||||
"pagedResults": "false",
|
||||
"Passwd": "{CRYPT-SHA512}$6$zvb8WVEHSAKEGtGO$573kA9Us8LtGLLm5Gu87P\/vIiF\/2Ol\/DauzPmUpvC4eCL\/t0WWiwBaY19Rx5G3wzbeZWWlE1kp2fikrpZTZ51\/ enZiOFdWRUhTQUtFR3RHTw==",
|
||||
"Admins": "cn=Manager,dc=my-domain,dc=com",
|
||||
"defaultLanguage": "en_GB.utf8",
|
||||
"scriptPath": "",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"useTLS": "no",
|
||||
"followReferrals": "false",
|
||||
"pagedResults": "false",
|
||||
"Passwd": "{CRYPT-SHA512}$6$9IWWua4lbp7uiLCC$AHPgST1YAm3yUAWKGeNZ5f9GCo1wBGyVo3MGvAt6.UOtQ9dYxs4WeQ4mlzjR30rD6cRayMNRBWqYFuBLvzn9T0 OUlXV3VhNGxicDd1aUxDQw==",
|
||||
"Admins": "cn=Administrator,cn=users,dc=my-domain,dc=com",
|
||||
"defaultLanguage": "en_GB.utf8",
|
||||
"scriptPath": "",
|
||||
|
|
|
@ -28,27 +28,23 @@
|
|||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Locate config.cfg: On DEB/RPM installations it is in
|
||||
/usr/share/ldap-account-manager/config and for tar.bz2 in config
|
||||
<emphasis
|
||||
role="bold">/usr/share/ldap-account-manager/config</emphasis> and
|
||||
for tar.bz2 in <emphasis role="bold">config</emphasis>
|
||||
folder.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Locate the "password" entry in the file</para>
|
||||
<para>Locate the "password" line in the file</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Replace the password hash after "password: " with your new
|
||||
clear-text password (e.g. "secret")</para>
|
||||
<para>Remove the password line in the configuration file</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>After the change the line should look like this:</para>
|
||||
|
||||
<literallayout>password: secret</literallayout>
|
||||
|
||||
<para>You can now login using your new password. Set the password once
|
||||
again via GUI in main configuration settings. This will then put again
|
||||
a hash value in the config.cfg file.</para>
|
||||
<para>When you open LAM's start page you will now be asked to set a
|
||||
new password.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
|
|
@ -44,11 +44,6 @@
|
|||
<section id="generalSettings">
|
||||
<title>General settings</title>
|
||||
|
||||
<para>After selecting "Edit general settings" you will need to enter the
|
||||
<link linkend="a_configPasswords">master configuration password</link>.
|
||||
The default password for new installations is "lam". Now you can edit the
|
||||
general settings.</para>
|
||||
|
||||
<section>
|
||||
<title>Configuration Database</title>
|
||||
|
||||
|
|
|
@ -87,26 +87,15 @@
|
|||
<listitem>
|
||||
<para>Edge (max. 2 years old)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Opera (max. 2 years old)</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The default password to edit the configuration options is
|
||||
"lam".</para>
|
||||
|
||||
<para><emphasis role="bold">License:</emphasis></para>
|
||||
|
||||
<para>LAM is published under the GNU General Public License. The complete
|
||||
list of licenses can be found in the copyright file.</para>
|
||||
|
||||
<para><emphasis role="bold">Default password:</emphasis></para>
|
||||
|
||||
<para>The default password for the LAM configuration is "lam".</para>
|
||||
|
||||
<literallayout>
|
||||
Have fun!
|
||||
The LAM development team</literallayout>
|
||||
|
|
|
@ -12,7 +12,7 @@ use function LAM\TYPES\getScopeFromTypeId;
|
|||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2024 Roland Gruber
|
||||
Copyright (C) 2003 - 2025 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
|
||||
|
@ -50,6 +50,19 @@ include_once __DIR__ . "/types.inc";
|
|||
/** 2-factor */
|
||||
include_once __DIR__ . '/2factor.inc';
|
||||
|
||||
/**
|
||||
* Checks if the configuration password is secure.
|
||||
*
|
||||
* @param string $password password
|
||||
* @return bool is secure
|
||||
*/
|
||||
function isValidConfigurationPassword(string $password): bool {
|
||||
return preg_match('/[a-zA-Z]/', $password)
|
||||
&& preg_match('/\d/', $password)
|
||||
&& preg_match('/[^a-zA-Z0-9]/', $password)
|
||||
&& (strlen($password) >= 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the environment variables for custom SSL CA certificates.
|
||||
*/
|
||||
|
@ -1453,6 +1466,15 @@ class LAMConfig {
|
|||
return "{CRYPT-SHA512}" . crypt($password, '$6$' . $salt) . " " . base64_encode($salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the server profile has a password set.
|
||||
*
|
||||
* @return bool password is set
|
||||
*/
|
||||
public function hasPasswordSet(): bool {
|
||||
return ($this->Passwd != null) && ($this->Passwd !== '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the LDAP suffix for the given account type
|
||||
*
|
||||
|
@ -3242,8 +3264,9 @@ class LAMCfgMain {
|
|||
|
||||
/**
|
||||
* Saves the configuration to the persistence layer.
|
||||
* @throws LAMException error saving config
|
||||
*/
|
||||
public function save() {
|
||||
public function save(): void {
|
||||
if ($this->configDatabaseType === self::DATABASE_MYSQL) {
|
||||
$this->saveLocal(true);
|
||||
$this->saveDb();
|
||||
|
@ -3261,7 +3284,7 @@ class LAMCfgMain {
|
|||
@chmod($sslPath, 0600);
|
||||
}
|
||||
else {
|
||||
StatusMessage("ERROR", _("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||
throw new LAMException(_("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||
}
|
||||
}
|
||||
// delete SSL certificate
|
||||
|
@ -3269,7 +3292,7 @@ class LAMCfgMain {
|
|||
$sslPath = $this->getInternalSSLCaCertFileName();
|
||||
$result = @unlink($sslPath);
|
||||
if (!$result) {
|
||||
StatusMessage("ERROR", _("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||
throw new LAMException(_("Cannot write certificate file. Please check the permissions of config/serverCerts.pem."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3296,6 +3319,7 @@ class LAMCfgMain {
|
|||
* Saves preferences to config file config.cfg
|
||||
*
|
||||
* @param bool $persistenceOnly store only persistence related data
|
||||
* @throws LAMException error saving config
|
||||
*/
|
||||
public function saveLocal(bool $persistenceOnly): void {
|
||||
$data = $persistenceOnly ? $this->exportPersistenceData() : $this->exportData();
|
||||
|
@ -3308,10 +3332,19 @@ class LAMCfgMain {
|
|||
chmod($this->conffile, 0600);
|
||||
}
|
||||
else {
|
||||
StatusMessage("ERROR", "", _("Cannot open config file!") . " (" . $this->conffile . ")");
|
||||
throw new LAMException(_("Cannot open config file!") . " (" . $this->conffile . ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the main config has a password set.
|
||||
*
|
||||
* @return bool password is set
|
||||
*/
|
||||
public function hasPasswordSet(): bool {
|
||||
return ($this->password != null) && ($this->password !== '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new config password.
|
||||
*
|
||||
|
|
Binary file not shown.
|
@ -5,12 +5,13 @@
|
|||
# Julio C. Ortega, 2022-2024
|
||||
# Julio C. Ortega, 2015-2021
|
||||
# Leandro Lattanzio, 2023
|
||||
# Roland Gruber <post@rolandgruber.de>, 2025
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: LDAP Account Manager\n"
|
||||
"Report-Msgid-Bugs-To: post@rolandgruber.de\n"
|
||||
"PO-Revision-Date: 2011-09-29 18:53+0000\n"
|
||||
"Last-Translator: Julio C. Ortega, 2022-2024\n"
|
||||
"Last-Translator: Roland Gruber <post@rolandgruber.de>, 2025\n"
|
||||
"Language-Team: Spanish (Spain) (http://app.transifex.com/gruberroland/lam/language/es_ES/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
@ -8775,11 +8776,11 @@ msgstr "Móvil"
|
|||
#: ../lib/modules/inetOrgPerson.inc:3760 ../lib/modules/inetOrgPerson.inc:3802
|
||||
#: ../lib/modules/inetOrgPerson.inc:4147
|
||||
msgid "Mobile number"
|
||||
msgstr "Numero de ḿmóbil"
|
||||
msgstr "Número de móvil"
|
||||
|
||||
#: ../lib/modules/inetOrgPerson.inc:2751
|
||||
msgid "Mobile telephone number"
|
||||
msgstr "Número de teléfono movil"
|
||||
msgstr "Número de teléfono móvil"
|
||||
|
||||
#: ../lib/modules/qmailGroup.inc:183 ../lib/modules/qmailGroup.inc:187
|
||||
#: ../lib/modules/qmailGroup.inc:316 ../lib/modules/qmailGroup.inc:376
|
||||
|
@ -16357,7 +16358,7 @@ msgstr "Número de Fax del usuario."
|
|||
#: ../lib/modules/windowsLDSUser.inc:312 ../lib/modules/inetOrgPerson.inc:648
|
||||
#: ../lib/modules/inetOrgPerson.inc:652 ../lib/modules/windowsUser.inc:423
|
||||
msgid "The user's mobile number."
|
||||
msgstr "Numero de móvil del usuario."
|
||||
msgstr "Número de móvil del usuario."
|
||||
|
||||
#: ../lib/modules/windowsLDSUser.inc:284 ../lib/modules/windowsLDSUser.inc:288
|
||||
#: ../lib/modules/inetOrgPerson.inc:780 ../lib/modules/inetOrgPerson.inc:784
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<?php
|
||||
namespace LAM\CONFIG;
|
||||
|
||||
use \htmlStatusMessage;
|
||||
use \htmlResponsiveRow;
|
||||
use \LAMCfgMain;
|
||||
use \htmlButton;
|
||||
use \htmlOutputText;
|
||||
use \htmlLink;
|
||||
use \htmlDiv;
|
||||
use \htmlResponsiveSelect;
|
||||
use \htmlResponsiveInputField;
|
||||
use \htmlHorizontalLine;
|
||||
use htmlStatusMessage;
|
||||
use htmlResponsiveRow;
|
||||
use LAMCfgMain;
|
||||
use htmlButton;
|
||||
use htmlOutputText;
|
||||
use htmlLink;
|
||||
use htmlDiv;
|
||||
use htmlResponsiveSelect;
|
||||
use htmlResponsiveInputField;
|
||||
use htmlHorizontalLine;
|
||||
use LAMException;
|
||||
use ServerProfilePersistenceManager;
|
||||
|
||||
/*
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2023 Roland Gruber
|
||||
Copyright (C) 2003 - 2025 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
|
||||
|
@ -74,18 +74,29 @@ for ($i = 0; $i < count($sessionKeys); $i++) {
|
|||
echo $_SESSION['header'];
|
||||
|
||||
$serverProfilePersistenceManager = new ServerProfilePersistenceManager();
|
||||
$files = [];
|
||||
$profileNames = [];
|
||||
$profileNamesWithoutPassword = [];
|
||||
try {
|
||||
$files = $serverProfilePersistenceManager->getProfiles();
|
||||
$profileNames = $serverProfilePersistenceManager->getProfiles();
|
||||
foreach ($profileNames as $profileName) {
|
||||
$profile = $serverProfilePersistenceManager->loadProfile($profileName);
|
||||
if (!$profile->hasPasswordSet()) {
|
||||
$profileNamesWithoutPassword[] = $profileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (LAMException $e) {
|
||||
logNewMessage(LOG_ERR, 'Unable to read server profiles: ' . $e->getTitle());
|
||||
}
|
||||
printHeaderContents(_("Login"), '../..');
|
||||
|
||||
if (count($files) < 1) {
|
||||
if (count($profileNames) < 1) {
|
||||
$message = new htmlStatusMessage('INFO', _("No server profiles found. Please create one."));
|
||||
}
|
||||
if ($profileNamesWithoutPassword !== []) {
|
||||
$message = new htmlStatusMessage('INFO', _("There is at least one server profile without password. Please click on the manage server profiles link to set a password."),
|
||||
htmlspecialchars(implode(', ', $profileNamesWithoutPassword)));
|
||||
}
|
||||
?>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -128,36 +139,34 @@ printJsIncludes('../..');
|
|||
|
||||
// message
|
||||
if ($message !== null) {
|
||||
$row->add($message, 12);
|
||||
$row->add($message);
|
||||
$row->addVerticalSpacer('2rem');
|
||||
}
|
||||
|
||||
$box = new htmlResponsiveRow();
|
||||
if (count($files) > 0) {
|
||||
$box->add(new htmlOutputText(_("Please enter your password to change the server preferences:")), 12);
|
||||
if (count($profileNames) > 0) {
|
||||
$box->add(new htmlOutputText(_("Please enter your password to change the server preferences:")));
|
||||
$box->addVerticalSpacer('1.5rem');
|
||||
$conf = new LAMCfgMain();
|
||||
$selectedProfile = [];
|
||||
$profilesExisting = false;
|
||||
$profiles = $files;
|
||||
if (!empty($_COOKIE["lam_default_profile"]) && in_array($_COOKIE["lam_default_profile"], $files)) {
|
||||
if (!empty($_COOKIE["lam_default_profile"]) && in_array($_COOKIE["lam_default_profile"], $profileNames)) {
|
||||
$selectedProfile[] = $_COOKIE["lam_default_profile"];
|
||||
}
|
||||
else {
|
||||
$selectedProfile[] = $conf->default;
|
||||
}
|
||||
$box->add(new htmlResponsiveSelect('filename', $profiles, $selectedProfile, _('Profile name')), 12);
|
||||
$box->add(new htmlResponsiveSelect('filename', $profileNames, $selectedProfile, _('Profile name')));
|
||||
$passwordInput = new htmlResponsiveInputField(_('Password'), 'passwd', '', '200');
|
||||
$passwordInput->setIsPassword(true);
|
||||
$passwordInput->setCSSClasses(['lam-initial-focus']);
|
||||
$box->add($passwordInput, 12);
|
||||
$box->add($passwordInput);
|
||||
$box->addVerticalSpacer('1rem');
|
||||
$button = new htmlButton('submit', _("Ok"));
|
||||
$button->setCSSClasses(['lam-primary']);
|
||||
$box->addLabel($button);
|
||||
$box->add(new htmlOutputText(''), 0, 6);
|
||||
$box->addVerticalSpacer('1.5rem');
|
||||
$box->add(new htmlHorizontalLine(), 12);
|
||||
$box->add(new htmlHorizontalLine());
|
||||
$box->addVerticalSpacer('1.5rem');
|
||||
}
|
||||
$manageLink = new htmlLink(_("Manage server profiles"), 'profmanage.php');
|
||||
|
@ -165,7 +174,7 @@ printJsIncludes('../..');
|
|||
|
||||
$boxDiv = new htmlDiv(null, $box);
|
||||
$boxDiv->setCSSClasses(['roundedShadowBox', 'limitWidth', 'text-center']);
|
||||
$row->add($boxDiv, 12);
|
||||
$row->add($boxDiv);
|
||||
|
||||
// back link
|
||||
$row->addVerticalSpacer('2rem');
|
||||
|
|
|
@ -27,7 +27,7 @@ use ServerProfilePersistenceManager;
|
|||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2023 Roland Gruber
|
||||
Copyright (C) 2003 - 2025 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
|
||||
|
@ -842,10 +842,13 @@ function checkInput(): array {
|
|||
$conf->setTwoFactorRememberDevicePassword($_POST['twoFactorRememberDevicePassword']);
|
||||
}
|
||||
// check if password was changed
|
||||
if (isset($_POST['passwd1']) && ($_POST['passwd1'] != '')) {
|
||||
if ($_POST['passwd1'] != $_POST['passwd2']) {
|
||||
if (!empty($_POST['passwd1'])) {
|
||||
if ($_POST['passwd1'] !== $_POST['passwd2']) {
|
||||
$errors[] = ["ERROR", _("Passwords are different!")];
|
||||
}
|
||||
elseif (!isValidConfigurationPassword($_POST['passwd1'])) {
|
||||
$errors[] = ["ERROR", _('Profile password'), _('Please enter at least 8 characters including letters, a number and a symbol.')];
|
||||
}
|
||||
else {
|
||||
// set new password
|
||||
$conf->set_Passwd($_POST['passwd1']);
|
||||
|
|
|
@ -4,28 +4,28 @@ namespace LAM\CONFIG;
|
|||
use htmlJavaScript;
|
||||
use htmlResponsiveTable;
|
||||
use LAM\LOGIN\WEBAUTHN\WebauthnManager;
|
||||
use \LAMCfgMain;
|
||||
use \htmlTable;
|
||||
use \htmlTitle;
|
||||
use \htmlStatusMessage;
|
||||
use \htmlSubTitle;
|
||||
use \htmlSpacer;
|
||||
use \htmlOutputText;
|
||||
use \htmlLink;
|
||||
use \htmlGroup;
|
||||
use \htmlButton;
|
||||
use \htmlHelpLink;
|
||||
use \htmlInputField;
|
||||
use \htmlInputFileUpload;
|
||||
use \DateTime;
|
||||
use \DateTimeZone;
|
||||
use \htmlResponsiveRow;
|
||||
use \htmlResponsiveInputTextarea;
|
||||
use \htmlResponsiveSelect;
|
||||
use \htmlResponsiveInputCheckbox;
|
||||
use \htmlResponsiveInputField;
|
||||
use \htmlDiv;
|
||||
use \htmlHiddenInput;
|
||||
use LAMCfgMain;
|
||||
use htmlTable;
|
||||
use htmlTitle;
|
||||
use htmlStatusMessage;
|
||||
use htmlSubTitle;
|
||||
use htmlSpacer;
|
||||
use htmlOutputText;
|
||||
use htmlLink;
|
||||
use htmlGroup;
|
||||
use htmlButton;
|
||||
use htmlHelpLink;
|
||||
use htmlInputField;
|
||||
use htmlInputFileUpload;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use htmlResponsiveRow;
|
||||
use htmlResponsiveInputTextarea;
|
||||
use htmlResponsiveSelect;
|
||||
use htmlResponsiveInputCheckbox;
|
||||
use htmlResponsiveInputField;
|
||||
use htmlDiv;
|
||||
use htmlHiddenInput;
|
||||
use LAMException;
|
||||
use LamTemporaryFilesManager;
|
||||
use PDO;
|
||||
|
@ -33,7 +33,7 @@ use PDO;
|
|||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2024 Roland Gruber
|
||||
Copyright (C) 2003 - 2025 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
|
||||
|
@ -114,7 +114,8 @@ printHeaderContents(_("Edit general settings"), '../..');
|
|||
<?php
|
||||
if (is_dir(__DIR__ . '/../../docs/manual')) {
|
||||
?>
|
||||
<a class="lam-header-right lam-menu-icon hide-on-tablet" href="javascript:void(0);" class="icon" onclick="window.lam.topmenu.toggle();">
|
||||
<a class="lam-header-right lam-menu-icon hide-on-tablet" href="javascript:void(0);" class="icon"
|
||||
onclick="window.lam.topmenu.toggle();">
|
||||
<img class="align-middle" width="16" height="16" alt="menu" src="../../graphics/menu.svg">
|
||||
<span class="padding0"> </span>
|
||||
</a>
|
||||
|
@ -158,13 +159,17 @@ if (isset($_POST['submitFormData'])) {
|
|||
}
|
||||
}
|
||||
// set master password
|
||||
if (isset($_POST['masterpassword']) && ($_POST['masterpassword'] != "")) {
|
||||
if ($_POST['masterpassword'] && $_POST['masterpassword2'] && ($_POST['masterpassword'] == $_POST['masterpassword2'])) {
|
||||
if (!empty($_POST['masterpassword'])) {
|
||||
if (($_POST['masterpassword'] !== $_POST['masterpassword2'])) {
|
||||
$errors[] = _("Master passwords are different.");
|
||||
}
|
||||
elseif (!isValidConfigurationPassword($_POST['masterpassword'])) {
|
||||
$errors[] = _('Please enter at least 8 characters including letters, a number and a symbol.');
|
||||
}
|
||||
else {
|
||||
$cfg->setPassword($_POST['masterpassword']);
|
||||
$msg = _("New master password set successfully.");
|
||||
unset($_SESSION["mainconf_password"]);
|
||||
} else {
|
||||
$errors[] = _("Master passwords are different or empty!");
|
||||
}
|
||||
}
|
||||
// set license
|
||||
|
@ -213,11 +218,12 @@ if (isset($_POST['submitFormData'])) {
|
|||
}
|
||||
}
|
||||
$allowedHosts = implode(",", $allowedHostsList);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$allowedHosts = "";
|
||||
}
|
||||
$cfg->allowedHosts = $allowedHosts;
|
||||
// set allowed hosts for self service
|
||||
// set allowed hosts for self-service
|
||||
if (isLAMProVersion()) {
|
||||
if (isset($_POST['allowedHostsSelfService'])) {
|
||||
$allowedHostsSelfService = $_POST['allowedHostsSelfService'];
|
||||
|
@ -237,7 +243,8 @@ if (isset($_POST['submitFormData'])) {
|
|||
}
|
||||
$allowedHostsSelfServiceList = array_unique($allowedHostsSelfServiceList);
|
||||
$allowedHostsSelfService = implode(",", $allowedHostsSelfServiceList);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$allowedHostsSelfService = "";
|
||||
}
|
||||
$cfg->allowedHostsSelfService = $allowedHostsSelfService;
|
||||
|
@ -247,15 +254,18 @@ if (isset($_POST['submitFormData'])) {
|
|||
// set log destination
|
||||
if ($_POST['logDestination'] == "none") {
|
||||
$cfg->logDestination = "NONE";
|
||||
} elseif ($_POST['logDestination'] == "syslog") {
|
||||
}
|
||||
elseif ($_POST['logDestination'] == "syslog") {
|
||||
$cfg->logDestination = "SYSLOG";
|
||||
} elseif ($_POST['logDestination'] == "remote") {
|
||||
}
|
||||
elseif ($_POST['logDestination'] == "remote") {
|
||||
$cfg->logDestination = "REMOTE:" . $_POST['logRemote'];
|
||||
$remoteParts = explode(':', $_POST['logRemote']);
|
||||
if ((count($remoteParts) !== 2) || !get_preg($remoteParts[0], 'DNSname') || !get_preg($remoteParts[1], 'digit')) {
|
||||
$errors[] = _("Please enter a valid remote server in format \"server:port\".");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$isValidLogFile = isset($_POST['logFile']) && LAMCfgMain::isValidLogFilename($_POST['logFile']);
|
||||
$blockedPrefixes = ['/usr', '/etc', '/dev', '/boot', '/lib', '/proc', '/root', '/run', '/sys', '/snap'];
|
||||
if (!empty($_SERVER['DOCUMENT_ROOT'])) {
|
||||
|
@ -327,7 +337,7 @@ if (isset($_POST['submitFormData'])) {
|
|||
$matches = [];
|
||||
if (preg_match('/^ldaps:\/\/([a-zA-Z0-9_.-]+)(:(\d+))?$/', $_POST['serverurl'], $matches)) {
|
||||
$port = '636';
|
||||
if (isset($matches[3]) && !empty($matches[3])) {
|
||||
if (!empty($matches[3])) {
|
||||
$port = $matches[3];
|
||||
}
|
||||
$pemResult = getLDAPSSLCertificate($matches[1], $port);
|
||||
|
@ -335,10 +345,12 @@ if (isset($_POST['submitFormData'])) {
|
|||
$messages[] = _('Imported certificate from server.');
|
||||
$messages[] = _('You might need to restart your webserver for changes to take effect.');
|
||||
$cfg->uploadSSLCaCert($pemResult);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$errors[] = _('Unable to import server certificate. Please use the upload function.');
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$errors[] = _('Invalid server name. Please enter "server" or "server:port".');
|
||||
}
|
||||
}
|
||||
|
@ -387,14 +399,17 @@ if (isset($_POST['submitFormData'])) {
|
|||
}
|
||||
$cfg->setModuleSettings($moduleSettings);
|
||||
// save settings
|
||||
if (isset($_POST['submit'])) {
|
||||
if (isset($_POST['submit']) && empty($errors)) {
|
||||
try {
|
||||
$cfg->save();
|
||||
if (empty($errors)) {
|
||||
$scriptTag = new htmlJavaScript('window.lam.dialog.showSuccessMessageAndRedirect("' . _("Your settings were successfully saved.") . '", "", "' . _('Ok') . '", "../login.php")');
|
||||
parseHtml(null, $scriptTag, [], false, null);
|
||||
echo '</body></html>';
|
||||
exit();
|
||||
}
|
||||
catch (LAMException $e) {
|
||||
$errors[] = $e->getTitle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,12 +430,12 @@ if (isset($_POST['submitFormData'])) {
|
|||
|
||||
// check if config file is writable
|
||||
if (!$cfg->isWritable()) {
|
||||
$row->add(new htmlStatusMessage('WARN', _('The config file is not writable.'), _('Your changes cannot be saved until you make the file writable for the webserver user.')), 12);
|
||||
$row->add(new htmlStatusMessage('WARN', _('The config file is not writable.'), _('Your changes cannot be saved until you make the file writable for the webserver user.')));
|
||||
}
|
||||
|
||||
// database
|
||||
if (extension_loaded('PDO')) {
|
||||
$row->add(new htmlSubTitle(_('Configuration storage')), 12);
|
||||
$row->add(new htmlSubTitle(_('Configuration storage')));
|
||||
$storageProviders = [
|
||||
_('Local file system') => LAMCfgMain::DATABASE_FILE_SYSTEM
|
||||
];
|
||||
|
@ -439,28 +454,28 @@ if (isset($_POST['submitFormData'])) {
|
|||
LAMCfgMain::DATABASE_MYSQL => []
|
||||
];
|
||||
$storageProviderSelect->setTableRowsToHide($dbRowsToHide);
|
||||
$row->add($storageProviderSelect, 12);
|
||||
$row->add($storageProviderSelect);
|
||||
$dbHost = new htmlResponsiveInputField(_('Database host'), 'configDatabaseServer', $cfg->configDatabaseServer, '273');
|
||||
$dbHost->setRequired(true);
|
||||
$row->add($dbHost, 12);
|
||||
$row->add($dbHost);
|
||||
$dbPort = new htmlResponsiveInputField(_('Database port'), 'configDatabasePort', $cfg->configDatabasePort, '274');
|
||||
$row->add($dbPort, 12);
|
||||
$row->add($dbPort);
|
||||
$dbName = new htmlResponsiveInputField(_('Database name'), 'configDatabaseName', $cfg->configDatabaseName, '276');
|
||||
$dbName->setRequired(true);
|
||||
$row->add($dbName, 12);
|
||||
$row->add($dbName);
|
||||
$dbUser = new htmlResponsiveInputField(_('Database user'), 'configDatabaseUser', $cfg->configDatabaseUser, '275');
|
||||
$dbUser->setRequired(true);
|
||||
$row->add($dbUser, 12);
|
||||
$row->add($dbUser);
|
||||
$dbPassword = new htmlResponsiveInputField(_('Database password'), 'configDatabasePassword', deobfuscateText($cfg->configDatabasePassword), '275');
|
||||
$dbPassword->setRequired(true);
|
||||
$dbPassword->setIsPassword(true);
|
||||
$row->add($dbPassword, 12);
|
||||
$row->add($dbPassword);
|
||||
}
|
||||
|
||||
// license
|
||||
if (isLAMProVersion()) {
|
||||
$row->add(new htmlSubTitle(_('Licence')), 12);
|
||||
$row->add(new htmlResponsiveInputTextarea('license', implode("\n", $cfg->getLicenseLines()), '30', '10', _('Licence'), '287'), 12);
|
||||
$row->add(new htmlSubTitle(_('Licence')));
|
||||
$row->add(new htmlResponsiveInputTextarea('license', implode("\n", $cfg->getLicenseLines()), '30', '10', _('Licence'), '287'));
|
||||
$warningOptions = [
|
||||
_('Screen') => LAMCfgMain::LICENSE_WARNING_SCREEN,
|
||||
_('Email') => LAMCfgMain::LICENSE_WARNING_EMAIL,
|
||||
|
@ -478,19 +493,19 @@ if (isset($_POST['submitFormData'])) {
|
|||
LAMCfgMain::LICENSE_WARNING_EMAIL => ['licenseEmailFrom', 'licenseEmailTo'],
|
||||
LAMCfgMain::LICENSE_WARNING_ALL => ['licenseEmailFrom', 'licenseEmailTo']
|
||||
]);
|
||||
$row->add($warningTypeSelect, 12);
|
||||
$row->add($warningTypeSelect);
|
||||
$licenseFrom = new htmlResponsiveInputField(_('From address'), 'licenseEmailFrom', $cfg->licenseEmailFrom, '289');
|
||||
$licenseFrom->setRequired(true);
|
||||
$row->add($licenseFrom, 12);
|
||||
$row->add($licenseFrom);
|
||||
$licenseTo = new htmlResponsiveInputField(_('To address'), 'licenseEmailTo', $cfg->licenseEmailTo, '290');
|
||||
$licenseTo->setRequired(true);
|
||||
$row->add($licenseTo, 12);
|
||||
$row->add($licenseTo);
|
||||
|
||||
$row->add(new htmlSpacer(null, '1rem'), true);
|
||||
}
|
||||
|
||||
// security settings
|
||||
$row->add(new htmlSubTitle(_("Security settings")), 12);
|
||||
$row->add(new htmlSubTitle(_("Security settings")));
|
||||
$options = [5, 10, 20, 30, 60, 90, 120, 240];
|
||||
$row->add(new htmlResponsiveSelect('sessionTimeout', $options, [$cfg->sessionTimeout], _("Session timeout"), '238'));
|
||||
$hideLoginErrorDetails = ($cfg->hideLoginErrorDetails === 'true');
|
||||
|
@ -561,39 +576,39 @@ if (isset($_POST['submitFormData'])) {
|
|||
}
|
||||
$certsTable = new htmlResponsiveTable($certsTitles, $certsData);
|
||||
$certsTable->setCSSClasses(['text-left']);
|
||||
$row->add($certsTable, 12);
|
||||
$row->add($certsTable);
|
||||
}
|
||||
|
||||
// password policy
|
||||
$row->add(new htmlSubTitle(_("Password policy")), 12);
|
||||
$row->add(new htmlSubTitle(_("Password policy")));
|
||||
$optionsPwdLength = [];
|
||||
for ($i = 0; $i <= 50; $i++) {
|
||||
$optionsPwdLength[] = $i;
|
||||
}
|
||||
$options4 = [0, 1, 2, 3, 4];
|
||||
$row->add(new htmlResponsiveSelect('passwordMinLength', $optionsPwdLength, [$cfg->passwordMinLength], _('Minimum password length'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinLength', $optionsPwdLength, [$cfg->passwordMinLength], _('Minimum password length'), '242'));
|
||||
$row->addVerticalSpacer('1rem');
|
||||
$row->add(new htmlResponsiveSelect('passwordMinLower', $optionsPwdLength, [$cfg->passwordMinLower], _('Minimum lowercase characters'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinUpper', $optionsPwdLength, [$cfg->passwordMinUpper], _('Minimum uppercase characters'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinNumeric', $optionsPwdLength, [$cfg->passwordMinNumeric], _('Minimum numeric characters'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinSymbol', $optionsPwdLength, [$cfg->passwordMinSymbol], _('Minimum symbolic characters'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinClasses', $options4, [$cfg->passwordMinClasses], _('Minimum character classes'), '242'), 12);
|
||||
$row->add(new htmlResponsiveSelect('passwordMinLower', $optionsPwdLength, [$cfg->passwordMinLower], _('Minimum lowercase characters'), '242'));
|
||||
$row->add(new htmlResponsiveSelect('passwordMinUpper', $optionsPwdLength, [$cfg->passwordMinUpper], _('Minimum uppercase characters'), '242'));
|
||||
$row->add(new htmlResponsiveSelect('passwordMinNumeric', $optionsPwdLength, [$cfg->passwordMinNumeric], _('Minimum numeric characters'), '242'));
|
||||
$row->add(new htmlResponsiveSelect('passwordMinSymbol', $optionsPwdLength, [$cfg->passwordMinSymbol], _('Minimum symbolic characters'), '242'));
|
||||
$row->add(new htmlResponsiveSelect('passwordMinClasses', $options4, [$cfg->passwordMinClasses], _('Minimum character classes'), '242'));
|
||||
$row->addVerticalSpacer('1rem');
|
||||
$rulesCountOptions = [_('all') => '-1', '3' => '3', '4' => '4'];
|
||||
$rulesCountSelect = new htmlResponsiveSelect('passwordRulesCount', $rulesCountOptions, [$cfg->checkedRulesCount], _('Number of rules that must match'), '246');
|
||||
$rulesCountSelect->setHasDescriptiveElements(true);
|
||||
$row->add($rulesCountSelect, 12);
|
||||
$row->add($rulesCountSelect);
|
||||
$passwordMustNotContainUser = ($cfg->passwordMustNotContainUser === 'true');
|
||||
$row->add(new htmlResponsiveInputCheckbox('passwordMustNotContainUser', $passwordMustNotContainUser, _('Password must not contain user name'), '247'), 12);
|
||||
$row->add(new htmlResponsiveInputCheckbox('passwordMustNotContainUser', $passwordMustNotContainUser, _('Password must not contain user name'), '247'));
|
||||
$passwordMustNotContain3Chars = ($cfg->passwordMustNotContain3Chars === 'true');
|
||||
$row->add(new htmlResponsiveInputCheckbox('passwordMustNotContain3Chars', $passwordMustNotContain3Chars, _('Password must not contain part of user/first/last name'), '248'), 12);
|
||||
$row->add(new htmlResponsiveInputCheckbox('passwordMustNotContain3Chars', $passwordMustNotContain3Chars, _('Password must not contain part of user/first/last name'), '248'));
|
||||
if (function_exists('curl_init')) {
|
||||
$row->addVerticalSpacer('1rem');
|
||||
$row->add(new htmlResponsiveInputField(_('External password check'), 'externalPwdCheckUrl', $cfg->externalPwdCheckUrl, '249'), 12);
|
||||
$row->add(new htmlResponsiveInputField(_('External password check'), 'externalPwdCheckUrl', $cfg->externalPwdCheckUrl, '249'));
|
||||
}
|
||||
|
||||
// logging
|
||||
$row->add(new htmlSubTitle(_("Logging")), 12);
|
||||
$row->add(new htmlSubTitle(_("Logging")));
|
||||
$levelOptions = [
|
||||
_("Debug") => LOG_DEBUG,
|
||||
_("Notice") => LOG_NOTICE,
|
||||
|
@ -602,7 +617,7 @@ if (isset($_POST['submitFormData'])) {
|
|||
];
|
||||
$levelSelect = new htmlResponsiveSelect('logLevel', $levelOptions, [$cfg->logLevel], _("Log level"), '239');
|
||||
$levelSelect->setHasDescriptiveElements(true);
|
||||
$row->add($levelSelect, 12);
|
||||
$row->add($levelSelect);
|
||||
$destinationOptions = [
|
||||
_("No logging") => "none",
|
||||
_("System logging") => "syslog",
|
||||
|
@ -615,10 +630,12 @@ if (isset($_POST['submitFormData'])) {
|
|||
if ($cfg->logDestination == 'NONE') {
|
||||
$destinationSelected = 'none';
|
||||
$destinationPath = '';
|
||||
} elseif ($cfg->logDestination == 'SYSLOG') {
|
||||
}
|
||||
elseif ($cfg->logDestination == 'SYSLOG') {
|
||||
$destinationSelected = 'syslog';
|
||||
$destinationPath = '';
|
||||
} elseif (str_starts_with($cfg->logDestination, 'REMOTE')) {
|
||||
}
|
||||
elseif (str_starts_with($cfg->logDestination, 'REMOTE')) {
|
||||
$destinationSelected = 'remote';
|
||||
$remoteParts = explode(':', $cfg->logDestination, 2);
|
||||
$destinationRemote = empty($remoteParts[1]) ? '' : $remoteParts[1];
|
||||
|
@ -636,9 +653,9 @@ if (isset($_POST['submitFormData'])) {
|
|||
'remote' => ['logRemote']
|
||||
]);
|
||||
$logDestinationSelect->setHasDescriptiveElements(true);
|
||||
$row->add($logDestinationSelect, 12);
|
||||
$row->add(new htmlResponsiveInputField(_('File'), 'logFile', $destinationPath), 12);
|
||||
$row->add(new htmlResponsiveInputField(_('Remote server'), 'logRemote', $destinationRemote, '251'), 12);
|
||||
$row->add($logDestinationSelect);
|
||||
$row->add(new htmlResponsiveInputField(_('File'), 'logFile', $destinationPath));
|
||||
$row->add(new htmlResponsiveInputField(_('Remote server'), 'logRemote', $destinationRemote, '251'));
|
||||
$errorLogOptions = [
|
||||
_('PHP system setting') => LAMCfgMain::ERROR_REPORTING_SYSTEM,
|
||||
_('default') => LAMCfgMain::ERROR_REPORTING_DEFAULT,
|
||||
|
@ -650,7 +667,7 @@ if (isset($_POST['submitFormData'])) {
|
|||
|
||||
// mail options
|
||||
if (isLAMProVersion()) {
|
||||
$row->add(new htmlSubTitle(_('Mail options')), 12);
|
||||
$row->add(new htmlSubTitle(_('Mail options')));
|
||||
$mailServer = new htmlResponsiveInputField(_("Mail server"), 'mailServer', $cfg->mailServer, '253');
|
||||
$row->add($mailServer);
|
||||
$mailUser = new htmlResponsiveInputField(_("User name"), 'mailUser', $cfg->mailUser, '254');
|
||||
|
@ -688,7 +705,7 @@ if (isset($_POST['submitFormData'])) {
|
|||
|
||||
// webauthn management
|
||||
if (extension_loaded('PDO')
|
||||
&& in_array('sqlite', \PDO::getAvailableDrivers())) {
|
||||
&& in_array('sqlite', PDO::getAvailableDrivers())) {
|
||||
include_once __DIR__ . '/../../lib/webauthn.inc';
|
||||
$webAuthnManager = new WebauthnManager();
|
||||
try {
|
||||
|
@ -696,7 +713,7 @@ if (isset($_POST['submitFormData'])) {
|
|||
if ($database->hasRegisteredCredentials()) {
|
||||
$row->add(new htmlSubTitle(_('WebAuthn devices')));
|
||||
$webauthnSearchField = new htmlResponsiveInputField(_('User DN'), 'webauthn_searchTerm', null, '252');
|
||||
$row->add($webauthnSearchField, 12);
|
||||
$row->add($webauthnSearchField);
|
||||
$row->addVerticalSpacer('0.5rem');
|
||||
$row->add(new htmlButton('webauthn_search', _('Search')), 12, 12, 12, 'text-center');
|
||||
$resultDiv = new htmlDiv('webauthn_results', new htmlOutputText(''), ['lam-webauthn-results', 'text-left']);
|
||||
|
@ -745,11 +762,11 @@ if (isset($_POST['submitFormData'])) {
|
|||
$row->add(new htmlSubTitle(_("Change master password")));
|
||||
$pwd1 = new htmlResponsiveInputField(_("New master password"), 'masterpassword', '', '235');
|
||||
$pwd1->setIsPassword(true, false, true);
|
||||
$row->add($pwd1, 12);
|
||||
$row->add($pwd1);
|
||||
$pwd2 = new htmlResponsiveInputField(_("Reenter password"), 'masterpassword2', '');
|
||||
$pwd2->setIsPassword(true, false, true);
|
||||
$pwd2->setSameValueFieldID('masterpassword');
|
||||
$row->add($pwd2, 12);
|
||||
$row->add($pwd2);
|
||||
$row->addVerticalSpacer('3rem');
|
||||
|
||||
// buttons
|
||||
|
@ -760,8 +777,8 @@ if (isset($_POST['submitFormData'])) {
|
|||
$buttonTable->addElement($saveButton);
|
||||
$buttonTable->addElement(new htmlSpacer('0.5rem', null));
|
||||
$buttonTable->addElement(new htmlButton('cancel', _("Cancel")));
|
||||
$row->add($buttonTable, 12);
|
||||
$row->add(new htmlHiddenInput('submitFormData', '1'), 12);
|
||||
$row->add($buttonTable);
|
||||
$row->add(new htmlHiddenInput('submitFormData', '1'));
|
||||
}
|
||||
|
||||
$box = new htmlDiv(null, $row);
|
||||
|
|
|
@ -19,7 +19,7 @@ use ServerProfilePersistenceManager;
|
|||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2024 Roland Gruber
|
||||
Copyright (C) 2003 - 2025 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
|
||||
|
@ -155,10 +155,15 @@ if (isset($_POST['action'])) {
|
|||
if (preg_match("/^[a-z0-9_-]+$/i", (string) $_POST['defaultfilename'])) {
|
||||
$configMain = new LAMCfgMain();
|
||||
$configMain->default = $_POST['defaultfilename'];
|
||||
try {
|
||||
$configMain->save();
|
||||
$configMain = null;
|
||||
$msg = _("New default profile set successfully.");
|
||||
}
|
||||
catch (LAMException $e) {
|
||||
$error = $e->getTitle();
|
||||
}
|
||||
}
|
||||
else {
|
||||
$error = _("Profile name is invalid!");
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use ServerProfilePersistenceManager;
|
|||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2003 - 2006 Michael Duergner
|
||||
2005 - 2024 Roland Gruber
|
||||
2005 - 2025 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
|
||||
|
@ -60,10 +60,19 @@ include __DIR__ . '/../lib/checkEnvironment.inc';
|
|||
|
||||
/** security functions */
|
||||
include_once(__DIR__ . "/../lib/security.inc");
|
||||
/** self service functions */
|
||||
/** self-service functions */
|
||||
include_once(__DIR__ . "/../lib/selfService.inc");
|
||||
/** access to configuration options */
|
||||
include_once(__DIR__ . "/../lib/config.inc");
|
||||
|
||||
$cfgMain = new LAMCfgMain();
|
||||
|
||||
// check if main config password is set
|
||||
if (!$cfgMain->hasPasswordSet()) {
|
||||
metaRefresh('setInitialPassword.php');
|
||||
die();
|
||||
}
|
||||
|
||||
$licenseValidator = null;
|
||||
if (isLAMProVersion()) {
|
||||
include_once(__DIR__ . "/../lib/env.inc");
|
||||
|
@ -110,12 +119,10 @@ if (isset($_POST['language'])) {
|
|||
setcookie('lam_last_language', htmlspecialchars((string) $_POST['language']), $cookieOptions);
|
||||
}
|
||||
|
||||
// init some session variables
|
||||
$default_Config = new LAMCfgMain();
|
||||
$_SESSION["cfgMain"] = $default_Config;
|
||||
$_SESSION["cfgMain"] = $cfgMain;
|
||||
setSSLCaCert();
|
||||
|
||||
$default_Profile = $default_Config->default;
|
||||
$default_Profile = $cfgMain->default;
|
||||
if (isset($_COOKIE["lam_default_profile"]) && in_array($_COOKIE["lam_default_profile"], $profiles)) {
|
||||
$default_Profile = $_COOKIE["lam_default_profile"];
|
||||
}
|
||||
|
@ -142,7 +149,7 @@ catch (LAMException $e) {
|
|||
$error_message = $e->getTitle();
|
||||
}
|
||||
|
||||
if (!isset($default_Config->default) || !in_array($default_Config->default, $profiles)) {
|
||||
if (!isset($cfgMain->default) || !in_array($cfgMain->default, $profiles)) {
|
||||
$error_message = _('No default profile set. Please set it in the server profile configuration.');
|
||||
}
|
||||
|
||||
|
@ -549,7 +556,7 @@ if (isset($_POST['checklogin'])) {
|
|||
cleanLDAPResult($searchInfo);
|
||||
if (empty($searchInfo)) {
|
||||
$searchSuccess = false;
|
||||
if ($default_Config->isHideLoginErrorDetails()) {
|
||||
if ($cfgMain->isHideLoginErrorDetails()) {
|
||||
$searchError = _('Wrong password/user name combination. Please try again.');
|
||||
}
|
||||
else {
|
||||
|
@ -560,7 +567,7 @@ if (isset($_POST['checklogin'])) {
|
|||
}
|
||||
elseif (count($searchInfo) > 1) {
|
||||
$searchSuccess = false;
|
||||
if ($default_Config->isHideLoginErrorDetails()) {
|
||||
if ($cfgMain->isHideLoginErrorDetails()) {
|
||||
$searchError = _('Wrong password/user name combination. Please try again.');
|
||||
}
|
||||
else {
|
||||
|
@ -575,7 +582,7 @@ if (isset($_POST['checklogin'])) {
|
|||
}
|
||||
else {
|
||||
$searchSuccess = false;
|
||||
if ($default_Config->isHideLoginErrorDetails()) {
|
||||
if ($cfgMain->isHideLoginErrorDetails()) {
|
||||
$searchError = _('Wrong password/user name combination. Please try again.');
|
||||
}
|
||||
else {
|
||||
|
@ -590,7 +597,7 @@ if (isset($_POST['checklogin'])) {
|
|||
}
|
||||
else {
|
||||
$searchSuccess = false;
|
||||
if ($default_Config->isHideLoginErrorDetails()) {
|
||||
if ($cfgMain->isHideLoginErrorDetails()) {
|
||||
$searchError = _('Wrong password/user name combination. Please try again.');
|
||||
}
|
||||
else {
|
||||
|
@ -641,13 +648,13 @@ if (isset($_POST['checklogin'])) {
|
|||
header("HTTP/1.1 403 Forbidden");
|
||||
$extraMessage = null;
|
||||
if (($searchLDAP !== null) && ($e->getLdapErrorCode() == 49)) {
|
||||
if (!$default_Config->isHideLoginErrorDetails()) {
|
||||
if (!$cfgMain->isHideLoginErrorDetails()) {
|
||||
$extraMessage = getExtraInvalidCredentialsMessage($searchLDAP->server(), $username);
|
||||
}
|
||||
$searchLDAP->close();
|
||||
}
|
||||
$message = $e->getMessage();
|
||||
if ($default_Config->isHideLoginErrorDetails()) {
|
||||
if ($cfgMain->isHideLoginErrorDetails()) {
|
||||
$message = null;
|
||||
}
|
||||
display_LoginPage($licenseValidator, $e->getTitle(), $message, $extraMessage);
|
||||
|
|
162
lam/templates/setInitialPassword.php
Normal file
162
lam/templates/setInitialPassword.php
Normal file
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
namespace LAM\INIT;
|
||||
|
||||
use htmlButton;
|
||||
use htmlJavaScript;
|
||||
use htmlOutputText;
|
||||
use htmlResponsiveInputField;
|
||||
use htmlResponsiveRow;
|
||||
use htmlStatusMessage;
|
||||
use htmlTitle;
|
||||
use LAMCfgMain;
|
||||
use LAMException;
|
||||
|
||||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2025 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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Password dialog for initial configuration.
|
||||
*
|
||||
* @author Roland Gruber
|
||||
* @package main
|
||||
*/
|
||||
|
||||
/** security functions */
|
||||
include_once(__DIR__ . "/../lib/security.inc");
|
||||
/** access to configuration settings */
|
||||
include_once(__DIR__ . "/../lib/config.inc");
|
||||
/** status messages */
|
||||
include_once(__DIR__ . "/../lib/status.inc");
|
||||
|
||||
// set session save path
|
||||
if (isFileBasedSession()) {
|
||||
session_save_path(__DIR__ . '/../sess');
|
||||
}
|
||||
|
||||
lam_start_session();
|
||||
|
||||
$cfgMain = new LAMCfgMain();
|
||||
if ($cfgMain->hasPasswordSet()) {
|
||||
logNewMessage(LOG_ERR, 'Invalid attempt to set initial config password');
|
||||
die();
|
||||
}
|
||||
|
||||
setlanguage();
|
||||
|
||||
if (!empty($_POST)) {
|
||||
validateSecurityToken();
|
||||
}
|
||||
|
||||
$message = null;
|
||||
|
||||
// check if user already pressed button
|
||||
if (isset($_POST['changePassword'])) {
|
||||
// check new password
|
||||
$password1 = $_POST['password1'];
|
||||
$password2 = $_POST['password2'];
|
||||
if ($password1 == '') {
|
||||
$message = new htmlStatusMessage('ERROR', _('No password was entered!'));
|
||||
printContent($message);
|
||||
exit();
|
||||
}
|
||||
// check if passwords match
|
||||
if ($password1 != $password2) {
|
||||
$message = new htmlStatusMessage('ERROR', _('Passwords are different!'));
|
||||
printContent($message);
|
||||
exit();
|
||||
}
|
||||
// check password strength
|
||||
$pwdPolicyResult = isValidConfigurationPassword($password1);
|
||||
if (!$pwdPolicyResult) {
|
||||
$message = new htmlStatusMessage('ERROR', _('Please enter at least 8 characters including letters, a number and a symbol.'));
|
||||
printContent($message);
|
||||
exit();
|
||||
}
|
||||
// set new password
|
||||
$cfgMain->setPassword($password1);
|
||||
try {
|
||||
$cfgMain->save();
|
||||
metaRefresh('config/mainlogin.php');
|
||||
exit();
|
||||
}
|
||||
catch (LAMException $e) {
|
||||
$message = new htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
printContent($message);
|
||||
|
||||
/**
|
||||
* Displays the content area
|
||||
*
|
||||
* @param htmlStatusMessage|null $message status message
|
||||
* @param bool $showPasswordInputs show password input fields
|
||||
*/
|
||||
function printContent(htmlStatusMessage $message = null, bool $showPasswordInputs = true): void {
|
||||
echo '
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta http-equiv="pragma" content="no-cache">
|
||||
<meta http-equiv="cache-control" content="no-cache">
|
||||
';
|
||||
printHeaderContents('LDAP Account Manager', '..');
|
||||
echo '</head>
|
||||
<body>';
|
||||
printJsIncludes('..');
|
||||
|
||||
echo '<div class="smallPaddingContent">';
|
||||
echo "<form action=\"setInitialPassword.php\" method=\"post\">\n";
|
||||
addSecurityTokenToSession();
|
||||
$container = new htmlResponsiveRow();
|
||||
if ($message !== null) {
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$container->add($message);
|
||||
}
|
||||
$container->addVerticalSpacer('2rem');
|
||||
if ($showPasswordInputs) {
|
||||
$container->add(new htmlTitle(_('Initial configuration')));
|
||||
$container->addVerticalSpacer('3rem');
|
||||
$container->add(new htmlOutputText(_("Please enter your new LAM main configuration password.")), 12, 12, 12, 'text-center');
|
||||
$container->addVerticalSpacer('2rem');
|
||||
$pwdInput1 = new htmlResponsiveInputField(_('New password'), 'password1', '');
|
||||
$pwdInput1->setIsPassword(true, true, true);
|
||||
$container->add($pwdInput1);
|
||||
$pwdInput2 = new htmlResponsiveInputField(_('Repeat password'), 'password2', '');
|
||||
$pwdInput2->setIsPassword(true);
|
||||
$pwdInput2->setSameValueFieldID('password1');
|
||||
$container->add($pwdInput2);
|
||||
$container->addVerticalSpacer('1rem');
|
||||
$container->add(new htmlButton('changePassword', _("Submit")), 12, 12, 12, 'text-center');
|
||||
addSecurityTokenToMetaHTML($container);
|
||||
$container->add(new htmlJavaScript('checkFieldsHaveSameValues("password1", "password2");'));
|
||||
}
|
||||
|
||||
parseHtml(null, $container, [], false, 'user');
|
||||
|
||||
echo '</form><br>
|
||||
</div>
|
||||
<br><br>
|
||||
</body>
|
||||
</html>';
|
||||
}
|
|
@ -3,7 +3,7 @@ use PHPUnit\Framework\TestCase;
|
|||
/*
|
||||
|
||||
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
|
||||
Copyright (C) 2020 - 2023 Roland Gruber
|
||||
Copyright (C) 2020 - 2025 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
|
||||
|
@ -56,6 +56,7 @@ class LAMCfgMainTest extends TestCase {
|
|||
|
||||
/**
|
||||
* Mail related settings
|
||||
* @throws LAMException error saving config
|
||||
*/
|
||||
public function testMail() {
|
||||
$this->assertEquals(LAMCfgMain::MAIL_ATTRIBUTE_DEFAULT, $this->conf->getMailAttribute());
|
||||
|
@ -81,6 +82,7 @@ class LAMCfgMainTest extends TestCase {
|
|||
|
||||
/**
|
||||
* License related settings.
|
||||
* @throws LAMException error saving config
|
||||
*/
|
||||
public function testLicense() {
|
||||
$timestamp = '12345';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue