diff --git a/CHANGELOG b/CHANGELOG
index 71238630d31c8736005588340a7e3a290821acd4..ee70789babc0df0dc3ff766c6fa727d8c2f9a069 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,7 @@ v 7.14.3
 
 v 7.14.2
   - Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
+  - Allow configuration of LDAP attributes GitLab will use for the new user account.
 
 v 7.14.1
   - Improve abuse reports management from admin area
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index b2bd8796004dbd3c5435b6167698fb2c74e0adeb..0005d44e0f2335c7349e4663175068f510c28d9f 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -159,7 +159,7 @@ production: &base
         method: 'plain' # "tls" or "ssl" or "plain"
         bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
         password: '_the_password_of_the_bind_user'
-
+          
         # This setting specifies if LDAP server is Active Directory LDAP server.
         # For non AD servers it skips the AD specific queries.
         # If your LDAP server is not AD, set this to false.
@@ -196,6 +196,26 @@ production: &base
         #
         user_filter: ''
 
+        # LDAP attributes that GitLab will use to create an account for the LDAP user.
+        # The specified attribute can either be the attribute name as a string (e.g. 'mail'),
+        # or an array of attribute names to try in order (e.g. ['mail', 'email']).
+        # Note that the user's LDAP login will always be the attribute specified as `uid` above.
+        attributes:
+          # The username will be used in paths for the user's own projects
+          # (like `gitlab.example.com/username/project`) and when mentioning
+          # them in issues, merge request and comments (like `@username`).
+          # If the attribute specified for `username` contains an email address, 
+          # the GitLab username will be the part of the email address before the '@'.
+          username: ['uid', 'userid', 'sAMAccountName']
+          email:    ['mail', 'email', 'userPrincipalName']
+
+          # If no full name could be found at the attribute specified for `name`,
+          # the full name is determined using the attributes specified for 
+          # `first_name` and `last_name`.
+          name:       'cn'
+          first_name: 'givenName'
+          last_name:  'sn'
+
       # GitLab EE only: add more LDAP servers
       # Choose an ID made of a-z and 0-9 . This ID will be stored in the database
       # so that GitLab can remember which LDAP server a user belongs to.
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 339419559d118011d00435b87698668c25950b50..fe81ffd420554da441f917229cfa3061b8e38202 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -109,6 +109,7 @@ if Settings.ldap['enabled'] || Rails.env.test?
     server['block_auto_created_users'] = false if server['block_auto_created_users'].nil?
     server['allow_username_or_email_login'] = false if server['allow_username_or_email_login'].nil?
     server['active_directory'] = true if server['active_directory'].nil?
+    server['attributes'] = {} if server['attributes'].nil?
     server['provider_name'] ||= "ldap#{key}".downcase
     server['provider_class'] = OmniAuth::Utils.camelize(server['provider_name'])
   end
diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md
index 904d5d7fee2156cff2b8d59814151e2e21061e1d..3bc5df21ef4232df773e779a102d38df9c652696 100644
--- a/doc/integration/ldap.md
+++ b/doc/integration/ldap.md
@@ -78,6 +78,26 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server
   #
   user_filter: ''
 
+  # LDAP attributes that GitLab will use to create an account for the LDAP user.
+  # The specified attribute can either be the attribute name as a string (e.g. 'mail'),
+  # or an array of attribute names to try in order (e.g. ['mail', 'email']).
+  # Note that the user's LDAP login will always be the attribute specified as `uid` above.
+  attributes:
+    # The username will be used in paths for the user's own projects
+    # (like `gitlab.example.com/username/project`) and when mentioning
+    # them in issues, merge request and comments (like `@username`).
+    # If the attribute specified for `username` contains an email address, 
+    # the GitLab username will be the part of the email address before the '@'.
+    username: ['uid', 'userid', 'sAMAccountName']
+    email:    ['mail', 'email', 'userPrincipalName']
+
+    # If no full name could be found at the attribute specified for `name`,
+    # the full name is determined using the attributes specified for 
+    # `first_name` and `last_name`.
+    name:       'cn'
+    first_name: 'givenName'
+    last_name:  'sn'
+
 # GitLab EE only: add more LDAP servers
 # Choose an ID made of a-z and 0-9 . This ID will be stored in the database
 # so that GitLab can remember which LDAP server a user belongs to.
diff --git a/lib/gitlab/ldap/auth_hash.rb b/lib/gitlab/ldap/auth_hash.rb
new file mode 100644
index 0000000000000000000000000000000000000000..55deeeacd903ec62bdf4b9c83ceed74a044169f5
--- /dev/null
+++ b/lib/gitlab/ldap/auth_hash.rb
@@ -0,0 +1,35 @@
+# Class to parse and transform the info provided by omniauth
+#
+module Gitlab
+  module LDAP
+    class AuthHash < Gitlab::OAuth::AuthHash
+      private
+
+      def get_info(key)
+        attributes = ldap_config.attributes[key]
+        return super unless attributes
+
+        attributes = Array(attributes)
+
+        value = nil
+        attributes.each do |attribute|
+          value = get_raw(attribute)
+          break if value.present?
+        end
+        
+        return super unless value
+
+        Gitlab::Utils.force_utf8(value)
+        value
+      end
+
+      def get_raw(key)
+        auth_hash.extra[:raw_info][key]
+      end
+
+      def ldap_config
+        @ldap_config ||= Gitlab::LDAP::Config.new(self.provider)
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb
index d2ffa2e1fe8d09df464705b1fc5f250014b5c648..101a3285f4bc8c121404a401a783786772b480c9 100644
--- a/lib/gitlab/ldap/config.rb
+++ b/lib/gitlab/ldap/config.rb
@@ -84,6 +84,10 @@ module Gitlab
         options['block_auto_created_users']
       end
 
+      def attributes
+        options['attributes']
+      end
+
       protected
       def base_config
         Gitlab.config.ldap
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index 04a2223747828987bc10b302624897fa5a89d6bd..cb66fd500fe28da06d8db47fcc36b0b5ca212227 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -71,6 +71,10 @@ module Gitlab
       def ldap_config
         Gitlab::LDAP::Config.new(auth_hash.provider)
       end
+
+      def auth_hash=(auth_hash)
+        @auth_hash = Gitlab::LDAP::AuthHash.new(auth_hash)
+      end
     end
   end
 end
diff --git a/lib/gitlab/o_auth/auth_hash.rb b/lib/gitlab/o_auth/auth_hash.rb
index 9b8e783d16c467286efaba5496b9e008776df61b..d94b104bbf86804f2b92e8b1614d0ae95a581a4e 100644
--- a/lib/gitlab/o_auth/auth_hash.rb
+++ b/lib/gitlab/o_auth/auth_hash.rb
@@ -16,16 +16,6 @@ module Gitlab
         @provider ||= Gitlab::Utils.force_utf8(auth_hash.provider.to_s)
       end
 
-      def info
-        auth_hash.info
-      end
-
-      def get_info(key)
-        value = info.try(key)
-        Gitlab::Utils.force_utf8(value) if value
-        value
-      end
-
       def name
         @name ||= get_info(:name) || "#{get_info(:first_name)} #{get_info(:last_name)}"
       end
@@ -44,9 +34,19 @@ module Gitlab
 
       private
 
+      def info
+        auth_hash.info
+      end
+
+      def get_info(key)
+        value = info[key]
+        Gitlab::Utils.force_utf8(value) if value
+        value
+      end
+
       def username_and_email
         @username_and_email ||= begin
-          username  = get_info(:nickname) || get_info(:username)
+          username  = get_info(:username) || get_info(:nickname)
           email     = get_info(:email)
 
           username ||= generate_username(email)             if email
diff --git a/spec/lib/gitlab/ldap/auth_hash_spec.rb b/spec/lib/gitlab/ldap/auth_hash_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..18c7924fea132370a58a1322461905ad195d6995
--- /dev/null
+++ b/spec/lib/gitlab/ldap/auth_hash_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe Gitlab::LDAP::AuthHash do
+  let(:auth_hash) do
+    Gitlab::LDAP::AuthHash.new(
+      OmniAuth::AuthHash.new(
+        uid: '123456', 
+        provider: 'ldapmain', 
+        info: info,
+        extra: {
+          raw_info: raw_info
+        }
+      )
+    )
+  end
+
+  let(:info) do
+    {
+      name:     'Smith, J.',
+      email:    'johnsmith@example.com',
+      nickname: '123456'
+    }
+  end
+
+  let(:raw_info) do
+    {
+      uid:      '123456',
+      email:    'johnsmith@example.com',
+      cn:       'Smith, J.',
+      fullName: 'John Smith'
+    }
+  end
+
+  context "without overridden attributes" do
+
+    it "has the correct username" do
+      expect(auth_hash.username).to eq("123456") 
+    end
+
+    it "has the correct name" do
+      expect(auth_hash.name).to eq("Smith, J.") 
+    end
+  end
+
+  context "with overridden attributes" do
+    let(:attributes) do
+      {
+        username: ['mail', 'email'],
+        name:     'fullName'
+      }
+    end
+
+    before do
+      allow_any_instance_of(Gitlab::LDAP::Config).to receive(:attributes).and_return(attributes)
+    end
+
+    it "has the correct username" do
+      expect(auth_hash.username).to eq("johnsmith@example.com") 
+    end
+
+    it "has the correct name" do
+      expect(auth_hash.name).to eq("John Smith") 
+    end
+  end
+end
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index 84d9fb54b615fee2ad102e1a41dd1dd43f1f5932..fd2e5f6d0e170df0dc56f347b2f99d61fb3b04e6 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::LDAP::User do
     }
   end
   let(:auth_hash) do
-    double(uid: 'my-uid', provider: 'ldapmain', info: double(info))
+    OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info)
   end
 
   describe :changed? do
diff --git a/spec/lib/gitlab/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
index e4a6cd954cc6ef1f06f506a3dbc5b70189692565..5632f2306ec6f5ce037e5f46957db3b449161e89 100644
--- a/spec/lib/gitlab/o_auth/auth_hash_spec.rb
+++ b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
@@ -3,11 +3,11 @@ require 'spec_helper'
 describe Gitlab::OAuth::AuthHash do
   let(:auth_hash) do
     Gitlab::OAuth::AuthHash.new(
-      double({
+      OmniAuth::AuthHash.new(
         provider: provider_ascii,
         uid: uid_ascii,
-        info: double(info_hash)
-      })
+        info: info_hash
+      )
     )
   end
 
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index c6cca98a037dcf0ddcf675971e83a076f83ee3af..c0083fc85be562fa9fc7818affceb551814d3690 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::OAuth::User do
   let(:gl_user) { oauth_user.gl_user }
   let(:uid) { 'my-uid' }
   let(:provider) { 'my-provider' }
-  let(:auth_hash) { double(uid: uid, provider: provider, info: double(info_hash)) }
+  let(:auth_hash) { OmniAuth::AuthHash.new(uid: uid, provider: provider, info: info_hash) }
   let(:info_hash) do
     {
       nickname: '-john+gitlab-ETC%.git@gmail.com',