Skip to content

Commit

Permalink
lmtp: Moved client_input_data_write_local() from commands.c to lmtp-l…
Browse files Browse the repository at this point in the history
…ocal.c.
  • Loading branch information
stephanbosch committed Dec 7, 2017
1 parent e3d554c commit cbd1d1a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 59 deletions.
52 changes: 0 additions & 52 deletions src/lmtp/commands.c
Expand Up @@ -10,7 +10,6 @@
#include "ostream.h"
#include "istream-dot.h"
#include "safe-mkstemp.h"
#include "restrict-access.h"
#include "anvil-client.h"
#include "master-service.h"
#include "master-service-ssl.h"
Expand All @@ -22,7 +21,6 @@
#include "index/raw/raw-storage.h"
#include "lda-settings.h"
#include "lmtp-settings.h"
#include "mail-autoexpunge.h"
#include "lmtp-local.h"
#include "mail-deliver.h"
#include "message-address.h"
Expand Down Expand Up @@ -572,56 +570,6 @@ static struct istream *client_get_input(struct client *client)
return cinput;
}

static void
client_input_data_write_local(struct client *client, struct istream *input)
{
struct mail_deliver_session *session;
uid_t old_uid, first_uid;

if (client_open_raw_mail(client, input) < 0)
return;

session = mail_deliver_session_init();
old_uid = geteuid();
first_uid = client_deliver_to_rcpts(client, session);
mail_deliver_session_deinit(&session);

if (client->state.first_saved_mail != NULL) {
struct mail *mail = client->state.first_saved_mail;
struct mailbox_transaction_context *trans = mail->transaction;
struct mailbox *box = trans->box;
struct mail_user *user = box->storage->user;

/* just in case these functions are going to write anything,
change uid back to user's own one */
if (first_uid != old_uid) {
if (seteuid(0) < 0)
i_fatal("seteuid(0) failed: %m");
if (seteuid(first_uid) < 0)
i_fatal("seteuid() failed: %m");
}

mail_free(&mail);
mailbox_transaction_rollback(&trans);
mailbox_free(&box);
mail_user_autoexpunge(user);
mail_user_unref(&user);
}

if (old_uid == 0) {
/* switch back to running as root, since that's what we're
practically doing anyway. it's also important in case we
lose e.g. config connection and need to reconnect to it. */
if (seteuid(0) < 0)
i_fatal("seteuid(0) failed: %m");
/* enable core dumping again. we need to chdir also to
root-owned directory to get core dumps. */
restrict_access_allow_coredumps(TRUE);
if (chdir(base_dir) < 0)
i_error("chdir(%s) failed: %m", base_dir);
}
}

static void client_input_data_finish(struct client *client)
{
client_io_reset(client);
Expand Down
56 changes: 53 additions & 3 deletions src/lmtp/lmtp-local.c
Expand Up @@ -7,6 +7,7 @@
#include "hostpid.h"
#include "var-expand.h"
#include "ioloop.h"
#include "restrict-access.h"
#include "settings-parser.h"
#include "mail-storage.h"
#include "mail-storage-service.h"
Expand Down Expand Up @@ -331,8 +332,8 @@ static bool client_rcpt_to_is_last(struct client *client)
return client->state.rcpt_idx >= array_count(&client->state.rcpt_to);
}

uid_t client_deliver_to_rcpts(struct client *client,
struct mail_deliver_session *session)
static uid_t client_deliver_to_rcpts(struct client *client,
struct mail_deliver_session *session)
{
uid_t first_uid = (uid_t)-1;
struct mail *src_mail;
Expand Down Expand Up @@ -374,7 +375,7 @@ uid_t client_deliver_to_rcpts(struct client *client,
return first_uid;
}

int client_open_raw_mail(struct client *client, struct istream *input)
static int client_open_raw_mail(struct client *client, struct istream *input)
{
static const char *wanted_headers[] = {
"From", "To", "Message-ID", "Subject", "Return-Path",
Expand Down Expand Up @@ -403,3 +404,52 @@ int client_open_raw_mail(struct client *client, struct istream *input)
mail_set_seq(client->state.raw_mail, 1);
return 0;
}

void client_input_data_write_local(struct client *client, struct istream *input)
{
struct mail_deliver_session *session;
uid_t old_uid, first_uid;

if (client_open_raw_mail(client, input) < 0)
return;

session = mail_deliver_session_init();
old_uid = geteuid();
first_uid = client_deliver_to_rcpts(client, session);
mail_deliver_session_deinit(&session);

if (client->state.first_saved_mail != NULL) {
struct mail *mail = client->state.first_saved_mail;
struct mailbox_transaction_context *trans = mail->transaction;
struct mailbox *box = trans->box;
struct mail_user *user = box->storage->user;

/* just in case these functions are going to write anything,
change uid back to user's own one */
if (first_uid != old_uid) {
if (seteuid(0) < 0)
i_fatal("seteuid(0) failed: %m");
if (seteuid(first_uid) < 0)
i_fatal("seteuid() failed: %m");
}

mail_free(&mail);
mailbox_transaction_rollback(&trans);
mailbox_free(&box);
mail_user_autoexpunge(user);
mail_user_unref(&user);
}

if (old_uid == 0) {
/* switch back to running as root, since that's what we're
practically doing anyway. it's also important in case we
lose e.g. config connection and need to reconnect to it. */
if (seteuid(0) < 0)
i_fatal("seteuid(0) failed: %m");
/* enable core dumping again. we need to chdir also to
root-owned directory to get core dumps. */
restrict_access_allow_coredumps(TRUE);
if (chdir(base_dir) < 0)
i_error("chdir(%s) failed: %m", base_dir);
}
}
5 changes: 1 addition & 4 deletions src/lmtp/lmtp-local.h
Expand Up @@ -11,9 +11,6 @@ bool cmd_rcpt_finish(struct client *client, struct mail_recipient *rcpt);

void rcpt_anvil_lookup_callback(const char *reply, void *context);

uid_t client_deliver_to_rcpts(struct client *client,
struct mail_deliver_session *session);

int client_open_raw_mail(struct client *client, struct istream *input);
void client_input_data_write_local(struct client *client, struct istream *input);

#endif

0 comments on commit cbd1d1a

Please sign in to comment.