74
74
#include <unistd.h> /* close(), SEEK_SET, off_t, write(),
75
75
getuid(), getgid(), seteuid(),
76
setgid(), pause(), _exit() */
77
77
#include <arpa/inet.h> /* inet_pton(), htons, inet_ntop() */
78
78
#include <iso646.h> /* not, or, and */
79
79
#include <argp.h> /* struct argp_option, error_t, struct
87
87
EX_NOHOST, EX_IOERR, EX_PROTOCOL */
88
88
#include <sys/wait.h> /* waitpid(), WIFEXITED(),
89
89
WEXITSTATUS(), WTERMSIG() */
90
#include <grp.h> /* setgroups() */
92
93
#include <sys/klog.h> /* klogctl() */
203
205
/* Add server to set of servers to retry periodically */
204
int add_server(const char *ip, uint16_t port, AvahiIfIndex if_index,
206
bool add_server(const char *ip, uint16_t port, AvahiIfIndex if_index,
207
209
server *new_server = malloc(sizeof(server));
208
210
if(new_server == NULL){
209
211
perror_plus("malloc");
212
214
*new_server = (server){ .ip = strdup(ip),
1030
1032
avahi_simple_poll_quit(mc.simple_poll);
1032
ret = add_server(ip, port, interface,
1033
avahi_proto_to_af(proto));
1034
if(not add_server(ip, port, interface,
1035
avahi_proto_to_af(proto))){
1036
fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1406
1411
pid_t hook_pid = fork();
1407
1412
if(hook_pid == 0){
1414
/* Raise privileges */
1418
perror_plus("seteuid");
1420
/* Raise privileges even more */
1424
perror_plus("setuid");
1430
perror_plus("setgid");
1432
/* Reset supplementary groups */
1434
ret = setgroups(0, NULL);
1436
perror_plus("setgroups");
1409
1438
dup2(devnull, STDIN_FILENO);
1410
1439
close(devnull);
1411
1440
dup2(STDERR_FILENO, STDOUT_FILENO);
1412
1441
ret = setenv("MANDOSNETHOOKDIR", hookdir, 1);
1414
1443
perror_plus("setenv");
1417
1446
ret = setenv("DEVICE", interface, 1);
1419
1448
perror_plus("setenv");
1422
1451
ret = setenv("VERBOSE", debug ? "1" : "0", 1);
1424
1453
perror_plus("setenv");
1427
1456
ret = setenv("MODE", mode, 1);
1429
1458
perror_plus("setenv");
1432
1461
char *delaystring;
1433
1462
ret = asprintf(&delaystring, "%f", delay);
1435
1464
perror_plus("asprintf");
1438
1467
ret = setenv("DELAY", delaystring, 1);
1440
1469
free(delaystring);
1441
1470
perror_plus("setenv");
1444
1473
free(delaystring);
1445
ret = execl(fullname, direntry->d_name, mode, NULL);
1446
perror_plus("execl");
1474
if(execl(fullname, direntry->d_name, mode, NULL) == -1){
1475
perror_plus("execl");
1476
_exit(EXIT_FAILURE);
1449
1480
if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
1646
1677
argp_state_help(state, state->out_stream,
1647
1678
ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
1648
1679
case 'V': /* --version */
1649
fprintf_plus(state->out_stream,
1650
"Mandos plugin mandos-client: ");
1651
1680
fprintf_plus(state->out_stream, "%s\n", argp_program_version);
1652
1681
exit(argp_err_exit_status);
1682
1711
/* Work around Debian bug #633582:
1683
1712
<http://bugs.debian.org/633582> */
1686
1714
/* Re-raise priviliges */
1688
1716
ret = seteuid(0);
1690
1718
perror_plus("seteuid");
1693
if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
1694
int seckey_fd = open(seckey, O_RDONLY);
1695
if(seckey_fd == -1){
1696
perror_plus("open");
1698
ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
1700
perror_plus("fstat");
1702
if(S_ISREG(st.st_mode)
1703
and st.st_uid == 0 and st.st_gid == 0){
1704
ret = fchown(seckey_fd, uid, gid);
1706
perror_plus("fchown");
1710
TEMP_FAILURE_RETRY(close(seckey_fd));
1714
if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
1715
int pubkey_fd = open(pubkey, O_RDONLY);
1716
if(pubkey_fd == -1){
1717
perror_plus("open");
1719
ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
1721
perror_plus("fstat");
1723
if(S_ISREG(st.st_mode)
1724
and st.st_uid == 0 and st.st_gid == 0){
1725
ret = fchown(pubkey_fd, uid, gid);
1727
perror_plus("fchown");
1731
TEMP_FAILURE_RETRY(close(pubkey_fd));
1735
/* Lower privileges */
1739
perror_plus("seteuid");
1743
/* Run network hooks */
1746
/* Re-raise priviliges */
1750
perror_plus("seteuid");
1753
if(not run_network_hooks("start", interface, delay)){
1722
if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
1723
int seckey_fd = open(seckey, O_RDONLY);
1724
if(seckey_fd == -1){
1725
perror_plus("open");
1727
ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
1729
perror_plus("fstat");
1731
if(S_ISREG(st.st_mode)
1732
and st.st_uid == 0 and st.st_gid == 0){
1733
ret = fchown(seckey_fd, uid, gid);
1735
perror_plus("fchown");
1739
TEMP_FAILURE_RETRY(close(seckey_fd));
1743
if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
1744
int pubkey_fd = open(pubkey, O_RDONLY);
1745
if(pubkey_fd == -1){
1746
perror_plus("open");
1748
ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
1750
perror_plus("fstat");
1752
if(S_ISREG(st.st_mode)
1753
and st.st_uid == 0 and st.st_gid == 0){
1754
ret = fchown(pubkey_fd, uid, gid);
1756
perror_plus("fchown");
1760
TEMP_FAILURE_RETRY(close(pubkey_fd));
1757
1764
/* Lower privileges */
1759
1766
ret = seteuid(uid);
2232
/* Run network hooks */
2233
run_network_hooks("stop", interface, delay);
2220
2235
/* Re-raise priviliges */
2226
perror_plus("seteuid");
2240
perror_plus("seteuid");
2230
/* Run network hooks */
2231
run_network_hooks("stop", interface, delay);
2233
2243
/* Take down the network interface */
2234
2244
if(take_down_interface and geteuid() == 0){
2235
2245
ret = ioctl(sd, SIOCGIFFLAGS, &network);