diff options
-rw-r--r-- | ChangeLog.txt | 1 | ||||
-rw-r--r-- | Makefile.in | 3 | ||||
-rwxr-xr-x | configure | 11 | ||||
-rw-r--r-- | pseudo.1 | 9 | ||||
-rw-r--r-- | pseudo.h | 3 | ||||
-rw-r--r-- | pseudo_client.c | 2 | ||||
-rw-r--r-- | pseudo_util.c | 78 |
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) \ @@ -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 @@ -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 @@ -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; } |