`emailrelay-ldap-verify.py `_ -------------------------------------------------------- .. code:: python #!/usr/bin/env python3 # # SPDX-FileCopyrightText: 2020-2026 # SPDX-License-Identifier: FSFAP # # Copyright (c) 2020-2026 # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty. # === # # emailrelay-ldap-verify.py # # Example E-MailRelay address verifier script using LDAP. # # See also: https://www.python-ldap.org/en/python-ldap-3.3.0 # import sys import ldap # configuration -- edit as required if sys.platform == "win32": Server = "ldaps://ldaps-server.example.com:636" Timeout = 3 Username = "EXAMPLE\\user" Password = "secret" UserSearchPath = "CN=Users,DC=example,DC=com" UserFilter = "(&(objectCategory=person)(objectclass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(proxyAddresses=SMTP:%s))" FolderSearchPath = "CN=Microsoft Exchange System Objects,DC=example,DC=com" FolderFilter = "(&(objectclass=publicFolder)(proxyAddresses=SMTP:%s))" else: Server = "ldap://" Timeout = 3 Username = "cn=admin,dc=example,dc=com" Password = "secret" UserSearchPath = "dc=example,dc=com" UserFilter = "(mail=%s)" FolderSearchPath = None FolderFilter = None # parse the command-line try: ArgAddress = sys.argv[1] ArgDomain = sys.argv[4] except: print("error") print("Usage: emailrelay-ldap-verify.py ...") sys.exit(3) # check for basic "user-part@domain-part" syntax AtPos = ArgAddress.find("@") if AtPos <= 0: print("invalid mailbox") print("malformed address") sys.exit(2) # optionally check the domain-part matches the emailrelay # "--domain" to avoid unnecessary ldap lookups LocalDomain = "@" + ArgDomain if ArgAddress[AtPos:].lower() != LocalDomain.lower(): print("invalid mailbox") print("invalid domain") sys.exit(2) def first(attrname,ldapresult): try: return ldapresult[0][1][attrname][0].decode('utf-8') except: pass return None # ldap query, optionally in two passes try: ldapobject = ldap.initialize(Server) scope = ldap.SCOPE_SUBTREE ldapobject.set_option(ldap.OPT_NETWORK_TIMEOUT, Timeout) ldapobject.set_option(ldap.OPT_REFERRALS, 0) ldapobject.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) ldapobject.set_option(ldap.OPT_X_TLS_NEWCTX, 0) ldapobject.simple_bind_s(Username, Password) result = ldapobject.search_s( UserSearchPath, scope, UserFilter % ArgAddress, ["mail"] ) mail = first("mail",result) if mail is not None: print() print(mail) sys.exit(1) if FolderSearchPath is None: print("invalid mailbox") print("invalid mailbox: %s" % ArgAddress) sys.exit(2) result = ldapobject.search_s( FolderSearchPath, scope, FolderFilter % ArgAddress, ["mail"] ) mail = first("mail",result) if mail is not None: print() print(mail) sys.exit(1) print("invalid mailbox") print("invalid mailbox: %s" % ArgAddress) sys.exit(2) except ldap.LDAPError as e: print("temporary error") print("ldap error: %s" % str(e)) sys.exit(3) except Exception as e: print("error") print("exception: %s" % str(e)) sys.exit(3) .. _../examples/emailrelay-ldap-verify.py: emailrelay-ldap-verify_py.html