mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
util: add a crypt wrapper, derived from dsdb:password_hash
This is going to be used by the dsdb password_hash module, and exposed to Python via pyglue. We're doing this because Python 3.13 has dropped crypt from the Python standard library. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15756 Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
5ad1a93107
commit
833455c7f9
90
lib/util/util_crypt.c
Normal file
90
lib/util/util_crypt.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include <replace.h>
|
||||
#include "data_blob.h"
|
||||
#include <talloc.h>
|
||||
#include <crypt.h>
|
||||
#include "util_crypt.h"
|
||||
|
||||
|
||||
static int crypt_as_best_we_can(const char *phrase,
|
||||
const char *setting,
|
||||
const char **hashp)
|
||||
{
|
||||
int ret = 0;
|
||||
const char *hash = NULL;
|
||||
|
||||
#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN)
|
||||
struct crypt_data crypt_data = {
|
||||
.initialized = 0 /* working storage used by crypt */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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(phrase, setting,
|
||||
&crypt_data,
|
||||
sizeof(crypt_data));
|
||||
#elif HAVE_CRYPT_R
|
||||
hash = crypt_r(phrase, setting, &crypt_data);
|
||||
#else
|
||||
/*
|
||||
* No crypt_r falling back to crypt, which is NOT thread safe
|
||||
* Thread safety MT-Unsafe race:crypt
|
||||
*/
|
||||
hash = crypt(phrase, setting);
|
||||
#endif
|
||||
/*
|
||||
* On error, crypt() and crypt_r() may return a null pointer,
|
||||
* or a pointer to an invalid hash beginning with a '*'.
|
||||
*/
|
||||
ret = errno;
|
||||
errno = 0;
|
||||
if (hash == NULL || hash[0] == '*') {
|
||||
if (ret == 0) {
|
||||
/* this is annoying */
|
||||
ret = ENOTRECOVERABLE;
|
||||
}
|
||||
}
|
||||
|
||||
*hashp = hash;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int talloc_crypt_blob(TALLOC_CTX *mem_ctx,
|
||||
const char *phrase,
|
||||
const char *setting,
|
||||
DATA_BLOB *blob)
|
||||
{
|
||||
const char *hash = NULL;
|
||||
int ret = crypt_as_best_we_can(phrase, setting, &hash);
|
||||
if (ret != 0) {
|
||||
blob->data = NULL;
|
||||
blob->length = 0;
|
||||
return ret;
|
||||
}
|
||||
blob->length = strlen(hash);
|
||||
blob->data = talloc_memdup(mem_ctx, hash, blob->length);
|
||||
if (blob->data == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
5
lib/util/util_crypt.h
Normal file
5
lib/util/util_crypt.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
int talloc_crypt_blob(TALLOC_CTX *mem_ctx,
|
||||
const char *phrase,
|
||||
const char *cmd,
|
||||
DATA_BLOB *blob);
|
@ -253,6 +253,12 @@ else:
|
||||
private_library=True,
|
||||
local_include=False)
|
||||
|
||||
bld.SAMBA_LIBRARY('util_crypt',
|
||||
source='util_crypt.c',
|
||||
deps='talloc crypt',
|
||||
private_library=True,
|
||||
local_include=False)
|
||||
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('UNIX_PRIVS',
|
||||
source='unix_privs.c',
|
||||
|
Loading…
Reference in New Issue
Block a user