Dec 302011

A while back, I described a method for authenticating CentOS and RHEL servers to Active Directory using LDAP.  While this approach is easy to set up and works right out of the gate, there are a few drawbacks to it that I’ve run across:

  • Changing passwords from the Linux server does not work unless you set up LDAP over TLS/SSL, which I’ve found very difficult (though not impossible!) to accomplish
  • While changing the passwords does work, it can be very user unfriendly.  In particular error messages given are very cryptic to the lay user.  Unless you are in IT, you’re not going to know or care about the LDAP error codes that are reported back, nor are you going to want to research what the appropriate character classes are for the AD passwords so that you can choose from at least three of them appropriately.

In this article, I’ll describe how to use winbind to join your Linux server to a Microsoft Active Directory and become a domain member.

First, you need to set up your users in AD with the required POSIX attributes.  At a minimum, you need to set only two attributes, uidNumber and gidNumber.  For the uidNumber, I recommend using the RID of the user you are setting these attributes for.  You can also set unixHomeDirectory, gecos and loginShell if you want to maintain this information in AD.  These are optional in the set up I am proposing, so it could be considered more of a best practice than a requirement.  So my user object looks something like this (many many attributes omitted for brevity):

Then you need a group to go with it.  Note that I’ve set this user’s gidNumber to 513.  In order for winbind to operate, the gidNumber in AD needs to be set to a group that exists in AD – that is, a user’s primary group can’t be a local group.  The user simply will be ignored by winbind and therefore Unix.  Keeping that in mind, this is the object dump of my AD group:

Note how the uidNumber for the user object and the gidNumber for the group are based off of the RID of the object (the last number of the object’s SID).  This isn’t required.  You can set the gidNumber and uidNumber to any arbitrary (but unique) value you choose.  I did it simply because the SID is going to be unique in a directory.

Now that we have our user and group objects set up, using winbind relatively simple to do.  The first thing I do is to make sure you have the appropriate packages installed.  A simple yum command will set that up.

Next, I run authconfig-tui and select ‘Cache Information’ and ‘Use Winbind’ under ‘User Information’ and ‘Use MD5 Passwords,’ ‘Use Shadow Passwords,’ ‘Use Winbind Authentication,’ and ‘Local authorization is sufficient’ under ‘Authentication.’   This will configure PAM and NSS for you so you don’t have to worry about editing those files by hand.  Unfortunately, (at least the way I want to do things), authconfig-tui does not handle setting up smb.conf quite the way I want it to AND it tries to start winbind without joining it to the domain first.  We’ll clean up that cache files that the aborted attempt at starting winbind makes and there are only a couple files to edit by hand and they are consistent across all servers in the domain.

So first:

Then make sure your /etc/hosts looks similar to the following:

Pretty simple, right?  It was just one of the things I found that made my life easier since anaconda (or maybe Network Manager?) has a tendency to put the hostname in with the localhost line, which I’ve found confuses certain applications.

Next, /etc/krb5.conf needs to be tweaked a bit:

And finally, the all-important /etc/samba/smb.conf.  I’ll show you what I do with it and then explain it afterwards.

There are a lot more options you can put in your smb.conf if you want your server to serve up cifs or smb shares or printers, etc.  I’m just focusing on authentication, and this is a configuration file that works to perform this function.  Things to note here are that I am setting the id range for uid’s and gid’s to be from 500 – 33554431.  This may not work for you if you already have local users that have id’s in this range.  CentOS and RHEL work on trying to keep all service accounts (apache, mail, sshd, nscd, etc) uid numbers under 500 so this seemed like a good place to start for me since all of my users will be in AD (no local or LDAP accounts).  If you’ll recall, I mentioned above that the loginShell and unixHomeDirectory attributes are not required.  That is true, but only if you have the template shell and template homedir set (as above).  If either of these attributes are missing, the values from smb.conf will be used.

Now that we’ve got samba configured, we’re ready to join the domain.  Using an account with privileges to join servers to the domain, run

The createcomputer argument is not required.  It is used if you want your computer object to be place into the directory in a different OU from /Computers.  If that doesn’t matter, just leave off the argument altogether.  Another thing to note is that you’ll most like receive what looks like an error – usually it’s that the account doesn’t exist in Kerberos or a DNS update failed.  This is fine; just look for the text “<computername> joined to domain.”

Finally start up the winbind service:

Now, you should be able to authenticate with your AD users and get user information.  A word of warning – although authentication and commands like finger and id work against the AD users, one of the shortcomings of winbind is that getent passwd and getent group will not return any entries for AD accounts or groups.  Just something to keep in mind.

One of the side benefits of having your computer joined to the domain is that you can now easily run queries or create and delete users and groups.  For example, if you wanted to find information about Tester X, you could run

[root@winbind-teste ~]# net ads search -P ‘(cn=Tester X)’

This would return an ldif-like stanza of the Tester X object.  The -P tells net ads search to use the computer’s machine account to authenticate while performing the search.


In the end, I’ve presented two methods of integrating your Linux system authentication into an existing AD infrastructure – one using straight LDAP into AD and the other using winbind to join the machine to the domain and use native calls.  There advantages to each method.

Advantages to LDAP:

  • Easy to configure
  • Is a more “standard” configuration for Unix and Linux
  • Returns user information properly with commands like getent passwd

Advantages to Winbind:

  • Uses native calls into AD
  • Presents a slightly more user-friendly interface into functions (eg, passwd displaying more readable errors)
  • Allows for changing passwords without having to worry about setting up certificates
  • Certain AD functions can be achieved using the ‘net’ command

During the course of my testing and speaking with other Unix engineers, I’ve gotten the impression that authenticating to AD is looked down upon.  I don’t see it that way.  If you’ve got an established directory service set up, there’s no reason why it shouldn’t be leveraged.  In fact, AD authentication just goes to show the strength of *nix systems; after all, how many Windows systems do you know of that can authenticate exclusively against LDAP or NIS?

  10 Responses to “CentOS 6 Authentication to Active Directory – Part 2”

  1. Hello,

    I am trying to integrate AD authentication to Cent OS 6 servers. I am running to this error when I tried to join with AD server. I installed both Samba as well as windbind. can you please suggest where I am missing.

    error message :


    # net ads join -U 504783
    Host is not configured as a member server.
    Invalid configuration. Exiting….
    Failed to join domain: This operation is only allowed for the PDC of the doma in.

    configuration file of samba smb.conf under [global] is updated with this info.

    workgroup = ctab
    realm = CTAB.ALPHA.COM
    security = ads
    idmap uid = 7000-500000
    idmap gid = 7000-500000
    template shell = /bin/bash
    template homedir = /home/%U
    winbind use default domain = true
    winbind offline logon = false
    winbind nss info = rfc2307
    idmap config TRD:backend = ad
    idmap config TRD:defauly = yes
    idmap config TRD:range = 70000-500000
    idmap config TRD:schema_mode = rfc2307
    server string = Samba Server Version %y
    I have updated krb5.conf as this


    #more /etc/krb5.conf
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    default_realm = CTAB.ALPHA.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true

    kdc =
    admin_server =

    [domain_realm] = CTLAB.ALPHA.COM = CTLAB.ALPHA.COM
    I wasnt able to fix it can someone please suggest.


    • A couple things:

      First, you need to fix the lines that still contain TRD. Change that to your domain (CTAB). Next, you’ve misspelled ‘default’ in the idmap config TRD:defauly = yes line. You’ve also set the range for your idmap to 70000 where you had 7000 as the previous minimum; was this intentional?

      Ultimately, I believe your error message stems from a missing password server = line. I think that’s why when you try the join, net is thinking it is a PDC rather than contacting an outside one.

      Hope it helps!

      • Hi Greg,

        Thanks for your reply, I still have same issues, I was able to join the domain, but when execute wbinfo for user and group I am getting into error messages any idea??

        workgroup = CTAB
        realm = CTAB.ALPHA.COM
        server string = Samba Server Version %v
        security = ADS
        password server = CTAB.ALPHA.COM
        log file = /var/log/samba/log.%m
        max log size = 50
        idmap backend = nss
        idmap uid = 10000-20000
        idmap gid = 10000-20000
        template homedir = /home/%U
        template shell = /bin/bash
        winbind separator = +
        winbind cache time = 10
        winbind enum users = Yes
        winbind enum groups = Yes
        winbind use default domain = Yes
        winbind nss info = rfc2307
        idmap config CTAB:schema_mode = rfc2307
        idmap config CTAB:range = 10000-20000
        idmap config CTAB:default = yes
        idmap config CTAB:backend = ad
        cups options = raw

        # net ads join -U z504783
        Enter z504783′s password:
        Using short domain name — CTAB
        Joined ‘HOSTNAME1′ to realm ‘’
        [2012/01/16 16:17:58.005964, 0] libads/kerberos.c:333(ads_kinit_password)
        kerberos_kinit_password HOSTNAME1$@CTAB.ALPHA.COM failed: Preauthentication failed

        [root@HOSTNAME1 /]# wbinfo -u
        Error looking up domain users
        [root@HOSTNAME1 /]# wbinfo -g
        Error looking up domain groups
        [root@HOSTNAME1 /]#

  2. Hi

    Thanks for the wonderful article. I followed the steps and it worked fine. I could get a list of users by using wbinfo -u and groups by wbinfo -g. However, I had to restart the system for some reason. After reboot, I could rejoin the domain, but can’t authenticate anymore. wbinfo -u and -g come back with errors saying Error Looking up domain users. Please help. What happened between reboots? How do I fix this once and for all.
    Does it matter that CentOS is running in a VM (Hyper-V)?

  3. To answer your final question, it does not matter if the CentOS server is virtual or physical. As far as the OS cares, it’s just another hardware platform.

    The first thing you need to do is verify winbind is running. You can check that with

    If it is running, you might want to try stopping it and then removing the *.tdb files in /var/cache/winbind if you’re running CentOS 5 or /var/lib/samba/*.tdb if you’re running CentOS 6. Then restart winbind and check your results again.

  4. Hi there,

    Thanks for this, I have successfully joined a centos client to the domain, and wbinfo returns the correct values.

    What I would like to do next is acctually log onto the Centos box with the AD user credentials.

    Is this possible?

  5. I was able to get this going without any walkthrough however how do you manuall set the UID?

    Im in an environment where we have users already setup on our linux boxen and UID’s are already setup and need to stay consistent.


    [chicken@strips ~]$ id chicken
    uid=544(chicken) gid=544(chicken) groups=544(chicken)
    [chicken@strips ~]$

    I know of win2k8′s SFU role that can be added to AD, i set the UID and GID but when the user logins in, it doesnt retain the proper ip.

  6. We also have kg problem. We joined succesfully to the domain, with this commands:

    authconfig –enableshadow –enablemd5 –passalgo=md5 –krb5kdc=$ADSERVER –krb5realm=$DOMAIN –smbservers=$ADSERVER –smbworkgroup=$WORKGROUP –enablewinbind –enablewinbindauth –smbsecurity=ads –smbrealm=$DOMAIN –smbidmapuid=”16777216-33554431″ –smbidmapgid=”16777216-33554431″ –winbindseparator=”\\” –winbindtemplateshell=”/bin/false” –enablewinbindusedefaultdomain –disablewinbindoffline –winbindjoin=<binduser> –disablewins –disablecache –enablelocauthorize –updateall

    This is output:

    Enter apse010′s password:
    Using short domain name — APSYSTEMS
    Joined ‘FIREWALL1′ to dns domain ‘apsystems.local’
    net_update_dns_internal: Failed to connect to our DC!
    DNS update failed!
    Starting Winbind services: [ OK ]

    however, the server is connected to the domain and squid authentication with domain works well.

    After some time, some days, the server seems to lose domain membership.

    We try adding in crontab:

    /usr/bin/net rpc changetrustpw

    But even this worked. We must re-run the configuration command “authconfig…” that recreates the connection to the domain.


    Someone can help us ?

  7. I’m not sure where you are getting your info, but good topic.
    I needs to spend some time learning more or understanding more.

    Thanks for magnificent information I was looking for this information
    for my mission.

 Leave a Reply



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">