You are here

function simple_ldap_server_check in Simple LDAP 7.2

Run some basic tests to make debugging LDAP connections easier.

1 string reference to 'simple_ldap_server_check'
simple_ldap_menu in ./simple_ldap.module
Implements hook_menu().

File

./simple_ldap.admin.inc, line 158
Functions for Simple LDAP admin interface.

Code

function simple_ldap_server_check() {
  $ldap_host = variable_get('simple_ldap_host', '');
  $matches = array();
  $results = array();
  if (empty($ldap_host)) {
    $error = t('No host speciifed.  Set a host in <a href="@url">LDAP Settings</a> and try again.', array(
      '@url' => url('admin/config/people/simple_ldap/server/settings'),
    ));
    return "<p>{$error}</p>";
  }

  // Strip it apart.
  preg_match('/(ldap[si]?):\\/\\/([^:\\/]*)(:(\\d*))?(\\/)?(.*)/', $ldap_host, $matches);
  if (empty($matches)) {
    $error = t('Could not parse host %host.  Check <a href="@url">LDAP Settings</a> and try again.', array(
      '@url' => url('admin/config/people/simple_ldap/server/settings'),
      '%host' => $ldap_host,
    ));
    return "<p>{$error}</p>";
  }
  $proto = $matches[1];
  $host = $matches[2];
  $port = $matches[4];
  $extra = $matches[5];

  //
  // Test 1 - Report the connection type.
  //
  switch ($proto) {
    case 'ldap':
      $connection = t('Unencrypted LDAP connection');
      break;
    case 'ldaps':
      $connection = t('Encrypted LDAP connection');
      break;
    case 'ldapi':
      $connection = t('Connection over UNIX socket');
      break;
    default:
      $connection = t('Unknown connection type');
  }
  $results[] = array(
    'class' => array(
      'ldap-test-information',
    ),
    'data' => array(
      t('Connection Type'),
      $connection,
    ),
  );

  //
  // Test 2 - If it's not socket-based, lookup the host / IP in DNS.
  //
  if (!empty($host)) {
    $php_ipv6 = defined('AF_INET6');
    $is_ipaddr = @inet_pton($host);
    $status = 'ldap-test-ok';
    if ($is_ipaddr) {
      $hostname = gethostbyaddr($host);
      $ip_list = array(
        $host,
      );
    }
    else {
      $ip_list = gethostbynamel($host);
      $hostname = $host;
    }
    if ($ip_list === FALSE || $hostname === FALSE) {
      $dns_result = t('Could not fetch DNS information about @address', array(
        '@address' => $host,
      ));
      $status = 'ldap-test-warning';
    }
    else {
      $dns_result = "{$host} resolves as {$hostname} (" . implode(', ', $ip_list) . ')';
    }
    $results[] = array(
      'class' => array(
        $status,
      ),
      'data' => array(
        t('DNS Checks'),
        $dns_result,
      ),
    );
  }

  //
  // Test 3 - Make a simple TCP connection to the server and port.
  //
  // If this test fails, then it's probably a connectivity issue.
  //
  if (!empty($host)) {
    if (empty($port)) {
      $port = variable_get('simple_ldap_port', '389');
    }
    if (empty($port)) {
      $port = $proto == 'ldaps' ? '636' : '389';
    }
    $waitTimeoutInSeconds = 5;
    $starttime = microtime(true);
    $fp = @fsockopen($host, (int) $port, $errCode, $errStr, $waitTimeoutInSeconds);
    $stoptime = microtime(true);
    $connect_test = $fp ? 'Connected in @time ms to %host:%port.' : 'Failed to establish connection to %host:%port in @time ms: @error.';
    $results[] = array(
      'class' => $fp ? array(
        'ldap-test-ok',
      ) : array(
        'ldap-test-error',
      ),
      'data' => array(
        t('TCP Connection Check'),
        t($connect_test, array(
          '%host' => $host,
          '%port' => $port,
          '@time' => (int) (($stoptime - $starttime) * 1000),
          '@error' => $errStr,
        )),
      ),
    );
    if ($fp) {
      fclose($fp);
    }
    if ($proto == 'ldaps' && $port == '389') {
      $results[] = array(
        'class' => array(
          'ldap-test-warning',
        ),
        'data' => array(
          t('PROTOCOL MISMATCH'),
          t('Attempting to connect with SSL/TLS to default unencrypted port.'),
        ),
      );
    }
    if ($proto == 'ldap' && $port == '636') {
      $results[] = array(
        'class' => array(
          'ldap-test-warning',
        ),
        'data' => array(
          t('PROTOCOL MISMATCH'),
          t('Attempting to connect without encryption to default LDAP SSL port.'),
        ),
      );
    }
  }

  //
  // Test 4 - Try to bind to the server
  //
  $error = '';
  try {
    $server = SimpleLdapServer::singleton();
  } catch (SimpleLdapException $e) {
    $error = $e
      ->getMessage();
    dpm($e);
  }
  if ($server->bound) {
    $results[] = array(
      'class' => array(
        'ldap-test-ok',
      ),
      'data' => array(
        t('Bind to Server'),
        t('Success'),
      ),
    );
  }
  else {
    $results[] = array(
      'class' => array(
        'ldap-test-error',
      ),
      'data' => array(
        t('Bind to Server'),
        t('Failed with error: @error', array(
          '@error' => $error,
        )),
      ),
    );
  }

  //
  // Add a line identifying the kind of LDAP server we have.
  //
  $results[] = array(
    'class' => array(
      'ldap-test-information',
    ),
    'data' => array(
      t('Server Type'),
      $server->type,
    ),
  );

  //
  // Test 6 - Load the RootDSE to share some basic data about the server
  //
  try {
    $rootdse = $server
      ->__get('rootdse');
  } catch (SimpleLdapException $e) {
    $rootdse = array();
  }
  if ($rootdse) {
    $results[] = array(
      'class' => array(
        'ldap-test-ok',
      ),
      'data' => array(
        t('Base DNs'),
        theme('item_list', array(
          'items' => $rootdse['namingcontexts'],
        )),
      ),
    );
  }
  else {
    $results[] = array(
      'class' => array(
        'ldap-test-error',
      ),
      'data' => array(
        t('Base DNs'),
        t('Could not fetch server information.'),
      ),
    );
  }

  //
  // Test 7 - Pull the list of supported ObjectClasses.
  //
  $error = '';
  try {
    $objectclasses = $server->schema
      ->get('objectclasses');
  } catch (SimpleLdapException $e) {
    $error = $e
      ->getMessage();
  }
  if (empty($objectclasses)) {
    $results[] = array(
      'class' => array(
        'ldap-test-warning',
      ),
      'data' => array(
        t('Object Classes'),
        t('No object classes found. @error', array(
          '@error' => $error,
        )),
      ),
    );
  }
  else {
    $results[] = array(
      'class' => array(
        'ldap-test-ok',
      ),
      'data' => array(
        t('Object Classes'),
        theme('item_list', array(
          'items' => array_map('_simple_ldap_objectclass_map', $objectclasses),
        )),
      ),
    );
  }

  //
  // Generate the report
  //
  $header = array(
    'Test',
    'Result',
  );
  $table = array(
    'header' => $header,
    'rows' => $results,
    'attributes' => array(
      'class' => array(
        'ldap-report',
      ),
      'id' => 'simple-ldap-debug-report',
    ),
  );
  drupal_add_css(drupal_get_path('module', 'simple_ldap') . '/simple_ldap.css');
  return theme('table', $table);
}