[Dovecot] LIST problem with Dovecot1.1beta10
Hi,
Certain IMAP folder problems started popping up with Squirrelmail with the 1.1beta10 version of Dovecot (and possibly earlier versions). Looked into it and I am seeing odd behavior with the LIST command.
Here is how to reproduce problem, unless I'm missing something obvious:
a001 login dean <password> a001 OK Logged in.
a002 list "" *
- LIST (\NoInferiors \UnMarked) "/" "Sent"
- LIST (\NoInferiors \UnMarked) "/" "Trash"
- LIST (\NoInferiors \UnMarked) "/" "Drafts"
- LIST (\NoInferiors \UnMarked) "/" "INBOX" a002 OK List completed.
a003 list "" Trash*
- LIST (\NoInferiors \UnMarked) "/" "Trash" a003 OK List completed.
a004 list "" Trash a004 OK List completed. <*** What? Shouldn't it have listed Trash instead of returning nothing?>
a005 list "" Trash" <*** Unbalanced quote causes total lockup!
It appears that Squirrelmail, and possibly others, are using the LIST command to test for the presence of a mailbox, but it seems impossible to get an exact match.
Am I missing something here?
-- Dean Brooks dean@iglou.com
On Mon, 2007-12-03 at 16:11 -0500, Dean Brooks wrote:
a003 list "" Trash*
- LIST (\NoInferiors \UnMarked) "/" "Trash" a003 OK List completed.
a004 list "" Trash a004 OK List completed. <*** What? Shouldn't it have listed Trash instead of returning nothing?>
Works here:
x list "" Trash
- LIST (\NoInferiors \Marked) "/" "Trash" x OK List completed.
Show me your dovecot -n output?
a005 list "" Trash" <*** Unbalanced quote causes total lockup!
I noticed this myself also while testing SEARCH. It's not a real problem though since clients shouldn't do that, and doing it manually doesn't break anything. The process dies when the client disconnects. I'll try to get that fixed anyway.
On Tue, Dec 04, 2007 at 03:43:44PM +0200, Timo Sirainen wrote:
On Mon, 2007-12-03 at 16:11 -0500, Dean Brooks wrote:
a003 list "" Trash*
- LIST (\NoInferiors \UnMarked) "/" "Trash" a003 OK List completed.
Works here:
x list "" Trash
- LIST (\NoInferiors \Marked) "/" "Trash" x OK List completed.
Show me your dovecot -n output?
The output of dovecot -n follows. I confirmed that the problem is definitely different behavior than the old version we were running, although I'm confused how you couldn't be able to reproduce it.
Well, I'm sure others will run into it if it's a configuration-specific thing, so it's probably worth checking into. I'll see if I can figure it out by twiddling with some settings.
base_dir: /var/run/dovecot/ protocols: imap listen: 192.107.41.70 ssl_disable: yes disable_plaintext_auth: no login_dir: /var/run/dovecot//login login_executable: /usr/local/adm/dovecot/libexec/dovecot/imap-login login_user: daemon login_log_format_elements: user=%u ip=%r first_valid_uid: 100 last_valid_uid: 128000 mail_extra_groups: mail mail_location: mbox:%h/Mail:INBOX=/var/mail/%u:INDEX=/mail/indexes/local/%u mmap_disable: yes mail_nfs_storage: yes mail_nfs_index: yes mbox_write_locks: fcntl mail_plugins: quota imap_quota auth default: mechanisms: plain login passdb: driver: shadow userdb: driver: passwd plugin: quota: fs
-- Dean Brooks dean@iglou.com
On Tue, Dec 04, 2007 at 03:43:44PM +0200, Timo Sirainen wrote:
On Mon, 2007-12-03 at 16:11 -0500, Dean Brooks wrote:
a003 list "" Trash*
- LIST (\NoInferiors \UnMarked) "/" "Trash" a003 OK List completed.
Works here:
x list "" Trash
- LIST (\NoInferiors \Marked) "/" "Trash" x OK List completed.
Show me your dovecot -n output?
Well, I confirmed that doing a specific LIST on INBOX works properly:
x list "" INBOX
- LIST (\NoInferiors \UnMarked) "/" "INBOX" x OK List completed.
However, no matter what configuration changes I make, Dovecot refuses to list a filesystem mailbox unless you specify a wildcard:
x list "" Sent x OK List completed.
x list "" Sent*
- LIST (\NoInferiors \UnMarked) "/" "Sent" x OK List completed.
Were there any changes to the filesystem listing code? We're on NFS filesystem if it makes any difference.
This problem practically makes Dovecot unusable.
I've been trying to trace the code on this, but I'm having a hard time narrowing down what function is actually excluding individual files from the list.
-- Dean Brooks dean@iglou.com
On Tue, 2007-12-04 at 12:12 -0500, Dean Brooks wrote:
However, no matter what configuration changes I make, Dovecot refuses to list a filesystem mailbox unless you specify a wildcard:
x list "" Sent x OK List completed.
x list "" Sent*
- LIST (\NoInferiors \UnMarked) "/" "Sent" x OK List completed.
Were there any changes to the filesystem listing code? We're on NFS filesystem if it makes any difference.
That might explain it, but I can't think of any change that could have broken this.
I've been trying to trace the code on this, but I'm having a hard time narrowing down what function is actually excluding individual files from the list.
src/lib-storage/list/mailbox-list-fs-iter.c has most of the code (list_file() probably the most interesting function) and src/lib-storage/index/mbox/mbox-storage.c has mbox_list_iter_is_mailbox().
On Tue, Dec 04, 2007 at 07:34:37PM +0200, Timo Sirainen wrote:
On Tue, 2007-12-04 at 12:12 -0500, Dean Brooks wrote:
However, no matter what configuration changes I make, Dovecot refuses to list a filesystem mailbox unless you specify a wildcard:
x list "" Sent x OK List completed.
x list "" Sent*
- LIST (\NoInferiors \UnMarked) "/" "Sent" x OK List completed.
Were there any changes to the filesystem listing code? We're on NFS filesystem if it makes any difference.
That might explain it, but I can't think of any change that could have broken this.
Found it.
It affects anyone under Solaris 8 , and probably all other versions of Solaris.
In src/list/mailbox-list-fs-iter.c, in the function fs_list_dir_next(), the following code near the end of the function is the culprit:
if (i_strocpy(dir->dirent.d_name, fname,
sizeof(dir->dirent.d_name)) < 0) {
/* name too large.. shouldn't happen. */
continue;
}
To fix it, I changed it to:
if (i_strocpy(dir->dirent.d_name, fname, MAXNAMLEN) < 0) {
/* name too large.. shouldn't happen. */
continue;
}
It appears that sizeof(dir->dirent.d_name) always returns "1" under Solaris. Indeed, when I do a "man dirent", I see this:
The dirent structure is defined:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[1];
};
The field d_name
is the beginning of the character array giving the name of
the directory entry. This name is null terminated and may
have at most MAXNAMLEN characters. This results in file
system independent directory entries being variable length
entities.
Turns out this is a common dirent portability issue that affects a few operating systems, including Solaris. I googled around and found other authors who have done crazy stuff like this:
#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME strcpy(dirent->d_name, filename, MAXPATHLEN); #else strcpy(dirent->d_name, filename, sizeof(dirent->d_name)); #endif
There is probably a cleaner way to deal with this though. Anyway, it something that needs to be dealt with. From what I can tell, this is the only place in Dovecot where a sizeof() is done on d_name.
-- Dean Brooks dean@iglou.com
participants (2)
-
Dean Brooks
-
Timo Sirainen