1<?php 2/* 3 * $Id: ActiveDirectory.php 501 2013-07-11 17:44:37Z imooreyahoo@gmail.com $ 4* Experimental! 5*/ 6class phpvbAuthActiveDirectory implements phpvbAuth { 7 8 var $capabilities = array( 9 'canChangePassword' => false, 10 'canLogout' => true 11 ); 12 13 var $config = array( 14 'host' => '127.0.0.1', 15 'admin_group' => null, 16 'adminUser' => null, 17 'user_group' => null, 18 'container' => 'CN=Users', 19 'domain' => 'internal.local', 20 'filter' => '(&(objectclass=User)(objectCategory=Person))' 21 ); 22 23 /** 24 * Constructor 25 * @param array $userConfig - user configuration for this module 26 */ 27 function phpvbAuthActiveDirectory($userConfig = null) { 28 // Merge user config 29 if($userConfig) { 30 $this->config = array_merge($this->config,$userConfig); 31 } 32 } 33 34 /** 35 * Test log in and set $_SESSION vars 36 * @param string $username 37 * @param string $password 38 * @see phpvbAuth::login() 39 */ 40 function login($username, $password) 41 { 42 global $_SESSION; 43 44 45 /* 46 * Check for LDAP functionality and provide some direction 47 */ 48 if(!function_exists('ldap_connect')) { 49 50 $ex = 'LDAP support is not enabled in your PHP configuration.'; 51 52 if(strtolower(substr(PHP_OS, 0, 3)) == 'win') { 53 54 ob_start(); 55 phpinfo(INFO_GENERAL); 56 $phpinfo = ob_get_contents(); 57 ob_end_clean(); 58 preg_match('/Loaded Configuration File <\/td><td.*?>(.*?)\s*</', $phpinfo, $phpinfo); 59 60 $ex .= ' You probably just need to uncomment the line ;extension=php_ldap.dll in php.ini'. 61 (count($phpinfo) > 1 ? ' (' .trim($phpinfo[1]).')' : '') . ' by removing the ";" and restart your web server.'; 62 63 } else if(strtolower(substr(PHP_OS, 0, 5)) == 'Linux') { 64 65 $ex .= ' You probably need to install the php5-ldap (or similar depending on your distribution) package and restart your web server.'; 66 67 } 68 throw new Exception($ex); 69 } 70 71 $_SESSION['valid'] = false; 72 73 // Connect to server 74 if(!($auth = ldap_connect($this->config['host']))) { 75 throw new Exception('Active Directory error ('.ldap_errno($auth).') ' . ldap_error($auth)); 76 } 77 78 // Set relevant LDAP options 79 ldap_set_option($auth,LDAP_OPT_PROTOCOL_VERSION, 3); 80 81 82 // Main login /bind 83 if(!($bind = @ldap_bind($auth, $username . "@" .$this->config['domain'], $password))) { 84 if(ldap_errno($auth) == 49) return false; 85 throw new Exception('Active Directory error ('.ldap_errno($auth).') ' . ldap_error($auth)); 86 } 87 88 89 // Get user information from AD 90 //////////////////////////////////// 91 92 93 // Set filter and sanitize username before sending it to AD 94 $filter = "(sAMAccountName=" . 95 str_replace(array(',','=','+','<','>',';','\\','"','#','(',')','*',chr(0)), '', $username) . ")"; 96 if($this->config['filter'] && false) { 97 $filter = '(&'. $this->config['filter'] .' ('. $filter .'))'; 98 } 99 100 $result = @ldap_search($auth, 101 $this->config['container'] . ',DC=' . join(',DC=', explode('.', $this->config['domain'])), 102 $filter, array("memberof","useraccountcontrol")); 103 104 if(!result) throw new Exception ("Unable to search Active Directory server: " . ldap_error($auth)); 105 @list($entries) = @ldap_get_entries($auth, $result); 106 @ldap_unbind($auth); 107 if(!$entries) { 108 throw new Exception("Permission denied"); 109 } 110 111 112 // Check for disabled user 113 if((intval($entries['useraccountcontrol'][0]) & 2)) { 114 throw new Exception('This account is disabled in Active Directory.'); 115 } 116 117 // check for valid admin group 118 if($this->config['admin_group']) { 119 foreach($entries['memberof'] as $group) { 120 list($group) = explode(',', $group); 121 if(strtolower($group) == strtolower('cn='.$this->config['admin_group'])) { 122 $_SESSION['admin'] = $_SESSION['valid'] = true; 123 break; 124 } 125 } 126 } 127 128 // Admin user explicitly set? 129 if(!$_SESSION['admin'] && $this->config['adminUser']) { 130 $_SESSION['admin'] = (strtolower($this->config['adminUser']) == strtolower($username)); 131 // Admin is ok 132 $_SESSION['valid'] = ($_SESSION['admin'] || $_SESSION['valid']); 133 } 134 135 // check for valid user group 136 if($this->config['user_group'] && !$_SESSION['valid']) { 137 foreach($entries['memberof'] as $group) { 138 list($group) = explode(',', $group); 139 if(strtolower($group) == strtolower('cn='.$this->config['user_group'])) { 140 $_SESSION['valid'] = true; 141 break; 142 } 143 } 144 } else { 145 $_SESSION['valid'] = true; 146 } 147 148 if(!$_SESSION['valid']) 149 throw new Exception("Permission denied"); 150 151 // Admin user explicitly set? 152 if(!$_SESSION['admin'] && $this->config['adminUser']) { 153 $_SESSION['admin'] = (strtolower($this->config['adminUser']) == strtolower($username)); 154 } 155 156 // No admin information specified makes everyone an admin 157 if(!$this->config['adminUser'] && !$this->config['admin_group']) 158 $_SESSION['admin'] = true; 159 160 // user has permission. establish session variables 161 $_SESSION['user'] = $username; 162 $_SESSION['authCheckHeartbeat'] = time(); 163 164 165 return true; 166 167 } 168 169 function heartbeat($vbox) 170 { 171 global $_SESSION; 172 173 $_SESSION['valid'] = true; 174 $_SESSION['authCheckHeartbeat'] = time(); 175 } 176 177 function changePassword($old, $new) 178 { 179 } 180 181 function logout(&$response) 182 { 183 global $_SESSION; 184 if(function_exists('session_destroy')) session_destroy(); 185 else unset($_SESSION['valid']); 186 $response['data']['result'] = 1; 187 } 188 189 function listUsers() 190 { 191 192 } 193 194 function updateUser($vboxRequest, $skipExistCheck) 195 { 196 197 } 198 199 function deleteUser($user) 200 { 201 202 } 203} 204