diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-04-05 13:37:54 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-04-05 13:37:54 +0000 |
commit | 2128d8c24ac57b8f498e14dae00fff94c4e49df4 (patch) | |
tree | 983e771d8620b67f4b596927e7cefe89dfffa1d4 /mtasim | |
parent | 58fe26ad349c1cb394c7c00867efe539ccbf5c5b (diff) | |
download | mailfromd-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.c | 93 |
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; |