Read Me About CryptNoMore.txt

Read Me About CryptNoMore
=========================
1.2
 
Since the introduction of Mac OS X 10.3, it is no longer possible to authenticate a user (that is, check the validity of their password) using crypt <x-man-page://3/crypt>.  This sample shows how to authenticate a user using Open Directory (Directory Services).  It's targeted at folks who are currently using crypt and find that their code mysteriously stopped working in 10.3.
 
CryptNoMore should work on any version of Mac OS X.  It was originally tested on Mac OS X 10.3.5 and Mac OS X 10.4.  This version has been tested on Mac OS X 10.4.11 and Mac OS X 10.5.
 
Packing List
------------
The sample contains the following items:
 
o Read Me About CryptNoMore.txt -- This file.
o CryptNoMore.c -- C source code for the program.
o CryptNoMore.xcodeproj -- An Xcode 3.0 project for the program.
o build -- A built version of the program.
 
Using the Sample
----------------
To try out the sample, change into the sample directory.
 
$ cd ~/Downloads/CryptNoMore
 
You can get help using the "-?" option.
 
$ build/Debug/CryptNoMore -?
build/Debug/CryptNoMore: illegal option -- ?
usage: CryptNoMore [option] [ username [ password ] ]
  -d use Open Directory (Directory Services) (default, recommended)
  -p use PAM
  -c use crypt(3) (recommended against)
  -l when using Open Directory, only allow local users
 
You can use the "-d" option to authenticate a user using Open Directory.  In the following example, the user's name is "mrgumby" and their password is "opendoor".
 
$ build/Debug/CryptNoMore -d mrgumby opendoor
Authenticated!
 
You can use the "-c" option to authenticate a user using crypt.  This is provided for completeness only; it does not work on Mac OS X 10.3 and later (for a standard user).  This is because the user's password is stored in a shadow password file.
 
$ build/Debug/CryptNoMore -c mrgumby opendoor
Authentication failed because the user's password is not available
 
Finally, CryptNoMore also support authentication via PAM.  See the comments in the source for a discussion of the pros and cons of using PAM for authentication on Mac OS X.
 
Building the Sample
-------------------
The sample was built using Xcode 3.0 on Mac OS X 10.5.1.  You should be able to just open the project and choose Build from the Build menu.  This will build the CryptNoMore tool in the "build" directory.
 
How it Works
------------
The sample's main routine just dispatches to one of three different implementations:
 
o AuthenticateWithCrypt implements classic crypt-based authentication.
 
o AuthenticateWithPAM is a fairly simple PAM-based authentication implementation.  PAM has a number of pros and cons on Mac OS X.  These are discussed in the comments in the code, and I won't reiterate them here.
 
o AuthenticateWithOpenDirectory is the default authentication mechanism.  If you just want to cut'n'paste code, you should copy the GetSearchNodePathList, FindUsersAuthInfo, AddToBuf, AuthenticateWithNode, and CheckPasswordUsingOpenDirectory routines into your project and call CheckPasswordUsingOpenDirectory to check a password.  If you want to understand what's going on, read on...
 
There are three steps to authenticating with Open Directory:
 
1. Find the search node -- You need access to this node in order to search for the Open Directory record of the user you want to authenticate.  The search node is responsible for enforcing the authentication policy decisions you set in the Directory Access utility.  For example, if you modify Directory Access to allow LDAP users to log into your machine, this information is known to the search node.  The code to find the search node is in GetSearchNodePathList.
 
2. Look up the user's record -- To authenticate a user you need to know two attributes of the user: their authentication name and their authentication node (the node that's responsible for checking their user name and password; this might be, for example, a password server).  To find this you must look up the user's record and then get those two attributes from the user record.  This is done by the FindUsersAuthInfo routine.
 
3. Authenticate the user -- Once you know the authentication node for the user, you can call dsDoDirNodeAuth (an Open Directory routine) to do the authentication.  The code to do this is in AuthenticateWithNode.
 
Caveats
-------
Crypt-based authentication is not useful in modern versions of Mac OS X.  You should use Open Directory or PAM instead.
 
PAM has a number of caveats when used on Mac OS X; these are described by comments in the code.
 
My current Open Directory code treats eDSAuthNewPasswordRequired and eDSAuthPasswordExpired results as login failures; a fully featured program would let the user change their password.
 
Credits and Version History
---------------------------
If you find any problems with this sample, mail <dts@apple.com> and I'll try to fix them up.
 
1.0 (Oct 2004) was the first shipping version.
 
1.1 (Jul 2005) was updated to include an Xcode 2.1 project to produce universal binaries.  There were no code changes required for it to run correctly on the Developer Transition Systems.  However, I did modify the code slightly to eliminate some new warnings produced by GCC 4.0.
 
1.2 (Feb 2008) corrects a bug with Open Directory-based authentication that was uncovered by Mac OS X 10.5 <rdar://problem/5768067>.  Also, Open Directory authentication now works correctly when built 64-bit.
 
Share and Enjoy.
 
Apple Developer Technical Support
Networking, Communications, Hardware
 
27 Feb 2008