1<?php 2 3namespace LibreNMS\Authentication; 4 5use LibreNMS\Config; 6use LibreNMS\Exceptions\AuthenticationException; 7use LibreNMS\Exceptions\LdapMissingException; 8 9class ADAuthorizationAuthorizer extends MysqlAuthorizer 10{ 11 use LdapSessionCache; 12 use ActiveDirectoryCommon; 13 14 protected static $AUTH_IS_EXTERNAL = true; 15 protected static $CAN_UPDATE_PASSWORDS = false; 16 17 protected $ldap_connection; 18 19 public function __construct() 20 { 21 if (! function_exists('ldap_connect')) { 22 throw new LdapMissingException(); 23 } 24 25 // Disable certificate checking before connect if required 26 if (Config::has('auth_ad_check_certificates') && 27 Config::get('auth_ad_check_certificates') == 0) { 28 putenv('LDAPTLS_REQCERT=never'); 29 } 30 31 // Set up connection to LDAP server 32 $this->ldap_connection = @ldap_connect(Config::get('auth_ad_url')); 33 if (! $this->ldap_connection) { 34 throw new AuthenticationException('Fatal error while connecting to AD url ' . Config::get('auth_ad_url') . ': ' . ldap_error($this->ldap_connection)); 35 } 36 37 // disable referrals and force ldap version to 3 38 ldap_set_option($this->ldap_connection, LDAP_OPT_REFERRALS, 0); 39 ldap_set_option($this->ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3); 40 41 // Bind to AD 42 if (Config::has('auth_ad_binduser') && Config::has('auth_ad_bindpassword')) { 43 // With specified bind user 44 if (! ldap_bind($this->ldap_connection, Config::get('auth_ad_binduser') . '@' . Config::get('auth_ad_domain'), Config::get('auth_ad_bindpassword'))) { 45 echo ldap_error($this->ldap_connection); 46 } 47 } else { 48 // Anonymous 49 if (! ldap_bind($this->ldap_connection)) { 50 echo ldap_error($this->ldap_connection); 51 } 52 } 53 } 54 55 public function authenticate($credentials) 56 { 57 if (isset($credentials['username']) && $this->userExists($credentials['username'])) { 58 return true; 59 } 60 61 if (Config::get('http_auth_guest')) { 62 return true; 63 } 64 65 throw new AuthenticationException(); 66 } 67 68 public function userExists($username, $throw_exception = false) 69 { 70 if ($this->authLdapSessionCacheGet('user_exists')) { 71 return true; 72 } 73 74 $search = ldap_search( 75 $this->ldap_connection, 76 Config::get('auth_ad_base_dn'), 77 $this->userFilter($username), 78 ['samaccountname'] 79 ); 80 $entries = ldap_get_entries($this->ldap_connection, $search); 81 82 if ($entries['count']) { 83 /* 84 * Cache positiv result as this will result in more queries which we 85 * want to speed up. 86 */ 87 $this->authLdapSessionCacheSet('user_exists', 1); 88 89 return true; 90 } 91 92 return false; 93 } 94 95 public function getUserlevel($username) 96 { 97 $userlevel = $this->authLdapSessionCacheGet('userlevel'); 98 if ($userlevel) { 99 return $userlevel; 100 } else { 101 $userlevel = 0; 102 } 103 104 // Find all defined groups $username is in 105 $search = ldap_search( 106 $this->ldap_connection, 107 Config::get('auth_ad_base_dn'), 108 $this->userFilter($username), 109 ['memberOf'] 110 ); 111 $entries = ldap_get_entries($this->ldap_connection, $search); 112 113 // Loop the list and find the highest level 114 foreach ($entries[0]['memberof'] as $entry) { 115 $group_cn = $this->getCn($entry); 116 $auth_ad_groups = Config::get('auth_ad_groups'); 117 if ($auth_ad_groups[$group_cn]['level'] > $userlevel) { 118 $userlevel = $auth_ad_groups[$group_cn]['level']; 119 } 120 } 121 122 $this->authLdapSessionCacheSet('userlevel', $userlevel); 123 124 return $userlevel; 125 } 126 127 public function getUserid($username) 128 { 129 $user_id = $this->authLdapSessionCacheGet('userid'); 130 if (isset($user_id)) { 131 return $user_id; 132 } else { 133 $user_id = -1; 134 } 135 136 $attributes = ['objectsid']; 137 $search = ldap_search( 138 $this->ldap_connection, 139 Config::get('auth_ad_base_dn'), 140 $this->userFilter($username), 141 $attributes 142 ); 143 $entries = ldap_get_entries($this->ldap_connection, $search); 144 145 if ($entries['count']) { 146 $user_id = $this->getUseridFromSid($this->sidFromLdap($entries[0]['objectsid'][0])); 147 } 148 149 $this->authLdapSessionCacheSet('userid', $user_id); 150 151 return $user_id; 152 } 153 154 protected function getConnection() 155 { 156 return $this->ldap_connection; 157 } 158} 159