[Dovecot] dirsize quota assertion problem

Alan Ferrency alan at pair.com
Sat Sep 1 00:42:16 EEST 2007


Our current virtual mailbox configuration is not compatible with one of
the assertions in the dovecot quota plugin's assertions in quota-dirsize.c.

I believe the assertion is incorrect, but I would also be happy if I
could get the same result with a better configuration setting.


Here is a sample passdb entry which causes the quota assertion to fail:

test at example.com:<snip>:3007:1000::/usr/boxes/username/example.com::userdb_mail=mbox:~/test^/.imap:INBOX=~/test userdb_uid=3007 userdb_gid=1000 userdb_home=/usr/boxes/username/example.com userdb_quota=dirsize:storage=100

The imap folder is "~/test^/.imap" and the INBOX is "~/test". As you can
see, these are in different locations, but the INBOX string happens to
be a substring of the imap folder directory.

An example of the failed assertion error:

Aug 31 16:44:13 www2 dovecot: IMAP(test at example.com): file quota-dirsize.c: line 180 (quota_count_path_add): assertion failed: (!is_file)


This particular error log line was generated by dovecot 1.0.3, but the
code in quota-dirsize.c is the same in dovecot 1.1 alpha3's version of
quota-dirsize.c:

131                  if (strncmp(count_path[i].path, path, strlen(path)) == 0) {
132                          /* the new path contains the existing path */
133                          i_assert(!is_file);
134                          count_path += i;
135                          break;
136                  }

First, quota_count_path_add() is called for directory "~/test^/.imap"
and it succeeds. When it is subsequently called for file "~/test":

- the strncmp matches because "~/test" is a substring of "~/test^/.imap"
- the assertion fails because "~/test" is a file and not a directory

It seems to me that instead of asserting !is_file, it would be better to
simply skip the conditional in that case, since a path variable that is
a file should never be tested to see whether it contains an existing path.


                if (!is_file &&
                    strncmp(count_path[i].path, path, strlen(path)) == 0) {
                        /* the new path contains the existing path */
                        count_path += i;
                        break;
                }

But this also has a bug: if path is a directory which substring matches
count_path[i].path, but the same path with a directory separator
appended to it does not substring match count_path[i].path, then it is a
different path and does not contain the existing path.

For example, if count_path[i] is the directory
/usr/home/test/mailbox_folders, and path is the directory
/usr/home/test/mailbox, then /usr/home/test/mailbox does not
contain/usr/home/test/mailbox_folders, and this condition should fail.


If some other code were to enforce that /usr/home/test/mailbox be
terminated with a directory separator, then this is not a problem and my
patch should work.


I hope this makes sense.

Thanks,

Alan Ferrency
pair Networks, Inc.
alan at pair.com







More information about the dovecot mailing list