[12833] Refactor directoryservice user provider
Previously, the OS X directoryservice user provider could not handle
10.8 users due to version 10.8 of OS X implementing PBKDF2-style
password hashing/stretching. The user provider also struggled with
setting 10.7-style passwords in a single run due to the way that
passwords are stored in OS X versions 10.7 and higher.
The dscl binary is in charge of changing user attributes, and CAN be
used to set a user's password, but it must be provided with a plaintext
password. We have discovered no way to use dscl or dsimport and pass
it a password hash that will be set for a user. Because of this fault,
the user's plist located in /var/db/dslocal/nodes/Default/users must be
directly modified. Because the dscl command maintains its own caching
system, changes made using the dscl command will not be immediately written
to disk. Conversely, DIRECT CHANGES to the user's plist file will NOT be
recognized by the dscl command unless you flush its cache. Flushing the
dscl cache is an asynchronous action, however, so you must sleep long
enough for dscl to read-from/write-to disk.
With the mechanism for reading/writing passwords cleaned up, the problem
remains that 10.8 uses PBKDF2 passwords that rely on a salt and iterations
value. These three values (the hash, the salt, and the iterations value)
together form a unique key that comprise the user's password. Because
the salt and iterations values must be specified, the user type had to
be modified to allow these values to be passed in a user resource
declaration. This change does not break clients on versions of OS X
older than 10.8.
With these two faults in mind, the decision was made to completely
re-write the directoryservice user provide so that it shed its reliance
on the lib/puppet/provider/nameservice/directoryservice plugin and was
completely independent. This commit refactors the directoryservice user
provider according to the aforementioned deficiencies and implements
tests for the new user provider.