diff --git a/core/app.cpp b/core/app.cpp index a71c10e..8f9a04d 100755 --- a/core/app.cpp +++ b/core/app.cpp @@ -7,8 +7,8 @@ * */ -#include -#include +#include +#include #include #include @@ -723,16 +723,16 @@ Error status = request.status; void App::LogUser(const char * msg, uid_t id) { - log << log3 << msg << " "; - - passwd * p = getpwuid(id); - - if( p ) - log << p->pw_name; - else - log << id; - - log << logend; + log << log3 << msg << " "; + + passwd * p = getpwuid(id); + + if( p ) + log << p->pw_name; + else + log << id; + + log << logend; } @@ -740,104 +740,104 @@ void App::LogGroup(const char * msg, gid_t id, bool put_logend) { log << log3 << msg << " "; - group * g = getgrgid(id); - - if( g ) - log << g->gr_name; - else - log << (int)id; - - if( put_logend ) - log << logend; + group * g = getgrgid(id); + + if( g ) + log << g->gr_name; + else + log << (int)id; + + if( put_logend ) + log << logend; } void App::LogUsers() { -uid_t eid, rid; - - eid = geteuid(); - rid = getuid(); - - if( eid == rid ) - { - LogUser("App: effective/real user:", eid); - } - else - { - LogUser("App: effective user:", eid); - LogUser("App: real user:", rid); - } +uid_t eid, rid; + + eid = geteuid(); + rid = getuid(); + + if( eid == rid ) + { + LogUser("App: effective/real user:", eid); + } + else + { + LogUser("App: effective user:", eid); + LogUser("App: real user:", rid); + } } -void App::LogEffectiveGroups(std::vector & tab) -{ - log << log3 << "App: effective groups:"; - - for(size_t i=0 ; i & tab) +{ + log << log3 << "App: effective groups:"; + + for(size_t i=0 ; i tab; -gid_t rgid; -int len; - - rgid = getgid(); - len = getgroups(0, 0); - - if( len <= 0 ) - { - log << log3 << "App: I can't read how many groups there are" << logend; - return; - } - - tab.resize(len); - len = getgroups(len, &(tab[0])); - - if( len == -1 ) - { - log << log3 << "App: I can't read groups" << logend; - return; - } - - if( len == 1 && rgid == tab[0] ) - { - LogGroup("App: effective/real group:", rgid); - } - else - { - tab.resize(len); - LogEffectiveGroups(tab); - LogGroup("App: real group:", rgid); - } +std::vector tab; +gid_t rgid; +int len; + + rgid = getgid(); + len = getgroups(0, 0); + + if( len <= 0 ) + { + log << log3 << "App: I can't read how many groups there are" << logend; + return; + } + + tab.resize(len); + len = getgroups(len, &(tab[0])); + + if( len == -1 ) + { + log << log3 << "App: I can't read groups" << logend; + return; + } + + if( len == 1 && rgid == tab[0] ) + { + LogGroup("App: effective/real group:", rgid); + } + else + { + tab.resize(len); + LogEffectiveGroups(tab); + LogGroup("App: real group:", rgid); + } } void App::LogUserGroups() { - LogUsers(); - LogGroups(); + LogUsers(); + LogGroups(); } @@ -846,84 +846,114 @@ bool App::DropPrivileges(const std::string & user, uid_t uid, gid_t gid, bool ad { if( additional_groups ) { - if( initgroups(user.c_str(), gid) < 0 ) - { - log << log1 << "App: I can't init groups for user: " << user << logend << logsave; - return false; - } - } - else - { - if( setgroups(1, &gid) < 0 ) - { - log << log1 << "App: I can't init groups for user: " << user << logend << logsave; - return false; - } - } - - // for setting real and saved gid too - if( setgid(gid) ) - { - log << log1 << "App: I can't change real and saved gid" << logend << logsave; - return false; - } - - if( setuid(uid) < 0 ) - { - log << log1 << "App: I can't drop privileges to user: " << user - << " (uid:" << uid << ")" << logend << logsave; - return false; - } - - if( getuid()==0 || geteuid()==0 ) - { - log << log1 << "App: sorry, for security reasons you should not run me as the root" << logend << logsave; - return false; - } + if( initgroups(user.c_str(), gid) < 0 ) + { + log << log1 << "App: I can't init groups for user: " << user << logend << logsave; + return false; + } + } + else + { + if( setgroups(1, &gid) < 0 ) + { + log << log1 << "App: I can't init groups for user: " << user << logend << logsave; + return false; + } + } + + // for setting real and saved gid too + if( setgid(gid) ) + { + log << log1 << "App: I can't change real and saved gid" << logend << logsave; + return false; + } + + if( setuid(uid) < 0 ) + { + log << log1 << "App: I can't drop privileges to user: " << user + << " (uid:" << uid << ")" << logend << logsave; + return false; + } + + if( getuid()==0 || geteuid()==0 ) + { + log << log1 << "App: sorry, for security reasons you should not run me as the root" << logend << logsave; + return false; + } return true; } -bool App::DropPrivileges() -{ - if( getuid()!=0 && geteuid()!=0 ) - return true; - - log << log2 << "App: dropping privileges" << logend; - - if( config.user.empty() ) - { - log << log1 << "App: you should specify user name in the config file " - << "to which I have to drop privileges" << logend << logsave; - return false; - } - - if( config.group.empty() ) - { - log << log1 << "App: you should specify group name in the config file " - << "to which I have to drop privileges" << logend << logsave; - return false; - } - - passwd * p = getpwnam(config.user.c_str()); - group * g = getgrnam(config.group.c_str()); - - if( !p ) - { - log << log1 << "App: there is no such a user as: \"" << config.user << "\"" << logend << logsave; - return false; - } - - if( !g ) - { - log << log1 << "App: there is no such a group as: \"" << config.group << "\"" << logend << logsave; - return false; - } - - if( !DropPrivileges(config.user, p->pw_uid, g->gr_gid, config.additional_groups) ) - return false; - -return true; -} - +bool App::DropPrivileges() +{ + if( getuid()!=0 && geteuid()!=0 ) + return true; + + log << log2 << "App: dropping privileges" << logend; + + if( config.user.empty() ) + { + log << log1 << "App: you should specify user name in the config file " + << "to which I have to drop privileges" << logend << logsave; + return false; + } + + if( config.group.empty() ) + { + log << log1 << "App: you should specify group name in the config file " + << "to which I have to drop privileges" << logend << logsave; + return false; + } + + passwd * p = getpwnam(config.user.c_str()); + group * g = getgrnam(config.group.c_str()); + + if( !p ) + { + log << log1 << "App: there is no such a user as: \"" << config.user << "\"" << logend << logsave; + return false; + } + + if( !g ) + { + log << log1 << "App: there is no such a group as: \"" << config.group << "\"" << logend << logsave; + return false; + } + + if( !DropPrivileges(config.user, p->pw_uid, g->gr_gid, config.additional_groups) ) + return false; + +return true; +} + + + +bool App::Demonize() +{ + // in linux fork() should be used twice + + int pid = fork(); + + if( pid == -1 ) + { + log << log1 << "App: I can't demonize myself (fork problem)" << logend << logsave; + return false; + } + + if( pid != 0 ) + { + // parent + exit(0); + } + + // child + if( setsid() == -1 ) + { + log << log1 << "App: I can't demonize myself (setsid problem)" << logend << logsave; + return false; + } + +return true; +} + diff --git a/core/app.h b/core/app.h index 63ba658..4df763f 100755 --- a/core/app.h +++ b/core/app.h @@ -52,7 +52,7 @@ public: void Close(); bool DropPrivileges(); void LogUserGroups(); - + bool Demonize(); // configuration read from a config file Config config; diff --git a/core/config.cpp b/core/config.cpp index 3ebb0e3..39e5ffa 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -89,6 +89,8 @@ bool Config::ReadConfig(bool errors_to_stdout_, bool stdout_is_closed) void Config::AssignValues(bool stdout_is_closed) { + demonize = Bool("demonize", true); + user = Text("user"); group = Text("group"); additional_groups = Bool("additional_groups", true); diff --git a/core/config.h b/core/config.h index 51ee216..abdf2ae 100755 --- a/core/config.h +++ b/core/config.h @@ -21,9 +21,14 @@ class Config { public: - // name of the config file (full path can be) + // name of the config file + // this is the parameter passed to winix programm std::string config_file; + // start as a demon (in the background) + // default: true + bool demonize; + // system user name (to which drop privileges) // used only if winix is started as the root std::string user; @@ -47,6 +52,8 @@ public: int log_level; // logging to stdout too + // only if demonize is 'false' + // default: false bool log_stdout; // how many requests should be logged in the same time diff --git a/main/main.cpp b/main/main.cpp index 57ca806..997cceb 100755 --- a/main/main.cpp +++ b/main/main.cpp @@ -68,7 +68,7 @@ int main(int argv, char ** argc) if( !app.config.ReadConfig(true, false) ) /* errors to stdout, stdout in not closed */ return 2; - if( app.stdout_is_closed ) + if( app.stdout_is_closed || app.config.demonize ) app.config.log_stdout = false; // closing descriptors only at the beginning @@ -90,6 +90,9 @@ int main(int argv, char ** argc) app.LogUserGroups(); + if( app.config.demonize && !app.Demonize() ) + return 4; + // app.config.base_server can be changed (stripped from 'http://' or a last slash) // it is done when the config is read log << log3 << "base_server: " << app.config.base_server << logend;