diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-03 18:56:10 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-03 18:56:10 +0300 |
commit | 89569341997df14df1f3fdfe2bbbb5bb6fa0e7a9 (patch) | |
tree | 9914bd27e698e1b0884070500013a0dc9b88c449 /src | |
parent | 5424cc32d47c5e98b9edfb2b342d9d98d97a1175 (diff) | |
download | rspamd-89569341997df14df1f3fdfe2bbbb5bb6fa0e7a9.tar.gz rspamd-89569341997df14df1f3fdfe2bbbb5bb6fa0e7a9.zip |
* Add ability to fork multiply lmtp workers
* Add ability to drop privilleges of rspamd processes
* Add ability to install redirector with rspamd
* Add FreeBSD start scripts for rspamd and redirector
* Remove command line parsing from util.c as it has specific usage only in main process
Diffstat (limited to 'src')
-rw-r--r-- | src/cfg_file.h | 3 | ||||
-rw-r--r-- | src/cfg_file.y | 6 | ||||
-rw-r--r-- | src/main.c | 128 | ||||
-rw-r--r-- | src/util.c | 33 | ||||
-rw-r--r-- | src/util.h | 2 |
5 files changed, 116 insertions, 56 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h index 78ad6e93a..75c3a8c2f 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -136,6 +136,8 @@ struct config_scalar { * Structure that stores all config data */ struct config_file { + char *rspamd_user; /**< user to run as */ + char *rspamd_group; /**< group to run as */ memory_pool_t *cfg_pool; /**< memory pool for config */ char *cfg_name; /**< name of config file */ char *pid_file; /**< name of pid file */ @@ -156,6 +158,7 @@ struct config_file { gboolean no_fork; /**< if 1 do not call daemon() */ gboolean config_test; /**< if TRUE do only config file test */ unsigned int workers_number; /**< number of workers */ + unsigned int lmtp_workers_number; /**< number of lmtp workers */ enum rspamd_log_type log_type; /**< log type */ int log_facility; /**< log facility in case of syslog */ diff --git a/src/cfg_file.y b/src/cfg_file.y index 7eee8516c..dd48520f2 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -676,6 +676,7 @@ lmtpcmd: lmtpenabled | lmtpsock | lmtpmetric + | lmtpworkers ; lmtpenabled: @@ -698,6 +699,11 @@ lmtpmetric: cfg->lmtp_metric = memory_pool_strdup (cfg->cfg_pool, $3); } ; +lmtpworkers: + WORKERS EQSIGN NUMBER { + cfg->lmtp_workers_number = $3; + } + ; delivery: DELIVERY OBRACE deliverybody EBRACE diff --git a/src/main.c b/src/main.c index 1e9ba6788..f0eca39d3 100644 --- a/src/main.c +++ b/src/main.c @@ -77,6 +77,84 @@ void sig_handler (int signo) } } +static void +read_cmd_line (int argc, char **argv, struct config_file *cfg) +{ + int ch; + while ((ch = getopt(argc, argv, "thfc:u:g:")) != -1) { + switch (ch) { + case 'f': + cfg->no_fork = 1; + break; + case 'c': + if (optarg && cfg->cfg_name) { + cfg->cfg_name = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 't': + cfg->config_test = 1; + break; + case 'u': + if (optarg) { + cfg->rspamd_user = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 'g': + if (optarg) { + cfg->rspamd_group = memory_pool_strdup (cfg->cfg_pool, optarg); + } + break; + case 'h': + case '?': + default: + /* Show help message and exit */ + printf ("Rspamd version " RVERSION "\n" + "Usage: rspamd [-t] [-h] [-n] [-f] [-c config_file]\n" + "-h: This help message\n" + "-t: Do config test and exit\n" + "-f: Do not daemonize main process\n" + "-c: Specify config file (./rspamd.conf is used by default)\n" + "-u: User to run rspamd as\n" + "-g: Group to run rspamd as\n"); + exit (0); + break; + } + } +} + +static void +drop_priv (struct config_file *cfg) +{ + struct passwd *pwd; + struct group *grp; + + if (geteuid () == 0 && cfg->rspamd_user) { + pwd = getpwnam (cfg->rspamd_user); + if (pwd == NULL) { + msg_err ("drop_priv: user specified does not exists (%s), aborting", strerror (errno)); + exit (-errno); + } + if (cfg->rspamd_group) { + grp = getgrnam (cfg->rspamd_group); + if (grp == NULL) { + msg_err ("drop_priv: group specified does not exists (%s), aborting", strerror (errno)); + exit (-errno); + } + if (setgid (grp->gr_gid) == -1) { + msg_err ("drop_priv: cannot setgid to %d (%s), aborting", (int)grp->gr_gid, strerror (errno)); + exit (-errno); + } + if (initgroups(cfg->rspamd_user, grp->gr_gid) == -1) { + msg_err ("drop_priv: initgroups failed (%s), aborting", strerror (errno)); + exit (-errno); + } + } + if (setuid (pwd->pw_uid) == -1) { + msg_err ("drop_priv: cannot setuid to %d (%s), aborting", (int)pwd->pw_uid, strerror (errno)); + exit (-errno); + } + } +} static void config_logger (struct rspamd_main *rspamd, gboolean is_fatal) @@ -321,11 +399,6 @@ main (int argc, char **argv, char **env) exit (-errno); } - if (write_pid (rspamd) == -1) { - msg_err ("main: cannot write pid file %s", rspamd->cfg->pid_file); - exit (-errno); - } - /* Init C modules */ for (i = 0; i < MODULES_NUM; i ++) { cur_module = memory_pool_alloc (rspamd->cfg->cfg_pool, sizeof (struct module_ctx)); @@ -338,21 +411,8 @@ main (int argc, char **argv, char **env) rspamd->type = TYPE_MAIN; init_signals (&signals, sig_handler); - /* Init perl interpreter */ - dTHXa (perl_interpreter); - PERL_SYS_INIT3 (&argc, &argv, &env); - perl_interpreter = perl_alloc (); - if (perl_interpreter == NULL) { - msg_err ("main: cannot allocate perl interpreter, %s", strerror (errno)); - exit (-errno); - } - - PERL_SET_CONTEXT (perl_interpreter); - perl_construct (perl_interpreter); - perl_parse (perl_interpreter, xs_init, 3, args, NULL); - /* Block signals to use sigsuspend in future */ - sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL); + /* Create listen socket */ if (rspamd->cfg->bind_family == AF_INET) { if ((listen_sock = make_tcp_socket (&rspamd->cfg->bind_addr, rspamd->cfg->bind_port, TRUE)) == -1) { msg_err ("main: cannot create tcp listen socket. %s", strerror (errno)); @@ -371,6 +431,30 @@ main (int argc, char **argv, char **env) msg_err ("main: cannot listen on socket. %s", strerror (errno)); exit(-errno); } + + /* Drop privilleges */ + drop_priv (cfg); + + if (write_pid (rspamd) == -1) { + msg_err ("main: cannot write pid file %s", rspamd->cfg->pid_file); + exit (-errno); + } + + /* Init perl interpreter */ + dTHXa (perl_interpreter); + PERL_SYS_INIT3 (&argc, &argv, &env); + perl_interpreter = perl_alloc (); + if (perl_interpreter == NULL) { + msg_err ("main: cannot allocate perl interpreter, %s", strerror (errno)); + exit (-errno); + } + + PERL_SET_CONTEXT (perl_interpreter); + perl_construct (perl_interpreter); + perl_parse (perl_interpreter, xs_init, 3, args, NULL); + /* Block signals to use sigsuspend in future */ + sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL); + TAILQ_INIT (&rspamd->workers); @@ -389,7 +473,9 @@ main (int argc, char **argv, char **env) /* Start lmtp if enabled */ if (cfg->lmtp_enable) { - fork_worker (rspamd, listen_sock, 0, TYPE_LMTP); + for (i = 0; i < cfg->lmtp_workers_number; i++) { + fork_worker (rspamd, listen_sock, 0, TYPE_LMTP); + } } /* Signal processing cycle */ @@ -443,7 +529,7 @@ main (int argc, char **argv, char **env) /* Start new worker that would reread configuration*/ active_worker = fork_worker (rspamd, listen_sock, 1, TYPE_WORKER); } - /* Do not start new workers untill active worker is not ready for accept */ + /* Do not start new workers until active worker is not ready for accept */ } if (child_ready) { child_ready = 0; diff --git a/src/util.c b/src/util.c index 6a107436a..589d5b5d9 100644 --- a/src/util.c +++ b/src/util.c @@ -203,39 +203,6 @@ make_unix_socket (const char *path, struct sockaddr_un *addr, gboolean is_server return (-1); } -void -read_cmd_line (int argc, char **argv, struct config_file *cfg) -{ - int ch; - while ((ch = getopt(argc, argv, "thfc:")) != -1) { - switch (ch) { - case 'f': - cfg->no_fork = 1; - break; - case 'c': - if (optarg && cfg->cfg_name) { - cfg->cfg_name = memory_pool_strdup (cfg->cfg_pool, optarg); - } - break; - case 't': - cfg->config_test = 1; - break; - case 'h': - case '?': - default: - /* Show help message and exit */ - printf ("Rspamd version " RVERSION "\n" - "Usage: rspamd [-t] [-h] [-n] [-f] [-c config_file]\n" - "-h: This help message\n" - "-t: Do config test and exit\n" - "-f: Do not daemonize main process\n" - "-c: Specify config file (./rspamd.conf is used by default)\n"); - exit (0); - break; - } - } -} - int write_pid (struct rspamd_main *main) { diff --git a/src/util.h b/src/util.h index f0764b960..7267a719b 100644 --- a/src/util.h +++ b/src/util.h @@ -12,8 +12,6 @@ int make_tcp_socket (struct in_addr *, u_short, gboolean is_server); int accept_from_socket (int listen_sock, struct sockaddr *addr, socklen_t *len); /* Create and bind or connect unix socket */ int make_unix_socket (const char *, struct sockaddr_un *, gboolean is_server); -/* Parse command line arguments using getopt (3) */ -void read_cmd_line (int , char **, struct config_file *); /* Write pid to file */ int write_pid (struct rspamd_main *); /* Make specified socket non-blocking */ |