diff options
Diffstat (limited to 'doc/administration/auth/ldap/ldap-troubleshooting.md')
-rw-r--r-- | doc/administration/auth/ldap/ldap-troubleshooting.md | 678 |
1 files changed, 678 insertions, 0 deletions
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md new file mode 100644 index 00000000000..909802b5dec --- /dev/null +++ b/doc/administration/auth/ldap/ldap-troubleshooting.md @@ -0,0 +1,678 @@ +--- +type: reference +stage: Manage +group: Access +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers +--- + +# LDAP Troubleshooting for Administrators + +## Common Problems & Workflows + +### Connection + +#### Connection refused + +If you are getting `Connection Refused` errors when trying to connect to the +LDAP server please double-check the LDAP `port` and `encryption` settings used by +GitLab. Common combinations are `encryption: 'plain'` and `port: 389`, OR +`encryption: 'simple_tls'` and `port: 636`. + +#### Connection times out + +If GitLab cannot reach your LDAP endpoint, you will see a message like this: + +```plaintext +Could not authenticate you from Ldapmain because "Connection timed out - user specified timeout". +``` + +If your configured LDAP provider and/or endpoint is offline or otherwise +unreachable by GitLab, no LDAP user will be able to authenticate and log in. +GitLab does not cache or store credentials for LDAP users to provide authentication +during an LDAP outage. + +Contact your LDAP provider or administrator if you are seeing this error. + +#### Referral error + +If you see `LDAP search error: Referral` in the logs, or when troubleshooting +LDAP Group Sync, this error may indicate a configuration problem. The LDAP +configuration `/etc/gitlab/gitlab.rb` (Omnibus) or `config/gitlab.yml` (source) +is in YAML format and is sensitive to indentation. Check that `group_base` and +`admin_group` configuration keys are indented 2 spaces past the server +identifier. The default identifier is `main` and an example snippet looks like +the following: + +```yaml +main: # 'main' is the GitLab 'provider ID' of this LDAP server + label: 'LDAP' + host: 'ldap.example.com' + ... + group_base: 'cn=my_group,ou=groups,dc=example,dc=com' + admin_group: 'my_admin_group' +``` + +#### Query LDAP **(STARTER ONLY)** + +The following allows you to perform a search in LDAP using the rails console. +Depending on what you're trying to do, it may make more sense to query [a +user](#query-a-user-in-ldap) or [a group](#query-a-group-in-ldap-starter-only) directly, or +even [use `ldapsearch`](#ldapsearch) instead. + +```ruby +adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') +options = { + # :base is required + # use .base or .group_base + base: adapter.config.group_base, + + # :filter is optional + # 'cn' looks for all "cn"s under :base + # '*' is the search string - here, it's a wildcard + filter: Net::Ldap::Filter.eq('cn', '*'), + + # :attributes is optional + # the attributes we want to get returned + attributes: %w(dn cn memberuid member submember uniquemember memberof) +} +adapter.ldap_search(options) +``` + +For examples of how this is run, +[review the `Adapter` module](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/lib/ee/gitlab/auth/ldap/adapter.rb). + +### User logins + +#### No users are found + +If [you've confirmed](#ldap-check) that a connection to LDAP can be +established but GitLab doesn't show you LDAP users in the output, one of the +following is most likely true: + +- The `bind_dn` user doesn't have enough permissions to traverse the user tree. +- The user(s) don't fall under the [configured `base`](index.md#configuration-core-only). +- The [configured `user_filter`](index.md#set-up-ldap-user-filter-core-only) blocks access to the user(s). + +In this case, you con confirm which of the above is true using +[ldapsearch](#ldapsearch) with the existing LDAP configuration in your +`/etc/gitlab/gitlab.rb`. + +#### User(s) cannot login + +A user can have trouble logging in for any number of reasons. To get started, +here are some questions to ask yourself: + +- Does the user fall under the [configured `base`](index.md#configuration-core-only) in + LDAP? The user must fall under this `base` to login. +- Does the user pass through the [configured `user_filter`](index.md#set-up-ldap-user-filter-core-only)? + If one is not configured, this question can be ignored. If it is, then the + user must also pass through this filter to be allowed to login. + - Refer to our docs on [debugging the `user_filter`](#debug-ldap-user-filter). + +If the above are both okay, the next place to look for the problem is +the logs themselves while reproducing the issue. + +- Ask the user to login and let it fail. +- [Look through the output](#gitlab-logs) for any errors or other + messages about the login. You may see one of the other error messages on + this page, in which case that section can help resolve the issue. + +If the logs don't lead to the root of the problem, use the +[rails console](#rails-console) to [query this user](#query-a-user-in-ldap) +to see if GitLab can read this user on the LDAP server. + +It can also be helpful to +[debug a user sync](#sync-all-users-starter-only) to +investigate further. + +#### Invalid credentials on login + +If that the login credentials used are accurate on LDAP, ensure the following +are true for the user in question: + +- Make sure the user you are binding with has enough permissions to read the user's + tree and traverse it. +- Check that the `user_filter` is not blocking otherwise valid users. +- Run [an LDAP check command](#ldap-check) to make sure that the LDAP settings + are correct and [GitLab can see your users](#no-users-are-found). + +#### Email has already been taken + +A user tries to login with the correct LDAP credentials, is denied access, +and the [production.log](../../logs.md#productionlog) shows an error that looks like this: + +```plaintext +(LDAP) Error saving user <USER DN> (email@example.com): ["Email has already been taken"] +``` + +This error is referring to the email address in LDAP, `email@example.com`. Email +addresses must be unique in GitLab and LDAP links to a user's primary email (as opposed +to any of their possibly-numerous secondary emails). Another user (or even the +same user) has the email `email@example.com` set as a secondary email, which +is throwing this error. + +We can check where this conflicting email address is coming from using the +[rails console](#rails-console). Once in the console, run the following: + +```ruby +# This searches for an email among the primary AND secondary emails +user = User.find_by_any_email('email@example.com') +user.username +``` + +This will show you which user has this email address. One of two steps will +have to be taken here: + +- To create a new GitLab user/username for this user when logging in with LDAP, + remove the secondary email to remove the conflict. +- To use an existing GitLab user/username for this user to use with LDAP, + remove this email as a secondary email and make it a primary one so GitLab + will associate this profile to the LDAP identity. + +The user can do either of these steps [in their +profile](../../../user/profile/index.md#user-profile) or an admin can do it. + +#### Debug LDAP user filter + +[`ldapsearch`](#ldapsearch) allows you to test your configured +[user filter](index.md#set-up-ldap-user-filter-core-only) +to confirm that it returns the users you expect it to return. + +```shell +ldapsearch -H ldaps://$host:$port -D "$bind_dn" -y bind_dn_password.txt -b "$base" "$user_filter" sAMAccountName +``` + +- Variables beginning with a `$` refer to a variable from the LDAP section of + your configuration file. +- Replace `ldaps://` with `ldap://` if you are using the plain authentication method. + Port `389` is the default `ldap://` port and `636` is the default `ldaps://` + port. +- We are assuming the password for the `bind_dn` user is in `bind_dn_password.txt`. + +#### Sync all users **(STARTER ONLY)** + +The output from a manual [user sync](index.md#user-sync-starter-only) can show you what happens when +GitLab tries to sync its users against LDAP. Enter the [rails console](#rails-console) +and then run: + +```ruby +Rails.logger.level = Logger::DEBUG + +LdapSyncWorker.new.perform +``` + +Next, [learn how to read the +output](#example-console-output-after-a-user-sync-starter-only). + +##### Example console output after a user sync **(STARTER ONLY)** + +The output from a [manual user sync](#sync-all-users-starter-only) will be very verbose, and a +single user's successful sync can look like this: + +```shell +Syncing user John, email@example.com + Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1 +Instantiating Gitlab::Auth::Ldap::Person with LDIF: +dn: cn=John Smith,ou=people,dc=example,dc=com +cn: John Smith +mail: email@example.com +memberof: cn=admin_staff,ou=people,dc=example,dc=com +uid: John + + UserSyncedAttributesMetadata Load (0.9ms) SELECT "user_synced_attributes_metadata".* FROM "user_synced_attributes_metadata" WHERE "user_synced_attributes_metadata"."user_id" = 20 LIMIT 1 + (0.3ms) BEGIN + Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."owner_id" = 20 AND "namespaces"."type" IS NULL LIMIT 1 + Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE "routes"."source_id" = 27 AND "routes"."source_type" = 'Namespace' LIMIT 1 + Ci::Runner Load (1.1ms) SELECT "ci_runners".* FROM "ci_runners" INNER JOIN "ci_runner_namespaces" ON "ci_runners"."id" = "ci_runner_namespaces"."runner_id" WHERE "ci_runner_namespaces"."namespace_id" = 27 + (0.7ms) COMMIT + (0.4ms) BEGIN + Route Load (0.8ms) SELECT "routes".* FROM "routes" WHERE (LOWER("routes"."path") = LOWER('John')) + Namespace Load (1.0ms) SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."id" = 27 LIMIT 1 + Route Exists (0.9ms) SELECT 1 AS one FROM "routes" WHERE LOWER("routes"."path") = LOWER('John') AND "routes"."id" != 50 LIMIT 1 + User Update (1.1ms) UPDATE "users" SET "updated_at" = '2019-10-17 14:40:59.751685', "last_credential_check_at" = '2019-10-17 14:40:59.738714' WHERE "users"."id" = 20 +``` + +There's a lot here, so let's go over what could be helpful when debugging. + +First, GitLab will look for all users that have previously +logged in with LDAP and iterate on them. Each user's sync will start with +the following line that contains the user's username and email, as they +exist in GitLab now: + +```shell +Syncing user John, email@example.com +``` + +If you don't find a particular user's GitLab email in the output, then that +user hasn't logged in with LDAP yet. + +Next, GitLab searches its `identities` table for the existing +link between this user and the configured LDAP provider(s): + +```sql + Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1 +``` + +The identity object will have the DN that GitLab will use to look for the user +in LDAP. If the DN isn't found, the email is used instead. We can see that +this user is found in LDAP: + +```shell +Instantiating Gitlab::Auth::Ldap::Person with LDIF: +dn: cn=John Smith,ou=people,dc=example,dc=com +cn: John Smith +mail: email@example.com +memberof: cn=admin_staff,ou=people,dc=example,dc=com +uid: John +``` + +If the user wasn't found in LDAP with either the DN or email, you may see the +following message instead: + +```shell +LDAP search error: No Such Object +``` + +...in which case the user will be blocked: + +```shell + User Update (0.4ms) UPDATE "users" SET "state" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["state", "ldap_blocked"], ["updated_at", "2019-10-18 15:46:22.902177"], ["id", 20]] +``` + +Once the user is found in LDAP the rest of the output will update the GitLab +database with any changes. + +#### Query a user in LDAP + +This will test that GitLab can reach out to LDAP and read a particular user. +It can expose potential errors connecting to and/or querying LDAP +that may seem to fail silently in the GitLab UI. + +```ruby +Rails.logger.level = Logger::DEBUG + +adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider +Gitlab::Auth::Ldap::Person.find_by_uid('<uid>', adapter) +``` + +### Group memberships **(STARTER ONLY)** + +#### Membership(s) not granted **(STARTER ONLY)** + +Sometimes you may think a particular user should be added to a GitLab group via +LDAP group sync, but for some reason it's not happening. There are several +things to check to debug the situation. + +- Ensure LDAP configuration has a `group_base` specified. + [This configuration](index.md#group-sync-starter-only) is required for group sync to work properly. +- Ensure the correct [LDAP group link is added to the GitLab + group](index.md#adding-group-links-starter-only). +- Check that the user has an LDAP identity: + 1. Sign in to GitLab as an administrator user. + 1. Navigate to **Admin area -> Users**. + 1. Search for the user + 1. Open the user, by clicking on their name. Do not click 'Edit'. + 1. Navigate to the **Identities** tab. There should be an LDAP identity with + an LDAP DN as the 'Identifier'. If not, this user hasn't logged in with + LDAP yet and must do so first. +- You've waited an hour or [the configured + interval](index.md#adjusting-ldap-group-sync-schedule-starter-only) for the group to + sync. To speed up the process, either go to the GitLab group **Settings -> + Members** and press **Sync now** (sync one group) or [run the group sync Rake + task](../../raketasks/ldap.md#run-a-group-sync-starter-only) (sync all groups). + +If all of the above looks good, jump in to a little more advanced debugging in +the rails console. + +1. Enter the [rails console](#rails-console). +1. Choose a GitLab group to test with. This group should have an LDAP group link + already configured. +1. [Enable debug logging, find the above GitLab group, and sync it with LDAP](#sync-one-group-starter-only). +1. Look through the output of the sync. See [example log + output](#example-console-output-after-a-group-sync-starter-only) + for how to read the output. +1. If you still aren't able to see why the user isn't being added, [query the + LDAP group directly](#query-a-group-in-ldap-starter-only) to see what members are listed. +1. Is the user's DN or UID in one of the lists from the above output? One of the DNs or + UIDs here should match the 'Identifier' from the LDAP identity checked earlier. If it doesn't, + the user does not appear to be in the LDAP group. + +#### Admin privileges not granted + +When [Administrator sync](index.md#administrator-sync-starter-only) has been configured +but the configured users aren't granted the correct admin privileges, confirm +the following are true: + +- A [`group_base` is also configured](index.md#group-sync-starter-only). +- The configured `admin_group` in the `gitlab.rb` is a CN, rather than a DN or an array. +- This CN falls under the scope of the configured `group_base`. +- The members of the `admin_group` have already logged into GitLab with their LDAP + credentials. GitLab will only grant this admin access to the users whose + accounts are already connected to LDAP. + +If all the above are true and the users are still not getting access, [run a manual +group sync](#sync-all-groups-starter-only) in the rails console and [look through the +output](#example-console-output-after-a-group-sync-starter-only) to see what happens when +GitLab syncs the `admin_group`. + +#### Sync all groups **(STARTER ONLY)** + +NOTE: **NOTE:** +To sync all groups manually when debugging is unnecessary, [use the Rake +task](../../raketasks/ldap.md#run-a-group-sync-starter-only) instead. + +The output from a manual [group sync](index.md#group-sync-starter-only) can show you what happens +when GitLab syncs its LDAP group memberships against LDAP. + +```ruby +Rails.logger.level = Logger::DEBUG + +LdapAllGroupsSyncWorker.new.perform +``` + +Next, [learn how to read the +output](#example-console-output-after-a-group-sync-starter-only). + +##### Example console output after a group sync **(STARTER ONLY)** + +Like the output from the user sync, the output from the [manual group +sync](#sync-all-groups-starter-only) will also be very verbose. However, it contains lots +of helpful information. + +Indicates the point where syncing actually begins: + +```shell +Started syncing 'ldapmain' provider for 'my_group' group +``` + +The following entry shows an array of all user DNs GitLab sees in the LDAP server. +Note that these are the users for a single LDAP group, not a GitLab group. If +you have multiple LDAP groups linked to this GitLab group, you will see multiple +log entries like this - one for each LDAP group. If you don't see an LDAP user +DN in this log entry, LDAP is not returning the user when we do the lookup. +Verify the user is actually in the LDAP group. + +```shell +Members in 'ldap_group_1' LDAP group: ["uid=john0,ou=people,dc=example,dc=com", +"uid=mary0,ou=people,dc=example,dc=com", "uid=john1,ou=people,dc=example,dc=com", +"uid=mary1,ou=people,dc=example,dc=com", "uid=john2,ou=people,dc=example,dc=com", +"uid=mary2,ou=people,dc=example,dc=com", "uid=john3,ou=people,dc=example,dc=com", +"uid=mary3,ou=people,dc=example,dc=com", "uid=john4,ou=people,dc=example,dc=com", +"uid=mary4,ou=people,dc=example,dc=com"] +``` + +Shortly after each of the above entries, you will see a hash of resolved member +access levels. This hash represents all user DNs GitLab thinks should have +access to this group, and at which access level (role). This hash is additive, +and more DNs may be added, or existing entries modified, based on additional +LDAP group lookups. The very last occurrence of this entry should indicate +exactly which users GitLab believes should be added to the group. + +NOTE: **Note:** +10 is 'Guest', 20 is 'Reporter', 30 is 'Developer', 40 is 'Maintainer' +and 50 is 'Owner'. + +```shell +Resolved 'my_group' group member access: {"uid=john0,ou=people,dc=example,dc=com"=>30, +"uid=mary0,ou=people,dc=example,dc=com"=>30, "uid=john1,ou=people,dc=example,dc=com"=>30, +"uid=mary1,ou=people,dc=example,dc=com"=>30, "uid=john2,ou=people,dc=example,dc=com"=>30, +"uid=mary2,ou=people,dc=example,dc=com"=>30, "uid=john3,ou=people,dc=example,dc=com"=>30, +"uid=mary3,ou=people,dc=example,dc=com"=>30, "uid=john4,ou=people,dc=example,dc=com"=>30, +"uid=mary4,ou=people,dc=example,dc=com"=>30} +``` + +It's not uncommon to see warnings like the following. These indicate that GitLab +would have added the user to a group, but the user could not be found in GitLab. +Usually this is not a cause for concern. + +If you think a particular user should already exist in GitLab, but you're seeing +this entry, it could be due to a mismatched DN stored in GitLab. See +[User DN and/or email have changed](#user-dn-orand-email-have-changed) to update the user's LDAP identity. + +```shell +User with DN `uid=john0,ou=people,dc=example,dc=com` should have access +to 'my_group' group but there is no user in GitLab with that +identity. Membership will be updated once the user signs in for +the first time. +``` + +Finally, the following entry says syncing has finished for this group: + +```shell +Finished syncing all providers for 'my_group' group +``` + +Once all the configured group links have been synchronized, GitLab will look +for any Administrators or External users to sync: + +```shell +Syncing admin users for 'ldapmain' provider +``` + +The output will look similar to what happens with a single group, and then +this line will indicate the sync is finished: + +```shell +Finished syncing admin users for 'ldapmain' provider +``` + +If [admin sync](index.md#administrator-sync-starter-only) is not configured, you'll see a message +stating as such: + +```shell +No `admin_group` configured for 'ldapmain' provider. Skipping +``` + +#### Sync one group **(STARTER ONLY)** + +[Syncing all groups](#sync-all-groups-starter-only) can produce a lot of noise in the output, which can be +distracting when you're only interested in troubleshooting the memberships of +a single GitLab group. In that case, here's how you can just sync this group +and see its debug output: + +```ruby +Rails.logger.level = Logger::DEBUG + +# Find the GitLab group. +# If the output is `nil`, the group could not be found. +# If a bunch of group attributes are in the output, your group was found successfully. +group = Group.find_by(name: 'my_gitlab_group') + +# Sync this group against LDAP +EE::Gitlab::Auth::Ldap::Sync::Group.execute_all_providers(group) +``` + +The output will be similar to +[that you'd get from syncing all groups](#example-console-output-after-a-group-sync-starter-only). + +#### Query a group in LDAP **(STARTER ONLY)** + +When you'd like to confirm that GitLab can read a LDAP group and see all its members, +you can run the following: + +```ruby +# Find the adapter and the group itself +adapter = Gitlab::Auth::Ldap::Adapter.new('ldapmain') # If `main` is the LDAP provider +ldap_group = EE::Gitlab::Auth::Ldap::Group.find_by_cn('group_cn_here', adapter) + +# Find the members of the LDAP group +ldap_group.member_dns +ldap_group.member_uids +``` + +### User DN or/and email have changed + +When an LDAP user is created in GitLab, their LDAP DN is stored for later reference. + +If GitLab cannot find a user by their DN, it will fall back +to finding the user by their email. If the lookup is successful, GitLab will +update the stored DN to the new value so both values will now match what's in +LDAP. + +If the email has changed and the DN has not, GitLab will find the user with +the DN and update its own record of the user's email to match the one in LDAP. + +However, if the primary email _and_ the DN change in LDAP, then GitLab will +have no way of identifying the correct LDAP record of the user and, as a +result, the user will be blocked. To rectify this, the user's existing +profile will have to be updated with at least one of the new values (primary +email or DN) so the LDAP record can be found. + +The following script will update the emails for all provided users so they +won't be blocked or unable to access their accounts. + +>**NOTE**: The following script will require that any new accounts with the new +email address are removed first. This is because emails have to be unique in GitLab. + +Go to the [rails console](#rails-console) and then run: + +```ruby +# Each entry will have to include the old username and the new email +emails = { + 'ORIGINAL_USERNAME' => 'NEW_EMAIL_ADDRESS', + ... +} + +emails.each do |username, email| + user = User.find_by_username(username) + user.email = email + user.skip_reconfirmation! + user.save! +end +``` + +You can then [run a UserSync](#sync-all-users-starter-only) **(STARTER ONLY)** to sync the latest DN +for each of these users. + +## Debugging Tools + +### LDAP check + +The [Rake task to check LDAP](../../raketasks/ldap.md#check) is a valuable tool +to help determine whether GitLab can successfully establish a connection to +LDAP and can get so far as to even read users. + +If a connection can't be established, it is likely either because of a problem +with your configuration or a firewall blocking the connection. + +- Ensure you don't have a firewall blocking the +connection, and that the LDAP server is accessible to the GitLab host. +- Look for an error message in the Rake check output, which may lead to your LDAP configuration to +confirm that the configuration values (specifically `host`, `port`, `bind_dn`, and +`password`) are correct. +- Look for [errors](#connection) in [the logs](#gitlab-logs) to further debug connection failures. + +If GitLab can successfully connect to LDAP but doesn't return any +users, [see what to do when no users are found](#no-users-are-found). + +### GitLab logs + +If a user account is blocked or unblocked due to the LDAP configuration, a +message will be [logged to `application.log`](../../logs.md#applicationlog). + +If there is an unexpected error during an LDAP lookup (configuration error, +timeout), the login is rejected and a message will be [logged to +`production.log`](../../logs.md#productionlog). + +### ldapsearch + +`ldapsearch` is a utility that will allow you to query your LDAP server. You can +use it to test your LDAP settings and ensure that the settings you're using +will get you the results you expect. + +When using `ldapsearch`, be sure to use the same settings you've already +specified in your `gitlab.rb` configuration so you can confirm what happens +when those exact settings are used. + +Running this command on the GitLab host will also help confirm that there's no +obstruction between the GitLab host and LDAP. + +For example, consider the following GitLab configuration: + +```shell +gitlab_rails['ldap_servers'] = YAML.load <<-'EOS' # remember to close this block with 'EOS' below + main: # 'main' is the GitLab 'provider ID' of this LDAP server + label: 'LDAP' + host: '127.0.0.1' + port: 389 + uid: 'uid' + encryption: 'plain' + bind_dn: 'cn=admin,dc=ldap-testing,dc=example,dc=com' + password: 'Password1' + active_directory: true + allow_username_or_email_login: false + block_auto_created_users: false + base: 'dc=ldap-testing,dc=example,dc=com' + user_filter: '' + attributes: + username: ['uid', 'userid', 'sAMAccountName'] + email: ['mail', 'email', 'userPrincipalName'] + name: 'cn' + first_name: 'givenName' + last_name: 'sn' + group_base: 'ou=groups,dc=ldap-testing,dc=example,dc=com' + admin_group: 'gitlab_admin' +EOS +``` + +You would run the following `ldapsearch` to find the `bind_dn` user: + +```shell +ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \ + -w Password1 \ + -p 389 \ + -h 127.0.0.1 \ + -b "dc=ldap-testing,dc=example,dc=com" +``` + +Note that the `bind_dn`, `password`, `port`, `host`, and `base` are all +identical to what's configured in the `gitlab.rb`. + +Please see [the official +`ldapsearch` documentation](https://linux.die.net/man/1/ldapsearch) for more. + +### Using **AdFind** (Windows) + +You can use the [`AdFind`](https://social.technet.microsoft.com/wiki/contents/articles/7535.adfind-command-examples.aspx) utility (on Windows based systems) to test that your LDAP server is accessible and authentication is working correctly. This is a freeware utility built by [Joe Richards](http://www.joeware.net/freetools/tools/adfind/index.htm). + +**Return all objects** + +You can use the filter `objectclass=*` to return all directory objects. + +```shell +adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (objectClass=*) +``` + +**Return single object using filter** + +You can also retrieve a single object by **specifying** the object name or full **DN**. In this example we specify the object name only `CN=Leroy Fox`. + +```shell +adfind -h ad.example.org:636 -ssl -u "CN=GitLabSRV,CN=Users,DC=GitLab,DC=org" -up Password1 -b "OU=GitLab INT,DC=GitLab,DC=org" -f (&(objectcategory=person)(CN=Leroy Fox))” +``` + +### Rails console + +CAUTION: **CAUTION:** +Please note that it is very easy to create, read, modify, and destroy data on the +rails console, so please be sure to run commands exactly as listed. + +The rails console is a valuable tool to help debug LDAP problems. It allows you to +directly interact with the application by running commands and seeing how GitLab +responds to them. + +Please refer to [this guide](../../troubleshooting/debug.md#starting-a-rails-console-session) +for instructions on how to use the rails console. + +#### Enable debug output + +This will provide debug output that will be useful to see +what GitLab is doing and with what. This value is not persisted, and will only +be enabled for this session in the rails console. + +To enable debug output in the rails console, [enter the rails +console](#rails-console) and run: + +```ruby +Rails.logger.level = Logger::DEBUG +``` |