]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Add mail_index_use_existing_permissions()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 24 Jul 2017 18:07:44 +0000 (21:07 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 24 Jul 2017 18:11:03 +0000 (21:11 +0300)
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
src/lib-index/mail-index.h

index 264205defad44df53831cb83252d2550072e3dc9..bc5b983199caef0a64174eeaa3f60d86e153e643 100644 (file)
@@ -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)
 {
index a5d740d0a47407ad461be2e6b493247cbfbee5c2..87e002879d5da94598e0dabea9b5e0046481f082 100644 (file)
@@ -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