Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1151:058f6c26f405 HEAD
Added mail_full_filesystem_access setting. Some of the setting variable
types were declared wrong and caused Dovecot to crash if they were set in
config file.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 11 Feb 2003 21:37:16 +0200 |
parents | 18a2074a4d3d |
children | 95d67b5c3fd4 |
files | dovecot-example.conf src/lib-storage/index/maildir/maildir-list.c src/lib-storage/index/mbox/mbox-list.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib/Makefile.am src/lib/home-expand.c src/lib/home-expand.h src/master/master-settings.c src/master/master-settings.h |
diffstat | 11 files changed, 175 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Tue Feb 11 20:01:38 2003 +0200 +++ b/dovecot-example.conf Tue Feb 11 21:37:16 2003 +0200 @@ -223,6 +223,12 @@ # NOTE: Evolution client breaks with this option when it's trying to APPEND. #mailbox_check_interval = 0 +# Allow full filesystem access to clients. There's no access checks other than +# what the operating system does for the active UID/GID. It works with both +# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/ +# or ~user/. +#mail_full_filesystem_access = no + # Save mails with CR+LF instead of plain LF. This makes sending those mails # take less CPU, especially with sendfile() syscall with Linux and FreeBSD. # But it also creates a bit more disk I/O which may just make it slower.
--- a/src/lib-storage/index/maildir/maildir-list.c Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib-storage/index/maildir/maildir-list.c Tue Feb 11 21:37:16 2003 +0200 @@ -2,6 +2,7 @@ #include "lib.h" #include "hostpid.h" +#include "home-expand.h" #include "unlink-directory.h" #include "imap-match.h" #include "subscription-file/subscription-file.h" @@ -79,15 +80,32 @@ struct dirent *d; struct stat st; enum mailbox_flags flags; + const char *dir, *prefix, *p; char path[PATH_MAX]; - int failed, found_inbox; + int failed, found_inbox, ret; mail_storage_clear_error(storage); - dirp = opendir(storage->dir); + if (!full_filesystem_access || (p = strrchr(mask, '/')) == NULL) { + dir = storage->dir; + prefix = ""; + } else { + if (mask == p) + dir = prefix = "/"; + else { + dir = t_strdup_until(mask, p); + prefix = t_strdup_until(mask, p+1); + } + + if (*mask != '/' && *mask != '~') + dir = t_strconcat(storage->dir, "/", dir, NULL); + dir = home_expand(dir); + } + + dirp = opendir(dir); if (dirp == NULL) { mail_storage_set_critical(storage, "opendir(%s) failed: %m", - storage->dir); + dir); return FALSE; } @@ -106,10 +124,13 @@ /* make sure the mask matches - dirs beginning with ".." should be deleted and we always want to check those. */ - if (fname[1] == '.' || imap_match(glob, fname+1) <= 0) + t_push(); + ret = imap_match(glob, t_strconcat(prefix, fname+1, NULL)); + t_pop(); + if (fname[1] == '.' || ret <= 0) continue; - if (str_path(path, sizeof(path), storage->dir, fname) < 0) + if (str_path(path, sizeof(path), dir, fname) < 0) continue; /* make sure it's a directory */ @@ -147,7 +168,8 @@ t_push(); flags = maildir_get_marked_flags(storage, path); - callback(storage, fname+1, flags, context); + callback(storage, t_strconcat(prefix, fname+1, NULL), + flags, context); t_pop(); }
--- a/src/lib-storage/index/mbox/mbox-list.c Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib-storage/index/mbox/mbox-list.c Tue Feb 11 21:37:16 2003 +0200 @@ -6,6 +6,7 @@ #include "subscription-file/subscription-file.h" #include "mbox-index.h" #include "mbox-storage.h" +#include "home-expand.h" #include <dirent.h> #include <sys/stat.h> @@ -15,10 +16,16 @@ void *context; }; -static int mbox_find_path(struct mail_storage *storage, - struct imap_match_glob *glob, - mailbox_list_callback_t callback, void *context, - const char *relative_dir) +struct list_context { + struct mail_storage *storage; + struct imap_match_glob *glob; + mailbox_list_callback_t *callback; + void *context; + + const char *rootdir; +}; + +static int mbox_find_path(struct list_context *ctx, const char *relative_dir) { DIR *dirp; struct dirent *d; @@ -31,11 +38,14 @@ t_push(); if (relative_dir == NULL) - dir = storage->dir; + dir = ctx->rootdir; + else if (*ctx->rootdir == '\0' && *relative_dir != '\0') + dir = relative_dir; else { if (str_path(fulldir, sizeof(fulldir), - storage->dir, relative_dir) < 0) { - mail_storage_set_critical(storage, "Path too long: %s", + ctx->rootdir, relative_dir) < 0) { + mail_storage_set_critical(ctx->storage, + "Path too long: %s", relative_dir); return FALSE; } @@ -43,6 +53,7 @@ dir = fulldir; } + dir = home_expand(dir); dirp = opendir(dir); if (dirp == NULL) { t_pop(); @@ -54,7 +65,16 @@ return TRUE; } - mail_storage_set_critical(storage, + if (errno == EACCES) { + if (relative_dir != NULL) { + /* subfolder, ignore */ + return TRUE; + } + mail_storage_set_error(ctx->storage, "Access denied"); + return FALSE; + } + + mail_storage_set_critical(ctx->storage, "opendir(%s) failed: %m", dir); return FALSE; } @@ -78,7 +98,7 @@ else { if (str_path(path, sizeof(path), relative_dir, fname) < 0) { - mail_storage_set_critical(storage, + mail_storage_set_critical(ctx->storage, "Path too long: %s/%s", relative_dir, fname); failed = TRUE; @@ -87,12 +107,12 @@ listpath = path; } - if ((match = imap_match(glob, listpath)) < 0) + if ((match = imap_match(ctx->glob, listpath)) < 0) continue; /* see if it's a directory */ if (str_path(fullpath, sizeof(fullpath), dir, fname) < 0) { - mail_storage_set_critical(storage, + mail_storage_set_critical(ctx->storage, "Path too long: %s/%s", dir, fname); failed = TRUE; @@ -103,8 +123,9 @@ if (errno == ENOENT) continue; /* just deleted, ignore */ - mail_storage_set_critical(storage, "stat(%s) failed: " - "%m", fullpath); + mail_storage_set_critical(ctx->storage, + "stat(%s) failed: %m", + fullpath); failed = TRUE; break; } @@ -112,22 +133,23 @@ if (S_ISDIR(st.st_mode)) { /* subdirectory, scan it too */ t_push(); - callback(storage, listpath, MAILBOX_NOSELECT, context); + ctx->callback(ctx->storage, listpath, MAILBOX_NOSELECT, + ctx->context); t_pop(); - if (!mbox_find_path(storage, glob, callback, - context, listpath)) { + if (!mbox_find_path(ctx, listpath)) { failed = TRUE; break; } } else if (match > 0 && - strcmp(fullpath, storage->inbox_file) != 0 && + strcmp(fullpath, ctx->storage->inbox_file) != 0 && strcasecmp(listpath, "INBOX") != 0) { /* don't match any INBOX here, it's added later. we might also have ~/mail/inbox, ~/mail/Inbox etc. Just ignore them for now. */ t_push(); - callback(storage, listpath, MAILBOX_NOINFERIORS, context); + ctx->callback(ctx->storage, listpath, + MAILBOX_NOINFERIORS, ctx->context); t_pop(); } } @@ -148,12 +170,13 @@ last_dir = p; } - return last_dir != NULL ? t_strdup_until(mask, last_dir) : NULL; + return last_dir == NULL ? NULL : t_strdup_until(mask, last_dir); } int mbox_find_mailboxes(struct mail_storage *storage, const char *mask, mailbox_list_callback_t callback, void *context) { + struct list_context ctx; struct imap_match_glob *glob; const char *relative_dir; @@ -175,7 +198,31 @@ callback(storage, "INBOX", MAILBOX_NOINFERIORS, context); } - if (!mbox_find_path(storage, glob, callback, context, relative_dir)) + memset(&ctx, 0, sizeof(ctx)); + ctx.storage = storage; + ctx.glob = glob; + ctx.callback = callback; + ctx.context = context; + + if (!full_filesystem_access || relative_dir == NULL || + (*relative_dir != '/' && *relative_dir != '~' && + *relative_dir != '\0')) + ctx.rootdir = storage->dir; + else + ctx.rootdir = ""; + + if (relative_dir != NULL) { + const char *matchdir = t_strconcat(relative_dir, "/", NULL); + + if (imap_match(ctx.glob, matchdir) > 0) { + t_push(); + ctx.callback(ctx.storage, matchdir, MAILBOX_NOSELECT, + ctx.context); + t_pop(); + } + } + + if (!mbox_find_path(&ctx, relative_dir)) return FALSE; return TRUE;
--- a/src/lib-storage/index/mbox/mbox-storage.c Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Tue Feb 11 21:37:16 2003 +0200 @@ -220,6 +220,13 @@ const char *p; int newdir; + if (full_filesystem_access) + return TRUE; + + /* make sure it's not absolute path */ + if (*mask == '/' || *mask == '\\' || *mask == '~') + return FALSE; + /* make sure there's no "../" or "..\" stuff */ newdir = TRUE; for (p = mask; *p != '\0'; p++) {
--- a/src/lib-storage/mail-storage.c Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib-storage/mail-storage.c Tue Feb 11 21:37:16 2003 +0200 @@ -28,6 +28,7 @@ static struct mail_storage_list *storages = NULL; enum client_workarounds client_workarounds = 0; +int full_filesystem_access = FALSE; void mail_storage_init(void) { @@ -35,6 +36,8 @@ const char *env; const char *const *str; + full_filesystem_access = getenv("FULL_FILESYSTEM_ACCESS") != NULL; + env = getenv("CLIENT_WORKAROUNDS"); if (env == NULL) return;
--- a/src/lib-storage/mail-storage.h Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib-storage/mail-storage.h Tue Feb 11 21:37:16 2003 +0200 @@ -394,6 +394,7 @@ }; extern enum client_workarounds client_workarounds; +extern int full_filesystem_access; /* Initialize mail storage. */ void mail_storage_init(void);
--- a/src/lib/Makefile.am Tue Feb 11 20:01:38 2003 +0200 +++ b/src/lib/Makefile.am Tue Feb 11 21:37:16 2003 +0200 @@ -14,6 +14,7 @@ file-set-size.c \ hash.c \ hex-binary.c \ + home-expand.c \ hostpid.c \ imem.c \ iostream.c \ @@ -68,6 +69,7 @@ file-set-size.h \ hash.h \ hex-binary.h \ + home-expand.h \ hostpid.h \ imem.h \ iostream-internal.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/home-expand.c Tue Feb 11 21:37:16 2003 +0200 @@ -0,0 +1,41 @@ +/* Copyright (C) 2003 Timo Sirainen */ + +#include "lib.h" +#include "home-expand.h" + +#include <stdlib.h> +#include <pwd.h> + +/* expand ~/ or ~user/ in beginning of path */ +const char *home_expand(const char *path) +{ + const char *home, *p, *orig_path; + struct passwd *pw; + + if (*path != '~') + return path; + + orig_path = path++; + if (*path == '/' || *path == '\0') { + home = getenv("HOME"); + if (*path != '\0') path++; + } else { + p = strchr(path, '/'); + if (p == NULL) { + pw = getpwnam(path); + path = ""; + } else { + pw = getpwnam(t_strdup_until(path, p)); + path = p+1; + } + + home = pw == NULL ? NULL : pw->pw_dir; + } + + if (home == NULL) + return orig_path; + else if (*path == '\0') + return t_strdup(home); + else + return t_strconcat(home, "/", path, NULL); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/home-expand.h Tue Feb 11 21:37:16 2003 +0200 @@ -0,0 +1,7 @@ +#ifndef __HOME_EXPAND_H +#define __HOME_EXPAND_H + +/* expand ~/ or ~user/ in beginning of path */ +const char *home_expand(const char *path); + +#endif
--- a/src/master/master-settings.c Tue Feb 11 20:01:38 2003 +0200 +++ b/src/master/master-settings.c Tue Feb 11 21:37:16 2003 +0200 @@ -54,17 +54,18 @@ DEF(SET_STR, mail_cache_fields), DEF(SET_STR, mail_never_cache_fields), DEF(SET_STR, client_workarounds), - DEF(SET_STR, mailbox_check_interval), - DEF(SET_STR, mail_save_crlf), - DEF(SET_STR, mail_read_mmaped), - DEF(SET_STR, maildir_copy_with_hardlinks), - DEF(SET_STR, maildir_check_content_changes), + DEF(SET_INT, mailbox_check_interval), + DEF(SET_BOOL, mail_full_filesystem_access), + DEF(SET_BOOL, mail_save_crlf), + DEF(SET_BOOL, mail_read_mmaped), + DEF(SET_BOOL, maildir_copy_with_hardlinks), + DEF(SET_BOOL, maildir_check_content_changes), DEF(SET_STR, mbox_locks), - DEF(SET_STR, mbox_read_dotlock), - DEF(SET_STR, mbox_lock_timeout), - DEF(SET_STR, mbox_dotlock_change_timeout), - DEF(SET_STR, overwrite_incompatible_index), - DEF(SET_STR, umask), + DEF(SET_BOOL, mbox_read_dotlock), + DEF(SET_INT, mbox_lock_timeout), + DEF(SET_INT, mbox_dotlock_change_timeout), + DEF(SET_BOOL, overwrite_incompatible_index), + DEF(SET_INT, umask), /* imap */ DEF(SET_STR, imap_executable), @@ -157,6 +158,7 @@ MEMBER(mail_never_cache_fields) NULL, MEMBER(client_workarounds) NULL, MEMBER(mailbox_check_interval) 0, + MEMBER(mail_full_filesystem_access) FALSE, MEMBER(mail_save_crlf) FALSE, MEMBER(mail_read_mmaped) FALSE, MEMBER(maildir_copy_with_hardlinks) FALSE,
--- a/src/master/master-settings.h Tue Feb 11 20:01:38 2003 +0200 +++ b/src/master/master-settings.h Tue Feb 11 21:37:16 2003 +0200 @@ -39,6 +39,7 @@ const char *mail_never_cache_fields; const char *client_workarounds; unsigned int mailbox_check_interval; + int mail_full_filesystem_access; int mail_save_crlf; int mail_read_mmaped; int maildir_copy_with_hardlinks;