From cded712c19ea8fb43c22726331de26b8a8dd234b Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 24 Jul 2017 21:07:44 +0300 Subject: [PATCH] lib-index: Add mail_index_use_existing_permissions() This has annoyingly lot of copy&pasting from mailbox_list_get_permissions_stat(), but there didn't seem to be any nice place where to share the code. --- src/lib-index/mail-index.c | 28 ++++++++++++++++++++++++++++ src/lib-index/mail-index.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 264205defa..bc5b983199 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -104,6 +104,34 @@ void mail_index_set_fsync_mode(struct mail_index *index, index->fsync_mask = mask; } +bool mail_index_use_existing_permissions(struct mail_index *index) +{ + struct stat st; + + if (stat(index->dir, &st) < 0) + return FALSE; + + index->mode = st.st_mode & 0666; + if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) { + /* directory's GID is used automatically for new files */ + index->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 */ + index->gid = (gid_t)-1; + } else if (getegid() == st.st_gid) { + /* using our own gid, no need to change it */ + index->gid = (gid_t)-1; + } else { + index->gid = st.st_gid; + } + + i_free(index->gid_origin); + if (index->gid != (gid_t)-1) + index->gid_origin = i_strdup("preserved existing GID"); + return TRUE; +} + void mail_index_set_permissions(struct mail_index *index, mode_t mode, gid_t gid, const char *gid_origin) { diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index a5d740d0a4..87e002879d 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -251,6 +251,10 @@ void mail_index_free(struct mail_index **index); can be used to specify which transaction types to fsync. */ void mail_index_set_fsync_mode(struct mail_index *index, enum fsync_mode mode, enum mail_index_fsync_mask mask); +/* Try to set the index's permissions based on its index directory. Returns + TRUE if successful (directory existed), FALSE if mail_index_set_permissions() + should be called. */ +bool mail_index_use_existing_permissions(struct mail_index *index); void mail_index_set_permissions(struct mail_index *index, mode_t mode, gid_t gid, const char *gid_origin); /* Set locking method and maximum time to wait for a lock