=========== README.LDAP Jos Visser (josv@osp.nl) =========== Date: Mon Dec 4 12:42:34 CET 2000 Introduction ------------ And thus it came to pass that for an extranet project I was working on I felt this pressing need to have the WU FTP daemon lookup and authenticate users in an LDAP compliant directory service (e.g. the Netscape Directory Server). After having looked around on the Internet, and investigating things like PAM, I decided to extend WU FTP with an LDAP capability. Since you're reading this file, I presume that you want to know how it works. First of all, the current capability is *very* basic, but, it is exactly what I need and can relatively easily be extended. An important thing that is currently missing is connecting over SSL (port 636). But, who knows what the future will hold? Why? ---- Good question. Traditionally, FTP knows two types of users: anonymous users and real users. The anonymous user has a virtual user name ("anonymous" or "ftp"), whereas real users must be present in the system password file. WU FTP has a "guest user" capability which restricts a real user to his home directory. However, the user and password are still maintained in the system password file (/etc/passwd). In my project, I had an extranet application that uses a mix of web and FTP to up-and-download files to and from an Internet server. Both web and FTP access are restricted to authenticated and authorised users. I want to use the same user administration for web and FTP access, and I do not want the users to be in the Unix password file (for security and other reasons). My web server is a Netscape Enterprise (web) Server which has built-in capabilities to use an LDAP directory server. So, all I lack is LDAP support in my FTP daemon. Building WU FTP with LDAP ------------------------- The following description assumes that you're a code warrior who has build, installed and configured WU FTP before. Fortunately, as of 2.6.0 the WU FTP gurus decided to configure and build with GNU autoconf. This greatly eased my changes to the build environment (thanks guys :-). To build WU FTP with LDAP support you need: - WU FTP 2.6.1 - a patched version of src/ftpd.c - ldapftp.c - OpenLDAP 2.x - Cyrus SASL First, build OpenLDAP conform its instructions. We only need the LDAP SDK libraries, but why not build the OpenLDAP directory server and play with it while your at it? Then, build WU FTP with LDAP support: ./configure --enable-ldap --with-openldap-dir=/your/openldap/dir/here If you're really lucky, everything builds. Mind you, currently this is all development code. It builds on my laptop (SuSE Linux 6.3) and that's all I can currently promise. After configuring, run "make" and "make install". If everything went ok, then FTP to yourself, and WU FTP should say hello like this: 220 jadzia.josv.com FTP server (Version wu-2.6.1(5) Sat Oct 23 23:23:40 MEST 1999, with LDAP support) ready. Pay attention to the "with LDAP support", this is the sign that LDAP support has been built in. How does the WU FTP daemon use LDAP? ------------------------------------ The core of WU FTP is in the file "src/ftpd.c". When an FTP user sends his/her user name, WU FTP normally uses "getpwnam" to retrieve user information such as the uid, gid and home directory. When this fails user authentication fails. In the patched ftpd.c compiled with '#define USE_LDAP 1', ftpd.c then calls out to "getpwnam_ldap()" (in ldapftp.c) which tries to look up the user in the directory. If this succeeds, the user information is retrieved from the directory and then copied in an industry standard "struct passwd". If the user then sends his/her password (and the user information was looked up using LDAP), the routine "check_pass_ldap()" is called to check the password against the password field in the directory. Please beware that the patched "ftpd.c" *first* looks up the user using the "old" lookup scheme (anonymous, system password file), and only when this fails it employs LDAP to lookup the user in the directory. So it remains possible to FTP in using a real user! Furthermore, LDAP can be employed *together* with the "guest user" facility. WU FTP with LDAP retrieves the numeric uid and gid from the directory, and then the ordinary "ftpaccess" statements like "guestuser" and "guestgroup" are checked to see if access restrictions apply. Most commonly you would want to use "guest access" together with LDAP! Configuring WU FTP for LDAP access ---------------------------------- All necessary parameters for the LDAP connection have to be specified in the "ftpaccess" file. A couple of new ftpaccess statements have been added that allow the administrator to specify the connection parameters: ldap-host ldap.osp.nl ldap-port 389 ldap-base o=osp.nl ldap-user uid=dirmgr, ou=Directory Users, o=osp.nl ldap-password secret Sensible defaults exist for these parameters, so you do not need to specify anything. However, the "ldap-user" used in the LDAP connection must have enough permission to search the directory, retrieve user information and compare the user password to the value stored in the directory. Configuring the directory for WU FTP ------------------------------------ WU FTP looks up users with the search filter "uid=username". The user entries for which you want to allow FTP access *must* be of object class "ftpUser". Presumably this object class does not exist in your directory. The solution: add it using your directories extensible schema editor. WU FTP expects the following attributes to be present in the user entry: - uid the user name (string) - userPassword (string) - uidNumber the numeric userid (a la Unix, integer) - gidNumber the numeric groupid (a la Unix, integer) - homeDirectory the user's home directory (string) The following attributes may be present: - cn the common name of the user (string) - gecos a standard Unix gecos field (string) You need to set up permissions in the directory so that the user that WU FTP uses has enough permissions to search through the directory, retrieve the attributes specified before *and* have "compare" permission to the userPassword field. Regarding user password storage. WU FTP tries SHA, MD5 and clear text passwords before it gives up. Reference --------- There is tons of stuff on LDAP out there. From personal experience I can recommend the book "LDAP -- programming directory enabled applications with lightweight directory access protocol" by Tim Howes and Mark Smith. Example ------- The following is the output of a series of Unix commands that show how things work (everything following // are my comments): // First I perform an ldapsearch to show you the entry of user test in // the directory $ ldapsearch -b o=osp.nl uid=test uid=test,o=OSP,ou=extranet,o=osp.nl objectclass=top objectclass=person objectclass=organizationalPerson objectclass=inetOrgPerson objectclass=ftpUser // You see, this is an FTP user cn=Test User uid=test givenname=Test sn=User creatorsname=uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot createtimestamp=19990819205615Z homedirectory=/home/josv/tmp uidnumber=1003 // Pay attention here! gidnumber=1003 modifiersname=uid=dirmgr,ou=Directory Users,o=osp.nl modifytimestamp=19990820093201Z // Please note that you do not see the userPassword field in the entry // above. This is because the anonymous LDAP user that I used in the // ldapsearch does not have read permission for this attribute. // Now I am going to perform an FTP $ ftp localhost Connected to localhost. 220 jadzia.josv.com FTP server (Version wu-2.6.1(5) Sat Oct 23 23:23:40 MEST 1999, with LDAP support) ready. Name (localhost:josv): test // This is a directory user! 331 Password required for test. Password: 230-Welcome Test User // This comes from the "cn" attribute 230-Please read the file README 230- it was last modified on Fri Apr 2 08:19:31 1999 - 140 days ago 230 User test logged in. Access restrictions apply. // Pay attention! Remote system type is UNIX. Using binary mode to transfer files. ftp> pwd 257 "/" is current directory. // Pay attention! ftp> quit 221-You have transferred 0 bytes in 0 files. 221-Total traffic for this session was 431 bytes in 0 transfers. 221-Thank you for using the FTP service on jadzia.josv.com. 221 Goodbye. // Well, that spoke for itself I reckon.... // And we have logged something in the syslog $ tail /var/log/messages Aug 20 16:36:43 jadzia wu.ftpd[8722]: connect from josv@127.0.0.1 Aug 20 16:36:45 jadzia ftpd[8722]: test recognised as uid=test,o=OSP,ou=extranet,o=osp.nl (Test User) About the example ----------------- In this example, I used the WU FTP guest user facility in combination with WU FTP LDAP. In the directory the numeric uid and gid of the user "test" are 1003. This is the actual uid and gid of a user and group in the system: In /etc/passwd: extraftp:x:1003:1003:Extranet FTP user:/not/exist:/no/shell In /etc/group: extraftp:x:1003:extraftp So, the FTP daemon assumes the identity of the "extraftp" Unix user. Furthermore, in "/etc/ftpaccess" we have: guestuser %1003 So, after having authenticated the user, WU FTP fires up its normal "guest" facilities, doing a chroot to the user's home directory (from the directory (/home/josv/tmp)) and restricts the user to that directory. Neat uh? Questions? Comments? -------------------- This work is contributed in the hope that it may prove useful to someone. Feel free to adopt, adapt and improve as you see fit. Any questions related to this code can be addressed to josv@osp.nl. Share and Enjoy!