Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ptclient: implement canonification across multiple domains. #2283

Merged
merged 1 commit into from Mar 9, 2018
Merged

ptclient: implement canonification across multiple domains. #2283

merged 1 commit into from Mar 9, 2018

Conversation

tpokorra
Copy link
Contributor

@tpokorra tpokorra commented Mar 5, 2018

allow users to just connect with their UID.
this patch adds functionality to search each existing domain for the user UID via LDAP.
fixes #2282

allow users to just connect with their UID.
this patch adds functionality to search each existing domain for the user UID via LDAP.
fixes #2282
@elliefm
Copy link
Contributor

elliefm commented Mar 5, 2018

Looks good to me, but I have no way to meaningfully test it. Can I get some additional eyeballs on this please? @ajaysusarla

My main concern was how it handled the case where the user@ matched multiple domains, but it looks like it's doing this correctly: rejects it if it's ambiguous.

@tpokorra if you could summarise the testing this has received on your end, that'd be a great help

I've also raised cyrusimap/cassandane#45 cause we really ought to make the ptclient code testable

@ajaysusarla
Copy link
Contributor

The code looks sane to me. Again, like @elliefm mentioned, I have no way to test this code, and that highlights what's missing in Cassandane.

Thanks for the patch @tpokorra

@tpokorra
Copy link
Contributor Author

tpokorra commented Mar 7, 2018

@elliefm Thanks for reviewing this!

My testing was with Kolab. With the Kolab Webadmin Panel I created multiple domains in LDAP, and created various users inside those domains. Each user has a UID, and an e-mail address.
Then I tried to login with either the UID, or the e-mail address. I enabled debugging on Cyrus (debug: 1 in /etc/imapd.conf), to see the messages that are printed with syslog(LOG_DEBUG, "...")

My /etc/cyrus.conf looks like this:

# standard standalone server implementation

START {
    # do not delete this entry!
    recover         cmd="ctl_cyrusdb -r"

    idled       cmd="idled"
}

# UNIX sockets start with a slash and are put into /var/lib/imap/sockets
SERVICES {
    imap                cmd="imapd -U 30" listen="imap" prefork=5
    imaps               cmd="imapd -s -U 30" listen="imaps" prefork=1 maxchild=500

    pop3                cmd="pop3d" listen="pop3" prefork=3
    pop3s                cmd="pop3d -s" listen="pop3s" prefork=1
    sieve       cmd="timsieved" listen="sieve"                          prefork=0

    ptloader    cmd="ptloader"  listen="/var/lib/imap/ptclient/ptsock"  prefork=0

    lmtpunix    cmd="lmtpd"     listen="/var/lib/imap/socket/lmtp"      prefork=1

    notify      cmd="notifyd"   listen="/var/lib/imap/socket/notify"    proto="udp" prefork=1
}

EVENTS {
    # this is required
    checkpoint  cmd="ctl_cyrusdb -c" period=30

    # this is only necessary if using duplicate delivery suppression,
    # Sieve or NNTP
    duplicateprune cmd="cyr_expire -E 3" at=0400

    # Expire data older then 69 days. Two full months of 31 days
    # each includes two full backup cycles, plus 1 week margin
    # because we run our full backups on the first sat/sun night
    # of each month.
    deleteprune cmd="cyr_expire -E 4 -D 69" at=0430
    expungeprune cmd="cyr_expire -E 4 -X 69" at=0445

    # this is only necessary if caching TLS sessions
    tlsprune    cmd="tls_prune" at=0400

    # Create search indexes regularly
    #squatter    cmd="squatter -s -i" at=0530
}

My /etc/imapd.conf looks like this:

configdirectory: /var/lib/imap
partition-default: /var/spool/imap
admins: cyrus-admin
sievedir: /var/lib/imap/sieve
sendmail: /usr/sbin/sendmail
sasl_pwcheck_method: saslauthd
sasl_mech_list: PLAIN LOGIN
allowplaintext: yes
tls_server_cert: /etc/pki/tls/certs/150-kolab16.tp.dev.tbits.net.crt
tls_server_key: /etc/pki/tls/private/150-kolab16.tp.dev.tbits.net.key
tls_client_ca_file: /etc/pki/tls/certs/150-kolab16.tp.dev.tbits.net.ca-chain.pem
# uncomment this if you're operating in a DSCP environment (RFC-4594)
# qosmarking: af13
auth_mech: pts
pts_module: ldap
ldap_servers: ldap://localhost:389
ldap_sasl: 0
ldap_base: dc=%2,dc=%1
ldap_bind_dn: uid=kolab-service,ou=Special Users,dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
ldap_password: randomlygenerated
ldap_filter: (|(&(|(uid=cyrus-admin)(uid=cyrus-murder))(uid=%U))(&(|(uid=%U)(mail=%U@%d)(mail=%U@%r))(objectclass=kolabinetorgperson)))
ldap_user_attribute: mail
ldap_group_base: dc=%2,dc=%1
ldap_group_filter: (&(cn=%u)(objectclass=ldapsubentry)(objectclass=nsroledefinition))
ldap_group_scope: one
ldap_member_base: ou=People,dc=%2,dc=%1
ldap_member_method: attribute
ldap_member_attribute: nsrole
ldap_restart: 1
ldap_timeout: 10
ldap_time_limit: 10
unixhierarchysep: 1
virtdomains: userid
annotation_definitions: /etc/imapd.annotations.conf
sieve_extensions: fileinto reject envelope body vacation imapflags notify include regex subaddress relational copy date index
allowallsubscribe: 0
allowusermoves: 1
altnamespace: 1
hashimapspool: 1
anysievefolder: 1
fulldirhash: 0
sieveusehomedir: 0
sieve_allowreferrals: 0
lmtp_downcase_rcpt: 1
lmtp_fuzzy_mailbox_match: 1
username_tolower: 1
deletedprefix: DELETED
delete_mode: delayed
expunge_mode: delayed
postuser: shared
tls_ciphers: EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
sieve_maxscripts: 10
sievenotifier: mailto
debug: 1
ldap_domain_base_dn: cn=kolab,cn=config
ldap_domain_filter: (&(objectclass=domainrelatedobject)(associateddomain=%s))
ldap_domain_name_attribute: associatedDomain
ldap_domain_scope: sub
ldap_domain_result_attribute: inetdomainbasedn

Sample calls:

telnet localhost 143
  . login test2 test

Result in journalctl -u cyrus-imapd:

Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Domain filter: (&(objectclass=domainrelatedobject)(associateddomain=*))
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain 150-kolab16.tp.dev.tbits.net
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain 150-kolab16.tp.dev.tbits.net
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain schule.de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain schule.de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain test.de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain test.de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: Found test2 in dc=test,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net ptloader[848]: we have found test2 in dc=test,dc=de
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: timeout_select: sock = 15, rp = 0x7ffeaa27d670, wp = 0x0, sec = 30
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: ptload read data back
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: ptload returning data
Mär 07 17:39:07 150-kolab16.tp.dev.tbits.net imap[827]: canonified test2 -> test2@test.de
Mär 07 17:39:08 150-kolab16.tp.dev.tbits.net imap[827]: login: [127.0.0.1] test2@test.de plaintext User logged in SESSIONID=<150-kolab16.tp.dev.tbits.net-827-1520440743-1-41740623
88037204642>
Mär 07 17:39:08 150-kolab16.tp.dev.tbits.net imaps[828]: accepted connection
telnet localhost 143
  . login test2@test.de test

Result in journalctl -u cyrus-imapd:

Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: accepted connection
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Attempting to get domain for test2@test.de from cn=kolab,cn=config
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Domain filter: (&(objectclass=domainrelatedobject)(associateddomain=test.de))
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Domain test.de is an alias domain for parent domain test.de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain test.de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net ptloader[848]: Continuing with ptsm->base: dc=test,dc=de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: timeout_select: sock = 15, rp = 0x7ffe7a54db60, wp = 0x0, sec = 30
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: ptload read data back
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: ptload returning data
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: canonified test2@test.de -> test2@test.de
Mär 07 17:42:09 150-kolab16.tp.dev.tbits.net imap[824]: login: [127.0.0.1] test2@test.de plaintext User logged in SESSIONID=<150-kolab16.tp.dev.tbits.net-824-1520440910-1-64514717
94398901066>
telnet localhost 143
  . login nonexisting test

Result in journalctl -u cyrus-imapd:

är 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: accepted connection
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: collecting all domains from cn=kolab,cn=config
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Domain filter: (&(objectclass=domainrelatedobject)(associateddomain=*))
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain 150-kolab16.tp.dev.tbits.net
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain 150-kolab16.tp.dev.tbits.net
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=150-kolab16,dc=tp,dc=dev,dc=tbits,dc=net
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain schule.de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain schule.de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=schule,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: we have a domain test.de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: ptsmodule_standard_root_dn called for domain test.de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: Root DN now dc=test,dc=de
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net ptloader[848]: LDAP search for notexisting failed because it does not match any account in all domains.
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: timeout_select: sock = 15, rp = 0x7fff53ecbfc0, wp = 0x0, sec = 30
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: timeout_select exiting. r = 1; errno = 0
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: ptload read data back
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: ptload(): bad response from ptloader server: identifier not found
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: No data available at all from ptload()
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: ptload completely failed: unable to canonify identifier: notexisting
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: SASL bad userid authenticated
Mär 07 17:49:03 150-kolab16.tp.dev.tbits.net imap[823]: badlogin: [127.0.0.1] notexisting LOGIN invalid user

@elliefm elliefm merged commit 5373c55 into cyrusimap:master Mar 9, 2018
@elliefm
Copy link
Contributor

elliefm commented Mar 9, 2018

Thanks, I'm happy with this! :)

@elliefm
Copy link
Contributor

elliefm commented Mar 14, 2018

@postilion Have you seen this PR, wrt your recent question on cyrus-devel about LDAP configuration?

@postilion
Copy link
Contributor

@elliefm Thanks for bringing this back to my attention. My use case is different, but this thread does seem to provide some useful example configuration which I will shamelessly steal from. :-)

-nic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ptloader: canonification should work across multiple domains
4 participants