aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-03 18:56:10 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-03-03 18:56:10 +0300
commit89569341997df14df1f3fdfe2bbbb5bb6fa0e7a9 (patch)
tree9914bd27e698e1b0884070500013a0dc9b88c449 /src
parent5424cc32d47c5e98b9edfb2b342d9d98d97a1175 (diff)
downloadrspamd-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.h3
-rw-r--r--src/cfg_file.y6
-rw-r--r--src/main.c128
-rw-r--r--src/util.c33
-rw-r--r--src/util.h2
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 */