2016-01-21 21:33:15 +01:00
< ? php
/*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
/**
* libreNMS HTTP-Authentication and LDAP Authorization Library
* @author Maximilian Wilhelm <max@rfc2324.org>
* @copyright 2016 LibreNMS, Barbarossa
* @license GPL
* @package LibreNMS
* @subpackage Authentication
*
* This Authentitation / Authorization module provides the ability to let
* the webserver (e.g. Apache) do the user Authentication (using Kerberos
* f.e.) and let libreNMS do the Authorization of the already known user.
* Authorization and setting of libreNMS user level is done by LDAP group
* names specified in the configuration file. The group configuration is
* basicly copied from the existing ldap Authentication module.
*
* Most of the code is copied from the http-auth and ldap Authentication
* modules already existing.
*
* To save lots of redundant queries to the LDAP server and speed up the
* libreNMS WebUI, all information is cached within the PHP $_SESSION as
* long as specified in $config['auth_ldap_cache_ttl'] (Default: 300s).
*/
2017-05-15 22:18:23 -05:00
use LibreNMS\Exceptions\AuthenticationException ;
2017-07-03 15:38:58 -05:00
function init_auth ()
{
global $ldap_connection , $config ;
2016-01-21 21:33:15 +01:00
2017-07-03 15:38:58 -05:00
if ( ! isset ( $_SESSION [ 'username' ])) {
$_SESSION [ 'username' ] = '' ;
}
2016-01-21 21:33:15 +01:00
2017-07-03 15:38:58 -05:00
/**
* Set up connection to LDAP server
*/
$ldap_connection = @ ldap_connect ( $config [ 'auth_ldap_server' ], $config [ 'auth_ldap_port' ]);
if ( ! $ldap_connection ) {
echo '<h2>Fatal error while connecting to LDAP server ' . $config [ 'auth_ldap_server' ] . ':' . $config [ 'auth_ldap_port' ] . ': ' . ldap_error ( $ldap_connection ) . '</h2>' ;
2016-01-21 21:33:15 +01:00
exit ;
}
2017-07-03 15:38:58 -05:00
if ( $config [ 'auth_ldap_version' ]) {
ldap_set_option ( $ldap_connection , LDAP_OPT_PROTOCOL_VERSION , $config [ 'auth_ldap_version' ]);
}
if ( $config [ 'auth_ldap_starttls' ] && ( $config [ 'auth_ldap_starttls' ] == 'optional' || $config [ 'auth_ldap_starttls' ] == 'require' )) {
$tls = ldap_start_tls ( $ldap_connection );
if ( $config [ 'auth_ldap_starttls' ] == 'require' && $tls === false ) {
echo '<h2>Fatal error: LDAP TLS required but not successfully negotiated:' . ldap_error ( $ldap_connection ) . '</h2>' ;
exit ;
}
}
2016-01-21 21:33:15 +01:00
}
2016-08-18 20:28:22 -05:00
function authenticate ( $username , $password )
{
2016-01-21 21:33:15 +01:00
global $config ;
2016-08-18 20:28:22 -05:00
if ( isset ( $_SERVER [ 'REMOTE_USER' ])) {
$_SESSION [ 'username' ] = mres ( $_SERVER [ 'REMOTE_USER' ]);
2016-01-21 21:33:15 +01:00
2016-08-18 20:28:22 -05:00
if ( user_exists ( $_SESSION [ 'username' ])) {
2017-05-15 22:18:23 -05:00
return true ;
2016-01-21 21:33:15 +01:00
}
$_SESSION [ 'username' ] = $config [ 'http_auth_guest' ];
2017-05-15 22:18:23 -05:00
return true ;
2016-01-21 21:33:15 +01:00
}
2017-05-15 22:18:23 -05:00
throw new AuthenticationException ();
2016-01-21 21:33:15 +01:00
}
2016-09-13 15:10:42 +01:00
2017-05-15 22:18:23 -05:00
function reauthenticate ( $sess_id , $token )
2016-09-13 15:10:42 +01:00
{
2017-05-15 22:18:23 -05:00
return false ;
2016-09-13 15:10:42 +01:00
}
2016-08-18 20:28:22 -05:00
function passwordscanchange ( $username = '' )
{
2016-01-21 21:33:15 +01:00
// Not supported
return 0 ;
}
2016-08-18 20:28:22 -05:00
function changepassword ( $username , $newpassword )
{
2016-01-21 21:33:15 +01:00
// Not supported
return 0 ;
}
2016-08-18 20:28:22 -05:00
function auth_usermanagement ()
{
2016-01-21 21:33:15 +01:00
// Not supported
return 0 ;
}
2017-04-01 16:18:00 -05:00
function adduser ( $username , $password , $level , $email = '' , $realname = '' , $can_modify_passwd = 1 , $description = '' )
2016-08-18 20:28:22 -05:00
{
2016-01-21 21:33:15 +01:00
// Not supported
return false ;
}
2016-08-18 20:28:22 -05:00
function user_exists ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2016-01-21 21:33:15 +01:00
2016-08-18 20:28:22 -05:00
if ( auth_ldap_session_cache_get ( 'user_exists' )) {
2016-01-21 21:33:15 +01:00
return 1 ;
2016-08-18 20:28:22 -05:00
}
2016-01-21 21:33:15 +01:00
$filter = '(' . $config [ 'auth_ldap_prefix' ] . $username . ')' ;
2016-08-18 20:28:22 -05:00
$search = ldap_search ( $ldap_connection , trim ( $config [ 'auth_ldap_suffix' ], ',' ), $filter );
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-01-21 21:33:15 +01:00
if ( $entries [ 'count' ]) {
/*
* Cache positiv result as this will result in more queries which we
* want to speed up.
*/
2016-08-18 20:28:22 -05:00
auth_ldap_session_cache_set ( 'user_exists' , 1 );
2016-01-21 21:33:15 +01:00
return 1 ;
}
/*
* Don't cache that user doesn't exists as this might be a misconfiguration
* on some end and the user will be happy if it "just works" after the user
* has been added to LDAP.
*/
return 0 ;
}
2016-08-18 20:28:22 -05:00
function get_userlevel ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2016-01-21 21:33:15 +01:00
2016-08-18 20:28:22 -05:00
$userlevel = auth_ldap_session_cache_get ( 'userlevel' );
2016-01-21 21:33:15 +01:00
if ( $userlevel ) {
return $userlevel ;
} else {
$userlevel = 0 ;
}
// Find all defined groups $username is in
2016-08-18 20:28:22 -05:00
$filter = '(&(|(cn=' . join ( ')(cn=' , array_keys ( $config [ 'auth_ldap_groups' ])) . '))(' . $config [ 'auth_ldap_groupmemberattr' ] . '=' . get_membername ( $username ) . '))' ;
$search = ldap_search ( $ldap_connection , $config [ 'auth_ldap_groupbase' ], $filter );
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-01-21 21:33:15 +01:00
// Loop the list and find the highest level
foreach ( $entries as $entry ) {
$groupname = $entry [ 'cn' ][ 0 ];
if ( $config [ 'auth_ldap_groups' ][ $groupname ][ 'level' ] > $userlevel ) {
$userlevel = $config [ 'auth_ldap_groups' ][ $groupname ][ 'level' ];
}
}
2016-08-18 20:28:22 -05:00
auth_ldap_session_cache_set ( 'userlevel' , $userlevel );
2016-01-21 21:33:15 +01:00
return $userlevel ;
}
2016-08-18 20:28:22 -05:00
function get_userid ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2016-01-21 21:33:15 +01:00
2016-08-18 20:28:22 -05:00
$user_id = auth_ldap_session_cache_get ( 'userid' );
if ( isset ( $user_id )) {
2016-01-21 21:33:15 +01:00
return $user_id ;
} else {
$user_id = - 1 ;
}
$filter = '(' . $config [ 'auth_ldap_prefix' ] . $username . ')' ;
2016-08-18 20:28:22 -05:00
$search = ldap_search ( $ldap_connection , trim ( $config [ 'auth_ldap_suffix' ], ',' ), $filter );
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-01-21 21:33:15 +01:00
if ( $entries [ 'count' ]) {
$user_id = $entries [ 0 ][ 'uidnumber' ][ 0 ];
}
2016-08-18 20:28:22 -05:00
auth_ldap_session_cache_set ( 'userid' , $user_id );
2016-01-21 21:33:15 +01:00
return $user_id ;
}
2016-08-18 20:28:22 -05:00
function deluser ( $username )
{
2016-01-21 21:33:15 +01:00
// Not supported
return 0 ;
}
2016-08-18 20:28:22 -05:00
function get_userlist ()
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2016-01-21 21:33:15 +01:00
$userlist = array ();
$filter = '(' . $config [ 'auth_ldap_prefix' ] . '*)' ;
2016-08-18 20:28:22 -05:00
$search = ldap_search ( $ldap_connection , trim ( $config [ 'auth_ldap_suffix' ], ',' ), $filter );
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-01-21 21:33:15 +01:00
if ( $entries [ 'count' ]) {
foreach ( $entries as $entry ) {
$username = $entry [ 'uid' ][ 0 ];
$realname = $entry [ 'cn' ][ 0 ];
$user_id = $entry [ 'uidnumber' ][ 0 ];
$email = $entry [ $config [ 'auth_ldap_emailattr' ]][ 0 ];
2016-08-18 20:28:22 -05:00
$ldap_groups = get_group_list ();
2016-01-21 21:33:15 +01:00
foreach ( $ldap_groups as $ldap_group ) {
$ldap_comparison = ldap_compare (
2016-06-03 10:56:42 -05:00
$ldap_connection ,
2016-01-21 21:33:15 +01:00
$ldap_group ,
$config [ 'auth_ldap_groupmemberattr' ],
get_membername ( $username )
);
2016-08-18 20:28:22 -05:00
if ( ! isset ( $config [ 'auth_ldap_group' ]) || $ldap_comparison === true ) {
2016-01-21 21:33:15 +01:00
$userlist [] = array (
'username' => $username ,
'realname' => $realname ,
'user_id' => $user_id ,
'email' => $email ,
);
}
}
}
}
return $userlist ;
}
2016-08-18 20:28:22 -05:00
function can_update_users ()
{
2016-01-21 21:33:15 +01:00
// not supported
return 0 ;
}
2016-08-18 20:28:22 -05:00
function get_user ( $user_id )
{
2016-03-10 14:48:01 +01:00
foreach ( get_userlist () as $users ) {
2016-08-18 20:28:22 -05:00
if ( $users [ 'user_id' ] === $user_id ) {
return $users [ 'username' ];
}
2016-03-10 14:48:01 +01:00
}
2016-01-21 21:33:15 +01:00
return 0 ;
}
2016-08-18 20:28:22 -05:00
function update_user ( $user_id , $realname , $level , $can_modify_passwd , $email )
{
2016-01-21 21:33:15 +01:00
// Not supported
return 0 ;
}
2016-08-18 20:28:22 -05:00
function get_membername ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2016-01-21 21:33:15 +01:00
if ( $config [ 'auth_ldap_groupmembertype' ] == 'fulldn' ) {
$membername = $config [ 'auth_ldap_prefix' ] . $username . $config [ 'auth_ldap_suffix' ];
2016-08-18 20:28:22 -05:00
} elseif ( $config [ 'auth_ldap_groupmembertype' ] == 'puredn' ) {
2016-01-21 21:33:15 +01:00
$filter = '(' . $config [ 'auth_ldap_attr' ][ 'uid' ] . '=' . $username . ')' ;
2016-06-03 10:56:42 -05:00
$search = ldap_search ( $ldap_connection , $config [ 'auth_ldap_groupbase' ], $filter );
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-01-21 21:33:15 +01:00
$membername = $entries [ 0 ][ 'dn' ];
2016-08-18 20:28:22 -05:00
} else {
2016-01-21 21:33:15 +01:00
$membername = $username ;
}
return $membername ;
}
2016-08-18 20:28:22 -05:00
function auth_ldap_session_cache_get ( $attr )
{
2016-01-21 21:33:15 +01:00
global $config ;
$ttl = 300 ;
2016-08-18 20:28:22 -05:00
if ( $config [ 'auth_ldap_cache_ttl' ]) {
2016-01-21 21:33:15 +01:00
$ttl = $config [ 'auth_ldap_cache_ttl' ];
2016-08-18 20:28:22 -05:00
}
2016-01-21 21:33:15 +01:00
// auth_ldap cache present in this session?
2016-08-18 20:28:22 -05:00
if ( ! isset ( $_SESSION [ 'auth_ldap' ])) {
return null ;
}
2016-01-21 21:33:15 +01:00
$cache = $_SESSION [ 'auth_ldap' ];
// $attr present in cache?
2016-08-18 20:28:22 -05:00
if ( ! isset ( $cache [ $attr ])) {
return null ;
}
2016-01-21 21:33:15 +01:00
// Value still valid?
2016-08-18 20:28:22 -05:00
if ( time () - $cache [ $attr ][ 'last_updated' ] >= $ttl ) {
return null ;
}
2016-01-21 21:33:15 +01:00
$cache [ $attr ][ 'value' ];
}
2016-08-18 20:28:22 -05:00
function auth_ldap_session_cache_set ( $attr , $value )
{
2016-01-21 21:33:15 +01:00
$_SESSION [ 'auth_ldap' ][ $attr ][ 'value' ] = $value ;
2016-08-18 20:28:22 -05:00
$_SESSION [ 'auth_ldap' ][ $attr ][ 'last_updated' ] = time ();
2016-01-21 21:33:15 +01:00
}
2017-08-01 16:16:52 -04:00
function get_group_list ()
{
global $config ;
$ldap_groups = array ();
$default_group = 'cn=groupname,ou=groups,dc=example,dc=com' ;
if ( isset ( $config [ 'auth_ldap_group' ])) {
if ( $config [ 'auth_ldap_group' ] !== $default_group ) {
$ldap_groups [] = $config [ 'auth_ldap_group' ];
}
}
foreach ( $config [ 'auth_ldap_groups' ] as $key => $value ) {
$dn = " cn= $key , " . $config [ 'auth_ldap_groupbase' ];
$ldap_groups [] = $dn ;
}
return $ldap_groups ;
}