shrpx: Added --pid-file and --user option

--pid-file option saves PID to the specified file.  user option is
--used to drop root privileges.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-08-01 01:51:16 +09:00
parent 05e6d527b1
commit f3587e1591
3 changed files with 58 additions and 1 deletions

View File

@ -33,10 +33,12 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h> #include <getopt.h>
#include <pwd.h>
#include <limits> #include <limits>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <fstream>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
@ -233,6 +235,19 @@ int event_loop()
} }
} // namespace } // namespace
namespace {
void save_pid()
{
std::ofstream out(get_config()->pid_file, std::ios::binary);
out << getpid() << "\n";
out.close();
if(!out) {
LOG(ERROR) << "Could not save PID to file " << get_config()->pid_file;
exit(EXIT_FAILURE);
}
}
} // namespace
namespace { namespace {
void fill_default_config() void fill_default_config()
{ {
@ -387,6 +402,9 @@ void print_help(std::ostream& out)
<< " frontend connection to 2**<N>.\n" << " frontend connection to 2**<N>.\n"
<< " Default: " << " Default: "
<< get_config()->spdy_upstream_window_bits << "\n" << get_config()->spdy_upstream_window_bits << "\n"
<< " --pid-file=<PATH> Set path to save PID of this program.\n"
<< " --user=<USER> Run this program as USER. This option is\n"
<< " intended to be used to drop root privileges.\n"
<< " -h, --help Print this help.\n" << " -h, --help Print this help.\n"
<< std::endl; << std::endl;
} }
@ -422,6 +440,8 @@ int main(int argc, char **argv)
{"accesslog", no_argument, &flag, 7 }, {"accesslog", no_argument, &flag, 7 },
{"backend-keep-alive-timeout", required_argument, &flag, 8 }, {"backend-keep-alive-timeout", required_argument, &flag, 8 },
{"frontend-spdy-window-bits", required_argument, &flag, 9 }, {"frontend-spdy-window-bits", required_argument, &flag, 9 },
{"pid-file", required_argument, &flag, 10 },
{"user", required_argument, &flag, 11 },
{"help", no_argument, 0, 'h' }, {"help", no_argument, 0, 'h' },
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
@ -531,6 +551,20 @@ int main(int argc, char **argv)
} }
break; break;
} }
case 10:
mod_config()->pid_file = optarg;
break;
case 11: {
passwd *pwd = getpwnam(optarg);
if(pwd == 0) {
std::cerr << "--user: failed to get uid from " << optarg
<< ": " << strerror(errno) << std::endl;
exit(EXIT_FAILURE);
}
mod_config()->uid = pwd->pw_uid;
mod_config()->gid = pwd->pw_gid;
break;
}
default: default:
break; break;
} }
@ -576,6 +610,23 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if(get_config()->pid_file) {
save_pid();
}
if(getuid() == 0 && get_config()->uid != 0) {
if(setgid(get_config()->gid) != 0) {
std::cerr << "Could not change gid: " << strerror(errno) << std::endl;
exit(EXIT_FAILURE);
}
if(setuid(get_config()->uid) != 0) {
std::cerr << "Could not change uid: " << strerror(errno) << std::endl;
exit(EXIT_FAILURE);
}
if(setuid(0) != -1) {
std::cerr << "FATAL: Still have root privileges?" << std::endl;
exit(EXIT_FAILURE);
}
}
struct sigaction act; struct sigaction act;
memset(&act, 0, sizeof(struct sigaction)); memset(&act, 0, sizeof(struct sigaction));

View File

@ -44,7 +44,10 @@ Config::Config()
spdy_proxy(false), spdy_proxy(false),
add_x_forwarded_for(false), add_x_forwarded_for(false),
accesslog(false), accesslog(false),
spdy_upstream_window_bits(0) spdy_upstream_window_bits(0),
pid_file(0),
uid(0),
gid(0)
{} {}
namespace { namespace {

View File

@ -70,6 +70,9 @@ struct Config {
bool add_x_forwarded_for; bool add_x_forwarded_for;
bool accesslog; bool accesslog;
size_t spdy_upstream_window_bits; size_t spdy_upstream_window_bits;
const char* pid_file;
uid_t uid;
gid_t gid;
Config(); Config();
}; };