Hello,

I'm playing with allow_nets function. It is really cool!
In a filebased passwd backend you simply add "allow_nets=192.0.2.143/32"
as mentioned in http://wiki2.dovecot.org/PasswordDatabase/ExtraFields/AllowNets

But if I use an LDAP backend it looks different.
Following http://wiki2.dovecot.org/AuthDatabase/LDAP/AuthBinds and
http://wiki2.dovecot.org/AuthDatabase/LDAP/Userdb#Attribute_templates_.28v2.1.29
my pass_attrs looks this:

pass_attrs = =user=%{ldap:uid}, \
             =allow_nets=%{ldap:allownets}

Using this syntax I could add an attribute "allownets" in the ldapserver
to limit access for a user.

A problem occour if the attribute is not present. For example if a user
should not be limited or only some but not any user should be limited.
So I extend my pass_attrs with a default.

pass_attrs = =user=%{ldap:uid}, \
             =allow_nets=%{ldap:allownets:10.0.0.0/8}

Again, that's fine. Any user was allowed to connect from my private network.
But then some users connect via ipv6. I tried to extend my default to

pass_attrs = =user=%{ldap:uid}, \
             =allow_nets=%{ldap:allownets:10.0.0.0/8,fec0::/16}

That syntax, a comma separated list, produces errors no matter if quoting using 
" or ' or no quoting at all.

So I looked at the source (thanks, it's open!) and wrote a little patch to 
allow simple defaults:
 - ALL  -> allow any address
 - NONE -> deny any address

Now I could write
  pass_attrs = =user=%{ldap:uid}, =allow_nets=%{ldap:allownets:ALL} 
or
  pass_attrs = =user=%{ldap:uid}, =allow_nets=%{ldap:allownets:NONE}
to allow or deny any ldap account not having an attribute allownets.

Maybe there are other solutions, but that's my way...

Andreas

Index: dovecot-2.2.10/src/auth/auth-request.c
===================================================================
--- dovecot-2.2.10.orig/src/auth/auth-request.c	2014-01-25 17:34:02.000000000 +0100
+++ dovecot-2.2.10/src/auth/auth-request.c	2014-01-25 17:57:01.000000000 +0100
@@ -1291,6 +1291,16 @@
 		return;
 	}
 
+	if (strcmp(networks, "ALL") == 0) {
+		auth_request_log_debug(request, "auth", "allow_nets: found 'ALL'");
+		request->failed = FALSE;
+		return;
+	}
+	if (strcmp(networks, "NONE") == 0) {
+		auth_request_log_debug(request, "auth", "allow_nets: found 'NONE'");
+		request->failed = TRUE;
+		return;
+	}
 	for (net = t_strsplit_spaces(networks, ", "); *net != NULL; net++) {
 		auth_request_log_debug(request, "auth",
 			"allow_nets: Matching for network %s", *net);

Reply via email to