mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
dsdb: Allow "password hash userPassword schemes = CryptSHA256" to work on RHEL7
On RHEL7 crypt_r() will set errno. This is a problem because the implementation of crypt_r() in RHEL8 and elsewhere in libcrypt will return non-NULL but set errno on failure. The workaround is to use crypt_rn(), provided only by libcrypt, which will return NULL on failure, and so avoid checking errno in the non-failure case. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14424 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
This commit is contained in:
parent
213501163c
commit
91453f110f
@ -661,6 +661,7 @@ def configure(conf):
|
||||
|
||||
conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True)
|
||||
conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True)
|
||||
conf.CHECK_FUNCS_IN('crypt_rn', 'crypt', checklibc=True)
|
||||
|
||||
conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True,
|
||||
headers='readline.h readline/readline.h readline/history.h')
|
||||
|
@ -1473,8 +1473,10 @@ static int setup_primary_userPassword_hash(
|
||||
int rounds = 0; /* The number of hash rounds */
|
||||
DATA_BLOB *hash_blob = NULL;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
#ifdef HAVE_CRYPT_R
|
||||
struct crypt_data crypt_data; /* working storage used by crypt */
|
||||
#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN)
|
||||
struct crypt_data crypt_data = {
|
||||
.initialized = 0 /* working storage used by crypt */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Genrate a random password salt */
|
||||
@ -1515,8 +1517,32 @@ static int setup_primary_userPassword_hash(
|
||||
* Relies on the assertion that cleartext_utf8->data is a zero
|
||||
* terminated UTF-8 string
|
||||
*/
|
||||
|
||||
/*
|
||||
* crypt_r() and crypt() may return a null pointer upon error
|
||||
* depending on how libcrypt was configured, so we prefer
|
||||
* crypt_rn() from libcrypt / libxcrypt which always returns
|
||||
* NULL on error.
|
||||
*
|
||||
* POSIX specifies returning a null pointer and setting
|
||||
* errno.
|
||||
*
|
||||
* RHEL 7 (which does not use libcrypt / libxcrypt) returns a
|
||||
* non-NULL pointer from crypt_r() on success but (always?)
|
||||
* sets errno during internal processing in the NSS crypto
|
||||
* subsystem.
|
||||
*
|
||||
* By preferring crypt_rn we avoid the 'return non-NULL but
|
||||
* set-errno' that we otherwise cannot tell apart from the
|
||||
* RHEL 7 behaviour.
|
||||
*/
|
||||
errno = 0;
|
||||
#ifdef HAVE_CRYPT_R
|
||||
#ifdef HAVE_CRYPT_RN
|
||||
hash = crypt_rn((char *)io->n.cleartext_utf8->data,
|
||||
cmd,
|
||||
&crypt_data,
|
||||
sizeof(crypt_data));
|
||||
#elif HAVE_CRYPT_R
|
||||
hash = crypt_r((char *)io->n.cleartext_utf8->data, cmd, &crypt_data);
|
||||
#else
|
||||
/*
|
||||
@ -1525,10 +1551,7 @@ static int setup_primary_userPassword_hash(
|
||||
*/
|
||||
hash = crypt((char *)io->n.cleartext_utf8->data, cmd);
|
||||
#endif
|
||||
/* crypt_r and crypt may return a null pointer upon error depending on
|
||||
* how libcrypt was configured. POSIX specifies returning a null
|
||||
* pointer and setting errno. */
|
||||
if (hash == NULL || errno != 0) {
|
||||
if (hash == NULL) {
|
||||
char buf[1024];
|
||||
int err = strerror_r(errno, buf, sizeof(buf));
|
||||
if (err != 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user