| 
 |  
  | 
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.
 
- Verify you have the openldap-servers package installed.
If not, install it:
# yum install openldap-servers
 
 - 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
#
 
 - 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          
#
 
 - 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
 - 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) )
 
 - 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
 
 - 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
# 
 - 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
 - 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.
  - 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
 
 - 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
% 
 
 - 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
% 
 
 - 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
%
 
   
  | 
 | 
  | 
  
 |