aboutsummaryrefslogtreecommitdiffstats
path: root/pseudo_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'pseudo_client.c')
-rw-r--r--pseudo_client.c68
1 files changed, 66 insertions, 2 deletions
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 {