The printf("%s %s", foo(), foo()) problem is unusual for crypt() --- but it isn't for other functions that return points to global static memory, inet_ntoa() in particular (you often want to print both source and destination addresses). To get around this, I used to have a preloaded inet_ntoa that alternated between two global static buffers. :)
Preloading a version that alternates between two buffers is clearly Wrong, but I'm not sure what the right solution is - do you/does anyone have a pattern that they find works well for them?
Our codebase has quite a few functions like inet_ntoa():
/* returns ptr. to internal static storage */
const char *type_to_str(const Type *type);
You could pass an explicit argument, but that's pretty ugly:
(Warning: this is probably too clever. Note that you need the explicit size argument if you offer a library, or you risk your callers using a different FOO_TO_STR_SIZE than you do. There is probably a very minor performance penalty to this solution as the caller must, in general, completely initialize the string. Note the gcc warnings about compound literals in C++ - see https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html for a discussion.)
It's morally wrong, but since you usually only ever want to print two IP addresses, it feels so right. In any case: it can't break otherwise-correct code.
returning a const char is absolutely fine - I assume your type name is allocated when the type is and never changes, and you have locking if necessary.
There aren't that many left though, they are a terrible idea.
The NetBSD man page for inet_ntoa lists "The string returned by inet_ntoa() resides in a static memory area" in the BUGS section, Linux is not so forward about it.
The PHC is defining a standard API which works with all the proposed algorithms as part of the contest. There's a lot that a proper password hashing API can provide and be secure by default. The PHC mailing list has pretty extensive discussion on this topic.
Where I work we still have many solaris machines and our logins are managed via NIS. Is there a hashing function that is supported for logins on solaris, linux and BSD that we can use other than the DES based one?
Solaris 9+, recentish Linux, and recentish BSD should all support algorithm $1$ (MD5) at an absolute minimum. Depending on OS versions, you might also be able to choose from $2a$ (Blowfish), $5$ (SHA-256), and $6$ (SHA-512). On Solaris, the list of supported algorithms is in /etc/security/crypt.conf. "man 3 crypt" might tell you what's supported on your Linux and BSD machines.
For NIS, you'd need to ensure that every machine that touches passwords via NIS is configured to use the same algorithm when users change passwords. On Solaris, just configure CRYPT_* in /etc/security/policy.conf the same on every machine. (See the policy.conf man page — in short, you want to change the default algorithm to 1 [or whatever] and set __unix__ to be deprecated.) On Linux and *BSD, how you do it depends on the distro/version.
Fun fact about changing passwords in NIS: When a yppasswd client contacts rpc.yppasswdd to change a user's password, the user's new password is sent crypt()ed, but the user's old password is sent in the clear.
The printf("%s %s", foo(), foo()) problem is unusual for crypt() --- but it isn't for other functions that return points to global static memory, inet_ntoa() in particular (you often want to print both source and destination addresses). To get around this, I used to have a preloaded inet_ntoa that alternated between two global static buffers. :)