From 29c0d7c1c0f283c2c8caedef06be90cec3053c05 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sat, 28 Apr 2012 02:16:48 +0200 Subject: LDAP: fine-tuning the schema. --- fripost-docs.org | 407 ++++++++++++++++++++++++++----------------------------- 1 file changed, 193 insertions(+), 214 deletions(-) (limited to 'fripost-docs.org') diff --git a/fripost-docs.org b/fripost-docs.org index d54a7b0..30eaa39 100644 --- a/fripost-docs.org +++ b/fripost-docs.org @@ -312,7 +312,7 @@ ORIGIN_PORT="1917" 2b. Create a new user on the destination host: sudo adduser --home=$TUNNEL_HOME --shell=`type rbash|cut -d' ' -f3` \ - --disabled-password $TUNNEL_USER + --system $TUNNEL_USER echo "exit" | sudo -u $TUNNEL_USER tee $TUNNEL_HOME/.bash_profile # Note: We need bash, so we can not change the shell to something else. @@ -652,11 +652,14 @@ We do not want to listen all the Internet: in `/etc/default/slapd', change `SLAPD_SERVICES' accordingly. E.g., to only listen to (non SSL) localhost and UNIX sockets, specify -SLAPD_SERVICES="ldap:///127.0.0.1:389 ldapi:///%2fvar%2frun%2fopenldap%2fldapi/????x-mod=0777" +SLAPD_SERVICES="ldap:///127.0.0.1:389 ldapi:///" (This should be enough if the connection from the IMAP/SMTP services are wrapped into SSH or SSL/TLS tunnels.) +(Note: Unless specified, connections through the sockets bind with the users +permissions, hence regular users may not be able to explore the tree.) + We can check the configuration with ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config" @@ -670,65 +673,53 @@ and modify a .ldif file with We base our schema on qmail's (http://dhits.nl/download/qmail.new.schema) and Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html). - dc=mail, dc=fripost, dc=org - |- ou=mailboxes - | |- uid=user1@fripost.org - | | uid: user1@fripost.org - | | userPassword: xxxxxx - | | maildir: fripost.org/user1/ - | | isActive: TRUE - | | - | `- uid=user2@fripost.org - | - |- ou=domains - | |- 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 - | + o=mailHosting, dc=fripost, dc=org |- ou=managers | |- cn=admin1 - | | cn: admin1 | | userPassword: xxxxxx | `- cn=admin2 | - `- ou=services - `- cn=SMTP - cn: SMTP - userPassword: xxxxxx - - :: /etc/ldap/local/mail.fripost.org.ldif + |- ou=services + | `- cn=SMTP + | userPassword: xxxxxx + | + `- ou=domains + |- dc=fripost.org + | isActive: TRUE + | |- mailTarget=user1@fripost.org + | | mailLocalAddress: user1-alias + | | isActive: TRUE + | |- uid=user1 + | | userPassword: xxxxxx + | | isActive: TRUE + | | + | `- uid=user2 + | + `- dc=example.org + owner: uid=user1,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org + isActive: TRUE + `- mailTarget=user1@fripost.org + | mailLocalAddress: user1 + | isActive: TRUE + | + `- mailTarget=user1-alias@fripost.org + + + + :: /etc/ldap/fripost/fripost.ldif dn: cn=mail.fripost.org,cn=schema,cn=config objectClass: olcSchemaConfig cn: mail.fripost.org - 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.7914.1.2.1.2 NAME 'quota' + olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.1 NAME 'quota' DESC 'The quota on a mailbox e.g., "50MB".' 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' + olcAttributetypes: ( 1.3.6.1.4.1.7914.1.2.1.2 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' + olcAttributeTypes: ( 1.3.6.1.4.1.7914.1.2.1.3 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 ) @@ -745,7 +736,7 @@ Jamm's (http://jamm.sourceforge.net/howto/html/implementation.html). olcObjectclasses: ( 1.3.6.1.4.1.12461.1.2.3 NAME 'virtualMailbox' SUP top STRUCTURAL DESC 'Virtual Mailboxes.' - MUST ( uid $ userPassword $ maildir $ isActive ) + MUST ( uid $ userPassword $ isActive ) MAY ( gn $ sn $ quota ) ) @@ -756,7 +747,7 @@ don't matter) We can now add it to the schema list: - ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org.ldif + ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/fripost.ldif (A [dirty] way to delete the schema is to remove the coresponding file in `/etc/ldap/slapd.d/cn=config/cn=schema/' and to restart slapd.) @@ -780,17 +771,14 @@ and add with `ldapadd -Y EXTERNAL -H ldapi:/// -f '. ***** Add custom indexes The default indexes below are not enough for our purpose, since we will heavily -be looking for e.g., the `mail' attribute. +be looking for e.g., the `uid' attribute. :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" [...] olcDbIndex: objectClass eq - olcDbIndex: cn eq - olcDbIndex: ou eq - olcDbIndex: dc eq - :: /etc/ldap/local/mail.fripost.org-index.ldif + :: /etc/ldap/fripost/index.ldif dn: olcDatabase={1}hdb,cn=config changetype: modify @@ -800,8 +788,11 @@ be looking for e.g., the `mail' attribute. add: olcDbIndex olcDbIndex: objectClass pres,eq - - delete: olcDbIndex - olcDbIndex: dc eq + add: olcDbIndex + olcDbIndex: cn eq + - + add: olcDbIndex + olcDbIndex: ou eq - add: olcDbIndex olcDbIndex: dc eq,sub @@ -818,15 +809,15 @@ be looking for e.g., the `mail' attribute. add: olcDbIndex olcDbIndex: owner eq -ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/local/mail.fripost.org-index.ldif +ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/index.ldif :: ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(olcDatabase={1}hdb)" [...] + olcDbIndex: objectClass pres,eq olcDbIndex: cn eq olcDbIndex: ou eq - olcDbIndex: objectClass pres,eq - olcDbIndex: dc eq,sub + olcDbIndex: dc eq,sub olcDbIndex: uid eq,sub olcDbIndex: mailLocalAddress eq olcDbIndex: isActive eq @@ -849,70 +840,66 @@ http://www.openldap.org/doc/admin24/access-control.html for details. [...] - :: /etc/ldap/local/mail.fripost.org-acl.ldif - - 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 + :: /etc/ldap/fripost/acl.ldif + + dn: olcDatabase={1}hdb,cn=config + changetype: modify + # Service passwords are only writable (hence readable) by the admins. + # Anonymous services are only allowed to bind. + add: olcAccess + olcAccess: {0}to dn.one="ou=services,o=mailHosting,dc=fripost,dc=org" + attrs=userPassword + by self read + by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write + by anonymous auth + - + # 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: {1}to dn.children="o=mailHosting,dc=fripost,dc=org" + attrs=userPassword + by self write + by dn.one="ou=managers,o=mailHosting,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: {2}to dn.children="o=mailHosting,dc=fripost,dc=org" attrs=gn,sn + by self write + by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write + - + # Users are allowed to manage (create/delete/toggle activation) the + # the domains they own. + add: olcAccess + olcAccess: {3}to dn.regex="(.+,)?(dc=[^,]+,ou=domains,o=mailHosting,dc=fripost,dc=org)$" + by set.expand="[$2]/owner & user" write + by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write + by * break + - + # Admins have writing rights on the branch. Authenticated users can read + # their entry. The SMTP server can read entries on the branch. + add: olcAccess + olcAccess: {4}to dn.subtree="o=mailHosting,dc=fripost,dc=org" + by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write + by self read + by dn.exact="cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org" read + +ldapmodify -QY EXTERNAL -H ldapi:/// -f /etc/ldap/fripost/acl.ldif :: 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=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: {0}to dn.one="ou=services,o=mailHosting,dc=fripost,dc=org" attrs=userPassword by self read by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write by anonymous auth + olcAccess: {1}to dn.children="o=mailHosting,dc=fripost,dc=org" attrs=userPassword by self write by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write by anonymous auth + olcAccess: {2}to dn.children="o=mailHosting,dc=fripost,dc=org" attrs=gn,sn by self write by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write + olcAccess: {3}to dn.regex="(.+,)?(dc=[^,]+,ou=domains,o=mailHosting,dc=fripost,dc=org)$" by set.expand="[$2]/owner & user" write by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write by * break + olcAccess: {4}to dn.subtree="o=mailHosting,dc=fripost,dc=org" by dn.one="ou=managers,o=mailHosting,dc=fripost,dc=org" write by self read by dn.exact="cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org" read 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 @@ -921,93 +908,78 @@ a new ACL with writable [ou=domains,...]/children, and [dc=...,ou=domains,...]/e **** Create the base tree - :: /etc/ldap/local/mail.fripost.org-base.ldif + :: /etc/ldap/fripost/base.ldif - dn: dc=mail,dc=fripost,dc=org - objectClass: domain - dc: mail - - dn: ou=mailboxes,dc=mail,dc=fripost,dc=org - objectClass: organizationalUnit - ou: mailboxes - description: Virtual mailboxes - - dn: ou=domains,dc=mail,dc=fripost,dc=org + dn: o=mailHosting,dc=fripost,dc=org + objectClass: organizational + description: Mail hosting + + dn: ou=domains,o=mailHosting,dc=fripost,dc=org objectClass: organizationalUnit - ou: domains - description: Virtual domains - - dn: ou=managers,dc=mail,dc=fripost,dc=org + description: Virtual Hosting + + dn: ou=managers,o=mailHosting,dc=fripost,dc=org objectClass: organizationalUnit - ou: managers description: Postmasters - - dn: ou=services,dc=mail,dc=fripost,dc=org + + dn: ou=services,o=mailHosting,dc=fripost,dc=org objectClass: organizationalUnit - ou: services description: E-mail services -ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /etc/ldap/local/mail.fripost.org-base.ldif +ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /etc/ldap/fripost/base.ldif -To delete a leaf or a sub-tree: - ldapdelete -D cn=admin,dc=fripost,dc=org 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W +To delete a leaf (`-r' to delete the whole sub-tree): + ldapdelete -r -D cn=admin,dc=fripost,dc=org 'dc=example.org,ou=domains,o=mailHosting,dc=fripost,dc=org' -W **** Populate the tree :: /tmp/populate.ldif - dn: cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org - cn: SMTP + + dn: cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org objectClass: simpleSecurityObject objectClass: organizationalRole - userPassword: {SSHA}xxxxxxx - - dn: cn=admin1,ou=managers,dc=mail,dc=fripost,dc=org - cn: admin1 + userPassword: {SSHA}xxxxxx + + dn: cn=admin1,ou=managers,o=mailHosting,dc=fripost,dc=org objectClass: simpleSecurityObject objectClass: organizationalRole - userPassword: {SSHA}xxxxxxx - - dn: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org - uid: user@fripost.org - objectClass: top + userPassword: {SSHA}xxxxxx + + dn: dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org + objectClass: virtualDomain + isActive: TRUE + + dn: uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org objectClass: virtualMailbox gn: First Name sn: Last Name - userPassword: {SSHA}xxxxxxx - maildir: fripost.org/user/ + userPassword: {SSHA}xxxxxx isActive: TRUE - - dn: dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org - dc: example.org - objectClass: top + + dn: dc=example.org,ou=domains,o=mailHosting,dc=fripost,dc=org objectClass: virtualDomain - owner: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org + owner: uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org isActive: TRUE - dn: mailTarget=user@fripost.org,dc=example.org,ou=domains,dc=mail,dc=fripost,dc=org - mailTarget: user@fripost.org - objectClass: top + dn: mailTarget=user-alias@fripost.org,dc=example.org,ou=domains,o=mailHosting,dc=fripost, dc=org objectClass: inetLocalMailRecipient objectClass: virtualAliases isActive: TRUE - mailLocalAddress: user@example.org - mailLocalAddress: user-alias@example.org + mailLocalAddress: user + mailLocalAddress: user-alias - dn: uid=user2@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org - uid: user2@fripost.org - objectClass: top + dn: uid=user2,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org 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 + dn: mailTarget=user@fripost.org,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org + objectClass: inetLocalMailRecipient + objectClass: virtualAliases + mailLocalAddress: user-alias isActive: TRUE ldapadd -cxWD cn=admin,dc=fripost,dc=org -f /tmp/populate.ldif @@ -1021,15 +993,15 @@ e.g., `slappasswd -h "{SSHA}"'. `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' + slapacl -b 'dc=example.org,ou=domains,o=mailHosting,dc=fripost,dc=org' -D 'uid=user,dc=fripost.org,ou=domains,o=mailHosting,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 +ldapwhoami -xD "uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org" -W should return the whole dn: -"uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" +"uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org" **** Check the ACL @@ -1038,27 +1010,26 @@ should return the whole dn: `slpacat' (run as root) dumps everything in the tree, including the (hashed) passwords. So should - ldapsearch -xLLL -D "cn=admin,dc=fripost,dc=org" -b 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W + ldapsearch -xLLL -D "cn=admin,dc=fripost,dc=org" -b 'ou=domains,o=mailHosting,dc=fripost,dc=org' -W and - ldapsearch -xLLL -D "cn=admin1,ou=managers,dc=mail,dc=fripost,dc=org" -b 'ou=mailboxes,dc=mail,dc=fripost,dc=org' -W + ldapsearch -xLLL -D "cn=admin1,ou=managers,o=mailHosting,dc=fripost,dc=org" -b 'ou=domains,o=mailHosting,dc=fripost,dc=org' -W ***** Anonymous user -`ldapsearch -xLLL -b "ou=mailboxes,dc=mail,dc=fripost,dc=org"' should exit with status 0, but not return +`ldapsearch -xLLL -b "ou=domains,o=mailHosting,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 +ldapsearch -xLLL -D "cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org" -b 'ou=domains,o=mailHosting,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. +should not disclose the passwords. ***** Self -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 +ldapsearch -xLLL -D "uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org" -b 'ou=domains,o=mailHosting,dc=fripost,dc=org' -W should return all the information for this very user, but not e.g., the password of the other users. @@ -1067,37 +1038,59 @@ The user should be able to change his/her password, and aliases in his/her own d :: /tmp/usermod.ldif - dn: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org + dn: uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org changetype: modify replace: userPassword userPassword: xxxxxx - dn: mailTarget=user@fripost.org,dc=example.org,ou=domain,dc=mail,dc=fripost,dc=org + dn: mailTarget=user@fripost.org,dc=example.org,ou=domain,o=mailHosting,dc=fripost,dc=org changetype: modify add: mailLocalAddress mailLocalAddress: user-alias2@example.org -ldapmodify -D "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" -W -f /tmp/usermod.ldif +ldapmodify -D "uid=user,dc=fripost.org,ou=domains,o=mailHosting,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.] [Note: If the task is merely to change the password, there is also `ldappasswd'.] -Note: This not a safe way to let the user choose his/her aliases! Nothing prevents -from having "mailLocalAddress: admin@fripost.org" for example! - We now ensure that the leaf has been updated: - :: slapcat -s "uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org" + :: slapcat -s "uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org" [...] userPassword:: aG9w entryCSN: 20120404215647.957317Z#000000#000#000000 - modifiersName: uid=user@fripost.org,ou=mailboxes,dc=mail,dc=fripost,dc=org + modifiersName: uid=user,dc=fripost.org,ou=domains,o=mailHosting,dc=fripost,dc=org modifyTimestamp: 20120404215647Z On other modifications, for instance of `maildir', `ldapmodify' should refuse with `Insufficient access (50)'. +**** Partial replication on the MXs + +In case the LDAP goes down, we partly replicate the LDAP tree on the MXs. + +***** Installation + +Cf. installation of the master LDAP server. +(We also need to install fripost's schema and indexes.) + +The slave may only listen on the UNIX socket; To specify that, in +`/etc/defauld/slapd', change `SLAPD_SERVICES' to + +SLAPD_SERVICES="ldapi:///" + +In the rest of this section, we assume there is a tunnel from the master +LDAP server to the slave (i.e., ldap://localhost:389 on the slaves actually +speaks to the master). + +Following LDAP's terminology, the master server is also called "production", +and the slave is known as "consumer". + +***** Using syncrepl + +TODO + *** Configuring the main IMAP server **** Install packages @@ -1168,7 +1161,6 @@ sudo aptitude install dovecot-imapd virtual_mailbox_domains = ldap:$config_directory/ldap_virtual_mailbox_domains.cf virtual_alias_maps = ldap:$config_directory/ldap_virtual_alias_maps.cf - virtual_mailbox_maps = ldap:$config_directory/ldap_virtual_mailbox_maps.cf [...] @@ -1183,9 +1175,10 @@ 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 = ou=domains,o=mailHosting,dc=fripost,dc=org + scope = one bind = yes - bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org + bind_dn = cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org bind_pw = xxxxxx query_filter = (&(ObjectClass=virtualDomain)(dc=%s)(isActive=TRUE)) result_attribute = dc @@ -1200,32 +1193,18 @@ Test it: server_host = ldap://localhost/ version = 3 - search_base = ou=domains,dc=mail,dc=fripost,dc=org + search_base = dc=%d,ou=domains,o=mailHosting,dc=fripost,dc=org + scope = one bind = yes - bind_dn = cn=SMTP,ou=services,dc=mail,dc=fripost,dc=org - bind_pw = xxxxxx - query_filter = (&(ObjectClass=virtualAliases)(mailLocalAddress=%s)(isActive=TRUE)) + bind_dn = cn=SMTP,ou=services,o=mailHosting,dc=fripost,dc=org + bind_pw = smtp + query_filter = (&(ObjectClass=virtualAliases)(mailLocalAddress=%u)(isActive=TRUE)) result_attribute = mailTarget 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 - -:: /etc/postfix/ldap_virtual_mailbox_maps.cf - - server_host = ldap://localhost/ - version = 3 - 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)(uid=%s)(isActive=TRUE)) - result_attribute = maildir - -Test it: - postmap -q user@fripost.org ldap:/etc/postfix/ldap_virtual_mailbox_maps.cf - **** Test delivery sudo mkdir -p /home/mail/virtual/fripost.org/ @@ -1325,8 +1304,8 @@ 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 = uid=%u,ou=mailboxes,dc=mail,dc=fripost,dc=org - base = ou=mailboxes,dc=mail,dc=fripost,dc=org + auth_bind_userdn = uid=%u,ou=mailboxes,o=mailHosting,dc=fripost,dc=org + base = ou=mailboxes,o=mailHosting,dc=fripost,dc=org deref = never scope = subtree user_attrs = maildir=home=/home/mail/virtual/%$ @@ -1335,7 +1314,7 @@ Copy this file in /etc/dovecot, and chmod 600 it. Uncomment the following lines: 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". +of our tree structure, in our case dn="ou=mailboxes,o=mailHosting,dc=fripost,dc=org". [Note: the `user_attrs' and `user_filter' are only relevant if the result of the query is used in the `dovecot.conf', for instance with mail_location = maildir:~. Otherwise, the @@ -1404,8 +1383,8 @@ test our installation.) ldap_servers: ldap://localhost ldap_version: 3 ldap_auth_method: bind - ldap_search_base: ou=mailboxes,dc=mail,dc=fripost,dc=org - ldap_scope: sub + ldap_search_base: dc=%d,ou=domains,o=mailHosting,dc=fripost,dc=org + ldap_scope: one ldap_filter: (&(objectClass=virtualMailbox)(uid=%u)(isActive=TRUE)) After restarting saslauthd (`/etc/init.d/saslauthd restart'), we can test the @@ -1677,17 +1656,17 @@ Depends on PHP's LDAP library: :: apt-get install php-net-ldap2 -We now need to modify `.../plugins/password/config/inc.php.dist' as follows (TODO: not tested.) +We now need to modify `.../plugins/password/config/inc.php.dist' as follows [TODO: not tested.] $rcmail_config['password_ldap_host'] = '127.0.0.1'; $rcmail_config['password_ldap_port'] = '389'; $rcmail_config['password_ldap_starttls'] = false; $rcmail_config['password_ldap_version'] = '3'; -$rcmail_config['password_ldap_basedn'] = 'ou=mailboxes,dc=mail,dc=fripost,dc=org' +$rcmail_config['password_ldap_basedn'] = 'dc=domains,o=mailHosting,dc=fripost,dc=org' $rcmail_config['password_ldap_method'] = 'user'; $rcmail_config['password_ldap_adminDN'] = null; $rcmail_config['password_ldap_adminPW'] = null; -$rcmail_config['password_ldap_userDN_mask'] = 'uid=%login,ou=mailboxes,dc=mail,dc=fripost,dc=org'; +$rcmail_config['password_ldap_userDN_mask'] = 'uid=%name,dc=%domain,ou=domains,o=mailHosting,dc=fripost,dc=org'; $rcmail_config['password_ldap_searchDN'] = null $rcmail_config['password_ldap_searchPW'] = null $rcmail_config['password_ldap_search_base'] = null -- cgit v1.2.3