1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-11 16:58:40 +03:00

dsdb:password_hash: use talloc_crypt_blob()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15756

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Douglas Bagnall 2024-12-12 11:16:22 +13:00 committed by Andreas Schneider
parent 1edb12f795
commit c7597380b4
2 changed files with 13 additions and 57 deletions

View File

@ -51,6 +51,7 @@
#include "auth/common_auth.h"
#include "lib/messaging/messaging.h"
#include "lib/param/loadparm.h"
#include "lib/util/util_crypt.h"
#include "lib/crypto/gnutls_helpers.h"
#include <gnutls/crypto.h>
@ -1592,16 +1593,11 @@ static int setup_primary_userPassword_hash(
struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
const char *salt = NULL; /* Randomly generated salt */
const char *cmd = NULL; /* command passed to crypt */
const char *hash = NULL; /* password hash generated by crypt */
int algorithm = 0; /* crypt hash algorithm number */
int rounds = 0; /* The number of hash rounds */
int ret;
DATA_BLOB *hash_blob = NULL;
TALLOC_CTX *frame = talloc_stackframe();
#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN)
struct crypt_data crypt_data = {
.initialized = 0 /* working storage used by crypt */
};
#endif
/* Generate a random password salt */
salt = generate_random_str_list(frame,
@ -1660,52 +1656,20 @@ 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_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
/*
* No crypt_r falling back to crypt, which is NOT thread safe
* Thread safety MT-Unsafe race:crypt
*/
hash = crypt((char *)io->n.cleartext_utf8->data, cmd);
#endif
/*
* On error, crypt() and crypt_r() may return a null pointer,
* or a pointer to an invalid hash beginning with a '*'.
*/
if (hash == NULL || hash[0] == '*') {
ret = talloc_crypt_blob(hash_blob,
(char *)io->n.cleartext_utf8->data,
cmd,
hash_blob);
if (ret != 0) {
char buf[1024];
const char *reason = NULL;
if (errno == ERANGE) {
if (ret == ERANGE) {
reason = "Password exceeds maximum length allowed for crypt() hashing";
} else if (ret == ENOTRECOVERABLE) {
/* probably weird RHEL7 crypt, see talloc_crypt_blob() */
reason = "Unknown error";
} else {
int err = strerror_r(errno, buf, sizeof(buf));
int err = strerror_r(ret, buf, sizeof(buf));
if (err == 0) {
reason = buf;
} else {
@ -1723,14 +1687,6 @@ static int setup_primary_userPassword_hash(
return LDB_ERR_OPERATIONS_ERROR;
}
*hash_blob = data_blob_talloc(hash_blob,
(const uint8_t *)hash,
strlen(hash));
if (hash_blob->data == NULL) {
TALLOC_FREE(frame);
return ldb_oom(ldb);
}
hash_value->value = hash_blob;
TALLOC_FREE(frame);
return LDB_SUCCESS;

View File

@ -195,7 +195,7 @@ bld.SAMBA_MODULE('ldb_password_hash',
init_function='ldb_password_hash_module_init',
module_init_name='ldb_init_module',
internal_module=False,
deps='talloc samdb LIBCLI_AUTH NDR_DRSBLOBS authkrb5 krb5 gpgme DSDB_MODULE_HELPERS crypt db-glue'
deps='talloc samdb LIBCLI_AUTH NDR_DRSBLOBS authkrb5 krb5 gpgme DSDB_MODULE_HELPERS util_crypt db-glue'
)