aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt1
-rw-r--r--Makefile.in3
-rwxr-xr-xconfigure11
-rw-r--r--pseudo.19
-rw-r--r--pseudo.h3
-rw-r--r--pseudo_client.c2
-rw-r--r--pseudo_util.c78
7 files changed, 64 insertions, 43 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 81e20a0..4d4e56e 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -2,6 +2,7 @@
* (seebs) notes on some Futures planning.
* (seebs) Typo/formatting issue in man page.
* (seebs) message formatting/clarity cleanup and typo fixes.
+ * (seebs) First draft of passwd_fallback implementation.
2014-01-15:
* (seebs) performance test/test case updates.
diff --git a/Makefile.in b/Makefile.in
index f3f67ea..2d9e069 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -25,6 +25,7 @@ SQLITE=@SQLITE@
SQLITE_LIB=@SQLITE_LIB@
SQLITE_MEMORY=@SQLITE_MEMORY@
FORCE_ASYNC=@FORCE_ASYNC@
+PASSWD_FALLBACK=@PASSWD_FALLBACK@
BITS=@BITS@
ARCH_FLAGS=@ARCH_FLAGS@
MARK64=@MARK64@
@@ -39,7 +40,7 @@ LOCALSTATEDIR=$(PREFIX)/$(LOCALSTATE)
CFLAGS_BASE=-pipe -std=gnu99 -Wall -W -Wextra
CFLAGS_CODE=-fPIC -D_LARGEFILE64_SOURCE -D_ATFILE_SOURCE $(ARCH_FLAGS)
-CFLAGS_DEFS=-DPSEUDO_PREFIX='"$(PREFIX)"' -DPSEUDO_SUFFIX='"$(SUFFIX)"' -DPSEUDO_BINDIR='"$(BIN)"' -DPSEUDO_LIBDIR='"$(LIB)"' -DPSEUDO_LOCALSTATEDIR='"$(LOCALSTATE)"' -DPSEUDO_VERSION='"$(VERSION)"' $(SQLITE_MEMORY) $(FORCE_ASYNC)
+CFLAGS_DEFS=-DPSEUDO_PREFIX='"$(PREFIX)"' -DPSEUDO_SUFFIX='"$(SUFFIX)"' -DPSEUDO_BINDIR='"$(BIN)"' -DPSEUDO_LIBDIR='"$(LIB)"' -DPSEUDO_LOCALSTATEDIR='"$(LOCALSTATE)"' -DPSEUDO_VERSION='"$(VERSION)"' $(SQLITE_MEMORY) $(FORCE_ASYNC) -DPSEUDO_PASSWD_FALLBACK='$(PASSWD_FALLBACK)'
CFLAGS_DEBUG=-O2 -g
CFLAGS_SQL=-L$(SQLITE)/$(SQLITE_LIB) -I$(SQLITE)/include $(RPATH)
CFLAGS_PSEUDO=$(CFLAGS_BASE) $(CFLAGS_CODE) $(CFLAGS_DEFS) \
diff --git a/configure b/configure
index d88a930..80da1d1 100755
--- a/configure
+++ b/configure
@@ -27,6 +27,7 @@ opt_sqlite=/usr
opt_rpath=
opt_memory=
opt_async=
+opt_passwd_fallback='""'
compile_x86_32=-m32
compile_x86_64=-m64
@@ -44,6 +45,7 @@ usage()
echo >&2 " [--enable-static-sqlite]"
echo >&2 " [--with-static-sqlite=...]"
echo >&2 " [--with-rpath=...|--without-rpath]"
+ echo >&2 " [--with-passwd-fallback=...|--without-passwd-fallback]"
echo >&2 " [--cflags='']"
echo >&2 " [--bits=32|64]"
exit 1
@@ -69,6 +71,14 @@ do
sqlite_ldarg=$opt_sqlite_ldarg
use_maybe_rpath=false
;;
+ --without-passwd-fallback)
+ opt_passwd_fallback='NULL'
+ ;;
+ --with-passwd-fallback=*)
+ opt_passwd_fallback="${arg#--with-passwd-fallback=}"
+ # Trim a trailing /, remove quotes. So / => "".
+ opt_passwd_fallback="\"${opt_passwd_fallback%/}\""
+ ;;
--enable-static-sqlite)
sqlite_ldarg='$(SQLITE)/$(SQLITE_LIB)/libsqlite3.a'
use_maybe_rpath=false
@@ -230,6 +240,7 @@ sed -e '
s,@SQLITE_LIB@,'"$opt_sqlite_lib"',g
s,@SQLITE_MEMORY@,'"$SQLITE_MEMORY"',g
s,@FORCE_ASYNC@,'"$FORCE_ASYNC"',g
+ s,@PASSWD_FALLBACK@,'$opt_passwd_fallback',g
s!@RPATH@!'"$opt_rpath"'!g
s,@MARK64@,'"$opt_mark64"',g
s,@ARCH@,'"$opt_arch"',g
diff --git a/pseudo.1 b/pseudo.1
index 9c65fab..6906345 100644
--- a/pseudo.1
+++ b/pseudo.1
@@ -559,7 +559,14 @@ environment, the chroot directory is used by preference. The
parallelism between these cases is why this variable points at
the parent directory of
.I etc
-rather than the directory containing the files.
+rather than the directory containing the files. If there is no
+.I chroot
+environment, and this variable is also unset,
+.I pseudo
+falls back to a directory specified at configure time, with the
+default being the root directory. This is controlled by the
+.B PSEUDO_PASSWD_FALLBACK
+definition.
.TP 8
.B PSEUDO_PREFIX
If set, the variable
diff --git a/pseudo.h b/pseudo.h
index 15df164..1a0b257 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -76,8 +76,7 @@ extern int pseudo_logfile(char *defname);
extern ssize_t pseudo_sys_path_max(void);
extern ssize_t pseudo_path_max(void);
#define PSEUDO_PWD_MAX 4096
-extern int pseudo_etc_file(const char *filename, char *realname, int flags, char **search, int dircount);
-#define PSEUDO_ETC_FILE(name, realname, flags) pseudo_etc_file((name), (realname), (flags), (char *[]) { pseudo_chroot, pseudo_passwd }, 2)
+extern int pseudo_etc_file(const char *filename, char *realname, int flags, char *path[], int dircount);
extern void pseudo_stat32_from64(struct stat *, const struct stat64 *);
extern void pseudo_stat64_from32(struct stat64 *, const struct stat *);
diff --git a/pseudo_client.c b/pseudo_client.c
index 30983ad..2134c8e 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -88,6 +88,8 @@ gid_t pseudo_egid;
gid_t pseudo_sgid;
gid_t pseudo_fgid;
+#define PSEUDO_ETC_FILE(filename, realname, flags) pseudo_etc_file(filename, realname, flags, (char *[]) { pseudo_chroot, pseudo_passwd, PSEUDO_PASSWD_FALLBACK }, PSEUDO_PASSWD_FALLBACK ? 3 : 2)
+
/* helper function to make a directory, just like mkdir -p.
* Can't use system() because the child shell would end up trying
* to do the same thing...
diff --git a/pseudo_util.c b/pseudo_util.c
index 0d80008..277b058 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -1245,53 +1245,53 @@ FILE *pseudo_host_etc_group_file = &pseudo_fake_group_file;
#endif
int
-pseudo_etc_file(const char *file, char *realname, int flags, char **search_dirs, int dircount) {
+pseudo_etc_file(const char *file, char *realname, int flags, char *search_dirs[], int dircount) {
char filename[pseudo_path_max()];
- int rc;
+ int rc = -1;
if (!file) {
- pseudo_diag("pseudo_etc_file: needs argument, usually passwd/group\n");
- return 0;
+ pseudo_debug(PDBGF_CHROOT, "pseudo_etc_file: needs argument, usually passwd/group\n");
+ errno = ENOENT;
+ return -1;
}
- if (search_dirs) {
- char *s;
- int i;
- for (i = 0; i < dircount; ++i) {
- s = search_dirs[i];
- if (!s)
- continue;
- snprintf(filename, pseudo_path_max(), "%s/etc/%s",
- s, file);
- rc = open(filename, flags, 0600);
- if (rc >= 0) {
- if (realname)
- strcpy(realname, filename);
- pseudo_debug(PDBGF_CHROOT, "using <%s> for <%s>\n",
- filename, file);
- return rc;
- } else {
- pseudo_debug(PDBGF_CHROOT, "didn't find <%s>\n",
- filename);
- }
- }
- } else {
+ int i;
+ if (!search_dirs || dircount == 0) {
pseudo_debug(PDBGF_CHROOT, "pseudo_etc_file: no search dirs.\n");
+ errno = ENOENT;
+ return -1;
}
+ for (i = 0; i < dircount; ++i) {
+ char *s = search_dirs[i];
+ if (!s)
+ continue;
#if PSEUDO_PORT_DARWIN
- if (!strcmp("passwd", file)) {
- pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic passwd fd\n");
- return pseudo_host_etc_passwd_fd;
- } else if (!strcmp("group", file)) {
- pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic group fd\n");
- return pseudo_host_etc_group_fd;
- }
+ /* special magic: empty string implies our emulation
+ * of the passwd/group files.
+ */
+ if (!*s) {
+ if (!strcmp("passwd", file)) {
+ pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic passwd fd\n");
+ return pseudo_host_etc_passwd_fd;
+ } else if (!strcmp("group", file)) {
+ pseudo_debug(PDBGF_CHROOT, "Darwin hackery: pseudo_etc_passwd returning magic group fd\n");
+ return pseudo_host_etc_group_fd;
+ }
+ }
#endif
- snprintf(filename, pseudo_path_max(), "/etc/%s", file);
- pseudo_debug(PDBGF_CHROOT, "falling back on <%s> for <%s>\n",
- filename, file);
- rc = open(filename, flags, 0600);
- if (rc >= 0 && realname)
- strcpy(realname, filename);
+ snprintf(filename, pseudo_path_max(), "%s/etc/%s",
+ s, file);
+ rc = open(filename, flags, 0600);
+ if (rc >= 0) {
+ if (realname)
+ strcpy(realname, filename);
+ pseudo_debug(PDBGF_CHROOT, "pseudo_etc_file: using '%s' for '%s'.\n",
+ filename, file);
+ return rc;
+ } else {
+ pseudo_debug(PDBGF_CHROOT | PDBGF_VERBOSE, "didn't find <%s>\n",
+ filename);
+ }
+ }
return rc;
}