Add ability to execute command without help of /bin/su

It is important, if the program closes stdout, but does not exit.
Then, qrexec_agent does not see EOF (because su still holds the
file descriptor).
This commit is contained in:
Rafal Wojtczuk 2011-03-10 13:08:06 +01:00
parent a7cc09071f
commit 8f90623661

View File

@ -28,6 +28,8 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <pwd.h>
#include <grp.h>
#include "qrexec.h" #include "qrexec.h"
#include "buffer.h" #include "buffer.h"
#include "glue.h" #include "glue.h"
@ -66,18 +68,46 @@ void init()
peer_server_init(REXEC_PORT); peer_server_init(REXEC_PORT);
} }
void do_exec(char *cmd) void no_colon_in_cmd()
{ {
char *sep = index(cmd, ':');
if (!sep) {
fprintf(stderr, fprintf(stderr,
"cmdline is supposed to be in user:command form\n"); "cmdline is supposed to be in user:command form\n");
exit(1); exit(1);
}
void do_exec_directly(char *cmd)
{
struct passwd *pwd;
char *sep = index(cmd, ':');
if (!sep)
no_colon_in_cmd();
*sep = 0;
pwd = getpwnam(cmd);
if (!pwd) {
perror("getpwnam");
exit(1);
} }
setgid(pwd->pw_gid);
initgroups(cmd, pwd->pw_gid);
setuid(pwd->pw_uid);
setenv("HOME", pwd->pw_dir, 1);
setenv("USER", cmd, 1);
execl(sep + 1, sep + 1, NULL);
perror("execl");
exit(1);
}
void do_exec(char *cmd)
{
char *sep = index(cmd, ':');
if (!sep)
no_colon_in_cmd();
*sep = 0; *sep = 0;
signal(SIGCHLD, SIG_DFL); signal(SIGCHLD, SIG_DFL);
signal(SIGPIPE, SIG_DFL); signal(SIGPIPE, SIG_DFL);
if (!strcmp(cmd, "directly"))
do_exec_directly(sep + 1);
execl("/bin/su", "su", "-", cmd, "-c", sep + 1, NULL); execl("/bin/su", "su", "-", cmd, "-c", sep + 1, NULL);
perror("execl"); perror("execl");
exit(1); exit(1);
@ -89,7 +119,7 @@ void handle_just_exec(int clid, int len)
int fdn, pid; int fdn, pid;
read_all_vchan_ext(buf, len); read_all_vchan_ext(buf, len);
switch (pid=fork()) { switch (pid = fork()) {
case -1: case -1:
perror("fork"); perror("fork");
exit(1); exit(1);