Take a look at the code I posted. I sidestepped the issue with:
#define ENCRYPT "O26nQUAUM2vLA"
but the su program obtains the encrypted string from somewhere. Exactly where varies. It might be /etc/passwd. It might be /etc/shadow. It might be NIS or NIS+. There are other options too. All that matters is that the local su program knows where to obtain the encrypted string. And it gets the plaintext candidate password interactively from the user. Then it uses the code I posted to compare the two. (Or something pretty similiar. )
I think that what is bothering you is a missing piece of data. Usually we think of something roughly like this: PLAINTEXT + KEY = CHIPHERTEXT
Actually the cleartext password is the key and the encrypted password is the chiphertext. So where is the plaintext? It is a well known constant stored in crypt routine. This is why the Unix password is locked at 8 characters in length. It is easy to increase the length of the cleartext but a new algorithm is needed to the size of the key. They had to do it this way. If the key was stored in the source code, everyone (who cared) would know it and anyone could use it to decrypt the password. But there is no way to take the plaintext and the chiphertext and recover the key. They wanted the password to be secure even if you had the source code for crypt() and the encrypted password. Even today, all these decades later, brute force is still the only viable attack. The weakness of the Unix password scheme is that today brute force is feasible against an 8 character password. crypt() is actually an amazing piece of work.
The salt is just basicly one of 4096 random strings added to password. So if my password is "bullfrog" the encrypted password will be one of 4096 results. This makes it harder to recognize that two accounts have the same password. And if you try to build a database of possible encrypted strings, your job is now 4096 times harder.
The Unix password scheme is described in the paper
Password Security: A Case History by Robert Morris and Ken Thompson. This is not the RTM who wrote the Morris Worm; this is his father. I found a copy in the
UNIX System Manager's Manual which was part of the 4.3 BSD documents dated April, 1986. But I think that paper is circa 1975 or so. It is a very early paper. BTW, Morris and Thompson also wrote the crypt() routine itself.
[EDIT]
I found that paper at the ACM website:
Link
Published in 1979 I see... oh well, I had the right decade!