Wednesday, May 9, 2012

HOWTO : OpenLDAP 2.4 sudo Repository on CentOS 6.2

Today we continue with our OpenLDAP series of blog posts. Recall that our goals were :
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
Since goals 1 to 4 are already achieved in previous blog posts, we are now ready to tackle goal number 5 which is to configure OpenLDAP to be a repository of sudo rules. The official sudo website, the sudoers LDAP manual and the sudo LDAP README file are a good place to start.

Server Configuration


The first thing we need to check the sudo package. We know it is installed because we've been working with it a lot lately. So let's just check which version it is?

rpm -qi sudo | grep -i version
Version     : 1.7.4p5                           Vendor: CentOS

Ok, was it configured --with-ldap? It looks strange to type sudo sudo, but we need to assume UID zero if we want to see the binary's configuration.

sudo sudo -V | egrep -i '^config|ldap'

Configure args: --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --prefix=/usr --sbindir=/usr/sbin --libdir=/usr/lib64 --docdir=/usr/share/doc/sudo-1.7.4p5 --with-logging=syslog --with-logfac=authpriv --with-pam --with-pam-login --with-editor=/bin/vi --with-env-editor --with-ignore-dot --with-tty-tickets --with-ldap --with-ldap-conf-file=/etc/nslcd.conf --with-selinux --with-passprompt=[sudo] password for %p:  --with-linux-audit
ldap.conf path: /etc/nslcd.conf
ldap.secret path: /etc/ldap.secret

From the above output, we can see that this sudo binary has indeed the LDAP configurations and it's using /etc/nslcd.conf as the LDAP configuration path. According to the sudoers LDAP manual, all we need to do now is to add SUDOERS_BASE to /etc/nslcd.conf file. Right?

Wrong :(

The sudo version shipped with CentOS 6.2 (and RedHat 6.2 for that matter) has a bug with sudo. You can find both the CentOS bug and the RedHat bug pages. You can try to configure sudo parameters into /etc/nslcd.conf if you want. But that will only result in an error like this one :

Starting nslcd: nslcd: /etc/nslcd.conf:20: unknown keyword: 'sudoers_base'

So what should we do? Give up? No! We only have to download the latest sudo rpm from the official sudo download site. Simply get the latest binary package for CentOS 6 which is currently sudo-1.8.4-5.el6. So let's download it. NOTE : please don't just copy/paste this wget command, but make sure to grab the latest version of sudo from the official web site. Also, please note that we're using the 64 bit version. Maybe your machine requires the 32 bit version. In that case, the package would be called sudo-1.8.4-5.el6.i386.rpm

wget http://www.sudo.ws/sudo/dist/packages/Centos/6/sudo-1.8.4-5.el6.x86_64.rpm

Make sur to upgrade sudo on all the systems you need to have sudo LDAP enabled...

sudo rpm -U ./sudo-1.8.4-5.el6.x86_64.rpm

Check the new sudo package.

rpm -qi sudo | grep -i version
Version     : 1.8.4                             Vendor: Todd C. Miller

Check to see if it has a different LDAP configuration from the one which comes with CentOS 6?

sudo sudo -V | grep ldap

Configure options: --prefix=/usr --with-logging=syslog --with-logfac=authpriv --with-pam --enable-zlib=system --with-editor=/bin/vi --with-env-editor --with-ignore-dot --with-tty-tickets --with-ldap --with-passprompt=[sudo] password for %p:  --with-selinux --with-linux-audit --with-pam-login
ldap.conf path: /etc/ldap.conf
ldap.secret path: /etc/ldap.secret

And indeed it does. We can see that the ldap.conf file is not /etc/nslcd.conf anymore, but /etc/ldap.conf.

Now that we have a new version of sudo, we must check the LDAP schema that comes with it. 

rpm -ql sudo | grep schema

/usr/share/doc/sudo-1.8.4p4-5.el6/schema.ActiveDirectory
/usr/share/doc/sudo-1.8.4p4-5.el6/schema.OpenLDAP
/usr/share/doc/sudo-1.8.4p4-5.el6/schema.iPlanet

Ok, we need to check the /usr/share/doc/sudo-1.8.4p4-5.el6/schema.OpenLDAP file to find out what are the sudo schema objects?

grep NAME `rpm -ql sudo | grep -i openldap`

    NAME 'sudoUser'
    NAME 'sudoHost'
    NAME 'sudoCommand'
    NAME 'sudoRunAs'
    NAME 'sudoOption'
    NAME 'sudoRunAsUser'
    NAME 'sudoRunAsGroup'
    NAME 'sudoNotBefore'
    NAME 'sudoNotAfter'
    NAME 'sudoOrder'
objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL

Let's compare this list to our current sudo schema and see if we have access to all those objects? First we need to know in which schemas the sudo objects are defined.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn

dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}inetorgperson,cn=schema,cn=config
dn: cn={3}collective,cn=schema,cn=config
dn: cn={4}corba,cn=schema,cn=config
dn: cn={5}duaconf,cn=schema,cn=config
dn: cn={6}openldap,cn=schema,cn=config
dn: cn={7}dyngroup,cn=schema,cn=config
dn: cn={8}java,cn=schema,cn=config
dn: cn={9}misc,cn=schema,cn=config
dn: cn={10}nis,cn=schema,cn=config
dn: cn={11}ppolicy,cn=schema,cn=config
dn: cn={12}kerberos,cn=schema,cn=config
dn: cn={13}schema,cn=schema,cn=config

Hummm, that's strange, we don't have a sudo schema. But we did install one in a previous post when we first installed our OpenLDAP server. But wait, what's this strange cn={13}schema,cn=schema,cn=config schema? Let's see if it contains our sudo objects?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn={13}schema,cn=schema,cn=config | grep -i sudo

Sure enough, it contains our sudo objects. But is it complete? We're not sure because this sudo schema came with sudo version 1.7.x while we have sudo version 1.8.x installed now. Let's check which objects are currently in our OpenLDAP schema.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn={13}schema,cn=schema,cn=config | grep NAME | awk '{print $4,$5 }' | sort

NAME 'sudoCommand'
NAME 'sudoHost'
NAME 'sudoOption'
NAME 'sudoRole'
NAME 'sudoRunAs'
NAME 'sudoRunAsGroup'
NAME 'sudoRunAsUser'
NAME 'sudoUser'

When we compare this list of objects to the objects found in the schema.OpenLDAP file from sudo 8.x, we are missing a few objects (i.e. sudoNotAfter, sudoNotBefore and sudoOrder). Plus our sudo schema is not named correctly. So let's change all this. To do so, let's first remove the current sudo schema. According to this mailing-list archive thread, we cannot remove schemas from our OpenLDAP server via ldapdelete(1). So in order to remove the old cn={13}schema,cn=schema,cn=config schema from our OpenLDAP server, we must delete it from the /etc/openldap/slapd.d directory. If anyone knows a better way to remove schemas, please let me know!

sudo /etc/init.d/slapd stop
sudo rm /etc/openldap/slapd.d/cn\=config/cn\=schema/cn\=\{13\}schema.ldif

sudo /etc/init.d/slapd start

Confirm that the old {13}schema is now gone from the configuration.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn

As expected, the above command returned nothing. We can now generate a new sudo schema in LDIF format. To do so, create a temporary configuration file like this :

rpm -ql sudo | grep -i schema.openldap | sed 's/^/include /g' > ~/ldap/sudo.conf

Next, use slapcat(8C) to generate the new sudo schema in LDIF format.

slapcat -f sudo.conf -F ~/ldap -n 0

This will create the ~/ldap/cn\=config.ldif file and the ~/ldap/cn\=config directory in which our new sudo schema file was generated. It was unfortunately created with the wrong name again. If someone knows how to assign a name to a new LDIF schema, please let me know! So let's change it's name.

cp ~/ldap/cn\=config/cn\=schema/cn\=\{0\}schema.ldif ~/ldap/sudo.ldif

But changing the file name is not enough, we also need to change the dn: and cn: attribute values in the file. A quick sed(1) command does just that.

sed -i.bak -e "s/^dn: cn={0}schema/dn: cn=sudo,cn=schema,cn=config/g" -e "s/^cn: {0}schema/cn: sudo/g" ~/ldap/sudo.ldif

We should now be ready to install our new sudo schema. The OpenLDAP FAQ-O-Matic explains how to do so. But it never worked for me. YMMV of course, but let's use this recipe from the mailing-list archive. It says that we must first remove these objects from the file :

structuralObjectClass:
entryUUID:
creatorsName:
createTimestamp:
entryCSN:
modifiersName:
modifyTimestamp:

Again, a quick sed(1) will take care of that.

sed -i.bak -re "/^(structuralObjectClass|entry[C|U]|creat[e|o]|modif[i|y])/d" ~/ldap/sudo.ldif

If we don't remove those objects, we will see these errors in the sldapd log file :

slapd[10783]: conn=1010 op=2 RESULT tag=105 err=53 text=no global superior knowledge
slapd[10783]: conn=1012 op=2 RESULT tag=105 err=19 text=structuralObjectClass: no user modification allowed

The end LDIF file now should look like this. We can now add it to the directory.

sudo ldapmodify -a -H ldapi:/// -f ~/ldap/sudo.ldif

If you're looking into the server log file, you should see this :

slapd[10783]: conn=1013 op=2 ADD dn="cn=sudo,cn=schema,cn=config"

Confirm that we now have the new schema in place?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn | grep sudo

Excellent! :)

Let's clean-up a bit, since we don't need the ~/ldap/cn\=config.ldif, ~/ldap/sudo.ldif and ~/ldap/sudo.conf files nor the ~/ldap/cn\=config directory anymore, so we can remove them.

rm -rf ~/ldap/cn\=config* ~/ldap/sudo.*


Convert sudoers to LDAP


Before we convert the sudoers file, let's take a look at an example file.

sudo cat /etc/sudoers

To convert this sudoers file, we need to create yet another LDIF file.

sudo SUDOERS_BASE=ou=sudo,ou=services,dc=company,dc=com perl
/usr/share/doc/sudo*/sudoers2ldif /etc/sudoers > ~/ldap/sudoers.ldif

That generates the LDIF file with our current sudoers configuration translated into LDIF. This all good, but we don't have the LDAP container for sudo yet. Actually, we don't even have our services OU yet. So we need to add a few lines at the start of the file to create the services OU.

vi ~/ldap/sudoers.ldif # This is NOT the final sudoers.ldif file. See below for a complete one.

The rest of the file contains your sudoers configuration. Before we can add this new LDIF file, we must clean it up a bit. The problem are the spaces around the equal signs. If you leave it like this « env_keep = COLORS » instead of like that « env_keep=COLORS » then we will get LDAP errors. This quick sed(1) command will clean things up.

sed -i.bak -e "s/ = /=/g" -re 's/= {0,2}"/=/g' -e 's/"$//g' -e "s/p \+/p+/g" ~/ldap/sudoers.ldif

Almost there, we only need one more sed(1) run to add structure to the LDIF file.

sed -i.bak -e "/^dn: ou=sudo,/a objectClass: organizationalUnit" -e "/^dn: ou=sudo,/a description: sudo" ~/ldap/sudoers.ldif

The end result looks like that :

cat ~/ldap/sudoers.ldif

Now we can add it to our LDAP server.

sudo ldapmodify -aH ldapi:/// -f ~/ldap/sudoers.ldif

We should see this in the server logs :

slapd[10783]: conn=1028 op=2 ADD dn="ou=sudo,ou=services,dc=company,dc=com"
slapd[10783]: conn=1028 op=2 RESULT tag=105 err=0 text=
slapd[10783]: conn=1028 op=3 ADD dn="cn=defaults,ou=sudo,ou=services,dc=company,dc=com"
slapd[10783]: conn=1028 op=3 RESULT tag=105 err=0 text=
slapd[10783]: conn=1028 op=4 ADD dn="cn=root,ou=sudo,ou=services,dc=company,dc=com"
alice slapd[10783]: conn=1028 op=4 RESULT tag=105 err=0 text=
slapd[10783]: conn=1028 op=5 ADD dn="cn=panic,ou=sudo,ou=services,dc=company,dc=com"
slapd[10783]: conn=1028 op=5 RESULT tag=105 err=0 text=
slapd[10783]: conn=1028 op=6 ADD dn="cn=%sysadmin,ou=sudo,ou=services,dc=company,dc=com"

Confirm that we now have a sudoers file in our LDAP server?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b ou=sudo,ou=services,dc=company,dc=com

Excellent!

But can anybody see our sudoers configuration? That wouldn't be good. Let's find out...

ldapsearch -xZLLLWD cn=drobilla,ou=users,dc=company,dc=com -b ou=sudo,ou=services,dc=company,dc=com -H ldap://alice.company.com

Insufficient access (50)

Good! Exactly how it should be. But can the cn=nssproxy user read the data?

ldapsearch -xZLLLWD cn=nssproxy,ou=users,dc=company,dc=com -b ou=sudo,ou=services,dc=company,dc=com

Normally, we should see all of our sudoers configuration.

Client Configuration


Since we have a working sudo schema along with an LDAP version of our sudoers file, we can now configure client machines to fetch their sudoers data from the OpenLDAP server.

Make sure you install the latest sudo version on the client from the sudo website! See above on how to do this.

Then configure the sudo only /etc/ldap.conf file.


Fix permissions on the file (it has a password in it...)

sudo chmod 600 /etc/ldap.conf
sudo chown root:root /etc/ldap.conf

Don't forget to place your corporation's CA certificate on the client (if you use one or if you self signed it).

sudo cp ~/companyCA.crt /etc/pki/tls/certs/

Then change the sudoers line (or add it) to /etc/nsswitch.conf. Notice how files is listed before ldap? That's in case we have a general LDAP failure or a network failure. If that happens, then we'll be able to read the local sudoers file.

sudo vi /etc/nsswitch.conf

sudoers: files ldap

And now test our new LDAP-enabled sudo binary. We should see our LDAP sudoers configuration printed on screen.

sudo -l

If we take a look at the /var/log/slapd.log file on the OpenLDAP server, we will see some error messages like these :

slapd[10783]: <= bdb_equality_candidates: (sudoUser) not indexed

To fix this, go back to the OpenLDAP machine and create another LDIF file.


Add those new indexes to the database.

sudo ldapmodify -H ldapi:/// -f sudoers.indexes.ldif

While keeping an eye on the slapd.log file, run another sudo command from the client we just configured. 

sudo ls

The bdb_equality_candidates errors should now have disapeared.

We thus have achieved our fifth goal!
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
Next time we will configure an NFS server and use OpenLDAP to store our autofs configuration.

HTH,

DA+

43 comments:

  1. the broken sudo in Centos 6.2 was preventing me from upgrading several of my servers, and yesterday, I had to upgrade to fix a TLS bug (we just moved to the newest openldap). thank you for such a timely article :)

    ReplyDelete
  2. Glad to know I could help. Enjoy! :)

    ReplyDelete
  3. One thing I cannot do is:

    ldapmodify -a -H ldapi:/// -f ~/ldap/sudo.ldif

    But can do:

    ldapmodify -aWD cn=admin,dc=ecornerhosting,dc=com -H ldapi:/// -f ~/ldap/sudo.ldif

    Not sure why as have done all the changes.....

    Thanks

    ReplyDelete
    Replies
    1. Hello Grant,

      At which point do you have the problem? Have you tried using sudo ldapmodify? If you use sudo ldapmodify, the authenticated DN is « gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth », if you don't use sudo, then you need to either have a Kerberos ticket of a principal specified in the OpenLDAP ACL or use the cn=admin user. Maybe that was the problem?

      Let me know and I'll correct the post if required.

      DA+

      Delete
  4. Also keep having the same problem no matter how many times I restart the install:

    ldapmodify -aWD cn=admin,dc=something,dc=com -H ldapi:/// -f ~/ldap/sudoers.ldif

    adding new entry "ou=services,dc=something,dc=com"

    adding new entry "cn=defaults,ou=sudo,ou=services,dc=something,dc=com"
    ldap_add: No such object (32)
    matched DN: ou=services,dc=something,dc=com

    ReplyDelete
  5. Can you print the content of your sudoers.ldif file? Can you also print the output of the following query (obviously change the search base to your own DN)

    sudo ldapsearch -LLL -H ldapi:/// -b ou=sudo,ou=services,dc=company,dc=com

    ReplyDelete
    Replies
    1. Fixed it yesterday and all working. I was been too neat and tidy with the import files and removed too many blank lines :)

      Delete
    2. Even i am facing same issue. please help me to solve it. output of sudo ldapsearch -LLL -H ldapi:/// -b ou=sudo,ou=services,dc=company,dc=com is
      SASL/EXTERNAL authentication started
      SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
      SASL SSF: 0
      No such object (32)
      Matched DN: dc=company,dc=com

      Delete
  6. Hi,

    Have gone as far as the end off Use OpenLDAP as sudo's configuration repository and everything is working perfectly. Only thing you cannot do is change the users password from a client 'passwd', do I have to do the Kerberos section for this or is their an easier way :)

    Great instructions btw.

    Thanks

    ReplyDelete
  7. @Grant: Great news! And thank you :)

    Have tried my other post on user and group management?
    http://itdavid.blogspot.ca/2012/05/howto-openldap-24-sudo-repository-on.html

    Try to implement the pam_ldap section and see if you can change the users password from a client 'passwd' after that. Let me know how it goes please.

    Cheers,

    DA+

    ReplyDelete
  8. Can't do slapcat to convert config:

    [root@dc1 ldap]# slapcat -f sudo.conf -F ~/ldap -n 0
    str2entry: invalid value for attributeType olcSuffix #0 (syntax 1.3.6.1.4.1.1466.115.121.1.12)
    # no data for entry id=00000000

    ReplyDelete
  9. Fixed. Needed to create a subdirectory to make it work.

    ReplyDelete
  10. David,

    The Dropbox download link to file /etc/ldap.conf (https://dl.dropbox.com/u/72609528/blog/openldap/etc.ldap.conf) is not working.

    ReplyDelete
  11. @Roberto : Excellent! Let me know if you have any more issues and I'll try to help you.

    ReplyDelete
  12. @Roberto : strange, when I try the URL you mentionned, I don't have an error. Do you still need the info? Can you double-check to see if it works now?

    ReplyDelete
  13. I just follow your nice tutorial again, to add the sudo repository

    Too curious,I used hdb database instead of bdb (in your example) still get that <= bdb_substring_candidates: (sudoUser) not indexed meaning hdb doesn't work. Hope you can enlighten me?

    sudo ldapmodify -H ldapi:/// -f sudoers.indexes.ldif doesn't work me either but I use
    sudo ldapmodify -a -xWD cn=admin,dc=company,dc=com -f sudoers.indexes.ldif

    What's the significant difference of the two commands? Thank you again.

    ReplyDelete
    Replies
    1. Hello Ewann Kho,

      The « <= bdb_substring_candidates: (sudoUser) not indexed » error simply says that you don't have an index on the sudoUser attribute. You need to add an index in your cn=config for sudoUser. I'm at home right now and don't have access to an OpenLDAP server, but I'll update this post tomorrow. If you read this today, then check the OpenLDAP guide section 5.2.6.7. olcDbIndex at http://www.openldap.org/doc/admin24/slapdconf2.html

      I'll also update the answer for the difference between the two commands tomorrow :)

      DA+

      Delete
    2. Hello Ewann,

      Sorry for the (very) late reply, but I've been quite busy at work and with my baby.

      So, to answer your question, the difference between those two commands listed below is quite simple.

      a) sudo ldapmodify -H ldapi:/// -f sudoers.indexes.ldif
      b) sudo ldapmodify -a -xWD cn=admin,dc=company,dc=com -f sudoers.indexes.ldif

      Command a) uses the Inter Process Communcation (IPC) to talk to the OpenLDAP server. That's what the « -H ldapi:/// » arguments do. It tells ldapmodify(1) to use the UNIX sockets instead of the TCP/IP stack to connect to OpenLDAP. You can check the IPC socket with this command :

      netstat -A unix | grep ldap

      You should see something like this :

      unix 2 [ ACC ] STREAM LISTENING 1080226 /var/run/ldapi
      unix 3 [ ] STREAM CONNECTED 1082101 /var/run/ldapi

      Command a) also uses sudo(8) to launch ldapmodify(1) which means that it runs as the root user. That's where the OpenLDAP ACL come into play. These are the olcAccess attributes in your OpenLDAP server. Command a) will match the « dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" » part of the ACLs. Which basically say that if your UID is zero and your GID is zero (i.e. you're the root user), then you match this ACL.

      Command b) on the other hand uses the TCP/IP stack to communicate with the OpenLDAP server. There is not -H option, so ldapmodify opens /etc/openldap/ldap.conf to check for the URI value. This URI lists your OpenLDAP server(s) as we can see here :

      grep ^URI /etc/openldap/ldap.conf
      URI ldap://alice.caprion.com ldap://bob.caprion.com

      The ldapmodify command will also check this file to know if it should use TLS and which SASL mechanisms (if any) to use. These are the TLS_* values and SASL_MECH values respectively.

      Command b) also connects (binds to) the OpenLDAP server with the Administrator user as stated by the « -D cn=admin,dc=company,dc=com » flag. It will also prompt you for this administrator's password because of the -W flag. And it will perform a simple bind because of the -x flag.

      The ACLs for command b) are not required, because the OpenLDAP administrator user always has full read and write permissions to the LDAP data. That's probably why command a) failed while command b) worked. Check your olcAccess objects to see if you have something like this for the cn=config and your olcDatabase={1}bdb,cn=config :

      olcAccess: {0}to * by dn.base
      ="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage

      HTH,

      David

      Delete
  14. Sorry I think my previous post was redundant, coz someone asking with it. But now I used to solve the problems that was encountered(taken from the logs)

    slapd[19111]: <= bdb_substring_candidates: (sudoUser) not indexed
    to
    -date/time- xxx slapd[19111]: conn=1004 op=0 BIND dn="cn=admin,dc=company,dc=com" mech=SIMPLE ssf=0
    date xxx slapd[19111]: conn=1004 op=0 RESULT tag=97 err=0 text=
    -date/time- xxx slapd[19111]: conn=1004 op=1 MOD dn="olcDatabase={1}hdb,cn=config"
    -date/time- xxx slapd[19111]: conn=1004 op=1 MOD attr=olcDbIndex olcDbIndex
    -date/time- xxx slapd[19111]: conn=1004 op=1 RESULT tag=103 err=0 text=

    Everytime I issue <> conn will increment... eg. conn=1004 to conn=1005

    by modifying the <> and added the term "sub"

    dn: olcDatabase={1}hdb,cn=config
    changetype: modify
    replace: olcDbIndex
    olcDbIndex: sudoUser eq,sub
    -
    replace: olcDbIndex
    olcDbIndex: sudoHost eq,sub

    Please change hdb if you use bdb. It assumed you already added it and just modifying the entries. If not yet executed just add "sub" in your ldif.

    Hope it helps.

    ReplyDelete
  15. Hi David;
    I am running on centos6.2 with sudo version 1.7.4p5 ... just wanted to ask please ... would i need to update the version to 1.8 before trying fix or i am good to just update my system with your fix.
    Many thanks

    ReplyDelete
  16. Hello bojo,

    If you're running CentOS 6.2, then I would suggest you upgrade to CentOS 6.3. It's a very easy process because you simply have to issue this command :

    sudo yum -y upgrade

    It will update a few hundred rpm packages.

    Once the upgrade is over, you should reboot to make sure everything is working correctly (and prevent you from debugging something down the road when you don't even remember this upgrade).

    After the reboot, check the sudo version :

    rpm -qi sudo

    I'm not quite sure if this updated CentOS 6.3 sudo version will work as I've never tried it.

    But one thing is sure, this blog post worked for me and several other readers.

    HTH,

    David

    ReplyDelete
  17. Is it normal to have to manually export the path variable for root

    Unless I manually export it sudo is unable to find commands(sh,echo,tar,ls,cp,mv etc)

    Once exported I'm able to do sudo -i ls -al but still not sudo ls -al

    Is this normal

    ReplyDelete
    Replies
    1. Hello ldapn00b,

      The environment variables are often modified by sudo. Check your sudo configuration for this line :

      Defaults env_reset

      If present, then sudo resets the environment variables. You can select to preserve some environment variables with the « env_keep » configuration. Some lines like these are also often seen :

      Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
      Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"

      More specifically, the PATH variable can be controlled within sudo by a line such as this one :

      Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/kerberos/sbin:/usr/kerberos/bin

      Check the sudo documentation for more info.

      HTH,

      David

      Delete
  18. Hi David, if my openldap server does not allow anonymous access to the LDAP Directory then what should i do in that case Any Ideas?
    Thanks

    ReplyDelete
    Replies
    1. Hello Anonymous,

      Well, if you can't do anonymous binds to the LDAP directory, then you must use a valid user to perform the connection.

      Is it a server that you installed and have administrative access to? If so, then create an OpenLDAP user with a password, give him access in the ACL to the directory tree relevant to this user and then use his credentials to query the LDAP server.

      If you don't have access to modifiy users within this LDAP server, then find out who can and kindly ask them to have access to the LDAP server. Explain why you would need access, which types of access (read/write or read-only) and on which branch of the directory (or all of it).

      HTH,

      DA+

      Delete
  19. Hi David , Thanks for th quick reply. actually I have administrative access to LDAP server,I have a user which I placed in ou=sudoers in my LDAP server. I can login as that user but when i try to run any sudo command , it gives me an error that this user is not a part of sudoers file. The steps that i performed on my LDAP server are:
    1.Loaded sudo.schema,sudo.ldif into my database.
    2.created an organizational unit sudoers.Placed that user into it with ALL Access.
    3.Added the host to the directory from which I am serching LDAP and verified.

    On the client
    1.modified the nsswitch to consult ldap for sudoers
    2.updated ldap.conf with the entry of my "ldap uri" and "udoers_base" entry

    Is there anything else that I need to do for the sudo to work.
    Thanks

    ReplyDelete
  20. Hello David , Hope you are doing well. Just want to mention that i adding sudo.ldif to my database but with the kerberos authentication enabled it requires me to be a previliged user i.e kadmin and for that I need a kerberos tkt but when i type this command on my ldap+kerberos server:
    root@ldap$ kinit kadmin
    kinit:Client not found in kerberos database while getting initial credentials
    but when i type the command
    root@ldap$ kinit kadmin/admin it asks for password and when I provide the password which I set through kdb_util as stash it doesnt accept it. Therefore i cant modify my database and logging as other user to modify it gives me Insufficient access (50) error. Your help is highly appreciated. Thanks

    ReplyDelete
    Replies
    1. Hello kifal,

      When you run kadmin, by default it will append « /admin » to your own username. For example, if my username is drobilla, then when I try kadmin, the command will ask for the password of the « drobilla/admin@REALM » where REALM is more often than not the same as the DNS domain name (but it doesn't have to be). So if you don't have a kifal/admin principal in your realm, then that's why it says « kinit:Client not found in kerberos database while getting initial credentials »

      Now, if your admin principal does exist, then it might be your OpenLDAP ACL that prevent you from getting to it.

      There is a way around all this. Login to your Kerberos KDC machine and use the kadmin.local command with sudo. This will execute the kadmin as root on this machine. Make sure that once you're in kadmin, check to see if your machine has a correct keytab file. And that you have your own username/admin principal.

      As always, log files are your friend. Be sure to have a shell open that runs a tail -F on the slapd.log, the kadmin.log and the krb5kdc.log files.

      HTH,

      DA+

      Delete
  21. Hello David,
    I am facing NOT INDEX problem .Though I already use this "ldapmodify -H ldapi:/// -f sudoers.indexes.ldif" command and restart slapd.
    --------
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 fd=13 ACCEPT from IP=192.168.0.93:47615 (IP=0.0.0.0:389)
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=0 BIND dn="cn=nssproxy,ou=users,dc=suri,dc=com" method=128
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=0 BIND dn="cn=nssproxy,ou=users,dc=suri,dc=com" mech=SIMPLE ssf=0
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=0 RESULT tag=97 err=0 text=
    Apr 26 17:29:41 centosserver slapd[3128]: connection_input: conn=1000 deferring operation: binding
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=1 SRCH base="ou=sudo,ou=services,dc=suri,dc=com" scope=2 deref=0 filter="(cn=defaults)"
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=2 SRCH base="ou=sudo,ou=services,dc=suri,dc=com" scope=2 deref=0 filter="(|(sudoUser=root)(sudoUser=%root)(sudoUser=%#0)(sudoUser=ALL))"
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text=
    Apr 26 17:29:41 centosserver slapd[3128]: conn=1000 op=3 SRCH base="ou=sudo,ou=services,dc=suri,dc=com" scope=2 deref=0 filter="(sudoUser=+*)"
    Apr 26 17:29:41 centosserver slapd[3128]: <= bdb_substring_candidates: (sudoUser) not indexed
    --------------------------------------------------------------------------------------------------------------------------------------------------------------

    when I use " sudo -l" in client system it shows me this..

    Matching Defaults entries for root on this host:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="QTDIR
    KDEDIR", requiretty, !visiblepw, always_set_home, env_reset,
    env_keep+=COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR KDEDIR LS_COLORS,
    env_keep+=MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE,
    env_keep+=LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES,
    env_keep+=LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_MESSAGES,
    env_keep+=LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY,
    secure_path=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/bin:/usr/local/sbin:/usr/kerberos/sbin:/usr/kerberos/bin

    User root may run the following commands on this host:
    (ALL) ALL
    (ALL) ALL

    Please help me.
    Thanks!!

    ReplyDelete
  22. Hello again,

    The sudo -l command output is perfect. It shows that your sudo configuration is working :)

    Now the « bdb_substring_candidates: (sudoUser) not indexed » error is not fatal until you start having quite a lot of sudo users hitting the OpenLDAP machine. Let's check your indexes. Can you please run this from the server :

    sudo ldapsearch -LLH ldapi:/// -b olcDatabase={1}bdb,cn=config olcDbIndex

    DA+

    ReplyDelete
  23. not sure if you still monitor this but with sudo 1.8.6p3 on CentOS 6.4 I get the following

    slapcat -f sudo.conf -F ~/ldap -n 0
    str2entry: invalid value for attributeType olcSuffix #0 (syntax 1.3.6.1.4.1.1466.115.121.1.12)
    # no data for entry id=00000000

    ReplyDelete
    Replies
    1. Hello Jaqueline,

      I've recently redone this entire series with 6.4 and did not bump into this bug. Can you please post your sudo.conf file so that I can check it out?

      Thanks,

      David

      Delete
    2. ok I figured it out on my own it was the ~/ldap directory. for some reason on *my* centos instalation removing the cn={13}chema from /etc/openldap/slapd wasn't enough. I had to delete the config tree from ~/ldap (rm -rf ~/ldap/cn\=config*) as well. once i did that it stopped throwing errors. maybe a conflict in schemas ? I dunno.I see you do this at the end but I had to do it first.

      Delete
    3. Excellent! Glad you could figure it out.

      Delete
  24. Hello David,
    I created a user in LDAP and I have associated with the sysadmin group. The authentication server client works properly, but when I try to run the command sudo shows this error: sudo: ldap_sasl_bind_s (): Can not contact LDAP server. user is not in the sudoers file. This event will be marked. Why authentication working properly while sudo is not it? I checked all the files and look right

    Thanks!!

    ReplyDelete
    Replies
    1. Hello Roberto,

      So the first place to start is to check if you have this line in /etc/nsswitch.conf :

      sudoers: files ldap

      If that's present, then make sure your /etc/ldap.conf and /etc/sudo-ldap.conf files are properly configured.

      Once they are, make sure your /etc/nslcd.conf file is also properly configured. If it is, then make sure nslcd starts at boot (i.e. sudo chkconfig nslcd on) and start the daemon (i.e. sudo service nslcd start)

      Then try again. That should do it.

      HTH,

      DA+

      Delete
  25. Thanks David, 4 hours of work to find the url wrong :( Now all function!! :D

    ReplyDelete
    Replies
    1. Which URL? In which file?

      Good work! :)

      Delete
  26. Hello,
    in URI of ldap.conf sigh!!!

    ReplyDelete
  27. In /etc/sudo-ldap.cof argghh !!

    ReplyDelete
  28. Quick tip to simplify creation of the sudoers.ldif file. The OpenLDAP tools use the schema's file name for creating the ldif file. Since the schema is in schema.OpenLDAP, the resulting ldif file's name is schema.ldif. Simply copy schema.OpenLDAP and rename it to sudoers.schema. This converts to sudoers.ldif and no need for any sed tinkering in the generated file. Just remove the objects from the end of the file.

    ReplyDelete
  29. hey David just a tip for you on the wierd naming of the sudo schema the reason it does the {#}schema.ldif instead of {#}sudo.ldif is because of the file name of the schema. its named schema.OpenLdap the first part of that filename is schema and thats how slapcat names them. if you do like i did and copy the file to /etc/openldap/schemas and rename it to sudo.schema it will generate the proper schema file and you won't have to go to all that trouble of deleting the schema (which by the way is the worst thing you can do, it can corrupt the database and make it unusable) and re-adding it. if you look at your slapd.conf.temp *all* the schemas have name.schema except the sudo one :) have a nice day and maybe you can shorten your blog post a little now :)

    ReplyDelete
    Replies
    1. Ah ha! Interesting. Thanks for the tip!

      Delete