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 ||

Reply via email to