Allow ~ and ~user to expand for chdir and chroot.
This commit is contained in:
parent
e1341e372b
commit
20380d3144
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user