On Wednesday, August 17, 2011 01:49:34 AM you wrote: > Well there's a difference, I see "user.base" not "user^base". Sounds > like there's some difference between our imapd.confs. Although by this > point I would expect the name to be internalised.
Yep, you are right, my imapd.conf contains the "unixhierarchysep: true" setting, that is why I was confused. Internally all hierarchy separators are dots. > I don't use --trace-children, although I don't see why that should > matter. Are you getting any log messages from Valgrind running in the > child imapd process at all? Not at all, tried it with the proper input as well. > That sounds better. Another option would be returning early from the > function. Or using mboxname_to_parts() to do the parsing instead. Just for reference; the original code of the mboxlist_is_owner function seems to be extracted (and modified) from the original code base, check the commit http://git.cyrusimap.org/cyrus- imapd/commit/?id=4412656e218a42559964ccdce06e8daefb8197c5 here: @@ -1351,15 +1384,30 @@ int mboxlist_setacl(const char *name, const char *identifier, identifier = ident; } - if (!strncmp(name+domainlen, "user.", 5) && - (!(cp = strchr(userid, '.')) || (cp - userid) > useridlen) && - !strncmp(name+domainlen+5, userid, useridlen) && - (name[domainlen+5+useridlen] == '\0' || - name[domainlen+5+useridlen] == '.')) { Patch attached for this commit (cyrus-imapd-acl-patch-correction-2.patch), this should work fine, hope you do not get valgrind errors this time :) Kristóf PS Something else came up during manual testing, which is most probably beyond the scope of this patch and the original commit. I enabled virtual domains, relevant lines of the imapd.conf file: virtdomains: yes defaultdomain: net.lan admins: admin ad...@thedomain.here Playing around with cyradm, I get the following: [root@intradevel-aiesec cyrus-imapd]# cyradm localhost --user ad...@thedomain.here Password: intradevel-aiesec.net.lan> listmailbox admin (\HasNoChildren) intradevel-aiesec.net.lan> createmailbox user/base intradevel-aiesec.net.lan> listmailbox admin (\HasNoChildren) user/base (\HasNoChildren) intradevel-aiesec.net.lan> listacl user/base b...@thedomain.here lrswipkxtecdan intradevel-aiesec.net.lan> setacl user/base base all intradevel-aiesec.net.lan> listacl user/base base lrswipkxtecda b...@thedomain.here lrswipkxtecdan intradevel-aiesec.net.lan> setacl user/base base none intradevel-aiesec.net.lan> listacl user/base base lkxca b...@thedomain.here lrswipkxtecdan intradevel-aiesec.net.lan> intradevel-aiesec.net.lan> setacl user/base b...@thedomain.here none intradevel-aiesec.net.lan> listacl user/base base lkxca b...@thedomain.here lkxca My question: who is this "base" user without a domain part in this case? Someone from the default domain? That should not happen, I guess.
diff --git a/imap/mboxlist.c b/imap/mboxlist.c index 9995f28..164da19 100644 --- a/imap/mboxlist.c +++ b/imap/mboxlist.c @@ -1343,15 +1343,26 @@ int mboxlist_renamemailbox(const char *oldname, const char *newname, static int mboxlist_is_owner(const char *name, int domainlen, const char *user, int userlen) { - char *cp = NULL; + char *dot_position = NULL; - int enough_length = !strncmp(name+domainlen, "user.", 5); - int user_complete = (!(cp = strchr(user, '.')) || (cp - user) > userlen); - int match_strings = !strncmp(name+domainlen+5, user, userlen); - int match_length = (name[domainlen+5+userlen] == '\0' || - name[domainlen+5+userlen] == '.'); - - return (enough_length && user_complete && match_strings && match_length); + int is_user_mbox = !strncmp(name+domainlen, "user.", 5); + if(!is_user_mbox) + return 0; + + dot_position = strchr(user, '.'); + if (dot_position && (dot_position - user) <= userlen) + return 0; + + int starts_with_user = !strncmp(name+domainlen+5, user, userlen); + if(!starts_with_user) + return 0; + + int is_exactly_user = (name[domainlen+5+userlen] == '\0' || + name[domainlen+5+userlen] == '.'); + if(!is_exactly_user) + return 0; + + return 1; } /* @@ -1415,6 +1426,7 @@ int mboxlist_setacl(const char *name, const char *identifier, except for "anonymous", "anyone", the global admin and users in the default domain */ if ((cp = strchr(identifier, '@'))) { + identifierlen = cp - identifier; if (rights && ((domain && strncasecmp(cp+1, domain, strlen(cp+1))) || (!domain && (!config_defdomain ||