aboutsummaryrefslogtreecommitdiff
path: root/mtasim
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-04-05 13:37:54 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-04-05 13:37:54 +0000
commit2128d8c24ac57b8f498e14dae00fff94c4e49df4 (patch)
tree983e771d8620b67f4b596927e7cefe89dfffa1d4 /mtasim
parent58fe26ad349c1cb394c7c00867efe539ccbf5c5b (diff)
downloadmailfromd-2128d8c24ac57b8f498e14dae00fff94c4e49df4.tar.gz
mailfromd-2128d8c24ac57b8f498e14dae00fff94c4e49df4.tar.bz2
* mtasim/mtasim.c: New command line options --user and --group.
* doc/mailfromd.texi, doc/mtasim.texi, NEWS: Update. git-svn-id: file:///svnroot/mailfromd/trunk@1651 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'mtasim')
-rw-r--r--mtasim/mtasim.c93
1 files changed, 81 insertions, 12 deletions
diff --git a/mtasim/mtasim.c b/mtasim/mtasim.c
index bdf060d0..5eb8b57c 100644
--- a/mtasim/mtasim.c
+++ b/mtasim/mtasim.c
@@ -32,6 +32,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
+#include <sysexits.h>
#ifdef HAVE_READLINE_READLINE_H
# include <readline/readline.h>
# include <readline/history.h>
@@ -63,6 +64,10 @@ FILE *trace = NULL; /* diagnostic output */
int port = 0; /* Port number (for smtp mode) */
int verbose;
+
+char *user; /* When started as root, switch to this user privileges */
+mu_list_t grouplist; /* List of additional groups to be retained */
+
#ifdef HAVE_TLS
char *tls_cert; /* TLS sertificate */
char *tls_key; /* TLS key */
@@ -104,7 +109,54 @@ struct timeval milter_timeouts[GACOPYZ_TO_COUNT] = {
{ GACOPYZ_CONNECT_TIMEOUT, 0 }
};
-
+
+static int
+gid_comp (const void *item, const void *data)
+{
+ return (gid_t) item != (gid_t) data;
+}
+
+static void
+add_group (const char *gname)
+{
+ struct group *group = getgrnam(gname);
+ if (group)
+ {
+ if (!grouplist)
+ {
+ int rc = mu_list_create (&grouplist);
+ if (rc)
+ {
+ mu_error(_("Cannot create list: %s"), mu_strerror(rc));
+ exit (EX_SOFTWARE);
+ }
+ mu_list_set_comparator (grouplist, gid_comp);
+ }
+ mu_list_append (grouplist, (void*)group->gr_gid);
+ }
+ else
+ {
+ mu_error(_("Unknown group: %s"), gname);
+ exit (EX_DATAERR);
+ }
+}
+
+static void
+priv_setup ()
+{
+ if (getuid() == 0 && user)
+ {
+ struct passwd *pw = getpwnam (user);
+ if (!pw)
+ {
+ mu_error(_("No such user: %s"), user);
+ exit (EX_SOFTWARE);
+ }
+ if (pw && switch_to_privs (pw->pw_uid, pw->pw_gid, grouplist))
+ exit (EX_SOFTWARE);
+ }
+}
+
gacopyz_srv_t gsrv;
@@ -245,6 +297,13 @@ static struct argp_option options[] = {
{ "daemon", OPTION_DAEMON, NULL, 0,
N_("Run as daemon (same as -bd)"),
GRP+1 },
+ { "user", 'u', N_("NAME"), 0,
+ N_("Run with this user privileges"),
+ GRP+1 },
+ { "group", 'g', N_("NAME"), 0,
+ N_("Retain the supplementary group NAME when switching to user "
+ "privileges"),
+ GRP+1 },
#undef GRP
#define GRP 10
@@ -333,7 +392,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
default:
mu_error (_("unsupported mode"));
- exit (1);
+ exit (EX_USAGE);
}
break;
@@ -364,10 +423,18 @@ parse_opt (int key, char *arg, struct argp_state *state)
mu_error (_("wrong assignment format: %s"), arg);
break;
+ case 'g':
+ add_group (arg);
+ break;
+
case OPTION_TRACE_FILE:
trace_name = arg;
break;
+ case 'u':
+ user = arg;
+ break;
+
case 'X':
milter_port = arg;
break;
@@ -381,7 +448,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
if (*p)
{
mu_error (_("invalid number: %s"), arg);
- exit (1);
+ exit (EX_USAGE);
}
break;
@@ -390,7 +457,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
if (*p)
{
mu_error (_("invalid number: %s"), arg);
- exit (1);
+ exit (EX_USAGE);
}
break;
@@ -557,7 +624,7 @@ start_mailfromd (int argc, char **argv)
{
mu_error (_("cannot create temprorary directory (%s): %s"),
tmpdir, mu_strerror (errno));
- exit (1);
+ exit (EX_OSERR);
}
atexit (stop_mailfromd);
@@ -571,7 +638,7 @@ start_mailfromd (int argc, char **argv)
if (child_pid == -1)
{
mu_error (_("cannot fork: %s"), mu_strerror (errno));
- exit (1);
+ exit (EX_OSERR);
}
if (child_pid == 0)
@@ -615,7 +682,7 @@ start_mailfromd (int argc, char **argv)
if (got_sigchld)
{
mu_error (_("child process exited unexpectedly"));
- exit (1);
+ exit (EX_UNAVAILABLE);
}
tv.tv_sec = 0;
@@ -649,7 +716,9 @@ main (int argc, char **argv)
program_invocation_short_name = argv[0];
argp_program_version_hook = version;
if (argp_parse (&argp, argc, argv, 0, &index, NULL))
- exit (1);
+ exit (EX_USAGE);
+
+ priv_setup ();
#ifdef WITH_READLINE
if (interactive)
@@ -677,7 +746,7 @@ main (int argc, char **argv)
if (!mta_mode)
{
mu_error (_("use either --stdio or --daemon"));
- exit (1);
+ exit (EX_USAGE);
}
if (milter_port)
@@ -701,7 +770,7 @@ main (int argc, char **argv)
if (rc != MI_SUCCESS)
{
mu_error (_("cannot create gacopyz server"));
- exit (1);
+ exit (EX_UNAVAILABLE);
}
if (milter_version_option)
@@ -712,7 +781,7 @@ main (int argc, char **argv)
if (gacopyz_srv_connect (gsrv) != MI_SUCCESS)
{
mu_error (_("cannot connect to the milter using %s"), milter_port);
- exit (1);
+ exit (EX_UNAVAILABLE);
}
gacopyz_srv_negotiate (gsrv);
}
@@ -1015,7 +1084,7 @@ get_input_line (char *buf, size_t bufsize)
if (rc)
{
mu_error (_("Read failed: %s"), _mta_strerror (rc));
- exit (1);
+ exit (EX_IOERR);
}
if (n == 0)
break;

Return to:

Send suggestions and report system problems to the System administrator.