Merge pull request #24 from LDAPAccountManager/2factor_auth

2factor auth
This commit is contained in:
gruberroland 2017-02-11 22:37:24 +01:00 committed by GitHub
commit 968b6ebd22
41 changed files with 2010 additions and 13580 deletions

View File

@ -1,18 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="a_configuration"> <chapter id="a_configuration">
<title>Configuration</title> <title>Configuration</title>
<para>After you <link linkend="a_installation">installed</link> LAM you <para>After you <link linkend="a_installation">installed</link> LAM you can
can configure it to fit your needs. The complete configuration can be done configure it to fit your needs. The complete configuration can be done
inside the application. There is no need to edit configuration inside the application. There is no need to edit configuration files.</para>
files.</para>
<para>Please point you browser to the location where you installed LAM. <para>Please point you browser to the location where you installed LAM. E.g.
E.g. for Debian/RPM this is http://yourServer/lam. If you installed LAM for Debian/RPM this is http://yourServer/lam. If you installed LAM via the
via the tar.bz2 then this may vary. You should see the following tar.bz2 then this may vary. You should see the following page:</para>
page:</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -23,8 +21,8 @@
</screenshot> </screenshot>
<para>If you see an error message then you might need to install an <para>If you see an error message then you might need to install an
additional PHP extension. Please follow the instructions and reload the additional PHP extension. Please follow the instructions and reload the page
page afterwards.</para> afterwards.</para>
<para>Now you are ready to configure LAM. Click on the "LAM configuration" <para>Now you are ready to configure LAM. Click on the "LAM configuration"
link to proceed.</para> link to proceed.</para>
@ -37,18 +35,18 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>Here you can change LAM's general settings, setup server profiles <para>Here you can change LAM's general settings, setup server profiles for
for your LDAP server(s) and configure the <link your LDAP server(s) and configure the <link linkend="a_selfService">self
linkend="a_selfService">self service</link> (LAM Pro). You should start service</link> (LAM Pro). You should start with the general settings and
with the general settings and then setup a server profile.</para> then setup a server profile.</para>
<section id="generalSettings"> <section id="generalSettings">
<title>General settings</title> <title>General settings</title>
<para>After selecting "Edit general settings" you will need to enter the <para>After selecting "Edit general settings" you will need to enter the
<link linkend="a_configPasswords">master configuration password</link>. <link linkend="a_configPasswords">master configuration password</link>.
The default password for new installations is "lam". Now you can edit The default password for new installations is "lam". Now you can edit the
the general settings.</para> general settings.</para>
<section> <section>
<title>License (LAM Pro only)</title> <title>License (LAM Pro only)</title>
@ -80,9 +78,9 @@
<para>You may also set a list of IP addresses which are allowed to <para>You may also set a list of IP addresses which are allowed to
access LAM. The IPs can be specified as full IP (e.g. 123.123.123.123) access LAM. The IPs can be specified as full IP (e.g. 123.123.123.123)
or with the "*" wildcard (e.g. 123.123.123.*). Users which try to or with the "*" wildcard (e.g. 123.123.123.*). Users which try to access
access LAM via an untrusted IP only get blank pages. There is a LAM via an untrusted IP only get blank pages. There is a separate field
separate field for LAM Pro self service.</para> for LAM Pro self service.</para>
<para id="sessionEncryption">Session encryption will encrypt sensitive <para id="sessionEncryption">Session encryption will encrypt sensitive
data like passwords in your session files. This is only available when data like passwords in your session files. This is only available when
@ -102,17 +100,17 @@
<para id="conf_sslCert"><emphasis role="bold">SSL certificate <para id="conf_sslCert"><emphasis role="bold">SSL certificate
setup:</emphasis></para> setup:</emphasis></para>
<para>By default, LAM uses the CA certificates that are preinstalled <para>By default, LAM uses the CA certificates that are preinstalled on
on your system. This will work if you connect via SSL/TLS to an LDAP your system. This will work if you connect via SSL/TLS to an LDAP server
server that uses a certificate signed by a well-known CA. In case you that uses a certificate signed by a well-known CA. In case you use your
use your own CA (e.g. company internal CA) you can import the CA own CA (e.g. company internal CA) you can import the CA certificates
certificates here.</para> here.</para>
<para>Please note that this can affect other web applications on the <para>Please note that this can affect other web applications on the
same server if they require different certificates. There seem to be same server if they require different certificates. There seem to be
problems on Debian systems and you may also need to restart Apache. In problems on Debian systems and you may also need to restart Apache. In
case of any problems please delete the uploaded certificates and use case of any problems please delete the uploaded certificates and use the
the <link linkend="ssl_certSystem">system setup</link>.</para> <link linkend="ssl_certSystem">system setup</link>.</para>
<para>You can either upload a DER/PEM formatted certificate file or <para>You can either upload a DER/PEM formatted certificate file or
import the certificates directly from an LDAP server that is available import the certificates directly from an LDAP server that is available
@ -137,10 +135,10 @@
<section> <section>
<title>Password policy</title> <title>Password policy</title>
<para>This allows you to specify a central password policy for LAM. <para>This allows you to specify a central password policy for LAM. The
The policy is valid for all password fields inside LAM admin policy is valid for all password fields inside LAM admin (excluding tree
(excluding tree view) and LAM self service. Configuration passwords do view) and LAM self service. Configuration passwords do not need to
not need to follow this policy.</para> follow this policy.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -150,23 +148,22 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>You can set the minimum password length and also the complexity <para>You can set the minimum password length and also the complexity of
of the passwords.</para> the passwords.</para>
</section> </section>
<section id="conf_logging"> <section id="conf_logging">
<title>Logging</title> <title>Logging</title>
<para>LAM can log events (e.g. user logins). You can use system <para>LAM can log events (e.g. user logins). You can use system logging
logging (syslog for Unix, event viewer for Windows) or log to a (syslog for Unix, event viewer for Windows) or log to a separate file.
separate file. Please note that LAM may log sensitive data (e.g. Please note that LAM may log sensitive data (e.g. passwords) at log
passwords) at log level "Debug". Production systems should be set to level "Debug". Production systems should be set to "Warning" or
"Warning" or "Error".</para> "Error".</para>
<para>The PHP error reporting is only for developers. By default LAM <para>The PHP error reporting is only for developers. By default LAM
does not show PHP notice messages in the web pages. You can select to does not show PHP notice messages in the web pages. You can select to
use the php.ini setting here or printing all errors and use the php.ini setting here or printing all errors and notices.</para>
notices.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -180,8 +177,7 @@
<section> <section>
<title>Additional options</title> <title>Additional options</title>
<para id="mailEOL"><emphasis role="bold">Email <para id="mailEOL"><emphasis role="bold">Email format</emphasis></para>
format</emphasis></para>
<para>Some email servers are not standards compatible. If you receive <para>Some email servers are not standards compatible. If you receive
mails that look broken you can change the line endings for sent mails mails that look broken you can change the line endings for sent mails
@ -189,8 +185,7 @@
<para>At the moment, this option is only available in LAM Pro as there <para>At the moment, this option is only available in LAM Pro as there
is no mail sending in the free version. See <link is no mail sending in the free version. See <link
linkend="mailSetup">here</link> for setting up your SMTP linkend="mailSetup">here</link> for setting up your SMTP server.</para>
server.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -204,8 +199,8 @@
<section> <section>
<title>Change master password</title> <title>Change master password</title>
<para>If you would like to change the master configuration password <para>If you would like to change the master configuration password then
then enter a new password here.</para> enter a new password here.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -240,13 +235,13 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>Here you can create, rename and delete server profiles. The <para>Here you can create, rename and delete server profiles. The <link
<link linkend="a_configPasswords">passwords</link> of your server linkend="a_configPasswords">passwords</link> of your server profiles can
profiles can also be reset.</para> also be reset.</para>
<para>You may also specify the default server profile. This is the <para>You may also specify the default server profile. This is the
server profile which is preselected at the login page. It also server profile which is preselected at the login page. It also specifies
specifies the language of the login and configuration pages.</para> the language of the login and configuration pages.</para>
<para><emphasis role="bold">Templates for new server <para><emphasis role="bold">Templates for new server
profiles</emphasis></para> profiles</emphasis></para>
@ -287,15 +282,14 @@
<para>All operations on the profile management page require that you <para>All operations on the profile management page require that you
authenticate yourself with the <link authenticate yourself with the <link
linkend="a_configPasswords">configuration master linkend="a_configPasswords">configuration master password</link>.</para>
password</link>.</para>
</section> </section>
<section> <section>
<title>Editing a server profile</title> <title>Editing a server profile</title>
<para>Please select you server profile and enter its password to edit <para>Please select you server profile and enter its password to edit a
a server profile.</para> server profile.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -316,8 +310,8 @@
<listitem> <listitem>
<para><emphasis role="bold">Account types:</emphasis> list of <para><emphasis role="bold">Account types:</emphasis> list of
account types (e.g. users and groups) that you would like to account types (e.g. users and groups) that you would like to manage
manage and type specific settings (e.g. LDAP suffix)</para> and type specific settings (e.g. LDAP suffix)</para>
</listitem> </listitem>
<listitem> <listitem>
@ -353,17 +347,17 @@
specified with ldaps://. The port value is optional. TLS cannot be specified with ldaps://. The port value is optional. TLS cannot be
combined with ldaps://.</para> combined with ldaps://.</para>
<para>Hint: If you use a master/slave setup with referrals then <para>Hint: If you use a master/slave setup with referrals then point
point LAM to your master server. Due to bugs in the underlying LDAP LAM to your master server. Due to bugs in the underlying LDAP
libraries pointing to a slave might cause issues on write libraries pointing to a slave might cause issues on write
operations.</para> operations.</para>
<para>LAM includes an LDAP browser which allows direct modification <para>LAM includes an LDAP browser which allows direct modification of
of LDAP entries. If you would like to use it then enter the LDAP LDAP entries. If you would like to use it then enter the LDAP suffix
suffix at "Tree suffix".</para> at "Tree suffix".</para>
<para>The search limit is used to reduce the number of search <para>The search limit is used to reduce the number of search results
results which are returned by your LDAP server.</para> which are returned by your LDAP server.</para>
<para>The access level specifies if LAM should allow to modify LDAP <para>The access level specifies if LAM should allow to modify LDAP
entries. This feature is only available in LAM Pro. LAM non-Pro entries. This feature is only available in LAM Pro. LAM non-Pro
@ -373,8 +367,8 @@
<para><emphasis role="bold">Advanced options</emphasis></para> <para><emphasis role="bold">Advanced options</emphasis></para>
<para>Sometimes, you may not want to display the server address on <para>Sometimes, you may not want to display the server address on the
the login page. In this case you can setup a display name here (e.g. login page. In this case you can setup a display name here (e.g.
"Production").</para> "Production").</para>
<para>By default LAM will not follow LDAP referrals. This is ok for <para>By default LAM will not follow LDAP referrals. This is ok for
@ -402,14 +396,14 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>LAM can manage user home directories and quotas with an <para>LAM can manage user home directories and quotas with an external
external script. You can specify the home directory server and where script. You can specify the home directory server and where the script
the script is located. The default rights for new home directories is located. The default rights for new home directories can be set,
can be set, too.</para> too.</para>
<para>You can provide a fixed user name. If you leave the field <para>You can provide a fixed user name. If you leave the field empty
empty then LAM will use your current account (the account you used then LAM will use your current account (the account you used to login
to login to LAM).</para> to LAM).</para>
<para>There are two possibilities to connect to your home <para>There are two possibilities to connect to your home
directory/quota server:</para> directory/quota server:</para>
@ -424,8 +418,8 @@
<listitem> <listitem>
<para>Password: If you do not set a SSH key then LAM will try to <para>Password: If you do not set a SSH key then LAM will try to
connect with your current account (the password you used to connect with your current account (the password you used to login
login to LAM).</para> to LAM).</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -437,9 +431,9 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para id="profile_mail">LAM Pro users may directly set passwords <para id="profile_mail">LAM Pro users may directly set passwords from
from list view. You can configure if it should be possible to set list view. You can configure if it should be possible to set specific
specific passwords and showing password on screen is allowed.</para> passwords and showing password on screen is allowed.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -452,9 +446,9 @@
<para>LAM Pro users can send out changed passwords to their users. <para>LAM Pro users can send out changed passwords to their users.
Here you can specify the options for these mails.</para> Here you can specify the options for these mails.</para>
<para>If you select "Allow alternate address" then password mails <para>If you select "Allow alternate address" then password mails can
can be sent to any address (e.g. a secondary address if the user be sent to any address (e.g. a secondary address if the user account
account is also bound to the mailbox).</para> is also bound to the mailbox).</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -464,7 +458,17 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>LAM supports two methods for login.</para> <para>LAM supports two methods for login:</para>
<itemizedlist>
<listitem>
<para>Fixed list</para>
</listitem>
<listitem>
<para>LDAP search</para>
</listitem>
</itemizedlist>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -479,26 +483,25 @@
<para>The second one is to let LAM search for the DN in your <para>The second one is to let LAM search for the DN in your
directory. E.g. if a user logs in with the user name "joe" then LAM directory. E.g. if a user logs in with the user name "joe" then LAM
will do an LDAP search for this user name. When it finds a matching will do an LDAP search for this user name. When it finds a matching DN
DN then it will use this to authenticate the user. The wildcard then it will use this to authenticate the user. The wildcard "%USER%"
"%USER%" will be replaced by "joe" in this example. This way you can will be replaced by "joe" in this example. This way you can provide
provide login by user name, email address or other LDAP login by user name, email address or other LDAP attributes.</para>
attributes.</para>
<para>Additionally, you can enable HTTP authentication when using <para>Additionally, you can enable HTTP authentication when using
"LDAP search". This way the web server is responsible to "LDAP search". This way the web server is responsible to authenticate
authenticate your users. LAM will use the given user name + password your users. LAM will use the given user name + password for the LDAP
for the LDAP login. You can also configure this to setup advanced login. You can also configure this to setup advanced login
login restrictions (e.g. require group memberships for login). To restrictions (e.g. require group memberships for login). To setup HTTP
setup HTTP authentication in Apache please see this <ulink authentication in Apache please see this <ulink
url="http://httpd.apache.org/docs/2.2/howto/auth.html">link</ulink> url="http://httpd.apache.org/docs/2.2/howto/auth.html">link</ulink>
and an example for LDAP authentication <link lang="" and an example for LDAP authentication <link lang=""
linkend="apache_http_auth">here</link>.</para> linkend="apache_http_auth">here</link>.</para>
<para><emphasis role="bold">Hint:</emphasis> LDAP search with group <para><emphasis role="bold">Hint:</emphasis> LDAP search with group
membership check can be done with either <link membership check can be done with either <link
linkend="apache_http_auth">HTTP authentication</link> or LDAP linkend="apache_http_auth">HTTP authentication</link> or LDAP overlays
overlays like <ulink like <ulink
url="http://www.openldap.org/doc/admin24/overlays.html">"memberOf"</ulink> url="http://www.openldap.org/doc/admin24/overlays.html">"memberOf"</ulink>
or <ulink or <ulink
url="http://www.openldap.org/doc/admin24/overlays.html">"Dynamic url="http://www.openldap.org/doc/admin24/overlays.html">"Dynamic
@ -514,8 +517,60 @@
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>You may also change the password of this server profile. <para><emphasis role="bold">2-factor authentication</emphasis></para>
Please just enter the new password in both password fields.</para>
<para>LAM supports 2-factor authentication for your users. This means
the user will not only authenticate by user+password but also with
e.g. a token generated by a mobile device. This adds more security
because the token is generated on a physically separated device
(typically mobile phone).</para>
<para>The token is validated by a second application. LAM currently
supports:</para>
<itemizedlist>
<listitem>
<para><ulink
url="https://www.privacyidea.org/">privacyIdea</ulink></para>
</listitem>
</itemizedlist>
<para>By default LAM will enforce to use a token and reject users that
did not setup one. You can set this check to optional. But if a user
has setup a token then this will always be required.</para>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="images/configProfiles11.png" />
</imageobject>
</mediaobject>
</screenshot>
<para>After logging in with user + password LAM will ask for the 2nd
factor. If the user has setup multiple factors then he can choose one
of them.</para>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="images/configProfiles12.png" />
</imageobject>
</mediaobject>
</screenshot>
<para><emphasis role="bold">Password</emphasis></para>
<para>You may also change the password of this server profile. Please
just enter the new password in both password fields.</para>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="images/configProfiles13.png" />
</imageobject>
</mediaobject>
</screenshot>
</section> </section>
<section> <section>
@ -545,18 +600,18 @@
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis role="bold">List attributes:</emphasis> a list <para><emphasis role="bold">List attributes:</emphasis> a list of
of attributes which are shown in the account lists</para> attributes which are shown in the account lists</para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis role="bold">Additional LDAP filter:</emphasis> <para><emphasis role="bold">Additional LDAP filter:</emphasis> LAM
LAM will automatically detect the right LDAP entries for each will automatically detect the right LDAP entries for each account
account type. This can be used to further limit the number of type. This can be used to further limit the number of visible
visible entries (e.g. if you want to manage only some specific entries (e.g. if you want to manage only some specific groups).
groups). You can use "@@LOGIN_DN@@" as wildcard (e.g. You can use "@@LOGIN_DN@@" as wildcard (e.g.
"(owner=@@LOGIN_DN@@)"). It will be replaced by the DN of the "(owner=@@LOGIN_DN@@)"). It will be replaced by the DN of the user
user who is logged in.</para> who is logged in.</para>
</listitem> </listitem>
<listitem> <listitem>
@ -569,32 +624,32 @@
<listitem> <listitem>
<para><emphasis role="bold">Read-only (LAM Pro only):</emphasis> <para><emphasis role="bold">Read-only (LAM Pro only):</emphasis>
This allows to set a single account type to read-only mode. This allows to set a single account type to read-only mode. Please
Please note that this is a restriction on functional level (e.g. note that this is a restriction on functional level (e.g. group
group memberships can be changed on user page even if groups are memberships can be changed on user page even if groups are
read-only) and is no replacement for setting up proper ACLs on read-only) and is no replacement for setting up proper ACLs on
your LDAP server.</para> your LDAP server.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis role="bold">Custom label:</emphasis> Here you <para><emphasis role="bold">Custom label:</emphasis> Here you can
can set a custom label for the account types. Use this if the set a custom label for the account types. Use this if the standard
standard label does not fit for you (e.g. enter "Servers" for label does not fit for you (e.g. enter "Servers" for
hosts).</para> hosts).</para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis role="bold">No new entries (LAM Pro <para><emphasis role="bold">No new entries (LAM Pro
only):</emphasis> Use this if you want to prevent that new only):</emphasis> Use this if you want to prevent that new
accounts of this type are created by your users. The GUI will accounts of this type are created by your users. The GUI will hide
hide buttons to create new entries and also disable file upload buttons to create new entries and also disable file upload for
for this type.</para> this type.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis role="bold">Disallow delete (LAM Pro <para><emphasis role="bold">Disallow delete (LAM Pro
only):</emphasis> Use this if you want to prevent that accounts only):</emphasis> Use this if you want to prevent that accounts of
of this type are deleted by your users.</para> this type are deleted by your users.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -613,9 +668,9 @@
<section> <section>
<title>Modules</title> <title>Modules</title>
<para>The modules specify the active extensions for each account <para>The modules specify the active extensions for each account type.
type. E.g. here you can setup if your user entries should be address E.g. here you can setup if your user entries should be address book
book entries only or also support Unix or Samba.</para> entries only or also support Unix or Samba.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -640,9 +695,9 @@
<para>Depending on the activated account modules there may be <para>Depending on the activated account modules there may be
additional configuration options available. They can be found on the additional configuration options available. They can be found on the
"Module settings" tab. E.g. the Personal account module allows to "Module settings" tab. E.g. the Personal account module allows to hide
hide several input fields and the Unix module requires to specify several input fields and the Unix module requires to specify ranges
ranges for UID numbers.</para> for UID numbers.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -657,8 +712,8 @@
<section> <section>
<title>Cron jobs (LAM Pro)</title> <title>Cron jobs (LAM Pro)</title>
<para>LAM Pro can execute common tasks via cron job. This can be used <para>LAM Pro can execute common tasks via cron job. This can be used to
to e.g. notify your users before their passwords expire.</para> e.g. notify your users before their passwords expire.</para>
<section> <section>
<title>LDAP and database configuration</title> <title>LDAP and database configuration</title>
@ -673,8 +728,8 @@
<para><emphasis role="bold">SQLite</emphasis></para> <para><emphasis role="bold">SQLite</emphasis></para>
<para>This is a simple file based database. It needs no special <para>This is a simple file based database. It needs no special
database server. The database file will be located next to the database server. The database file will be located next to the server
server profile in config directory.</para> profile in config directory.</para>
<para>You will need to install the SQLite PDO module for PHP <para>You will need to install the SQLite PDO module for PHP
(pdo_sqlite.so). For Debian this is located in package (pdo_sqlite.so). For Debian this is located in package
@ -722,15 +777,15 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para><literallayout> <para><literallayout>
</literallayout><emphasis role="bold">Test your settings</emphasis></para> </literallayout><emphasis role="bold">Test your settings</emphasis></para>
<para>After the LDAP and database settings are done you can test <para>After the LDAP and database settings are done you can test your
your settings.</para> settings.</para>
<para><emphasis role="bold">Cron entry</emphasis></para> <para><emphasis role="bold">Cron entry</emphasis></para>
<para>LAM also prints the crontab line that you need to run the <para>LAM also prints the crontab line that you need to run the
configured jobs on a daily basis. The command must be run as the configured jobs on a daily basis. The command must be run as the same
same user as your webserver is running. You are free to change the user as your webserver is running. You are free to change the starting
starting time of the script or run it more often.</para> time of the script or run it more often.</para>
</section> </section>
<section> <section>
@ -738,12 +793,12 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>To add a new job just click on the "Add job" button and select <para>To add a new job just click on the "Add job" button and select
the job type you need. The list of available jobs depends on your the job type you need. The list of available jobs depends on your
active account modules. E.g. the PPolicy job will only be available active account modules. E.g. the PPolicy job will only be available if
if you activated PPolicy user module.</para> you activated PPolicy user module.</para>
<para>Depending on the job type jobs may be added multiple times <para>Depending on the job type jobs may be added multiple times with
with different configurations. For descriptions about the available different configurations. For descriptions about the available job
job types see next chapters.</para> types see next chapters.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -760,25 +815,25 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
password expires.</para> password expires.</para>
<para>You need to activate the PPolicy module for users to be able <para>You need to activate the PPolicy module for users to be able
to add this job. The job can be added multiple times (e.g. to send to add this job. The job can be added multiple times (e.g. to send a
a second warning at a later time).</para> second warning at a later time).</para>
<para>LAM calculates the expiration date based on the last <para>LAM calculates the expiration date based on the last password
password change and the assigned password policy (or the default change and the assigned password policy (or the default policy)
policy) using attributes pwdMaxAge and pwdExpireWarning.</para> using attributes pwdMaxAge and pwdExpireWarning.</para>
<para>Examples:</para> <para>Examples:</para>
<para>Warning time (pwdExpireWarning) = 14 days, notification <para>Warning time (pwdExpireWarning) = 14 days, notification period
period = 10: LAM will send out the email 24 days before the = 10: LAM will send out the email 24 days before the password
password expires</para> expires</para>
<para>Warning time (pwdExpireWarning) = 14 days, notification <para>Warning time (pwdExpireWarning) = 14 days, notification period
period = 0: LAM will send out the email 14 days before the = 0: LAM will send out the email 14 days before the password
password expires</para> expires</para>
<para>No warning time (pwdExpireWarning), notification period = <para>No warning time (pwdExpireWarning), notification period = 10:
10: LAM will send out the email 10 days before the password LAM will send out the email 10 days before the password
expires</para> expires</para>
<screenshot> <screenshot>
@ -797,8 +852,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -859,12 +913,12 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>Wildcards:</para> <para>Wildcards:</para>
<para>You can enter LDAP attributes as wildcards in the form <para>You can enter LDAP attributes as wildcards in the form
@@ATTRIBUTE_NAME@@. E.g. to add the user's common name use @@ATTRIBUTE_NAME@@. E.g. to add the user's common name use "@@cn@@".
"@@cn@@". For the common name it would be "@@cn@@".</para> For the common name it would be "@@cn@@".</para>
<para>There are also two special wildcards for the expiration <para>There are also two special wildcards for the expiration date.
date. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. "31.12.2016".
"31.12.2016". @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g. @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g.
"2016-12-31".</para> "2016-12-31".</para>
</section> </section>
@ -952,12 +1006,12 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>Wildcards:</para> <para>Wildcards:</para>
<para>You can enter LDAP attributes as wildcards in the form <para>You can enter LDAP attributes as wildcards in the form
@@ATTRIBUTE_NAME@@. E.g. to add the user's common name use @@ATTRIBUTE_NAME@@. E.g. to add the user's common name use "@@cn@@".
"@@cn@@". For the common name it would be "@@cn@@".</para> For the common name it would be "@@cn@@".</para>
<para>There are also two special wildcards for the expiration <para>There are also two special wildcards for the expiration date.
date. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. "31.12.2016".
"31.12.2016". @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g. @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g.
"2016-12-31".</para> "2016-12-31".</para>
</section> </section>
@ -967,21 +1021,21 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>This will send your users an email reminder before their <para>This will send your users an email reminder before their
password expires.</para> password expires.</para>
<para>You need to activate the Shadow module for users to be able <para>You need to activate the Shadow module for users to be able to
to add this job. The job can be added multiple times (e.g. to send add this job. The job can be added multiple times (e.g. to send a
a second warning at a later time).</para> second warning at a later time).</para>
<para>LAM calculates the expiration date based on the last <para>LAM calculates the expiration date based on the last password
password change, the password warning time (attribute change, the password warning time (attribute "shadowWarning") and
"shadowWarning") and the specified notification period.</para> the specified notification period.</para>
<para>Examples:</para> <para>Examples:</para>
<para>Warning time = 14, notification period = 10: LAM will send <para>Warning time = 14, notification period = 10: LAM will send out
out the email 24 days before the password expires</para> the email 24 days before the password expires</para>
<para>Warning time = 14, notification period = 0: LAM will send <para>Warning time = 14, notification period = 0: LAM will send out
out the email 14 days before the password expires</para> the email 14 days before the password expires</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -999,8 +1053,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1054,21 +1107,21 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>Wildcards:</para> <para>Wildcards:</para>
<para>You can enter LDAP attributes as wildcards in the form <para>You can enter LDAP attributes as wildcards in the form
@@ATTRIBUTE_NAME@@. E.g. to add the user's common name use @@ATTRIBUTE_NAME@@. E.g. to add the user's common name use "@@cn@@".
"@@cn@@". For the common name it would be "@@cn@@".</para> For the common name it would be "@@cn@@".</para>
<para>There are also two special wildcards for the expiration <para>There are also two special wildcards for the expiration date.
date. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. "31.12.2016".
"31.12.2016". @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g. @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g.
"2016-12-31".</para> "2016-12-31".</para>
</section> </section>
<section> <section>
<title>Shadow: Delete or move expired accounts</title> <title>Shadow: Delete or move expired accounts</title>
<para>You can automatically delete or move expired accounts. The <para>You can automatically delete or move expired accounts. The job
job checks Shadow account expiration dates (not password checks Shadow account expiration dates (not password expiration
expiration dates).</para> dates).</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1086,8 +1139,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1121,11 +1173,11 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
password expires.</para> password expires.</para>
<para>You need to activate the Windows module for users to be able <para>You need to activate the Windows module for users to be able
to add this job. The job can be added multiple times (e.g. to send to add this job. The job can be added multiple times (e.g. to send a
a second warning at a later time).</para> second warning at a later time).</para>
<para>LAM calculates the expiration date based on the last <para>LAM calculates the expiration date based on the last password
password change and the domain policy.</para> change and the domain policy.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1143,8 +1195,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1198,20 +1249,19 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<para>Wildcards:</para> <para>Wildcards:</para>
<para>You can enter LDAP attributes as wildcards in the form <para>You can enter LDAP attributes as wildcards in the form
@@ATTRIBUTE_NAME@@. E.g. to add the user's common name use @@ATTRIBUTE_NAME@@. E.g. to add the user's common name use "@@cn@@".
"@@cn@@". For the common name it would be "@@cn@@".</para> For the common name it would be "@@cn@@".</para>
<para>There are also two special wildcards for the expiration <para>There are also two special wildcards for the expiration date.
date. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. @@EXPIRE_DATE_DDMMYYYY@@ will print the date as e.g. "31.12.2016".
"31.12.2016". @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g. @@EXPIRE_DATE_YYYYMMDD@@ will print the date as e.g.
"2016-12-31".</para> "2016-12-31".</para>
</section> </section>
<section> <section>
<title>Windows: Delete or move expired accounts</title> <title>Windows: Delete or move expired accounts</title>
<para>You can automatically delete or move expired <para>You can automatically delete or move expired accounts.</para>
accounts.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1229,8 +1279,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1260,8 +1309,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<section> <section>
<title>FreeRadius: Delete or move expired accounts</title> <title>FreeRadius: Delete or move expired accounts</title>
<para>You can automatically delete or move expired <para>You can automatically delete or move expired accounts.</para>
accounts.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1279,8 +1327,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1310,8 +1357,8 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<section> <section>
<title>Qmail: Delete or move expired accounts</title> <title>Qmail: Delete or move expired accounts</title>
<para>You can automatically delete or move expired accounts. The <para>You can automatically delete or move expired accounts. The job
job reads the qmail deletion date of user accounts.</para> reads the qmail deletion date of user accounts.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1329,8 +1376,7 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<row> <row>
<entry><emphasis role="bold">Option</emphasis></entry> <entry><emphasis role="bold">Option</emphasis></entry>
<entry><emphasis <entry><emphasis role="bold">Description</emphasis></entry>
role="bold">Description</emphasis></entry>
</row> </row>
<row> <row>
@ -1377,18 +1423,18 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<section id="confTypicalScenarios"> <section id="confTypicalScenarios">
<title>Typical scenarios</title> <title>Typical scenarios</title>
<para>This is a list of typical scenarios how your LDAP environment <para>This is a list of typical scenarios how your LDAP environment may
may look like and how to structure the server profiles for it.</para> look like and how to structure the server profiles for it.</para>
<section> <section>
<title>Simple: One LDAP directory managed by a small group of <title>Simple: One LDAP directory managed by a small group of
admins</title> admins</title>
<para>This is the easiest and most common scenario. You want to <para>This is the easiest and most common scenario. You want to manage
manage a single LDAP server and there is only one or a few admins. a single LDAP server and there is only one or a few admins. In this
In this case just create one server profile and you are done. The case just create one server profile and you are done. The admins may
admins may be either specified as a fixed list or by using an LDAP be either specified as a fixed list or by using an LDAP search at
search at login time.</para> login time.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1404,11 +1450,10 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
groups</title> groups</title>
<para>Large organisations may have one big LDAP directory for all <para>Large organisations may have one big LDAP directory for all
user/group accounts. But the users are managed by different groups user/group accounts. But the users are managed by different groups of
of admins (e.g. departments, locations, subsidiaries, ...). The admins (e.g. departments, locations, subsidiaries, ...). The users are
users are typically divided into organisational units in the LDAP typically divided into organisational units in the LDAP tree. Admins
tree. Admins may only manage the users in their part of the may only manage the users in their part of the tree.</para>
tree.</para>
<screenshot> <screenshot>
<mediaobject> <mediaobject>
@ -1418,16 +1463,15 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
</mediaobject> </mediaobject>
</screenshot> </screenshot>
<para>In this situation it is recommended to create one server <para>In this situation it is recommended to create one server profile
profile for each admin group (e.g. department). Setup the LDAP for each admin group (e.g. department). Setup the LDAP suffixes in the
suffixes in the server profiles to point to the needed server profiles to point to the needed organisational units. E.g. use
organisational units. E.g. use
ou=people,ou=department1,dc=company,dc=com or ou=people,ou=department1,dc=company,dc=com or
ou=department1,ou=people,dc=company,dc=com as LDAP suffix for users. ou=department1,ou=people,dc=company,dc=com as LDAP suffix for users.
Do the same for groups, hosts, ... This way each admin group will Do the same for groups, hosts, ... This way each admin group will only
only see its own users. You may want to use LDAP search for the LAM see its own users. You may want to use LDAP search for the LAM login
login in this scenario. This will prevent that you need to update a in this scenario. This will prevent that you need to update a server
server profile if the number of admins changes.</para> profile if the number of admins changes.</para>
<para><emphasis role="bold">Attention:</emphasis> LAM's feature to <para><emphasis role="bold">Attention:</emphasis> LAM's feature to
automatically find free UIDs/GIDs for new users/groups will not work automatically find free UIDs/GIDs for new users/groups will not work
@ -1456,8 +1500,8 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
<section> <section>
<title>Single LDAP directory with lots of users (&gt;10 000)</title> <title>Single LDAP directory with lots of users (&gt;10 000)</title>
<para>LAM was tested to work with 10 000 users. If you have a lot <para>LAM was tested to work with 10 000 users. If you have a lot more
more users then you have basically two options.</para> users then you have basically two options.</para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -1476,4 +1520,4 @@ mysql&gt; GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
</section> </section>
</section> </section>
</section> </section>
</chapter> </chapter>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,6 +1,7 @@
<?php <?php
namespace LAM\LIB\TWO_FACTOR; namespace LAM\LIB\TWO_FACTOR;
use \selfServiceProfile; use \selfServiceProfile;
use \LAMConfig;
/* /*
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
@ -58,15 +59,15 @@ interface TwoFactorProvider {
*/ */
class PrivacyIDEAProvider implements TwoFactorProvider { class PrivacyIDEAProvider implements TwoFactorProvider {
private $profile; private $config;
/** /**
* Constructor. * Constructor.
* *
* @param selfServiceProfile $profile profile * @param TwoFactorConfiguration $config configuration
*/ */
public function __construct(&$profile) { public function __construct(&$config) {
$this->profile = $profile; $this->config = $config;
} }
/** /**
@ -99,7 +100,7 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
*/ */
private function authenticate($user, $password) { private function authenticate($user, $password) {
$curl = $this->getCurl(); $curl = $this->getCurl();
$url = $this->profile->twoFactorAuthenticationURL . "/auth"; $url = $this->config->twoFactorAuthenticationURL . "/auth";
curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_URL, $url);
$header = array('Accept: application/json'); $header = array('Accept: application/json');
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
@ -137,7 +138,7 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
*/ */
private function getCurl() { private function getCurl() {
$curl = curl_init(); $curl = curl_init();
if ($this->profile->twoFactorAuthenticationInsecure) { if ($this->config->twoFactorAuthenticationInsecure) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
} }
@ -154,7 +155,7 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
*/ */
private function getSerialsForUser($user, $token) { private function getSerialsForUser($user, $token) {
$curl = $this->getCurl(); $curl = $this->getCurl();
$url = $this->profile->twoFactorAuthenticationURL . "/token/?user=" . $user; $url = $this->config->twoFactorAuthenticationURL . "/token/?user=" . $user;
curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_URL, $url);
$header = array('Authorization: ' . $token, 'Accept: application/json'); $header = array('Authorization: ' . $token, 'Accept: application/json');
curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
@ -192,7 +193,7 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
*/ */
private function verify($token, $serial, $twoFactorInput) { private function verify($token, $serial, $twoFactorInput) {
$curl = $this->getCurl(); $curl = $this->getCurl();
$url = $this->profile->twoFactorAuthenticationURL . "/validate/check"; $url = $this->config->twoFactorAuthenticationURL . "/validate/check";
curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_URL, $url);
$options = array( $options = array(
'pass' => $twoFactorInput, 'pass' => $twoFactorInput,
@ -225,15 +226,25 @@ class PrivacyIDEAProvider implements TwoFactorProvider {
*/ */
class TwoFactorProviderService { class TwoFactorProviderService {
private $profile; /** 2factor authentication disabled */
const TWO_FACTOR_NONE = 'none';
/** 2factor authentication via privacyIDEA */
const TWO_FACTOR_PRIVACYIDEA = 'privacyidea';
private $config;
/** /**
* Constructor. * Constructor.
* *
* @param selfServiceProfile $profile profile * @param selfServiceProfile|LAMConfig $configObj profile
*/ */
public function __construct(&$profile) { public function __construct(&$configObj) {
$this->profile = $profile; if ($configObj instanceof selfServiceProfile) {
$this->config = $this->getConfigSelfService($configObj);
}
else {
$this->config = $this->getConfigAdmin($configObj);
}
} }
/** /**
@ -244,10 +255,49 @@ class TwoFactorProviderService {
* @throws \Exception unable to get provider * @throws \Exception unable to get provider
*/ */
public function getProvider() { public function getProvider() {
if ($this->profile->twoFactorAuthentication == selfServiceProfile::TWO_FACTOR_PRIVACYIDEA) { if ($this->config->twoFactorAuthentication == TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA) {
return new PrivacyIDEAProvider($this->profile); return new PrivacyIDEAProvider($this->config);
} }
throw new \Exception('Invalid provider: ' . $this->profile->twoFactorAuthentication); throw new \Exception('Invalid provider: ' . $this->config->twoFactorAuthentication);
}
/**
* Returns the configuration from self service.
*
* @param selfServiceProfile $profile profile
* @return TwoFactorConfiguration configuration
*/
private function getConfigSelfService(&$profile) {
$config = new TwoFactorConfiguration();
$config->twoFactorAuthentication = $profile->twoFactorAuthentication;
$config->twoFactorAuthenticationInsecure = $profile->twoFactorAuthenticationInsecure;
$config->twoFactorAuthenticationURL = $profile->twoFactorAuthenticationURL;
return $config;
}
/**
* Returns the configuration for admin interface.
*
* @param LAMConfig $conf configuration
* @return TwoFactorConfiguration configuration
*/
private function getConfigAdmin($conf) {
$config = new TwoFactorConfiguration();
$config->twoFactorAuthentication = $conf->getTwoFactorAuthentication();
$config->twoFactorAuthenticationInsecure = $conf->getTwoFactorAuthenticationInsecure();
$config->twoFactorAuthenticationURL = $conf->getTwoFactorAuthenticationURL();
return $config;
} }
} }
/**
* Configuration settings for 2-factor authentication.
*
* @author Roland Gruber
*/
class TwoFactorConfiguration {
public $twoFactorAuthentication = null;
public $twoFactorAuthenticationURL = null;
public $twoFactorAuthenticationInsecure = false;
}

View File

@ -1467,6 +1467,22 @@ function validateReCAPTCHA($secretKey) {
return $responseJSON->{'success'} === true; return $responseJSON->{'success'} === true;
} }
/**
* Checks if the user is logged in. Stops script execution if not.
*
* @param boolean $check2ndFactor check if the 2nd factor was provided if required
*/
function enforceUserIsLoggedIn($check2ndFactor = true) {
if (!isset($_SESSION['loggedIn']) || ($_SESSION['loggedIn'] !== true)) {
logNewMessage(LOG_WARNING, 'Detected unauthorized access to page that requires login: ' . $_SERVER["SCRIPT_FILENAME"]);
die();
}
if ($check2ndFactor && isset($_SESSION['2factorRequired'])) {
die();
logNewMessage(LOG_WARNING, 'Detected unauthorized access to page that requires login (2nd factor not provided): ' . $_SERVER["SCRIPT_FILENAME"]);
}
}
class LAMException extends Exception { class LAMException extends Exception {
private $title; private $title;

View File

@ -1,9 +1,10 @@
<?php <?php
use \LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
/* /*
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -31,11 +32,13 @@ $Id$
*/ */
/** Used to print messages. */ /** Used to print messages. */
include_once("status.inc"); include_once "status.inc";
/** Used to get module information. */ /** Used to get module information. */
include_once("modules.inc"); include_once "modules.inc";
/** Used to get type information. */ /** Used to get type information. */
include_once("types.inc"); include_once "types.inc";
/** 2-factor */
include_once '2factor.inc';
/** /**
* Sets the environment variables for custom SSL CA certificates. * Sets the environment variables for custom SSL CA certificates.
@ -567,6 +570,13 @@ class LAMConfig {
/** job configuration */ /** job configuration */
private $jobSettings = array(); private $jobSettings = array();
private $twoFactorAuthentication = TwoFactorProviderService::TWO_FACTOR_NONE;
private $twoFactorAuthenticationURL = 'https://localhost';
private $twoFactorAuthenticationInsecure = false;
private $twoFactorAuthenticationLabel = null;
private $twoFactorAuthenticationOptional = false;
private $twoFactorAuthenticationCaption = '';
/** List of all settings in config file */ /** List of all settings in config file */
private $settings = array("ServerURL", "useTLS", "followReferrals", 'pagedResults', "Passwd", "Admins", "treesuffix", private $settings = array("ServerURL", "useTLS", "followReferrals", 'pagedResults', "Passwd", "Admins", "treesuffix",
"defaultLanguage", "scriptPath", "scriptServer", "scriptRights", "cachetimeout", 'serverDisplayName', "defaultLanguage", "scriptPath", "scriptServer", "scriptRights", "cachetimeout", 'serverDisplayName',
@ -576,7 +586,9 @@ class LAMConfig {
'loginSearchPassword', 'timeZone', 'jobsBindUser', 'jobsBindPassword', 'jobsDatabase', 'jobToken', 'jobs', 'loginSearchPassword', 'timeZone', 'jobsBindUser', 'jobsBindPassword', 'jobsDatabase', 'jobToken', 'jobs',
'jobsDBHost', 'jobsDBPort', 'jobsDBUser', 'jobsDBPassword', 'jobsDBName', 'pwdResetAllowSpecificPassword', 'jobsDBHost', 'jobsDBPort', 'jobsDBUser', 'jobsDBPassword', 'jobsDBName', 'pwdResetAllowSpecificPassword',
'pwdResetAllowScreenPassword', 'pwdResetForcePasswordChange', 'pwdResetDefaultPasswordOutput', 'pwdResetAllowScreenPassword', 'pwdResetForcePasswordChange', 'pwdResetDefaultPasswordOutput',
'scriptUserName', 'scriptSSHKey', 'scriptSSHKeyPassword' 'scriptUserName', 'scriptSSHKey', 'scriptSSHKeyPassword', 'twoFactorAuthentication', 'twoFactorAuthenticationURL',
'twoFactorAuthenticationInsecure', 'twoFactorAuthenticationLabel', 'twoFactorAuthenticationOptional',
'twoFactorAuthenticationCaption'
); );
@ -816,6 +828,12 @@ class LAMConfig {
if (!in_array("pwdResetAllowScreenPassword", $saved)) array_push($file_array, "\n" . "pwdResetAllowScreenPassword: " . $this->pwdResetAllowScreenPassword . "\n"); if (!in_array("pwdResetAllowScreenPassword", $saved)) array_push($file_array, "\n" . "pwdResetAllowScreenPassword: " . $this->pwdResetAllowScreenPassword . "\n");
if (!in_array("pwdResetForcePasswordChange", $saved)) array_push($file_array, "\n" . "pwdResetForcePasswordChange: " . $this->pwdResetForcePasswordChange . "\n"); if (!in_array("pwdResetForcePasswordChange", $saved)) array_push($file_array, "\n" . "pwdResetForcePasswordChange: " . $this->pwdResetForcePasswordChange . "\n");
if (!in_array("pwdResetDefaultPasswordOutput", $saved)) array_push($file_array, "\n" . "pwdResetDefaultPasswordOutput: " . $this->pwdResetDefaultPasswordOutput . "\n"); if (!in_array("pwdResetDefaultPasswordOutput", $saved)) array_push($file_array, "\n" . "pwdResetDefaultPasswordOutput: " . $this->pwdResetDefaultPasswordOutput . "\n");
if (!in_array("twoFactorAuthentication", $saved)) array_push($file_array, "\n" . "twoFactorAuthentication: " . $this->twoFactorAuthentication . "\n");
if (!in_array("twoFactorAuthenticationURL", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationURL: " . $this->twoFactorAuthenticationURL . "\n");
if (!in_array("twoFactorAuthenticationInsecure", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationInsecure: " . $this->twoFactorAuthenticationInsecure . "\n");
if (!in_array("twoFactorAuthenticationLabel", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationLabel: " . $this->twoFactorAuthenticationLabel . "\n");
if (!in_array("twoFactorAuthenticationOptional", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationOptional: " . $this->twoFactorAuthenticationOptional . "\n");
if (!in_array("twoFactorAuthenticationCaption", $saved)) array_push($file_array, "\n" . "twoFactorAuthenticationCaption: " . $this->twoFactorAuthenticationCaption . "\n");
// check if all module settings were added // check if all module settings were added
$m_settings = array_keys($this->moduleSettings); $m_settings = array_keys($this->moduleSettings);
for ($i = 0; $i < sizeof($m_settings); $i++) { for ($i = 0; $i < sizeof($m_settings); $i++) {
@ -2044,6 +2062,116 @@ class LAMConfig {
public function setPwdResetDefaultPasswordOutput($pwdResetDefaultPasswordOutput) { public function setPwdResetDefaultPasswordOutput($pwdResetDefaultPasswordOutput) {
$this->pwdResetDefaultPasswordOutput = $pwdResetDefaultPasswordOutput; $this->pwdResetDefaultPasswordOutput = $pwdResetDefaultPasswordOutput;
} }
/**
* Returns the authentication type.
*
* @return string $twoFactorAuthentication authentication type
*/
public function getTwoFactorAuthentication() {
if (empty($this->twoFactorAuthentication)) {
return TwoFactorProviderService::TWO_FACTOR_NONE;
}
return $this->twoFactorAuthentication;
}
/**
* Sets the authentication type.
*
* @param string $twoFactorAuthentication authentication type
*/
public function setTwoFactorAuthentication($twoFactorAuthentication) {
$this->twoFactorAuthentication = $twoFactorAuthentication;
}
/**
* Returns the authentication URL.
*
* @return string $twoFactorAuthenticationURL authentication URL
*/
public function getTwoFactorAuthenticationURL() {
return $this->twoFactorAuthenticationURL;
}
/**
* Sets the authentication URL.
*
* @param string $twoFactorAuthenticationURL authentication URL
*/
public function setTwoFactorAuthenticationURL($twoFactorAuthenticationURL) {
$this->twoFactorAuthenticationURL = $twoFactorAuthenticationURL;
}
/**
* Returns if SSL certificate verification is turned off.
*
* @return bool $twoFactorAuthenticationInsecure SSL certificate verification is turned off
*/
public function getTwoFactorAuthenticationInsecure() {
return $this->twoFactorAuthenticationInsecure;
}
/**
* Sets if SSL certificate verification is turned off.
*
* @param boolean $twoFactorAuthenticationInsecure SSL certificate verification is turned off
*/
public function setTwoFactorAuthenticationInsecure($twoFactorAuthenticationInsecure) {
$this->twoFactorAuthenticationInsecure = $twoFactorAuthenticationInsecure;
}
/**
* Returns the authentication label.
*
* @return string $twoFactorAuthenticationLabel authentication label
*/
public function getTwoFactorAuthenticationLabel() {
return $this->twoFactorAuthenticationLabel;
}
/**
* Sets the authentication label.
*
* @param string $twoFactorAuthenticationLabel authentication label
*/
public function setTwoFactorAuthenticationLabel($twoFactorAuthenticationLabel) {
$this->twoFactorAuthenticationLabel = $twoFactorAuthenticationLabel;
}
/**
* Returns if 2nd factor is optional.
*
* @return bool $twoFactorAuthenticationOptional 2nd factor is optional
*/
public function getTwoFactorAuthenticationOptional() {
return $this->twoFactorAuthenticationOptional;
}
/**
* Sets if 2nd factor is optional.
*
* @param boolean $twoFactorAuthenticationOptional 2nd factor is optional
*/
public function setTwoFactorAuthenticationOptional($twoFactorAuthenticationOptional) {
$this->twoFactorAuthenticationOptional = $twoFactorAuthenticationOptional;
}
/**
* Returns the caption HTML.
*
* @return string $twoFactorAuthenticationCaption caption HTML
*/
public function getTwoFactorAuthenticationCaption() {
return $this->twoFactorAuthenticationCaption;
}
/**
* Sets the caption HTML.
*
* @param string $twoFactorAuthenticationCaption caption HTML
*/
public function setTwoFactorAuthenticationCaption($twoFactorAuthenticationCaption) {
$this->twoFactorAuthenticationCaption = $twoFactorAuthenticationCaption;
}
} }

View File

@ -1,4 +1,5 @@
<?PHP <?php
use \LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
/* /*
$Id$ $Id$
@ -31,9 +32,11 @@ $Id$
*/ */
/** modules */ /** modules */
include_once("modules.inc"); include_once "modules.inc";
/** account types */ /** account types */
include_once("types.inc"); include_once "types.inc";
/** 2-factor */
include_once '2factor.inc';
/** /**
* Returns if this is a LAM Pro installation. * Returns if this is a LAM Pro installation.
@ -302,11 +305,6 @@ function isSelfService() {
*/ */
class selfServiceProfile { class selfServiceProfile {
/** 2factor authentication disabled */
const TWO_FACTOR_NONE = 'none';
/** 2factor authentication via privacyIDEA */
const TWO_FACTOR_PRIVACYIDEA = 'privacyidea';
/** server address */ /** server address */
public $serverURL; public $serverURL;
@ -381,7 +379,7 @@ class selfServiceProfile {
public $timeZone = 'Europe/London'; public $timeZone = 'Europe/London';
public $twoFactorAuthentication = selfServiceProfile::TWO_FACTOR_NONE; public $twoFactorAuthentication = TwoFactorProviderService::TWO_FACTOR_NONE;
public $twoFactorAuthenticationURL = 'https://localhost'; public $twoFactorAuthenticationURL = 'https://localhost';
public $twoFactorAuthenticationInsecure = false; public $twoFactorAuthenticationInsecure = false;
public $twoFactorAuthenticationLabel = null; public $twoFactorAuthenticationLabel = null;
@ -425,7 +423,7 @@ class selfServiceProfile {
$this->enforceLanguage = true; $this->enforceLanguage = true;
$this->followReferrals = 0; $this->followReferrals = 0;
$this->timeZone = 'Europe/London'; $this->timeZone = 'Europe/London';
$this->twoFactorAuthentication = selfServiceProfile::TWO_FACTOR_NONE; $this->twoFactorAuthentication = TwoFactorProviderService::TWO_FACTOR_NONE;
$this->twoFactorAuthenticationURL = 'https://localhost'; $this->twoFactorAuthenticationURL = 'https://localhost';
$this->twoFactorAuthenticationInsecure = false; $this->twoFactorAuthenticationInsecure = false;
$this->twoFactorAuthenticationLabel = null; $this->twoFactorAuthenticationLabel = null;

View File

@ -21,6 +21,7 @@ function app_session_start() {
include_once '../../../../lib/config.inc'; include_once '../../../../lib/config.inc';
include_once '../../../../lib/ldap.inc'; include_once '../../../../lib/ldap.inc';
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
$config_file = CONFDIR.'config.php'; $config_file = CONFDIR.'config.php';
$config = check_config($config_file); $config = check_config($config_file);
# If we came via index.php, then set our $config. # If we came via index.php, then set our $config.

View File

@ -4,7 +4,7 @@ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2006 Tilo Lutz Copyright (C) 2003 - 2006 Tilo Lutz
2005 - 2016 Roland Gruber 2005 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -47,6 +47,7 @@ include_once('../../lib/modules.inc');
// Start session // Start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// Redirect to startpage if user is not loged in // Redirect to startpage if user is not loged in
if (!isLoggedIn()) { if (!isLoggedIn()) {

View File

@ -1,9 +1,10 @@
<?php <?php
use \LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
/* /*
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -37,6 +38,8 @@ include_once("../../lib/config.inc");
include_once("../../lib/modules.inc"); include_once("../../lib/modules.inc");
/** access to tools */ /** access to tools */
include_once("../../lib/tools.inc"); include_once("../../lib/tools.inc");
/** 2-factor */
include_once '../../lib/2facto.inc';
// start session // start session
if (strtolower(session_module_name()) == 'files') { if (strtolower(session_module_name()) == 'files') {
@ -523,8 +526,40 @@ $searchPasswordInput->setIsPassword(true);
$securitySettingsContent->addElement($searchPasswordInput, true); $securitySettingsContent->addElement($searchPasswordInput, true);
// HTTP authentication // HTTP authentication
$securitySettingsContent->addElement(new htmlTableExtendedInputCheckbox('httpAuthentication', ($conf->getHttpAuthentication() == 'true'), _('HTTP authentication'), '223', true), true); $securitySettingsContent->addElement(new htmlTableExtendedInputCheckbox('httpAuthentication', ($conf->getHttpAuthentication() == 'true'), _('HTTP authentication'), '223', true), true);
$securitySettingsContent->addElement(new htmlSpacer(null, '10px'), true); $securitySettingsContent->addElement(new htmlSpacer(null, '30px'), true);
// 2factor authentication
if (extension_loaded('curl')) {
$securitySettingsContent->addElement(new htmlSubTitle(_("2-factor authentication")), true);
$twoFactorOptions = array(
_('None') => TwoFactorProviderService::TWO_FACTOR_NONE,
_('privacyIDEA') => TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA,
);
$twoFactorSelect = new htmlTableExtendedSelect('twoFactor', $twoFactorOptions, array($conf->getTwoFactorAuthentication()), _('Provider'), '514');
$twoFactorSelect->setHasDescriptiveElements(true);
$twoFactorSelect->setTableRowsToHide(array(
TwoFactorProviderService::TWO_FACTOR_NONE => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel', 'twoFactorOptional', 'twoFactorCaption')
));
$twoFactorSelect->setTableRowsToShow(array(
TwoFactorProviderService::TWO_FACTOR_PRIVACYIDEA => array('twoFactorURL', 'twoFactorInsecure', 'twoFactorLabel', 'twoFactorOptional', 'twoFactorCaption')
));
$securitySettingsContent->addElement($twoFactorSelect, true);
$twoFactorUrl = new htmlTableExtendedInputField(_("Base URL"), 'twoFactorURL', $conf->getTwoFactorAuthenticationURL(), '515');
$twoFactorUrl->setRequired(true);
$securitySettingsContent->addElement($twoFactorUrl, true);
$twoFactorLabel = new htmlTableExtendedInputField(_("Label"), 'twoFactorLabel', $conf->getTwoFactorAuthenticationLabel(), '517');
$securitySettingsContent->addElement($twoFactorLabel, true);
$securitySettingsContent->addElement(new htmlTableExtendedInputCheckbox('twoFactorOptional', $conf->getTwoFactorAuthenticationOptional(), _('Optional'), '519'), true);
$securitySettingsContent->addElement(new htmlTableExtendedInputCheckbox('twoFactorInsecure', $conf->getTwoFactorAuthenticationInsecure(), _('Disable certificate check'), '516'), true);
$securitySettingsContent->addElement(new htmlSpacer(null, '5px'), true);
$twoFactorCaption = new htmlTableExtendedInputTextarea('twoFactorCaption', $conf->getTwoFactorAuthenticationCaption(), '80', '4', _("Caption"), '518');
$twoFactorCaption->setIsRichEdit(true);
$twoFactorCaption->alignment = htmlElement::ALIGN_TOP;
$securitySettingsContent->addElement($twoFactorCaption, true);
}
// new password // new password
$securitySettingsContent->addElement(new htmlSubTitle(_("Profile password")), true);
$password1 = new htmlTableExtendedInputField(_("New password"), 'passwd1', null, '212'); $password1 = new htmlTableExtendedInputField(_("New password"), 'passwd1', null, '212');
$password1->setIsPassword(true); $password1->setIsPassword(true);
$password2 = new htmlTableExtendedInputField(_("Reenter password"), 'passwd2'); $password2 = new htmlTableExtendedInputField(_("Reenter password"), 'passwd2');
@ -551,10 +586,12 @@ $buttonContainer->addElement($cancelButton, true);
$buttonContainer->addElement(new htmlSpacer(null, '10px'), true); $buttonContainer->addElement(new htmlSpacer(null, '10px'), true);
parseHtml(null, $buttonContainer, array(), false, $tabindex, 'user'); parseHtml(null, $buttonContainer, array(), false, $tabindex, 'user');
echo "</form>\n"; ?>
echo "</body>\n"; </form>
echo "</html>\n"; <script type="text/javascript" src="../lib/extra/ckeditor/ckeditor.js"></script>
</body>
</html>
<?php
/** /**
* Checks user input and saves the entered settings. * Checks user input and saves the entered settings.
@ -711,6 +748,15 @@ function checkInput() {
} }
} }
$conf->setToolSettings($toolSettings); $conf->setToolSettings($toolSettings);
// 2-factor
if (extension_loaded('curl')) {
$conf->setTwoFactorAuthentication($_POST['twoFactor']);
$conf->setTwoFactorAuthenticationURL($_POST['twoFactorURL']);
$conf->setTwoFactorAuthenticationInsecure(isset($_POST['twoFactorInsecure']) && ($_POST['twoFactorInsecure'] == 'on'));
$conf->setTwoFactorAuthenticationLabel($_POST['twoFactorLabel']);
$conf->setTwoFactorAuthenticationOptional(isset($_POST['twoFactorOptional']) && ($_POST['twoFactorOptional'] == 'on'));
$conf->setTwoFactorAuthenticationCaption(str_replace(array("\r", "\n"), array('', ''), $_POST['twoFactorCaption']));
}
// check if password was changed // check if password was changed
if (isset($_POST['passwd1']) && ($_POST['passwd1'] != '')) { if (isset($_POST['passwd1']) && ($_POST['passwd1'] != '')) {
if ($_POST['passwd1'] != $_POST['passwd2']) { if ($_POST['passwd1'] != $_POST['passwd2']) {

View File

@ -49,6 +49,7 @@ include_once('../lib/modules.inc');
// Start session // Start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
if (!checkIfWriteAccessIsAllowed()) { if (!checkIfWriteAccessIsAllowed()) {
die(); die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2015 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ include_once("../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
if (!checkIfWriteAccessIsAllowed()) { if (!checkIfWriteAccessIsAllowed()) {
die(); die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2007 - 2013 Roland Gruber Copyright (C) 2007 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ include_once("../../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -38,6 +38,7 @@ include_once("../../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2010 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ include_once("../../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -1,4 +1,6 @@
<?php <?php
use LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
/* /*
$Id$ $Id$
@ -324,6 +326,14 @@ function display_LoginPage($config_object, $cfgMain) {
StatusMessage("INFO", _("Your settings were successfully saved."), htmlspecialchars($_GET['selfserviceSaveOk'])); StatusMessage("INFO", _("Your settings were successfully saved."), htmlspecialchars($_GET['selfserviceSaveOk']));
echo "<br>"; echo "<br>";
} }
if (isset($_GET['2factor']) && ($_GET['2factor'] == 'error')) {
StatusMessage('ERROR', _("Unable to start 2-factor authentication."));
echo "<br>";
}
elseif (isset($_GET['2factor']) && ($_GET['2factor'] == 'noToken')) {
StatusMessage('ERROR', _("Unable to start 2-factor authentication because no tokens were found."));
echo "<br>";
}
if (!empty($config_object)) { if (!empty($config_object)) {
?> ?>
<br><br> <br><br>
@ -636,8 +646,20 @@ if(!empty($_POST['checklogin'])) {
addSecurityTokenToSession(); addSecurityTokenToSession();
// logging // logging
logNewMessage(LOG_NOTICE, 'User ' . $username . ' (' . $clientSource . ') successfully logged in.'); logNewMessage(LOG_NOTICE, 'User ' . $username . ' (' . $clientSource . ') successfully logged in.');
// Load main frame // Load main frame or 2 factor page
if ($_SESSION['config']->getTwoFactorAuthentication() == TwoFactorProviderService::TWO_FACTOR_NONE) {
metaRefresh("./main.php"); metaRefresh("./main.php");
}
else {
$_SESSION['2factorRequired'] = true;
if (($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) && ($_SESSION['config']->getHttpAuthentication() == 'true')) {
$_SESSION['user2factor'] = $_SERVER['PHP_AUTH_USER'];
}
else {
$_SESSION['user2factor'] = $_POST['username'];
}
metaRefresh("./login2Factor.php");
}
die(); die();
} }
else { else {

View File

@ -0,0 +1,241 @@
<?php
namespace LAM\LOGIN;
use \LAM\LIB\TWO_FACTOR\TwoFactorProviderService;
use \htmlResponsiveRow;
use \htmlGroup;
use \htmlOutputText;
use \htmlSpacer;
use \htmlSelect;
use \htmlInputField;
use \htmlButton;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2017 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
*/
/**
* This page redirects to the correct start page after checking 2nd factor.
*
* @package main
* @author Roland Gruber
*/
/** config object */
include_once '../lib/config.inc';
// start session
startSecureSession();
setlanguage();
$config = $_SESSION['config'];
$ldap = $_SESSION['ldap'];
$credentials = $ldap->decrypt_login();
$password = $credentials[1];
$user = $_SESSION['user2factor'];
if (get_preg($user, 'dn')) {
$user = extractRDNValue($user);
}
// get serials
try {
$service = new TwoFactorProviderService($config);
$provider = $service->getProvider();
$serials = $provider->getSerials($user, $password);
}
catch (\Exception $e) {
logNewMessage(LOG_ERR, 'Unable to get 2-factor serials for ' . $user . ' ' . $e->getMessage());
metaRefresh("login.php?2factor=error");
die();
}
$twoFactorLabel = empty($config->getTwoFactorAuthenticationLabel()) ? _('PIN+Token') : $config->getTwoFactorAuthenticationLabel();
if (sizeof($serials) == 0) {
if ($config->getTwoFactorAuthenticationOptional()) {
unset($_SESSION['2factorRequired']);
unset($_SESSION['user2factor']);
metaRefresh("main.php");
die();
}
else {
metaRefresh("login.php?2factor=noToken");
die();
}
}
if (isset($_POST['logout'])) {
// destroy session
session_destroy();
unset($_SESSION);
// redirect to login page
metaRefresh("login.php");
exit();
}
if (isset($_POST['submit'])) {
$twoFactorInput = $_POST['2factor'];
$serial = $_POST['serial'];
if (empty($twoFactorInput) || !in_array($serial, $serials)) {
$errorMessage = _(sprintf('Please enter "%s".', $twoFactorLabel));
}
else {
$twoFactorValid = false;
try {
$twoFactorValid = $provider->verify2ndFactor($user, $password, $serial, $twoFactorInput);
}
catch (\Exception $e) {
logNewMessage(LOG_WARNING, '2-factor verification failed: ' . $e->getMessage());
}
if ($twoFactorValid) {
unset($_SESSION['2factorRequired']);
unset($_SESSION['user2factor']);
metaRefresh("main.php");
die();
}
else {
$errorMessage = _(sprintf('Verification failed.', $twoFactorLabel));
}
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html class="no-js">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<title><?php echo _("Login"); ?></title>
<link rel="stylesheet" type="text/css" href="../style/responsive/105_normalize.css">
<link rel="stylesheet" type="text/css" href="../style/responsive/110_foundation.css">
<?php
// include all CSS files
$cssDirName = dirname(__FILE__) . '/../style';
$cssDir = dir($cssDirName);
$cssFiles = array();
$cssEntry = $cssDir->read();
while ($cssEntry !== false) {
if (substr($cssEntry, strlen($cssEntry) - 4, 4) == '.css') {
$cssFiles[] = $cssEntry;
}
$cssEntry = $cssDir->read();
}
sort($cssFiles);
foreach ($cssFiles as $cssEntry) {
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"../style/" . $cssEntry . "\">\n";
}
if (isset($profile->additionalCSS) && ($profile->additionalCSS != '')) {
$CSSlinks = explode("\n", $profile->additionalCSS);
for ($i = 0; $i < sizeof($CSSlinks); $i++) {
$CSSlinks[$i] = trim($CSSlinks[$i]);
if ($CSSlinks[$i] == '') {
continue;
}
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $CSSlinks[$i] . "\">\n";
}
}
?>
</head>
<body class="admin">
<?php
// include all JavaScript files
$jsDirName = dirname(__FILE__) . '/lib';
$jsDir = dir($jsDirName);
$jsFiles = array();
while ($jsEntry = $jsDir->read()) {
if (substr($jsEntry, strlen($jsEntry) - 3, 3) != '.js') continue;
$jsFiles[] = $jsEntry;
}
sort($jsFiles);
foreach ($jsFiles as $jsEntry) {
echo "<script type=\"text/javascript\" src=\"lib/" . $jsEntry . "\"></script>\n";
}
?>
<script type="text/javascript" src="lib/extra/responsive/200_modernizr.js"></script>
<script type="text/javascript" src="lib/extra/responsive/250_foundation.js"></script>
<table border=0 width="100%" class="lamHeader ui-corner-all">
<tr>
<td align="left" height="30">
<a class="lamLogo" href="http://www.ldap-account-manager.org/" target="new_window">LDAP Account Manager</a>
</td>
<td align="right" height=20>
</td>
</tr>
</table>
<br><br>
<form enctype="multipart/form-data" action="login2Factor.php" method="post" autocomplete="off">
<?php
echo $config->getTwoFactorAuthenticationCaption();
?>
<div class="centeredTable">
<div class="roundedShadowBox limitWidth">
<?php
$group = new htmlGroup();
$row = new htmlResponsiveRow();
// error
if (!empty($errorMessage)) {
$row->add(new \htmlStatusMessage('ERROR', $errorMessage), 12);
$row->add(new htmlSpacer('1em', '1em'), 12);
}
// serial
$row->add(new htmlOutputText(_('Serial number')), 12, 12, 12, 'text-left');
$serialSelect = new htmlSelect('serial', $serials);
$row->add($serialSelect, 12);
// token
$row->add(new htmlOutputText($twoFactorLabel), 12, 12, 12, 'text-left');
$twoFactorInput = new htmlInputField('2factor', '');
$twoFactorInput->setFieldSize(null);
$twoFactorInput->setIsPassword(true);
$row->add($twoFactorInput, 12);
$row->add(new htmlSpacer('1em', '1em'), 12);
$submit = new htmlButton('submit', _("Submit"));
$submit->setCSSClasses(array('fullwidth'));
$row->add($submit, 12, 12, 12, 'fullwidth');
$row->add(new htmlSpacer('0.5em', '0.5em'), 12);
$logout = new htmlButton('logout', _("Cancel"));
$logout->setCSSClasses(array('fullwidth'));
$row->add($logout, 12);
$group->addElement($row);
$tabindex = 1;
addSecurityTokenToMetaHTML($group);
parseHtml(null, $group, array(), false, $tabindex, 'user');
?>
</div>
</div>
</form>
<br><br>
<script type="text/javascript">
$(document).foundation();
myElement = document.getElementsByName('2factor')[0];
myElement.focus();
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2006 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -44,6 +44,7 @@ include_once("../lib/ldap.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// log message // log message
$ldapUser = $_SESSION['ldap']->decrypt_login(); $ldapUser = $_SESSION['ldap']->decrypt_login();

View File

@ -4,7 +4,7 @@ namespace LAM\INIT;
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -36,6 +36,7 @@ include_once '../lib/profiles.inc';
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -63,6 +63,7 @@ class lamAjax {
validateSecurityToken(false); validateSecurityToken(false);
if (isset($_GET['module']) && isset($_GET['scope']) && in_array($_GET['module'], getAvailableModules($_GET['scope']))) { if (isset($_GET['module']) && isset($_GET['scope']) && in_array($_GET['module'], getAvailableModules($_GET['scope']))) {
enforceUserIsLoggedIn();
if (isset($_GET['useContainer']) && ($_GET['useContainer'] == '1')) { if (isset($_GET['useContainer']) && ($_GET['useContainer'] == '1')) {
if (!isset($_SESSION['account'])) die(); if (!isset($_SESSION['account'])) die();
$module = $_SESSION['account']->getAccountModule($_GET['module']); $module = $_SESSION['account']->getAccountModule($_GET['module']);
@ -82,12 +83,13 @@ class lamAjax {
} }
$jsonInput = $_POST['jsonInput']; $jsonInput = $_POST['jsonInput'];
if ($function == 'passwordStrengthCheck') {
lamAjax::checkPasswordStrength($jsonInput);
}
enforceUserIsLoggedIn();
if ($function == 'passwordChange') { if ($function == 'passwordChange') {
lamAjax::managePasswordChange($jsonInput); lamAjax::managePasswordChange($jsonInput);
} }
elseif ($function == 'passwordStrengthCheck') {
lamAjax::checkPasswordStrength($jsonInput);
}
elseif ($function == 'upload') { elseif ($function == 'upload') {
include_once('../../lib/upload.inc'); include_once('../../lib/upload.inc');
$typeManager = new \LAM\TYPES\TypeManager(); $typeManager = new \LAM\TYPES\TypeManager();

View File

@ -21,7 +21,7 @@ use \htmlInputTextarea;
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2013 - 2016 Roland Gruber Copyright (C) 2013 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -57,6 +57,7 @@ include_once("../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -50,6 +50,7 @@ include_once("../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -15,13 +15,12 @@ use \htmlInputFileUpload;
use \htmlHelpLink; use \htmlHelpLink;
use \htmlInputField; use \htmlInputField;
use \htmlHiddenInput; use \htmlHiddenInput;
use \htmlDiv;
/* /*
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2006 Michael Duergner Copyright (C) 2003 - 2006 Michael Duergner
2005 - 2016 Roland Gruber 2005 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -60,6 +59,7 @@ include_once("../../lib/modules.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -19,7 +19,7 @@ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2006 Michael Duergner Copyright (C) 2003 - 2006 Michael Duergner
2007 - 2016 Roland Gruber 2007 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -62,6 +62,7 @@ include_once('../../lib/xml_parser.inc');
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -18,7 +18,7 @@ use \htmlInputField;
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -54,6 +54,7 @@ include_once("../../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -12,7 +12,7 @@ use \htmlHiddenInput;
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2016 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -52,6 +52,7 @@ include_once("../../lib/status.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
Copyright (C) 2004 David Smith Copyright (C) 2004 David Smith
modified to fit for LDAP Account Manager 2005 - 2012 Roland Gruber modified to fit for LDAP Account Manager 2005 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -42,6 +42,7 @@ require_once("../../lib/schema.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
checkIfToolIsActive('toolSchemaBrowser'); checkIfToolIsActive('toolSchemaBrowser');

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2009 - 2012 Roland Gruber Copyright (C) 2009 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@ include_once("../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
checkIfToolIsActive('toolServerInformation'); checkIfToolIsActive('toolServerInformation');

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2006 - 2012 Roland Gruber Copyright (C) 2006 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@ include_once("../../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2006 - 2016 Roland Gruber Copyright (C) 2006 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -36,6 +36,7 @@ include_once("../../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2007 - 2016 Roland Gruber Copyright (C) 2007 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ include_once("../../lib/schema.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// die if no write access // die if no write access
if (!checkIfWriteAccessIsAllowed()) die(); if (!checkIfWriteAccessIsAllowed()) die();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2011 Roland Gruber Copyright (C) 2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -37,6 +37,7 @@ include_once("../lib/tools.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -3,7 +3,7 @@
$Id$ $Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2010 - 2011 Roland Gruber Copyright (C) 2010 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -36,6 +36,7 @@ include_once("../../lib/config.inc");
// start session // start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
setlanguage(); setlanguage();

View File

@ -48,6 +48,7 @@ include_once('../../lib/modules.inc');
// Start session // Start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// check if this tool may be run // check if this tool may be run
checkIfToolIsActive('toolFileUpload'); checkIfToolIsActive('toolFileUpload');

View File

@ -45,6 +45,7 @@ include_once('../../lib/pdf.inc');
// Start session // Start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// check if this tool may be run // check if this tool may be run
checkIfToolIsActive('toolFileUpload'); checkIfToolIsActive('toolFileUpload');

View File

@ -62,6 +62,7 @@ include_once('../../lib/upload.inc');
// Start session // Start session
startSecureSession(); startSecureSession();
enforceUserIsLoggedIn();
// check if this tool may be run // check if this tool may be run
checkIfToolIsActive('toolFileUpload'); checkIfToolIsActive('toolFileUpload');

1
lam/tmp/.gitignore vendored
View File

@ -1 +0,0 @@
/*.jpg