version 1.31, 2016/03/23 06:16:35 |
version 1.32, 2016/10/20 05:48:50 |
|
|
return o; |
return o; |
} |
} |
|
|
|
static int |
|
start_helper(int background) |
|
{ |
|
struct passwd *pw; |
|
int s[2]; |
|
pid_t pid; |
|
|
|
if (geteuid() == 0) { |
|
if ((pw = getpwnam(SNDIO_PRIV_USER)) == NULL) |
|
errx(1, "unknown user %s", SNDIO_PRIV_USER); |
|
} else |
|
pw = NULL; |
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) < 0) { |
|
perror("socketpair"); |
|
return 0; |
|
} |
|
pid = fork(); |
|
if (pid == -1) { |
|
log_puts("can't fork\n"); |
|
return 0; |
|
} |
|
if (pid == 0) { |
|
setproctitle("helper"); |
|
close(s[0]); |
|
if (fdpass_new(s[1], &helper_fileops) == NULL) |
|
return 0; |
|
if (background) { |
|
log_flush(); |
|
log_level = 0; |
|
if (daemon(0, 0) < 0) |
|
err(1, "daemon"); |
|
} |
|
if (pw != NULL) { |
|
if (setgroups(1, &pw->pw_gid) || |
|
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || |
|
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) |
|
err(1, "cannot drop privileges"); |
|
} |
|
if (pledge("stdio sendfd rpath wpath", NULL) < 0) |
|
err(1, "pledge"); |
|
while (file_poll()) |
|
; /* nothing */ |
|
exit(0); |
|
} else { |
|
close(s[1]); |
|
if (fdpass_new(s[0], &worker_fileops) == NULL) |
|
return 0; |
|
} |
|
return 1; |
|
} |
|
|
|
static void |
|
stop_helper(void) |
|
{ |
|
if (fdpass_peer) |
|
fdpass_close(fdpass_peer); |
|
} |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
|
|
char *host; |
char *host; |
struct tcpaddr *next; |
struct tcpaddr *next; |
} *tcpaddr_list, *ta; |
} *tcpaddr_list, *ta; |
int s[2]; |
|
pid_t pid; |
|
uid_t euid, hpw_uid, wpw_uid; |
|
gid_t hpw_gid, wpw_gid; |
|
char *wpw_dir; |
|
|
|
atexit(log_flush); |
atexit(log_flush); |
|
|
|
|
setsig(); |
setsig(); |
filelist_init(); |
filelist_init(); |
|
|
euid = geteuid(); |
if (!start_helper(background)) |
if (euid == 0) { |
return 1; |
if ((pw = getpwnam(SNDIO_PRIV_USER)) == NULL) |
|
errx(1, "unknown user %s", SNDIO_PRIV_USER); |
if (geteuid() == 0) { |
hpw_uid = pw->pw_uid; |
|
hpw_gid = pw->pw_gid; |
|
if ((pw = getpwnam(SNDIO_USER)) == NULL) |
if ((pw = getpwnam(SNDIO_USER)) == NULL) |
errx(1, "unknown user %s", SNDIO_USER); |
errx(1, "unknown user %s", SNDIO_USER); |
wpw_uid = pw->pw_uid; |
} else |
wpw_gid = pw->pw_gid; |
pw = NULL; |
wpw_dir = xstrdup(pw->pw_dir); |
getbasepath(base); |
} else { |
snprintf(path, SOCKPATH_MAX, "%s/" SOCKPATH_FILE "%u", base, unit); |
hpw_uid = wpw_uid = hpw_gid = wpw_gid = 0xdeadbeef; |
if (!listen_new_un(path)) |
wpw_dir = NULL; |
|
} |
|
|
|
/* start subprocesses */ |
|
|
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) < 0) { |
|
perror("socketpair"); |
|
return 1; |
return 1; |
|
for (ta = tcpaddr_list; ta != NULL; ta = ta->next) { |
|
if (!listen_new_tcp(ta->host, AUCAT_PORT + unit)) |
|
return 1; |
} |
} |
pid = fork(); |
for (l = listen_list; l != NULL; l = l->next) { |
if (pid == -1) { |
if (!listen_init(l)) |
log_puts("can't fork\n"); |
return 1; |
return 1; |
|
} |
} |
if (pid == 0) { |
midi_init(); |
setproctitle("helper"); |
for (p = port_list; p != NULL; p = p->next) { |
close(s[0]); |
if (!port_init(p)) |
if (fdpass_new(s[1], &helper_fileops) == NULL) |
|
return 1; |
return 1; |
if (background) { |
} |
log_flush(); |
for (d = dev_list; d != NULL; d = d->next) { |
log_level = 0; |
if (!dev_init(d)) |
if (daemon(0, 0) < 0) |
return 1; |
err(1, "daemon"); |
} |
} |
if (background) { |
if (euid == 0) { |
log_flush(); |
if (setgroups(1, &hpw_gid) || |
log_level = 0; |
setresgid(hpw_gid, hpw_gid, hpw_gid) || |
if (daemon(0, 0) < 0) |
setresuid(hpw_uid, hpw_uid, hpw_uid)) |
err(1, "daemon"); |
err(1, "cannot drop privileges"); |
} |
} |
if (pw != NULL) { |
if (pledge("stdio sendfd rpath wpath", NULL) < 0) |
if (setpriority(PRIO_PROCESS, 0, SNDIO_PRIO) < 0) |
|
err(1, "setpriority"); |
|
if (chroot(pw->pw_dir) != 0 || chdir("/") != 0) |
|
err(1, "cannot chroot to %s", pw->pw_dir); |
|
if (setgroups(1, &pw->pw_gid) || |
|
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || |
|
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) |
|
err(1, "cannot drop privileges"); |
|
} |
|
if (tcpaddr_list) { |
|
if (pledge("stdio audio recvfd unix inet", NULL) == -1) |
err(1, "pledge"); |
err(1, "pledge"); |
while (file_poll()) |
|
; /* nothing */ |
|
} else { |
} else { |
close(s[1]); |
if (pledge("stdio audio recvfd unix", NULL) == -1) |
if (fdpass_new(s[0], &worker_fileops) == NULL) |
err(1, "pledge"); |
return 1; |
|
|
|
getbasepath(base); |
|
snprintf(path, |
|
SOCKPATH_MAX, "%s/" SOCKPATH_FILE "%u", |
|
base, unit); |
|
if (!listen_new_un(path)) |
|
return 1; |
|
for (ta = tcpaddr_list; ta != NULL; ta = ta->next) { |
|
if (!listen_new_tcp(ta->host, AUCAT_PORT + unit)) |
|
return 1; |
|
} |
|
for (l = listen_list; l != NULL; l = l->next) { |
|
if (!listen_init(l)) |
|
return 1; |
|
} |
|
|
|
midi_init(); |
|
for (p = port_list; p != NULL; p = p->next) { |
|
if (!port_init(p)) |
|
return 1; |
|
} |
|
for (d = dev_list; d != NULL; d = d->next) { |
|
if (!dev_init(d)) |
|
return 1; |
|
} |
|
if (background) { |
|
log_flush(); |
|
log_level = 0; |
|
if (daemon(0, 0) < 0) |
|
err(1, "daemon"); |
|
} |
|
if (euid == 0) { |
|
if (setpriority(PRIO_PROCESS, 0, SNDIO_PRIO) < 0) |
|
err(1, "setpriority"); |
|
if (chroot(wpw_dir) != 0 || chdir("/") != 0) |
|
err(1, "cannot chroot to %s", wpw_dir); |
|
if (setgroups(1, &wpw_gid) || |
|
setresgid(wpw_gid, wpw_gid, wpw_gid) || |
|
setresuid(wpw_uid, wpw_uid, wpw_uid)) |
|
err(1, "cannot drop privileges"); |
|
} |
|
if (tcpaddr_list) { |
|
if (pledge("stdio audio recvfd unix inet", NULL) == -1) |
|
err(1, "pledge"); |
|
} else { |
|
if (pledge("stdio audio recvfd unix", NULL) == -1) |
|
err(1, "pledge"); |
|
} |
|
for (;;) { |
|
if (quit_flag) |
|
break; |
|
if (!fdpass_peer) |
|
break; |
|
if (!file_poll()) |
|
break; |
|
} |
|
if (fdpass_peer) |
|
fdpass_close(fdpass_peer); |
|
while (listen_list != NULL) |
|
listen_close(listen_list); |
|
while (sock_list != NULL) |
|
sock_close(sock_list); |
|
for (d = dev_list; d != NULL; d = d->next) |
|
dev_done(d); |
|
for (p = port_list; p != NULL; p = p->next) |
|
port_done(p); |
|
while (file_poll()) |
|
; /* nothing */ |
|
midi_done(); |
|
} |
} |
|
for (;;) { |
|
if (quit_flag) |
|
break; |
|
if (!fdpass_peer) |
|
break; |
|
if (!file_poll()) |
|
break; |
|
} |
|
stop_helper(); |
|
while (listen_list != NULL) |
|
listen_close(listen_list); |
|
while (sock_list != NULL) |
|
sock_close(sock_list); |
|
for (d = dev_list; d != NULL; d = d->next) |
|
dev_done(d); |
|
for (p = port_list; p != NULL; p = p->next) |
|
port_done(p); |
|
while (file_poll()) |
|
; /* nothing */ |
|
midi_done(); |
|
|
while (opt_list != NULL) |
while (opt_list != NULL) |
opt_del(opt_list); |
opt_del(opt_list); |
while (dev_list) |
while (dev_list) |