public function getOption($name) { if (!@ldap_get_option($this->connection, ConnectionOptions::getOption($name), $ret)) { throw new LdapException(sprintf('Could not retrieve value for option "%s".', $name)); } return $ret; }
/** * Gets current value set for an option * * @param int $option Ldap option name * * @return mixed value set for the option * * @throws OptionException if option cannot be retrieved */ public function getOption($option) { $value = null; if (!@ldap_get_option($this->connection, $option, $value)) { $code = @ldap_errno($this->connection); throw new OptionException(sprintf('Could not retrieve option %s value: Ldap Error Code=%s - %s', $option, $code, ldap_err2str($code)), $code); } return $value; }
/** * @Route("enrolarverificar/") * @Template() */ public function enrolarverificarAction(Request $request) { $em = $this->getDoctrine()->getManager(); $Dominio = 'municipiorg.gob.ar'; $Usuario = $request->get('_username'); $Contrasena = $request->get('_password'); $Documento = str_replace(array('.', ' ', '-', ','), '', $request->get('_documento')); if (!$Documento || !$Usuario || !$Contrasena) { $this->get('session')->getFlashBag()->add('danger', 'Por favor escriba los datos solicitados.'); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } $Persona = $em->getRepository('YacareBaseBundle:Persona')->findBy(array('DocumentoNumero' => $Documento)); if (count($Persona) < 1) { $this->get('session')->getFlashBag()->add('danger', 'No se encuentra una persona relacionada al DNI Nº ' . $Documento . ' en la base de datos.'); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } else { if (count($Persona) > 1) { $this->get('session')->getFlashBag()->add('danger', 'Hay más de una persona asociada al DNI Nº ' . $Documento . ' en la base de datos.'); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } } $Persona = $Persona[0]; $IdAgente = $Persona->getAgenteId(); if (!$IdAgente) { $this->get('session')->getFlashBag()->add('danger', 'No se encuentra un agente municipal relacionado al DNI Nº ' . $Documento . '.'); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } if ($IdAgente) { $Agente = $em->getRepository('YacareRecursosHumanosBundle:Agente')->find($IdAgente); if (!$Agente) { $this->get('session')->getFlashBag()->add('warning', 'No se encuentra un agente municipal relacionado al DNI Nº ' . $Documento); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } } $ServidorAd = \ldap_connect('192.168.100.44'); ldap_set_option($ServidorAd, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ServidorAd, LDAP_OPT_REFERRALS, 0); $UsrBind = @\ldap_bind($ServidorAd, $Usuario . '@' . $Dominio, $Contrasena); if ($UsrBind) { return array('agente' => $Agente, 'usuario' => $Usuario, 'contrasena' => $Contrasena, 'documento' => $Documento); } else { $extended_error = ''; if (ldap_get_option($ServidorAd, LDAP_OPT_ERROR_STRING, $extended_error)) { echo "Error Binding to LDAP: {$extended_error}"; } else { echo "Error Binding to LDAP: No additional information is available."; } $this->get('session')->getFlashBag()->add('danger', 'No se puede conectar con la cuenta proporcionada. Verifique el nombre de usuario y la contraseña.'); return $this->redirect($this->generateUrl('yacare_munirg_ldap_enrolarinicio')); } }
function authenticate($username, $password) { global $config, $ldap_connection, $auth_error; if ($ldap_connection) { // bind with sAMAccountName instead of full LDAP DN if ($username && $password && ldap_bind($ldap_connection, "{$username}@{$config['auth_ad_domain']}", $password)) { // group membership in one of the configured groups is required if (isset($config['auth_ad_require_groupmembership']) && $config['auth_ad_require_groupmembership']) { $search = ldap_search($ldap_connection, $config['auth_ad_base_dn'], get_auth_ad_user_filter($username), array('memberOf')); $entries = ldap_get_entries($ldap_connection, $search); unset($entries[0]['memberof']['count']); //remove the annoying count 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 adduser($username); return 1; } } 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; } else { // group membership is not required and user is valid adduser($username); return 1; } } } if (!isset($password) || $password == '') { $auth_error = "A password is required"; } elseif (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; } else { $auth_error = ldap_error($ldap_connection); } return 0; }
public function authenticate($ps_username, $ps_password = '', $pa_options = null) { $vo_bind = $this->bindToDirectory($ps_username, $ps_password); if (!$vo_bind) { if (ldap_get_option($this->getLinkIdentifier(), 0x32, $extended_error)) { $vs_bind_rdn = $this->getProcessedConfigValue("ldap_bind_rdn_format", $ps_username, "", ""); caLogEvent("ERR", "LDAP ERROR (" . ldap_errno($this->getLinkIdentifier()) . ") {$extended_error} [{$vs_bind_rdn}]", "OpenLDAP::Authenticate"); } return false; } // check group membership if (!$this->hasRequiredGroupMembership($ps_username)) { return false; } // user role and group membership syncing with directory $this->syncWithDirectory($ps_username); return true; }
function getOption($option) { $ret = ''; switch ($option) { case 'sid': $ret = $this->sid; break; case 'version': $ret = -1; ldap_get_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $ret); break; case 'name': $ret = $this->name; break; case 'port': $ret = $this->port; break; case 'tls': $ret = $this->tls; break; case 'encrypted': $ret = $this->encrypted; break; case 'user_attr': $ret = isset($this->user_attr) ? $this->user_attr : NULL; break; case 'attr_filter': $ret = isset($this->attr_filter) ? $this->attr_filter : NULL; break; case 'basedn': $ret = isset($this->basedn) ? $this->basedn : NULL; break; case 'mail_attr': $ret = isset($this->mail_attr) ? $this->mail_attr : NULL; break; case 'binddn': $ret = isset($this->binddn) ? $this->binddn : NULL; break; case 'bindpw': $ret = isset($this->bindpw) ? $this->bindpw : NULL; break; } return $ret; }
public static function getLdapData($userLogin) { //Соединяемся с каталогом global $app; $ldapconn = ldap_connect($app->ldap->addr); //Выставляем опции ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0); ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_get_option($ldapconn, LDAP_OPT_ERROR_STRING, $err); //авторизуемся в каталоге $ldap_bind = ldap_bind($ldapconn, $app->ldap->uname, $app->ldap->pass); //ищем в каталоге $reslultsrh = ldap_search($ldapconn, 'dc=ab,dc=SRB,dc=local ', "(samaccountname={$userLogin}*)", array("cn", "userprincipalname", "telephonenumber")); $get_Res = ldap_get_entries($ldapconn, $reslultsrh); $res = array(); @($res['cn'] = $get_Res['0']['cn']['0']); @($res['userprincipalname'] = $get_Res['0']['userprincipalname']['0']); @($res['telephonenumber'] = $get_Res['0']['telephonenumber']['0']); ldap_unbind($ldapconn); return $res; }
public function __construct(Ldap $link, $result = null) { $this->result = $result; if (is_resource($result)) { // Get the status code, matched DN and referrals from the response ldap_parse_result($link->resource(), $result, $this->code, $this->matchedDN, $this->message, $this->referrals); // Get the string representation of the status code $this->message = ldap_err2str($this->code); // Extract the data from the resource $this->data = ldap_get_entries($link->resource(), $result); $this->data = $this->cleanup_result($this->data); // Remove the referrals array if there's nothing inside count($this->referrals) == 0 && ($this->referrals = null); // Try to extract pagination cookie and estimated number of objects to be returned // Since there's no way to tell if pagination has been enabled or not, I am suppressing php errors @ldap_control_paged_result_response($link->resource(), $result, $this->cookie, $this->estimated); } else { $this->code = ldap_errno($link->resource()); $this->message = ldap_error($link->resource()); } // Active Directory conceals some additional error codes in the ErrorMessage of the response // that we cannot get to with ldap_errno() in authentication failures - let's try to // extract them! if ($this->code == 49) { $message = null; ldap_get_option($link->resource(), Option::ErrorString, $message); if (stripos($message, 'AcceptSecurityContext') !== false) { $message = explode(', ', $message); end($message); $message = prev($message); $this->code = explode(' ', $message)[1]; // For compatibility reasons with standard ldap, if the error code // is 52e let's replace it with 49 ( their meanings are equal, it's just // Microsoft doing it its own way again ) if ($this->code == '52e') { $this->code = ResponseCode::InvalidCredentials; } } } }
function user_login_ldap($username, $password) { $ldapsrv = ''; // set your LDAP servers IP address (ex.192.168.0.1) $ldapsrv_domain = ''; // set your LDAP servers Domain $ldaperr['525'] = 'User not found'; $ldaperr['52e'] = 'Invalid credentials'; $ldaperr['530'] = 'Not permitted to logon at this time'; $ldaperr['531'] = 'Not permitted to logon at this workstation'; $ldaperr['532'] = 'Password expired'; $ldaperr['533'] = 'Account disabled'; $ldaperr['701'] = 'Account expired'; $ldaperr['773'] = 'User must reset password'; $ldaperr['775'] = 'User account locked'; if (!($ds = ldap_connect($ldapsrv))) { return 'Unable to connect to LDAP server'; } else { ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); if ($ger = @ldap_bind($ds, $username . '@' . $ldapsrv_domain, $password)) { return true; } else { ldap_get_option($ds, LDAP_OPT_ERROR_STRING, $diagmsg); if (isset($diagmsg)) { $diagmsg2 = explode(',', $diagmsg); } if (isset($diagmsg2) and preg_match('/data (.*)/i', trim($diagmsg2[2]), $res2) and isset($ldaperr[$res2[1]])) { return $ldaperr[$res2[1]]; } else { return ldap_error($ds); } } ldap_close($ds); } }
function ServerInfo() { if (is_array($this->version)) { return $this->version; } $version = array(); /* Determines how aliases are handled during search. LDAP_DEREF_NEVER (0x00) LDAP_DEREF_SEARCHING (0x01) LDAP_DEREF_FINDING (0x02) LDAP_DEREF_ALWAYS (0x03) The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but not when locating the base object of the search. The LDAP_DEREF_FINDING value means aliases are dereferenced when locating the base object but not during the search. Default: LDAP_DEREF_NEVER */ ldap_get_option($this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF']); switch ($version['LDAP_OPT_DEREF']) { case 0: $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER'; case 1: $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING'; case 2: $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING'; case 3: $version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS'; } /* A limit on the number of entries to return from a search. LDAP_NO_LIMIT (0) means no limit. Default: LDAP_NO_LIMIT */ ldap_get_option($this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT']); if ($version['LDAP_OPT_SIZELIMIT'] == 0) { $version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT'; } /* A limit on the number of seconds to spend on a search. LDAP_NO_LIMIT (0) means no limit. Default: LDAP_NO_LIMIT */ ldap_get_option($this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT']); if ($version['LDAP_OPT_TIMELIMIT'] == 0) { $version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT'; } /* Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not. LDAP_OPT_ON LDAP_OPT_OFF Default: ON */ ldap_get_option($this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS']); if ($version['LDAP_OPT_REFERRALS'] == 0) { $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF'; } else { $version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON'; } /* Determines whether LDAP I/O operations are automatically restarted if they abort prematurely. LDAP_OPT_ON LDAP_OPT_OFF Default: OFF */ ldap_get_option($this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART']); if ($version['LDAP_OPT_RESTART'] == 0) { $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF'; } else { $version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON'; } /* This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server. LDAP_VERSION2 (2) LDAP_VERSION3 (3) Default: LDAP_VERSION2 (2) */ ldap_get_option($this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION']); if ($version['LDAP_OPT_PROTOCOL_VERSION'] == 2) { $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2'; } else { $version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3'; } /* The host name (or list of hosts) for the primary LDAP server. */ ldap_get_option($this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME']); ldap_get_option($this->_connectionID, OPT_ERROR_NUMBER, $version['OPT_ERROR_NUMBER']); ldap_get_option($this->_connectionID, OPT_ERROR_STRING, $version['OPT_ERROR_STRING']); ldap_get_option($this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN']); return $this->version = $version; }
/** * Find a user record using the username and password provided. * * @param string $username The username/identifier. * @param string|null $password The password * @return bool|array Either false on failure, or an array of user data. */ protected function _findUser($username, $password = null) { if (!empty($this->_config['domain']) && !empty($username) && strpos($username, '@') === false) { $username .= '@' . $this->_config['domain']; } set_error_handler(function ($errorNumber, $errorText, $errorFile, $errorLine) { throw new ErrorException($errorText, 0, $errorNumber, $errorFile, $errorLine); }, E_ALL); try { $ldapBind = ldap_bind($this->ldapConnection, isset($this->_config['bindDN']) ? $this->_config['bindDN']($username, $this->_config['domain']) : $username, $password); if ($ldapBind === true) { $searchResults = ldap_search($this->ldapConnection, $this->_config['baseDN']($username, $this->_config['domain']), '(' . $this->_config['search'] . '=' . $username . ')'); $entry = ldap_first_entry($this->ldapConnection, $searchResults); return ldap_get_attributes($this->ldapConnection, $entry); } } catch (ErrorException $e) { if ($this->logErrors === true) { $this->log($e->getMessage()); } if (ldap_get_option($this->ldapConnection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError)) { if (!empty($extendedError)) { foreach ($this->_config['errors'] as $error => $errorMessage) { if (strpos($extendedError, $error) !== false) { $messages[] = ['message' => $errorMessage, 'key' => $this->_config['flash']['key'], 'element' => $this->_config['flash']['element'], 'params' => $this->_config['flash']['params']]; } } } } } restore_error_handler(); if (!empty($messages)) { $controller = $this->_registry->getController(); $controller->request->session()->write('Flash.' . $this->_config['flash']['key'], $messages); } return false; }
/** * Fetch data from LDAP server * * Searches the LDAP server for the given username/password * combination. Escapes all LDAP meta characters in username * before performing the query. * * @param string Username * @param string Password * @return boolean */ function fetchData($username, $password) { $this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG); $err = $this->_prepare(); if ($err !== true) { return PEAR::raiseError($err->getMessage(), $err->getCode()); } $err = $this->_getBaseDN(); if ($err !== true) { return PEAR::raiseError($err->getMessage(), $err->getCode()); } // UTF8 Encode username for LDAPv3 if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) { $this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG); $username = utf8_encode($username); } // make search filter $filter = sprintf('(&(%s=%s)%s)', $this->options['userattr'], $this->_quoteFilterString($username), $this->options['userfilter']); // make search base dn $search_basedn = $this->options['userdn']; if ($search_basedn != '' && substr($search_basedn, -1) != ',') { $search_basedn .= ','; } $search_basedn .= $this->options['basedn']; // attributes $searchAttributes = $this->options['attributes']; // make functions params array $func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes); // search function to use $func_name = $this->_scope2function($this->options['userscope']); $this->log("Searching with {$func_name} and filter {$filter} in {$search_basedn}", AUTH_LOG_DEBUG); // search if (($result_id = @call_user_func_array($func_name, $func_params)) === false) { $this->log('User not found', AUTH_LOG_DEBUG); } elseif (@ldap_count_entries($this->conn_id, $result_id) >= 1) { // did we get some possible results? $this->log('User(s) found', AUTH_LOG_DEBUG); $first = true; $entry_id = null; do { // then get the user dn if ($first) { $entry_id = @ldap_first_entry($this->conn_id, $result_id); $first = false; } else { $entry_id = @ldap_next_entry($this->conn_id, $entry_id); if ($entry_id === false) { break; } } $user_dn = @ldap_get_dn($this->conn_id, $entry_id); // as the dn is not fetched as an attribute, we save it anyway if (is_array($searchAttributes) && in_array('dn', $searchAttributes)) { $this->log('Saving DN to AuthData', AUTH_LOG_DEBUG); $this->_auth_obj->setAuthData('dn', $user_dn); } // fetch attributes if ($attributes = @ldap_get_attributes($this->conn_id, $entry_id)) { if (is_array($attributes) && isset($attributes['count']) && $attributes['count'] > 0) { // ldap_get_attributes() returns a specific multi dimensional array // format containing all the attributes and where each array starts // with a 'count' element providing the number of attributes in the // entry, or the number of values for attribute. For compatibility // reasons, it remains the default format returned by LDAP container // setAuthData(). // The code below optionally returns attributes in another format, // more compliant with other Auth containers, where each attribute // element are directly set in the 'authData' list. This option is // enabled by setting 'attrformat' to // 'AUTH' in the 'options' array. // eg. $this->options['attrformat'] = 'AUTH' if (strtoupper($this->options['attrformat']) == 'AUTH') { $this->log('Saving attributes to Auth data in AUTH format', AUTH_LOG_DEBUG); unset($attributes['count']); foreach ($attributes as $attributeName => $attributeValue) { if (is_int($attributeName)) { continue; } if (is_array($attributeValue) && isset($attributeValue['count'])) { unset($attributeValue['count']); } if (count($attributeValue) <= 1) { $attributeValue = $attributeValue[0]; } $this->log('Storing additional field: ' . $attributeName, AUTH_LOG_DEBUG); $this->_auth_obj->setAuthData($attributeName, $attributeValue); } } else { $this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG); $this->_auth_obj->setAuthData('attributes', $attributes); } } } @ldap_free_result($result_id); // need to catch an empty password as openldap seems to return TRUE // if anonymous binding is allowed if ($password != "") { $this->log("Bind as {$user_dn}", AUTH_LOG_DEBUG); // try binding as this user with the supplied password if (@ldap_bind($this->conn_id, $user_dn, $password)) { $this->log('Bind successful', AUTH_LOG_DEBUG); // check group if appropiate if (strlen($this->options['group'])) { // decide whether memberattr value is a dn or the username $this->log('Checking group membership', AUTH_LOG_DEBUG); $return = $this->checkGroup($this->options['memberisdn'] ? $user_dn : $username); $this->_disconnect(); return $return; } else { $this->log('Authenticated', AUTH_LOG_DEBUG); $this->_disconnect(); return true; // user authenticated } // checkGroup } // bind } // non-empty password } while ($this->options['try_all'] == true); // interate through entries } // get results // default $this->log('NOT authenticated!', AUTH_LOG_DEBUG); $this->_disconnect(); return false; }
public function testExplicitNetworkTimeoutConnect() { $networkTimeout = 1; $host = TESTS_ZEND_LDAP_HOST; $port = 0; if (defined('TESTS_ZEND_LDAP_PORT') && TESTS_ZEND_LDAP_PORT != 389) { $port = TESTS_ZEND_LDAP_PORT; } $useSsl = false; if (defined('TESTS_ZEND_LDAP_USE_SSL')) { $useSsl = TESTS_ZEND_LDAP_USE_SSL; } $ldap = new Ldap\Ldap(); $ldap->connect($host, $port, $useSsl, null, $networkTimeout); ldap_get_option($ldap->getResource(), LDAP_OPT_NETWORK_TIMEOUT, $actual); $this->assertEquals($networkTimeout, $actual); }
/** * Returns true if the username and password work and false if they are * wrong or don't exist. * * @param string $username The username (without system magic quotes) * @param string $password The password (without system magic quotes) * * @return bool Authentication success or failure. */ function user_login($username, $password) { if (!function_exists('ldap_bind')) { print_error('auth_ldapnotinstalled', 'auth_ldap'); return false; } if (!$username or !$password) { // Don't allow blank usernames or passwords return false; } $extusername = core_text::convert($username, 'utf-8', $this->config->ldapencoding); $extpassword = core_text::convert($password, 'utf-8', $this->config->ldapencoding); // Before we connect to LDAP, check if this is an AD SSO login // if we succeed in this block, we'll return success early. // $key = sesskey(); if (!empty($this->config->ntlmsso_enabled) && $key === $password) { $cf = get_cache_flags($this->pluginconfig . '/ntlmsess'); // We only get the cache flag if we retrieve it before // it expires (AUTH_NTLMTIMEOUT seconds). if (!isset($cf[$key]) || $cf[$key] === '') { return false; } $sessusername = $cf[$key]; if ($username === $sessusername) { unset($sessusername); unset($cf); // Check that the user is inside one of the configured LDAP contexts $validuser = false; $ldapconnection = $this->ldap_connect(); // if the user is not inside the configured contexts, // ldap_find_userdn returns false. if ($this->ldap_find_userdn($ldapconnection, $extusername)) { $validuser = true; } $this->ldap_close(); // Shortcut here - SSO confirmed return $validuser; } } // End SSO processing unset($key); $ldapconnection = $this->ldap_connect(); $ldap_user_dn = $this->ldap_find_userdn($ldapconnection, $extusername); // If ldap_user_dn is empty, user does not exist if (!$ldap_user_dn) { $this->ldap_close(); return false; } // Try to bind with current username and password $ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, $extpassword); // If login fails and we are using MS Active Directory, retrieve the diagnostic // message to see if this is due to an expired password, or that the user is forced to // change the password on first login. If it is, only proceed if we can change // password from Moodle (otherwise we'll get stuck later in the login process). if (!$ldap_login && $this->config->user_type == 'ad' && $this->can_change_password() && (!empty($this->config->expiration) and $this->config->expiration == 1)) { // We need to get the diagnostic message right after the call to ldap_bind(), // before any other LDAP operation. ldap_get_option($ldapconnection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $diagmsg); if ($this->ldap_ad_pwdexpired_from_diagmsg($diagmsg)) { // If login failed because user must change the password now or the // password has expired, let the user in. We'll catch this later in the // login process when we explicitly check for expired passwords. $ldap_login = true; } } $this->ldap_close(); return $ldap_login; }
function ConnectToAD($username, $password) { $ChilliConf = unserialize(base64_decode(@file_get_contents("/etc/artica-postfix/settings/Daemons/ChilliConf"))); if ($ChilliConf["EnableActiveDirectory"] == 0) { return false; } $AD_DOMAIN = $ChilliConf["AD_DOMAIN"]; define(LDAP_OPT_DIAGNOSTIC_MESSAGE, 0x32); events("ldap_connect({$ChilliConf["AD_SERVER"]},{$ChilliConf["AD_PORT"]})..."); $cnx = @ldap_connect($ChilliConf["AD_SERVER"], $ChilliConf["AD_PORT"]); if (!$cnx) { events("Fatal: ldap_connect({$ChilliConf["AD_SERVER"]},{$ChilliConf["AD_PORT"]} ) Check your configuration..."); @ldap_close(); return false; } events("OK: ldap_connect({$ChilliConf["AD_SERVER"]},{$ChilliConf["AD_PORT"]} ) SUCCESS"); @ldap_set_option($cnx, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($cnx, LDAP_OPT_REFERRALS, 0); @ldap_set_option($cnx, LDAP_OPT_PROTOCOL_VERSION, 3); // on passe le LDAP en version 3, necessaire pour travailler avec le AD @ldap_set_option($cnx, LDAP_OPT_REFERRALS, 0); events("Check ident {$username}@{$AD_DOMAIN} {$password}"); $bind = @ldap_bind($cnx, "{$username}@{$AD_DOMAIN}", $password); if (!$bind) { $errn = ldap_errno($cnx); $error = "Error {$errn}: " . ldap_err2str($errn); if (@ldap_get_option($cnx, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) { $error = $error . " {$extended_error}"; } events("{$error}"); return false; } events("Active Directory session SUCCESS"); return true; }
/** * Connect to the LDAP server using the global options * * @access private * @return object Returns a PEAR error object if an error occurs. */ function _connect() { // connect if (isset($this->options['url']) && $this->options['url'] != '') { $this->conn_id = @ldap_connect($this->options['url']); } else { $this->conn_id = @ldap_connect($this->options['host'], $this->options['port']); } // try switchig to LDAPv3 $ver = 0; if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver >= 2) { @ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, 3); } // bind anonymously for searching if (@ldap_bind($this->conn_id) == false) { return PEAR::raiseError("Auth_Container_LDAP: Could not connect and bind to LDAP server.", 41, PEAR_ERROR_DIE); } }
/** * Get an LDAP option value * * @param string $option Option to get * * @access public * @return Net_LDAP2_Error|string Net_LDAP2_Error or option value */ public function getOption($option) { if ($this->_link) { if (defined($option)) { if (@ldap_get_option($this->_link, constant($option), $value)) { return $value; } else { $err = @ldap_errno($this->_link); if ($err) { $msg = @ldap_err2str($err); } else { $err = NET_LDAP2_ERROR; $msg = Net_LDAP2::errorMessage($err); } return $this->raiseError($msg, $err); } } else { $this->raiseError("Unkown Option requested"); } } else { $this->raiseError("No LDAP connection"); } }
/** * Convenience method to create an LDAPException as well as log the * description. * * @param string $description * The exception's description * @return Exception */ private function makeException($description, $type = NULL) { $errNo = 0x0; // Log LDAP code and description, if possible. if (empty($this->ldap)) { SimpleSAML_Logger::error($description); } else { $errNo = @ldap_errno($this->ldap); } // Decide exception type and return if ($type) { if ($errNo !== 0) { // Only log real LDAP errors; not success. SimpleSAML_Logger::error($description . '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')'); } else { SimpleSAML_Logger::error($description); } switch ($type) { case ERR_INTERNAL: // 1 - ExInternal return new SimpleSAML_Error_Exception($description, $errNo); case ERR_NO_USER: // 2 - ExUserNotFound return new SimpleSAML_Error_UserNotFound($description, $errNo); case ERR_WRONG_PW: // 3 - ExInvalidCredential return new SimpleSAML_Error_InvalidCredential($description, $errNo); case ERR_AS_DATA_INCONSIST: // 4 - ExAsDataInconsist return new SimpleSAML_Error_AuthSource('ldap', $description); case ERR_AS_INTERNAL: // 5 - ExAsInternal return new SimpleSAML_Error_AuthSource('ldap', $description); } } else { if ($errNo !== 0) { $description .= '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')'; if (@ldap_get_option($this->ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError) && !empty($extendedError)) { $description .= '; additional: \'' . $extendedError . '\''; } } switch ($errNo) { case 0x20: //LDAP_NO_SUCH_OBJECT SimpleSAML_Logger::warning($description); return new SimpleSAML_Error_UserNotFound($description, $errNo); case 0x31: //LDAP_INVALID_CREDENTIALS SimpleSAML_Logger::info($description); return new SimpleSAML_Error_InvalidCredential($description, $errNo); case -1: //NO_SERVER_CONNECTION SimpleSAML_Logger::error($description); return new SimpleSAML_Error_AuthSource('ldap', $description); default: SimpleSAML_Logger::error($description); return new SimpleSAML_Error_AuthSource('ldap', $description); } } }
/** * Returns an LDAP option value. * * @param string $option Option to get. * * @return Horde_Ldap_Error|string Horde_Ldap_Error or option value * @throws Horde_Ldap_Exception */ public function getOption($option) { if (!$this->_link) { throw new Horde_Ldap_Exception('No LDAP connection'); } if (!defined($option)) { throw new Horde_Ldap_Exception('Unkown option requested'); } if (@ldap_get_option($this->_link, constant($option), $value)) { return $value; } $err = @ldap_errno($this->_link); if ($err) { throw new Horde_Ldap_Exception(ldap_err2str($err), $err); } throw new Horde_Ldap_Exception('Unknown error'); }
/** * Retrieve ldap option value * * @param int option * @return var value */ public function getOption($option) { if (false === ($res = ldap_get_option($this->_hdl, $option, $value))) { throw new LDAPException('Cannot get value "' . $option . '"', ldap_errno($this->_hdl)); } return $value; }
/** * Verification de la version du serveur ldap. * * @return string version */ function getVersion() { $version = 0; $version = @ldap_get_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $version); return $version; }
<?php require "connect.inc"; $link = ldap_connect($host, $port); $option = null; var_dump(ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version)); ldap_get_option($link, LDAP_OPT_PROTOCOL_VERSION, $option); var_dump($option); ?> ===DONE===
/** * Return the diagnostic Message. * * @return string $diagnosticMessage */ public function getDiagnosticMessage() { ldap_get_option($this->getConnection(), LDAP_OPT_ERROR_STRING, $diagnosticMessage); return $diagnosticMessage; }
function ConnectToLDAP() { BuildDefault(); $array = $GLOBALS["KerbAuthInfos"]; if (!is_array($array)) { WLOG("KerbAuthInfos not an array"); return false; } if (!isset($array["LDAP_SERVER"])) { WLOG("LDAP_SERVER not set"); return; } if (!isset($array["LDAP_SUFFIX"])) { WLOG("LDAP_SUFFIX not set"); return; } $GLOBALS["SUFFIX"] = $array["LDAP_SUFFIX"]; $GLOBALS["CONNECTION"] = @ldap_connect($array["LDAP_SERVER"], $array["LDAP_PORT"]); //WLOG("[LDAP]: Connecting to LDAP server `{$array["LDAP_SERVER"]}:{$array["LDAP_PORT"]}`"); if (!$GLOBALS["CONNECTION"]) { WLOG("[LDAP]: Fatal: ldap_connect({$array["LDAP_SERVER"]},{$array["LDAP_PORT"]} )"); @ldap_close(); return false; } //WLOG("[LDAP]: Connecting to LDAP server {$array["LDAP_SERVER"]} <span style='font-weight:bold;color:#00B218'>success</span> with suffix:«{$GLOBALS["SUFFIX"]}»"); @ldap_set_option($GLOBALS["CONNECTION"], LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($GLOBALS["CONNECTION"], LDAP_OPT_REFERRALS, 0); @ldap_set_option($GLOBALS["CONNECTION"], LDAP_OPT_PROTOCOL_VERSION, 3); // on passe le LDAP en version 3, necessaire pour travailler avec le AD @ldap_set_option($GLOBALS["CONNECTION"], LDAP_OPT_REFERRALS, 0); if (preg_match("#^(.+?)\\/(.+?)\$#", $array["WINDOWS_SERVER_ADMIN"], $re)) { $array["WINDOWS_SERVER_ADMIN"] = $re[1]; } if (preg_match("#^(.+?)\\\\(.+?)\$#", $array["WINDOWS_SERVER_ADMIN"], $re)) { $array["WINDOWS_SERVER_ADMIN"] = $re[1]; } //$GLOBALS["BIND"]=ldap_bind($GLOBALS["CONNECTION"], $array["LDAP_DN"], $array["LDAP_PASSWORD"]); $GLOBALS["BIND"] = @ldap_bind($GLOBALS["CONNECTION"], "{$array["WINDOWS_SERVER_ADMIN"]}@{$array["WINDOWS_DNS_SUFFIX"]}", $array["WINDOWS_SERVER_PASS"]); if (!$GLOBALS["BIND"]) { if (@ldap_get_option($GLOBALS["CONNECTION"], LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) { $error = $error . " {$extended_error}"; } switch (ldap_errno($GLOBALS["CONNECTION"])) { case 0x31: $error = $error . " Bad username or password. Please try again."; break; case 0x32: $error = $error . " Insufficient access rights."; break; case 81: $error = $error . " Unable to connect to the LDAP server \n\t\t\t\t{$array["LDAP_SERVER"]} please, verify if ldap daemon is running or the ldap server address"; break; case -1: break; default: $error = $error . " Could not bind to the LDAP server." . " " . @ldap_err2str($GLOBALS["CONNECTION"]); } WLOG("[LDAP]:" . __LINE__ . " Connecting to LDAP server {$array["LDAP_SERVER"]} failed {$error}"); return false; } //WLOG("[LDAP]: Binding to LDAP server {$array["LDAP_SERVER"]} <span style='font-weight:bold;color:#00B218'>success</span>."); return true; }
/** * Connect Method */ function connect() { if (!($con = ldap_connect($this->address, $this->port))) { watchdog('user', 'LDAP Connect failure to ' . $this->address . ':' . $this->port); return LDAP_CONNECT_ERROR; } ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($con, LDAP_OPT_REFERRALS, (int) $this->followrefs); // Use TLS if we are configured and able to. if ($this->tls) { ldap_get_option($con, LDAP_OPT_PROTOCOL_VERSION, $vers); if ($vers == -1) { watchdog('user', 'Could not get LDAP protocol version.'); return LDAP_PROTOCOL_ERROR; } if ($vers != 3) { watchdog('user', 'Could not start TLS, only supported by LDAP v3.'); return LDAP_CONNECT_ERROR; } elseif (!function_exists('ldap_start_tls')) { watchdog('user', 'Could not start TLS. It does not seem to be supported by this PHP setup.'); return LDAP_CONNECT_ERROR; } elseif (!ldap_start_tls($con)) { $msg = t("Could not start TLS. (Error %errno: %error).", array('%errno' => ldap_errno($con), '%error' => ldap_error($con))); watchdog('user', $msg); return LDAP_CONNECT_ERROR; } } // Store the resulting resource $this->connection = $con; return LDAP_SUCCESS; }
function TestLDAPAD_bind($server, $port, $user, $password) { $ldap_connection = @ldap_connect($server, $port); if (!$ldap_connection) { $error = "[CONNECT] ldap://{$server}:{$port}"; if (@ldap_get_option($ldap_connection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) { $error = $error . "<br>{$extended_error}"; if ($GLOBALS["VERBOSE"]) { echo "<strong style='color:red'>{$error}</strong><br>\n"; } } @ldap_close($ldap_connection); return $error; } @ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); @ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); @ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, 1); $bind = ldap_bind($ldap_connection, "{$user}", $password); if (!$bind) { $error = "[BIND] ldap://{$server}:{$port}"; if (@ldap_get_option($ldap_connection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extended_error)) { $error = $error . "<br>{$extended_error}"; if ($GLOBALS["VERBOSE"]) { echo "<strong style='color:red'>{$error}</strong><br>\n"; } } @ldap_close($ldap_connection); return $error; } if ($GLOBALS["VERBOSE"]) { echo "<strong style='color:red'>ldap://{$server}:{$port} [OK]</strong><br>\n"; } return null; }
function ldap_check_credentials($user, $pass) { foreach (explode(' ', LDAP_SERVERS) as $server) { // The connection may only be really established when needed, // so execute a dummy query to test if the server is available: $conn = @ldap_connect($server); if (!$conn || !ldap_get_option($conn, LDAP_OPT_PROTOCOL_VERSION, $dummy)) { continue; } /* // The following options are necessary to be able to talk // to an Active Directory: if ( !ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3) ) { error("Failed to set protocol version to 3."); } if ( !ldap_set_option($conn, LDAP_OPT_REFERRALS, 0) ) { error("Failed to set LDAP_OPT_REFERRALS."); } if ( !ldap_set_option($conn, LDAP_OPT_DEREF, 0) ) { error("Failed to set LDAP_OPT_DEREF."); } */ // Create the dn $ldap_dn = str_replace('&', $user, LDAP_DNQUERY); // Try to login to test credentials if (@ldap_bind($conn, $ldap_dn, $pass)) { @ldap_unbind($conn); return TRUE; } } return FALSE; }
/** * Connect to the LDAP server using the global options * * @access private * @return object Returns a PEAR error object if an error occurs. */ function _connect() { // connect if (isset($this->options['url']) && $this->options['url'] != '') { $this->_debug('Connecting with URL', __LINE__); $conn_params = array($this->options['url']); } else { $this->_debug('Connecting with host:port', __LINE__); $conn_params = array($this->options['host'], $this->options['port']); } if (($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) { return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41, PEAR_ERROR_DIE); } $this->_debug('Successfully connected to server', __LINE__); // try switchig to LDAPv3 $ver = 0; if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver >= 2) { $this->_debug('Switching to LDAPv3', __LINE__); @ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, 3); } // bind with credentials or anonymously if ($this->options['binddn'] && $this->options['bindpw']) { $this->_debug('Binding with credentials', __LINE__); $bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']); } else { $this->_debug('Binding anonymously', __LINE__); $bind_params = array($this->conn_id); } // bind for searching if (@call_user_func_array('ldap_bind', $bind_params) == false) { $this->_debug(); $this->_disconnect(); return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41, PEAR_ERROR_DIE); } $this->_debug('Binding was successful', __LINE__); }
/** * Return the LDAP error message of the last LDAP command * * @param int $errorCode * @param array $errorMessages * @return string */ public function getLastError(&$errorCode = null, array &$errorMessages = null) { $errorCode = $this->getLastErrorCode(); $errorMessages = array(); /* The various error retrieval functions can return * different things so we just try to collect what we * can and eliminate dupes. */ $estr1 = @ldap_error($this->_resource); if ($errorCode !== 0 && $estr1 === 'Success') { $estr1 = @ldap_err2str($errorCode); } if (!empty($estr1)) { $errorMessages[] = $estr1; } @ldap_get_option($this->_resource, LDAP_OPT_ERROR_STRING, $estr2); if (!empty($estr2) && !in_array($estr2, $errorMessages)) { $errorMessages[] = $estr2; } $message = ''; if ($errorCode > 0) { $message = '0x' . dechex($errorCode) . ' '; } else { $message = ''; } if (count($errorMessages) > 0) { $message .= '(' . implode('; ', $errorMessages) . ')'; } else { $message .= '(no error message from LDAP)'; } return $message; }
/** * Evaluates the given variable * * @param mixed &$subject Variable to query * @param bool $specialStr Should this be interpreted as a special string? * @return mixed Result (both HTML and text modes generate strings) */ protected function evaluate(&$subject, $specialStr = false) { switch ($type = gettype($subject)) { // https://github.com/digitalnature/php-ref/issues/13 case 'unknown type': return $this->fmt->text('unknown'); // null value // null value case 'NULL': return $this->fmt->text('null'); // integer/double/float // integer/double/float case 'integer': case 'double': return $this->fmt->text($type, $subject, $type); // boolean // boolean case 'boolean': $text = $subject ? 'true' : 'false'; return $this->fmt->text($text, $text, $type); // arrays // arrays case 'array': // empty array? if (empty($subject)) { $this->fmt->text('array'); return $this->fmt->emptyGroup(); } if (isset($subject[static::MARKER_KEY])) { unset($subject[static::MARKER_KEY]); $this->fmt->text('array'); $this->fmt->emptyGroup('recursion'); return; } // first recursion level detection; // this is optional (used to print consistent recursion info) foreach ($subject as $key => &$value) { if (!is_array($value)) { continue; } // save current value in a temporary variable $buffer = $value; // assign new value $value = $value !== 1 ? 1 : 2; // if they're still equal, then we have a reference if ($value === $subject) { $value = $buffer; $value[static::MARKER_KEY] = true; $this->evaluate($value); return; } // restoring original value $value = $buffer; } $this->fmt->text('array'); $count = count($subject); if (!$this->fmt->startGroup($count)) { return; } $max = max(array_map('static::strLen', array_keys($subject))); $subject[static::MARKER_KEY] = true; foreach ($subject as $key => &$value) { // ignore our temporary marker if ($key === static::MARKER_KEY) { continue; } if ($this->hasInstanceTimedOut()) { break; } $keyInfo = gettype($key); if ($keyInfo === 'string') { $encoding = static::$env['mbStr'] ? mb_detect_encoding($key) : ''; $keyLen = $encoding && $encoding !== 'ASCII' ? static::strLen($key) . '; ' . $encoding : static::strLen($key); $keyInfo = "{$keyInfo}({$keyLen})"; } else { $keyLen = strlen($key); } $this->fmt->startRow(); $this->fmt->text('key', $key, "Key: {$keyInfo}"); $this->fmt->colDiv($max - $keyLen); $this->fmt->sep('=>'); $this->fmt->colDiv(); $this->evaluate($value, $specialStr); $this->fmt->endRow(); } unset($subject[static::MARKER_KEY]); $this->fmt->endGroup(); return; // resource // resource case 'resource': $meta = array(); $resType = get_resource_type($subject); $this->fmt->text('resource', strval($subject)); if (!static::$config['showResourceInfo']) { return $this->fmt->emptyGroup($resType); } // @see: http://php.net/manual/en/resource.php // need to add more... switch ($resType) { // curl extension resource case 'curl': $meta = curl_getinfo($subject); break; case 'FTP Buffer': $meta = array('time_out' => ftp_get_option($subject, FTP_TIMEOUT_SEC), 'auto_seek' => ftp_get_option($subject, FTP_AUTOSEEK)); break; // gd image extension resource // gd image extension resource case 'gd': $meta = array('size' => sprintf('%d x %d', imagesx($subject), imagesy($subject)), 'true_color' => imageistruecolor($subject)); break; case 'ldap link': $constants = get_defined_constants(); array_walk($constants, function ($value, $key) use(&$constants) { if (strpos($key, 'LDAP_OPT_') !== 0) { unset($constants[$key]); } }); // this seems to fail on my setup :( unset($constants['LDAP_OPT_NETWORK_TIMEOUT']); foreach (array_slice($constants, 3) as $key => $value) { if (ldap_get_option($subject, (int) $value, $ret)) { $meta[strtolower(substr($key, 9))] = $ret; } } break; // mysql connection (mysql extension is deprecated from php 5.4/5.5) // mysql connection (mysql extension is deprecated from php 5.4/5.5) case 'mysql link': case 'mysql link persistent': $dbs = array(); $query = @mysql_list_dbs($subject); while ($row = @mysql_fetch_array($query)) { $dbs[] = $row['Database']; } $meta = array('host' => ltrim(@mysql_get_host_info($subject), 'MySQL host info: '), 'server_version' => @mysql_get_server_info($subject), 'protocol_version' => @mysql_get_proto_info($subject), 'databases' => $dbs); break; // mysql result // mysql result case 'mysql result': while ($row = @mysql_fetch_object($subject)) { $meta[] = (array) $row; if ($this->hasInstanceTimedOut()) { break; } } break; // stream resource (fopen, fsockopen, popen, opendir etc) // stream resource (fopen, fsockopen, popen, opendir etc) case 'stream': $meta = stream_get_meta_data($subject); break; } if (!$meta) { return $this->fmt->emptyGroup($resType); } if (!$this->fmt->startGroup($resType)) { return; } $max = max(array_map('static::strLen', array_keys($meta))); foreach ($meta as $key => $value) { $this->fmt->startRow(); $this->fmt->text('resourceProp', ucwords(str_replace('_', ' ', $key))); $this->fmt->colDiv($max - static::strLen($key)); $this->fmt->sep(':'); $this->fmt->colDiv(); $this->evaluate($value); $this->fmt->endRow(); } $this->fmt->endGroup(); return; // string // string case 'string': $length = static::strLen($subject); $encoding = static::$env['mbStr'] ? mb_detect_encoding($subject) : false; $info = $encoding && $encoding !== 'ASCII' ? $length . '; ' . $encoding : $length; if ($specialStr) { $this->fmt->sep('"'); $this->fmt->text(array('string', 'special'), $subject, "string({$info})"); $this->fmt->sep('"'); return; } $this->fmt->text('string', $subject, "string({$info})"); // advanced checks only if there are 3 characteres or more if (static::$config['showStringMatches'] && $length > 2 && trim($subject) !== '') { $isNumeric = is_numeric($subject); // very simple check to determine if the string could match a file path // @note: this part of the code is very expensive $isFile = $length < 2048 && max(array_map('strlen', explode('/', str_replace('\\', '/', $subject)))) < 128 && !preg_match('/[^\\w\\.\\-\\/\\\\:]|\\..*\\.|\\.$|:(?!(?<=^[a-zA-Z]:)[\\/\\\\])/', $subject); if ($isFile) { try { $file = new \SplFileInfo($subject); $flags = array(); $perms = $file->getPerms(); if (($perms & 0xc000) === 0xc000) { // socket $flags[] = 's'; } elseif (($perms & 0xa000) === 0xa000) { // symlink $flags[] = 'l'; } elseif (($perms & 0x8000) === 0x8000) { // regular $flags[] = '-'; } elseif (($perms & 0x6000) === 0x6000) { // block special $flags[] = 'b'; } elseif (($perms & 0x4000) === 0x4000) { // directory $flags[] = 'd'; } elseif (($perms & 0x2000) === 0x2000) { // character special $flags[] = 'c'; } elseif (($perms & 0x1000) === 0x1000) { // FIFO pipe $flags[] = 'p'; } else { // unknown $flags[] = 'u'; } // owner $flags[] = $perms & 0x100 ? 'r' : '-'; $flags[] = $perms & 0x80 ? 'w' : '-'; $flags[] = $perms & 0x40 ? $perms & 0x800 ? 's' : 'x' : ($perms & 0x800 ? 'S' : '-'); // group $flags[] = $perms & 0x20 ? 'r' : '-'; $flags[] = $perms & 0x10 ? 'w' : '-'; $flags[] = $perms & 0x8 ? $perms & 0x400 ? 's' : 'x' : ($perms & 0x400 ? 'S' : '-'); // world $flags[] = $perms & 0x4 ? 'r' : '-'; $flags[] = $perms & 0x2 ? 'w' : '-'; $flags[] = $perms & 0x1 ? $perms & 0x200 ? 't' : 'x' : ($perms & 0x200 ? 'T' : '-'); $size = is_dir($subject) ? '' : sprintf(' %.2fK', $file->getSize() / 1024); $this->fmt->startContain('file', true); $this->fmt->text('file', implode('', $flags) . $size); $this->fmt->endContain(); } catch (\Exception $e) { $isFile = false; } } // class/interface/function if (!preg_match('/[^\\w+\\\\]/', $subject) && $length < 96) { $isClass = class_exists($subject, false); if ($isClass) { $this->fmt->startContain('class', true); $this->fromReflector(new \ReflectionClass($subject)); $this->fmt->endContain(); } if (!$isClass && interface_exists($subject, false)) { $this->fmt->startContain('interface', true); $this->fromReflector(new \ReflectionClass($subject)); $this->fmt->endContain('interface'); } if (function_exists($subject)) { $this->fmt->startContain('function', true); $this->fromReflector(new \ReflectionFunction($subject)); $this->fmt->endContain('function'); } } // skip serialization/json/date checks if the string appears to be numeric, // or if it's shorter than 5 characters if (!$isNumeric && $length > 4) { // url if (static::$config['showUrls'] && static::$env['curlActive'] && filter_var($subject, FILTER_VALIDATE_URL)) { $ch = curl_init($subject); curl_setopt($ch, CURLOPT_NOBODY, true); curl_exec($ch); $nfo = curl_getinfo($ch); curl_close($ch); if ($nfo['http_code']) { $this->fmt->startContain('url', true); $contentType = explode(';', $nfo['content_type']); $this->fmt->text('url', sprintf('%s:%d %s %.2fms (%d)', !empty($nfo['primary_ip']) ? $nfo['primary_ip'] : null, !empty($nfo['primary_port']) ? $nfo['primary_port'] : null, $contentType[0], $nfo['total_time'], $nfo['http_code'])); $this->fmt->endContain(); } } // date if ($length < 128 && static::$env['supportsDate'] && !preg_match('/[^A-Za-z0-9.:+\\s\\-\\/]/', $subject)) { try { $date = new \DateTime($subject); $errors = \DateTime::getLastErrors(); if ($errors['warning_count'] < 1 && $errors['error_count'] < 1) { $now = new \Datetime('now'); $nowUtc = new \Datetime('now', new \DateTimeZone('UTC')); $diff = $now->diff($date); $map = array('y' => 'yr', 'm' => 'mo', 'd' => 'da', 'h' => 'hr', 'i' => 'min', 's' => 'sec'); $timeAgo = 'now'; foreach ($map as $k => $label) { if ($diff->{$k} > 0) { $timeAgo = $diff->format("%R%{$k}{$label}"); break; } } $tz = $date->getTimezone(); $offs = round($tz->getOffset($nowUtc) / 3600); if ($offs > 0) { $offs = "+{$offs}"; } $timeAgo .= (int) $offs !== 0 ? ' ' . sprintf('%s (UTC%s)', $tz->getName(), $offs) : ' UTC'; $this->fmt->startContain('date', true); $this->fmt->text('date', $timeAgo); $this->fmt->endContain(); } } catch (\Exception $e) { // not a date } } // attempt to detect if this is a serialized string static $unserializing = 0; $isSerialized = $unserializing < 3 && ($subject[$length - 1] === ';' || $subject[$length - 1] === '}') && in_array($subject[0], array('s', 'a', 'O'), true) && ($subject[0] === 's' && $subject[$length - 2] !== '"' || preg_match("/^{$subject[0]}:[0-9]+:/s", $subject)) && ($unserialized = @unserialize($subject)) !== false; if ($isSerialized) { $unserializing++; $this->fmt->startContain('serialized', true); $this->evaluate($unserialized); $this->fmt->endContain(); $unserializing--; } // try to find out if it's a json-encoded string; // only do this for json-encoded arrays or objects, because other types have too generic formats static $decodingJson = 0; $isJson = !$isSerialized && $decodingJson < 3 && in_array($subject[0], array('{', '['), true); if ($isJson) { $decodingJson++; $json = json_decode($subject); if ($isJson = json_last_error() === JSON_ERROR_NONE) { $this->fmt->startContain('json', true); $this->evaluate($json); $this->fmt->endContain(); } $decodingJson--; } // attempt to match a regex if ($length < 768) { try { $components = $this->splitRegex($subject); if ($components) { $regex = ''; $this->fmt->startContain('regex', true); foreach ($components as $component) { $this->fmt->text('regex-' . key($component), reset($component)); } $this->fmt->endContain(); } } catch (\Exception $e) { // not a regex } } } } return; } // if we reached this point, $subject must be an object // track objects to detect recursion static $hashes = array(); // hash ID of this object $hash = spl_object_hash($subject); $recursion = isset($hashes[$hash]); // sometimes incomplete objects may be created from string unserialization, // if the class to which the object belongs wasn't included until the unserialization stage... if ($subject instanceof \__PHP_Incomplete_Class) { $this->fmt->text('object'); $this->fmt->emptyGroup('incomplete'); return; } // check cache at this point if (!$recursion && $this->fmt->didCache($hash)) { static::$debug['cacheHits']++; return; } $reflector = new \ReflectionObject($subject); $this->fmt->startContain('class'); $this->fromReflector($reflector); $this->fmt->text('object', ' object'); $this->fmt->endContain(); // already been here? if ($recursion) { return $this->fmt->emptyGroup('recursion'); } $hashes[$hash] = 1; $flags = \ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED; if (static::$config['showPrivateMembers']) { $flags |= \ReflectionProperty::IS_PRIVATE; } $props = $reflector->getProperties($flags); $methods = array(); if (static::$config['showMethods']) { $flags = \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED; if (static::$config['showPrivateMembers']) { $flags |= \ReflectionMethod::IS_PRIVATE; } $methods = $reflector->getMethods($flags); } $constants = $reflector->getConstants(); $interfaces = $reflector->getInterfaces(); $traits = static::$env['is54'] ? $reflector->getTraits() : array(); $parents = static::getParentClasses($reflector); // work-around for https://bugs.php.net/bug.php?id=49154 // @see http://stackoverflow.com/questions/15672287/strange-behavior-of-reflectiongetproperties-with-numeric-keys if (!static::$env['is54']) { $props = array_values(array_filter($props, function ($prop) use($subject) { return !$prop->isPublic() || property_exists($subject, $prop->name); })); } // no data to display? if (!$props && !$methods && !$constants && !$interfaces && !$traits) { unset($hashes[$hash]); return $this->fmt->emptyGroup(); } if (!$this->fmt->startGroup()) { return; } // show contents for iterators if (static::$config['showIteratorContents'] && $reflector->isIterateable()) { $itContents = iterator_to_array($subject); $this->fmt->sectionTitle(sprintf('Contents (%d)', count($itContents))); foreach ($itContents as $key => $value) { $keyInfo = gettype($key); if ($keyInfo === 'string') { $encoding = static::$env['mbStr'] ? mb_detect_encoding($key) : ''; $length = $encoding && $encoding !== 'ASCII' ? static::strLen($key) . '; ' . $encoding : static::strLen($key); $keyInfo = sprintf('%s(%s)', $keyInfo, $length); } $this->fmt->startRow(); $this->fmt->text(array('key', 'iterator'), $key, sprintf('Iterator key: %s', $keyInfo)); $this->fmt->colDiv(); $this->fmt->sep('=>'); $this->fmt->colDiv(); $this->evaluate($value); //$this->evaluate($value instanceof \Traversable ? ((count($value) > 0) ? $value : (string)$value) : $value); $this->fmt->endRow(); } } // display the interfaces this objects' class implements if ($interfaces) { $items = array(); $this->fmt->sectionTitle('Implements'); $this->fmt->startRow(); $this->fmt->startContain('interfaces'); $i = 0; $count = count($interfaces); foreach ($interfaces as $name => $interface) { $this->fromReflector($interface); if (++$i < $count) { $this->fmt->sep(', '); } } $this->fmt->endContain(); $this->fmt->endRow(); } // traits this objects' class uses if ($traits) { $items = array(); $this->fmt->sectionTitle('Uses'); $this->fmt->startRow(); $this->fmt->startContain('traits'); $i = 0; $count = count($traits); foreach ($traits as $name => $trait) { $this->fromReflector($trait); if (++$i < $count) { $this->fmt->sep(', '); } } $this->fmt->endContain(); $this->fmt->endRow(); } // class constants if ($constants) { $this->fmt->sectionTitle('Constants'); $max = max(array_map('static::strLen', array_keys($constants))); foreach ($constants as $name => $value) { $meta = null; $type = array('const'); foreach ($parents as $parent) { if ($parent->hasConstant($name)) { if ($parent !== $reflector) { $type[] = 'inherited'; $meta = array('sub' => array(array('Prototype defined by', $parent->name))); } break; } } $this->fmt->startRow(); $this->fmt->sep('::'); $this->fmt->colDiv(); $this->fmt->startContain($type); $this->fmt->text('name', $name, $meta, $this->linkify($parent, $name)); $this->fmt->endContain(); $this->fmt->colDiv($max - static::strLen($name)); $this->fmt->sep('='); $this->fmt->colDiv(); $this->evaluate($value); $this->fmt->endRow(); } } // object/class properties if ($props) { $this->fmt->sectionTitle('Properties'); $max = 0; foreach ($props as $idx => $prop) { if (($propNameLen = static::strLen($prop->name)) > $max) { $max = $propNameLen; } } foreach ($props as $idx => $prop) { if ($this->hasInstanceTimedOut()) { break; } $bubbles = array(); $sourceClass = $prop->getDeclaringClass(); $inherited = $reflector->getShortName() !== $sourceClass->getShortName(); $meta = $sourceClass->isInternal() ? null : static::parseComment($prop->getDocComment()); if ($meta) { if ($inherited) { $meta['sub'] = array(array('Declared in', $sourceClass->getShortName())); } if (isset($meta['tags']['var'][0])) { $meta['left'] = $meta['tags']['var'][0][0]; } unset($meta['tags']); } if ($prop->isProtected() || $prop->isPrivate()) { $prop->setAccessible(true); } $value = $prop->getValue($subject); $this->fmt->startRow(); $this->fmt->sep($prop->isStatic() ? '::' : '->'); $this->fmt->colDiv(); $bubbles = array(); if ($prop->isProtected()) { $bubbles[] = array('P', 'Protected'); } if ($prop->isPrivate()) { $bubbles[] = array('!', 'Private'); } $this->fmt->bubbles($bubbles); $type = array('prop'); if ($inherited) { $type[] = 'inherited'; } if ($prop->isPrivate()) { $type[] = 'private'; } $this->fmt->colDiv(2 - count($bubbles)); $this->fmt->startContain($type); $this->fmt->text('name', $prop->name, $meta, $this->linkify($prop)); $this->fmt->endContain(); $this->fmt->colDiv($max - static::strLen($prop->name)); $this->fmt->sep('='); $this->fmt->colDiv(); $this->evaluate($value); $this->fmt->endRow(); } } // class methods if ($methods && !$this->hasInstanceTimedOut()) { $this->fmt->sectionTitle('Methods'); foreach ($methods as $idx => $method) { $this->fmt->startRow(); $this->fmt->sep($method->isStatic() ? '::' : '->'); $this->fmt->colDiv(); $bubbles = array(); if ($method->isAbstract()) { $bubbles[] = array('A', 'Abstract'); } if ($method->isFinal()) { $bubbles[] = array('F', 'Final'); } if ($method->isProtected()) { $bubbles[] = array('P', 'Protected'); } if ($method->isPrivate()) { $bubbles[] = array('!', 'Private'); } $this->fmt->bubbles($bubbles); $this->fmt->colDiv(4 - count($bubbles)); // is this method inherited? $inherited = $reflector->getShortName() !== $method->getDeclaringClass()->getShortName(); $type = array('method'); if ($inherited) { $type[] = 'inherited'; } if ($method->isPrivate()) { $type[] = 'private'; } $this->fmt->startContain($type); $name = $method->name; if ($method->returnsReference()) { $name = "&{$name}"; } $this->fromReflector($method, $name, $reflector); $paramCom = $method->isInternal() ? array() : static::parseComment($method->getDocComment(), 'tags'); $paramCom = empty($paramCom['param']) ? array() : $paramCom['param']; $paramCount = $method->getNumberOfParameters(); $this->fmt->sep('('); // process arguments foreach ($method->getParameters() as $idx => $parameter) { $meta = null; $paramName = "\${$parameter->name}"; $optional = $parameter->isOptional(); $variadic = static::$env['is56'] && $parameter->isVariadic(); if ($parameter->isPassedByReference()) { $paramName = "&{$paramName}"; } if ($variadic) { $paramName = "...{$paramName}"; } $type = array('param'); if ($optional) { $type[] = 'optional'; } $this->fmt->startContain($type); // attempt to build meta foreach ($paramCom as $tag) { list($pcTypes, $pcName, $pcDescription) = $tag; if ($pcName !== $paramName) { continue; } $meta = array('title' => $pcDescription); if ($pcTypes) { $meta['left'] = $pcTypes; } break; } try { $paramClass = $parameter->getClass(); } catch (\Exception $e) { // @see https://bugs.php.net/bug.php?id=32177&edit=1 } if (!empty($paramClass)) { $this->fmt->startContain('hint'); $this->fromReflector($paramClass, $paramClass->name); $this->fmt->endContain(); $this->fmt->sep(' '); } if ($parameter->isArray()) { $this->fmt->text('hint', 'array'); $this->fmt->sep(' '); } $this->fmt->text('name', $paramName, $meta); if ($optional) { $paramValue = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null; $this->fmt->sep(' = '); if (static::$env['is546'] && !$parameter->getDeclaringFunction()->isInternal() && $parameter->isDefaultValueConstant()) { $this->fmt->text('constant', $parameter->getDefaultValueConstantName(), 'Constant'); } else { $this->evaluate($paramValue, true); } } $this->fmt->endContain(); if ($idx < $paramCount - 1) { $this->fmt->sep(', '); } } $this->fmt->sep(')'); $this->fmt->endContain(); $this->fmt->endRow(); } } unset($hashes[$hash]); $this->fmt->endGroup(); $this->fmt->cacheLock($hash); }