diff --git a/src/shared/libcrypt-util.c b/src/shared/libcrypt-util.c index 85069314be..4760d66c92 100644 --- a/src/shared/libcrypt-util.c +++ b/src/shared/libcrypt-util.c @@ -30,25 +30,27 @@ int dlopen_libcrypt(void) { if (cached < 0) return cached; /* Already tried, and failed. */ - /* Several distributions like Debian/Ubuntu and OpenSUSE provide libxcrypt as libcrypt.so.1, - * while others like Fedora/CentOS and Arch provide it as libcrypt.so.2. */ + /* Several distributions like Debian/Ubuntu and OpenSUSE provide libxcrypt as libcrypt.so.1 + * (libcrypt.so.1.1 on some architectures), while others like Fedora/CentOS and Arch provide it as + * libcrypt.so.2. */ ELF_NOTE_DLOPEN("crypt", "Support for hashing passwords", ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, - "libcrypt.so.2", "libcrypt.so.1"); + "libcrypt.so.2", "libcrypt.so.1", "libcrypt.so.1.1"); _cleanup_(dlclosep) void *dl = NULL; - r = dlopen_safe("libcrypt.so.2", &dl, /* reterr_dlerror= */ NULL); - if (r < 0) { - const char *dle = NULL; - r = dlopen_safe("libcrypt.so.1", &dl, &dle); - if (r < 0) { - log_debug_errno(r, "libcrypt.so.2/libcrypt.so.1 is not available: %s", dle ?: STRERROR(r)); - return (cached = -EOPNOTSUPP); /* turn into recognizable error */ + const char *dle = NULL; + FOREACH_STRING(soname, "libcrypt.so.2", "libcrypt.so.1", "libcrypt.so.1.1") { + r = dlopen_safe(soname, &dl, &dle); + if (r >= 0) { + log_debug("Loaded '%s' via dlopen().", soname); + break; } - log_debug("Loaded 'libcrypt.so.1' via dlopen()"); - } else - log_debug("Loaded 'libcrypt.so.2' via dlopen()"); + } + if (r < 0) { + log_debug_errno(r, "Failed to load libcrypt: %s", dle ?: STRERROR(r)); + return (cached = -EOPNOTSUPP); /* turn into recognizable error */ + } r = dlsym_many_or_warn( dl, LOG_DEBUG,