]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Namespace configuration.
authorTimo Sirainen <tss@iki.fi>
Sun, 27 Jul 2003 05:37:58 +0000 (08:37 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 27 Jul 2003 05:37:58 +0000 (08:37 +0300)
--HG--
branch : HEAD

configure.in
src/master/mail-process.c
src/master/master-settings.c
src/master/master-settings.h

index 031acd019dca096a9cb3d135c8de29fbefcf1134..861423aa18c8a16d6c5fcd0e1baab50528899323 100644 (file)
@@ -1051,7 +1051,7 @@ dnl **
 dnl ** capabilities
 dnl **
 
-capability="IMAP4rev1 SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN LISTEXT LIST-SUBSCRIBED"
+capability="IMAP4rev1 SORT THREAD=REFERENCES MULTIAPPEND UNSELECT LITERAL+ IDLE CHILDREN LISTEXT LIST-SUBSCRIBED NAMESPACE"
 AC_DEFINE_UNQUOTED(CAPABILITY_STRING, "$capability", IMAP capabilities)
 
 CFLAGS="$CFLAGS $EXTRA_CFLAGS"
index a57f207e2369a79eca3b5223dea4838327b5008b..faf42b0465e6e611f01beacae3d7b3b0b9ee31fc 100644 (file)
@@ -103,13 +103,41 @@ static const char *expand_mail_env(const char *env, const char *user,
        return str_c(str);
 }
 
+static void env_put_namespace(struct namespace_settings *ns,
+                             const char *user, const char *home)
+{
+       const char *location;
+       unsigned int i;
+
+       for (i = 1; ns != NULL; i++, ns = ns->next) {
+               t_push();
+
+               location = expand_mail_env(ns->location, user, home);
+               env_put(t_strdup_printf("NAMESPACE_%u=%s", i, location));
+
+               if (ns->separator != NULL) {
+                       env_put(t_strdup_printf("NAMESPACE_%u_SEP=%s",
+                                               i, ns->separator));
+               }
+               if (ns->type != NULL) {
+                       env_put(t_strdup_printf("NAMESPACE_%u_TYPE=%s",
+                                               i, ns->type));
+               }
+               if (ns->prefix != NULL) {
+                       env_put(t_strdup_printf("NAMESPACE_%u_PREFIX=%s",
+                                               i, ns->prefix));
+               }
+               t_pop();
+       }
+}
+
 int create_mail_process(struct login_group *group, int socket,
                        struct ip_addr *ip,
                        struct auth_master_reply *reply, const char *data)
 {
        static const char *argv[] = { NULL, NULL, NULL };
        struct settings *set = group->set;
-       const char *addr, *mail, *chroot_dir, *home_dir, *full_home_dir;
+       const char *addr, *mail, *user, *chroot_dir, *home_dir, *full_home_dir;
        char title[1024];
        pid_t pid;
        int i, err, ret;
@@ -237,11 +265,12 @@ int create_mail_process(struct login_group *group, int socket,
           auth process, but don't trust that too much either. Some auth
           mechanism might allow leaving extra data there. */
        mail = data + reply->mail_idx;
-       if (*mail == '\0' && set->default_mail_env != NULL) {
-               mail = expand_mail_env(set->default_mail_env,
-                                      data + reply->virtual_user_idx,
-                                      home_dir);
-       }
+       user = data + reply->virtual_user_idx;
+       if (*mail == '\0' && set->default_mail_env != NULL)
+               mail = expand_mail_env(set->default_mail_env, user, home_dir);
+
+       if (set->server->namespaces != NULL)
+               env_put_namespace(set->server->namespaces, user, home_dir);
 
        env_put(t_strconcat("MAIL=", mail, NULL));
        env_put(t_strconcat("USER=", data + reply->virtual_user_idx, NULL));
index 59f634dfed5894aa29782ddd5f66d50ad85f63f1..827e58b53a081badcb4297308c567c69d08a3113 100644 (file)
@@ -15,7 +15,8 @@
 enum settings_type {
        SETTINGS_TYPE_ROOT,
        SETTINGS_TYPE_SERVER,
-       SETTINGS_TYPE_AUTH
+       SETTINGS_TYPE_AUTH,
+        SETTINGS_TYPE_NAMESPACE
 };
 
 struct settings_parse_ctx {
@@ -24,6 +25,7 @@ struct settings_parse_ctx {
 
        struct server_settings *root, *server;
        struct auth_settings *auth;
+        struct namespace_settings *namespace;
 
        int level;
 };
@@ -130,6 +132,19 @@ static struct setting_def auth_setting_defs[] = {
        { 0, NULL, 0 }
 };
 
+#undef DEF
+#define DEF(type, name) \
+       { type, #name, offsetof(struct namespace_settings, name) }
+
+static struct setting_def namespace_setting_defs[] = {
+       DEF(SET_STR, type),
+       DEF(SET_STR, separator),
+       DEF(SET_STR, prefix),
+       DEF(SET_STR, location),
+
+       { 0, NULL, 0 }
+};
+
 struct settings default_settings = {
        MEMBER(server) NULL,
        MEMBER(protocol) 0,
@@ -287,6 +302,27 @@ static int auth_settings_verify(struct auth_settings *auth)
        return TRUE;
 }
 
+static int namespace_settings_verify(struct namespace_settings *ns)
+{
+       const char *name;
+
+       name = ns->prefix != NULL ? ns->prefix : "";
+       if (ns->location == NULL) {
+               i_error("Namespace '%s': Missing location", name);
+               return FALSE;
+       }
+
+       if (ns->separator != NULL &&
+           ns->separator[0] != '\0' && ns->separator[1] != '\0') {
+               i_error("Namespace '%s': "
+                       "Hierarchy separator must be only one character long",
+                       name);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 static const char *get_directory(const char *path)
 {
        char *str, *p;
@@ -508,6 +544,38 @@ parse_new_auth(struct server_settings *server, const char *name,
        return auth_settings_new(server, name);
 }
 
+static struct namespace_settings *
+namespace_settings_new(struct server_settings *server, const char *type)
+{
+       struct namespace_settings *ns, **ns_p;
+
+       ns = p_new(settings_pool, struct namespace_settings, 1);
+
+       ns->parent = server;
+       ns->type = str_lcase(p_strdup(settings_pool, type));
+
+       ns_p = &server->namespaces;
+       while (*ns_p != NULL)
+               ns_p = &(*ns_p)->next;
+       *ns_p = ns;
+
+       return ns;
+}
+
+static struct namespace_settings *
+parse_new_namespace(struct server_settings *server, const char *name,
+                   const char **errormsg)
+{
+       if (strcasecmp(name, "private") != 0 &&
+           strcasecmp(name, "shared") != 0 &&
+           strcasecmp(name, "public") != 0) {
+               *errormsg = "Unknown namespace type";
+               return NULL;
+       }
+
+       return namespace_settings_new(server, name);
+}
+
 static const char *parse_setting(const char *key, const char *value,
                                 void *context)
 {
@@ -566,7 +634,11 @@ static const char *parse_setting(const char *key, const char *value,
                return error;
        case SETTINGS_TYPE_AUTH:
                return parse_setting_from_defs(settings_pool, auth_setting_defs,
-                                              ctx->auth, key + 5, value);
+                                              ctx->auth, key, value);
+       case SETTINGS_TYPE_NAMESPACE:
+               return parse_setting_from_defs(settings_pool,
+                                              namespace_setting_defs,
+                                              ctx->namespace, key, value);
        }
 
        i_unreached();
@@ -587,10 +659,12 @@ create_new_server(const char *name,
        *server->imap = *imap_defaults;
        *server->pop3 = *pop3_defaults;
 
+       server->imap->server = server;
        server->imap->protocol = MAIL_PROTOCOL_IMAP;
        server->imap->login_executable = PKG_LIBEXECDIR"/imap-login";
        server->imap->mail_executable = PKG_LIBEXECDIR"/imap";
 
+       server->pop3->server = server;
        server->pop3->protocol = MAIL_PROTOCOL_POP3;
        server->pop3->login_executable = PKG_LIBEXECDIR"/pop3-login";
        server->pop3->mail_executable = PKG_LIBEXECDIR"/pop3";
@@ -614,6 +688,7 @@ static int parse_section(const char *type, const char *name, void *context,
                        ctx->parent_type = SETTINGS_TYPE_ROOT;
                        ctx->server = ctx->root;
                        ctx->auth = NULL;
+                       ctx->namespace = NULL;
                }
                return TRUE;
        }
@@ -669,6 +744,19 @@ static int parse_section(const char *type, const char *name, void *context,
                return ctx->auth != NULL;
        }
 
+       if (strcmp(type, "namespace") == 0) {
+               if (ctx->type != SETTINGS_TYPE_ROOT &&
+                   ctx->type != SETTINGS_TYPE_SERVER) {
+                       *errormsg = "Namespace section not allowed here";
+                       return FALSE;
+               }
+
+               ctx->type = SETTINGS_TYPE_NAMESPACE;
+               ctx->namespace = parse_new_namespace(ctx->server, name,
+                                                    errormsg);
+               return ctx->namespace != NULL;
+       }
+
        *errormsg = "Unknown section type";
        return FALSE;
 }
@@ -678,6 +766,7 @@ int master_settings_read(const char *path)
        struct settings_parse_ctx ctx;
        struct server_settings *server, *prev;
        struct auth_settings *auth;
+       struct namespace_settings *ns;
        pool_t temp;
 
        memset(&ctx, 0, sizeof(ctx));
@@ -732,6 +821,11 @@ int master_settings_read(const char *path)
                                if (!auth_settings_verify(auth))
                                        return FALSE;
                        }
+                        ns = server->namespaces;
+                       for (; ns != NULL; ns = ns->next) {
+                               if (!namespace_settings_verify(ns))
+                                       return FALSE;
+                       }
                        prev = server;
                }
        }
index 64eb416470a11acf879542984d8fa82dd454e0c2..cb4c150aec2bf1636e7ed56c97eaeff2bad80356 100644 (file)
@@ -15,6 +15,7 @@ struct server_settings {
        struct settings *imap;
        struct settings *pop3;
        struct auth_settings *auths;
+        struct namespace_settings *namespaces;
 };
 
 struct settings {
@@ -118,6 +119,16 @@ struct auth_settings {
        unsigned int process_size;
 };
 
+struct namespace_settings {
+       struct server_settings *parent;
+       struct namespace_settings *next;
+
+       const char *type;
+       const char *separator;
+       const char *prefix;
+       const char *location;
+};
+
 extern struct server_settings *settings_root;
 
 int master_settings_read(const char *path);