Mercurial > dovecot > core-2.2
changeset 22295:cebd11880aea
lib-storage: Cleanup - move code to mailbox_list_get_permissions_stat()
Comments changed also a bit, but no functional changes.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 26 Jun 2017 18:41:27 +0300 |
parents | 948b471d551d |
children | 0dd7baafb46e |
files | src/lib-storage/mailbox-list.c |
diffstat | 1 files changed, 81 insertions(+), 71 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/mailbox-list.c Mon Jun 26 18:23:01 2017 +0300 +++ b/src/lib-storage/mailbox-list.c Mon Jun 26 18:41:27 2017 +0300 @@ -885,13 +885,77 @@ return list->v.get_hierarchy_sep(list); } +static bool +mailbox_list_get_permissions_stat(struct mailbox_list *list, const char *path, + struct mailbox_permissions *permissions_r) +{ + struct stat st; + + if (stat(path, &st) < 0) { + if (errno == EACCES) { + mailbox_list_set_critical(list, "%s", + mail_error_eacces_msg("stat", path)); + } else if (!ENOTFOUND(errno)) { + mailbox_list_set_critical(list, "stat(%s) failed: %m", + path); + } else if (list->mail_set->mail_debug) { + i_debug("Namespace %s: %s doesn't exist yet, " + "using default permissions", + list->ns->prefix, path); + } + return FALSE; + } + + permissions_r->file_uid = st.st_uid; + permissions_r->file_gid = st.st_gid; + permissions_r->file_create_mode = (st.st_mode & 0666) | 0600; + permissions_r->dir_create_mode = (st.st_mode & 0777) | 0700; + permissions_r->file_create_gid_origin = path; + + if (!S_ISDIR(st.st_mode)) { + /* we're getting permissions from a file. + apply +x modes as necessary. */ + permissions_r->dir_create_mode = + get_dir_mode(permissions_r->dir_create_mode); + } + + if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) { + /* directory's GID is used automatically for new files */ + permissions_r->file_create_gid = (gid_t)-1; + } else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) { + /* group has same permissions as world, so don't bother + changing it */ + permissions_r->file_create_gid = (gid_t)-1; + } else if (getegid() == st.st_gid) { + /* using our own gid, no need to change it */ + permissions_r->file_create_gid = (gid_t)-1; + } else { + permissions_r->file_create_gid = st.st_gid; + } + if (!S_ISDIR(st.st_mode) && + permissions_r->file_create_gid != (gid_t)-1) { + /* we need to stat() the parent directory to see if + it has setgid-bit set */ + const char *p = strrchr(path, '/'); + const char *parent_path = p == NULL ? NULL : + t_strdup_until(path, p); + if (parent_path != NULL && + stat(parent_path, &st) == 0 && + (st.st_mode & S_ISGID) != 0) { + /* directory's GID is used automatically for + new files */ + permissions_r->file_create_gid = (gid_t)-1; + } + } + return TRUE; +} + static void ATTR_NULL(2) mailbox_list_get_permissions_internal(struct mailbox_list *list, const char *name, struct mailbox_permissions *permissions_r) { - const char *path, *parent_name, *parent_path, *p; - struct stat st; + const char *path, *parent_name, *p; i_zero(permissions_r); @@ -916,81 +980,27 @@ if (path == NULL || (list->flags & MAILBOX_LIST_FLAG_NO_MAIL_FILES) != 0) { /* no filesystem support in storage */ - } else if (stat(path, &st) < 0) { - if (errno == EACCES) { - mailbox_list_set_critical(list, "%s", - mail_error_eacces_msg("stat", path)); - } else if (!ENOTFOUND(errno)) { - mailbox_list_set_critical(list, "stat(%s) failed: %m", - path); - } else if (list->mail_set->mail_debug) { - i_debug("Namespace %s: %s doesn't exist yet, " - "using default permissions", - list->ns->prefix, path); + } else if (mailbox_list_get_permissions_stat(list, path, permissions_r)) { + /* got permissions from the given path */ + permissions_r->gid_origin_is_mailbox_path = name != NULL; + } else if (name != NULL) { + /* path couldn't be stat()ed, try parent mailbox */ + p = strrchr(name, mailbox_list_get_hierarchy_sep(list)); + if (p == NULL) { + /* return root defaults */ + parent_name = NULL; + } else { + parent_name = t_strdup_until(name, p); } - if (name != NULL) { - /* return parent mailbox */ - p = strrchr(name, mailbox_list_get_hierarchy_sep(list)); - if (p == NULL) { - /* return root defaults */ - parent_name = NULL; - } else { - parent_name = t_strdup_until(name, p); - } - mailbox_list_get_permissions(list, parent_name, - permissions_r); - return; - } + mailbox_list_get_permissions(list, parent_name, + permissions_r); + return; + } else { /* assume current defaults for mailboxes that don't exist or can't be looked up for some other reason */ permissions_r->file_uid = geteuid(); permissions_r->file_gid = getegid(); - } else { - permissions_r->file_uid = st.st_uid; - permissions_r->file_gid = st.st_gid; - permissions_r->file_create_mode = (st.st_mode & 0666) | 0600; - permissions_r->dir_create_mode = (st.st_mode & 0777) | 0700; - permissions_r->file_create_gid_origin = path; - permissions_r->gid_origin_is_mailbox_path = name != NULL; - - if (!S_ISDIR(st.st_mode)) { - /* we're getting permissions from a file. - apply +x modes as necessary. */ - permissions_r->dir_create_mode = - get_dir_mode(permissions_r->dir_create_mode); - } - - if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) { - /* directory's GID is used automatically for new - files */ - permissions_r->file_create_gid = (gid_t)-1; - } else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) { - /* group has same permissions as world, so don't bother - changing it */ - permissions_r->file_create_gid = (gid_t)-1; - } else if (getegid() == st.st_gid) { - /* using our own gid, no need to change it */ - permissions_r->file_create_gid = (gid_t)-1; - } else { - permissions_r->file_create_gid = st.st_gid; - } - if (!S_ISDIR(st.st_mode) && - permissions_r->file_create_gid != (gid_t)-1) { - /* we need to stat() the parent directory to see if - it has setgid-bit set */ - p = strrchr(path, '/'); - parent_path = p == NULL ? NULL : - t_strdup_until(path, p); - if (parent_path != NULL && - stat(parent_path, &st) == 0 && - (st.st_mode & S_ISGID) != 0) { - /* directory's GID is used automatically for - new files */ - permissions_r->file_create_gid = (gid_t)-1; - } - } } - if (name == NULL) { mailbox_permissions_copy(&list->root_permissions, permissions_r, list->pool);