dovecot-2.0: script: Added enough features to get rawlog working...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Dec 12 02:26:37 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/b07f913040b1
changeset: 10460:b07f913040b1
user: Timo Sirainen <tss at iki.fi>
date: Fri Dec 11 19:26:26 2009 -0500
description:
script: Added enough features to get rawlog working again.
Also added -d parameter to drop privileges before executing script.
diffstat:
2 files changed, 71 insertions(+), 31 deletions(-)
src/util/Makefile.am | 5 +-
src/util/script.c | 97 +++++++++++++++++++++++++++++++++++---------------
diffs (205 lines):
diff -r e9cbc461c525 -r b07f913040b1 src/util/Makefile.am
--- a/src/util/Makefile.am Fri Dec 11 18:38:33 2009 -0500
+++ b/src/util/Makefile.am Fri Dec 11 19:26:26 2009 -0500
@@ -12,6 +12,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-auth \
-I$(top_srcdir)/src/lib-dict \
+ -I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-imap \
@@ -26,8 +27,8 @@ rawlog_SOURCES = \
rawlog_SOURCES = \
rawlog.c
-script_LDADD = $(LIBDOVECOT)
-script_DEPENDENCIES = $(LIBDOVECOT_DEPS)
+script_LDADD = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT) $(MODULE_LIBS)
+script_DEPENDENCIES = $(LIBDOVECOT_STORAGE) $(LIBDOVECOT_DEPS)
script_SOURCES = \
script.c
diff -r e9cbc461c525 -r b07f913040b1 src/util/script.c
--- a/src/util/script.c Fri Dec 11 18:38:33 2009 -0500
+++ b/src/util/script.c Fri Dec 11 19:26:26 2009 -0500
@@ -3,35 +3,42 @@
#include "lib.h"
#include "env-util.h"
#include "fdpass.h"
+#include "restrict-access.h"
#include "str.h"
#include "strescape.h"
+#include "settings-parser.h"
+#include "mail-storage-service.h"
#include "master-interface.h"
#include "master-service.h"
+#include "master-service-settings.h"
#include <stdlib.h>
#include <unistd.h>
#define ENV_USERDB_KEYS "USERDB_KEYS"
#define SCRIPT_COMM_FD 3
-#define SCRIPT_CLIENT_FD 1
static char **exec_args;
+static bool drop_privileges = FALSE;
static void client_connected(const struct master_service_connection *conn)
{
- string_t *input, *keys;
- const char **args, *arg, *key, *value, *username;
+ string_t *instr, *keys;
+ const char **args, *key, *value, *error;
+ struct mail_storage_service_ctx *service_ctx;
+ struct mail_storage_service_input input;
+ struct mail_storage_service_user *user;
char buf[1024];
unsigned int i;
int fd = -1;
ssize_t ret;
- input = t_str_new(1024);
+ instr = t_str_new(1024);
ret = fd_read(conn->fd, buf, sizeof(buf), &fd);
while (ret > 0) {
- str_append_n(input, buf, ret);
+ str_append_n(instr, buf, ret);
if (buf[ret-1] == '\n') {
- str_truncate(input, str_len(input)-1);
+ str_truncate(instr, str_len(instr)-1);
break;
}
@@ -51,37 +58,53 @@ static void client_connected(const struc
/* put everything to environment */
env_clean();
keys = t_str_new(256);
- args = t_strsplit(str_c(input), "\t");
+ args = t_strsplit(str_c(instr), "\t");
if (str_array_length(args) < 3)
i_fatal("Missing input fields");
i = 0;
- env_put(t_strconcat("LOCAL_IP=", args[i++], NULL));
- env_put(t_strconcat("IP=", args[i++], NULL));
- username = args[i++];
- env_put(t_strconcat("USER=", username, NULL));
+ memset(&input, 0, sizeof(input));
+ input.module = input.service = "script";
+ (void)net_addr2ip(args[i++], &input.local_ip);
+ (void)net_addr2ip(args[i++], &input.remote_ip);
+ input.username = args[i++];
+ input.userdb_fields = args + i;
+
+ env_put(t_strconcat("LOCAL_IP=", net_ip2addr(&input.local_ip), NULL));
+ env_put(t_strconcat("IP=", net_ip2addr(&input.remote_ip), NULL));
+ env_put(t_strconcat("USER=", input.username, NULL));
for (; args[i] != '\0'; i++) {
- arg = str_tabunescape(t_strdup_noconst(args[i]));
- value = strchr(arg, '=');
+ args[i] = str_tabunescape(t_strdup_noconst(args[i]));
+ value = strchr(args[i], '=');
if (value != NULL) {
- key = t_str_ucase(t_strdup_until(arg, value));
+ key = t_str_ucase(t_strdup_until(args[i], value));
env_put(t_strconcat(key, value, NULL));
str_printfa(keys, "%s ", key);
}
}
env_put(t_strconcat(ENV_USERDB_KEYS"=", str_c(keys), NULL));
- if (dup2(fd, SCRIPT_CLIENT_FD) < 0)
+ master_service_init_log(master_service,
+ t_strdup_printf("script(%s): ", input.username));
+
+ service_ctx = mail_storage_service_init(master_service, NULL, 0);
+ if (mail_storage_service_lookup(service_ctx, &input, &user, &error) < 0)
+ i_fatal("%s", error);
+ mail_storage_service_restrict_setenv(service_ctx, user);
+
+ if (drop_privileges)
+ restrict_access_by_env(getenv("HOME"), TRUE);
+
+ if (dup2(fd, STDIN_FILENO) < 0)
+ i_fatal("dup2() failed: %m");
+ if (dup2(fd, STDOUT_FILENO) < 0)
i_fatal("dup2() failed: %m");
if (conn->fd != SCRIPT_COMM_FD) {
if (dup2(conn->fd, SCRIPT_COMM_FD) < 0)
i_fatal("dup2() failed: %m");
}
-
- master_service_init_log(master_service,
- t_strdup_printf("script(%s): ", username));
(void)execvp(exec_args[0], exec_args);
i_fatal("execvp(%s) failed: %m", exec_args[0]);
@@ -113,7 +136,7 @@ static void script_execute_finish(void)
}
str_append_c(reply, '\n');
- ret = fd_send(SCRIPT_COMM_FD, SCRIPT_CLIENT_FD,
+ ret = fd_send(SCRIPT_COMM_FD, STDOUT_FILENO,
str_data(reply), str_len(reply));
if (ret < 0)
i_fatal("fd_send() failed: %m");
@@ -124,15 +147,25 @@ int main(int argc, char *argv[])
int main(int argc, char *argv[])
{
enum master_service_flags flags = 0;
- int i;
+ const char *path;
+ int i, c;
if (getenv(MASTER_UID_ENV) == NULL)
flags |= MASTER_SERVICE_FLAG_STANDALONE;
master_service = master_service_init("script", flags,
- &argc, &argv, NULL);
- if (master_getopt(master_service) > 0)
- return FATAL_DEFAULT;
+ &argc, &argv, "d");
+ while ((c = master_getopt(master_service)) > 0) {
+ switch (c) {
+ case 'd':
+ drop_privileges = TRUE;
+ break;
+ default:
+ return FATAL_DEFAULT;
+ }
+ }
+ argc -= optind;
+ argv += optind;
master_service_init_log(master_service, "script: ");
master_service_init_finish(master_service);
@@ -141,13 +174,19 @@ int main(int argc, char *argv[])
if ((flags & MASTER_SERVICE_FLAG_STANDALONE) != 0)
script_execute_finish();
else {
- if (argv[1] == NULL)
+ if (argv[0] == NULL)
i_fatal("Missing script path");
- exec_args = i_new(char *, argc + 1);
- for (i = 1; i < argc; i++)
- exec_args[i-1] = argv[i];
- exec_args[i-1] = PKG_LIBEXECDIR"/script";
- exec_args[i] = NULL;
+ exec_args = i_new(char *, argc + 2);
+ for (i = 0; i < argc; i++)
+ exec_args[i] = argv[i];
+ exec_args[i] = PKG_LIBEXECDIR"/script";
+ exec_args[i+1] = NULL;
+
+ if (exec_args[0][0] != '/') {
+ path = t_strconcat(PKG_LIBEXECDIR"/",
+ exec_args[0], NULL);
+ exec_args[0] = t_strdup_noconst(path);
+ }
master_service_run(master_service, client_connected);
}
More information about the dovecot-cvs
mailing list