Browse Source

Add --disable-nss flag to build without functions like getpwnam(). These functions in glibc need dlopen() and can't be linked statically

Serj Kalichev 3 months ago
parent
commit
2731481c14
4 changed files with 130 additions and 4 deletions
  1. 5 1
      Makefile.am
  2. 1 1
      clish/module.am
  3. 10 0
      configure.ac
  4. 114 2
      lub/db/db.c

+ 5 - 1
Makefile.am

@@ -14,7 +14,11 @@ if LEGACY
   LEGACY_CFLAGS = -DLEGACY
 endif
 
-AM_CFLAGS = -Wall $(DEBUG_CFLAGS) $(LEGACY_CFLAGS)
+if DISABLE_NSS
+  NSS_CFLAGS = -DDISABLE_NSS
+endif
+
+AM_CFLAGS = -Wall $(DEBUG_CFLAGS) $(LEGACY_CFLAGS) $(NSS_CFLAGS)
 #AM_CFLAGS = -ansi -pedantic -Werror -Wall -D_POSIX_C_SOURCE=199309 -DVERSION=$(VERSION) $(DEBUG_CFLAGS)
 
 bin_PROGRAMS =

+ 1 - 1
clish/module.am

@@ -6,7 +6,7 @@ libclish_la_SOURCES = \
 	clish/private.h
 
 libclish_la_LDFLAGS = $(AM_LDFLAGS) $(VERSION_INFO) @XML_LDFLAGS@
-libclish_la_CFLAGS = @XML_CFLAGS@ $(DEBUG_CFLAGS) $(LEGACY_CFLAGS)
+libclish_la_CFLAGS = @XML_CFLAGS@ $(DEBUG_CFLAGS) $(LEGACY_CFLAGS) $(NSS_CFLAGS)
 libclish_la_DEPENDENCIES = \
 	liblub.la \
 	libtinyrl.la \

+ 10 - 0
configure.ac

@@ -87,6 +87,16 @@ AC_ARG_ENABLE(legacy,
               [enable_legacy=no])
 AM_CONDITIONAL(LEGACY,test x$enable_legacy = xyes)
 
+################################
+# Deal with NSS glibc engine
+################################
+AC_ARG_ENABLE(nss,
+              [AS_HELP_STRING([--enable-nss],
+                              [Support for glibc NSS-dependent functions line getpwnam() [default=yes]])],
+              [],
+              [enable_nss=yes])
+AM_CONDITIONAL(DISABLE_NSS,test x$enable_nss != xyes)
+
 ################################
 # Check for Lua support
 ################################

+ 114 - 2
lub/db/db.c

@@ -2,14 +2,25 @@
 #include "lub/db.h"
 
 #include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
 #include <unistd.h>
+#include <assert.h>
+#include <string.h>
+
+#include <lub/conv.h>
 
 #define DEFAULT_GETPW_R_SIZE_MAX 1024
 
+// Workaround to implement fully statical build. The libc uses dlopen() to
+// implement NSS functions. So getpwnam() etc. need shared objects support.
+// Exclude them on static build. Application will support UIDs and GIDs in
+// digital format only.
+#ifndef DISABLE_NSS
+
 struct passwd *lub_db_getpwnam(const char *name)
 {
 	long int size;
@@ -47,7 +58,7 @@ struct passwd *lub_db_getpwuid(uid_t uid)
 {
 	long int size;
 	char *buf;
-	struct passwd *pwbuf; 
+	struct passwd *pwbuf;
 	struct passwd *pw = NULL;
 	int res = 0;
 
@@ -80,7 +91,7 @@ struct group *lub_db_getgrnam(const char *name)
 {
 	long int size;
 	char *buf;
-	struct group *grbuf; 
+	struct group *grbuf;
 	struct group *gr = NULL;
 	int res = 0;
 
@@ -141,3 +152,104 @@ struct group *lub_db_getgrgid(gid_t gid)
 
 	return grbuf;
 }
+
+// -----------------------------------------------------------------------------
+#else // DISABLE_NSS
+
+// All UIDs and GIDs must be in digital format. Functions only converts digits
+// to text or text to digits. Text names are not supported. So functions
+// simulate the real functions.
+
+struct passwd *lub_db_getpwnam(const char *name)
+{
+	long int size = 0;
+	struct passwd *buf = NULL;
+	long int val = 0;
+
+	assert(name);
+	if (!name)
+		return NULL;
+	size = strlen(name) + 1;
+
+	// Try to convert
+	if (lub_conv_atol(name, &val, 0) < 0)
+		return NULL;
+
+	buf = calloc(1, sizeof(*buf) + size);
+	if (!buf)
+		return NULL;
+	buf->pw_name = (char *)buf + sizeof(*buf);
+	memcpy(buf->pw_name, name, size);
+	buf->pw_uid = (uid_t)val;
+	buf->pw_gid = (gid_t)val; // Let's primary GID be the same as UID
+
+	return buf;
+}
+
+struct passwd *lub_db_getpwuid(uid_t uid)
+{
+	char str[20];
+	long int size = 0;
+	struct passwd *buf = NULL;
+
+	snprintf(str, sizeof(str), "%u", uid);
+	str[sizeof(str) - 1] = '\0';
+	size = strlen(str) + 1;
+
+	buf = calloc(1, sizeof(*buf) + size);
+	if (!buf)
+		return NULL;
+	buf->pw_name = (char *)buf + sizeof(*buf);
+	memcpy(buf->pw_name, str, size);
+	buf->pw_uid = uid;
+	buf->pw_gid = uid; // Let's primary GID be the same as UID
+
+	return buf;
+}
+
+struct group *lub_db_getgrnam(const char *name)
+{
+	long int size = 0;
+	struct group *buf = NULL;
+	long int val = 0;
+
+	assert(name);
+	if (!name)
+		return NULL;
+	size = strlen(name) + 1;
+
+	// Try to convert
+	if (lub_conv_atol(name, &val, 0) < 0)
+		return NULL;
+
+	buf = calloc(1, sizeof(*buf) + size);
+	if (!buf)
+		return NULL;
+	buf->gr_name = (char *)buf + sizeof(*buf);
+	memcpy(buf->gr_name, name, size);
+	buf->gr_gid = (gid_t)val;
+
+	return buf;
+}
+
+struct group *lub_db_getgrgid(gid_t gid)
+{
+	char str[20];
+	long int size = 0;
+	struct group *buf = NULL;
+
+	snprintf(str, sizeof(str), "%u", gid);
+	str[sizeof(str) - 1] = '\0';
+	size = strlen(str) + 1;
+
+	buf = calloc(1, sizeof(*buf) + size);
+	if (!buf)
+		return NULL;
+	buf->gr_name = (char *)buf + sizeof(*buf);
+	memcpy(buf->gr_name, str, size);
+	buf->gr_gid = gid;
+
+	return buf;
+}
+
+#endif // DISABLE_NSS