aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-04-18 03:25:46 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-04-18 03:25:46 +0200
commitb5bd63140f40f3bd479497f0dbb96d2ec95dc330 (patch)
treef4aebac42248fd6435ea7b50b4a6a9c65a4b26c9
parent3a00a2e0b0cb47e2634f02ed38baeb7c5b37c5c4 (diff)
LDAP: Using ACL Sets for self managed domains.
-rw-r--r--fripost-docs.org191
1 files changed, 95 insertions, 96 deletions
diff --git a/fripost-docs.org b/fripost-docs.org
index 73b0982..9ecbe59 100644
--- a/fripost-docs.org
+++ b/fripost-docs.org
@@ -677,26 +677,28 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html).
| | userPassword: xxxxxx
| | maildir: fripost.org/user1/
| | isActive: TRUE
- | | |- mailTarget=user1@fripost.org
- | | | mailTarget: user1@fripost.org
- | | | mailLocalAddress: user1-alias@example.org
- | | | isActive: TRUE
- | | `- dc=example.org
- | | dc: example.org
- | | isActive: TRUE
- | | `- mailTarget=user1@fripost.org
- | | | mailTarget: user1@fripost.org
- | | | mailLocalAddress: user1@example.org
- | | | isActive: TRUE
- | | |
- | | `- mailTarget=user1-alias@fripost.org
| |
| `- uid=user2@fripost.org
|
|- ou=domains
- | `- dc=fripost.org
- | dc: fripost.org
- | isActive: TRUE
+ | |- dc=fripost.org
+ | | dc: fripost.org
+ | | isActive: TRUE
+ | | `- mailTarget=user1@fripost.org
+ | | mailTarget: user1@fripost.org
+ | | mailLocalAddress: user1-alias@example.org
+ | | isActive: TRUE
+ | |
+ | `- dc=example.org
+ | dc: example.org
+ | owner: uid=user1@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ | isActive: TRUE
+ | `- mailTarget=user1@fripost.org
+ | | mailTarget: user1@fripost.org
+ | | mailLocalAddress: user1@example.org
+ | | isActive: TRUE
+ | |
+ | `- mailTarget=user1-alias@fripost.org
|
|- ou=managers
| |- cn=admin1
@@ -734,7 +736,7 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html).
SUP top STRUCTURAL
DESC 'Virtual Domains.'
MUST ( dc $ isActive )
- MAY ( description ) )
+ MAY ( owner $ description ) )
olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.2 NAME 'virtualAliases'
SUP top STRUCTURAL
DESC 'Virtual Aliases.'
@@ -812,6 +814,9 @@ be looking for e.g., the `mail' attribute.
-
add: olcDbIndex
olcDbIndex: isActive eq
+ -
+ add: olcDbIndex
+ olcDbIndex: owner eq
ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.ldif
@@ -825,12 +830,16 @@ ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.l
olcDbIndex: uid eq,sub
olcDbIndex: mailLocalAddress eq
olcDbIndex: isActive eq
+ olcDbIndex: owner eq
***** Restrict the access
The default ACL is not restrictive enough for our purpose.
Note: The ACLs are evaluated in order, hence the more specific rules should come
first.
+We are using the so-called "Sets" to let the users manage their domain themselves.
+See section 8.5 "Sets - Granting rights based on relationships" in LDAP's manual
+http://www.openldap.org/doc/admin24/access-control.html for details.
:: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)"
[...]
@@ -842,41 +851,48 @@ first.
:: /etc/ldap/local/mail.fripost.org-acl.ldif
- dn: olcDatabase={1}hdb,cn=config
- changetype: modify
- add: olcAccess
- olcAccess: {0}to dn.children="dc=mail,dc=fripost,dc=org" attrs=userPassword
- by self write
- by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- by anonymous auth
- -
- add: olcAccess
- olcAccess: {1}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=children,gn,sn
- by self write
- by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- by * break
- -
- add: olcAccess
- olcAccess: {2}to dn.regex="(.+,)?dc=[^,]+,(uid=[^,]+,ou=mailboxes,dc=mail,dc=fripost,dc=org)$"
- by dn.exact,expand="$2" write
- by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- by * break
- -
- add: olcAccess
- olcAccess: {3}to dn.children="ou=domains,dc=mail,dc=fripost,dc=org" attrs=entry,dc
- by dn="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read
- by * break
- -
- add: olcAccess
- olcAccess: {4}to dn.children="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=entry,dc,uid,maildir,mailLocalAddress,mailTarget
- by dn="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read
- by * break
- -
- add: olcAccess
- olcAccess: {5}to dn.subtree="dc=mail,dc=fripost,dc=org"
- by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- by self read
- by * search
+ dn: olcDatabase={1}hdb,cn=config
+ changetype: modify
+ # User passwords are only writable (hence readable) by the admins and the
+ # user him/herself. Anonymous users are only allowed to bind.
+ add: olcAccess
+ olcAccess: {0}to dn.children="dc=mail,dc=fripost,dc=org" attrs=userPassword
+ by self write
+ by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
+ by anonymous auth
+ -
+ # User names are only writable (hence readable) by the admins and the user
+ # him/herself.
+ add: olcAccess
+ olcAccess: {1}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=gn,sn
+ by self write
+ by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
+ -
+ # Users are allowed to manage (create/delete/toggle activation) the
+ # aliases for the domains they own. The SMTP server can read these
+ # attributes.
+ add: olcAccess
+ olcAccess: {2}to dn.regex="(.+,)?(dc=[^,]+,ou=domains,dc=mail,dc=fripost,dc=org)$"
+ attrs=entry,children,dc,mailLocalAddress,mailTarget,isActive,description
+ by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read
+ by set.expand="[$2]/owner & user" write
+ by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
+ by * none
+ -
+ # The SMTP server needs to read the user login and his/her maildir.
+ add: olcAccess
+ olcAccess: {3}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org"
+ attrs=entry,uid,maildir,isActive
+ by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read
+ by * break
+ -
+ # Admins have writing rights on the branch. Authenticated users can read
+ # their entry. The SMTP server can search through the branch.
+ add: olcAccess
+ olcAccess: {4}to dn.subtree="dc=mail,dc=fripost,dc=org"
+ by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
+ by self read
+ by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" search
ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-acl.ldif
@@ -884,20 +900,25 @@ ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-acl.ldi
:: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)"
[...]
olcAccess: {0}to dn.children="dc=mail,dc=fripost,dc=org" attrs=userPassword by self write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write by anonymous auth
- olcAccess: {1}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=children,gn,sn by self write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- olcAccess: {2}to dn.regex="(.+,)?dc=[^,]+,(uid=[^,]+,ou=mailboxes,dc=mail,dc=fripost,dc=org)$" by dn.exact,expand="$2" write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write by * break
- olcAccess: {3}to dn.children="ou=domains,dc=mail,dc=fripost,dc=org" attrs=dc,entry by dn="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read by * break
- olcAccess: {4}to dn.children="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=entry,dc,uid,maildir,mailLocalAddress,mailTarget by dn="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read by * break
- olcAccess: {5}to dn.subtree="dc=mail,dc=fripost,dc=org" by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write by * search
- olcAccess: {6}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fripost,dc=org" write by * none
- olcAccess: {7}to dn.base="" by * read
- olcAccess: {8}to * by self write by dn="cn=admin,dc=fripost,dc=org" write by * read
+ olcAccess: {1}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=gn,sn by self write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
+ olcAccess: {2}to dn.regex="(.+,)?(dc=[^,]+,ou=domains,dc=mail,dc=fripost,dc=org)$" attrs=entry,children,dc,mailLocalAddress,mailTarget,isActive,description by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read by set.expand="[$2]/owner & user" write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write by * none
+ olcAccess: {3}to dn.one="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=entry,uid,maildir,isActive by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read by * break
+ olcAccess: {4}to dn.subtree="dc=mail,dc=fripost,dc=org" by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write by self read by dn.exact="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" search
+ olcAccess: {5}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=fripost,dc=org" write by * none
+ olcAccess: {6}to dn.base="" by * read
+ olcAccess: {7}to * by self write by dn="cn=admin,dc=fripost,dc=org" write by * read
[...]
Note: Users are here allowed to manage their aliases themselves. Before inserting, we should
ensure that aliases are fully qualified with the domain they own! Otherwise it'd be easy
to steal aliases and probably even spy on other users...
+Note: Users are allowed to manage their domain, but an admin is needed to add a domain to the
+tree. A possibility to avoid that with a web-form is to send a mail to the postmaster@example.org
+(or even to the mail that appears in the WHOIS) with a confirmation hash. That would simply require
+a new ACL with writable [ou=domains,...]/children, and [dc=...,ou=domains,...]/entry. (And probably a
+"semi-admin" with only these rights.)
+
**** Create the base tree
:: /etc/ldap/local/mail.fripost.org-base.ldif
@@ -957,21 +978,14 @@ To delete a leaf or a sub-tree:
maildir: fripost.org/user/
isActive: TRUE
- dn: mailTarget=user@fripost.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
- mailTarget: user@fripost.org
- objectClass: top
- objectClass: inetLocalMailRecipient
- objectClass: virtualAliases
- mailLocalAddress: user-alias@fripost.org
- isActive: TRUE
-
- dn: dc=example.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ dn: dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org
dc: example.org
objectClass: top
objectClass: virtualDomain
+ owner: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
isActive: TRUE
- dn: mailTarget=user@fripost.org,dc=example.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ dn: mailTarget=user@fripost.org,dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org
mailTarget: user@fripost.org
objectClass: top
objectClass: inetLocalMailRecipient
@@ -1005,6 +1019,12 @@ e.g., `slappasswd -h "{SSHA}"'.
**** Check the SASL binds (authentication)
+`slapacl' is an helpful tool to debugs the ACLS. For instance, to check what are
+the rights of user@fripost.org on the domain example.org, we can run:
+ slapacl -b 'dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org' -D 'uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org'
+
+We can also check ACLs with concrete examples:
+
ldapwhoami -xD "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W
should return the whole dn:
@@ -1050,9 +1070,9 @@ The user should be able to change his/her password, and aliases in his/her own d
dn: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
changetype: modify
replace: userPassword
- userPassword: hop
+ userPassword: xxxxxx
- dn: mailTarget=user@fripost.org,dc=example.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ dn: mailTarget=user@fripost.org,dc=example.org,ou=domain,dc=mail,dc=fripost,dc=org
changetype: modify
add: mailLocalAddress
mailLocalAddress: user-alias2@example.org
@@ -1075,34 +1095,13 @@ We now ensure that the leaf has been updated:
modifiersName: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
modifyTimestamp: 20120404215647Z
-
-Also, he/she's allowed to add new virtual domains:
-
- :: /tmp/newdomain.ldif
-
- dn: dc=example2.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
- objectClass: top
- objectClass: virtualDomain
- dc: example2.org
- isActive: TRUE
-
- dn: mailTarget=user-alias@fripost.org,dc=example2.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
- mailTarget: user-alias@fripost.org
- objectClass: top
- objectClass: inetLocalMailRecipient
- objectClass: virtualAliases
- isActive: TRUE
- mailLocalAddress: user@example2.org
-
-ldapadd -D "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W -f /tmp/newdomain.ldif
-
On other modifications, for instance of `maildir', `ldapmodify'
should refuse with `Insufficient access (50)'.
*** Configuring the main IMAP server
**** Install packages
-sudo aptitude install postfix postfix-mysql
+sudo aptitude install postfix postfix-ldap
**** /etc/postfix/main.cf
@@ -1184,7 +1183,7 @@ http://www.tehinterweb.co.uk/roundcube/#pisieverules
server_host = ldap://localhost/
version = 3
- search_base = dc=mail,dc=fripost,dc=org
+ search_base = ou=domains,dc=mail,dc=fripost,dc=org
bind = yes
bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org
bind_pw = xxxxxx
@@ -1201,7 +1200,7 @@ Test it:
server_host = ldap://localhost/
version = 3
- search_base = ou=mailboxes,dc=mail,dc=fripost,dc=org
+ search_base = ou=domains,dc=mail,dc=fripost,dc=org
bind = yes
bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org
bind_pw = xxxxxx