paul at argo.demon.co.uk
Tue Feb 24 13:44:22 GMT 1998
Here is my understanding of the possibilities to support common
passwords between Unix and NT and Samba.
(Aside: standard description of the password hashing for
Standard Unix passwords are obtained through 25 iterations of
modified DES, using the password up to 8 characters and a
two character salt. The algorithm is not reversible.
NT stores 2 versions of the password. One is the Lanman hash
which involves a single standard DES encryption on each half
of a 14 character password (upper cased) independently and no
salt. The second is the NT hash which is MD4(Unicode(password)).
Neither of the hashes are reversible, but the Lanman one is
brute forceable given typical password usage constraints).
The NT and LM hashes also function as password equivalents
and their secrecy, even though they are hashed, is critical.
Evidently we can't reverse any of the hashes, and we don't
really want to brute force the Lanman hashes, so we can't
turn any to plaintext and reencrypt in the others.
This means we must gain access to the password whilst it
is plaintext and convert it, if that is desired.
There are two ways to do this: gain access to the plaintext
when it is changed, or gain access when it is used.
NT clients provide the plaintext password to the server
when the password is changed, so we could use that to
synchonise the passwords. This involves implementing a
couple of RPCs which are more or less understood, but just
need implementing. It is also nice in that we don't have
to make any client changes. The problem is that other ways
of changing the password don't provide the plaintext, such
as the SMB password change function and one of the MS CHAP
password change functions for example. These provide only
the new password hash, meaning we can't generate an /etc/passwd
If we wish to make a client modification we can gain access
to the plaintext password on NT by installing a notification
and install a dll that communicates the password
to the server (securely we hope), and allows it to
generate a Unix password.
When Unix passwords are changed, the are almost exclusively
hashed on the client and communicated to the name service
afterwards, (NIS, NIS+, /etc/passwd). This doesn't give
us any opportunity to form any other type of hash of the
plaintext. In order to synchonise passwords at this point
would require a modification to /bin/passwd or equivalent, or
a new PAM module.
At password usage time, we can gain access to the NT password
at several different points:-
GINA - The GINA module presents the GUI username and password
request at interactive login time. Obviously it has access to
your plaintext password and can use this to communicate with
another password server. There are several examples of replacement
GINAs, most notable being NISGINA which contains a full port of
ONC RPC and Unix compatible NIS library calls. The disadvantage
with this is that it is quite a large chunk of code leading
to lots of possibilities of introducing bugs, and also, lots
of other people like to make replacement GINAs too, making
interoperability difficult at best.
Next is a new "authentication package". The standard one, msv1_0
authenticates via the local SAM or a DC via the NETLOGON service.
There isn't much information on this other than lsaauth.hlp in
the ddk/msdn. I also haven't come across any freely available
examples. The lsaauth.hlp API information may be sufficient
to implement a replacement or augmentation of msv1_0 that would
allow the plaintext password to be communicated to a password
server (search for the LsaApCallPackage function and friends).
Next we have a "subauthentication dll". These are external DLLs
called by msv1_0 to do additional or replacement user validation.
The documentation (SDK samples/win32/winnt/security/subauth/readme.txt)
indicates that these DLLs have access to the password in order
to do alternative or extra validation.
It may also be possible to provide an alternative "network provider"
that also has access to the user password. I haven't really looked
into this and would welcome some insight.
On the Unix side we can modify /bin/login, su, passwd, telnetd,
etc., or the appropriate library interface or write a new PAM
for those systems that support it (at least Linux + Solaris).
These could generate the new smbpasswd entry.
Instead of trying to synchronise password hashes we can change
one system to use the hashes of the other. NT uses the password
hash in many places other than at login time, such as in RPCs,
HTTP-NTLM, SMB, and all of these would have to be modified to
support the new value.
On Unix here are PAMs to synchronise with NT servers (and therefore
Samba also), or Samba directly. However the disadvantage is
that we use the weak NT password equivalents.
Finally, we can skip all this completely. Stop anyone changing
password on either system somehow, and only allow password
changing via a Web browser (for example) over SSL, which propogates
the changes to all databases.
Personally I would prefer to change both systems to use a new
system in common such as http://srp.stanford.edu/srp/
This would involve writing PAMs for Unix and a new authentication
package for NT (at least). I definitely would not want to
have a new GINA (I've tried it...).
Please post any corrections, observations or pointers to examples.
More information about the samba-ntdom