aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-04-14 20:48:06 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-04-14 20:48:06 +0200
commit3a00a2e0b0cb47e2634f02ed38baeb7c5b37c5c4 (patch)
treea6f55b4ec9206ab0b75e6bd7f4d12843e1230fb4
parentf9127856478b1d5fd216bb4578a746258e9537cf (diff)
LDAP/aliases: arbitrary targets.
-rw-r--r--fripost-docs.org224
1 files changed, 147 insertions, 77 deletions
diff --git a/fripost-docs.org b/fripost-docs.org
index f6198ee..73b0982 100644
--- a/fripost-docs.org
+++ b/fripost-docs.org
@@ -672,23 +672,30 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html).
dc=mail, dc=fripost, dc=org
|- ou=mailboxes
- | |- mail=user1@fripost.org
- | | mail: user1@fripost.org
- | | maildir: user1/
- | | mailLocalAddress: user1-alias@fripost.org
+ | |- uid=user1@fripost.org
+ | | uid: user1@fripost.org
+ | | 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
| |
- | `- mail=user2@fripost.org
+ | `- uid=user2@fripost.org
|
|- ou=domains
- | |- dc=fripost.org
- | | dc: fripost.org
- | | isActive: TRUE
- | |
- | `- dc=example.org
- | dc: example.org
- | owner: mail=user1@fripost.org, ou=mailboxes, dc=mail, dc=fripost, dc=org
- | mailLocalAddress: user1@example.org
+ | `- dc=fripost.org
+ | dc: fripost.org
| isActive: TRUE
|
|- ou=managers
@@ -707,28 +714,38 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html).
dn: cn=mail.fripost.org,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: mail.fripost.org
- olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.1 NAME 'maildir'
+ olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'maildir'
DESC 'The path to the maildir.'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
- olcAttributeTypes: ( 1.3.6.1.4.1.12461.1.1.3 NAME 'quota'
+ olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.2 NAME 'quota'
DESC 'The quota on a mailbox e.g., "50MB".'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
- olcAttributetypes: ( 1.3.6.1.4.1.12461.1.1.4 NAME 'isActive'
+ EQUALITY caseExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.44 SINGLE-VALUE )
+ olcAttributetypes: ( 1.3.6.1.4.1.7914.1.2.1.3 NAME 'isActive'
DESC 'Is the leaf active?'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+ olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.4 NAME 'mailTarget'
+ DESC 'The target of e-mail virtual aliases.'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.1 NAME 'virtualDomain'
SUP top STRUCTURAL
- DESC 'Virtual Domains'
+ DESC 'Virtual Domains.'
MUST ( dc $ isActive )
- MAY ( owner $ mailLocalAddress $ description ) )
- olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.2 NAME 'virtualMailbox'
+ MAY ( description ) )
+ olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.2 NAME 'virtualAliases'
SUP top STRUCTURAL
- DESC 'Virtual Mailboxes'
- MUST ( mail $ userPassword $ maildir $ isActive )
- MAY ( mailLocalAddress $ gn $ sn $ quota ) )
+ DESC 'Virtual Aliases.'
+ MUST ( mailTarget $ isActive )
+ MAY ( mailLocalAddress ) )
+ olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.3 NAME 'virtualMailbox'
+ SUP top STRUCTURAL
+ DESC 'Virtual Mailboxes.'
+ MUST ( uid $ userPassword $ maildir $ isActive )
+ MAY ( gn $ sn $ quota ) )
+
Note: For the meaning of the sequences of digits above, grep the output of
`ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"'
@@ -788,10 +805,13 @@ be looking for e.g., the `mail' attribute.
olcDbIndex: dc eq,sub
-
add: olcDbIndex
- olcDbIndex: mail eq,sub
+ olcDbIndex: uid eq,sub
-
add: olcDbIndex
olcDbIndex: mailLocalAddress eq
+ -
+ add: olcDbIndex
+ olcDbIndex: isActive eq
ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.ldif
@@ -802,8 +822,9 @@ ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.l
olcDbIndex: ou eq
olcDbIndex: objectClass pres,eq
olcDbIndex: dc eq,sub
- olcDbIndex: mail eq,sub
+ olcDbIndex: uid eq,sub
olcDbIndex: mailLocalAddress eq
+ olcDbIndex: isActive eq
***** Restrict the access
@@ -830,23 +851,24 @@ first.
by anonymous auth
-
add: olcAccess
- olcAccess: {1}to dn.children="ou=mailboxes,dc=mail,dc=fripost,dc=org" attrs=gn,sn
+ 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.children="ou=domains,dc=mail,dc=fripost,dc=org" attrs=mailLocalAddress
- by dnattr=owner 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
-
add: olcAccess
- olcAccess: {3}to dn.children="ou=domains,dc=mail,dc=fripost,dc=org"
+ 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"
+ 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
-
@@ -862,17 +884,17 @@ 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.children="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.children="ou=domains,dc=mail,dc=fripost,dc=org" attrs=mailLocalAddress by dnattr=owner write by dn.one="ou=managers,dc=mail,dc=fripost,dc=org" write
- olcAccess: {3}to dn.children="ou=domains,dc=mail,dc=fripost,dc=org" 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" by dn="cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" read by * break
+ 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
[...]
-Note: Users are here able to manage their aliases themselves. Before inserting, we should
+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...
@@ -925,33 +947,54 @@ To delete a leaf or a sub-tree:
objectClass: organizationalRole
userPassword: {SSHA}xxxxxxx
- dn: mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
- mail: user@fripost.org
+ dn: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ uid: user@fripost.org
objectClass: top
- objectClass: inetLocalMailRecipient
objectClass: virtualMailbox
gn: First Name
sn: Last Name
userPassword: {SSHA}xxxxxxx
maildir: fripost.org/user/
isActive: TRUE
- mailLocalAddress: user-alias@fripost.org
- dn: dc=fripost.org,ou=domains,dc=mail,dc=fripost,dc=org
+ 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
+ dc: example.org
objectClass: top
objectClass: virtualDomain
- dc: fripost.org
isActive: TRUE
-
- dn: dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org
+
+ dn: mailTarget=user@fripost.org,dc=example.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ mailTarget: user@fripost.org
objectClass: top
objectClass: inetLocalMailRecipient
- objectClass: virtualDomain
- dc: example.org
+ objectClass: virtualAliases
isActive: TRUE
- owner: mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
mailLocalAddress: user@example.org
mailLocalAddress: user-alias@example.org
+
+ dn: uid=user2@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ uid: user2@fripost.org
+ objectClass: top
+ objectClass: virtualMailbox
+ gn: First Name
+ sn: Last Name
+ userPassword: {SSHA}xxxxxx
+ maildir: fripost.org/user2/
+ isActive: FALSE
+
+ dn: dc=fripost.org,ou=domains,dc=mail,dc=fripost,dc=org
+ dc: fripost.org
+ objectClass: top
+ objectClass: virtualDomain
+ isActive: TRUE
ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /tmp/populate.ldif
@@ -962,11 +1005,11 @@ e.g., `slappasswd -h "{SSHA}"'.
**** Check the SASL binds (authentication)
-ldapwhoami -xD "mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W
+ldapwhoami -xD "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W
should return the whole dn:
-"mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org"
+"uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org"
**** Check the ACL
@@ -983,11 +1026,19 @@ and
***** Anonymous user
-`ldapsearch -xLLL -b "ou=mailboxes,dc=mail,dc=fripost,dc=org"' should not return anything.
+`ldapsearch -xLLL -b "ou=mailboxes,dc=mail,dc=fripost,dc=org"' should exit with status 0, but not return
+anything.
+
+***** Services
+
+ldapsearch -xLLL -D "cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org" -b 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W
+
+should only print what Postifx needs to retrieve that is, the domain names, the maildirs
+and the e-mail addresses.
***** Self
-ldapsearch -xLLL -D "mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -b 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W
+ldapsearch -xLLL -D "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -b 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W
should return all the information for this very user, but not e.g., the password of the other users.
@@ -996,17 +1047,17 @@ The user should be able to change his/her password, and aliases in his/her own d
:: /tmp/usermod.ldif
- dn: mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ dn: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
changetype: modify
replace: userPassword
userPassword: hop
- dn: dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org
+ dn: mailTarget=user@fripost.org,dc=example.org,uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
changetype: modify
add: mailLocalAddress
mailLocalAddress: user-alias2@example.org
-ldapmodify -D "mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W -f /tmp/usermod.ldif
+ldapmodify -D "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W -f /tmp/usermod.ldif
[Note: Still that should be wrapped up in a script, and there is no need to write on
disk since the data is read from the standard input.]
@@ -1017,16 +1068,36 @@ from having "mailLocalAddress: admin@fripost.org" for example!
We now ensure that the leaf has been updated:
- :: slapcat -s "mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org"
+ :: slapcat -s "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org"
[...]
userPassword:: aG9w
entryCSN: 20120404215647.957317Z#000000#000#000000
- modifiersName: mail=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ modifiersName: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org
modifyTimestamp: 20120404215647Z
-Doing the same thing with eg, trying to change the `maildir', `ldapmodify'
-refuses with `Insufficient access (50)'.
+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
@@ -1097,8 +1168,8 @@ sudo aptitude install dovecot-imapd
:: /etc/postfix/main.cf
virtual_mailbox_domains = ldap:$config_directory/ldap_virtual_mailbox_domains.cf
- virtual_mailbox_maps = ldap:$config_directory/ldap_virtual_mailbox_maps.cf
virtual_alias_maps = ldap:$config_directory/ldap_virtual_alias_maps.cf
+ virtual_mailbox_maps = ldap:$config_directory/ldap_virtual_mailbox_maps.cf
[...]
@@ -1113,7 +1184,7 @@ http://www.tehinterweb.co.uk/roundcube/#pisieverules
server_host = ldap://localhost/
version = 3
- search_base = ou=domains,dc=mail,dc=fripost,dc=org
+ search_base = dc=mail,dc=fripost,dc=org
bind = yes
bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org
bind_pw = xxxxxx
@@ -1122,10 +1193,11 @@ http://www.tehinterweb.co.uk/roundcube/#pisieverules
Test it:
postmap -q fripost.org ldap:/etc/postfix/ldap_virtual_domains_maps.cf || echo 'failed!'
+ postmap -q example.org ldap:/etc/postfix/ldap_virtual_domains_maps.cf || echo 'failed!'
postmap -q fake.org ldap:/etc/postfix/ldap_virtual_domains_maps.cf || echo 'failed!'
-:: /etc/postfix/ldap_virtual_mailbox_maps.cf
+:: /etc/postfix/ldap_virtual_alias_maps.cf
server_host = ldap://localhost/
version = 3
@@ -1133,29 +1205,27 @@ Test it:
bind = yes
bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org
bind_pw = xxxxxx
- query_filter = (&(ObjectClass=virtualMailbox)(mail=%s)(isActive=TRUE))
- result_attribute = maildir
+ query_filter = (&(ObjectClass=virtualAliases)(mailLocalAddress=%s)(isActive=TRUE))
+ result_attribute = mailTarget
Test it:
- postmap -q user@fripost.org ldap:/etc/postfix/ldap_virtual_mailbox_maps.cf
+ postmap -q user-alias@fripost.org ldap:/etc/postfix/ldap_virtual_alias_maps.cf
+ postmap -q user@example.org ldap:/etc/postfix/ldap_virtual_alias_maps.cf
-:: /etc/postfix/ldap_virtual_alias_maps.cf
+:: /etc/postfix/ldap_virtual_mailbox_maps.cf
server_host = ldap://localhost/
version = 3
- search_base = dc=mail,dc=fripost,dc=org
+ search_base = ou=mailboxes,dc=mail,dc=fripost,dc=org
bind = yes
bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org
bind_pw = xxxxxx
- query_filter = (&(|(ObjectClass=virtualMailbox)(ObjectClass=virtualDomain))(mailLocalAddress=%s)(isActive=TRUE))
- result_attribute = mail
- special_result_attribute = owner
+ query_filter = (&(ObjectClass=virtualMailbox)(uid=%s)(isActive=TRUE))
+ result_attribute = maildir
Test it:
- postmap -q user-alias@fripost.org ldap:/etc/postfix/ldap_virtual_alias_maps.cf
- postmap -q user@example.org ldap:/etc/postfix/ldap_virtual_alias_maps.cf
-
+ postmap -q user@fripost.org ldap:/etc/postfix/ldap_virtual_mailbox_maps.cf
**** Test delivery
@@ -1256,14 +1326,14 @@ Copy this file in /etc/dovecot, and chmod 600 it. Uncomment the following lines:
hosts = localhost # Or wherever is our LDAP server
ldap_version = 3
auth_bind = yes
- auth_bind_userdn = mail=%u,ou=mailboxes,dc=mail,dc=fripost,dc=org
+ auth_bind_userdn = uid=%u,ou=mailboxes,dc=mail,dc=fripost,dc=org
base = ou=mailboxes,dc=mail,dc=fripost,dc=org
deref = never
scope = subtree
user_attrs = maildir=home=/home/mail/virtual/%$
- user_filter = (&(objectClass=virtualMailbox)(mail=%u)(dc=%d)(isActive=TRUE))
- pass_attrs = mail=user
- pass_filter = (&(objectClass=virtualMailbox)(mail=%u)(dc=%d)(isActive=TRUE))
+ user_filter = (&(objectClass=virtualMailbox)(uid=%u)(isActive=TRUE))
+ pass_attrs = uid=user
+ pass_filter = (&(objectClass=virtualMailbox)(uid=%u)(isActive=TRUE))
(And the TLS-related lines in case we are not using a tunnel.) The "base" is the root
of our tree structure, in our case dn="ou=mailboxes,dc=mail,dc=fripost,dc=org".
@@ -1337,7 +1407,7 @@ test our installation.)
ldap_auth_method: bind
ldap_search_base: ou=mailboxes,dc=mail,dc=fripost,dc=org
ldap_scope: sub
- ldap_filter: (&(objectClass=virtualMailbox)(mail=%u)(dc=%d)(isActive=TRUE))
+ ldap_filter: (&(objectClass=virtualMailbox)(uid=%u)(isActive=TRUE))
After restarting saslauthd (`/etc/init.d/saslauthd restart'), we can test the
authentication: `testsaslauthd -u user@fripost.org -p password'. (The password