|
|
#include <popt.h> | #include <popt.h> |
#include "network.h" | #include "network.h" |
#include <ipcportal.h> | #include <ipcportal.h> |
|
#include <sys/stat.h> |
|
#include <pwd.h> |
|
#include <grp.h> |
| |
// some older versions of popt don't define POPT_TABLEEND | // some older versions of popt don't define POPT_TABLEEND |
#ifndef POPT_TABLEEND | #ifndef POPT_TABLEEND |
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } | #define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } |
#endif | #endif |
| |
int main_unix_standalone(const std::string& confdir, bool nodaemon); |
int main_unix_standalone(const std::string& confdir, bool nodaemon, char *chroot, uid_t user, gid_t group); |
int main_unix_backend(Network::Socket csock, IPCPortal* portal); | int main_unix_backend(Network::Socket csock, IPCPortal* portal); |
| |
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) |
|
|
enum { | enum { |
ARG_VERSION = 1, | ARG_VERSION = 1, |
ARG_CONFDIR, | ARG_CONFDIR, |
|
ARG_CHROOT, |
|
ARG_USER, |
|
ARG_GROUP, |
ARG_NODAEMON, | ARG_NODAEMON, |
ARG_BACKEND | ARG_BACKEND |
}; | }; |
bool backend = false; | bool backend = false; |
bool nodaemon = false; | bool nodaemon = false; |
char *cdir = 0; | char *cdir = 0; |
|
char *chroot = 0; |
|
char *user = 0; |
|
char *group = 0; |
|
uid_t uid = 0; |
|
uid_t gid = 0; |
std::string confdir = CONFDIR; | std::string confdir = CONFDIR; |
struct poptOption options[] = { | struct poptOption options[] = { |
{ "version", 'v', POPT_ARG_NONE, NULL, ARG_VERSION, "Print version and exit" }, | { "version", 'v', POPT_ARG_NONE, NULL, ARG_VERSION, "Print version and exit" }, |
{ "confdir", 'c', POPT_ARG_STRING, &cdir, ARG_CONFDIR, "Set custom config directory", "dir" }, | { "confdir", 'c', POPT_ARG_STRING, &cdir, ARG_CONFDIR, "Set custom config directory", "dir" }, |
|
{ "chroot", 'r', POPT_ARG_STRING, &chroot, ARG_CHROOT, "Set chroot directory", "dir" }, |
|
{ "user", 'u', POPT_ARG_STRING, &user, ARG_USER, "Set unprivileged user", "name" }, |
|
{ "group", 'g', POPT_ARG_STRING, &group, ARG_GROUP, "Set unprivileged group", "name" }, |
{ "nodaemon", 'n', POPT_ARG_NONE, NULL, ARG_NODAEMON, "Disable background daemon mode" }, | { "nodaemon", 'n', POPT_ARG_NONE, NULL, ARG_NODAEMON, "Disable background daemon mode" }, |
{ "backend", '\0', POPT_ARG_NONE|POPT_ARGFLAG_DOC_HIDDEN, NULL, ARG_BACKEND }, | { "backend", '\0', POPT_ARG_NONE|POPT_ARGFLAG_DOC_HIDDEN, NULL, ARG_BACKEND }, |
POPT_AUTOHELP | POPT_AUTOHELP |
|
|
<< ": " << poptStrerror(arg) << std::endl; | << ": " << poptStrerror(arg) << std::endl; |
return 1; | return 1; |
} | } |
|
if (!backend && (chroot || user || group)) { |
|
struct stat stat_r; |
|
struct passwd *user_r; |
|
struct group *group_r; |
|
|
|
if (getuid()) { |
|
std::cerr << "Cannot lower privileges, not running as root" << std::endl; |
|
return 1; |
|
} |
|
|
|
if (chroot && stat(chroot, &stat_r)) { |
|
if (!S_ISDIR(stat_r.st_mode)){ |
|
std::cerr << "Cannot lower privileges, chroot directory does not exist" << std::endl; |
|
return 1; |
|
} |
|
} |
|
if (user) { |
|
user_r = getpwnam(user); |
|
if (user_r) |
|
uid = user_r->pw_uid; |
|
else { |
|
std::cerr << "Cannot lower privileges, unknown user" << std::endl; |
|
return 1; |
|
} |
|
} |
|
|
|
if (group) { |
|
group_r = getgrnam(group); |
|
if (group_r) |
|
gid = group_r->gr_gid; |
|
else { |
|
std::cerr << "Cannot lower privileges, unknown group" << std::endl; |
|
return 1; |
|
} |
|
} |
|
} |
poptFreeContext(context); | poptFreeContext(context); |
| |
if (backend) { | if (backend) { |
IPCPortal portal(0, 1); | IPCPortal portal(0, 1); |
return main_unix_backend(3, &portal); | return main_unix_backend(3, &portal); |
} else { | } else { |
return main_unix_standalone(confdir, nodaemon); |
return main_unix_standalone(confdir, nodaemon, chroot, uid, gid); |
} | } |
} | } |
| |