various: add -Dbuild-static and alternatives to libc functions
When we try to build with -static, the linker refuses dlopen and various functions related to nss. This commit adds the basic support to compile with -static and allow the link to pass.
This commit is contained in:
@@ -101,6 +101,10 @@ void block_dlopen(void) {
|
||||
}
|
||||
|
||||
int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
#if BUILD_STATIC
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"dlopen is not supported in static builds, cannot load %s.", filename);
|
||||
#else
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
int r;
|
||||
|
||||
@@ -142,4 +146,5 @@ int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
*ret = TAKE_PTR(dl);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
+43
-13
@@ -1171,6 +1171,9 @@ int lookup_pwent_in_files(
|
||||
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
#if !BUILD_STATIC
|
||||
|
||||
static size_t getpw_buffer_size(void) {
|
||||
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
return bufsize <= 0 ? 4096U : (size_t) bufsize;
|
||||
@@ -1182,15 +1185,25 @@ static bool errno_is_user_doesnt_exist(int error) {
|
||||
return IN_SET(abs(error), ENOENT, ESRCH, EBADF, EPERM);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int getpwnam_malloc(const char *name, struct passwd **ret) {
|
||||
/* For static builds use a very simplistic implementation that looks at 'passwd' in /etc/
|
||||
* and /usr/lib/, and for non-static builds use NSS. The first matching entry wins. The
|
||||
* same logic is implemented in getpwnam_malloc, getpwuid_malloc, getgrnam_malloc, and
|
||||
* getgrgid_malloc. */
|
||||
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_pwent_in_files(PASSWD_FILES, name, UID_INVALID, ret);
|
||||
#else
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
/* A wrapper around getpwnam_r() that allocates the necessary buffer on the heap. The caller must
|
||||
* free() the returned structures! */
|
||||
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
* free() the returned structure! */
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
@@ -1226,15 +1239,19 @@ int getpwnam_malloc(const char *name, struct passwd **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int getpwuid_malloc(uid_t uid, struct passwd **ret) {
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
if (!uid_is_valid(uid))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_pwent_in_files(PASSWD_FILES, /* name= */ NULL, uid, ret);
|
||||
#else
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1267,6 +1284,7 @@ int getpwuid_malloc(uid_t uid, struct passwd **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int copy_struct_group(const struct group *gr, struct group **ret) {
|
||||
@@ -1427,18 +1445,25 @@ ssize_t lookup_groups_in_files(
|
||||
return n_arr;
|
||||
}
|
||||
|
||||
#if !BUILD_STATIC
|
||||
|
||||
static size_t getgr_buffer_size(void) {
|
||||
long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
|
||||
return bufsize <= 0 ? 4096U : (size_t) bufsize;
|
||||
}
|
||||
|
||||
int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
#endif
|
||||
|
||||
int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_grent_in_files(GROUP_FILES, name, GID_INVALID, ret);
|
||||
#else
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1471,15 +1496,19 @@ int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int getgrgid_malloc(gid_t gid, struct group **ret) {
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
if (!gid_is_valid(gid))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_grent_in_files(GROUP_FILES, /* name= */ NULL, gid, ret);
|
||||
#else
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1512,4 +1541,5 @@ int getgrgid_malloc(gid_t gid, struct group **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -159,6 +159,10 @@ static inline bool hashed_password_is_locked_or_invalid(const char *password) {
|
||||
return password && password[0] != '$';
|
||||
}
|
||||
|
||||
/* Places where we will try to load account data from */
|
||||
#define PASSWD_FILES STRV_MAKE("/etc/passwd", "/usr/lib/passwd")
|
||||
#define GROUP_FILES STRV_MAKE("/etc/group", "/usr/lib/group")
|
||||
|
||||
/* A locked *and* invalid password for "struct spwd"'s .sp_pwdp and "struct passwd"'s .pw_passwd field */
|
||||
#define PASSWORD_LOCKED_AND_INVALID "!*"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user