Horde Passwortänderungen: Passwd
Als erste Applikation installieren wir uns die Anwendung Passwd. Diese Anwendung werden wir neben dem eigentlichen Einsatz, dem Verwalten unserer eMails, dazu nutzen, uns beim Horde-Framework anzumelden (Authentifizierung und Authorisierung). Informationen zu Installation und Konfiguration findet man auch auf der offiziellen Doku-Seite.
Installation
Wie auch schon bei der Grund-Installation des Horde-Frameworks, werden wir hier auf PHP Extension and Application Repository oder kurz PEAR zurück.
Das Programmpaket holen wir und nun erst einmal auf unseren Web-Server.
# pear install -a -B horde/passwd
horde/passwd can optionally use PHP extension "com"
downloading passwd-5.0.0.tgz ...
Starting to download passwd-5.0.0.tgz (1,116,754 bytes)
.........................done: 1,116,754 bytes
install ok: channel://pear.horde.org/passwd-5.0.0
vorbereitende Konfiguration
Die Konfiguration des Moduls Passwd erfolgt, wie auch bereits bei der Grundkonfiguration des Horde-Frameworks, erfolgt über die GUI des Horde-Framworks. Bevor wir uns daran machen können, benötigen wir noch eine entsprechende (leere) Backupdatei für die mitgelieferte Vorgabekonfigurationsdatei. Ferner müssen wir dafür sorgen, dass unser Apache-Webserver die Änderungen im Konfigurationsverzeichnis ablegen kann. Zunächst kopieren wir uns die Vorlagedateien, die bei der Hordeinstallation mit kamen.
# cp -a /var/www/horde/passwd/config/backends.php /var/www/horde/passwd/config/backends.local.php
Anschließend legen wir noch die besagte Backup-Datei für die Konfiguration an.
# touch /var/www/horde/passwd/config/conf.php.bak
Zum Schluß weisen wir noch die Datei und Besitzrechte für die Konfigurationsdatei- und dessen Verzeichnis zu.
# chown -R root:apache /var/www/horde/passwd/config
# chmod g+w -R /var/www/horde/passwd/config
Konfiguration des Backend-Server-Anbindung
Neben der Konfiguration der Anwendung selbst, müssen wir der Anwendung IMP auch noch mitteilen, wie es sich zum MDA1) also unserem IMAP-Server verbinden soll.
Bei diesem Konfigurationsbeispiel gehen wir von einem Dovecot IMAP-Server aus, von dem sich die Nutzer ihre eMails abholen. Die Authentifizierung erfolgt aber in diesem Beispiel direkt gegen das mySQL-Datenbank Backend, in dem die Konfiguration unserer virtuellen Domänen mit ihren Aliasen und Postkörben vorhgehalten wird.
Die mitgelieferte Konfigurationsdatei backends.php lassen wir unangetastet. Die Konfiguration nehmen wir über die zuvor kopierte Datei backends.local.php vor.
Hier eaktivieren wir nun den ersten Standardeintrag und konfigurieren die Passwortdetails, nach den Sicherheitsvorgaben bei der Kundeninstallation.
# vim /var/www/horde/passwd/config/backends.local.php
- /var/www/horde/passwd/config/backends.local.php
<?php /** * This file provides defaults for backends people use to change their * passwords. * * IMPORTANT: DO NOT EDIT THIS FILE! * Local overrides MUST be placed in backends.local.php or backends.d/. * If the 'vhosts' setting has been enabled in Horde's configuration, you can * use backends-servername.php. * * Properties that can be set for each server: * =========================================== * * disabled: (boolean) If true, the config entry is disabled. * * name: (string) This is the plaintext name displayed if using the server * list (also displayed on the main page). * * driver: The driver used to change the password. Valid drivers: * - adsi: ADSI COM interface. * - expect: Expect script. * - horde: Horde authentication driver. * - ldap: LDAP server. * - pine: Pine-encoded file. * - poppassd: Poppassd server. * - servuftp: Servuftp server. * - smbldap: LDAP server for both LDAP -and- Samba auth. * - smbpasswd: Smbpasswd command. * - sql: SQL authentication. * - vmailmgr: Local vmailmgr daemon. * - vpopmail: SQL based vpopmail. * * - composite: Allows you to chain multiple drivers together (see example * below). * * policy: (array) The password policies for this backend. You are responsible * for the sanity checks of these options. Options are: * - maxLength: (integer) Maximum length of the password. * - maxSpace: (integer) Maximum number of white space characters. * - minAlpha: (integer) Minimum number of alphabetic characters. * - minAlphaNum: (integer) Minimum number of alphanumeric characters. * - minLength: (integer) Minimum length of the password. * - minLower: (integer) Minimum number of lowercase characters. * - minNonAlpha: (integer) Minimum number of non-alphabetic characters * - minNumeric: (integer) Minimum number of numeric characters (0-9). * - minSymbol: (integer) Minimum number of punctuation / symbol characters. * - minUpper: (integer) Minimum number of uppercase characters. * * Alternatively/additionally, the minimum number of character classes can * be configured by setting 'minClasses'. The valid range is 0 through 4 * character classes may be required for a password. The available classes: * - lower * - number * - symbol * - upper * * For example: a password of 'p@ssw0rd' satisfies three classes ('number', * 'lower', and 'symbol'), while 'passw0rd' only satisfies two classes * ('lower'and 'symbols'). * * logout: (boolean) If true, this backend changes the password associated * with at least one Horde application. On a successful password * change the current session will be destroyed and the page will * redirect to the login screen. You CANNOT continue to use Horde * since the old password may be cached, which will cause errors. * * params: (array) Additional information that a driver needs. See examples * below for further details. * * preferred: (string) Useful if you want to use the same backend.php file * for different machines. If the hostname of the Passwd Machine is * identical to one of those in the preferred list, then the * corresponding option in the select box will include SELECTED, * i.e. it is selected per default. Otherwise the first entry in * the list is selected. */ $backends['hordeauth'] = array( // Django : 2013-06-10 // default: 'disabled' => true, 'disabled' => false, 'name' => 'Horde Authentication', 'driver' => 'Horde', 'policy' => array( // Django : 2013-06-10 // default: 'minLength' => 6, 'minNumeric' => 1, 'minLength' => 10, 'minNumeric' => 2, ), ); $backends['hordesql'] = array( 'disabled' => true, 'name' => 'Horde SQL Authentication', 'driver' => 'Sql', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array_merge( $GLOBALS['conf']['sql'], array( 'table' => 'horde_users', 'user_col' => 'user_uid', 'pass_col' => 'user_pass', 'show_encryption' => false, 'encryption' => isset($GLOBALS['conf']['auth']['params']['encryption']) ? $GLOBALS['conf']['auth']['params']['encryption'] : false ) ), ); $backends['poppassd'] = array( 'disabled' => true, 'name' => 'Poppassd Server', 'driver' => 'Poppassd', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'host' => 'localhost', 'port' => 106 ), ); $backends['servuftp'] = array( 'disabled' => true, 'name' => 'Serv-U FTP Server', 'driver' => 'Servuftp', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'host' => 'localhost', 'port' => 106, 'timeout' => 30 ), ); $backends['expect'] = array( 'disabled' => true, 'name' => 'Expect Script', 'driver' => 'Expect', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'program' => '/usr/bin/expect', 'script' => PASSWD_BASE . '/scripts/passwd-expect', 'params' => '-telnet -host localhost -output /tmp/passwd.log' ), ); $backends['sudo_expect'] = array( 'disabled' => true, 'name' => 'Expect with Sudo Script', 'driver' => 'Procopen', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'program' => '/usr/bin/expect ' . PASSWD_BASE . '/scripts/passwd-expect -sudo' ), ); $backends['smbpasswd'] = array( 'disabled' => true, 'name' => 'Samba Server', 'driver' => 'Smbpasswd', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'program' => '/usr/bin/smbpasswd', 'host' => 'localhost' ), ); // NOTE: to set the ldap userdn, see horde/config/hooks.php $backends['ldap'] = array( 'disabled' => true, 'name' => 'LDAP Server', 'driver' => 'Ldap', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'host' => 'localhost', 'port' => 389, 'basedn' => 'o=example.com', // LDAP object key attribute. 'uid' => 'uid', // The attribute storing the password. 'attribute' => 'userPassword', // These attributes will enable shadow password policies. // 'shadowlastchange' => 'shadowLastChange', // 'shadowmin' => 'shadowMin', // This will be appended to the username when looking for the userdn. 'realm' => '', // Use this filter when searching for the user's DN. 'filter' => '', // Hash method to use when storing the password 'encryption' => 'crypt', // Whether to enable TLS for this LDAP connection // Note: make sure that the host matches cn in the server certificate. 'tls' => false, // Determine the user's DN. %u will be replaced by the user's ID. //'userdn' => 'uid=%u,o=example.com' ), ); // NOTE: to set the ldap userdn, see horde/config/hooks.php $backends['ldapadmin'] = array( 'disabled' => true, 'name' => 'LDAP Server with Admin Bindings', 'driver' => 'Ldap', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'host' => 'localhost', 'port' => 389, 'basedn' => 'o=example.com', 'admindn' => 'cn=admin,o=example.com', 'adminpw' => 'somepassword', // LDAP object key attribute. 'uid' => 'uid', // The attribute storing the password. 'attribute' => 'userPassword', // These attributes will enable shadow password policies. // 'shadowlastchange' => 'shadowLastChange', // 'shadowmin' => 'shadowMin', // This will be appended to the username when looking for the userdn. 'realm' => '', // Use this filter when searching for the user's DN. 'filter' => '', // Hash method to use when storing the password 'encryption' => 'crypt', // If set, should be 0 or 1. See the LDAP documentation about the // corresponding parameter REFERRALS. // Windows 2003 Server require to set this parameter to 0 // 'referrals' => 0, // Whether to enable TLS for this LDAP connection // Note: make sure that the host matches cn in the server certificate. 'tls' => false ), ); // NOTE: to set the ldap userdn, see horde/config/hooks.php // NOTE: to make work with samba 2.x schema you must change lm_attribute and // nt_attribute $backends['smbldap'] = array( 'disabled' => true, 'name' => 'Samba/LDAP Server', 'preferred' => '', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'driver' => 'Smbldap', 'params' => array( 'host' => 'localhost', 'port' => 389, 'basedn' => 'o=example.com', // LDAP object key attribute. 'uid' => 'uid', // The attribute storing the password. 'attribute' => 'userPassword', // This will be appended to the username when looking for the userdn. 'realm' => '', // Use this filter when searching for the user's DN. 'filter' => '', // Hash method to use when storing the password 'encryption' => 'crypt', // Whether to enable TLS for this LDAP connection // Note: make sure that the host matches cn in the server certificate. 'tls' => false, // Determine the user's DN. %u will be replaced by the user's ID. //'userdn' => 'uid=%u,o=example.com' // If any of the following attributes are commented out, they // won't be set on the LDAP server. 'lm_attribute' => 'sambaLMPassword', 'nt_attribute' => 'sambaNTPassword', 'pw_set_attribute' => 'sambaPwdLastSet', 'pw_expire_attribute' => 'sambaPwdMustChange', // The number of days until samba passwords expire. If this // is commented out, passwords will never expire. 'pw_expire_time' => 180, ), ); $backends['sql'] = array( 'disabled' => true, 'name' => 'SQL Server', 'driver' => 'Sql', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'phptype' => 'mysql', 'hostspec' => 'localhost', 'username' => 'dbuser', 'password' => 'dbpasswd', 'encryption' => 'md5-hex', 'database' => 'db', 'table' => 'users', 'user_col' => 'user_uid', 'pass_col' => 'user_pass', 'show_encryption' => false // The following two settings allow you to specify custom queries for // lookup and modify functions if special functions need to be // performed. In places where a username or a password needs to be // used, refer to this placeholder reference: // %d -> gets substituted with the domain // %u -> gets substituted with the user // %U -> gets substituted with the user without a domain part // %p -> gets substituted with the plaintext password // %e -> gets substituted with the encrypted password // // 'query_lookup' => 'SELECT user_pass FROM horde_users WHERE user_uid = %u', // 'query_modify' => 'UPDATE horde_users SET user_pass = %e WHERE user_uid = %u', ), ); $backends['mailmgr'] = array( 'disabled' => true, 'name' => 'VMailMgr Server', 'driver' => 'Vmailmgr', 'policy' => array(), 'params' => array( 'vmailinc' => '/your/path/to/the/vmail.inc' ), ); $backends['vpopmail'] = array( 'disabled' => true, 'name' => 'Vpopmail Server', 'driver' => 'Vpopmail', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'phptype' => 'mysql', 'hostspec' => 'localhost', 'username' => '', 'password' => '', 'encryption' => 'crypt', 'database' => 'vpopmail', 'table' => 'vpopmail', 'name' => 'pw_name', 'domain' => 'pw_domain', 'passwd' => 'pw_passwd', 'clear_passwd' => 'pw_clear_passwd', 'use_clear_passwd' => true, 'show_encryption' => true ), ); $backends['pine'] = array( 'disabled' => true, 'name' => 'Pine Password File', 'driver' => 'Pine', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( // FTP server information. 'host' => 'localhost', 'port' => '21', 'path' => '', 'file' => '.pinepw', // Connect using the just-passed-in password? 'use_new_passwd' => false, // Host string to look for in the encrypted file. 'imaphost' => 'localhost' ), ); $backends['kolab'] = array( 'disabled' => true, 'name' => 'Local Kolab Server', 'driver' => 'Kolab', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array(), ); $backends['myscript'] = array( 'disabled' => true, 'name' => 'Custom Script', 'driver' => 'Procopen', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'program' => '/path/to/my/script + myargs' ), ); // This is an example configuration for the http driver. This allows // connecting to an arbitrary URL that contains a password change form. // The params 'username','oldPasswd','passwd1', and 'passwd2' params should be // set to the name of the respective form input elements on the html form. If // there are additional form fields that the form requires, define them in the // 'fields' array in the form 'formFieldName' => 'formFieldValue'. The driver // attempts to determine the success or failure based on searching the // returned html page for the values listed in the 'eval_results' array. $backends['http'] = array( 'disabled' => true, 'name' => 'HTTP Server', 'driver' => 'Http', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( 'url' => 'http://www.example.com/psoft/servlet/psoft.hsphere.CP', 'username' => 'mbox', 'oldPasswd' => 'old_password', 'passwd1' => 'password', 'passwd2' => 'password2', 'fields' => array( 'action' => 'change_mbox_password', 'ftemplate' => 'design/mail_passw.html' ), 'eval_results' => array( 'success' => 'Password successfully changed', 'badPass' => 'Bad old password', 'badUser' => 'Mailbox not found' ), ), ); $backends['soap'] = array( 'disabled' => true, 'name' => 'SOAP Server', 'driver' => 'Soap', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array( // If this service doesn't have a WSDL, the 'location' and 'uri' // parameters below must be specified instead. 'wsdl' => 'http://www.example.com/service.wsdl', 'method' => 'changePassword', // This is the order of the arguments to the method specified above. 'arguments' => array('username', 'oldpassword', 'newpassword'), // These parameters are directly passed to the SoapClient object, see // http://ww.php.net/manual/en/soapclient.soapclient.php for a // complete list of possible parameters. 'soap_params' => array( 'location' => '', 'uri' => '', ), ), ); // This is an example configuration for Postfix.admin 2.3. // Set the 'password_policy' section as you wish. // In most installations you probably only need to change the // hostspec and/or password fields. $backends['postfixadmin'] = array( 'disabled' => true, 'name' => 'Postfix Admin server', 'driver' => 'Sql', 'policy' => array( 'minLength' => 6, 'maxLength' => 20, 'minNumeric' => 1, ), 'params' => array( 'phptype' => 'mysql', 'hostspec' => 'localhost', 'username' => 'postfix', 'password' => 'PASSWORD', 'encryption' => 'crypt-md5', 'database' => 'postfix', 'table' => 'mailbox', 'user_col' => 'username', 'pass_col' => 'password', 'show_encryption' => false, // The following two settings allow you to specify custom queries for // lookup and modify functions if special functions need to be // performed. In places where a username or a password needs to be // used, refer to this placeholder reference: // %d -> gets substituted with the domain // %u -> gets substituted with the user // %U -> gets substituted with the user without a domain part // %p -> gets substituted with the plaintext password // %e -> gets substituted with the encrypted password // 'query_lookup' => 'SELECT password FROM mailbox WHERE username = %u and active = 1', 'query_modify' => 'UPDATE mailbox SET password = %e WHERE username = %u' ), ); // This is an example configuration for chaining multiple drivers to allow for // syncing of passwords across many backends using the composite driver as a // wrapper. // // Each of the subdrivers may contain an optional parameter called 'required' // that, when set to true, will cause the rest of the drivers be skipped if a // particular one fails. $backends['composite'] = array( 'disabled' => true, 'name' => 'All Services', 'driver' => 'Composite', 'policy' => array( 'minLength' => 6, 'minNumeric' => 1, ), 'params' => array('drivers' => array( 'sql' => array( 'name' => 'Horde Authentication', 'driver' => 'Sql', 'required' => true, 'params' => array( 'phptype' => 'mysql', 'hostspec' => 'localhost', 'username' => 'horde', 'password' => '', 'encryption' => 'md5-hex', 'database' => 'horde', 'table' => 'horde_users', 'user_col' => 'user_uid', 'pass_col' => 'user_pass', 'show_encryption' => false // 'query_lookup' => '', // 'query_modify' => '', ), ), 'smbpasswd' => array( 'name' => 'Samba Server', 'driver' => 'Smbpasswd', 'params' => array( 'program' => '/usr/bin/smbpasswd', 'host' => 'localhost', ), ), )), );
Damit nun die Anwendung Passwd die Passwortänderung vornehmen kann ist noch eine Änderung am Authentication-Modul vorzunehmen. Dies wird am Ende dieses Kapitel beschrieben.
Konfiguration über die WEB-GUI
Applikation Passwd
Die Konfiguration der Applikation IMP erfolgt dann über die GUI des Web-Frameworks. Dazu rufen wir unseren angelegten VHOST im Webbrowser auf.
$ firefox https://buero.nausch.org
Mit einem Klick auf das Zahnradsysmbol erreichen wir den Menüpunkt Administration.
Hier wählen wir den Menüpunkt Configuration aus.
Da wir die Anwendung Passwd noch nicht konfiguriert haben, ist die Fehlermeldungen erklärbar.
Um zur Konfiguration von Passwd zu gelangen, klicken wir nun auf den Punkt Passwort (passwd).
Auf dem nun zur Verfügung stehenden Reiter, erfolgt die Konfiguration der Horde-Applikation Passwd.
Backend Settings
$conf[backend][backend_list] [hidden] $conf[user][change] [ ] $conf[user][refused] root, bin, daemon, adm, lp, shutdown, halt, uucp, ftp, anonymous, nobody, httpd $conf[password][strengthtests] [✔]
Am Ende unserer Konfigurationsarbeit, sichern wir die Konfiguration mit einem Klick auf die Schaltfläche: Die erfolgreiche Sicherung wird uns entsprechend angezeigt.
Horde Framework
Abhängig davon, welchen Backendserver wir ansprechen wollen und werden, passen wir noch die Authentication Settings des Horde Framworks, über die WEB-GUI an. Die Einstellungen erreichen wir wie folgt:
$ firefox https://buero.nausch.org
Mit einem Klick auf das Zahnradsysmbol erreichen wir den Menüpunkt Administration.
Hier wählen wir den Menüpunkt Configuration aus.
Um zur Konfiguration der Authentication Settings zu gelangen, klicken wir nun auf den Punkt Horde (horde).
Auf dem Reiter Authentication passen wir nun unsere Einstellungen so an, dass Horde bei der Passwortänderung unserer Nutzer die mySQL-Datenbank von Postfixadmin nutzt.
Die hierzu notwendigen Einstellungen haben wir bei der Definition unseres MDAs vorgenommen.
Reiter Authentication
Authentication Settings
$conf[auth][admins] <eMail-Adresse(n) des/(r) Admins>
$conf[auth][checkip] [✔]
$conf[auth][checkbrowser] [✔]
$conf[auth][resetpassword] [✔]
$conf[auth][alternate_login] false
$conf[auth][redirect_on_logout] false
$conf[auth][list_users] Show an input field
$conf[auth][driver] SQL authentication w/custom made-queries
$conf[auth][params][phptype] MySQL (mysqli)
$conf[auth][params][protocol] TCP/IP
$conf[auth][params][hostspec] mysql.dmz.nausch.org
$conf[auth][params][port] 3306
$conf[auth][params][username] pfadmin-dbuser
$conf[auth][params][password] Django-1$-4-G33k!
$conf[auth][params][database] postfix
$conf[auth][params][query_auth] SELECT * FROM mailbox WHERE username = \L AND password =\P
$conf[auth][params][query_add] INSERT INTO mailbox (username, password, name, maildir, quota, local_part, domain, created, modified, active) VALUES ( \L, \P, '', CONCAT(SUBSTRING_INDEX(\L, '@', -1), '/', SUBSTRING_INDEX(\L, '@', 1), '/'), '5120000000', SUBSTRING_INDEX(\L, '@', 1), SUBSTRING_INDEX(\L, '@', -1), now(), now(), '1')
$conf[auth][params][query_getpw] SELECT password FROM mailbox WHERE username = \L
$conf[auth][params][query_update] UPDATE mailbox SET password = \P WHERE username = \L
$conf[auth][params][query_resetpassword] UPDATE users SET password = \P WHERE userid = \L
$conf[auth][params][query_remove] UPDATE users SET password = \P WHERE userid = \L
$conf[auth][params][query_list] SELECT username FROM mailbox
$conf[auth][params][query_exists] SELECT 1 FROM mailbox WHERE username = \L
$conf[auth][params][encryption] crypt-md5
$conf[auth][params][show_encryption] [ ]
$conf[auth][params][count_bad_logins] [ ]
$conf[auth][params][login_block] [ ]
$conf[auth][params][login_block_count 5
$conf[auth][params][login_block_time] 5
Terms of Service Agreement
$conf[tos][file]
Zum Schluß sichern wir die Konfiguration mit einem Klick auf die Schaltfläche: Die erfolgreiche Sicherung wird uns entsprechend angezeigt.