projects techreports press lab location staff
citi top.2 top.3
citi mid.3
bot.1 bot.2 bot.3
star

Projects: NFS Version 4 Open Source Reference Implementation

NFSv4 in a multi-realm environment

Setting up an LDAP server to process idmapd requests

These instructions assume you are starting with a complete installation of Fedora Core 2.

  1. Verify you have the openldap-servers package installed. If not, install it:
    # yum install openldap-servers
    
  2. Verify you have the cyrus-sasl-gssapi package installed. If not, install it:
    # yum list installed | grep sasl
    cyrus-sasl                          i386   2.1.18-2                 db
    cyrus-sasl-devel                    i386   2.1.18-2                 db
    cyrus-sasl-md5                      i386   2.1.18-2                 db
    cyrus-sasl-plain                    i386   2.1.18-2                 db
    # yum list available | grep sasl
    cyrus-sasl-gssapi                   i386   2.1.18-2                 base
    # yum install cyrus-sasl-gssapi
    Gathering header information file(s) from server(s)
    Server: Fedora Core 2 - i386 - Base
    Server: Fedora Core 2 - i386 - Released Updates
    Finding updated packages
    Downloading needed headers
    Resolving dependencies
    Dependencies resolved
    I will do the following:
    [install: cyrus-sasl-gssapi 2.1.18-2.i386]
    Is this ok [y/N]: y
    Downloading Packages
    Getting cyrus-sasl-gssapi-2.1.18-2.i386.rpm
    cyrus-sasl-gssapi-2.1.18- 100% |=========================|  28 kB    00:00
    Running test transaction:
    Test transaction complete, Success!
    cyrus-sasl-gssapi 100 % done 1/1
    Installed:  cyrus-sasl-gssapi 2.1.18-2.i386
    Transaction(s) Complete
    #
    
  3. Verify that the Kerberos libraries and workstation binaries are installed.
    # yum list installed | grep krb
    krb5-devel                          i386   1.3.4-6                  db          
    krb5-libs                           i386   1.3.4-6                  db          
    # yum install krb5-workstation
    Gathering header information file(s) from server(s)
    Server: Fedora Core 2 - i386 - Base
    Server: Fedora Core 2 - i386 - Released Updates
    Finding updated packages
    Downloading needed headers
    Resolving dependencies
    Dependencies resolved
    I will do the following:
    [install: krb5-workstation 1.3.4-6.i386]
    Is this ok [y/N]: y
    Downloading Packages
    Running test transaction:
    Test transaction complete, Success!
    krb5-workstation 100 % done 1/1 
    Installed:  krb5-workstation 1.3.4-6.i386
    Transaction(s) Complete
    # yum list installed | grep krb
    krb5-devel                          i386   1.3.4-6                  db          
    krb5-libs                           i386   1.3.4-6                  db          
    krb5-workstation                    i386   1.3.4-6                  db          
    #
    
  4. Now configure the OpenLDAP server. Here is our /etc/openldap/slapd.conf file:
    # $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
    #
    # See slapd.conf(5) for details on configuration options.
    # This file should NOT be world readable.
    # 
    include		/etc/openldap/schema/core.schema
    include		/etc/openldap/schema/cosine.schema
    include		/etc/openldap/schema/inetorgperson.schema
    include		/etc/openldap/schema/nis.schema
    include		/etc/openldap/schema/redhat/autofs.schema
    # +++ Add local schema +++
    include		/etc/openldap/schema/umich/umichlocal.schema
    include		/etc/openldap/schema/citi/citilocal.schema
    include		/etc/openldap/schema/citi/nfsv4.schema
    
    # Allow LDAPv2 client connections.  This is NOT the default.
    allow bind_v2
    
    # Do not enable referrals until AFTER you have a working directory
    # service AND an understanding of referrals.
    #referral	ldap://root.openldap.org
    
    pidfile /var/run/slapd.pid
    #argsfile	//var/run/slapd.args
    
    # Load dynamic backend modules:
    # modulepath	/usr/sbin/openldap
    # moduleload	back_bdb.la
    # moduleload	back_ldap.la
    # moduleload	back_ldbm.la
    # moduleload	back_passwd.la
    # moduleload	back_shell.la
    
    # The next three lines allow use of TLS for connections using a dummy test
    # certificate, but you should generate a proper certificate by changing to
    # /usr/share/ssl/certs, running "make slapd.pem", and fixing permissions on
    # slapd.pem so that the ldap user or group can read it.
    # TLSCACertificateFile /usr/share/ssl/certs/ca-bundle.crt
    # TLSCertificateFile /usr/share/ssl/certs/slapd.pem
    # TLSCertificateKeyFile /usr/share/ssl/certs/slapd.pem
    
    # +++ Use TLS! +++
    TLSCACertificateFile	/usr/share/ssl/certs/ca-bundle.crt
    TLSCertificateFile		/usr/share/ssl/certs/slapd.crt
    TLSCertificateKeyFile	/usr/share/ssl/certs/slapd.key
    TLSCipherSuite		HIGH:MEDIUM:+SSLv2
    TLSVerifyClient		try
    
    # +++ Add our SASL identity mappings +++
    #######################################################################
    # sasl identity mappings
    #######################################################################
    include         /etc/openldap/slapd.sasl-mappings
    
    # +++ Add our ACL settings +++
    #######################################################################
    # acl settings
    #######################################################################
    include         /etc/openldap/slapd.acls
    
    
    
    # Sample security restrictions
    #	Require integrity protection (prevent hijacking)
    #	Require 112-bit (3DES or better) encryption for updates
    #	Require 63-bit encryption for simple bind
    # security ssf=1 update_ssf=112 simple_bind=64
    
    # Sample access control policy:
    #	Root DSE: allow anyone to read it
    #	Subschema (sub)entry DSE: allow anyone to read it
    #	Other DSEs:
    #		Allow self write access
    #		Allow authenticated users read access
    #		Allow anonymous users to authenticate
    #	Directives needed to implement policy:
    # access to dn.base="" by * read
    # access to dn.base="cn=Subschema" by * read
    # access to *
    #	by self write
    #	by users read
    #	by anonymous auth
    #
    # if no access controls are present, the default policy is:
    #	Allow read by all
    #
    # rootdn can always write!
    
    #######################################################################
    # ldbm and/or bdb database definitions
    #######################################################################
    
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # +++ The main directory definitions
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # +++
    # +++ We'll use bdb
    database	bdb
    suffix		"dc=arbitrary, dc=domain, dc=org"
    rootdn		"cn=Manager, dc=arbitrary, dc=domain, dc=org"
    rootpw		omitted :-)
    # +++
    # +++
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    # database	ldbm
    # suffix	"dc=my-domain,dc=com"
    # rootdn	"cn=Manager,dc=my-domain,dc=com"
    # Cleartext passwords, especially for the rootdn, should
    # be avoided.  See slappasswd(8) and slapd.conf(5) for details.
    # Use of strong authentication encouraged.
    # rootpw	secret
    # rootpw	{crypt}ijFYNcSNctBYg
    
    # The database directory MUST exist prior to running slapd AND
    # should only be accessible by the slapd and slap tools.
    # Mode 700 recommended.
    directory	/var/lib/ldap
    
    # +++ Include file defining which attributes should be indexed +++
    include		/etc/openldap/slapd.index
    
    # Replicas of this database
    #replogfile /var/lib/ldap/openldap-master-replog
    #replica host=ldap-1.example.com:389 tls=yes
    #     bindmethod=sasl saslmech=GSSAPI
    #     authcId=host/ldap-master.example.com@EXAMPLE.COM
    
    
  5. As highlighted above, we have defined new schema for the NFSv4 Name to ID mapping. Below is our experimental (i.e. subject to change!) definition of new object classes and attributes. (Note that the OID values for these attributes were changed on 02/21/2005.) These definitions depend on the nis.schema, which in turn depends on core.schema and cosine.schema.
    attributetype ( 1.3.6.1.4.1.250.10.1
    	NAME ( 'NFSv4Name')
    	DESC 'NFS version 4 Name'
    	EQUALITY caseIgnoreIA5Match
    	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
    	SINGLE-VALUE)
    
    attributetype ( 1.3.6.1.4.1.250.10.2
    	NAME ( 'GSSAuthName')
    	DESC 'RPCSEC GSS authenticated user name'
    	EQUALITY caseIgnoreIA5Match
    	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
    
    #
    # minimal information for NFSv4 access. used when local filesystem 
    # access is not permitted (nsswitch ldap calls fail), or when
    # inetorgPerson is too much info.
    # 
    objectclass ( 1.3.6.1.4.1.250.10.3 NAME 'NFSv4RemotePerson'
    	DESC 'NFS version4 person from remote NFSv4 Domain'
    	SUP top AUXILIARY
    	MUST ( uidNumber $ gidNumber $ NFSv4Name )
    	MAY ( cn $ GSSAuthName $ description) )
    
    #
    # minimal information for NFSv4 access. used when local filesystem 
    # access is not permitted (nsswitch ldap calls fail), or when
    # inetorgPerson is too much info.
    # 
    objectclass ( 1.3.6.1.4.1.250.10.4 NAME 'NFSv4RemoteGroup'
    	DESC 'NFS version4 group from remote NFSv4 Domain'
    	SUP top AUXILIARY
    	MUST ( gidNumber $ NFSv4Name )
    	MAY ( cn $ memberUid $ description) )
    
    
    
  6. The new attributes must be indexed for quick searching. Here is our /etc/openldap/slapd.index file:
    # Indices to maintain for this database
    index objectClass			eq,pres
    index ou,cn,mail,surname,givenname	eq,pres,sub
    index uidNumber,gidNumber,loginShell	eq,pres
    index uid,memberUid			eq,pres,sub
    index nisMapName,nisMapEntry		eq,pres,sub
    index authname				eq,pres
    index GSSAuthName			eq,pres
    index NFSv4Name				eq,pres
    
    
  7. Set up the /etc/openldap/slapd.acls file. (Note that this may not be exactly what you want...)
    # cat /etc/openldap/slapd.acls
    # Define global ACLs to disable default read access.
    
    #-----------------------------------------------------------------------#
    # Sample Access Control
    #-----------------------------------------------------------------------#
    #       Allow read access of root DSE
    #       Allow self write access
    #       Allow authenticated users read access
    #       Allow anonymous users to authenticate
    #
    #access to dn="" by * read
    #access to *
    #       by self write
    #       by users read
    #       by anonymous auth
    #
    # if no access controls are present, the default is:
    #       Allow read by all
    #
    # rootdn can always write!
    
    #-----------------------------------------------------------------------#
    #       Allow [authenticated] users read access
    #       Allow Manager to write anything
    #       Allow nss_ldap read access
    #       Allow self write access to own entry
    #       Allow unauthenticated users to authenticate
    #-----------------------------------------------------------------------#
    access  to *
            by * read
            by dn.base="cn=Manager,dc=arbitrary,dc=domain,dc=org" write
            by dn.base="cn=nss_ldap,dc=arbitrary,dc=domain,dc=org" read
            by self write
            by anonymous auth
    
    #-----------------------------------------------------------------------#
    #       Allow unauthenticated users read access to the uid attribute
    #-----------------------------------------------------------------------#
    #access to * attr=uid
    #       by * read
    
    #-----------------------------------------------------------------------#
    #       Allow anyone read access to root DSE
    #-----------------------------------------------------------------------#
    access  to dn=""
            by * read
    
    #-----------------------------------------------------------------------#
    #       Otherwise, no access allowed!
    #-----------------------------------------------------------------------#
    access  to *
            by * none
    # 
    
    
  8. Modify the sasl bindings file, /etc/openldap/slapd.sasl-mappings, to map SASL-authenticated requestors to LDAP DN identities.

    In the following example, SASL/GSSAPI-authenticated user kwc@TANGENT.REALM is given access to the LDAP database as DN cn=Manager,dc=arbitrary,dc=domain,dc=org, while other SASL/GSSAPI-authenticated users are given access as their own DN. See the LDAP documentation for more information.

    #-----------------------------------------------------------------------
    # Sample SASL identity mappings
    #-----------------------------------------------------------------------
    #       Map SASL identities to directory identities
    
    sasl-host
            tangent.citi.umich.edu
    sasl-realm
            TANGENT.REALM
    sasl-regexp
            uid=admin
            cn=Manager,dc=arbitrary,dc=domain,dc=org
    
    sasl-regexp
            uid=admin,cn=TANGENT.REALM,cn=gssapi,cn=auth
            cn=Manager,dc=arbitrary,dc=domain,dc=org
    
    sasl-regexp
            uid=kwc,cn=TANGENT.REALM,cn=gssapi,cn=auth
            cn=Manager,dc=arbitrary,dc=domain,dc=org
    
    sasl-regexp
            uid=(.*),cn=TANGENT.REALM,cn=gssapi,cn=auth
            ldap:uid=$1,ou=People,dc=arbitrary,dc=domain,dc=org
    
    
    
  9. To use Kerberos authentication to the ldap server, a keytab entry is required in /etc/krb5.keytab on the ldap server machine for principal, ldap/<hostname>@REALM. For example: ldap/culver.citi.umich.edu@CITI.UMICH.EDU.

  10. If iptables is in use, add configuration in /etc/sysconfig/iptables to allow remote machines to access the ldap and ldaps ports. For example:
    # cat /etc/sysconfig/iptables
    # Firewall configuration written by system-config-securitylevel
    # Manual customization of this file is not recommended.
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    :RH-Firewall-1-INPUT - [0:0]
    -A INPUT -j RH-Firewall-1-INPUT
    -A FORWARD -j RH-Firewall-1-INPUT
    -A RH-Firewall-1-INPUT -i lo -j ACCEPT
    -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
    -A RH-Firewall-1-INPUT -p 50 -j ACCEPT
    -A RH-Firewall-1-INPUT -p 51 -j ACCEPT
    ######## ldap uses 389 ldaps uses 636
    -A RH-Firewall-1-INPUT -m state --state NEW -p udp --dport ldap -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -p tcp --dport ldap -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -p udp --dport ldaps -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -p tcp --dport ldaps -j ACCEPT
    ########
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
    COMMIT
    # /etc/init.d/iptables restart
    
    
  11. Set up the default ldap client parameters in /etc/openldap/ldap.conf as follows:
    % cat /etc/openldap/ldap.conf
    # $OpenLDAP: pkg/ldap/libraries/libldap/ldap.conf,v 1.9 2000/09/04 19:57:01 kurt Exp $
    #
    # LDAP Defaults
    #
    
    # See ldap.conf(5) for details
    # This file should be world readable but not world writable.
    
    #BASE   dc=example, dc=com
    #URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
    
    #SIZELIMIT      12
    #TIMELIMIT      15
    #DEREF          never
    HOST tangent.citi.umich.edu
    BASE dc=arbitrary,dc=domain,dc=org
    % 
    
    
  12. Phew! Finally, we can start the ldap server and add some data!
    # /etc/init.d/ldap start
    

    Now add some initial structure to the ldap database with the top-level organization, a Manager, and two organizational units with the following command and LDIF file:

    % cat initial.ldif
    # arbitrary.domain.org
    dn: dc=arbitrary, dc=domain, dc=org
    objectClass: dcObject
    objectClass: organization
    o: CITI Administrators
    dc: arbitrary
    
    # Manager, arbitrary.domain.org
    dn: cn=Manager, dc=arbitrary, dc=domain, dc=org
    objectClass: organizationalRole
    cn: Manager
    
    # ou=People, arbitrary.domain.org
    dn: ou=People, dc=arbitrary, dc=domain, dc=org
    objectClass: top
    objectClass: organizationalUnit
    ou: People
    
    # ou=Groups, arbitrary.domain.org
    dn: ou=Groups, dc=arbitrary, dc=domain, dc=org
    objectClass: top
    objectClass: organizationalUnit
    ou: Groups
    % kinit kwc
    Password for kwc@TANGENT.REALM:
    % klist
    Ticket cache: FILE:/tmp/krb5cc_20010
    Default principal: kwc@TANGENT.REALM
    
    Valid starting     Expires            Service principal
    10/22/04 11:30:20  10/23/04 11:30:16  krbtgt/TANGENT.REALM@TANGENT.REALM
    
    
    Kerberos 4 ticket cache: /tmp/tkt0
    klist: You have no tickets cached
    % /usr/bin/ldapadd -Y GSSAPI -f initial.ldif 
    SASL/GSSAPI authentication started
    SASL username: kwc@TANGENT.REALM
    SASL SSF: 56
    SASL installing layers
    adding entry "dc=arbitrary, dc=domain, dc=org"
    
    adding entry "cn=Manager, dc=arbitrary, dc=domain, dc=org"
    
    adding entry "ou=People, dc=arbitrary, dc=domain, dc=org"
    
    adding entry "ou=Groups, dc=arbitrary, dc=domain, dc=org"
    
    % /usr/bin/ldapsearch -Y GSSAPI -s one 'objectclass=*' '*'
    SASL/GSSAPI authentication started
    SASL username: kwc@TANGENT.REALM
    SASL SSF: 56
    SASL installing layers
    # extended LDIF
    #
    # LDAPv3
    # base <> with scope one
    # filter: objectclass=*
    # requesting: * 
    #
    
    # Manager, arbitrary.domain.org
    dn: cn=Manager,dc=arbitrary,dc=domain,dc=org
    objectClass: organizationalRole
    cn: Manager
    
    # People, arbitrary.domain.org
    dn: ou=People,dc=arbitrary,dc=domain,dc=org
    objectClass: top
    objectClass: organizationalUnit
    ou: People
    
    # Groups, arbitrary.domain.org
    dn: ou=Groups,dc=arbitrary,dc=domain,dc=org
    objectClass: top
    objectClass: organizationalUnit
    ou: Groups
    
    # search result
    search: 4
    result: 0 Success
    
    # numResponses: 4
    # numEntries: 3
    % 
    
    
  13. Here is an example of an entry with the new NFSv4 mapping attributes defined. (You may note that this entry is from the "other" NFSv4 Domain!)
    % /usr/bin/ldapsearch -Y GSSAPI -s sub 'GSSAuthName=*' '*'
    SASL/GSSAPI authentication started
    SASL SSF: 56
    SASL installing layers
    version: 2
    
    #
    # filter: GSSAuthName=*
    # requesting: * 
    #
    
    # andros, People, citi, umich, edu
    dn: uid=andros,ou=People,dc=citi,dc=umich,dc=edu
    universityid: 07749036
    objectClass: top
    objectClass: person
    objectClass: organizationalPerson
    objectClass: umichPerson
    objectClass: inetorgperson
    objectClass: posixAccount
    objectClass: NFSv4RemotePerson
    cn: William Adamson
    cn: William A Adamson 1
    cn: William A Adamson
    cn: Andy Adamson
    sn: Adamson
    uid: andros
    krbName: andros@umich.edu
    krbName: andros@engin.umich.edu
    onvacation: FALSE
    mail: andros@umich.edu
    uidNumber: 23975
    gidNumber: 10
    homeDirectory: /users/andros
    loginShell: /bin/csh
    displayName: William A Adamson
    NFSv4Name: andros@citi.umich.edu
    GSSAuthName: andros@CITI.UMICH.EDU
    
    # search result
    search: 4
    result: 0 Success
    
    # numResponses: 2
    # numEntries: 1
    %
    
    
blank.space
b.star projects | techreports | press | lab | location | staff Email address
or call +1 734 763 2929
Copyright © 1996-2013
The Regents of the University of Michigan
bottom.line
citi