aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt9
-rwxr-xr-xconfigure6
-rw-r--r--pseudo.h2
-rw-r--r--pseudo_client.c68
-rw-r--r--pseudo_util.c4
5 files changed, 83 insertions, 6 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index ba44239..940e781 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,12 @@
+2015-01-14:
+ * (seebs) Merge pabigot's fix for a missing antimagic() in
+ etc_file code.
+ * (seebs) Make configure reject a "prefix" of the current
+ directory. It fails in strange ways and is easy to detect.
+ * (seebs) handle colon-separated lists in PSEUDO_PASSWD.
+ Derived in part from contribution from pabigot.
+ * (seebs) change allocation order in password file locking.
+
2015-01-05:
* (seebs) First try at handling trailing slashes in path names
correctly. (Which is to say, a trailing slash on a file name
diff --git a/configure b/configure
index 345c44b..11bbee1 100755
--- a/configure
+++ b/configure
@@ -2,7 +2,7 @@
#
# configure, simulation of autoconf script, much simplified
#
-# Copyright (c) 2008-2013 Wind River Systems, Inc.
+# Copyright (c) 2008-2014 Wind River Systems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the Lesser GNU General Public License version 2.1 as
@@ -69,6 +69,10 @@ do
--) shift; break ;;
--prefix=*)
opt_prefix=${arg#--prefix=}
+ if [ "$(cd "$opt_prefix"; pwd)" == "$(pwd)" ]; then
+ echo >&2 "ERROR: Prefix is current directory. That doesn't work."
+ exit 1
+ fi
;;
--libdir=*)
opt_libdir=${arg#--libdir=}
diff --git a/pseudo.h b/pseudo.h
index 92020e4..05813c1 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -86,7 +86,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 *path[], int dircount);
+extern int pseudo_etc_file(const char *filename, char *realname, int flags, const char **search_dirs, 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 8deaa1b..e4be07e 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -75,6 +75,8 @@ int pseudo_umask = 022;
static char **fd_paths = NULL;
static int nfds = 0;
+static const char **passwd_paths = NULL;
+static int npasswd_paths = 0;
static int messages = 0;
static struct timeval message_time = { .tv_sec = 0 };
static int pseudo_inited = 0;
@@ -93,7 +95,7 @@ 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)
+#define PSEUDO_ETC_FILE(filename, realname, flags) pseudo_etc_file(filename, realname, flags, passwd_paths, npasswd_paths)
/* helper function to make a directory, just like mkdir -p.
* Can't use system() because the child shell would end up trying
@@ -117,6 +119,61 @@ mkdir_p(char *path) {
(void) mkdir(path, 0755);
}
+static int
+build_passwd_paths(void)
+{
+ int np = 0;
+
+ /* determine how many we need */
+ if (pseudo_chroot) {
+ ++np;
+ }
+ if (pseudo_passwd) {
+ ++np;
+ for (int i = 0; pseudo_passwd[i]; ++i)
+ if (pseudo_passwd[i] == ':')
+ ++np;
+ }
+ if (PSEUDO_PASSWD_FALLBACK) {
+ ++np;
+ }
+
+ npasswd_paths = np;
+ passwd_paths = malloc((np + 1) * sizeof(*passwd_paths));
+ if (!passwd_paths) {
+ pseudo_diag("couldn't allocate storage for password paths.\n");
+ exit(1);
+ }
+ np = 0;
+#define SHOW_PATH pseudo_debug(PDBGF_CHROOT | PDBGF_VERBOSE, "passwd_paths[%d]: '%s'\n", (np - 1), (passwd_paths[np - 1]))
+ if (pseudo_chroot) {
+ passwd_paths[np++] = pseudo_chroot;
+ SHOW_PATH;
+ }
+ if (pseudo_passwd) {
+ passwd_paths[np++] = pseudo_passwd;
+ SHOW_PATH;
+ for (int i = 0; pseudo_passwd[i]; ++i) {
+ if (pseudo_passwd[i] == ':') {
+ pseudo_passwd[i] = '\0';
+ passwd_paths[np++] = pseudo_passwd + i + 1;
+ SHOW_PATH;
+ }
+ }
+ }
+ if (PSEUDO_PASSWD_FALLBACK) {
+ passwd_paths[np++] = PSEUDO_PASSWD_FALLBACK;
+ SHOW_PATH;
+ }
+ passwd_paths[np] = NULL;
+ if (np != npasswd_paths) {
+ pseudo_diag("uh-oh, expected %d path(s) for passwd files, found %d.\n",
+ npasswd_paths, np);
+ }
+
+ return np;
+}
+
void
pseudo_init_client(void) {
char *env;
@@ -325,9 +382,12 @@ pseudo_init_client(void) {
env = pseudo_get_value("PSEUDO_PASSWD");
if (env) {
+ /* note: this means that pseudo_passwd is a
+ * string we're allowed to modify... */
pseudo_passwd = strdup(env);
}
free(env);
+ build_passwd_paths();
pseudo_inited = 1;
}
@@ -408,6 +468,7 @@ pseudo_file_open(char *name, int *fd, FILE **fp) {
*/
int
pseudo_pwd_lck_open(void) {
+ pseudo_pwd_lck_close();
if (!pseudo_pwd_lck_name) {
pseudo_pwd_lck_name = malloc(pseudo_path_max());
if (!pseudo_pwd_lck_name) {
@@ -415,21 +476,24 @@ pseudo_pwd_lck_open(void) {
return -1;
}
}
- pseudo_pwd_lck_close();
+ pseudo_antimagic();
pseudo_pwd_lck_fd = PSEUDO_ETC_FILE(".pwd.lock",
pseudo_pwd_lck_name, O_RDWR | O_CREAT);
+ pseudo_magic();
return pseudo_pwd_lck_fd;
}
int
pseudo_pwd_lck_close(void) {
if (pseudo_pwd_lck_fd != -1) {
+ pseudo_antimagic();
close(pseudo_pwd_lck_fd);
if (pseudo_pwd_lck_name) {
unlink(pseudo_pwd_lck_name);
free(pseudo_pwd_lck_name);
pseudo_pwd_lck_name = 0;
}
+ pseudo_magic();
pseudo_pwd_lck_fd = -1;
return 0;
} else {
diff --git a/pseudo_util.c b/pseudo_util.c
index 9ff2587..d15373b 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -1269,7 +1269,7 @@ 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, const char **search_dirs, int dircount) {
char filename[pseudo_path_max()];
int rc = -1;
@@ -1285,7 +1285,7 @@ pseudo_etc_file(const char *file, char *realname, int flags, char *search_dirs[]
return -1;
}
for (i = 0; i < dircount; ++i) {
- char *s = search_dirs[i];
+ const char *s = search_dirs[i];
if (!s)
continue;
#if PSEUDO_PORT_DARWIN