dovecot-2.0: lmtp: Fixes to seteuid calls.
dovecot at dovecot.org
dovecot at dovecot.org
Mon May 31 23:38:52 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/55b8480849b0
changeset: 11439:55b8480849b0
user: Timo Sirainen <tss at iki.fi>
date: Mon May 31 21:38:19 2010 +0100
description:
lmtp: Fixes to seteuid calls.
When delivering to multiple users, the first user's mail should be
deinitialized with that user's effective uid. Also there's no point in
setting uid to 0 between deliveries to multiple users.
diffstat:
src/lmtp/commands.c | 31 +++++++++++++++++++++----------
1 files changed, 21 insertions(+), 10 deletions(-)
diffs (82 lines):
diff -r 7adc45a6da2e -r 55b8480849b0 src/lmtp/commands.c
--- a/src/lmtp/commands.c Mon May 31 20:34:42 2010 +0100
+++ b/src/lmtp/commands.c Mon May 31 21:38:19 2010 +0100
@@ -415,13 +415,10 @@
struct mail_storage *storage;
const struct mail_storage_service_input *input;
void **sets;
- uid_t old_uid;
const char *error, *username;
enum mail_error mail_error;
int ret;
- old_uid = geteuid();
-
input = mail_storage_service_user_get_input(rcpt->service_user);
username = t_strdup(input->username);
@@ -474,13 +471,6 @@
}
ret = -1;
}
- 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");
- }
pool_unref(&dctx.pool);
return ret;
}
@@ -584,10 +574,12 @@
client_input_data_write_local(struct client *client, struct istream *input)
{
struct mail *src_mail;
+ uid_t old_uid, first_uid;
if (client_open_raw_mail(client, input) < 0)
return;
+ old_uid = geteuid();
src_mail = client->state.raw_mail;
while (client_deliver_next(client, src_mail)) {
if (client->state.first_saved_mail == NULL ||
@@ -598,6 +590,8 @@
this might allow hard linking the files. */
client->state.dest_user = NULL;
src_mail = client->state.first_saved_mail;
+ first_uid = geteuid();
+ i_assert(first_uid != 0);
}
}
@@ -607,11 +601,28 @@
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_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");
+ }
}
static void client_input_data_finish(struct client *client)
More information about the dovecot-cvs
mailing list