Allow ~ and ~user to expand for chdir and chroot.

This commit is contained in:
Roy Marples 2008-10-30 17:40:48 +00:00
parent e1341e372b
commit 20380d3144

View File

@ -96,10 +96,10 @@ typedef struct scheduleitem
TAILQ_ENTRY(scheduleitem) entries; TAILQ_ENTRY(scheduleitem) entries;
} SCHEDULEITEM; } SCHEDULEITEM;
TAILQ_HEAD(, scheduleitem) schedule; TAILQ_HEAD(, scheduleitem) schedule;
static char **nav = NULL; static char **nav;
extern const char *applet; extern const char *applet;
static char *changeuser = NULL; static char *changeuser, *ch_root, *ch_dir;
extern char **environ; extern char **environ;
@ -498,6 +498,45 @@ static void handle_signal(int sig)
errno = serrno; errno = serrno;
} }
static char *
expand_home(const char *home, const char *path)
{
char *pat, *p, *nh;
size_t len;
struct passwd *pw;
if (!path || *path != '~')
return xstrdup(path);
pat = xstrdup(path);
if (pat[1] != '/' && pat[1] != '\0') {
p = strchr(pat + 1, '/');
if (p)
*p = '\0';
pw = getpwnam(pat + 1);
if (pw) {
home = pw->pw_dir;
pat = p;
if (pat)
*pat = '/';
} else
home = NULL;
} else
pat++;
if (!home) {
free(pat);
return xstrdup(path);
}
if (!pat)
return xstrdup(home);
len = strlen(pat) + strlen(home) + 1;
nh = xmalloc(len);
snprintf(nh, len, "%s%s", home, pat);
free(pat);
return nh;
}
#include "_usage.h" #include "_usage.h"
#define getoptstring "KN:R:Sbc:d:e:g:k:mn:op:s:tu:r:x:1:2:" getoptstring_COMMON #define getoptstring "KN:R:Sbc:d:e:g:k:mn:op:s:tu:r:x:1:2:" getoptstring_COMMON
@ -582,8 +621,7 @@ int start_stop_daemon(int argc, char **argv)
bool makepidfile = false; bool makepidfile = false;
uid_t uid = 0; uid_t uid = 0;
gid_t gid = 0; gid_t gid = 0;
char *ch_root = NULL; char *home = NULL;
char *ch_dir = NULL;
int tid = 0; int tid = 0;
char *redirect_stderr = NULL; char *redirect_stderr = NULL;
char *redirect_stdout = NULL; char *redirect_stdout = NULL;
@ -624,6 +662,14 @@ int start_stop_daemon(int argc, char **argv)
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)", eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
applet, tmp); applet, tmp);
/* Get our initial dir */
home = getenv("HOME");
if (!home) {
pw = getpwuid(getuid());
if (pw)
home = pw->pw_dir;
}
while ((opt = getopt_long(argc, argv, getoptstring, longopts, while ((opt = getopt_long(argc, argv, getoptstring, longopts,
(int *) 0)) != -1) (int *) 0)) != -1)
switch (opt) { switch (opt) {
@ -633,7 +679,8 @@ int start_stop_daemon(int argc, char **argv)
case 'N': /* --nice */ case 'N': /* --nice */
if (sscanf(optarg, "%d", &nicelevel) != 1) if (sscanf(optarg, "%d", &nicelevel) != 1)
eerrorx("%s: invalid nice level `%s'", applet, optarg); eerrorx("%s: invalid nice level `%s'",
applet, optarg);
break; break;
case 'R': /* --retry <schedule>|<timeout> */ case 'R': /* --retry <schedule>|<timeout> */
@ -659,10 +706,12 @@ int start_stop_daemon(int argc, char **argv)
else else
pw = getpwuid((uid_t) tid); pw = getpwuid((uid_t) tid);
if (! pw) if (!pw)
eerrorx("%s: user `%s' not found", applet, tmp); eerrorx("%s: user `%s' not found",
applet, tmp);
uid = pw->pw_uid; uid = pw->pw_uid;
if (! gid) home = pw->pw_dir;
if (!gid)
gid = pw->pw_gid; gid = pw->pw_gid;
if (p) { if (p) {
@ -672,8 +721,9 @@ int start_stop_daemon(int argc, char **argv)
else else
gr = getgrgid((gid_t) tid); gr = getgrgid((gid_t) tid);
if (! gr) if (!gr)
eerrorx("%s: group `%s' not found", eerrorx("%s: group `%s'"
" not found",
applet, tmp); applet, tmp);
gid = gr->gr_gid; gid = gr->gr_gid;
} }
@ -686,9 +736,10 @@ int start_stop_daemon(int argc, char **argv)
case 'e': /* --env */ case 'e': /* --env */
if (putenv(optarg) == 0) { if (putenv(optarg) == 0) {
if (strncmp("HOME=", optarg, 5) == 0) if (strncmp("HOME=", optarg, 5) == 0) {
sethome = true; sethome = true;
else if (strncmp("USER=", optarg, 5) == 0) home = strchr(optarg, '=') + 1;
} else if (strncmp("USER=", optarg, 5) == 0)
setuser = true; setuser = true;
} }
break; break;
@ -700,8 +751,9 @@ int start_stop_daemon(int argc, char **argv)
else else
gr = getgrgid((gid_t) tid); gr = getgrgid((gid_t) tid);
if (! gr) if (!gr)
eerrorx("%s: group `%s' not found", applet, optarg); eerrorx("%s: group `%s' not found",
applet, optarg);
gid = gr->gr_gid; gid = gr->gr_gid;
} }
break; break;
@ -835,6 +887,12 @@ int start_stop_daemon(int argc, char **argv)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
/* Expand ~ */
if (ch_dir && *ch_dir == '~')
ch_dir = expand_home(home, ch_dir);
if (ch_root && *ch_root == '~')
ch_root = expand_home(home, ch_root);
/* Validate that the binary exists if we are starting */ /* Validate that the binary exists if we are starting */
if (*exec == '/' || *exec == '.') { if (*exec == '/' || *exec == '.') {
/* Full or relative path */ /* Full or relative path */