GoogleApps + Postfix + Fetchmail (OpenLdap + Postfix)
Background
We include additional schemes in the file /etc/openldap/slapd.conf: We write our new ldap database in slapd-hdb-db01.conf: If you plan to publish the database outside, we configure the interface that our Ldap server / etc / sysconfig / ldap will listen to (default 127.0.0.1): Starting the daemon: After which our base should be created in /var/lib/ldap/bases/your.ru
I must say right away that I used the Windows ports of awk utilities (http://gnuwin32.sourceforge.net/packages/gawk.htm), so this script was not tested under Linux. Be careful with the line feed in the file when importing to the server. I used JExplorer as a browser and a directory editor, this utility did not cause any complaints, it can do everything, including expot and import directory branches into .ldif files, the only thing is that it is written in Java. In principle, I heard that you can put PhpLdapAdmin, but I did not succeed on the move.
Implementation
Platform
AltLinux 4, kernel version 2.6.18-std-smp-alt6. All packages were installed from the official repository.Install LDAP Server
Install the packages openldap-servers-2.3.35-alt0, libldap2.3-2.3.35-alt0, openldap-clients-2.3.35-alt0, openldap-2.3.35-alt0, openldap-doc-2.3.35-alt0.We include additional schemes in the file /etc/openldap/slapd.conf: We write our new ldap database in slapd-hdb-db01.conf: If you plan to publish the database outside, we configure the interface that our Ldap server / etc / sysconfig / ldap will listen to (default 127.0.0.1): Starting the daemon: After which our base should be created in /var/lib/ldap/bases/your.ru
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/courier.schema
include /etc/openldap/schema/qmail.schema
allow bind_v2
concurrency 20
gentlehup on
sizelimit -1
password-hash {CLEARTEXT}
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
replica-pidfile /var/run/slurpd.pid
replica-argsfile /var/run/slurpd.args
rootDSE /etc/openldap/rootdse.ldif
access to dn.exact=""
by * read
access to dn.subtree="cn=Subschema"
by * read
access to attrs=userPassword
by self write
by anonymous auth
by * none
modulepath /usr/lib/openldap
moduleload back_hdb.la
moduleload back_monitor.la
moduleload back_null.la
include /etc/openldap/slapd-hdb-db01.conf
database hdb
suffix "dc=your,dc=ru"
rootdn "cn=admin,dc=your,dc=ru"
rootpw 123
directory /var/lib/ldap/bases/your.ru
index objectClass eq
index uid pres,eq,sub
index cn pres,eq,sub,subany
access to attrs=userPassword
by self write
by anonymous auth
by * none
access to *
by dn="cn=admin,dc=your,dc=ru" write
by * read
SLAPDURLLIST="ldap://servername.your.ru/"
SLAPD_OPTIONS=""
SLURPD_OPTIONS='-t /'
service slapd start
Filling the user base
If there is already an existing domain database, then it is possible to upload it to a text CSV file and parse it using AWK into an ldif file ready for import. One way or another, it is most convenient to create a text file with a list of users, and then use the AWK script to convert it to ldif, automatically generating user passwords. Thus, you will have a script to backup the Ldap database. Here is an example of a CSV file format for uploading from Active Directory: Here is an example AWK script for processing it:"DN","objectClass","ou","distinguishedName","instanceType","whenCreated","whenChanged","uSNCreated", "uSNChanged","name","objectGUID","objectCategory","dSCorePropagationData","cn","sn","displayName", "proxyAddresses","altRecipientBL","targetAddress","mAPIRecipient","mailNickname","internetEncoding", "legacyExchangeDN","textEncodedORAddress","mail","msExchPoliciesIncluded","msExchALObjectVersion", "msExchHideFromAddressLists","givenName","altRecipient","department","homeMTA","homeMDB", "mDBUseDefaults","userAccountControl","codePage","countryCode","pwdLastSet","primaryGroupID", "objectSid","accountExpires","sAMAccountName","sAMAccountType","showInAddressBook","userPrincipalName", "msExchHomeServerName","msExchMailboxSecurityDescriptor","msExchUserAccountControl","msExchMailboxGuid", "member","groupType","badPwdCount","badPasswordTime","lastLogoff","lastLogon","userParameters","logonCount", "lastLogonTimestamp","gPLink","gPOptions","userCertificate","adminCount","msNPAllowDialin","title", "physicalDeliveryOfficeName","telephoneNumber","initials","postOfficeBox","company","deliverAndRedirect", "memberOf","scriptPath","localPolicyFlags","operatingSystem","operatingSystemVersion", "operatingSystemServicePack","dNSHostName","servicePrincipalName","isCriticalSystemObject","location","flags", "uNCName","versionNumber","serverName","portName","driverName","priority","printStartTime","printEndTime", "printBinNames","printMaxResolutionSupported","printOrientationsSupported","printCollate","printColor", "printShareName","printSpooling","printKeepPrintedJobs","driverVersion","printMaxXExtent","printMaxYExtent", "printMinXExtent","printMinYExtent","printMediaSupported","printerName","url","shortServerName", "printDuplexSupported","printLanguage","printStaplingSupported","printMemory","printRate","printRateUnit", "printMediaReady","printNumberUp","printPagesPerMinute","description","deletedItemFlags","submissionContLength", "garbageCollPeriod","msExchRequireAuthToSendTo","homePhone","otherTelephone","mobile", "showInAdvancedViewOnly","keywords","serviceClassName","serviceDNSName","serviceDNSNameType", "mS-SQL-Name","mS-SQL-RegisteredOwner","mS-SQL-Contact","mS-SQL-Location","mS-SQL-Memory","mS-SQL-Build", "mS-SQL-ServiceAccount","mS-SQL-CharacterSet","mS-SQL-SortOrder","mS-SQL-UnicodeSortOrder","mS-SQL-Clustered", "mS-SQL-NamedPipe","mS-SQL-MultiProtocol","mS-SQL-SPX","mS-SQL-TCPIP","mS-SQL-AppleTalk","mS-SQL-Vines", "mS-SQL-Status","mS-SQL-LastUpdatedDate","mS-SQL-InformationURL","mS-SQL-GPSLatitude","mS-SQL-GPSLongitude", "mS-SQL-GPSHeight","mS-SQL-Keywords","mSMQSites","mSMQServiceType","mSMQOSType","mSMQEncryptKey","mSMQSignKey", "mSMQDependentClientServices","mSMQRoutingServices","mSMQDsServices","mS-SQL-Description","mS-SQL-Alias", "mS-SQL-Size","mS-SQL-CreationDate","mS-SQL-LastBackupDate","mS-SQL-LastDiagnosticDate","mS-SQL-Applications","msRRASAttribute","mS-DS-CreatorSID","rIDSetReferences","delivContLength","autoReplyMessage","reportToOriginator","reportToOwner", "oOFReplyToOriginator","mSMQSignCertificates","mSMQDigests"
##ВЫГРУЗКА ДЛЯ ГУГЛА
BEGIN {
FS=",";
##счетчик пользователей
userCounter = 0;
}
function pass(name)
{
return substr(name,1,1)""int(rand()*100000);
}
function trim(v)
{
## Remove leading and trailing spaces (add tabs if you like)
sub(/^ */,"",v);
sub(/ *$/,"",v);
return v;
}
##запятые могут встречаться внутри кавычек
{
num = 1;
for(i=1; i<= NF; i++)
{
if($(i)~/\"/)
{
rez[num] = $(i);
for(j=i+1; j<= NF; j++)
{
rez[num]= rez[num]","$(j);
if($(j)~/\"/)
{
i =j;
break;
}
}
gsub(/\"/, "", rez[num]);
}
else rez[num] = $(i);
num+= 1;
}
if(rez[2]=="user")
{
mail = rez[25];
split(substr($1, 5, length($1)), fio, "/");
if(rez[21]!= "")
{
userdn = "uid="rez[21]""substr(rez[1], length($1), length(rez[1]));
##Вытаскиваем русское наименование пользователя и его second name
i = 1;
while(i > 0)
{
if(i+1 in fio)
{
i++;
}
else
{
name = trim(fio[i]);
split(name, aname, " ");
if(2 in aname)
{
second_name = aname[2];
}
else
{
second_name = "null";
}
if(3 in aname)
{
second_name = second_name""aname[3];
}
delete aname;
break;
}
}
print "dn: cn="rez[21]",ou=People,dc=your,dc=ru\nobjectClass: inetOrgPerson\nobjectClass: organizationalPerson\nobjectClass: person\nobjectClass: qmailUser\nobjectClass: CourierMailAccount\nobjectClass: top\naccountStatus: active\ncn: "rez[21]"\nemployeeType: \ngidNumber: 100\nhomeDirectory: /var/spool/maildir\nmail: "mail"\nmailAlternateAddress: "rez[21]"@servername.your.ru\nmailAlternateAddress: "rez[21]"@your.ru\nmailMessageStore: /var/spool/maildir/"rez[21]"/\no: your.ru\nsn: "name"\nuid: "name"\nuidNumber: "userCounter+1000"\nuserPassword: "pass(rez[21])"\n";
userCounter += 1;
}
# uidNumber: 99 nobody
}
}
I must say right away that I used the Windows ports of awk utilities (http://gnuwin32.sourceforge.net/packages/gawk.htm), so this script was not tested under Linux. Be careful with the line feed in the file when importing to the server. I used JExplorer as a browser and a directory editor, this utility did not cause any complaints, it can do everything, including expot and import directory branches into .ldif files, the only thing is that it is written in Java. In principle, I heard that you can put PhpLdapAdmin, but I did not succeed on the move.
Postfix installation
Install the packages postfix-cyrus-2.3.11-alt1, postfix-control-1.6.1-alt1, postfix-2.3.11-alt1, postfix-ldap-2.3.11-alt1, cyrus-sasl2-2.1.22, libcourier- authlib-0.59.1-alt1.0, courier-imap-utils-4.1.2-alt1, courier-imap-4.1.2-alt1, courier-authlib-0.59.1-alt1.0, courier-authlib-ldap- 0.59.1-alt1.0, procmail-3.22-alt7. Configuring postfix: I use maildrop mailbox format (each letter is a separate text file in the mailbox folder). User mailboxes are created by themselves upon receipt of the first letter and subject to the permission to write to the maildir directory to the user under whom postfix works. Now compile this transport scheme with the command And update the configuration with the command In the next series, configure courier-imap and authorization for receiving mail.#/etc/postfix/main.cf
mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME
myhostname = servername.your.ru
#этой директивой мы замыкаем локальную почту пользователей сервера на виртуальную
local_transport = virtual
virtual_transport = virtual
virtual_mailbox_domains = your.ru
# этот каталог будет базовым для почтовых ящиков пользователей
virtual_mailbox_base = /var/spool/maildir
virtual_mailbox_maps = ldap:/etc/postfix/ldapvirtual.cf
virtual_uid_maps = static:999
virtual_gid_maps = static:12
virtual_mailbox_limit = 0
message_size_limit = 20480000
relayhost =
transport_maps = cdb:/etc/postfix/transport
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
# разрешить отправку писем только авторизованным клиентам
smtpd_recipient_restrictions = permit_sasl_authenticated, reject
smtpd_client_restrictions = permit
unknown_local_recipient_reject_code = 550
mynetworks = 192.168.0.0/24
#/etc/postfix/ldapvirtual.cf
server_host = servername.your.ru
server_port = 389
bind = yes
bind_dn = cn=admin,dc=your,dc=ru
bind_pw = 123
#узел каталога, который содержит пользователей
search_base = ou=People,dc=your,dc=ru
query_filter = (&(mail=%s)(objectClass=CourierMailAccount)(AccountStatus=active))
result_attribute = uid
result_format = %u/
#/etc/postfix/transport
your.ru :
.your.ru :
servername.your.ru :
* smtp:[mail.your_provider.ru]
postmap transport
postfix reload