2015-10-16 09:40:17 +02:00
< ? php
// easier to rewrite for Active Directory than to bash it into existing LDAP implementation
2015-11-13 11:05:05 -06:00
// disable certificate checking before connect if required
2015-11-16 10:24:16 +01:00
if ( isset ( $config [ 'auth_ad_check_certificates' ]) &&
2016-09-09 08:04:03 -05:00
! $config [ 'auth_ad_check_certificates' ]) {
2015-11-13 11:05:05 -06:00
putenv ( 'LDAPTLS_REQCERT=never' );
};
2016-09-09 08:04:03 -05:00
if ( isset ( $config [ 'auth_ad_debug' ]) && $config [ 'auth_ad_debug' ]) {
ldap_set_option ( null , LDAP_OPT_DEBUG_LEVEL , 7 );
}
2016-06-03 10:56:42 -05:00
$ldap_connection = @ ldap_connect ( $config [ 'auth_ad_url' ]);
2015-10-16 09:40:17 +02:00
// disable referrals and force ldap version to 3
2016-06-03 10:56:42 -05:00
ldap_set_option ( $ldap_connection , LDAP_OPT_REFERRALS , 0 );
ldap_set_option ( $ldap_connection , LDAP_OPT_PROTOCOL_VERSION , 3 );
2015-10-16 09:40:17 +02:00
2016-08-18 20:28:22 -05:00
function authenticate ( $username , $password )
{
2016-09-09 08:04:03 -05:00
global $config , $ldap_connection , $auth_error ;
2015-10-16 09:40:17 +02:00
2016-06-03 10:56:42 -05:00
if ( $ldap_connection ) {
2015-10-16 09:40:17 +02:00
// bind with sAMAccountName instead of full LDAP DN
2016-06-03 10:56:42 -05:00
if ( $username && ldap_bind ( $ldap_connection , " { $username } @ { $config [ 'auth_ad_domain' ] } " , $password )) {
2015-10-30 17:17:55 +01:00
// group membership in one of the configured groups is required
if ( isset ( $config [ 'auth_ad_require_groupmembership' ]) &&
2016-09-09 08:04:03 -05:00
$config [ 'auth_ad_require_groupmembership' ]) {
2016-08-18 20:28:22 -05:00
$search = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_user_filter ( $username ),
2016-08-18 20:28:22 -05:00
array ( 'memberOf' )
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-09-15 02:46:26 -05:00
unset ( $entries [ 0 ][ 'memberof' ][ 'count' ]); //remove the annoying count
2015-10-30 17:17:55 +01:00
foreach ( $entries [ 0 ][ 'memberof' ] as $entry ) {
$group_cn = get_cn ( $entry );
if ( isset ( $config [ 'auth_ad_groups' ][ $group_cn ][ 'level' ])) {
// user is in one of the defined groups
2015-11-16 13:37:12 +01:00
adduser ( $username );
2016-09-09 08:04:03 -05:00
return 1 ;
2016-08-18 20:28:22 -05:00
}
2015-10-30 17:17:55 +01:00
}
2016-09-09 08:04:03 -05:00
if ( isset ( $config [ 'auth_ad_debug' ]) && $config [ 'auth_ad_debug' ]) {
if ( $entries [ 'count' ] == 0 ) {
$auth_error = 'No groups found for user, check base dn' ;
} else {
$auth_error = 'User is not in one of the required groups' ;
}
} else {
$auth_error = 'Invalid credentials' ;
}
return 0 ;
2016-08-18 20:28:22 -05:00
} else {
2015-10-30 17:17:55 +01:00
// group membership is not required and user is valid
2015-11-16 13:37:12 +01:00
adduser ( $username );
2015-10-30 17:17:55 +01:00
return 1 ;
2015-11-10 10:39:42 +01:00
}
2015-10-16 09:40:17 +02:00
}
2016-09-09 08:04:03 -05:00
}
if ( isset ( $config [ 'auth_ad_debug' ]) && $config [ 'auth_ad_debug' ]) {
ldap_get_option ( $ldap_connection , LDAP_OPT_DIAGNOSTIC_MESSAGE , $extended_error );
$auth_error = ldap_error ( $ldap_connection ) . '<br />' . $extended_error ;
2016-08-18 20:28:22 -05:00
} else {
2016-09-09 08:04:03 -05:00
$auth_error = ldap_error ( $ldap_connection );
2015-10-16 09:40:17 +02:00
}
return 0 ;
}
2016-09-13 15:10:42 +01:00
function reauthenticate ()
{
// not supported so return 0
return 0 ;
}
2016-08-18 20:28:22 -05:00
function passwordscanchange ()
{
2015-10-22 09:16:20 +02:00
// not supported so return 0
2015-10-16 09:40:17 +02:00
return 0 ;
}
2016-08-18 20:28:22 -05:00
function changepassword ()
{
2015-10-22 09:16:20 +02:00
// not supported so return 0
2015-10-16 09:40:17 +02:00
return 0 ;
}
2016-08-18 20:28:22 -05:00
function auth_usermanagement ()
{
2015-10-22 09:16:20 +02:00
// not supported so return 0
2015-10-16 09:40:17 +02:00
return 0 ;
}
2016-08-18 20:28:22 -05:00
function adduser ( $username , $level = 0 , $email = '' , $realname = '' , $can_modify_passwd = 0 , $description = '' , $twofactor = 0 )
{
2015-11-16 13:37:12 +01:00
// Check to see if user is already added in the database
if ( ! user_exists_in_db ( $username )) {
2016-01-19 22:27:04 +00:00
$userid = dbInsert ( array ( 'username' => $username , 'realname' => $realname , 'email' => $email , 'descr' => $description , 'level' => $level , 'can_modify_passwd' => $can_modify_passwd , 'twofactor' => $twofactor , 'user_id' => get_userid ( $username )), 'users' );
2015-11-21 12:25:34 +00:00
if ( $userid == false ) {
return false ;
2016-08-18 20:28:22 -05:00
} else {
foreach ( dbFetchRows ( 'select notifications.* from notifications where not exists( select 1 from notifications_attribs where notifications.notifications_id = notifications_attribs.notifications_id and notifications_attribs.user_id = ?) order by notifications.notifications_id desc' , array ( $userid )) as $notif ) {
dbInsert ( array ( 'notifications_id' => $notif [ 'notifications_id' ], 'user_id' => $userid , 'key' => 'read' , 'value' => 1 ), 'notifications_attribs' );
2015-11-21 12:25:34 +00:00
}
}
return $userid ;
2016-08-18 20:28:22 -05:00
} else {
2015-11-16 13:37:12 +01:00
return false ;
}
2015-10-16 09:40:17 +02:00
}
2016-08-18 20:28:22 -05:00
function user_exists_in_db ( $username )
{
2015-11-17 12:28:28 +01:00
$return = dbFetchCell ( 'SELECT COUNT(*) FROM users WHERE username = ?' , array ( $username ), true );
2015-11-16 13:37:12 +01:00
return $return ;
}
2015-10-16 09:40:17 +02:00
2016-08-18 20:28:22 -05:00
function user_exists ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2015-10-16 09:40:17 +02:00
2016-08-18 20:28:22 -05:00
$search = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_user_filter ( $username ),
2016-08-18 20:28:22 -05:00
array ( 'samaccountname' )
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $search );
2015-10-16 09:40:17 +02:00
if ( $entries [ 'count' ]) {
return 1 ;
}
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 ;
2015-10-16 09:40:17 +02:00
$userlevel = 0 ;
// Find all defined groups $username is in
2016-08-18 20:28:22 -05:00
$search = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_user_filter ( $username ),
2016-08-18 20:28:22 -05:00
array ( 'memberOf' )
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $search );
2016-09-15 02:46:26 -05:00
unset ( $entries [ 0 ][ 'memberof' ][ 'count' ]);
2015-10-16 09:40:17 +02:00
// Loop the list and find the highest level
foreach ( $entries [ 0 ][ 'memberof' ] as $entry ) {
$group_cn = get_cn ( $entry );
2016-09-15 02:46:26 -05:00
if ( isset ( $config [ 'auth_ad_groups' ][ $group_cn ][ 'level' ]) &&
$config [ 'auth_ad_groups' ][ $group_cn ][ 'level' ] > $userlevel ) {
2015-10-16 09:40:17 +02:00
$userlevel = $config [ 'auth_ad_groups' ][ $group_cn ][ 'level' ];
}
}
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 ;
2015-10-16 09:40:17 +02:00
$attributes = array ( 'objectsid' );
2016-08-18 20:28:22 -05:00
$search = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_user_filter ( $username ),
2016-08-18 20:28:22 -05:00
$attributes
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $search );
2015-10-16 09:40:17 +02:00
if ( $entries [ 'count' ]) {
2016-08-18 20:28:22 -05:00
return preg_replace ( '/.*-(\d+)$/' , '$1' , sid_from_ldap ( $entries [ 0 ][ 'objectsid' ][ 0 ]));
2015-10-16 09:40:17 +02:00
}
return - 1 ;
}
2016-08-18 20:28:22 -05:00
function deluser ( $username )
{
2016-01-17 15:26:35 +00:00
dbDelete ( 'bill_perms' , '`user_name` = ?' , array ( $username ));
dbDelete ( 'devices_perms' , '`user_name` = ?' , array ( $username ));
dbDelete ( 'ports_perms' , '`user_name` = ?' , array ( $username ));
dbDelete ( 'users_prefs' , '`user_name` = ?' , array ( $username ));
dbDelete ( 'users' , '`user_name` = ?' , array ( $username ));
return dbDelete ( 'users' , '`username` = ?' , array ( $username ));
2015-10-16 09:40:17 +02:00
}
2016-08-18 20:28:22 -05:00
function get_userlist ()
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2015-10-16 09:40:17 +02:00
$userlist = array ();
2015-11-10 10:03:47 +01:00
$userhash = array ();
2015-10-16 09:40:17 +02:00
$ldap_groups = get_group_list ();
2016-08-18 20:28:22 -05:00
foreach ( $ldap_groups as $ldap_group ) {
2016-09-21 13:42:59 -06:00
$search_filter = " (memberOf= $ldap_group ) " ;
if ( $config [ 'auth_ad_user_filter' ]) {
$search_filter = " (& { $config [ 'auth_ad_user_filter' ] } $search_filter ) " ;
}
$search = ldap_search ( $ldap_connection , $config [ 'auth_ad_base_dn' ], $search_filter , array ( 'samaccountname' , 'displayname' , 'objectsid' , 'mail' ));
$results = ldap_get_entries ( $ldap_connection , $search );
foreach ( $results as $result ) {
if ( isset ( $result [ 'samaccountname' ][ 0 ])) {
$userid = preg_replace (
'/.*-(\d+)$/' ,
'$1' ,
sid_from_ldap ( $result [ 'objectsid' ][ 0 ])
);
// don't make duplicates, user may be member of more than one group
$userhash [ $result [ 'samaccountname' ][ 0 ]] = array (
'realname' => $result [ 'displayName' ][ 0 ],
'user_id' => $userid ,
'email' => $result [ 'mail' ][ 0 ]
);
2015-10-16 09:40:17 +02:00
}
}
}
2016-08-18 20:28:22 -05:00
foreach ( array_keys ( $userhash ) as $key ) {
2015-10-16 09:40:17 +02:00
$userlist [] = array (
'username' => $key ,
'realname' => $userhash [ $key ][ 'realname' ],
'user_id' => $userhash [ $key ][ 'user_id' ],
'email' => $userhash [ $key ][ 'email' ]
);
}
return $userlist ;
}
2016-08-18 20:28:22 -05:00
function can_update_users ()
{
2015-10-16 09:40:17 +02:00
// not supported so return 0
return 0 ;
}
2016-08-18 20:28:22 -05:00
function get_user ( $user_id )
{
2015-10-16 09:40:17 +02:00
// not supported so return 0
2016-01-17 15:26:35 +00:00
return dbFetchRow ( 'SELECT * FROM `users` WHERE `user_id` = ?' , array ( $user_id ), true );
2015-10-16 09:40:17 +02:00
}
2016-08-18 20:28:22 -05:00
function update_user ( $user_id , $realname , $level , $can_modify_passwd , $email )
{
2016-01-17 15:26:35 +00:00
dbUpdate ( array ( 'realname' => $realname , 'can_modify_passwd' => $can_modify_passwd , 'email' => $email ), 'users' , '`user_id` = ?' , array ( $user_id ));
2015-10-16 09:40:17 +02:00
}
2016-08-18 20:28:22 -05:00
function get_fullname ( $username )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2015-10-16 09:40:17 +02:00
$attributes = array ( 'name' );
2016-08-18 20:28:22 -05:00
$result = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_user_filter ( $username ),
2016-08-18 20:28:22 -05:00
$attributes
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $result );
2015-10-16 09:40:17 +02:00
if ( $entries [ 'count' ] > 0 ) {
$membername = $entries [ 0 ][ 'name' ][ 0 ];
2016-08-18 20:28:22 -05:00
} else {
2015-10-16 09:40:17 +02:00
$membername = $username ;
}
return $membername ;
}
2016-08-18 20:28:22 -05:00
function get_group_list ()
{
2015-10-16 09:40:17 +02:00
global $config ;
$ldap_groups = array ();
// show all Active Directory Users by default
$default_group = 'Users' ;
if ( isset ( $config [ 'auth_ad_group' ])) {
if ( $config [ 'auth_ad_group' ] !== $default_group ) {
$ldap_groups [] = $config [ 'auth_ad_group' ];
}
}
if ( ! isset ( $config [ 'auth_ad_groups' ]) && ! isset ( $config [ 'auth_ad_group' ])) {
$ldap_groups [] = get_dn ( $default_group );
}
foreach ( $config [ 'auth_ad_groups' ] as $key => $value ) {
$ldap_groups [] = get_dn ( $key );
}
return $ldap_groups ;
}
2016-08-18 20:28:22 -05:00
function get_dn ( $samaccountname )
{
2016-06-03 10:56:42 -05:00
global $config , $ldap_connection ;
2015-10-16 09:40:17 +02:00
$attributes = array ( 'dn' );
2016-08-18 20:28:22 -05:00
$result = ldap_search (
$ldap_connection ,
$config [ 'auth_ad_base_dn' ],
2016-09-21 13:42:59 -06:00
get_auth_ad_group_filter ( $samaccountname ),
2016-08-18 20:28:22 -05:00
$attributes
);
2016-06-03 10:56:42 -05:00
$entries = ldap_get_entries ( $ldap_connection , $result );
2015-10-16 09:40:17 +02:00
if ( $entries [ 'count' ] > 0 ) {
return $entries [ 0 ][ 'dn' ];
2016-08-18 20:28:22 -05:00
} else {
2015-10-16 09:40:17 +02:00
return '' ;
}
}
2016-08-18 20:28:22 -05:00
function get_cn ( $dn )
{
$dn = str_replace ( '\\,' , '~C0mmA~' , $dn );
2015-10-16 09:40:17 +02:00
preg_match ( '/[^,]*/' , $dn , $matches , PREG_OFFSET_CAPTURE , 3 );
2016-09-15 02:46:26 -05:00
return str_replace ( '~C0mmA~' , ',' , $matches [ 0 ][ 0 ]);
2015-10-16 09:40:17 +02:00
}
function sid_from_ldap ( $sid )
{
2016-09-15 02:46:26 -05:00
$sidUnpacked = unpack ( 'H*hex' , $sid );
$sidHex = array_shift ( $sidUnpacked );
2016-08-18 20:28:22 -05:00
$subAuths = unpack ( 'H2/H2/n/N/V*' , $sid );
2015-10-16 09:40:17 +02:00
$revLevel = hexdec ( substr ( $sidHex , 0 , 2 ));
2016-08-18 20:28:22 -05:00
$authIdent = hexdec ( substr ( $sidHex , 4 , 12 ));
2015-10-16 09:40:17 +02:00
return 'S-' . $revLevel . '-' . $authIdent . '-' . implode ( '-' , $subAuths );
}